Rename airtime_mvc/ to legacy/
This commit is contained in:
parent
f0879322c2
commit
3e18d42c8b
1316 changed files with 0 additions and 0 deletions
143
legacy/application/models/Auth.php
Normal file
143
legacy/application/models/Auth.php
Normal file
|
@ -0,0 +1,143 @@
|
|||
<?php
|
||||
|
||||
class Application_Model_Auth
|
||||
{
|
||||
const TOKEN_LIFETIME = 'P2D'; // DateInterval syntax
|
||||
|
||||
private function generateToken($action, $user_id)
|
||||
{
|
||||
$salt = md5("pro");
|
||||
$token = self::generateRandomString();
|
||||
|
||||
$info = new CcSubjsToken();
|
||||
$info->setDbUserId($user_id);
|
||||
$info->setDbAction($action);
|
||||
$info->setDbToken(sha1($token.$salt));
|
||||
$info->setDbCreated(gmdate(DEFAULT_TIMESTAMP_FORMAT));
|
||||
$info->save();
|
||||
|
||||
Logging::debug("generated token {$token}");
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
public function sendPasswordRestoreLink($user, $view)
|
||||
{
|
||||
$token = $this->generateToken('password.restore', $user->getDbId());
|
||||
|
||||
$e_link_protocol = empty($_SERVER['HTTPS']) ? "http" : "https";
|
||||
$e_link_base = $_SERVER['SERVER_NAME'];
|
||||
$e_link_port = $_SERVER['SERVER_PORT'];
|
||||
$e_link_path = $view->url(array('user_id' => $user->getDbId(), 'token' => $token), 'password-change');
|
||||
|
||||
$message = sprintf(_("Hi %s, \n\nPlease click this link to reset your password: "), $user->getDbLogin());
|
||||
$message .= "{$e_link_protocol}://{$e_link_base}:{$e_link_port}{$e_link_path}";
|
||||
$message .= sprintf(_("\n\nIf you have any problems, please contact our support team: %s"), SUPPORT_ADDRESS);
|
||||
$message .= sprintf(_("\n\nThank you,\nThe %s Team"), SAAS_PRODUCT_BRANDING_NAME);
|
||||
|
||||
$str = sprintf(_('%s Password Reset'), SAAS_PRODUCT_BRANDING_NAME);
|
||||
return Application_Model_Email::send($str, $message, $user->getDbEmail());
|
||||
}
|
||||
|
||||
public function invalidateTokens($user, $action)
|
||||
{
|
||||
CcSubjsTokenQuery::create()
|
||||
->filterByDbAction($action)
|
||||
->filterByDbUserId($user->getDbId())
|
||||
->delete();
|
||||
}
|
||||
|
||||
public function checkToken($user_id, $token, $action)
|
||||
{
|
||||
$salt = md5("pro");
|
||||
|
||||
$token_info = CcSubjsTokenQuery::create()
|
||||
->filterByDbAction($action)
|
||||
->filterByDbUserId($user_id)
|
||||
->filterByDbToken(sha1($token.$salt))
|
||||
->findOne();
|
||||
|
||||
if (empty($token_info)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$now = new DateTime();
|
||||
$token_life = new DateInterval(self::TOKEN_LIFETIME);
|
||||
$token_created = new DateTime($token_info->getDbCreated(), new DateTimeZone("UTC"));
|
||||
|
||||
return $now->sub($token_life)->getTimestamp() < $token_created->getTimestamp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the adapter for authentication against a database table
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public static function getAuthAdapter()
|
||||
{
|
||||
$CC_CONFIG = Config::getConfig();
|
||||
if ($CC_CONFIG['auth'] !== 'local') {
|
||||
return self::getCustomAuthAdapter($CC_CONFIG['auth']);
|
||||
}
|
||||
|
||||
// Database config
|
||||
$db = Zend_Db::factory('PDO_' . $CC_CONFIG['dsn']['phptype'], array(
|
||||
'host' => $CC_CONFIG['dsn']['hostspec'],
|
||||
'username' => $CC_CONFIG['dsn']['username'],
|
||||
'password' => $CC_CONFIG['dsn']['password'],
|
||||
'dbname' => $CC_CONFIG['dsn']['database']
|
||||
));
|
||||
Zend_Db_Table_Abstract::setDefaultAdapter($db);
|
||||
$authAdapter = new Zend_Auth_Adapter_DbTable($db);
|
||||
|
||||
$authAdapter->setTableName('cc_subjs')
|
||||
->setIdentityColumn('login')
|
||||
->setCredentialColumn('pass')
|
||||
->setCredentialTreatment('MD5(?)');
|
||||
|
||||
return $authAdapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an alternative Adapter that does not need to auth agains a databse table
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public static function getCustomAuthAdapter($adaptor) {
|
||||
return new $adaptor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get random string
|
||||
*
|
||||
* @param int $length
|
||||
* @param string $allowed_chars
|
||||
* @return string
|
||||
*/
|
||||
final public function generateRandomString($length = 12, $allowed_chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
|
||||
{
|
||||
$string = '';
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$string .= $allowed_chars[mt_rand(0, strlen($allowed_chars) - 1)];
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/** It is essential to do this before interacting with Zend_Auth otherwise sessions could be shared between
|
||||
* different copies of Airtime on the same webserver. This essentially pins this session to:
|
||||
* - The server hostname - including subdomain so we segment multiple Airtime installs on different subdomains
|
||||
* - The remote IP of the browser - to help prevent session hijacking
|
||||
* - The client ID - same reason as server hostname
|
||||
* @param Zend_Auth $auth Get this with Zend_Auth::getInstance().
|
||||
*/
|
||||
public static function pinSessionToClient($auth)
|
||||
{
|
||||
$CC_CONFIG = Config::getConfig();
|
||||
|
||||
$serverName = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : "";
|
||||
$remoteAddr = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : "";
|
||||
$sessionIdentifier = 'Airtime' . '-' . $serverName . '-' . $remoteAddr . '-' . Application_Model_Preference::GetClientId() . '-' . $CC_CONFIG["baseDir"];
|
||||
$auth->setStorage(new Zend_Auth_Storage_Session($sessionIdentifier));
|
||||
}
|
||||
}
|
1886
legacy/application/models/Block.php
Normal file
1886
legacy/application/models/Block.php
Normal file
File diff suppressed because it is too large
Load diff
146
legacy/application/models/Dashboard.php
Normal file
146
legacy/application/models/Dashboard.php
Normal file
|
@ -0,0 +1,146 @@
|
|||
<?php
|
||||
|
||||
class Application_Model_Dashboard
|
||||
{
|
||||
|
||||
public static function GetPreviousItem($p_timeNow)
|
||||
{
|
||||
//get previous show and previous item in the schedule table.
|
||||
//Compare the two and if the last show was recorded and started
|
||||
//after the last item in the schedule table, then return the show's
|
||||
//name. Else return the last item from the schedule.
|
||||
|
||||
$showInstance = Application_Model_ShowInstance::GetLastShowInstance($p_timeNow);
|
||||
$row = Application_Model_Schedule::GetLastScheduleItem($p_timeNow);
|
||||
|
||||
if (is_null($showInstance)) {
|
||||
if (count($row) == 0) {
|
||||
return null;
|
||||
} else {
|
||||
return array("name"=>$row[0]["artist_name"]." - ".$row[0]["track_title"],
|
||||
"starts"=>$row[0]["starts"],
|
||||
"ends"=>$row[0]["ends"]);
|
||||
|
||||
}
|
||||
} else {
|
||||
if (count($row) == 0) {
|
||||
if ($showInstance->isRecorded()) {
|
||||
//last item is a show instance
|
||||
return array("name"=>$showInstance->getName(),
|
||||
"starts"=>$showInstance->getShowInstanceStart(),
|
||||
"ends"=>$showInstance->getShowInstanceEnd());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
//return the one that started later.
|
||||
if ($row[0]["starts"] >= $showInstance->getShowInstanceStart()) {
|
||||
return array("name"=>$row[0]["artist_name"]." - ".$row[0]["track_title"],
|
||||
"starts"=>$row[0]["starts"],
|
||||
"ends"=>$row[0]["ends"]);
|
||||
} else {
|
||||
return array("name"=>$showInstance->getName(),
|
||||
"starts"=>$showInstance->getShowInstanceStart(),
|
||||
"ends"=>$showInstance->getShowInstanceEnd());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function GetCurrentItem($p_timeNow)
|
||||
{
|
||||
//get previous show and previous item in the schedule table.
|
||||
//Compare the two and if the last show was recorded and started
|
||||
//after the last item in the schedule table, then return the show's
|
||||
//name. Else return the last item from the schedule.
|
||||
|
||||
$row = array();
|
||||
$showInstance = Application_Model_ShowInstance::GetCurrentShowInstance($p_timeNow);
|
||||
if (!is_null($showInstance)) {
|
||||
$instanceId = $showInstance->getShowInstanceId();
|
||||
$row = Application_Model_Schedule::GetCurrentScheduleItem($p_timeNow, $instanceId);
|
||||
}
|
||||
if (is_null($showInstance)) {
|
||||
if (count($row) == 0) {
|
||||
return null;
|
||||
} else {
|
||||
/* Should never reach here, but lets return the track information
|
||||
* just in case we allow tracks to be scheduled without a show
|
||||
* in the future.
|
||||
*/
|
||||
|
||||
return array("name"=>$row[0]["artist_name"]." - ".$row[0]["track_title"],
|
||||
"artwork_data"=>$row[0]["artwork_data"],
|
||||
"starts"=>$row[0]["starts"],
|
||||
"ends"=>$row[0]["ends"]);
|
||||
}
|
||||
} else {
|
||||
if (count($row) == 0) {
|
||||
//last item is a show instance
|
||||
if ($showInstance->isRecorded()) {
|
||||
return array("name"=>$showInstance->getName(),
|
||||
"starts"=>$showInstance->getShowInstanceStart(),
|
||||
"ends"=>$showInstance->getShowInstanceEnd(),
|
||||
"media_item_played"=>false,
|
||||
"record"=>true);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return array("name"=>$row[0]["artist_name"]." - ".$row[0]["track_title"],
|
||||
"artwork_data"=>$row[0]["artwork_data"],
|
||||
"starts"=>$row[0]["starts"],
|
||||
"ends"=>$row[0]["ends"],
|
||||
"media_item_played"=>$row[0]["media_item_played"],
|
||||
"record"=>0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function GetNextItem($p_timeNow)
|
||||
{
|
||||
//get previous show and previous item in the schedule table.
|
||||
//Compare the two and if the last show was recorded and started
|
||||
//after the last item in the schedule table, then return the show's
|
||||
//name. Else return the last item from the schedule.
|
||||
|
||||
$showInstance = Application_Model_ShowInstance::GetNextShowInstance($p_timeNow);
|
||||
$row = Application_Model_Schedule::GetNextScheduleItem($p_timeNow);
|
||||
|
||||
if (is_null($showInstance)) {
|
||||
if (count($row) == 0) {
|
||||
return null;
|
||||
} else {
|
||||
return array("name"=>$row[0]["artist_name"]." - ".$row[0]["track_title"],
|
||||
"artwork_data"=>$row[0]["artwork_data"],
|
||||
"starts"=>$row[0]["starts"],
|
||||
"ends"=>$row[0]["ends"]);
|
||||
}
|
||||
} else {
|
||||
if (count($row) == 0) {
|
||||
if ($showInstance->isRecorded()) {
|
||||
//last item is a show instance
|
||||
return array("name"=>$showInstance->getName(),
|
||||
"starts"=>$showInstance->getShowInstanceStart(),
|
||||
"ends"=>$showInstance->getShowInstanceEnd());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
//return the one that starts sooner.
|
||||
|
||||
if ($row[0]["starts"] <= $showInstance->getShowInstanceStart()) {
|
||||
return array("name"=>$row[0]["artist_name"]." - ".$row[0]["track_title"],
|
||||
"artwork_data"=>$row[0]["artwork_data"],
|
||||
"starts"=>$row[0]["starts"],
|
||||
"ends"=>$row[0]["ends"]);
|
||||
} else {
|
||||
return array("name"=>$showInstance->getName(),
|
||||
"starts"=>$showInstance->getShowInstanceStart(),
|
||||
"ends"=>$showInstance->getShowInstanceEnd());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
223
legacy/application/models/Datatables.php
Normal file
223
legacy/application/models/Datatables.php
Normal file
|
@ -0,0 +1,223 @@
|
|||
<?php
|
||||
|
||||
class Application_Model_Datatables
|
||||
{
|
||||
private static function buildWhereClauseForAdvancedSearch($dbname2searchTerm)
|
||||
{
|
||||
$where = array();
|
||||
$where['clause'] = array();
|
||||
$where['params'] = array();
|
||||
foreach ($dbname2searchTerm as $dbname=>$term) {
|
||||
$isRange = false;
|
||||
if (strstr($term, '~')) {
|
||||
$info = explode('~', $term);
|
||||
if ($dbname == 'utime' || $dbname == 'mtime' || $dbname == 'lptime') {
|
||||
|
||||
try {
|
||||
$input1 = ($info[0] != "") ? Application_Common_DateHelper::UserTimezoneStringToUTCString($info[0]) : null;
|
||||
$input2 = ($info[1] != "") ? Application_Common_DateHelper::UserTimezoneStringToUTCString($info[1]) : null;
|
||||
} catch (Exception $e) {
|
||||
$input1 = null;
|
||||
$input2 = null;
|
||||
}
|
||||
|
||||
} else if($dbname == 'bit_rate' || $dbname == 'sample_rate') {
|
||||
$input1 = isset($info[0])?doubleval($info[0]) * 1000:null;
|
||||
$input2 = isset($info[1])?doubleval($info[1]) * 1000:null;
|
||||
} else {
|
||||
$input1 = isset($info[0])?$info[0]:null;
|
||||
$input2 = isset($info[1])?$info[1]:null;
|
||||
}
|
||||
$isRange = true;
|
||||
} else {
|
||||
$input1 = $term;
|
||||
}
|
||||
|
||||
if ($isRange) {
|
||||
$sub = array();
|
||||
if ($input1 != null) {
|
||||
$sub[] = $dbname." >= :" . $dbname . "1";
|
||||
}
|
||||
if ($input2 != null) {
|
||||
$sub[] = $dbname." <= :" . $dbname . "2";
|
||||
}
|
||||
if (!empty($sub)) {
|
||||
$where['clause'][$dbname] = "(".implode(' AND ', $sub).")";
|
||||
if ($input1 != null) {
|
||||
$where['params'][$dbname."1"] = $input1;
|
||||
}
|
||||
if ($input2 != null) {
|
||||
$where['params'][$dbname."2"] = $input2;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (trim($input1) !== "") {
|
||||
$where['clause'][$dbname] = $dbname." ILIKE :" . $dbname."1";
|
||||
$where['params'][$dbname."1"] = "%".$input1."%";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $where;
|
||||
}
|
||||
/*
|
||||
* query used to return data for a paginated/searchable datatable.
|
||||
*/
|
||||
public static function findEntries($con, $displayColumns, $fromTable,
|
||||
$data, $dataProp = "aaData")
|
||||
{
|
||||
|
||||
$where = array();
|
||||
/* Holds the parameters for binding after the statement has been
|
||||
prepared */
|
||||
$params = array();
|
||||
|
||||
if (isset($data['advSearch']) && $data['advSearch'] === 'true') {
|
||||
|
||||
$librarySetting = Application_Model_Preference::getCurrentLibraryTableColumnMap();
|
||||
//$displayColumns[] = 'owner';
|
||||
|
||||
// map that maps original column position to db name
|
||||
$current2dbname = array();
|
||||
// array of search terms
|
||||
$orig2searchTerm = array();
|
||||
foreach ($data as $key => $d) {
|
||||
if (strstr($key, "mDataProp_")) {
|
||||
list($dump, $index) = explode("_", $key);
|
||||
$current2dbname[$index] = $d;
|
||||
} elseif (strstr($key, "sSearch_")) {
|
||||
list($dump, $index) = explode("_", $key);
|
||||
$orig2searchTerm[$index] = $d;
|
||||
}
|
||||
}
|
||||
|
||||
// map that maps dbname to searchTerm
|
||||
$dbname2searchTerm = array();
|
||||
foreach ($current2dbname as $currentPos => $dbname) {
|
||||
$new_index = $librarySetting($currentPos);
|
||||
// TODO : Fix this retarded hack later. Just a band aid for
|
||||
// now at least we print some warnings so that we don't
|
||||
// forget about this -- cc-4462
|
||||
if ( array_key_exists($new_index, $orig2searchTerm) ) {
|
||||
$dbname2searchTerm[$dbname] = $orig2searchTerm[$new_index];
|
||||
} else {
|
||||
Logging::warn("Trying to reorder to unknown index
|
||||
printing as much debugging as possible...");
|
||||
$debug = array(
|
||||
'$new_index' => $new_index,
|
||||
'$currentPos' => $currentPos,
|
||||
'$orig2searchTerm' => $orig2searchTerm);
|
||||
Logging::warn($debug);
|
||||
}
|
||||
}
|
||||
|
||||
$advancedWhere = self::buildWhereClauseForAdvancedSearch($dbname2searchTerm);
|
||||
if (!empty($advancedWhere['clause'])) {
|
||||
$where[] = join(" AND ", $advancedWhere['clause']);
|
||||
$params = $advancedWhere['params'];
|
||||
}
|
||||
}
|
||||
|
||||
if ($data["sSearch"] !== "") {
|
||||
$searchTerms = explode(" ", $data["sSearch"]);
|
||||
}
|
||||
|
||||
$selectorCount = "SELECT COUNT(*) ";
|
||||
$selectorRows = "SELECT ".join(",", $displayColumns)." ";
|
||||
|
||||
$sql = $selectorCount." FROM ".$fromTable;
|
||||
$sqlTotalRows = $sql;
|
||||
|
||||
if (isset($searchTerms)) {
|
||||
$searchCols = array();
|
||||
for ($i = 0; $i < $data["iColumns"]; $i++) {
|
||||
if ($data["bSearchable_".$i] == "true") {
|
||||
$searchCols[] = $data["mDataProp_{$i}"];
|
||||
}
|
||||
}
|
||||
|
||||
$outerCond = array();
|
||||
$simpleWhere = array();
|
||||
|
||||
foreach ($searchTerms as $term) {
|
||||
|
||||
foreach ($searchCols as $col) {
|
||||
$simpleWhere['clause']["simple_".$col] = "{$col}::text ILIKE :simple_".$col;
|
||||
$simpleWhere['params']["simple_".$col] = "%".$term."%";
|
||||
}
|
||||
$outerCond[] = "(".implode(" OR ", $simpleWhere['clause']).")";
|
||||
}
|
||||
$where[] = "(" .implode(" AND ", $outerCond). ")";
|
||||
$params = array_merge($params, $simpleWhere['params']);
|
||||
}
|
||||
// End Where clause
|
||||
|
||||
// Order By clause
|
||||
$orderby = array();
|
||||
for ($i = 0; $i < $data["iSortingCols"]; $i++) {
|
||||
$num = $data["iSortCol_".$i];
|
||||
$orderby[] = $data["mDataProp_{$num}"]." ".$data["sSortDir_".$i];
|
||||
}
|
||||
$orderby[] = "id";
|
||||
$orderby = join("," , $orderby);
|
||||
// End Order By clause
|
||||
|
||||
$displayLength = intval($data["iDisplayLength"]);
|
||||
$needToBind = false;
|
||||
if (count($where) > 0) {
|
||||
$needToBind = true;
|
||||
$where = join(" OR ", $where);
|
||||
$sql = $selectorCount." FROM ".$fromTable." WHERE ".$where;
|
||||
$sqlTotalDisplayRows = $sql;
|
||||
|
||||
$sql = $selectorRows." FROM ".$fromTable." WHERE ".$where." ORDER BY ".$orderby;
|
||||
|
||||
}
|
||||
else {
|
||||
$sql = $selectorRows." FROM ".$fromTable." ORDER BY ".$orderby;
|
||||
}
|
||||
|
||||
//limit the results returned.
|
||||
if ($displayLength !== -1) {
|
||||
$sql .= " OFFSET ".$data["iDisplayStart"]." LIMIT ".$displayLength;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
//Logging::info($sqlTotalRows);
|
||||
|
||||
$r = $con->query($sqlTotalRows);
|
||||
$totalRows = $r->fetchColumn(0);
|
||||
|
||||
if (isset($sqlTotalDisplayRows)) {
|
||||
//Logging::info("sql is set");
|
||||
//Logging::info($sqlTotalDisplayRows);
|
||||
$totalDisplayRows = Application_Common_Database::prepareAndExecute($sqlTotalDisplayRows, $params, 'column');
|
||||
}
|
||||
else {
|
||||
//Logging::info("sql is not set.");
|
||||
$totalDisplayRows = $totalRows;
|
||||
}
|
||||
|
||||
//TODO
|
||||
if ($needToBind) {
|
||||
$results = Application_Common_Database::prepareAndExecute($sql, $params);
|
||||
}
|
||||
else {
|
||||
$stmt = $con->query($sql);
|
||||
$stmt->setFetchMode(PDO::FETCH_ASSOC);
|
||||
$results = $stmt->fetchAll();
|
||||
}
|
||||
}
|
||||
catch (Exception $e) {
|
||||
Logging::info($e->getMessage());
|
||||
}
|
||||
|
||||
return array(
|
||||
"sEcho" => intval($data["sEcho"]),
|
||||
"iTotalDisplayRecords" => intval($totalDisplayRows),
|
||||
"iTotalRecords" => intval($totalRows),
|
||||
$dataProp => $results
|
||||
);
|
||||
}
|
||||
}
|
21
legacy/application/models/Email.php
Normal file
21
legacy/application/models/Email.php
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
class Application_Model_Email
|
||||
{
|
||||
|
||||
/**
|
||||
* Send email
|
||||
*
|
||||
* @param string $subject
|
||||
* @param string $message
|
||||
* @param mixed $to
|
||||
* @return boolean
|
||||
*/
|
||||
public static function send($subject, $message, $to) {
|
||||
|
||||
$headers = sprintf('From: %s <%s>', SAAS_PRODUCT_BRANDING_NAME, LIBRETIME_EMAIL_FROM);
|
||||
return mail($to, $subject, $message, $headers);
|
||||
|
||||
}
|
||||
|
||||
}
|
74
legacy/application/models/FreeIpa.php
Normal file
74
legacy/application/models/FreeIpa.php
Normal file
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
class LibreTime_Model_FreeIpa {
|
||||
|
||||
/**
|
||||
* get userinfo in the format needed by the Auth Adaptor
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function GetUserInfo($username)
|
||||
{
|
||||
$config = Config::getConfig();
|
||||
$conn = self::_getLdapConnection();
|
||||
|
||||
$ldapResults = $conn->search(sprintf('%s=%s', $config['ldap_filter_field'], $username, $config['ldap_basedn']));
|
||||
|
||||
if ($ldapResults->count() !== 1) {
|
||||
throw new Exception('Could not find logged user in LDAP');
|
||||
}
|
||||
$ldapUser = $ldapResults->getFirst();
|
||||
|
||||
$groupMap = array(
|
||||
UTYPE_GUEST => $config['ldap_groupmap_guest'],
|
||||
UTYPE_HOST => $config['ldap_groupmap_host'],
|
||||
UTYPE_PROGRAM_MANAGER => $config['ldap_groupmap_program_manager'],
|
||||
UTYPE_ADMIN => $config['ldap_groupmap_admin'],
|
||||
UTYPE_SUPERADMIN => $config['ldap_groupmap_superadmin'],
|
||||
);
|
||||
$type = UTYPE_GUEST;
|
||||
foreach ($groupMap as $groupType => $group) {
|
||||
if (in_array($group, $ldapUser['memberof'])) {
|
||||
$type = $groupType;
|
||||
}
|
||||
}
|
||||
|
||||
// grab first value for multivalue field
|
||||
$firstName = $ldapUser['givenname'][0];
|
||||
$lastName = $ldapUser['sn'][0];
|
||||
$mail = $ldapUser['mail'][0];
|
||||
|
||||
// return full user info for auth adapter
|
||||
return array(
|
||||
'type' => $type,
|
||||
'first_name' => $firstName,
|
||||
'last_name' => $lastName,
|
||||
'email' => $mail,
|
||||
'cell_phone' => '', # empty since I did not find it in ldap
|
||||
'skype' => '', # empty until we decide on a field
|
||||
'jabber' => '' # empty until we decide on a field
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind to ldap so we can fetch additional user info
|
||||
*
|
||||
* @return Zend_Ldap
|
||||
*/
|
||||
private static function _getLdapConnection()
|
||||
{
|
||||
$config = Config::getConfig();
|
||||
|
||||
$options = array(
|
||||
'host' => $config['ldap_hostname'],
|
||||
'username' => $config['ldap_binddn'],
|
||||
'password' => $config['ldap_password'],
|
||||
'bindRequiresDn' => true,
|
||||
'accountDomainName' => $config['ldap_account_domain'],
|
||||
'baseDn' => $config['ldap_basedn']
|
||||
);
|
||||
$conn = new Zend_Ldap($options);
|
||||
$conn->connect();
|
||||
return $conn;
|
||||
}
|
||||
}
|
75
legacy/application/models/Library.php
Normal file
75
legacy/application/models/Library.php
Normal file
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
class Application_Model_Library
|
||||
{
|
||||
|
||||
public static function getObjInfo($p_type)
|
||||
{
|
||||
$info = array();
|
||||
|
||||
if (strcmp($p_type, 'playlist')==0) {
|
||||
$info['className'] = 'Application_Model_Playlist';
|
||||
} elseif (strcmp($p_type, 'block')==0) {
|
||||
$info['className'] = 'Application_Model_Block';
|
||||
} elseif (strcmp($p_type, 'webstream')==0) {
|
||||
$info['className'] = 'Application_Model_Webstream';
|
||||
} else {
|
||||
throw new Exception("Unknown object type: '$p_type'");
|
||||
}
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
public static function changePlaylist($p_id, $p_type)
|
||||
{
|
||||
$obj_sess = new Zend_Session_Namespace(UI_PLAYLISTCONTROLLER_OBJ_SESSNAME);
|
||||
|
||||
if (is_null($p_id) || is_null($p_type)) {
|
||||
unset($obj_sess->id);
|
||||
unset($obj_sess->type);
|
||||
} else {
|
||||
$obj_sess->id = intval($p_id);
|
||||
$obj_sess->type = $p_type;
|
||||
}
|
||||
}
|
||||
|
||||
public static function getPlaylistNames($alphasort = false)
|
||||
{
|
||||
|
||||
$playlistNames = array(NULL => _("None"));
|
||||
//if we want to return the playlists sorted alphabetically by name
|
||||
if ($alphasort) {
|
||||
$playlists = CcPlaylistQuery::create()
|
||||
->setFormatter(ModelCriteria::FORMAT_ON_DEMAND)
|
||||
->orderByname()
|
||||
->find();
|
||||
|
||||
}
|
||||
else {
|
||||
$playlists = CcPlaylistQuery::create()
|
||||
->setFormatter(ModelCriteria::FORMAT_ON_DEMAND)
|
||||
->find();
|
||||
}
|
||||
foreach ($playlists as $playlist) {
|
||||
$playlistNames[$playlist->getDbId()] = $playlist->getDbName();
|
||||
}
|
||||
|
||||
return $playlistNames;
|
||||
}
|
||||
|
||||
public static function getTracktypes()
|
||||
{
|
||||
$track_type_options = array(NULL => _("None"));
|
||||
$track_types = Application_Model_Tracktype::getTracktypes();
|
||||
|
||||
array_multisort(array_map(function($element) {
|
||||
return $element['type_name'];
|
||||
}, $track_types), SORT_ASC, $track_types);
|
||||
|
||||
foreach ($track_types as $key => $tt) {
|
||||
$track_type_options[$tt['code']] = $tt['type_name'];
|
||||
}
|
||||
|
||||
return $track_type_options;
|
||||
}
|
||||
}
|
10
legacy/application/models/LibraryEditable.php
Normal file
10
legacy/application/models/LibraryEditable.php
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
interface Application_Model_LibraryEditable
|
||||
{
|
||||
|
||||
public function setMetadata($key, $val);
|
||||
public function setName($name);
|
||||
public function getLength();
|
||||
public function getId();
|
||||
}
|
193
legacy/application/models/ListenerStat.php
Normal file
193
legacy/application/models/ListenerStat.php
Normal file
|
@ -0,0 +1,193 @@
|
|||
<?php
|
||||
class Application_Model_ListenerStat
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public static function getDataPointsWithinRange($p_start, $p_end) {
|
||||
$sql = <<<SQL
|
||||
SELECT mount_name, count(*)
|
||||
FROM cc_listener_count AS lc
|
||||
INNER JOIN cc_timestamp AS ts ON (lc.timestamp_id = ts.ID)
|
||||
INNER JOIN cc_mount_name AS mn ON (lc.mount_name_id = mn.ID)
|
||||
WHERE (ts.timestamp >=:p1 AND ts.timestamp <=:p2)
|
||||
group by mount_name
|
||||
SQL;
|
||||
$data = Application_Common_Database::prepareAndExecute($sql,
|
||||
array('p1'=>$p_start, 'p2'=>$p_end));
|
||||
$out = array();
|
||||
|
||||
foreach ($data as $d) {
|
||||
$jump = intval($d['count']/1000);
|
||||
$jump = max(1, $jump);
|
||||
$remainder = $jump == 1?0:1;
|
||||
|
||||
$sql = <<<SQL
|
||||
SELECT *
|
||||
FROM
|
||||
(SELECT lc.id, ts.timestamp, lc.listener_count, mn.mount_name,
|
||||
ROW_NUMBER() OVER (ORDER BY timestamp) as rownum
|
||||
FROM cc_listener_count AS lc
|
||||
INNER JOIN cc_timestamp AS ts ON (lc.timestamp_id = ts.ID)
|
||||
INNER JOIN cc_mount_name AS mn ON (lc.mount_name_id = mn.ID)
|
||||
WHERE (ts.timestamp >=:p1 AND ts.timestamp <= :p2) AND mount_name=:p3) as temp
|
||||
WHERE (temp.rownum%:p4) = :p5;
|
||||
SQL;
|
||||
$result = Application_Common_Database::prepareAndExecute($sql,
|
||||
array('p1'=>$p_start, 'p2'=>$p_end, 'p3'=>$d['mount_name'], 'p4'=>$jump, 'p5'=>$remainder));
|
||||
|
||||
$utcTimezone = new DateTimeZone("UTC");
|
||||
$displayTimezone = new DateTimeZone(Application_Model_Preference::GetUserTimezone());
|
||||
|
||||
foreach ($result as $r) {
|
||||
$t = new DateTime($r['timestamp'], $utcTimezone);
|
||||
$t->setTimezone($displayTimezone);
|
||||
// tricking javascript so it thinks the server timezone is in UTC
|
||||
$dt = new DateTime($t->format(DEFAULT_TIMESTAMP_FORMAT), $utcTimezone);
|
||||
|
||||
$r['timestamp'] = $dt->format("U");
|
||||
$out[$r['mount_name']][] = $r;
|
||||
}
|
||||
}
|
||||
|
||||
return $out;
|
||||
$enabledStreamIds = Application_Model_StreamSetting::getEnabledStreamIds();
|
||||
$enabledOut = array();
|
||||
|
||||
foreach ($enabledStreamIds as $sId) {
|
||||
|
||||
$sql = "SELECT value FROM cc_stream_setting"
|
||||
." WHERE keyname = :key";
|
||||
|
||||
$result = Application_Common_Database::prepareAndExecute($sql, array('key' => $sId."_mount"), "single");
|
||||
|
||||
$enabledMountPoint = $result["value"];
|
||||
|
||||
if (isset($out[$enabledMountPoint])) {
|
||||
$enabledOut[$enabledMountPoint] = $out[$enabledMountPoint];
|
||||
}
|
||||
else {
|
||||
//TODO fix this hack (here for CC-5254)
|
||||
//all shoutcast streams are automatically put under "shoutcast" mount point.
|
||||
if (isset($out["shoutcast"])) {
|
||||
$enabledOut["shoutcast"] = $out["shoutcast"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $enabledOut;
|
||||
}
|
||||
// this will currently log the average number of listeners to a specific show during a certain range
|
||||
public static function getShowDataPointsWithinRange($p_start, $p_end, $show_id) {
|
||||
$showData = [];
|
||||
$ccShow = CcShowQuery::create()->findPk($show_id);
|
||||
$showName = $ccShow->getDbName();
|
||||
|
||||
|
||||
// this query selects all show instances that aired in this date range that match the show_id
|
||||
$sql = <<<SQL
|
||||
SELECT id, starts, ends FROM cc_show_instances WHERE show_id =:p1
|
||||
AND starts >=:p2 AND ends <=:p3
|
||||
SQL;
|
||||
$data = Application_Common_Database::prepareAndExecute($sql,
|
||||
array('p1'=>$show_id,'p2'=>$p_start, 'p3'=>$p_end));
|
||||
foreach ($data as $d) {
|
||||
$sql = <<<SQL
|
||||
SELECT timestamp, SUM(listener_count) AS listeners
|
||||
FROM cc_listener_count AS lc
|
||||
INNER JOIN cc_timestamp AS ts ON (lc.timestamp_id = ts.ID)
|
||||
INNER JOIN cc_mount_name AS mn ON (lc.mount_name_id = mn.ID)
|
||||
WHERE (ts.timestamp >=:p1 AND ts.timestamp <=:p2)
|
||||
GROUP BY timestamp
|
||||
SQL;
|
||||
$data = Application_Common_Database::prepareAndExecute($sql,
|
||||
array('p1'=>$d['starts'], 'p2'=>$d['ends']));
|
||||
$utcTimezone = new DateTimeZone("UTC");
|
||||
$displayTimezone = new DateTimeZone(Application_Model_Preference::GetUserTimezone());
|
||||
if (sizeof($data) > 0) {
|
||||
$t = new DateTime($data[0]['timestamp'], $utcTimezone);
|
||||
$t->setTimezone($displayTimezone);
|
||||
// tricking javascript so it thinks the server timezone is in UTC
|
||||
$average_listeners = array_sum(array_column($data, 'listeners')) / sizeof($data);
|
||||
$max_num_listeners = max(array_column($data, 'listeners'));
|
||||
$entry = array("show" => $showName, "time" => $t->format( 'Y-m-d H:i:s')
|
||||
, "average_number_of_listeners" => $average_listeners,
|
||||
"maximum_number_of_listeners" => $max_num_listeners);
|
||||
array_push($showData, $entry);
|
||||
}
|
||||
}
|
||||
return($showData);
|
||||
}
|
||||
public static function getAllShowDataPointsWithinRange($p_start, $p_end) {
|
||||
// this query selects the id of all show instances that aired in this date range
|
||||
$all_show_data = [];
|
||||
$sql = <<<SQL
|
||||
SELECT show_id FROM cc_show_instances
|
||||
WHERE starts >=:p1 AND ends <=:p2
|
||||
GROUP BY show_id
|
||||
SQL;
|
||||
$data = Application_Common_Database::prepareAndExecute($sql,
|
||||
array('p1'=>$p_start, 'p2'=>$p_end));
|
||||
|
||||
foreach($data as $show_id) {
|
||||
$all_show_data = array_merge(self::getShowDataPointsWithinRange($p_start,$p_end,$show_id['show_id']), $all_show_data);
|
||||
}
|
||||
/* option to sort by number of listeners currently commented out
|
||||
usort($all_show_data, function($a, $b) {
|
||||
return $a['average_number_of_listeners'] - $b['average_number_of_listeners'];
|
||||
});
|
||||
*/
|
||||
return $all_show_data;
|
||||
}
|
||||
|
||||
public static function insertDataPoints($p_dataPoints) {
|
||||
|
||||
|
||||
$timestamp_sql = "INSERT INTO cc_timestamp (timestamp) VALUES
|
||||
(:ts::TIMESTAMP) RETURNING id;";
|
||||
|
||||
$mount_name_check_sql = "SELECT id from cc_mount_name WHERE
|
||||
mount_name = :mn;";
|
||||
|
||||
$mount_name_insert_sql = "INSERT INTO cc_mount_name (mount_name) VALUES
|
||||
(:mn) RETURNING id;";
|
||||
|
||||
$stats_sql = "INSERT INTO cc_listener_count (timestamp_id,
|
||||
listener_count, mount_name_id) VALUES (:timestamp_id,
|
||||
:listener_count, :mount_name_id)";
|
||||
|
||||
foreach ($p_dataPoints as $dp) {
|
||||
$timestamp_id = Application_Common_Database::prepareAndExecute(
|
||||
$timestamp_sql,
|
||||
array('ts'=> $dp['timestamp']),
|
||||
"column");
|
||||
|
||||
$mount_name_id = Application_Common_Database::prepareAndExecute(
|
||||
$mount_name_check_sql,
|
||||
array('mn' => $dp['mount_name']),
|
||||
"column");
|
||||
|
||||
if (strlen($mount_name_id) == 0) {
|
||||
//there is a race condition here where theoretically the row
|
||||
//with value "mount_name" could appear, but this is *very*
|
||||
//unlikely and won't break anything even if it happens.
|
||||
$mount_name_id = Application_Common_Database::prepareAndExecute(
|
||||
$mount_name_insert_sql,
|
||||
array('mn' => $dp['mount_name']),
|
||||
"column");
|
||||
}
|
||||
|
||||
Application_Common_Database::prepareAndExecute($stats_sql,
|
||||
array('timestamp_id' => $timestamp_id,
|
||||
'listener_count' => $dp["num_listeners"],
|
||||
'mount_name_id' => $mount_name_id,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
370
legacy/application/models/LiveLog.php
Normal file
370
legacy/application/models/LiveLog.php
Normal file
|
@ -0,0 +1,370 @@
|
|||
<?php
|
||||
|
||||
class Application_Model_LiveLog
|
||||
{
|
||||
|
||||
public static function GetLiveShowDuration($p_keepData=false)
|
||||
{
|
||||
try {
|
||||
|
||||
$sql = "SELECT * FROM CC_LIVE_LOG"
|
||||
." WHERE state = :state"
|
||||
." and (start_time >= (now() - INTERVAL '1 day'))"
|
||||
." ORDER BY id";
|
||||
$rows = Application_Common_Database::prepareAndExecute($sql, array(':state'=>'L'),
|
||||
Application_Common_Database::ALL);
|
||||
|
||||
/* Check if last log has end time.
|
||||
* If not, set end time to current time
|
||||
*/
|
||||
if ($rows != null) {
|
||||
$last_row = self::UpdateLastLogEndTime(array_pop($rows));
|
||||
array_push($rows, $last_row);
|
||||
$skip = false;
|
||||
} else {
|
||||
$sql = "SELECT * FROM CC_LIVE_LOG"
|
||||
." WHERE state = :state"
|
||||
." ORDER BY id";
|
||||
$rows = Application_Common_Database::prepareAndExecute($sql, array(':state'=>'L'),
|
||||
Application_Common_Database::ALL);
|
||||
|
||||
if ($rows != null) {
|
||||
$last_row = self::UpdateLastLogEndTime(array_pop($rows));
|
||||
array_push($rows, $last_row);
|
||||
foreach ($rows as $row) {
|
||||
$sql_delete = "DELETE FROM CC_LIVE_LOG"
|
||||
." WHERE id = :id";
|
||||
Application_Common_Database::prepareAndExecute($sql_delete, array(':id'=>$row['id']),
|
||||
Application_Common_Database::EXECUTE);
|
||||
}
|
||||
}
|
||||
$skip = true;
|
||||
}
|
||||
|
||||
$hours = 0;
|
||||
$minutes = 0;
|
||||
$seconds = 0;
|
||||
|
||||
if (!$skip) {
|
||||
foreach ($rows as $row) {
|
||||
$end = new DateTime($row['end_time']);
|
||||
$start = new DateTime($row['start_time']);
|
||||
$duration = $start->diff($end);
|
||||
$duration = $duration->format("%H:%i:%s");
|
||||
$intervals = explode(":", $duration);
|
||||
for ($i = 0; $i < sizeof($intervals); $i++) {
|
||||
if (!isset($intervals[$i])) {
|
||||
$intervals[$i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Trim milliseconds (DateInterval does not support)
|
||||
$sec = explode(".", $intervals[2]);
|
||||
if (isset($sec[0])) {
|
||||
$intervals[2] = $sec[0];
|
||||
}
|
||||
|
||||
$seconds += $intervals[2];
|
||||
if ($seconds / 60 >= 1) {
|
||||
$minutes += 1;
|
||||
$seconds -= 60;
|
||||
}
|
||||
|
||||
$minutes += $intervals[1];
|
||||
if ($minutes / 60 >= 1) {
|
||||
$hours += 1;
|
||||
$minutes -= 60;
|
||||
}
|
||||
|
||||
$hours += $intervals[0];
|
||||
|
||||
if (!$p_keepData) {
|
||||
// Delete data we just used to start a new log history
|
||||
$sql_delete = "DELETE FROM CC_LIVE_LOG"
|
||||
." WHERE id = :id";
|
||||
Application_Common_Database::prepareAndExecute($sql_delete, array(':id'=>$row['id']),
|
||||
Application_Common_Database::EXECUTE);
|
||||
}
|
||||
}
|
||||
//Trim milliseconds
|
||||
$seconds = explode(".", $seconds);
|
||||
if (isset($seconds[0])) {
|
||||
$minutes = (double) (($hours*60)+$minutes . "." . $seconds[0]);
|
||||
} else {
|
||||
$minutes = (double) (($hours*60)+$minutes);
|
||||
}
|
||||
}
|
||||
|
||||
return $minutes;
|
||||
} catch (Exception $e) {
|
||||
header('HTTP/1.0 503 Service Unavailable');
|
||||
Logging::info("GetLiveShowDuration - Could not connect to database.");
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
public static function GetScheduledDuration($p_keepData=false)
|
||||
{
|
||||
try {
|
||||
|
||||
$sql_get_logs = "SELECT * FROM CC_LIVE_LOG"
|
||||
." WHERE state = :state"
|
||||
." and (start_time >= (now() - INTERVAL '1 day'))"
|
||||
." ORDER BY id";
|
||||
|
||||
$rows = Application_Common_Database::prepareAndExecute($sql_get_logs, array(':state'=>'S'),
|
||||
Application_Common_Database::ALL);
|
||||
|
||||
/* Check if last log has end time.
|
||||
* If not, set end time to current time
|
||||
*/
|
||||
if ($rows != null) {
|
||||
$last_row = self::UpdateLastLogEndTime(array_pop($rows));
|
||||
array_push($rows, $last_row);
|
||||
$skip = false;
|
||||
} else {
|
||||
$sql = "SELECT * FROM CC_LIVE_LOG"
|
||||
." WHERE state = :state"
|
||||
." ORDER BY id";
|
||||
$rows = Application_Common_Database::prepareAndExecute($sql, array(':state'=>'S'),
|
||||
Application_Common_Database::ALL);
|
||||
|
||||
if ($rows != null) {
|
||||
$last_row = self::UpdateLastLogEndTime(array_pop($rows));
|
||||
array_push($rows, $last_row);
|
||||
foreach ($rows as $row) {
|
||||
$sql_delete = "DELETE FROM CC_LIVE_LOG"
|
||||
." WHERE id = :id";
|
||||
Application_Common_Database::prepareAndExecute($sql_delete, array(':id'=>$row['id']),
|
||||
Application_Common_Database::EXECUTE);
|
||||
}
|
||||
}
|
||||
$skip = true;
|
||||
}
|
||||
|
||||
$hours = 0;
|
||||
$minutes = 0;
|
||||
$seconds = 0;
|
||||
|
||||
if (!$skip) {
|
||||
/* Get all shows and tracks from cc_schedule that played
|
||||
* during a scheduled state
|
||||
*/
|
||||
foreach ($rows as $row) {
|
||||
$sql_get_tracks = "SELECT * FROM cc_schedule"
|
||||
." WHERE starts >= :starts1"
|
||||
." AND starts < :starts2"
|
||||
." AND file_id IS NOT NULL"
|
||||
." AND media_item_played IS TRUE";
|
||||
$params = array(
|
||||
':starts1'=>$row['start_time'],
|
||||
':starts2'=>$row['end_time']
|
||||
);
|
||||
$tracks = Application_Common_Database::prepareAndExecute($sql_get_tracks, $params,
|
||||
Application_Common_Database::ALL);
|
||||
|
||||
foreach ($tracks as $track) {
|
||||
if ($track['ends'] > $row['end_time']) {
|
||||
$scheduled_ends = new DateTime($row['end_time']);
|
||||
$track_ends = new DateTime($track['ends']);
|
||||
$extra_time = $scheduled_ends->diff($track_ends);
|
||||
|
||||
/* Get difference between clip_length
|
||||
* and the extra time. We need to subtract
|
||||
* this difference from the track's
|
||||
* clip length.
|
||||
*/
|
||||
$clip_length = $track['clip_length'];
|
||||
//Convert clip_length into seconds
|
||||
$clip_length_intervals = explode(":", $clip_length);
|
||||
for ($i = 0; $i < sizeof($clip_length_intervals); $i++) {
|
||||
if (!isset($clip_length_intervals[$i])) {
|
||||
$clip_length_intervals[$i] = 0;
|
||||
}
|
||||
}
|
||||
$clip_length_seconds = $clip_length_intervals[0]*3600 + $clip_length_intervals[1]*60 + $clip_length_intervals[2];
|
||||
|
||||
$extra_time = $extra_time->format("%H:%i:%s");
|
||||
//Convert extra_time into seconds;
|
||||
$extra_time_intervals = explode(":", $extra_time);
|
||||
for ($i = 0; $i < sizeof($extra_time_intervals); $i++) {
|
||||
if (!isset($extra_time_intervals[$i])) {
|
||||
$extra_time_intervals[$i] = 0;
|
||||
}
|
||||
}
|
||||
$extra_time_seconds = $extra_time_intervals[0]*3600 + $extra_time_intervals[1]*60 + $extra_time_intervals[2];
|
||||
|
||||
$clip_length_seconds -= $extra_time_seconds;
|
||||
|
||||
//Convert new clip_length into "H-i-s" format
|
||||
$clip_length_arr = array();
|
||||
if ($clip_length_seconds / 3600 >= 1) {
|
||||
array_push($clip_length_arr, str_pad(floor($clip_length_seconds / 3600), 2, "0", STR_PAD_LEFT));
|
||||
$clip_length_seconds -= floor($clip_length_seconds / 3600);
|
||||
} else {
|
||||
array_push($clip_length_arr, "00");
|
||||
}
|
||||
if ($clip_length_seconds / 60 >= 1) {
|
||||
array_push($clip_length_arr, str_pad(floor($clip_length_seconds / 60), 2, "0", STR_PAD_LEFT));
|
||||
$clip_length_seconds -= floor($clip_length_seconds / 60);
|
||||
} else {
|
||||
array_push($clip_length_arr, "00");
|
||||
}
|
||||
|
||||
array_push($clip_length_arr, str_pad($clip_length_seconds, 2, "0", STR_PAD_LEFT));
|
||||
$clip_length = implode(":", $clip_length_arr);
|
||||
} else {
|
||||
$clip_length = $track['clip_length'];
|
||||
}
|
||||
|
||||
$intervals = explode(":", $clip_length);
|
||||
for ($i = 0; $i < sizeof($intervals); $i++) {
|
||||
if (!isset($intervals[$i])) {
|
||||
$intervals[$i] = 0;
|
||||
}
|
||||
}
|
||||
// Trim milliseconds (DateInteral does not support)
|
||||
$sec = explode(".", $intervals[2]);
|
||||
if (isset($sec[0])) {
|
||||
$intervals[2] = $sec[0];
|
||||
}
|
||||
|
||||
$seconds += $intervals[2];
|
||||
if ($seconds / 60 >= 1) {
|
||||
$minutes += 1;
|
||||
$seconds -= 60;
|
||||
}
|
||||
|
||||
$minutes += $intervals[1];
|
||||
if ($minutes / 60 >= 1) {
|
||||
$hours += 1;
|
||||
$minutes -= 60;
|
||||
}
|
||||
|
||||
$hours += $intervals[0];
|
||||
}
|
||||
|
||||
if (!$p_keepData) {
|
||||
//Delete row because we do not need data anymore
|
||||
$sql_delete = "DELETE FROM CC_LIVE_LOG"
|
||||
." WHERE id = :id";
|
||||
Application_Common_Database::prepareAndExecute($sql_delete, array(':id'=>$row['id']),
|
||||
Application_Common_Database::EXECUTE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$seconds = explode(".", $seconds);
|
||||
if (isset($seconds[0])) {
|
||||
$minutes = (double) (($hours*60)+$minutes . "." . $seconds[0]);
|
||||
} else {
|
||||
$minutes = (double) (($hours*60)+$minutes);
|
||||
}
|
||||
}
|
||||
|
||||
return $minutes;
|
||||
} catch (Exception $e) {
|
||||
header('HTTP/1.0 503 Service Unavailable');
|
||||
Logging::info("GetScheduledDuration - Could not connect to database.");
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
public static function UpdateLastLogEndTime($log)
|
||||
{
|
||||
if ($log['end_time'] == null) {
|
||||
$current_time = new DateTime("now", new DateTimeZone('UTC'));
|
||||
$log['end_time'] = $current_time;
|
||||
$log['end_time'] = $log['end_time']->format(DEFAULT_TIMESTAMP_FORMAT);
|
||||
self::SetEndTime($log['state'], $current_time, true);
|
||||
self::SetNewLogTime($log['state'], $current_time);
|
||||
}
|
||||
|
||||
return $log;
|
||||
}
|
||||
|
||||
public static function SetNewLogTime($state, $dateTime)
|
||||
{
|
||||
try {
|
||||
|
||||
$scheduled = Application_Model_Preference::GetSourceSwitchStatus('scheduled_play');
|
||||
if ($state == 'L' && $scheduled == 'on') {
|
||||
self::SetEndTime('S', $dateTime);
|
||||
}
|
||||
|
||||
/* Only insert new state if last log
|
||||
* has ended
|
||||
*/
|
||||
$sql_select = "SELECT max(id) from CC_LIVE_LOG"
|
||||
." WHERE (state= :state1 and end_time is NULL) or (state= :state2 and end_time is NULL)";
|
||||
$params = array(
|
||||
":state1"=> 'L',
|
||||
":state2"=> 'S'
|
||||
);
|
||||
$id = Application_Common_Database::prepareAndExecute($sql_select, $params,
|
||||
Application_Common_Database::COLUMN);
|
||||
|
||||
if ($id == null) {
|
||||
$sql_insert = "INSERT INTO CC_LIVE_LOG (state, start_time)"
|
||||
." VALUES (:state, :start)";
|
||||
$params = array(
|
||||
':state'=>$state,
|
||||
':start'=>$dateTime->format(DEFAULT_TIMESTAMP_FORMAT)
|
||||
);
|
||||
Application_Common_Database::prepareAndExecute($sql_insert, $params,
|
||||
Application_Common_Database::EXECUTE);
|
||||
if ($state == "S") {
|
||||
// if scheduled play source is getting broadcasted
|
||||
Application_Model_Schedule::UpdateBrodcastedStatus($dateTime, 1);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
header('HTTP/1.0 503 Service Unavailable');
|
||||
Logging::info("SetNewLogTime - Could not connect to database.");
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
public static function SetEndTime($state, $dateTime, $override=false)
|
||||
{
|
||||
try {
|
||||
$dj_live = Application_Model_Preference::GetSourceSwitchStatus('live_dj');
|
||||
$master_live = Application_Model_Preference::GetSourceSwitchStatus('master_dj');
|
||||
|
||||
if (($dj_live=='off' && $master_live=='off') || $state == 'S' || $override) {
|
||||
$sql = "SELECT id, state from cc_live_log"
|
||||
." where id in (select max(id) from cc_live_log)";
|
||||
$row = Application_Common_Database::prepareAndExecute($sql, array(),
|
||||
Application_Common_Database::SINGLE);
|
||||
|
||||
/* Only set end time if state recevied ($state)
|
||||
* is the last row in cc_live_log
|
||||
*/
|
||||
if ($row['state'] == $state) {
|
||||
$update_sql = "UPDATE CC_LIVE_LOG"
|
||||
." SET end_time = :end"
|
||||
." WHERE id = :id";
|
||||
$params = array(
|
||||
':end'=>$dateTime->format(DEFAULT_TIMESTAMP_FORMAT),
|
||||
':id'=>$row['id']
|
||||
);
|
||||
Application_Common_Database::prepareAndExecute($update_sql, $params,
|
||||
Application_Common_Database::EXECUTE);
|
||||
}
|
||||
|
||||
//If live broadcasting is off, turn scheduled play on
|
||||
$scheduled = Application_Model_Preference::GetSourceSwitchStatus('scheduled_play');
|
||||
if ($state == 'L' && $scheduled=='on' && !$override) {
|
||||
self::SetNewLogTime('S', $dateTime);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
header('HTTP/1.0 503 Service Unavailable');
|
||||
Logging::info("SetEndTime - Could not connect to database.");
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
83
legacy/application/models/Locale.php
Normal file
83
legacy/application/models/Locale.php
Normal file
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
|
||||
final class Application_Model_Locale
|
||||
{
|
||||
private static $domains = array(
|
||||
'airtime',
|
||||
'pro',
|
||||
);
|
||||
|
||||
public static $locales = array(
|
||||
"en_CA" => "English (Canada)",
|
||||
"en_GB" => "English (Britain)",
|
||||
"en_US" => "English (USA)",
|
||||
"cs_CZ" => "Český",
|
||||
"de_DE" => "Deutsch",
|
||||
"de_AT" => "Deutsch (Österreich)",
|
||||
"el_GR" => "Ελληνικά",
|
||||
"es_ES" => "Español",
|
||||
"fr_FR" => "Français",
|
||||
"hr_HR" => "Hrvatski",
|
||||
"hu_HU" => "Magyar",
|
||||
"it_IT" => "Italiano",
|
||||
"ja_JP" => "日本語",
|
||||
"ko_KR" => "한국어",
|
||||
"pl_PL" => "Polski",
|
||||
"pt_BR" => "Português (Brasil)",
|
||||
"ru_RU" => "Русский",
|
||||
"sr_RS" => "Српски (Ћирилица)",
|
||||
"sr_RS@latin" => "Srpski (Latinica)",
|
||||
"zh_CN" => "简体中文"
|
||||
);
|
||||
|
||||
public static function getLocales()
|
||||
{
|
||||
return self::$locales;
|
||||
}
|
||||
|
||||
public static function configureLocalization($locale = null)
|
||||
{
|
||||
$codeset = 'UTF-8';
|
||||
if (is_null($locale)) {
|
||||
$lang = Application_Model_Preference::GetLocale().'.'.$codeset;
|
||||
} else {
|
||||
$lang = $locale.'.'.$codeset;
|
||||
}
|
||||
//putenv("LC_ALL=$lang");
|
||||
//putenv("LANG=$lang");
|
||||
//Setting the LANGUAGE env var supposedly lets gettext search inside our locale dir even if the system
|
||||
//doesn't have the particular locale that we want installed. This doesn't actually seem to work though. -- Albert
|
||||
putenv("LANGUAGE=$locale");
|
||||
if (setlocale(LC_MESSAGES, $lang) === false)
|
||||
{
|
||||
Logging::warn("Your system does not have the " . $lang . " locale installed. Run: sudo locale-gen " . $lang);
|
||||
}
|
||||
|
||||
// We need to run bindtextdomain and bind_textdomain_codeset for each domain we're using.
|
||||
foreach (self::$domains as $domain) {
|
||||
bindtextdomain($domain, '../locale');
|
||||
bind_textdomain_codeset($domain, $codeset);
|
||||
}
|
||||
|
||||
textdomain('airtime');
|
||||
}
|
||||
|
||||
/**
|
||||
* We need this function for the case where a user has logged out, but
|
||||
* has an airtime_locale cookie containing their locale setting.
|
||||
*
|
||||
* If the user does not have an airtime_locale cookie set, we default
|
||||
* to the station locale.
|
||||
*
|
||||
* When the user logs in, the value set in the login form will be passed
|
||||
* into the airtime_locale cookie. This cookie is also updated when
|
||||
* a user updates their user settings.
|
||||
*/
|
||||
public static function getUserLocale() {
|
||||
$request = Zend_Controller_Front::getInstance()->getRequest();
|
||||
$locale = $request->getCookie('airtime_locale', Application_Model_Preference::GetLocale());
|
||||
return $locale;
|
||||
}
|
||||
|
||||
}
|
||||
|
38
legacy/application/models/LoginAttempts.php
Normal file
38
legacy/application/models/LoginAttempts.php
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
class Application_Model_LoginAttempts
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public static function increaseAttempts($ip)
|
||||
{
|
||||
$sql = "select count(*) from cc_login_attempts WHERE ip= :ip";
|
||||
$res = Application_Common_Database::prepareAndExecute($sql, array(':ip'=>$ip), Application_Common_Database::ALL);
|
||||
if ($res) {
|
||||
$sql = "UPDATE cc_login_attempts SET attempts=attempts+1 WHERE ip= :ip";
|
||||
Application_Common_Database::prepareAndExecute($sql, array(':ip'=>$ip), Application_Common_Database::EXECUTE);
|
||||
} else {
|
||||
$sql = "INSERT INTO cc_login_attempts (ip, attempts) values (':ip', '1')";
|
||||
Application_Common_Database::prepareAndExecute($sql, array(':ip'=>$ip), Application_Common_Database::EXECUTE);
|
||||
}
|
||||
}
|
||||
|
||||
public static function getAttempts($ip)
|
||||
{
|
||||
$sql = "select attempts from cc_login_attempts WHERE ip= :ip";
|
||||
$res = Application_Common_Database::prepareAndExecute($sql, array(':ip'=>$ip), Application_Common_Database::ALL);
|
||||
|
||||
return $res ? $res : 0;
|
||||
}
|
||||
|
||||
public static function resetAttempts($ip)
|
||||
{
|
||||
$sql = "select count(*) from cc_login_attempts WHERE ip= :ip";
|
||||
$res = Application_Common_Database::prepareAndExecute($sql, array(':ip'=>$ip), Application_Common_Database::COLUMN);
|
||||
if ($res > 0) {
|
||||
$sql = "DELETE FROM cc_login_attempts WHERE ip= :ip";
|
||||
Application_Common_Database::prepareAndExecute($sql, array(':ip'=>$ip), Application_Common_Database::EXECUTE);
|
||||
}
|
||||
}
|
||||
}
|
468
legacy/application/models/MusicDir.php
Normal file
468
legacy/application/models/MusicDir.php
Normal file
|
@ -0,0 +1,468 @@
|
|||
<?php
|
||||
|
||||
class NestedDirectoryException extends Exception { }
|
||||
|
||||
class Application_Model_MusicDir
|
||||
{
|
||||
/**
|
||||
* @holds propel database object
|
||||
*/
|
||||
private $_dir;
|
||||
|
||||
public function __construct($dir)
|
||||
{
|
||||
$this->_dir = $dir;
|
||||
}
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return $this->_dir->getId();
|
||||
}
|
||||
|
||||
public function getType()
|
||||
{
|
||||
return $this->_dir->getType();
|
||||
}
|
||||
|
||||
public function setType($type)
|
||||
{
|
||||
$this->_dir->setType($type);
|
||||
}
|
||||
|
||||
public function getDirectory()
|
||||
{
|
||||
return $this->_dir->getDirectory();
|
||||
}
|
||||
|
||||
public function setDirectory($dir)
|
||||
{
|
||||
$this->_dir->setDirectory($dir);
|
||||
$this->_dir->save();
|
||||
}
|
||||
|
||||
public function setExistsFlag($flag)
|
||||
{
|
||||
$this->_dir->setExists($flag);
|
||||
$this->_dir->save();
|
||||
}
|
||||
|
||||
public function setWatchedFlag($flag)
|
||||
{
|
||||
$this->_dir->setWatched($flag);
|
||||
$this->_dir->save();
|
||||
}
|
||||
|
||||
public function getWatchedFlag()
|
||||
{
|
||||
return $this->_dir->getWatched();
|
||||
}
|
||||
|
||||
public function getExistsFlag()
|
||||
{
|
||||
return $this->_dir->getExists();
|
||||
}
|
||||
|
||||
/**
|
||||
* There are 2 cases where this function can be called.
|
||||
* 1. When watched dir was removed
|
||||
* 2. When some dir was watched, but it was unmounted
|
||||
*
|
||||
* In case of 1, $userAddedWatchedDir should be true
|
||||
* In case of 2, $userAddedWatchedDir should be false
|
||||
*
|
||||
* When $userAddedWatchedDir is true, it will set "Watched" flag to false
|
||||
* otherwise, it will set "Exists" flag to true
|
||||
*/
|
||||
public function remove($userAddedWatchedDir=true)
|
||||
{
|
||||
|
||||
$music_dir_id = $this->getId();
|
||||
|
||||
$sql = <<<SQL
|
||||
SELECT DISTINCT s.instance_id
|
||||
FROM cc_music_dirs AS md
|
||||
LEFT JOIN cc_files AS f ON f.directory = md.id
|
||||
RIGHT JOIN cc_schedule AS s ON s.file_id = f.id
|
||||
WHERE md.id = :musicDirId;
|
||||
SQL;
|
||||
$show_instances = Application_Common_Database::prepareAndExecute($sql,
|
||||
array( ':musicDirId' => $music_dir_id ), 'all' );
|
||||
|
||||
// get all the files on this dir
|
||||
$sql = <<<SQL
|
||||
UPDATE cc_files
|
||||
SET file_exists = 'f'
|
||||
WHERE id IN
|
||||
(SELECT f.id
|
||||
FROM cc_music_dirs AS md
|
||||
LEFT JOIN cc_files AS f ON f.directory = md.id
|
||||
WHERE md.id = :musicDirId);
|
||||
SQL;
|
||||
|
||||
$affected = Application_Common_Database::prepareAndExecute($sql,
|
||||
array( ':musicDirId' => $music_dir_id ), 'all');
|
||||
|
||||
// set RemovedFlag to true
|
||||
if ($userAddedWatchedDir) {
|
||||
self::setWatchedFlag(false);
|
||||
} else {
|
||||
self::setExistsFlag(false);
|
||||
}
|
||||
//$res = $this->_dir->delete();
|
||||
|
||||
foreach ($show_instances as $show_instance_row) {
|
||||
$temp_show = new Application_Model_ShowInstance($show_instance_row["instance_id"]);
|
||||
$temp_show->updateScheduledTime();
|
||||
}
|
||||
Application_Model_RabbitMq::PushSchedule();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if p_dir1 is the ancestor of p_dir2. Returns
|
||||
* true if it is the ancestor, false otherwise. Note that
|
||||
* /home/user is considered the ancestor of /home/user
|
||||
*
|
||||
* @param string $p_dir1
|
||||
* The potential ancestor directory.
|
||||
* @param string $p_dir2
|
||||
* The potential descendent directory.
|
||||
* @return boolean
|
||||
* Returns true if it is the ancestor, false otherwise.
|
||||
*/
|
||||
private static function isAncestorDir($p_dir1, $p_dir2)
|
||||
{
|
||||
if (strlen($p_dir1) > strlen($p_dir2)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return substr($p_dir2, 0, strlen($p_dir1)) == $p_dir1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the path provided is a valid path. A valid path
|
||||
* is defined as not being nested within an existing watched directory,
|
||||
* or vice-versa. Throws a NestedDirectoryException if invalid.
|
||||
*
|
||||
* @param string $p_path
|
||||
* The path we want to validate
|
||||
* @return void
|
||||
*/
|
||||
public static function isPathValid($p_path)
|
||||
{
|
||||
$dirs = self::getWatchedDirs();
|
||||
$dirs[] = self::getStorDir();
|
||||
|
||||
foreach ($dirs as $dirObj) {
|
||||
$dir = $dirObj->getDirectory();
|
||||
$diff = strlen($dir) - strlen($p_path);
|
||||
if ($diff == 0) {
|
||||
if ($dir == $p_path) {
|
||||
throw new NestedDirectoryException(sprintf(_("%s is already watched."), $p_path));
|
||||
}
|
||||
} elseif ($diff > 0) {
|
||||
if (self::isAncestorDir($p_path, $dir)) {
|
||||
throw new NestedDirectoryException(sprintf(_("%s contains nested watched directory: %s"), $p_path, $dir));
|
||||
}
|
||||
} else { /* diff < 0*/
|
||||
if (self::isAncestorDir($dir, $p_path)) {
|
||||
throw new NestedDirectoryException(sprintf(_("%s is nested within existing watched directory: %s"), $p_path, $dir));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** There are 2 cases where this function can be called.
|
||||
* 1. When watched dir was added
|
||||
* 2. When some dir was watched, but it was unmounted somehow, but gets mounted again
|
||||
*
|
||||
* In case of 1, $userAddedWatchedDir should be true
|
||||
* In case of 2, $userAddedWatchedDir should be false
|
||||
*
|
||||
* When $userAddedWatchedDir is true, it will set "Removed" flag to false
|
||||
* otherwise, it will set "Exists" flag to true
|
||||
*
|
||||
* @param $nestedWatch - if true, bypass path check, and Watched to false
|
||||
**/
|
||||
public static function addDir($p_path, $p_type, $userAddedWatchedDir=true, $nestedWatch=false)
|
||||
{
|
||||
if (!is_dir($p_path)) {
|
||||
return array("code"=>2, "error"=>sprintf(_("%s is not a valid directory."), $p_path));
|
||||
}
|
||||
$real_path = Application_Common_OsPath::normpath($p_path)."/";
|
||||
if ($real_path != "/") {
|
||||
$p_path = $real_path;
|
||||
}
|
||||
|
||||
$exist_dir = self::getDirByPath($p_path);
|
||||
|
||||
if (is_null($exist_dir)) {
|
||||
$temp_dir = new CcMusicDirs();
|
||||
$dir = new Application_Model_MusicDir($temp_dir);
|
||||
} else {
|
||||
$dir = $exist_dir;
|
||||
}
|
||||
|
||||
$dir->setType($p_type);
|
||||
$p_path = Application_Common_OsPath::normpath($p_path)."/";
|
||||
|
||||
try {
|
||||
/* isPathValid() checks if path is a substring or a superstring of an
|
||||
* existing dir and if not, throws NestedDirectoryException */
|
||||
if (!$nestedWatch) {
|
||||
self::isPathValid($p_path);
|
||||
}
|
||||
if ($userAddedWatchedDir) {
|
||||
$dir->setWatchedFlag(true);
|
||||
} else {
|
||||
if ($nestedWatch) {
|
||||
$dir->setWatchedFlag(false);
|
||||
}
|
||||
$dir->setExistsFlag(true);
|
||||
}
|
||||
$dir->setDirectory($p_path);
|
||||
|
||||
return array("code"=>0);
|
||||
} catch (NestedDirectoryException $nde) {
|
||||
$msg = $nde->getMessage();
|
||||
|
||||
return array("code"=>1, "error"=>"$msg");
|
||||
} catch (Exception $e) {
|
||||
return array("code"=>1,
|
||||
"error" => sprintf(
|
||||
_("%s is already set as the current storage dir or in the".
|
||||
" watched folders list"),
|
||||
$p_path
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** There are 2 cases where this function can be called.
|
||||
* 1. When watched dir was added
|
||||
* 2. When some dir was watched, but it was unmounted somehow, but gets mounted again
|
||||
*
|
||||
* In case of 1, $userAddedWatchedDir should be true
|
||||
* In case of 2, $userAddedWatchedDir should be false
|
||||
*
|
||||
* When $userAddedWatchedDir is true, it will set "Watched" flag to true
|
||||
* otherwise, it will set "Exists" flag to true
|
||||
**/
|
||||
public static function addWatchedDir($p_path, $userAddedWatchedDir=true, $nestedWatch=false)
|
||||
{
|
||||
$res = self::addDir($p_path, "watched", $userAddedWatchedDir, $nestedWatch);
|
||||
|
||||
if ($res['code'] != 0) { return $res; }
|
||||
|
||||
//convert "linked" files (Airtime <= 1.8.2) to watched files.
|
||||
$propel_link_dir = CcMusicDirsQuery::create()
|
||||
->filterByType('link')
|
||||
->findOne();
|
||||
|
||||
//see if any linked files exist.
|
||||
if (isset($propel_link_dir)) {
|
||||
|
||||
//newly added watched directory object
|
||||
$propel_new_watch = CcMusicDirsQuery::create()
|
||||
->filterByDirectory(Application_Common_OsPath::normpath($p_path)."/")
|
||||
->findOne();
|
||||
|
||||
//any files of the deprecated "link" type.
|
||||
$link_files = CcFilesQuery::create()
|
||||
->setFormatter(ModelCriteria::FORMAT_ON_DEMAND)
|
||||
->filterByDbDirectory($propel_link_dir->getId())
|
||||
->find();
|
||||
|
||||
$newly_watched_dir = $propel_new_watch->getDirectory();
|
||||
|
||||
foreach ($link_files as $link_file) {
|
||||
$link_filepath = $link_file->getDbFilepath();
|
||||
|
||||
//convert "link" file into a watched file.
|
||||
if ((strlen($newly_watched_dir) < strlen($link_filepath)) && (substr($link_filepath, 0, strlen($newly_watched_dir)) === $newly_watched_dir)) {
|
||||
|
||||
//get the filepath path not including the watched directory.
|
||||
$sub_link_filepath = substr($link_filepath, strlen($newly_watched_dir));
|
||||
|
||||
$link_file->setDbDirectory($propel_new_watch->getId());
|
||||
$link_file->setDbFilepath($sub_link_filepath);
|
||||
$link_file->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$data = array();
|
||||
$data["directory"] = $p_path;
|
||||
Application_Model_RabbitMq::SendMessageToMediaMonitor("new_watch", $data);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
public static function getDirByPK($pk)
|
||||
{
|
||||
$dir = CcMusicDirsQuery::create()->findPK($pk);
|
||||
if (!$dir) {
|
||||
return null;
|
||||
}
|
||||
$mus_dir = new Application_Model_MusicDir($dir);
|
||||
|
||||
return $mus_dir;
|
||||
}
|
||||
|
||||
public static function getDirByPath($p_path)
|
||||
{
|
||||
$dir = CcMusicDirsQuery::create()
|
||||
->filterByDirectory($p_path)
|
||||
->findOne();
|
||||
if ($dir == NULL) {
|
||||
return null;
|
||||
} else {
|
||||
$mus_dir = new Application_Model_MusicDir($dir);
|
||||
|
||||
return $mus_dir;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Search and returns watched dirs
|
||||
*
|
||||
* @param $exists search condition with exists flag
|
||||
* @param $watched search condition with watched flag
|
||||
*/
|
||||
public static function getWatchedDirs($exists=true, $watched=true)
|
||||
{
|
||||
$result = array();
|
||||
|
||||
$dirs = CcMusicDirsQuery::create()
|
||||
->filterByType("watched");
|
||||
if ($exists !== null) {
|
||||
$dirs = $dirs->filterByExists($exists);
|
||||
}
|
||||
if ($watched !== null) {
|
||||
$dirs = $dirs->filterByWatched($watched);
|
||||
}
|
||||
$dirs = $dirs->find();
|
||||
|
||||
foreach ($dirs as $dir) {
|
||||
$result[] = new Application_Model_MusicDir($dir);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function getStorDir()
|
||||
{
|
||||
$dir = CcMusicDirsQuery::create()
|
||||
->filterByType("stor")
|
||||
->findOne();
|
||||
|
||||
$mus_dir = new Application_Model_MusicDir($dir);
|
||||
|
||||
return $mus_dir;
|
||||
}
|
||||
|
||||
public static function setStorDir($p_dir)
|
||||
{
|
||||
// we want to be consistent when storing dir path.
|
||||
// path should always ends with trailing '/'
|
||||
$p_dir = Application_Common_OsPath::normpath($p_dir)."/";
|
||||
if (!is_dir($p_dir)) {
|
||||
return array("code"=>2, "error"=>sprintf(_("%s is not a valid directory."), $p_dir));
|
||||
} elseif (Application_Model_Preference::GetImportTimestamp()+10 > time()) {
|
||||
return array("code"=>3, "error"=>"Airtime is currently importing files. Please wait until this is complete before changing the storage directory.");
|
||||
}
|
||||
$dir = self::getStorDir();
|
||||
// if $p_dir doesn't exist in DB
|
||||
$exist = $dir->getDirByPath($p_dir);
|
||||
if ($exist == NULL) {
|
||||
$dir->setDirectory($p_dir);
|
||||
$dirId = $dir->getId();
|
||||
$data = array();
|
||||
$data["directory"] = $p_dir;
|
||||
$data["dir_id"] = $dirId;
|
||||
Application_Model_RabbitMq::SendMessageToMediaMonitor("change_stor", $data);
|
||||
|
||||
return array("code"=>0);
|
||||
} else {
|
||||
return array("code"=>1,
|
||||
"error"=>sprintf(_("%s is already set as the current storage dir or in the watched folders list."), $p_dir));
|
||||
}
|
||||
}
|
||||
|
||||
public static function getWatchedDirFromFilepath($p_filepath)
|
||||
{
|
||||
$dirs = CcMusicDirsQuery::create()
|
||||
->filterByType(array("watched", "stor"))
|
||||
->filterByExists(true)
|
||||
->filterByWatched(true)
|
||||
->find();
|
||||
|
||||
foreach ($dirs as $dir) {
|
||||
$directory = $dir->getDirectory();
|
||||
if (substr($p_filepath, 0, strlen($directory)) === $directory) {
|
||||
$mus_dir = new Application_Model_MusicDir($dir);
|
||||
|
||||
return $mus_dir;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/** There are 2 cases where this function can be called.
|
||||
* 1. When watched dir was removed
|
||||
* 2. When some dir was watched, but it was unmounted
|
||||
*
|
||||
* In case of 1, $userAddedWatchedDir should be true
|
||||
* In case of 2, $userAddedWatchedDir should be false
|
||||
*
|
||||
* When $userAddedWatchedDir is true, it will set "Watched" flag to false
|
||||
* otherwise, it will set "Exists" flag to true
|
||||
**/
|
||||
public static function removeWatchedDir($p_dir, $userAddedWatchedDir=true)
|
||||
{
|
||||
//make sure that $p_dir has a trailing "/"
|
||||
$real_path = Application_Common_OsPath::normpath($p_dir)."/";
|
||||
if ($real_path != "/") {
|
||||
$p_dir = $real_path;
|
||||
}
|
||||
$dir = Application_Model_MusicDir::getDirByPath($p_dir);
|
||||
if (is_null($dir)) {
|
||||
return array("code"=>1, "error"=>sprintf(_("%s doesn't exist in the watched list."), $p_dir));
|
||||
} else {
|
||||
$dir->remove($userAddedWatchedDir);
|
||||
$data = array();
|
||||
$data["directory"] = $p_dir;
|
||||
Application_Model_RabbitMq::SendMessageToMediaMonitor("remove_watch", $data);
|
||||
|
||||
return array("code"=>0);
|
||||
}
|
||||
}
|
||||
|
||||
public static function splitFilePath($p_filepath)
|
||||
{
|
||||
$mus_dir = self::getWatchedDirFromFilepath($p_filepath);
|
||||
|
||||
if (is_null($mus_dir)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$length_dir = strlen($mus_dir->getDirectory());
|
||||
$fp = substr($p_filepath, $length_dir);
|
||||
|
||||
return array($mus_dir->getDirectory(), trim($fp));
|
||||
}
|
||||
|
||||
|
||||
public function unhideFiles()
|
||||
{
|
||||
$files = $this->_dir->getCcFiless();
|
||||
$hid = 0;
|
||||
foreach ($files as $file) {
|
||||
$hid++;
|
||||
$file->setDbHidden(false);
|
||||
$file->save();
|
||||
}
|
||||
Logging::info("unhide '$hid' files");
|
||||
}
|
||||
}
|
1158
legacy/application/models/Playlist.php
Normal file
1158
legacy/application/models/Playlist.php
Normal file
File diff suppressed because it is too large
Load diff
1590
legacy/application/models/Preference.php
Normal file
1590
legacy/application/models/Preference.php
Normal file
File diff suppressed because it is too large
Load diff
132
legacy/application/models/RabbitMq.php
Normal file
132
legacy/application/models/RabbitMq.php
Normal file
|
@ -0,0 +1,132 @@
|
|||
<?php
|
||||
|
||||
class Application_Model_RabbitMq
|
||||
{
|
||||
public static $doPush = false;
|
||||
|
||||
/**
|
||||
* Sets a flag to push the schedule at the end of the request.
|
||||
*/
|
||||
public static function PushSchedule()
|
||||
{
|
||||
self::$doPush = true;
|
||||
}
|
||||
|
||||
private static function sendMessage($exchange, $exchangeType, $autoDeleteExchange, $data, $queue="")
|
||||
{
|
||||
$CC_CONFIG = Config::getConfig();
|
||||
|
||||
$conn = new \PhpAmqpLib\Connection\AMQPConnection($CC_CONFIG["rabbitmq"]["host"],
|
||||
$CC_CONFIG["rabbitmq"]["port"],
|
||||
$CC_CONFIG["rabbitmq"]["user"],
|
||||
$CC_CONFIG["rabbitmq"]["password"],
|
||||
$CC_CONFIG["rabbitmq"]["vhost"]);
|
||||
|
||||
if (!isset($conn)) {
|
||||
throw new Exception("Cannot connect to RabbitMQ server");
|
||||
}
|
||||
|
||||
$channel = $conn->channel();
|
||||
$channel->access_request($CC_CONFIG["rabbitmq"]["vhost"], false, false,
|
||||
true, true);
|
||||
|
||||
//I'm pretty sure we DON'T want to autodelete ANY exchanges but I'm keeping the code
|
||||
//the way it is just so I don't accidentally break anything when I add the Analyzer code in. -- Albert, March 13, 2014
|
||||
$channel->exchange_declare($exchange, $exchangeType, false, true, $autoDeleteExchange);
|
||||
|
||||
$msg = new \PhpAmqpLib\Message\AMQPMessage($data, array('content_type' => 'text/plain'));
|
||||
|
||||
$channel->basic_publish($msg, $exchange);
|
||||
$channel->close();
|
||||
$conn->close();
|
||||
}
|
||||
|
||||
public static function SendMessageToPypo($event_type, $md)
|
||||
{
|
||||
$md["event_type"] = $event_type;
|
||||
|
||||
$exchange = 'airtime-pypo';
|
||||
$data = json_encode($md, JSON_FORCE_OBJECT);
|
||||
self::sendMessage($exchange, 'direct', true, $data);
|
||||
}
|
||||
|
||||
public static function SendMessageToMediaMonitor($event_type, $md)
|
||||
{
|
||||
$md["event_type"] = $event_type;
|
||||
|
||||
$exchange = 'airtime-analyzer';
|
||||
$data = json_encode($md);
|
||||
self::sendMessage($exchange, 'direct', true, $data);
|
||||
}
|
||||
|
||||
public static function SendMessageToShowRecorder($event_type)
|
||||
{
|
||||
$exchange = 'airtime-pypo';
|
||||
|
||||
$now = new DateTime("@".time()); //in UTC timezone
|
||||
$end_timestamp = new DateTime("@".(time() + 3600*2)); //in UTC timezone
|
||||
|
||||
$temp = array();
|
||||
$temp['event_type'] = $event_type;
|
||||
$temp['server_timezone'] = Application_Model_Preference::GetTimezone();
|
||||
if ($event_type == "update_recorder_schedule") {
|
||||
$temp['shows'] = Application_Model_Show::getShows($now,
|
||||
$end_timestamp, $onlyRecord=true);
|
||||
}
|
||||
$data = json_encode($temp);
|
||||
|
||||
self::sendMessage($exchange, 'direct', true, $data);
|
||||
}
|
||||
|
||||
public static function SendMessageToAnalyzer($tmpFilePath, $importedStorageDirectory, $originalFilename,
|
||||
$callbackUrl, $apiKey, $storageBackend, $filePrefix)
|
||||
{
|
||||
$config = Config::getConfig();
|
||||
|
||||
$conn = new \PhpAmqpLib\Connection\AMQPConnection($config["rabbitmq"]["host"],
|
||||
$config["rabbitmq"]["port"],
|
||||
$config["rabbitmq"]["user"],
|
||||
$config["rabbitmq"]["password"],
|
||||
$config["rabbitmq"]["vhost"]);
|
||||
|
||||
$exchange = 'airtime-uploads';
|
||||
$exchangeType = 'topic';
|
||||
$queue = 'airtime-uploads';
|
||||
$autoDeleteExchange = false;
|
||||
$data['tmp_file_path'] = $tmpFilePath;
|
||||
$data['storage_backend'] = $storageBackend;
|
||||
$data['import_directory'] = $importedStorageDirectory;
|
||||
$data['original_filename'] = $originalFilename;
|
||||
$data['callback_url'] = $callbackUrl;
|
||||
$data['api_key'] = $apiKey;
|
||||
|
||||
// We add a prefix to the resource name so files are not all placed
|
||||
// under the root folder. We do this in case we need to restore a
|
||||
// customer's file/s; File restoration is done via the S3 Browser
|
||||
// client. The client will hang if there are too many files under the
|
||||
// same folder.
|
||||
$data['file_prefix'] = $filePrefix;
|
||||
|
||||
$jsonData = json_encode($data);
|
||||
//self::sendMessage($exchange, 'topic', false, $jsonData, 'airtime-uploads');
|
||||
|
||||
if (!isset($conn)) {
|
||||
throw new Exception("Cannot connect to RabbitMQ server");
|
||||
}
|
||||
|
||||
$channel = $conn->channel();
|
||||
$channel->access_request($config["rabbitmq"]["vhost"], false, false,
|
||||
true, true);
|
||||
|
||||
//I'm pretty sure we DON'T want to autodelete ANY exchanges but I'm keeping the code
|
||||
//the way it is just so I don't accidentally break anything when I add the Analyzer code in. -- Albert, March 13, 2014
|
||||
$channel->exchange_declare($exchange, $exchangeType, false, true, $autoDeleteExchange);
|
||||
|
||||
$msg = new \PhpAmqpLib\Message\AMQPMessage($jsonData, array('content_type' => 'text/plain'));
|
||||
|
||||
$channel->basic_publish($msg, $exchange);
|
||||
$channel->close();
|
||||
$conn->close();
|
||||
|
||||
}
|
||||
}
|
1266
legacy/application/models/Schedule.php
Normal file
1266
legacy/application/models/Schedule.php
Normal file
File diff suppressed because it is too large
Load diff
1375
legacy/application/models/Scheduler.php
Normal file
1375
legacy/application/models/Scheduler.php
Normal file
File diff suppressed because it is too large
Load diff
40
legacy/application/models/ServiceRegister.php
Normal file
40
legacy/application/models/ServiceRegister.php
Normal file
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
class Application_Model_ServiceRegister
|
||||
{
|
||||
public static function GetRemoteIpAddr()
|
||||
{
|
||||
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
|
||||
//check ip from share internet
|
||||
$ip=$_SERVER['HTTP_CLIENT_IP'];
|
||||
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
|
||||
//to check ip is pass from proxy
|
||||
$ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
|
||||
} else {
|
||||
$ip=$_SERVER['REMOTE_ADDR'];
|
||||
}
|
||||
|
||||
return $ip;
|
||||
}
|
||||
|
||||
public static function Register($p_componentName, $p_ipAddress)
|
||||
{
|
||||
$component = CcServiceRegisterQuery::create()->findOneByDbName($p_componentName);
|
||||
|
||||
if (is_null($component)) {
|
||||
$component = new CcServiceRegister();
|
||||
$component->setDbName($p_componentName);
|
||||
}
|
||||
|
||||
// Need to convert ipv6 to ipv4 since Monit server does not appear
|
||||
// to allow access via an ipv6 address.
|
||||
// http://[::1]:2812 does not respond.
|
||||
// Bug: http://savannah.nongnu.org/bugs/?27608
|
||||
if ($p_ipAddress == "::1") {
|
||||
$p_ipAddress = "127.0.0.1";
|
||||
}
|
||||
|
||||
$component->setDbIp($p_ipAddress);
|
||||
$component->save();
|
||||
}
|
||||
|
||||
}
|
1610
legacy/application/models/Show.php
Normal file
1610
legacy/application/models/Show.php
Normal file
File diff suppressed because it is too large
Load diff
492
legacy/application/models/ShowBuilder.php
Normal file
492
legacy/application/models/ShowBuilder.php
Normal file
|
@ -0,0 +1,492 @@
|
|||
<?php
|
||||
|
||||
class Application_Model_ShowBuilder
|
||||
{
|
||||
private $timezone;
|
||||
|
||||
//in UTC timezone
|
||||
private $startDT;
|
||||
//in UTC timezone
|
||||
private $endDT;
|
||||
|
||||
private $user;
|
||||
private $opts;
|
||||
|
||||
private $pos;
|
||||
private $contentDT;
|
||||
private $epoch_now;
|
||||
private $currentShow;
|
||||
private $currentShowId;
|
||||
|
||||
private $showInstances = array();
|
||||
|
||||
private $defaultRowArray = array(
|
||||
"header" => false,
|
||||
"footer" => false,
|
||||
"empty" => false,
|
||||
"allowed" => false,
|
||||
"linked_allowed" => true,
|
||||
"id" => 0,
|
||||
"instance" => "",
|
||||
"starts" => "",
|
||||
"ends" => "",
|
||||
"runtime" => "",
|
||||
"title" => "",
|
||||
"creator" => "",
|
||||
"album" => "",
|
||||
"timestamp" => null,
|
||||
"cuein" => "",
|
||||
"cueout" => "",
|
||||
"fadein" => "",
|
||||
"fadeout" => "",
|
||||
"image" => false,
|
||||
"mime" => null,
|
||||
"color" => "", //in hex without the '#' sign.
|
||||
"backgroundColor" => "", //in hex without the '#' sign.
|
||||
);
|
||||
|
||||
/*
|
||||
* @param DateTime $p_startsDT
|
||||
* @param DateTime $p_endsDT
|
||||
*/
|
||||
public function __construct($p_startDT, $p_endDT, $p_opts)
|
||||
{
|
||||
$this->startDT = $p_startDT;
|
||||
$this->endDT = $p_endDT;
|
||||
$this->timezone = Application_Model_Preference::GetUserTimezone();
|
||||
$this->user = Application_Model_User::getCurrentUser();
|
||||
$this->opts = $p_opts;
|
||||
$this->epoch_now = floatval(microtime(true));
|
||||
$this->currentShow = false;
|
||||
}
|
||||
|
||||
private function getUsersShows()
|
||||
{
|
||||
$shows = array();
|
||||
|
||||
$host_shows = CcShowHostsQuery::create()
|
||||
->setFormatter(ModelCriteria::FORMAT_ON_DEMAND)
|
||||
->filterByDbHost($this->user->getId())
|
||||
->find();
|
||||
|
||||
foreach ($host_shows as $host_show) {
|
||||
$shows[] = $host_show->getDbShow();
|
||||
}
|
||||
|
||||
return $shows;
|
||||
}
|
||||
|
||||
//check to see if this row should be editable by the user.
|
||||
private function isAllowed($p_item, &$row)
|
||||
{
|
||||
//cannot schedule in a recorded show.
|
||||
if (intval($p_item["si_record"]) === 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->currentShow) {
|
||||
$this->currentShowId = $p_item["show_id"];
|
||||
}
|
||||
|
||||
/* If any linked show instance is currently playing
|
||||
* we have to disable editing, or else the times
|
||||
* will not make sense for shows scheduled in the future
|
||||
*/
|
||||
if ($p_item["linked"] && $p_item["show_id"] == $this->currentShowId) {
|
||||
$row["linked_allowed"] = false;
|
||||
}
|
||||
|
||||
if ($this->user->canSchedule($p_item["show_id"]) == true) {
|
||||
$row["allowed"] = true;
|
||||
}
|
||||
}
|
||||
|
||||
private function getItemColor($p_item, &$row)
|
||||
{
|
||||
$defaultColor = "ffffff";
|
||||
$defaultBackground = DEFAULT_SHOW_COLOR;
|
||||
|
||||
$color = $p_item["show_color"];
|
||||
if ($color === '') {
|
||||
$color = $defaultColor;
|
||||
}
|
||||
$backgroundColor = $p_item["show_background_color"];
|
||||
if ($backgroundColor === '') {
|
||||
$backgroundColor = $defaultBackground;
|
||||
}
|
||||
|
||||
$row["color"] = $color;
|
||||
$row["backgroundColor"] = $backgroundColor;
|
||||
}
|
||||
|
||||
//information about whether a track is inside|boundary|outside a show.
|
||||
private function getItemStatus($p_item, &$row)
|
||||
{
|
||||
$row["status"] = intval($p_item["playout_status"]);
|
||||
}
|
||||
|
||||
private function getRowTimestamp($p_item, &$row)
|
||||
{
|
||||
if (is_null($p_item["si_last_scheduled"])) {
|
||||
$ts = 0;
|
||||
} else {
|
||||
$dt = new DateTime($p_item["si_last_scheduled"], new DateTimeZone("UTC"));
|
||||
$ts = intval($dt->format("U"));
|
||||
}
|
||||
$row["timestamp"] = $ts;
|
||||
}
|
||||
|
||||
/*
|
||||
* marks a row's status.
|
||||
* 0 = past
|
||||
* 1 = current
|
||||
* 2 = future
|
||||
* TODO : change all of the above to real constants -- RG
|
||||
*/
|
||||
private function getScheduledStatus($p_epochItemStart, $p_epochItemEnd, &$row)
|
||||
{
|
||||
if ($row["footer"] === true && $this->epoch_now > $p_epochItemStart &&
|
||||
$this->epoch_now > $p_epochItemEnd) {
|
||||
$row["scheduled"] = 0;
|
||||
} elseif ($row["footer"] === true && $this->epoch_now < $p_epochItemEnd) {
|
||||
$row["scheduled"] = 2;
|
||||
} elseif ($row["header"] === true && $this->epoch_now >= $p_epochItemStart) {
|
||||
$row["scheduled"] = 0;
|
||||
} elseif ($row["header"] === true && $this->epoch_now < $p_epochItemEnd) {
|
||||
$row["scheduled"] = 2;
|
||||
}
|
||||
|
||||
//item is in the past.
|
||||
else if ($this->epoch_now > $p_epochItemEnd) {
|
||||
$row["scheduled"] = 0;
|
||||
}
|
||||
|
||||
//item is the currently scheduled item.
|
||||
else if ($this->epoch_now >= $p_epochItemStart && $this->epoch_now < $p_epochItemEnd) {
|
||||
$row["scheduled"] = 1;
|
||||
//how many seconds the view should wait to redraw itself.
|
||||
$row["refresh"] = $p_epochItemEnd - $this->epoch_now;
|
||||
}
|
||||
|
||||
//item is in the future.
|
||||
else if ($this->epoch_now < $p_epochItemStart) {
|
||||
$row["scheduled"] = 2;
|
||||
} else {
|
||||
Logging::warn("No-op? is this what should happen...printing
|
||||
debug just in case");
|
||||
$d = array(
|
||||
'$p_epochItemStart' => $p_epochItemStart,
|
||||
'$p_epochItemEnd' => $p_epochItemEnd,
|
||||
'$row' => $row);
|
||||
Logging::warn($d);
|
||||
}
|
||||
}
|
||||
|
||||
private function makeHeaderRow($p_item)
|
||||
{
|
||||
$row = $this->defaultRowArray;
|
||||
//$this->isAllowed($p_item, $row);
|
||||
$this->getRowTimestamp($p_item, $row);
|
||||
$this->getItemColor($p_item, $row);
|
||||
|
||||
$showStartDT = new DateTime($p_item["si_starts"], new DateTimeZone("UTC"));
|
||||
$showStartDT->setTimezone(new DateTimeZone($this->timezone));
|
||||
$startsEpoch = floatval($showStartDT->format("U.u"));
|
||||
$showEndDT = new DateTime($p_item["si_ends"], new DateTimeZone("UTC"));
|
||||
$showEndDT->setTimezone(new DateTimeZone($this->timezone));
|
||||
$endsEpoch = floatval($showEndDT->format("U.u"));
|
||||
|
||||
//is a rebroadcast show
|
||||
if (intval($p_item["si_rebroadcast"]) === 1) {
|
||||
$row["rebroadcast"] = true;
|
||||
|
||||
$parentInstance = CcShowInstancesQuery::create()->findPk($p_item["parent_show"]);
|
||||
$name = $parentInstance->getCcShow()->getDbName();
|
||||
$dt = $parentInstance->getDbStarts(null);
|
||||
$dt->setTimezone(new DateTimeZone($this->timezone));
|
||||
$time = $dt->format("Y-m-d H:i");
|
||||
|
||||
$row["rebroadcast_title"] = sprintf(_("Rebroadcast of %s from %s"), $name, $time);
|
||||
} elseif (intval($p_item["si_record"]) === 1) {
|
||||
$row["record"] = true;
|
||||
}
|
||||
|
||||
if ($startsEpoch < $this->epoch_now && $endsEpoch > $this->epoch_now) {
|
||||
$row["currentShow"] = true;
|
||||
$this->currentShow = true;
|
||||
} else {
|
||||
$this->currentShow = false;
|
||||
}
|
||||
|
||||
$this->isAllowed($p_item, $row);
|
||||
|
||||
$row["header"] = true;
|
||||
$row["starts"] = $showStartDT->format("Y-m-d H:i");
|
||||
$row["startDate"] = $showStartDT->format("Y-m-d");
|
||||
$row["startTime"] = $showStartDT->format("H:i");
|
||||
$row["refresh"] = floatval($showStartDT->format("U.u")) - $this->epoch_now;
|
||||
$row["ends"] = $showEndDT->format("Y-m-d H:i");
|
||||
$row["endDate"] = $showEndDT->format("Y-m-d");
|
||||
$row["endTime"] = $showEndDT->format("H:i");
|
||||
$row["duration"] = floatval($showEndDT->format("U.u")) - floatval($showStartDT->format("U.u"));
|
||||
$row["title"] = htmlspecialchars($p_item["show_name"]);
|
||||
$row["instance"] = intval($p_item["si_id"]);
|
||||
$row["image"] = '';
|
||||
|
||||
$this->getScheduledStatus($startsEpoch, $endsEpoch, $row);
|
||||
|
||||
$this->contentDT = $showStartDT;
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
private function makeScheduledItemRow($p_item)
|
||||
{
|
||||
$row = $this->defaultRowArray;
|
||||
|
||||
if (isset($p_item["sched_starts"])) {
|
||||
|
||||
$schedStartDT = new DateTime($p_item["sched_starts"],
|
||||
new DateTimeZone("UTC"));
|
||||
$schedStartDT->setTimezone(new DateTimeZone($this->timezone));
|
||||
$schedEndDT = new DateTime($p_item["sched_ends"],
|
||||
new DateTimeZone("UTC"));
|
||||
$schedEndDT->setTimezone(new DateTimeZone($this->timezone));
|
||||
$showEndDT = new DateTime($p_item["si_ends"], new DateTimeZone("UTC"));
|
||||
|
||||
$this->getItemStatus($p_item, $row);
|
||||
|
||||
$startsEpoch = floatval($schedStartDT->format("U.u"));
|
||||
$endsEpoch = floatval($schedEndDT->format("U.u"));
|
||||
$showEndEpoch = floatval($showEndDT->format("U.u"));
|
||||
|
||||
//don't want an overbooked item to stay marked as current.
|
||||
$this->getScheduledStatus($startsEpoch, min($endsEpoch, $showEndEpoch), $row);
|
||||
|
||||
$row["id"] = intval($p_item["sched_id"]);
|
||||
$row["image"] = $p_item["file_exists"];
|
||||
$row["instance"] = intval($p_item["si_id"]);
|
||||
$row["starts"] = $schedStartDT->format("H:i:s");
|
||||
$row["ends"] = $schedEndDT->format("H:i:s");
|
||||
|
||||
$cue_out = Application_Common_DateHelper::playlistTimeToSeconds($p_item['cue_out']);
|
||||
$cue_in = Application_Common_DateHelper::playlistTimeToSeconds($p_item['cue_in']);
|
||||
|
||||
$run_time = $cue_out-$cue_in;
|
||||
|
||||
$formatter = new LengthFormatter(Application_Common_DateHelper::secondsToPlaylistTime($run_time));
|
||||
$row['runtime'] = $formatter->format();
|
||||
|
||||
$row["title"] = htmlspecialchars($p_item["file_track_title"]);
|
||||
$row["creator"] = htmlspecialchars($p_item["file_artist_name"]);
|
||||
$row["album"] = htmlspecialchars($p_item["file_album_title"]);
|
||||
|
||||
$row["cuein"] = $p_item["cue_in"];
|
||||
$row["cueout"] = $p_item["cue_out"];
|
||||
$row["fadein"] = round(substr($p_item["fade_in"], 6), 6);
|
||||
$row["fadeout"] = round(substr($p_item["fade_out"], 6), 6);
|
||||
$row["mime"] = $p_item["file_mime"];
|
||||
|
||||
$row["pos"] = $this->pos++;
|
||||
|
||||
$this->contentDT = $schedEndDT;
|
||||
}
|
||||
//show is empty or is a special kind of show (recording etc)
|
||||
else if (intval($p_item["si_record"]) === 1) {
|
||||
$row["record"] = true;
|
||||
$row["instance"] = intval($p_item["si_id"]);
|
||||
|
||||
$showStartDT = new DateTime($p_item["si_starts"], new DateTimeZone("UTC"));
|
||||
$showEndDT = new DateTime($p_item["si_ends"], new DateTimeZone("UTC"));
|
||||
|
||||
$startsEpoch = floatval($showStartDT->format("U.u"));
|
||||
$endsEpoch = floatval($showEndDT->format("U.u"));
|
||||
|
||||
$this->getScheduledStatus($startsEpoch, $endsEpoch, $row);
|
||||
} else {
|
||||
$row["empty"] = true;
|
||||
$row["id"] = 0 ;
|
||||
$row["instance"] = intval($p_item["si_id"]);
|
||||
}
|
||||
|
||||
if (intval($p_item["si_rebroadcast"]) === 1) {
|
||||
$row["rebroadcast"] = true;
|
||||
}
|
||||
|
||||
if ($this->currentShow === true) {
|
||||
$row["currentShow"] = true;
|
||||
}
|
||||
|
||||
$this->getItemColor($p_item, $row);
|
||||
$this->getRowTimestamp($p_item, $row);
|
||||
$this->isAllowed($p_item, $row);
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
private function makeFooterRow($p_item)
|
||||
{
|
||||
$row = $this->defaultRowArray;
|
||||
$row["footer"] = true;
|
||||
$row["instance"] = intval($p_item["si_id"]);
|
||||
$this->getRowTimestamp($p_item, $row);
|
||||
|
||||
$showEndDT = new DateTime($p_item["si_ends"], new DateTimeZone("UTC"));
|
||||
$contentDT = $this->contentDT;
|
||||
|
||||
$runtime = bcsub($contentDT->format("U.u"), $showEndDT->format("U.u"), 6);
|
||||
$row["runtime"] = $runtime;
|
||||
|
||||
$timeFilled = new TimeFilledFormatter($runtime);
|
||||
$row["fRuntime"] = $timeFilled->format();
|
||||
|
||||
$showStartDT = new DateTime($p_item["si_starts"], new DateTimeZone("UTC"));
|
||||
$showStartDT->setTimezone(new DateTimeZone($this->timezone));
|
||||
$startsEpoch = floatval($showStartDT->format("U.u"));
|
||||
$showEndDT = new DateTime($p_item["si_ends"], new DateTimeZone("UTC"));
|
||||
$showEndDT->setTimezone(new DateTimeZone($this->timezone));
|
||||
$endsEpoch = floatval($showEndDT->format("U.u"));
|
||||
|
||||
$row["refresh"] = floatval($showEndDT->format("U.u")) - $this->epoch_now;
|
||||
|
||||
if ($this->currentShow === true) {
|
||||
$row["currentShow"] = true;
|
||||
}
|
||||
|
||||
$this->getScheduledStatus($startsEpoch, $endsEpoch, $row);
|
||||
$this->isAllowed($p_item, $row);
|
||||
|
||||
if (intval($p_item["si_record"]) === 1) {
|
||||
$row["record"] = true;
|
||||
}
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
/*
|
||||
* @param int $timestamp Unix timestamp in seconds.
|
||||
*
|
||||
* @return boolean whether the schedule in the show builder's range has
|
||||
* been updated.
|
||||
*
|
||||
*/
|
||||
public function hasBeenUpdatedSince($timestamp, $instances)
|
||||
{
|
||||
$outdated = false;
|
||||
$shows = Application_Model_Show::getShows($this->startDT, $this->endDT);
|
||||
|
||||
$include = array();
|
||||
if ($this->opts["showFilter"] !== 0) {
|
||||
$include[] = $this->opts["showFilter"];
|
||||
} elseif ($this->opts["myShows"] === 1) {
|
||||
|
||||
$include = $this->getUsersShows();
|
||||
}
|
||||
|
||||
|
||||
$currentInstances = array();
|
||||
|
||||
foreach ($shows as $show) {
|
||||
|
||||
if (empty($include) || in_array($show["show_id"], $include)) {
|
||||
$currentInstances[] = $show["instance_id"];
|
||||
|
||||
if (isset($show["last_scheduled"])) {
|
||||
$dt = new DateTime($show["last_scheduled"],
|
||||
new DateTimeZone("UTC"));
|
||||
} else {
|
||||
$dt = new DateTime($show["created"],
|
||||
new DateTimeZone("UTC"));
|
||||
}
|
||||
|
||||
//check if any of the shows have a more recent timestamp.
|
||||
$showTimeStamp = intval($dt->format("U"));
|
||||
if ($timestamp < $showTimeStamp) {
|
||||
$outdated = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//see if the displayed show instances have changed. (deleted,
|
||||
//empty schedule etc)
|
||||
if ($outdated === false && count($instances)
|
||||
!== count($currentInstances)) {
|
||||
Logging::debug("show instances have changed.");
|
||||
$outdated = true;
|
||||
}
|
||||
|
||||
return $outdated;
|
||||
}
|
||||
|
||||
public function getItems()
|
||||
{
|
||||
$current_id = -1;
|
||||
$display_items = array();
|
||||
|
||||
$shows = array();
|
||||
$showInstance = array();
|
||||
if ($this->opts["myShows"] === 1) {
|
||||
|
||||
$shows = $this->getUsersShows();
|
||||
} elseif ($this->opts["showFilter"] !== 0) {
|
||||
$shows[] = $this->opts["showFilter"];
|
||||
} elseif ($this->opts["showInstanceFilter"] !== 0) {
|
||||
$showInstance[] = $this->opts["showInstanceFilter"];
|
||||
}
|
||||
|
||||
$scheduled_items = Application_Model_Schedule::GetScheduleDetailItems(
|
||||
$this->startDT, $this->endDT, $shows, $showInstance);
|
||||
|
||||
for ($i = 0, $rows = count($scheduled_items); $i < $rows; $i++) {
|
||||
|
||||
$item = $scheduled_items[$i];
|
||||
|
||||
//don't send back data for filler rows.
|
||||
if (isset($item["playout_status"]) &&
|
||||
$item["playout_status"] < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//make a header row.
|
||||
if ($current_id !== $item["si_id"]) {
|
||||
|
||||
//make a footer row.
|
||||
if ($current_id !== -1) {
|
||||
// pass in the previous row as it's the last row for
|
||||
// the previous show.
|
||||
$display_items[] = $this->makeFooterRow(
|
||||
$scheduled_items[$i-1]);
|
||||
}
|
||||
|
||||
$display_items[] = $this->makeHeaderRow($item);
|
||||
|
||||
$current_id = $item["si_id"];
|
||||
|
||||
$this->pos = 1;
|
||||
}
|
||||
|
||||
//make a normal data row.
|
||||
$row = $this->makeScheduledItemRow($item);
|
||||
//don't display the empty rows.
|
||||
if (isset($row)) {
|
||||
$display_items[] = $row;
|
||||
}
|
||||
|
||||
if ($current_id !== -1 &&
|
||||
!in_array($current_id, $this->showInstances)) {
|
||||
$this->showInstances[] = $current_id;
|
||||
}
|
||||
}
|
||||
|
||||
//make the last footer if there were any scheduled items.
|
||||
if (count($scheduled_items) > 0) {
|
||||
$display_items[] = $this->makeFooterRow($scheduled_items[
|
||||
count($scheduled_items)-1]);
|
||||
}
|
||||
|
||||
return array(
|
||||
"schedule" => $display_items,
|
||||
"showInstances" => $this->showInstances);
|
||||
}
|
||||
}
|
828
legacy/application/models/ShowInstance.php
Normal file
828
legacy/application/models/ShowInstance.php
Normal file
|
@ -0,0 +1,828 @@
|
|||
<?php
|
||||
|
||||
class Application_Model_ShowInstance
|
||||
{
|
||||
private $_instanceId;
|
||||
private $_showInstance;
|
||||
|
||||
public function __construct($instanceId)
|
||||
{
|
||||
$this->_instanceId = $instanceId;
|
||||
$this->_showInstance = CcShowInstancesQuery::create()->findPK($instanceId);
|
||||
|
||||
if (is_null($this->_showInstance)) {
|
||||
throw new Exception();
|
||||
}
|
||||
}
|
||||
|
||||
public function getShowId()
|
||||
{
|
||||
return $this->_showInstance->getDbShowId();
|
||||
}
|
||||
|
||||
/* TODO: A little inconsistent because other models have a getId() method
|
||||
to get PK --RG */
|
||||
public function getShowInstanceId()
|
||||
{
|
||||
return $this->_instanceId;
|
||||
}
|
||||
|
||||
public function getShow()
|
||||
{
|
||||
return new Application_Model_Show($this->getShowId());
|
||||
}
|
||||
|
||||
public function deleteRebroadcasts()
|
||||
{
|
||||
$timestamp = gmdate(DEFAULT_TIMESTAMP_FORMAT);
|
||||
$instance_id = $this->getShowInstanceId();
|
||||
$sql = <<<SQL
|
||||
DELETE FROM cc_show_instances
|
||||
WHERE starts > :timestamp::TIMESTAMP
|
||||
AND instance_id = :instanceId
|
||||
AND rebroadcast = 1;
|
||||
SQL;
|
||||
Application_Common_Database::prepareAndExecute( $sql, array(
|
||||
':instanceId' => $instance_id,
|
||||
':timestamp' => $timestamp), 'execute');
|
||||
}
|
||||
|
||||
/* This function is weird. It should return a boolean, but instead returns
|
||||
* an integer if it is a rebroadcast, or returns null if it isn't. You can convert
|
||||
* it to boolean by using is_null(isRebroadcast), where true means isn't and false
|
||||
* means that it is. */
|
||||
public function isRebroadcast()
|
||||
{
|
||||
return $this->_showInstance->getDbOriginalShow();
|
||||
}
|
||||
|
||||
public function isRecorded()
|
||||
{
|
||||
return $this->_showInstance->getDbRecord();
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
$show = CcShowQuery::create()->findPK($this->getShowId());
|
||||
|
||||
return $show->getDbName();
|
||||
}
|
||||
|
||||
public function getImagePath()
|
||||
{
|
||||
$show = CcShowQuery::create()->findPK($this->getShowId());
|
||||
|
||||
return $show->getDbImagePath();
|
||||
}
|
||||
|
||||
public function getGenre()
|
||||
{
|
||||
$show = CcShowQuery::create()->findPK($this->getShowId());
|
||||
|
||||
return $show->getDbGenre();
|
||||
}
|
||||
|
||||
|
||||
public function hasAutoPlaylist()
|
||||
{
|
||||
$show = CcShowQuery::create()->findPK($this->getShowId());
|
||||
return $show->getDbHasAutoPlaylist();
|
||||
|
||||
}
|
||||
|
||||
public function getAutoPlaylistId()
|
||||
{
|
||||
$show = CcShowQuery::create()->findPK($this->getShowId());
|
||||
return $show->getDbAutoPlaylistId();
|
||||
|
||||
}
|
||||
|
||||
public function getAutoPlaylistRepeat()
|
||||
{
|
||||
$show = CcShowQuery::create()->findPK($this->getShowId());
|
||||
return $show->getDbAutoPlaylistRepeat();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the start time of the Show (UTC time)
|
||||
* @return string in format DEFAULT_TIMESTAMP_FORMAT (PHP time notation)
|
||||
*/
|
||||
public function getShowInstanceStart($format=DEFAULT_TIMESTAMP_FORMAT)
|
||||
{
|
||||
return $this->_showInstance->getDbStarts($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the end time of the Show (UTC time)
|
||||
* @return string in format DEFAULT_TIMESTAMP_FORMAT (PHP time notation)
|
||||
*/
|
||||
public function getShowInstanceEnd($format=DEFAULT_TIMESTAMP_FORMAT)
|
||||
{
|
||||
return $this->_showInstance->getDbEnds($format);
|
||||
}
|
||||
|
||||
public function getStartDate()
|
||||
{
|
||||
$showStart = $this->getShowInstanceStart();
|
||||
$showStartExplode = explode(" ", $showStart);
|
||||
|
||||
return $showStartExplode[0];
|
||||
}
|
||||
|
||||
public function getStartTime()
|
||||
{
|
||||
$showStart = $this->getShowInstanceStart();
|
||||
$showStartExplode = explode(" ", $showStart);
|
||||
|
||||
return $showStartExplode[1];
|
||||
}
|
||||
|
||||
public function getRecordedFile()
|
||||
{
|
||||
$file_id = $this->_showInstance->getDbRecordedFile();
|
||||
|
||||
if (isset($file_id)) {
|
||||
$file = Application_Model_StoredFile::RecallById($file_id);
|
||||
|
||||
if (isset($file)) {
|
||||
$filePaths = $file->getFilePaths();
|
||||
if (file_exists($filePaths[0])) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function setShowStart($start)
|
||||
{
|
||||
$this->_showInstance->setDbStarts($start)
|
||||
->save();
|
||||
Application_Model_RabbitMq::PushSchedule();
|
||||
}
|
||||
|
||||
public function setShowEnd($end)
|
||||
{
|
||||
$this->_showInstance->setDbEnds($end)
|
||||
->save();
|
||||
Application_Model_RabbitMq::PushSchedule();
|
||||
}
|
||||
|
||||
public function setAutoPlaylistBuilt($bool)
|
||||
{
|
||||
$this->_showInstance->setDbAutoPlaylistBuilt($bool)
|
||||
->save();
|
||||
}
|
||||
|
||||
public function updateScheduledTime()
|
||||
{
|
||||
$con = Propel::getConnection(CcShowInstancesPeer::DATABASE_NAME);
|
||||
$this->_showInstance->updateDbTimeFilled($con);
|
||||
}
|
||||
|
||||
public function isDeleted()
|
||||
{
|
||||
$this->_showInstance->getDbModifiedInstance();
|
||||
}
|
||||
|
||||
/*
|
||||
* @param $dateTime
|
||||
* php Datetime object to add deltas to
|
||||
*
|
||||
* @param $deltaDay
|
||||
* php int, delta days show moved
|
||||
*
|
||||
* @param $deltaMin
|
||||
* php int, delta mins show moved
|
||||
*
|
||||
* @return $newDateTime
|
||||
* php DateTime, $dateTime with the added time deltas.
|
||||
*/
|
||||
public static function addDeltas($dateTime, $deltaDay, $deltaMin)
|
||||
{
|
||||
$newDateTime = clone $dateTime;
|
||||
|
||||
$days = abs($deltaDay);
|
||||
$mins = abs($deltaMin);
|
||||
|
||||
$dayInterval = new DateInterval("P{$days}D");
|
||||
$minInterval = new DateInterval("PT{$mins}M");
|
||||
|
||||
if ($deltaDay > 0) {
|
||||
$newDateTime->add($dayInterval);
|
||||
} elseif ($deltaDay < 0) {
|
||||
$newDateTime->sub($dayInterval);
|
||||
}
|
||||
|
||||
if ($deltaMin > 0) {
|
||||
$newDateTime->add($minInterval);
|
||||
} elseif ($deltaMin < 0) {
|
||||
$newDateTime->sub($minInterval);
|
||||
}
|
||||
|
||||
return $newDateTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a playlist as the last item of the current show.
|
||||
*
|
||||
* @param int $plId
|
||||
* Playlist ID.
|
||||
*/
|
||||
public function addPlaylistToShow($pl_id, $checkUserPerm = true)
|
||||
{
|
||||
$ts = intval($this->_showInstance->getDbLastScheduled("U")) ? : 0;
|
||||
$id = $this->_showInstance->getDbId();
|
||||
$lastid = $this->getLastAudioItemId();
|
||||
$scheduler = new Application_Model_Scheduler($checkUserPerm);
|
||||
$scheduler->scheduleAfter(
|
||||
array(array("id" => $lastid, "instance" => $id, "timestamp" => $ts)),
|
||||
array(array("id" => $pl_id, "type" => "playlist"))
|
||||
);
|
||||
// doing this to update the database schedule so that subsequent adds will work.
|
||||
$con = Propel::getConnection(CcShowInstancesPeer::DATABASE_NAME);
|
||||
$this->_showInstance->updateScheduleStatus($con);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a playlist as the first item of the current show.
|
||||
*
|
||||
* @param int $plId
|
||||
* Playlist ID.
|
||||
*/
|
||||
public function addPlaylistToShowStart($pl_id, $checkUserPerm = true)
|
||||
{
|
||||
$ts = intval($this->_showInstance->getDbLastScheduled("U")) ? : 0;
|
||||
$id = $this->_showInstance->getDbId();
|
||||
$scheduler = new Application_Model_Scheduler($checkUserPerm);
|
||||
$scheduler->scheduleAfter(
|
||||
array(array("id" => 0, "instance" => $id, "timestamp" => $ts)),
|
||||
array(array("id" => $pl_id, "type" => "playlist"))
|
||||
);
|
||||
// doing this to update the database schedule so that subsequent adds will work.
|
||||
$con = Propel::getConnection(CcShowInstancesPeer::DATABASE_NAME);
|
||||
$this->_showInstance->updateScheduleStatus($con);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a media file as the last item in the show.
|
||||
*
|
||||
* @param int $file_id
|
||||
*/
|
||||
public function addFileToShow($file_id, $checkUserPerm = true)
|
||||
{
|
||||
$ts = intval($this->_showInstance->getDbLastScheduled("U")) ? : 0;
|
||||
$id = $this->_showInstance->getDbId();
|
||||
|
||||
$scheduler = new Application_Model_Scheduler();
|
||||
$scheduler->setCheckUserPermissions($checkUserPerm);
|
||||
$scheduler->scheduleAfter(
|
||||
array(array("id" => 0, "instance" => $id, "timestamp" => $ts)),
|
||||
array(array("id" => $file_id, "type" => "audioclip"))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the given playlists to the show.
|
||||
*
|
||||
* @param array $plIds
|
||||
* An array of playlist IDs.
|
||||
*/
|
||||
public function scheduleShow($plIds)
|
||||
{
|
||||
foreach ($plIds as $plId) {
|
||||
$this->addPlaylistToShow($plId);
|
||||
}
|
||||
}
|
||||
|
||||
public function clearShow()
|
||||
{
|
||||
CcScheduleQuery::create()
|
||||
->filterByDbInstanceId($this->_instanceId)
|
||||
->delete();
|
||||
Application_Model_RabbitMq::PushSchedule();
|
||||
$this->updateScheduledTime();
|
||||
}
|
||||
|
||||
private function checkToDeleteShow($showId)
|
||||
|
||||
{
|
||||
//UTC DateTime object
|
||||
$showsPopUntil = Application_Model_Preference::GetShowsPopulatedUntil();
|
||||
|
||||
$showDays = CcShowDaysQuery::create()
|
||||
->filterByDbShowId($showId)
|
||||
->findOne();
|
||||
|
||||
$showEnd = $showDays->getDbLastShow();
|
||||
|
||||
//there will always be more shows populated.
|
||||
if (is_null($showEnd)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$lastShowStartDateTime = new DateTime("{$showEnd} {$showDays->getDbStartTime()}", new DateTimeZone($showDays->getDbTimezone()));
|
||||
//end dates were non inclusive.
|
||||
$lastShowStartDateTime = self::addDeltas($lastShowStartDateTime, -1, 0);
|
||||
|
||||
//there's still some shows left to be populated.
|
||||
if ($lastShowStartDateTime->getTimestamp() > $showsPopUntil->getTimestamp()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if there are any non deleted show instances remaining.
|
||||
$showInstances = CcShowInstancesQuery::create()
|
||||
->filterByDbShowId($showId)
|
||||
->filterByDbModifiedInstance(false)
|
||||
->filterByDbRebroadcast(0)
|
||||
->find();
|
||||
|
||||
if (is_null($showInstances)) {
|
||||
return true;
|
||||
}
|
||||
//only 1 show instance left of the show, make it non repeating.
|
||||
else if (count($showInstances) === 1) {
|
||||
$showInstance = $showInstances[0];
|
||||
|
||||
$showDaysOld = CcShowDaysQuery::create()
|
||||
->filterByDbShowId($showId)
|
||||
->find();
|
||||
|
||||
$tz = $showDaysOld[0]->getDbTimezone();
|
||||
|
||||
$startDate = new DateTime($showInstance->getDbStarts(), new DateTimeZone("UTC"));
|
||||
$startDate->setTimeZone(new DateTimeZone($tz));
|
||||
$endDate = self::addDeltas($startDate, 1, 0);
|
||||
|
||||
//make a new rule for a non repeating show.
|
||||
$showDayNew = new CcShowDays();
|
||||
$showDayNew->setDbFirstShow($startDate->format("Y-m-d"));
|
||||
$showDayNew->setDbLastShow($endDate->format("Y-m-d"));
|
||||
$showDayNew->setDbStartTime($startDate->format("H:i:s"));
|
||||
$showDayNew->setDbTimezone($tz);
|
||||
$showDayNew->setDbDay($startDate->format('w'));
|
||||
$showDayNew->setDbDuration($showDaysOld[0]->getDbDuration());
|
||||
$showDayNew->setDbRepeatType(-1);
|
||||
$showDayNew->setDbShowId($showDaysOld[0]->getDbShowId());
|
||||
$showDayNew->setDbRecord($showDaysOld[0]->getDbRecord());
|
||||
$showDayNew->save();
|
||||
|
||||
//delete the old rules for repeating shows
|
||||
$showDaysOld->delete();
|
||||
|
||||
//remove the old repeating deleted instances.
|
||||
$showInstances = CcShowInstancesQuery::create()
|
||||
->filterByDbShowId($showId)
|
||||
->filterByDbModifiedInstance(true)
|
||||
->delete();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function delete($rabbitmqPush = true)
|
||||
{
|
||||
// see if it was recording show
|
||||
$recording = $this->isRecorded();
|
||||
// get show id
|
||||
$showId = $this->getShowId();
|
||||
|
||||
$show = $this->getShow();
|
||||
|
||||
$current_timestamp = gmdate(DEFAULT_TIMESTAMP_FORMAT);
|
||||
|
||||
if ($current_timestamp <= $this->getShowInstanceEnd()) {
|
||||
if ($show->isRepeating()) {
|
||||
|
||||
CcShowInstancesQuery::create()
|
||||
->findPK($this->_instanceId)
|
||||
->setDbModifiedInstance(true)
|
||||
->save();
|
||||
|
||||
if ($this->isRebroadcast()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//delete the rebroadcasts of the removed recorded show.
|
||||
if ($recording) {
|
||||
CcShowInstancesQuery::create()
|
||||
->filterByDbOriginalShow($this->_instanceId)
|
||||
->delete();
|
||||
}
|
||||
|
||||
/* Automatically delete all files scheduled in cc_schedules table. */
|
||||
CcScheduleQuery::create()
|
||||
->filterByDbInstanceId($this->_instanceId)
|
||||
->delete();
|
||||
|
||||
|
||||
if ($this->checkToDeleteShow($showId)) {
|
||||
CcShowQuery::create()
|
||||
->filterByDbId($showId)
|
||||
->delete();
|
||||
}
|
||||
} else {
|
||||
if ($this->isRebroadcast()) {
|
||||
$this->_showInstance->delete();
|
||||
} else {
|
||||
$show->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($rabbitmqPush) {
|
||||
Application_Model_RabbitMq::PushSchedule();
|
||||
}
|
||||
}
|
||||
|
||||
public function setRecordedFile($file_id)
|
||||
{
|
||||
$showInstance = CcShowInstancesQuery::create()
|
||||
->findPK($this->_instanceId);
|
||||
$showInstance->setDbRecordedFile($file_id)
|
||||
->save();
|
||||
|
||||
$rebroadcasts = CcShowInstancesQuery::create()
|
||||
->filterByDbOriginalShow($this->_instanceId)
|
||||
->find();
|
||||
|
||||
foreach ($rebroadcasts as $rebroadcast) {
|
||||
|
||||
try {
|
||||
$rebroad = new Application_Model_ShowInstance($rebroadcast->getDbId());
|
||||
$rebroad->addFileToShow($file_id, false);
|
||||
} catch (Exception $e) {
|
||||
Logging::info($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getTimeScheduled()
|
||||
{
|
||||
$time = $this->_showInstance->getDbTimeFilled();
|
||||
|
||||
if ($time != "00:00:00" && !empty($time)) {
|
||||
$time_arr = explode(".", $time);
|
||||
if (count($time_arr) > 1) {
|
||||
$time_arr[1] = "." . $time_arr[1];
|
||||
$milliseconds = number_format(round($time_arr[1], 2), 2);
|
||||
$time = $time_arr[0] . substr($milliseconds, 1);
|
||||
} else {
|
||||
$time = $time_arr[0] . ".00";
|
||||
}
|
||||
} else {
|
||||
$time = "00:00:00.00";
|
||||
}
|
||||
|
||||
return $time;
|
||||
}
|
||||
|
||||
|
||||
public function getTimeScheduledSecs()
|
||||
{
|
||||
$time_filled = $this->getTimeScheduled();
|
||||
|
||||
return Application_Common_DateHelper::playlistTimeToSeconds($time_filled);
|
||||
}
|
||||
|
||||
public function getDurationSecs()
|
||||
{
|
||||
$ends = $this->getShowInstanceEnd(null);
|
||||
$starts = $this->getShowInstanceStart(null);
|
||||
|
||||
return intval($ends->format('U')) - intval($starts->format('U'));
|
||||
}
|
||||
|
||||
// should return the amount of seconds remaining to be scheduled in a show instance
|
||||
public function getSecondsRemaining()
|
||||
{
|
||||
return ($this->getDurationSecs() - $this->getTimeScheduledSecs());
|
||||
}
|
||||
|
||||
public function getPercentScheduled()
|
||||
{
|
||||
$durationSeconds = $this->getDurationSecs();
|
||||
$timeSeconds = $this->getTimeScheduledSecs();
|
||||
|
||||
if ($durationSeconds != 0) { //Prevent division by zero if the show duration is somehow zero.
|
||||
$percent = ceil(($timeSeconds / $durationSeconds) * 100);
|
||||
} else {
|
||||
$percent = 0;
|
||||
}
|
||||
return $percent;
|
||||
}
|
||||
|
||||
public function getShowLength()
|
||||
{
|
||||
$start = $this->getShowInstanceStart(null);
|
||||
$end = $this->getShowInstanceEnd(null);
|
||||
|
||||
$interval = $start->diff($end);
|
||||
$days = $interval->format("%d");
|
||||
$hours = sprintf("%02d" ,$interval->format("%h"));
|
||||
|
||||
if ($days > 0) {
|
||||
$totalHours = $days * 24 + $hours;
|
||||
//$interval object does not have milliseconds so hard code to .00
|
||||
$returnStr = $totalHours . ":" . $interval->format("%I:%S") . ".00";
|
||||
} else {
|
||||
$returnStr = $hours . ":" . $interval->format("%I:%S") . ".00";
|
||||
}
|
||||
|
||||
return $returnStr;
|
||||
}
|
||||
|
||||
public static function getContentCount($p_start, $p_end)
|
||||
{
|
||||
$sql = <<<SQL
|
||||
SELECT instance_id,
|
||||
count(*) AS instance_count
|
||||
FROM cc_schedule
|
||||
WHERE ends > :p_start::TIMESTAMP
|
||||
AND starts < :p_end::TIMESTAMP
|
||||
GROUP BY instance_id
|
||||
SQL;
|
||||
|
||||
$counts = Application_Common_Database::prepareAndExecute($sql, array(
|
||||
':p_start' => $p_start->format("Y-m-d G:i:s"),
|
||||
':p_end' => $p_end->format("Y-m-d G:i:s"))
|
||||
, 'all');
|
||||
|
||||
$real_counts = array();
|
||||
foreach ($counts as $c) {
|
||||
$real_counts[$c['instance_id']] = $c['instance_count'];
|
||||
}
|
||||
return $real_counts;
|
||||
|
||||
}
|
||||
|
||||
public static function getIsFull($p_start, $p_end)
|
||||
{
|
||||
$sql = <<<SQL
|
||||
SELECT id, ends-starts-'00:00:05' < time_filled as filled
|
||||
from cc_show_instances
|
||||
WHERE ends > :p_start::TIMESTAMP
|
||||
AND starts < :p_end::TIMESTAMP
|
||||
SQL;
|
||||
|
||||
$res = Application_Common_Database::prepareAndExecute($sql, array(
|
||||
':p_start' => $p_start->format("Y-m-d G:i:s"),
|
||||
':p_end' => $p_end->format("Y-m-d G:i:s"))
|
||||
, 'all');
|
||||
|
||||
$isFilled = array();
|
||||
foreach ($res as $r) {
|
||||
$isFilled[$r['id']] = $r['filled'];
|
||||
}
|
||||
|
||||
return $isFilled;
|
||||
}
|
||||
|
||||
public static function getShowHasAutoplaylist($p_start, $p_end)
|
||||
{
|
||||
$con = Propel::getConnection(CcShowInstancesPeer::DATABASE_NAME);
|
||||
$con->beginTransaction();
|
||||
try {
|
||||
// query the show instances to find whether a show instance has an autoplaylist
|
||||
$showInstances = CcShowInstancesQuery::create()
|
||||
->filterByDbEnds($p_end->format(DEFAULT_TIMESTAMP_FORMAT), Criteria::LESS_THAN)
|
||||
->filterByDbStarts($p_start->format(DEFAULT_TIMESTAMP_FORMAT), Criteria::GREATER_THAN)
|
||||
->leftJoinCcShow()
|
||||
->where('CcShow.has_autoplaylist = ?', 'true')
|
||||
->find($con);
|
||||
$hasAutoplaylist = array();
|
||||
foreach ($showInstances->toArray() as $ap) {
|
||||
$hasAutoplaylist[$ap['DbId']] = true;
|
||||
}
|
||||
return $hasAutoplaylist;
|
||||
}
|
||||
|
||||
catch (Exception $e) {
|
||||
$con->rollback();
|
||||
Logging::info("Couldn't query show instances for calendar to find which had autoplaylists");
|
||||
Logging::info($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function showEmpty()
|
||||
{
|
||||
$sql = <<<SQL
|
||||
SELECT s.starts
|
||||
FROM cc_schedule AS s
|
||||
WHERE s.instance_id = :instance_id
|
||||
AND s.playout_status >= 0
|
||||
AND ((s.stream_id IS NOT NULL)
|
||||
OR (s.file_id IS NOT NULL)) LIMIT 1
|
||||
SQL;
|
||||
# TODO : use prepareAndExecute properly
|
||||
$res = Application_Common_Database::prepareAndExecute($sql,
|
||||
array( ':instance_id' => $this->_instanceId ), 'all' );
|
||||
# TODO : A bit retarded. fix this later
|
||||
foreach ($res as $r) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
public function getShowListContent($timezone = null)
|
||||
{
|
||||
$con = Propel::getConnection();
|
||||
|
||||
$sql = <<<SQL
|
||||
SELECT *
|
||||
FROM (
|
||||
(SELECT s.starts,
|
||||
0::INTEGER as type ,
|
||||
f.id AS item_id,
|
||||
f.track_title,
|
||||
f.album_title AS album,
|
||||
f.genre AS genre,
|
||||
f.length AS length,
|
||||
f.artist_name AS creator,
|
||||
f.file_exists AS EXISTS,
|
||||
f.filepath AS filepath,
|
||||
f.mime AS mime
|
||||
FROM cc_schedule AS s
|
||||
LEFT JOIN cc_files AS f ON f.id = s.file_id
|
||||
WHERE s.instance_id = :instance_id1
|
||||
AND s.playout_status >= 0
|
||||
AND s.file_id IS NOT NULL
|
||||
AND f.hidden = 'false')
|
||||
UNION
|
||||
(SELECT s.starts,
|
||||
1::INTEGER as type,
|
||||
ws.id AS item_id,
|
||||
(ws.name || ': ' || ws.url) AS title,
|
||||
null AS album,
|
||||
null AS genre,
|
||||
ws.length AS length,
|
||||
sub.login AS creator,
|
||||
't'::boolean AS EXISTS,
|
||||
ws.url AS filepath,
|
||||
ws.mime as mime
|
||||
FROM cc_schedule AS s
|
||||
LEFT JOIN cc_webstream AS ws ON ws.id = s.stream_id
|
||||
LEFT JOIN cc_subjs AS sub ON ws.creator_id = sub.id
|
||||
WHERE s.instance_id = :instance_id2
|
||||
AND s.playout_status >= 0
|
||||
AND s.stream_id IS NOT NULL)) AS temp
|
||||
ORDER BY starts;
|
||||
SQL;
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute(array(
|
||||
':instance_id1' => $this->_instanceId,
|
||||
':instance_id2' => $this->_instanceId
|
||||
));
|
||||
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if (isset($timezone)) {
|
||||
$displayTimezone = new DateTimeZone($timezone);
|
||||
} else {
|
||||
$userTimezone = Application_Model_Preference::GetUserTimezone();
|
||||
$displayTimezone = new DateTimeZone($userTimezone);
|
||||
}
|
||||
|
||||
$utcTimezone = new DateTimeZone("UTC");
|
||||
|
||||
foreach ($results as &$row) {
|
||||
|
||||
$dt = new DateTime($row["starts"], $utcTimezone);
|
||||
$dt->setTimezone($displayTimezone);
|
||||
$row["starts"] = $dt->format(DEFAULT_TIMESTAMP_FORMAT);
|
||||
|
||||
if (isset($row['length'])) {
|
||||
$formatter = new LengthFormatter($row["length"]);
|
||||
$row["length"] = $formatter->format();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
public function getLastAudioItemId()
|
||||
{
|
||||
$con = Propel::getConnection();
|
||||
|
||||
$sql = "SELECT id FROM cc_schedule "
|
||||
."WHERE instance_id = :instanceId "
|
||||
."ORDER BY ends DESC "
|
||||
."LIMIT 1";
|
||||
|
||||
$query = Application_Common_Database::prepareAndExecute( $sql,
|
||||
array(':instanceId' => $this->_instanceId), 'column');
|
||||
|
||||
return ($query !== false) ? $query : null;
|
||||
}
|
||||
|
||||
|
||||
public function getLastAudioItemEnd()
|
||||
{
|
||||
$con = Propel::getConnection();
|
||||
|
||||
$sql = "SELECT ends FROM cc_schedule "
|
||||
."WHERE instance_id = :instanceId "
|
||||
."ORDER BY ends DESC "
|
||||
."LIMIT 1";
|
||||
|
||||
$query = Application_Common_Database::prepareAndExecute( $sql,
|
||||
array(':instanceId' => $this->_instanceId), 'column');
|
||||
|
||||
return ($query !== false) ? $query : null;
|
||||
}
|
||||
|
||||
public static function GetLastShowInstance($p_timeNow)
|
||||
{
|
||||
$sql = <<<SQL
|
||||
SELECT si.id
|
||||
FROM cc_show_instances si
|
||||
WHERE si.ends < :timeNow::TIMESTAMP
|
||||
AND si.modified_instance = 'f'
|
||||
ORDER BY si.ends DESC LIMIT 1;
|
||||
SQL;
|
||||
$id = Application_Common_Database( $sql, array(
|
||||
':timeNow' => $p_timeNow ), 'column' );
|
||||
|
||||
return ($id ? new Application_Model_ShowInstance($id) : null );
|
||||
}
|
||||
|
||||
public static function GetCurrentShowInstance($p_timeNow)
|
||||
{
|
||||
/* Orderby si.starts descending, because in some cases
|
||||
* we can have multiple shows overlapping each other. In
|
||||
* this case, the show that started later is the one that
|
||||
* is actually playing, and so this is the one we want.
|
||||
*/
|
||||
|
||||
$sql = <<<SQL
|
||||
SELECT si.id
|
||||
FROM cc_show_instances si
|
||||
WHERE si.starts <= :timeNow1::TIMESTAMP
|
||||
AND si.ends > :timeNow2::TIMESTAMP
|
||||
AND si.modified_instance = 'f'
|
||||
ORDER BY si.starts DESC LIMIT 1
|
||||
SQL;
|
||||
|
||||
$id = Application_Common_Database( $sql, array(
|
||||
':timeNow1' => $p_timeNow,
|
||||
':timeNow2' => $p_timeNow ), 'column');
|
||||
|
||||
return ( $id ? new Application_Model_ShowInstance($id) : null );
|
||||
}
|
||||
|
||||
public static function GetNextShowInstance($p_timeNow)
|
||||
{
|
||||
$sql = <<<SQL
|
||||
SELECT si.id
|
||||
FROM cc_show_instances si
|
||||
WHERE si.starts > :timeNow::TIMESTAMP
|
||||
AND si.modified_instance = 'f'
|
||||
ORDER BY si.starts
|
||||
LIMIT 1
|
||||
SQL;
|
||||
$id = Application_Common_Database::prepareAndExecute( $sql,
|
||||
array( 'timeNow' => $p_timeNow ), 'column' );
|
||||
return ( $id ? new Application_Model_ShowInstance($id) : null );
|
||||
}
|
||||
|
||||
// returns number of show instances that ends later than $day
|
||||
public static function GetShowInstanceCount($day)
|
||||
{
|
||||
$sql = <<<SQL
|
||||
SELECT count(*) AS cnt
|
||||
FROM cc_show_instances
|
||||
WHERE ends < :day
|
||||
SQL;
|
||||
return Application_Common_Database::prepareAndExecute( $sql,
|
||||
array( ':day' => $day ), 'column' );
|
||||
}
|
||||
|
||||
// this returns end timestamp of all shows that are in the range and has live DJ set up
|
||||
public static function GetEndTimeOfNextShowWithLiveDJ($p_startTime, $p_endTime)
|
||||
{
|
||||
$sql = <<<SQL
|
||||
SELECT ends
|
||||
FROM cc_show_instances AS si
|
||||
JOIN cc_show AS sh ON si.show_id = sh.id
|
||||
WHERE si.ends > :startTime::TIMESTAMP
|
||||
AND si.ends < :endTime::TIMESTAMP
|
||||
AND (sh.live_stream_using_airtime_auth
|
||||
OR live_stream_using_custom_auth)
|
||||
ORDER BY si.ends
|
||||
SQL;
|
||||
return Application_Common_Database::prepareAndExecute( $sql, array(
|
||||
':startTime' => $p_startTime,
|
||||
':endTime' => $p_endTime), 'all');
|
||||
}
|
||||
|
||||
public function isRepeating()
|
||||
{
|
||||
return $this->getShow()->isRepeating();
|
||||
}
|
||||
}
|
1202
legacy/application/models/StoredFile.php
Normal file
1202
legacy/application/models/StoredFile.php
Normal file
File diff suppressed because it is too large
Load diff
536
legacy/application/models/StreamSetting.php
Normal file
536
legacy/application/models/StreamSetting.php
Normal file
|
@ -0,0 +1,536 @@
|
|||
<?php
|
||||
|
||||
define("MAX_NUM_STREAMS", 4);
|
||||
|
||||
class Application_Model_StreamSetting
|
||||
{
|
||||
public static function setValue($key, $value, $type)
|
||||
{
|
||||
$con = Propel::getConnection();
|
||||
|
||||
// Check if key already exists
|
||||
$sql = "SELECT COUNT(*) FROM cc_stream_setting"
|
||||
." WHERE keyname = :key";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(':key', $key);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
$result = $stmt->fetchColumn(0);
|
||||
} else {
|
||||
$msg = implode(',', $stmt->errorInfo());
|
||||
throw new Exception("Error: $msg");
|
||||
}
|
||||
|
||||
if ($result == 1) {
|
||||
$sql = "UPDATE cc_stream_setting"
|
||||
." SET value = :value, type = :type"
|
||||
." WHERE keyname = :key";
|
||||
} else {
|
||||
$sql = "INSERT INTO cc_stream_setting (keyname, value, type)"
|
||||
." VALUES (:key, :value, :type)";
|
||||
}
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(':key', $key);
|
||||
$stmt->bindParam(':value', $value);
|
||||
$stmt->bindParam(':type', $type);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
//do nothing
|
||||
} else {
|
||||
$msg = implode(',', $stmt->errorInfo());
|
||||
throw new Exception("Error: $msg");
|
||||
}
|
||||
}
|
||||
|
||||
public static function getValue($key, $default="")
|
||||
{
|
||||
$con = Propel::getConnection();
|
||||
|
||||
//Check if key already exists
|
||||
$sql = "SELECT value FROM cc_stream_setting"
|
||||
." WHERE keyname = :key";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(':key', $key);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
$result = $stmt->fetchColumn(0);
|
||||
} else {
|
||||
$msg = implode(',', $stmt->errorInfo());
|
||||
throw new Exception("Error: $msg");
|
||||
}
|
||||
|
||||
return $result ? $result : $default;
|
||||
}
|
||||
|
||||
public static function getEnabledStreamData()
|
||||
{
|
||||
$streams = Array();
|
||||
$streamIds = self::getEnabledStreamIds();
|
||||
foreach ($streamIds as $id) {
|
||||
$streamData = self::getStreamData($id);
|
||||
$prefix = $id."_";
|
||||
$host = $streamData[$prefix."host"];
|
||||
$port = $streamData[$prefix."port"];
|
||||
$mount = $streamData[$prefix."mount"];
|
||||
if ($streamData[$prefix."output"] == "shoutcast") {
|
||||
$url = "http://$host:$port/;"; //The semi-colon is important to make Shoutcast stream URLs play instead turn into a page.
|
||||
} else { //Icecast
|
||||
$url = "http://$host:$port/$mount";
|
||||
}
|
||||
$streams[$id] = Array(
|
||||
"url" => $url,
|
||||
"codec" => $streamData[$prefix."type"],
|
||||
"bitrate" => $streamData[$prefix."bitrate"],
|
||||
"mobile" => $streamData[$prefix."mobile"]
|
||||
);
|
||||
}
|
||||
return $streams;
|
||||
}
|
||||
|
||||
/* Returns the id's of all streams that are enabled in an array. An
|
||||
* example of the array returned in JSON notation is ["s1", "s2", "s3"] */
|
||||
public static function getEnabledStreamIds()
|
||||
{
|
||||
$con = Propel::getConnection();
|
||||
$sql = "SELECT * "
|
||||
."FROM cc_stream_setting "
|
||||
."WHERE keyname LIKE '%_enable' "
|
||||
."AND value='true'";
|
||||
|
||||
$ids = array();
|
||||
|
||||
$rows = Application_Common_Database::prepareAndExecute($sql, array(), 'all');
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$ids[] = substr($row["keyname"], 0, strpos($row["keyname"], "_"));
|
||||
}
|
||||
|
||||
return $ids;
|
||||
}
|
||||
|
||||
/* Returns all information related to a specific stream. An example
|
||||
* of a stream id is 's1' or 's2'. */
|
||||
public static function getStreamData($p_streamId)
|
||||
{
|
||||
$rows = CcStreamSettingQuery::create()
|
||||
->filterByDbKeyName("${p_streamId}_%")
|
||||
->find();
|
||||
|
||||
//This is way too much code because someone made only stupid decisions about how
|
||||
//the layout of this table worked. The git history doesn't lie.
|
||||
$data = array();
|
||||
foreach ($rows as $row) {
|
||||
$key = $row->getDbKeyName();
|
||||
$value = $row->getDbValue();
|
||||
$type = $row->getDbType();
|
||||
//Fix stupid defaults so we end up with proper typing in our JSON
|
||||
if ($row->getDbType() == "boolean") {
|
||||
if (empty($value)) {
|
||||
//In Python, there is no way to tell the difference between ints and booleans,
|
||||
//which we need to differentiate between for when we're generating the Liquidsoap
|
||||
//config file. Returning booleans as a string is a workaround that lets us do that.
|
||||
$value = "false";
|
||||
}
|
||||
$data[$key] = $value;
|
||||
}
|
||||
elseif ($row->getDbType() == "integer") {
|
||||
if (empty($value)) {
|
||||
$value = 0;
|
||||
}
|
||||
$data[$key] = intval($value);
|
||||
}
|
||||
else {
|
||||
$data[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
//Add in defaults in case they don't exist in the database.
|
||||
$keyPrefix = $p_streamId . '_';
|
||||
self::ensureKeyExists($keyPrefix . 'admin_pass', $data);
|
||||
self::ensureKeyExists($keyPrefix . 'admin_user', $data);
|
||||
self::ensureKeyExists($keyPrefix . 'bitrate', $data, 128);
|
||||
self::ensureKeyExists($keyPrefix . 'channels', $data, "stereo");
|
||||
self::ensureKeyExists($keyPrefix . 'description', $data);
|
||||
self::ensureKeyExists($keyPrefix . 'enable', $data, "false");
|
||||
self::ensureKeyExists($keyPrefix . 'genre', $data);
|
||||
self::ensureKeyExists($keyPrefix . 'host', $data);
|
||||
self::ensureKeyExists($keyPrefix . 'liquidsoap_error', $data, "waiting");
|
||||
self::ensureKeyExists($keyPrefix . 'mount', $data);
|
||||
self::ensureKeyExists($keyPrefix . 'name', $data);
|
||||
self::ensureKeyExists($keyPrefix . 'output', $data);
|
||||
self::ensureKeyExists($keyPrefix . 'pass', $data);
|
||||
self::ensureKeyExists($keyPrefix . 'port', $data, 8000);
|
||||
self::ensureKeyExists($keyPrefix . 'type', $data);
|
||||
self::ensureKeyExists($keyPrefix . 'url', $data);
|
||||
self::ensureKeyExists($keyPrefix . 'user', $data);
|
||||
self::ensureKeyExists($keyPrefix . 'mobile', $data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/* Similar to getStreamData, but removes all sX prefixes to
|
||||
* make data easier to iterate over */
|
||||
public static function getStreamDataNormalized($p_streamId)
|
||||
{
|
||||
$settings = self::getStreamData($p_streamId);
|
||||
foreach ($settings as $key => $value)
|
||||
{
|
||||
unset($settings[$key]);
|
||||
$newKey = substr($key, strlen($p_streamId)+1); //$p_streamId is assumed to be the key prefix.
|
||||
$settings[$newKey] = $value;
|
||||
}
|
||||
return $settings;
|
||||
}
|
||||
|
||||
private static function ensureKeyExists($key, &$array, $default='')
|
||||
{
|
||||
if (!array_key_exists($key, $array)) {
|
||||
$array[$key] = $default;
|
||||
}
|
||||
return $array;
|
||||
}
|
||||
|
||||
public static function getStreamSetting()
|
||||
{
|
||||
$settings = array();
|
||||
$numStreams = MAX_NUM_STREAMS;
|
||||
for ($streamIdx = 1; $streamIdx <= $numStreams; $streamIdx++)
|
||||
{
|
||||
$settings = array_merge($settings, self::getStreamData("s" . $streamIdx));
|
||||
}
|
||||
$settings["master_live_stream_port"] = self::getMasterLiveStreamPort();
|
||||
$settings["master_live_stream_mp"] = self::getMasterLiveStreamMountPoint();
|
||||
$settings["dj_live_stream_port"] = self::getDjLiveStreamPort();
|
||||
$settings["dj_live_stream_mp"] = self::getDjLiveStreamMountPoint();
|
||||
$settings["off_air_meta"] = self::getOffAirMeta();
|
||||
$settings["icecast_vorbis_metadata"] = self::getIcecastVorbisMetadata();
|
||||
$settings["output_sound_device"] = self::getOutputSoundDevice();
|
||||
$settings["output_sound_device_type"] = self::getOutputSoundDeviceType();
|
||||
return $settings;
|
||||
}
|
||||
|
||||
|
||||
private static function saveStreamSetting($key, $value)
|
||||
{
|
||||
$stream_setting = CcStreamSettingQuery::create()->filterByDbKeyName($key)->findOne();
|
||||
if (is_null($stream_setting)) {
|
||||
//throw new Exception("Keyname $key does not exist!");
|
||||
$stream_setting = new CcStreamSetting();
|
||||
$stream_setting->setDbKeyName($key);
|
||||
$stream_setting->setDbType("");
|
||||
}
|
||||
|
||||
$stream_setting->setDbValue($value);
|
||||
$stream_setting->save();
|
||||
}
|
||||
|
||||
/*
|
||||
* function that take all the information of stream and sets them.
|
||||
* This is used by stream setting via UI.
|
||||
*
|
||||
* @param $data - array that contains all the data. $data is [][] which
|
||||
* contains multiple stream information
|
||||
*/
|
||||
public static function setStreamSetting($data)
|
||||
{
|
||||
foreach ($data as $key => $d) {
|
||||
if ($key == "output_sound_device" || $key == "icecast_vorbis_metadata") {
|
||||
$v = ($d == 1) ? "true" : "false";
|
||||
|
||||
self::saveStreamSetting($key, $v);
|
||||
} elseif ($key == "output_sound_device_type") {
|
||||
self::saveStreamSetting($key, $d);
|
||||
} elseif (is_array($d)) {
|
||||
$temp = explode('_', $key);
|
||||
$prefix = $temp[0];
|
||||
// SAAS-876 - If we're using Airtime Pro streaming, set the stream to use the default settings
|
||||
if (!Application_Model_Preference::getUsingCustomStreamSettings()) {
|
||||
$d = array_merge($d, static::getDefaults($prefix));
|
||||
}
|
||||
foreach ($d as $k => $v) {
|
||||
$keyname = $prefix . "_" . $k;
|
||||
if ($k == 'enable') {
|
||||
$v = $d['enable'] == 1 ? 'true' : 'false';
|
||||
}
|
||||
$v = trim($v);
|
||||
if ($k != 'admin_pass') {
|
||||
self::saveStreamSetting($keyname, $v);
|
||||
/* We use 'xxxxxx' as the admin password placeholder so we
|
||||
* only want to save it when it is a different string
|
||||
*/
|
||||
} elseif ($v != 'xxxxxx') {
|
||||
self::saveStreamSetting($keyname, $v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* SAAS-876 - Get the default stream settings values for Airtime Pro streaming
|
||||
*
|
||||
* @param int $prefix
|
||||
*
|
||||
* @return array array of default stream setting values
|
||||
*/
|
||||
public static function getDefaults($prefix) {
|
||||
$config = Config::getConfig();
|
||||
return array(
|
||||
'host' => $config['baseUrl'],
|
||||
'port' => DEFAULT_ICECAST_PORT,
|
||||
'output' => 'icecast',
|
||||
'user' => $config['stationId'],
|
||||
'pass' => Application_Model_Preference::getDefaultIcecastPassword(),
|
||||
// Manually setting default mountpoint
|
||||
'mount' => 'airtime_128',
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets individual stream setting.
|
||||
*
|
||||
* $data - data array. $data is [].
|
||||
* TODO: Make this SQL a prepared statement!
|
||||
*
|
||||
* Do not remove this function. It is called by airtime-system.php
|
||||
*/
|
||||
public static function setIndividualStreamSetting($data)
|
||||
{
|
||||
foreach ($data as $keyname => $v) {
|
||||
$sql = "UPDATE cc_stream_setting SET value=:v WHERE keyname=:keyname";
|
||||
$map = array(":v" => $v, ":keyname"=>$keyname);
|
||||
|
||||
$res = Application_Common_Database::prepareAndExecute($sql, $map,
|
||||
Application_Common_Database::EXECUTE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Stores liquidsoap status if $boot_time > save time.
|
||||
* save time is the time that user clicked save on stream setting page
|
||||
*/
|
||||
public static function setLiquidsoapError($stream_id, $msg, $boot_time=null)
|
||||
{
|
||||
$con = Propel::getConnection();
|
||||
|
||||
$update_time = Application_Model_Preference::GetStreamUpdateTimestemp();
|
||||
|
||||
if ($boot_time == null || $boot_time > $update_time) {
|
||||
$keyname = "s".$stream_id."_liquidsoap_error";
|
||||
$sql = "SELECT COUNT(*) FROM cc_stream_setting"
|
||||
." WHERE keyname = :keyname";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(':keyname', $keyname);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
$result= $stmt->fetchColumn(0);
|
||||
} else {
|
||||
$msg = implode(',', $stmt->errorInfo());
|
||||
throw new Exception("Error: $msg");
|
||||
}
|
||||
|
||||
if ($result == 1) {
|
||||
$sql = "UPDATE cc_stream_setting"
|
||||
." SET value = :msg"
|
||||
." WHERE keyname = :keyname";
|
||||
} else {
|
||||
$sql = "INSERT INTO cc_stream_setting (keyname, value, type)"
|
||||
." VALUES (:keyname, :msg, 'string')";
|
||||
}
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(':keyname', $keyname);
|
||||
$stmt->bindParam(':msg', $msg);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
//do nothing
|
||||
} else {
|
||||
$msg = implode(',', $stmt->errorInfo());
|
||||
throw new Exception("Error: $msg");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function getLiquidsoapError($stream_id)
|
||||
{
|
||||
$con = Propel::getConnection();
|
||||
|
||||
$keyname = "s".$stream_id."_liquidsoap_error";
|
||||
$sql = "SELECT value FROM cc_stream_setting"
|
||||
." WHERE keyname = :keyname";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(':keyname', $keyname);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
$result= $stmt->fetchColumn(0);
|
||||
} else {
|
||||
$msg = implode(',', $stmt->errorInfo());
|
||||
throw new Exception("Error: $msg");
|
||||
}
|
||||
|
||||
return ($result !== false) ? $result : null;
|
||||
}
|
||||
|
||||
public static function getStreamEnabled($stream_id)
|
||||
{
|
||||
$con = Propel::getConnection();
|
||||
|
||||
$keyname = "s" . $stream_id . "_enable";
|
||||
$sql = "SELECT value FROM cc_stream_setting"
|
||||
." WHERE keyname = :keyname";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(':keyname', $keyname);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
$result= $stmt->fetchColumn(0);
|
||||
} else {
|
||||
$msg = implode(',', $stmt->errorInfo());
|
||||
throw new Exception("Error: $msg");
|
||||
}
|
||||
|
||||
return ($result != 'false');
|
||||
}
|
||||
|
||||
/*
|
||||
* Only returns info that is needed for data collection
|
||||
* returns array('s1'=>array(keyname=>value))
|
||||
*/
|
||||
public static function getStreamInfoForDataCollection()
|
||||
{
|
||||
$con = Propel::getConnection();
|
||||
|
||||
$out = array();
|
||||
$enabled_stream = self::getEnabledStreamIds();
|
||||
|
||||
foreach ($enabled_stream as $stream) {
|
||||
$keys = array("{$stream}_output", "{$stream}_type", "{$stream}_bitrate", "{$stream}_host");
|
||||
$key_csv = implode(',', $keys);
|
||||
|
||||
$sql = "SELECT keyname, value FROM cc_stream_setting"
|
||||
." WHERE keyname IN (:key_csv)";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(':key_csv', $key_csv);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
$rows = $stmt->fetchAll();
|
||||
} else {
|
||||
$msg = implode(',', $stmt->errorInfo());
|
||||
throw new Exception("Error: $msg");
|
||||
}
|
||||
|
||||
$info = array();
|
||||
foreach ($rows as $r) {
|
||||
$temp = explode("_", $r['keyname']);
|
||||
$info[$temp[1]] = $r['value'];
|
||||
$out[$stream] = $info;
|
||||
}
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
public static function setMasterLiveStreamPort($value)
|
||||
{
|
||||
self::setValue("master_live_stream_port", $value, "integer");
|
||||
}
|
||||
|
||||
public static function getMasterLiveStreamPort()
|
||||
{
|
||||
return self::getValue("master_live_stream_port", 8001);
|
||||
}
|
||||
|
||||
public static function setMasterLiveStreamMountPoint($value)
|
||||
{
|
||||
self::setValue("master_live_stream_mp", $value, "string");
|
||||
}
|
||||
|
||||
public static function getMasterLiveStreamMountPoint()
|
||||
{
|
||||
return self::getValue("master_live_stream_mp", "/master");
|
||||
}
|
||||
|
||||
public static function setDjLiveStreamPort($value)
|
||||
{
|
||||
self::setValue("dj_live_stream_port", $value, "integer");
|
||||
}
|
||||
|
||||
public static function getDjLiveStreamPort()
|
||||
{
|
||||
return self::getValue("dj_live_stream_port", 8002);
|
||||
}
|
||||
|
||||
public static function setDjLiveStreamMountPoint($value)
|
||||
{
|
||||
self::setValue("dj_live_stream_mp", $value, "string");
|
||||
}
|
||||
|
||||
public static function getDjLiveStreamMountPoint()
|
||||
{
|
||||
return self::getValue("dj_live_stream_mp", "/show");
|
||||
}
|
||||
|
||||
public static function getAdminUser($stream){
|
||||
return self::getValue($stream."_admin_user");
|
||||
}
|
||||
|
||||
public static function setAdminUser($stream, $v){
|
||||
self::setValue($stream."_admin_user", $v, "string");
|
||||
}
|
||||
|
||||
public static function getAdminPass($stream){
|
||||
return self::getValue($stream."_admin_pass");
|
||||
}
|
||||
|
||||
public static function setAdminPass($stream, $v){
|
||||
self::setValue($stream."_admin_pass", $v, "string");
|
||||
}
|
||||
|
||||
public static function getOffAirMeta(){
|
||||
return self::getValue("off_air_meta");
|
||||
}
|
||||
|
||||
public static function setOffAirMeta($offAirMeta){
|
||||
self::setValue("off_air_meta", $offAirMeta, "string");
|
||||
}
|
||||
|
||||
public static function GetAllListenerStatErrors(){
|
||||
|
||||
$sql = "SELECT * FROM cc_stream_setting WHERE keyname like :p1";
|
||||
$mounts = Application_Common_Database::prepareAndExecute($sql, array(':p1'=>'%_mount'));
|
||||
|
||||
$mps = array();
|
||||
|
||||
foreach($mounts as $mount) {
|
||||
$mps[] = "'" .$mount["value"] . "_listener_stat_error'";
|
||||
}
|
||||
|
||||
$in = implode(",", $mps);
|
||||
|
||||
$sql = "SELECT * FROM cc_stream_setting WHERE keyname IN ( $in )";
|
||||
return Application_Common_Database::prepareAndExecute($sql, array());
|
||||
}
|
||||
|
||||
public static function SetListenerStatError($key, $v) {
|
||||
self::setValue($key, $v, 'string');
|
||||
}
|
||||
|
||||
public static function getIcecastVorbisMetadata() {
|
||||
return self::getValue("icecast_vorbis_metadata", "");
|
||||
}
|
||||
|
||||
public static function getOutputSoundDevice() {
|
||||
return self::getValue("output_sound_device", "false");
|
||||
}
|
||||
|
||||
public static function getOutputSoundDeviceType() {
|
||||
return self::getValue("output_sound_device_type", "");
|
||||
}
|
||||
}
|
54
legacy/application/models/Subjects.php
Normal file
54
legacy/application/models/Subjects.php
Normal file
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
/**
|
||||
* Subj class
|
||||
*
|
||||
* users + groups
|
||||
* with "linearized recursive membership" ;)
|
||||
* (allow adding users to groups or groups to groups)
|
||||
*
|
||||
* @package Airtime
|
||||
* @subpackage Alib
|
||||
* @copyright 2010 Sourcefabric O.P.S.
|
||||
* @license http://www.gnu.org/licenses/gpl.txt
|
||||
*/
|
||||
class Application_Model_Subjects
|
||||
{
|
||||
/* ======================================================= public methods */
|
||||
|
||||
public static function increaseLoginAttempts($login)
|
||||
{
|
||||
$sql = "UPDATE cc_subjs SET login_attempts = login_attempts+1"
|
||||
." WHERE login=:login";
|
||||
|
||||
$map = array(":login" => $login);
|
||||
|
||||
$res = Application_Common_Database::prepareAndExecute($sql, $map,
|
||||
Application_Common_Database::EXECUTE);
|
||||
|
||||
return (intval($res) > 0);
|
||||
}
|
||||
|
||||
public static function resetLoginAttempts($login)
|
||||
{
|
||||
$sql = "UPDATE cc_subjs SET login_attempts = '0'"
|
||||
." WHERE login=:login";
|
||||
$map = array(":login" => $login);
|
||||
|
||||
$res = Application_Common_Database::prepareAndExecute($sql, $map,
|
||||
Application_Common_Database::EXECUTE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function getLoginAttempts($login)
|
||||
{
|
||||
$sql = "SELECT login_attempts FROM cc_subjs WHERE login=:login";
|
||||
$map = array(":login" => $login);
|
||||
|
||||
$res = Application_Common_Database::prepareAndExecute($sql, $map,
|
||||
Application_Common_Database::COLUMN);
|
||||
|
||||
return ($res !== false) ? $res : 0;
|
||||
}
|
||||
|
||||
} // class Subjects
|
245
legacy/application/models/Systemstatus.php
Normal file
245
legacy/application/models/Systemstatus.php
Normal file
|
@ -0,0 +1,245 @@
|
|||
<?php
|
||||
|
||||
class Application_Model_Systemstatus
|
||||
{
|
||||
|
||||
public static function GetMonitStatus($p_ip)
|
||||
{
|
||||
$CC_CONFIG = Config::getConfig();
|
||||
// $monit_user = $CC_CONFIG['monit_user'];
|
||||
// $monit_password = $CC_CONFIG['monit_password'];
|
||||
|
||||
$url = "http://$p_ip:2812/_status?format=xml";
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
// curl_setopt($ch, CURLOPT_USERPWD, "$monit_user:$monit_password");
|
||||
//wait a max of 3 seconds before aborting connection attempt
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
|
||||
$result = curl_exec($ch);
|
||||
|
||||
$info = curl_getinfo($ch);
|
||||
curl_close($ch);
|
||||
|
||||
$docRoot = null;
|
||||
if ($result !== FALSE && $info["http_code"] === 200) {
|
||||
if ($result != "") {
|
||||
$xmlDoc = new DOMDocument();
|
||||
$xmlDoc->loadXML($result);
|
||||
$docRoot = $xmlDoc->documentElement;
|
||||
}
|
||||
}
|
||||
|
||||
return $docRoot;
|
||||
}
|
||||
|
||||
public static function ExtractServiceInformation($p_docRoot, $p_serviceName)
|
||||
{
|
||||
$starting = array(
|
||||
"name"=>"",
|
||||
"process_id"=>"STARTING...",
|
||||
"uptime_seconds"=>"-1",
|
||||
"status"=>0,
|
||||
"memory_perc"=>"0%",
|
||||
"memory_kb"=>"0",
|
||||
"cpu_perc"=>"0%");
|
||||
|
||||
$notMonitored = array(
|
||||
"name"=>$p_serviceName,
|
||||
"process_id"=>"NOT MONITORED",
|
||||
"uptime_seconds"=>"1",
|
||||
"status"=>1,
|
||||
"memory_perc"=>"0%",
|
||||
"memory_kb"=>"0",
|
||||
"cpu_perc"=>"0%"
|
||||
);
|
||||
|
||||
$notRunning = array(
|
||||
"name"=>$p_serviceName,
|
||||
"process_id"=>"FAILED",
|
||||
"uptime_seconds"=>"-1",
|
||||
"status"=>0,
|
||||
"memory_perc"=>"0%",
|
||||
"memory_kb"=>"0",
|
||||
"cpu_perc"=>"0%"
|
||||
);
|
||||
$data = $notRunning;
|
||||
|
||||
if (!is_null($p_docRoot)) {
|
||||
foreach ($p_docRoot->getElementsByTagName("service") AS $item) {
|
||||
if ($item->getElementsByTagName("name")->item(0)->nodeValue == $p_serviceName) {
|
||||
|
||||
$monitor = $item->getElementsByTagName("monitor");
|
||||
if ($monitor->length > 0) {
|
||||
$status = $monitor->item(0)->nodeValue;
|
||||
if ($status == "2") {
|
||||
$data = $starting;
|
||||
} elseif ($status == 1) {
|
||||
//is monitored, but is it running?
|
||||
$pid = $item->getElementsByTagName("pid");
|
||||
if ($pid->length == 0) {
|
||||
$data = $notRunning;
|
||||
} else {
|
||||
//running!
|
||||
}
|
||||
} elseif ($status == 0) {
|
||||
$data = $notMonitored;
|
||||
}
|
||||
}
|
||||
|
||||
$process_id = $item->getElementsByTagName("name");
|
||||
if ($process_id->length > 0) {
|
||||
$data["name"] = $process_id->item(0)->nodeValue;
|
||||
}
|
||||
|
||||
$process_id = $item->getElementsByTagName("pid");
|
||||
if ($process_id->length > 0) {
|
||||
$data["process_id"] = $process_id->item(0)->nodeValue;
|
||||
$data["status"] = 0;
|
||||
}
|
||||
|
||||
$uptime = $item->getElementsByTagName("uptime");
|
||||
if ($uptime->length > 0) {
|
||||
$data["uptime_seconds"] = $uptime->item(0)->nodeValue;
|
||||
}
|
||||
|
||||
$memory = $item->getElementsByTagName("memory");
|
||||
if ($memory->length > 0) {
|
||||
$data["memory_perc"] = $memory->item(0)->getElementsByTagName("percenttotal")->item(0)->nodeValue."%";
|
||||
$data["memory_kb"] = $memory->item(0)->getElementsByTagName("kilobytetotal")->item(0)->nodeValue;
|
||||
}
|
||||
|
||||
$cpu = $item->getElementsByTagName("cpu");
|
||||
if ($cpu->length > 0) {
|
||||
$data["cpu_perc"] = $cpu->item(0)->getElementsByTagName("percent")->item(0)->nodeValue."%";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public static function GetPlatformInfo()
|
||||
{
|
||||
$keys = array("release", "machine", "memory", "swap");
|
||||
$data = array();
|
||||
foreach ($keys as $key) {
|
||||
$data[$key] = "UNKNOWN";
|
||||
}
|
||||
|
||||
$docRoot = self::GetMonitStatus("localhost");
|
||||
if (!is_null($docRoot)) {
|
||||
foreach ($docRoot->getElementsByTagName("platform") AS $item) {
|
||||
foreach ($keys as $key) {
|
||||
$keyElement = $item->getElementsByTagName($key);
|
||||
if ($keyElement->length > 0) {
|
||||
$data[$key] = $keyElement->item(0)->nodeValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public static function GetPypoStatus()
|
||||
{
|
||||
$component = CcServiceRegisterQuery::create()->findOneByDbName("pypo");
|
||||
if (is_null($component)) {
|
||||
return null;
|
||||
} else {
|
||||
$ip = $component->getDbIp();
|
||||
|
||||
$docRoot = self::GetMonitStatus($ip);
|
||||
$data = self::ExtractServiceInformation($docRoot, "airtime-playout");
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
public static function GetLiquidsoapStatus()
|
||||
{
|
||||
$component = CcServiceRegisterQuery::create()->findOneByDbName("pypo");
|
||||
if (is_null($component)) {
|
||||
return null;
|
||||
} else {
|
||||
$ip = $component->getDbIp();
|
||||
|
||||
$docRoot = self::GetMonitStatus($ip);
|
||||
$data = self::ExtractServiceInformation($docRoot, "airtime-liquidsoap");
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
public static function GetMediaMonitorStatus()
|
||||
{
|
||||
$component = CcServiceRegisterQuery::create()->findOneByDbName("media-monitor");
|
||||
if (is_null($component)) {
|
||||
return null;
|
||||
} else {
|
||||
$ip = $component->getDbIp();
|
||||
|
||||
$docRoot = self::GetMonitStatus($ip);
|
||||
$data = self::ExtractServiceInformation($docRoot, "airtime-analyzer");
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
public static function GetIcecastStatus()
|
||||
{
|
||||
$docRoot = self::GetMonitStatus("localhost");
|
||||
$data = self::ExtractServiceInformation($docRoot, "icecast2");
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public static function GetRabbitMqStatus()
|
||||
{
|
||||
if (isset($_SERVER["RABBITMQ_HOST"])) {
|
||||
$rabbitmq_host = $_SERVER["RABBITMQ_HOST"];
|
||||
} else {
|
||||
$rabbitmq_host = "localhost";
|
||||
}
|
||||
$docRoot = self::GetMonitStatus($rabbitmq_host);
|
||||
$data = self::ExtractServiceInformation($docRoot, "rabbitmq-server");
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public static function GetDiskInfo()
|
||||
{
|
||||
$partitions = array();
|
||||
/* First lets get all the watched directories. Then we can group them
|
||||
* into the same partitions by comparing the partition sizes. */
|
||||
$musicDirs = Application_Model_MusicDir::getWatchedDirs();
|
||||
$musicDirs[] = Application_Model_MusicDir::getStorDir();
|
||||
foreach ($musicDirs as $md) {
|
||||
$totalSpace = disk_total_space($md->getDirectory());
|
||||
if (!isset($partitions[$totalSpace])) {
|
||||
$partitions[$totalSpace] = new StdClass;
|
||||
$partitions[$totalSpace]->totalSpace = $totalSpace;
|
||||
$partitions[$totalSpace]->totalFreeSpace = disk_free_space($md->getDirectory());
|
||||
$partitions[$totalSpace]->usedSpace = $totalSpace - $partitions[$totalSpace]->totalFreeSpace;
|
||||
}
|
||||
$partitions[$totalSpace]->dirs[] = $md->getDirectory();
|
||||
}
|
||||
return array_values($partitions);
|
||||
}
|
||||
|
||||
public static function isDiskOverQuota()
|
||||
{
|
||||
$diskInfo = self::GetDiskInfo();
|
||||
$diskInfo = $diskInfo[0];
|
||||
$diskUsage = $diskInfo->totalSpace - $diskInfo->totalFreeSpace;
|
||||
if ($diskUsage > 0 && $diskUsage >= $diskInfo->totalSpace) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
173
legacy/application/models/Tracktype.php
Normal file
173
legacy/application/models/Tracktype.php
Normal file
|
@ -0,0 +1,173 @@
|
|||
<?php
|
||||
|
||||
class Application_Model_Tracktype
|
||||
{
|
||||
private $_tracktypeInstance;
|
||||
|
||||
public function __construct($tracktypeId)
|
||||
{
|
||||
if (empty($tracktypeId)) {
|
||||
$this->_tracktypeInstance = $this->createTracktype();
|
||||
} else {
|
||||
$this->_tracktypeInstance = CcTracktypesQuery::create()->findPK($tracktypeId);
|
||||
|
||||
if (is_null($this->_tracktypeInstance)) {
|
||||
throw new Exception();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return $this->_tracktypeInstance->getDbId();
|
||||
}
|
||||
|
||||
public function setCode($code)
|
||||
{
|
||||
$tracktype = $this->_tracktypeInstance;
|
||||
$tracktype->setDbCode($code);
|
||||
}
|
||||
|
||||
public function setTypeName($typeName)
|
||||
{
|
||||
$tracktype = $this->_tracktypeInstance;
|
||||
$tracktype->setDbTypeName($typeName);
|
||||
}
|
||||
|
||||
public function setDescription($description)
|
||||
{
|
||||
$tracktype = $this->_tracktypeInstance;
|
||||
$tracktype->setDbDescription($description);
|
||||
}
|
||||
|
||||
public function setVisibility($visibility)
|
||||
{
|
||||
$tracktype = $this->_tracktypeInstance;
|
||||
$tracktype->setDbVisibility($visibility);
|
||||
}
|
||||
|
||||
public function getCode()
|
||||
{
|
||||
$tracktype = $this->_tracktypeInstance;
|
||||
|
||||
return $tracktype->getDbCode();
|
||||
}
|
||||
|
||||
public function getTypeName()
|
||||
{
|
||||
$tracktype = $this->_tracktypeInstance;
|
||||
|
||||
return $tracktype->getDbTypeName();
|
||||
}
|
||||
|
||||
public function getDescription()
|
||||
{
|
||||
$tracktype = $this->_tracktypeInstance;
|
||||
|
||||
return $tracktype->getDbDescription();
|
||||
}
|
||||
|
||||
public function getVisibility()
|
||||
{
|
||||
$tracktype = $this->_tracktypeInstance;
|
||||
|
||||
return $tracktype->getDbVisibility();
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
$this->_tracktypeInstance->save();
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
if (!$this->_tracktypeInstance->isDeleted()) {
|
||||
$this->_tracktypeInstance->delete();
|
||||
}
|
||||
}
|
||||
|
||||
private function createTracktype()
|
||||
{
|
||||
$tracktype = new CcTracktypes();
|
||||
|
||||
return $tracktype;
|
||||
}
|
||||
|
||||
public static function getTracktypes($search=null)
|
||||
{
|
||||
return Application_Model_Tracktype::getTracktypesData(array(true), $search);
|
||||
}
|
||||
|
||||
public static function getTracktypesData(array $visible, $search=null)
|
||||
{
|
||||
$con = Propel::getConnection();
|
||||
|
||||
$sql_gen = "SELECT id, code, type_name, description FROM cc_track_types ";
|
||||
|
||||
$visibility = array();
|
||||
$params = array();
|
||||
for ($i=0; $i<count($visible); $i++) {
|
||||
$p = ":visibility{$i}";
|
||||
$visibility[] = "visibility = $p";
|
||||
$params[$p] = $visible[$i];
|
||||
}
|
||||
|
||||
$sql_type = join(" OR ", $visibility);
|
||||
|
||||
$sql = $sql_gen ." WHERE (". $sql_type.") ";
|
||||
|
||||
$sql .= " AND code ILIKE :search";
|
||||
$params[":search"] = "%$search%";
|
||||
|
||||
$sql = $sql ." ORDER BY id";
|
||||
|
||||
return Application_Common_Database::prepareAndExecute($sql, $params, "all");
|
||||
}
|
||||
|
||||
public static function getTracktypeCount()
|
||||
{
|
||||
$sql_gen = "SELECT count(*) AS cnt FROM cc_track_types";
|
||||
|
||||
$query = Application_Common_Database::prepareAndExecute($sql_gen, array(),
|
||||
Application_Common_Database::COLUMN);
|
||||
|
||||
return ($query !== false) ? $query : null;
|
||||
}
|
||||
|
||||
public static function getTracktypesDataTablesInfo($datatables)
|
||||
{
|
||||
|
||||
$con = Propel::getConnection(CcTracktypesPeer::DATABASE_NAME);
|
||||
|
||||
$displayColumns = array("id", "code", "type_name", "description", "visibility");
|
||||
$fromTable = "cc_track_types";
|
||||
$tracktypename = "";
|
||||
|
||||
$res = Application_Model_Datatables::findEntries($con, $displayColumns, $fromTable, $datatables);
|
||||
|
||||
foreach($res['aaData'] as $key => &$record){
|
||||
if ($record['code'] == $tracktypename) {
|
||||
$record['delete'] = "self";
|
||||
} else {
|
||||
$record['delete'] = "";
|
||||
}
|
||||
$record = array_map('htmlspecialchars', $record);
|
||||
}
|
||||
|
||||
$res['aaData'] = array_values($res['aaData']);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
public static function getTracktypeData($id)
|
||||
{
|
||||
$sql = <<<SQL
|
||||
SELECT code, type_name, description, visibility, id
|
||||
FROM cc_track_types
|
||||
WHERE id = :id
|
||||
SQL;
|
||||
return Application_Common_Database::prepareAndExecute($sql, array(
|
||||
":id" => $id), 'single');
|
||||
}
|
||||
|
||||
}
|
403
legacy/application/models/User.php
Normal file
403
legacy/application/models/User.php
Normal file
|
@ -0,0 +1,403 @@
|
|||
<?php
|
||||
|
||||
class Application_Model_User
|
||||
{
|
||||
private $_userInstance;
|
||||
|
||||
public function __construct($userId)
|
||||
{
|
||||
if (empty($userId)) {
|
||||
$this->_userInstance = $this->createUser();
|
||||
} else {
|
||||
$this->_userInstance = CcSubjsQuery::create()->findPK($userId);
|
||||
|
||||
if (is_null($this->_userInstance)) {
|
||||
throw new Exception();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return $this->_userInstance->getDbId();
|
||||
}
|
||||
|
||||
public function isGuest()
|
||||
{
|
||||
return $this->getType() == UTYPE_GUEST;
|
||||
}
|
||||
|
||||
public function isHostOfShow($showId)
|
||||
{
|
||||
$userId = $this->_userInstance->getDbId();
|
||||
return CcShowHostsQuery::create()
|
||||
->filterByDbShow($showId)
|
||||
->filterByDbHost($userId)->count() > 0;
|
||||
}
|
||||
|
||||
public function isHost()
|
||||
{
|
||||
return $this->isUserType(UTYPE_HOST);
|
||||
}
|
||||
|
||||
public function isPM()
|
||||
{
|
||||
return $this->isUserType(UTYPE_PROGRAM_MANAGER);
|
||||
}
|
||||
|
||||
public function isAdmin()
|
||||
{
|
||||
return $this->isUserType(UTYPE_ADMIN);
|
||||
}
|
||||
|
||||
public function isSuperAdmin()
|
||||
{
|
||||
return $this->isUserType(UTYPE_SUPERADMIN);
|
||||
}
|
||||
|
||||
public function canSchedule($p_showId)
|
||||
{
|
||||
$type = $this->getType();
|
||||
$result = false;
|
||||
|
||||
if ($this->isAdmin() ||
|
||||
$this->isSuperAdmin() ||
|
||||
$this->isPM() ||
|
||||
self::isHostOfShow($p_showId)) {
|
||||
$result = true;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function isSourcefabricAdmin()
|
||||
{
|
||||
$username = $this->getLogin();
|
||||
if ($username == "sourcefabric_admin") {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO : refactor code to only accept arrays for isUserType and
|
||||
// simplify code even further
|
||||
public function isUserType($type)
|
||||
{
|
||||
if (!is_array($type)) {
|
||||
$type = array($type);
|
||||
}
|
||||
$real_type = $this->_userInstance->getDbType();
|
||||
return in_array($real_type, $type);
|
||||
}
|
||||
|
||||
public function setLogin($login)
|
||||
{
|
||||
$user = $this->_userInstance;
|
||||
$user->setDbLogin($login);
|
||||
}
|
||||
|
||||
public function setPassword($password)
|
||||
{
|
||||
$user = $this->_userInstance;
|
||||
$user->setDbPass(md5($password));
|
||||
}
|
||||
|
||||
public function setFirstName($firstName)
|
||||
{
|
||||
$user = $this->_userInstance;
|
||||
$user->setDbFirstName($firstName);
|
||||
}
|
||||
|
||||
public function setLastName($lastName)
|
||||
{
|
||||
$user = $this->_userInstance;
|
||||
$user->setDbLastName($lastName);
|
||||
}
|
||||
|
||||
public function setType($type)
|
||||
{
|
||||
$user = $this->_userInstance;
|
||||
$user->setDbType($type);
|
||||
}
|
||||
|
||||
public function setEmail($email)
|
||||
{
|
||||
$user = $this->_userInstance;
|
||||
$user->setDbEmail(strtolower($email));
|
||||
}
|
||||
|
||||
public function setCellPhone($cellPhone)
|
||||
{
|
||||
$user = $this->_userInstance;
|
||||
$user->setDbCellPhone($cellPhone);
|
||||
}
|
||||
|
||||
public function setSkype($skype)
|
||||
{
|
||||
$user = $this->_userInstance;
|
||||
$user->setDbSkypeContact($skype);
|
||||
}
|
||||
|
||||
public function setJabber($jabber)
|
||||
{
|
||||
$user = $this->_userInstance;
|
||||
$user->setDbJabberContact($jabber);
|
||||
}
|
||||
|
||||
public function getLogin()
|
||||
{
|
||||
$user = $this->_userInstance;
|
||||
|
||||
return $user->getDbLogin();
|
||||
}
|
||||
|
||||
public function getPassword()
|
||||
{
|
||||
$user = $this->_userInstance;
|
||||
|
||||
return $user->getDbPass();
|
||||
}
|
||||
|
||||
public function getFirstName()
|
||||
{
|
||||
$user = $this->_userInstance;
|
||||
|
||||
return $user->getDbFirstName();
|
||||
}
|
||||
|
||||
public function getLastName()
|
||||
{
|
||||
$user = $this->_userInstance;
|
||||
|
||||
return $user->getDbLastName();
|
||||
}
|
||||
|
||||
public function getType()
|
||||
{
|
||||
$user = $this->_userInstance;
|
||||
|
||||
return $user->getDbType();
|
||||
}
|
||||
|
||||
public function getEmail()
|
||||
{
|
||||
$user = $this->_userInstance;
|
||||
|
||||
return $user->getDbEmail();
|
||||
}
|
||||
|
||||
public function getCellPhone()
|
||||
{
|
||||
$user = $this->_userInstance;
|
||||
|
||||
return $user->getDbCellPhone();
|
||||
}
|
||||
|
||||
public function getSkype()
|
||||
{
|
||||
$user = $this->_userInstance;
|
||||
|
||||
return $user->getDbSkypeContact();
|
||||
}
|
||||
|
||||
public function getJabber()
|
||||
{
|
||||
$user = $this->_userInstance;
|
||||
|
||||
return $user->getDbJabberContact();
|
||||
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
$this->_userInstance->save();
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
if (!$this->_userInstance->isDeleted()) {
|
||||
$this->_userInstance->delete();
|
||||
}
|
||||
}
|
||||
public function getOwnedFiles()
|
||||
{
|
||||
$user = $this->_userInstance;
|
||||
// do we need a find call at the end here?
|
||||
return $user->getCcFilessRelatedByDbOwnerId();
|
||||
}
|
||||
|
||||
public function donateFilesTo($user) // $user is object not user id
|
||||
{
|
||||
$my_files = $this->getOwnedFiles();
|
||||
foreach ($my_files as $file) {
|
||||
$file->reassignTo($user);
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteAllFiles()
|
||||
{
|
||||
$my_files = $this->getOwnedFiles();
|
||||
foreach ($my_files as $file) {
|
||||
$file->delete();
|
||||
}
|
||||
}
|
||||
|
||||
private function createUser()
|
||||
{
|
||||
$user = new CcSubjs();
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
public static function getUsersOfType($type)
|
||||
{
|
||||
return CcSubjsQuery::create()->filterByDbType($type)->find();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first admin user from the database
|
||||
*
|
||||
* This function gets used in UserController in the delete action. The controller
|
||||
* uses it to figure out who to reassign the deleted users files to.
|
||||
*
|
||||
* @param $ignoreUser String optional userid of a user that shall be ignored when
|
||||
* when looking for the "first" admin.
|
||||
*
|
||||
* @return CcSubj|null
|
||||
*/
|
||||
public static function getFirstAdmin($ignoreUser = null) {
|
||||
$superAdmins = Application_Model_User::getUsersOfType('S');
|
||||
if (count($superAdmins) > 0) { // found superadmin => pick first one
|
||||
return $superAdmins[0];
|
||||
} else {
|
||||
// get all admin users
|
||||
$query = CcSubjsQuery::create()->filterByDbType('A');
|
||||
// ignore current user if one was specified
|
||||
if ($ignoreUser !== null) {
|
||||
$query->filterByDbId($ignoreUser, Criteria::NOT_EQUAL);
|
||||
}
|
||||
$admins = $query->find();
|
||||
if (count($admins) > 0) { // found admin => pick first one
|
||||
return $admins[0];
|
||||
}
|
||||
Logging::warn("Warning. no admins found in database");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static function getUsers(array $type, $search=null)
|
||||
{
|
||||
$con = Propel::getConnection();
|
||||
|
||||
$sql_gen = "SELECT login AS value, login AS label, id as index FROM cc_subjs ";
|
||||
|
||||
$types = array();
|
||||
$params = array();
|
||||
for ($i=0; $i<count($type); $i++) {
|
||||
$p = ":type{$i}";
|
||||
$types[] = "type = $p";
|
||||
$params[$p] = $type[$i];
|
||||
}
|
||||
|
||||
$sql_type = join(" OR ", $types);
|
||||
|
||||
$sql = $sql_gen ." WHERE (". $sql_type.") ";
|
||||
|
||||
$sql .= " AND login ILIKE :search";
|
||||
$params[":search"] = "%$search%";
|
||||
|
||||
$sql = $sql ." ORDER BY login";
|
||||
|
||||
return Application_Common_Database::prepareAndExecute($sql, $params, "all");
|
||||
}
|
||||
|
||||
public static function getUserCount()
|
||||
{
|
||||
$sql_gen = "SELECT count(*) AS cnt FROM cc_subjs";
|
||||
|
||||
$query = Application_Common_Database::prepareAndExecute($sql_gen, array(),
|
||||
Application_Common_Database::COLUMN);
|
||||
|
||||
return ($query !== false) ? $query : null;
|
||||
}
|
||||
|
||||
public static function getHosts($search=null)
|
||||
{
|
||||
return Application_Model_User::getUsers(array('H'), $search);
|
||||
}
|
||||
|
||||
public static function getNonGuestUsers($search=null)
|
||||
{
|
||||
return Application_Model_User::getUsers(array('H','A','S','P'), $search);
|
||||
}
|
||||
|
||||
public static function getUsersDataTablesInfo($datatables)
|
||||
{
|
||||
|
||||
$con = Propel::getConnection(CcSubjsPeer::DATABASE_NAME);
|
||||
|
||||
$displayColumns = array("id", "login", "first_name", "last_name", "type");
|
||||
$fromTable = "cc_subjs";
|
||||
|
||||
// get current user
|
||||
$username = "";
|
||||
$auth = Zend_Auth::getInstance();
|
||||
|
||||
if ($auth->hasIdentity()) {
|
||||
$username = $auth->getIdentity()->login;
|
||||
}
|
||||
|
||||
$res = Application_Model_Datatables::findEntries($con, $displayColumns, $fromTable, $datatables);
|
||||
|
||||
// mark record which is for the current user
|
||||
foreach($res['aaData'] as $key => &$record){
|
||||
if ($record['login'] == $username) {
|
||||
$record['delete'] = "self";
|
||||
} else {
|
||||
$record['delete'] = "";
|
||||
}
|
||||
|
||||
if($record['login'] == 'sourcefabric_admin'){
|
||||
//arrays in PHP are basically associative arrays that can be iterated in order.
|
||||
//Deleting an earlier element does not change the keys of elements that come after it. --MK
|
||||
unset($res['aaData'][$key]);
|
||||
$res['iTotalDisplayRecords']--;
|
||||
$res['iTotalRecords']--;
|
||||
}
|
||||
|
||||
$record = array_map('htmlspecialchars', $record);
|
||||
}
|
||||
|
||||
$res['aaData'] = array_values($res['aaData']);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
public static function getUserData($id)
|
||||
{
|
||||
$sql = <<<SQL
|
||||
SELECT login, first_name, last_name, type, id, email, cell_phone, skype_contact,
|
||||
jabber_contact
|
||||
FROM cc_subjs
|
||||
WHERE id = :id
|
||||
SQL;
|
||||
return Application_Common_Database::prepareAndExecute($sql, array(
|
||||
":id" => $id), 'single');
|
||||
}
|
||||
|
||||
public static function getCurrentUser()
|
||||
{
|
||||
$userinfo = Zend_Auth::getInstance()->getStorage()->read();
|
||||
if (is_null($userinfo)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return new self($userinfo->id);
|
||||
} catch (Exception $e) {
|
||||
//we get here if $userinfo->id is defined, but doesn't exist
|
||||
//in the database anymore.
|
||||
Zend_Auth::getInstance()->clearIdentity();
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
455
legacy/application/models/Webstream.php
Normal file
455
legacy/application/models/Webstream.php
Normal file
|
@ -0,0 +1,455 @@
|
|||
<?php
|
||||
|
||||
class Application_Model_Webstream implements Application_Model_LibraryEditable
|
||||
{
|
||||
private $id;
|
||||
|
||||
public function __construct($webstream)
|
||||
{
|
||||
//TODO: hacky...
|
||||
if (is_int($webstream)) {
|
||||
$this->webstream = CcWebstreamQuery::create()->findPK($webstream);
|
||||
if (is_null($this->webstream)) {
|
||||
throw new Exception();
|
||||
}
|
||||
} else {
|
||||
$this->webstream = $webstream;
|
||||
}
|
||||
}
|
||||
|
||||
public function getOrm()
|
||||
{
|
||||
return $this->webstream;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->webstream->getDbName();
|
||||
}
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return $this->webstream->getDbId();
|
||||
}
|
||||
|
||||
public function getCreatorId()
|
||||
{
|
||||
return $this->webstream->getDbCreatorId();
|
||||
}
|
||||
|
||||
public function getLastModified($p_type)
|
||||
{
|
||||
return $this->webstream->getDbMtime();
|
||||
}
|
||||
|
||||
public function getDefaultLength()
|
||||
{
|
||||
$dateString = $this->webstream->getDbLength();
|
||||
$arr = explode(":", $dateString);
|
||||
if (count($arr) == 3) {
|
||||
list($hours, $min, $sec) = $arr;
|
||||
$di = new DateInterval("PT{$hours}H{$min}M{$sec}S");
|
||||
|
||||
return $di->format("%Hh %Im");
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public function getLength()
|
||||
{
|
||||
return $this->getDefaultLength();
|
||||
}
|
||||
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->webstream->getDbDescription();
|
||||
}
|
||||
|
||||
public function getUrl()
|
||||
{
|
||||
return $this->webstream->getDbUrl();
|
||||
}
|
||||
|
||||
public function getMetadata()
|
||||
{
|
||||
$subjs = CcSubjsQuery::create()->findPK($this->webstream->getDbCreatorId());
|
||||
|
||||
$username = $subjs->getDbLogin();
|
||||
|
||||
return array(
|
||||
"name" => $this->webstream->getDbName(),
|
||||
"length" => $this->webstream->getDbLength(),
|
||||
"description" => $this->webstream->getDbDescription(),
|
||||
"login" => $username,
|
||||
"url" => $this->webstream->getDbUrl(),
|
||||
);
|
||||
}
|
||||
|
||||
public static function deleteStreams($p_ids, $p_userId)
|
||||
{
|
||||
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
|
||||
$user = new Application_Model_User($userInfo->id);
|
||||
$isAdminOrPM = $user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER));
|
||||
|
||||
if (!$isAdminOrPM) {
|
||||
//Make sure the user has ownership of ALL the selected webstreams before
|
||||
$leftOver = self::streamsNotOwnedByUser($p_ids, $p_userId);
|
||||
if (count($leftOver) == 0) {
|
||||
CcWebstreamQuery::create()->findPKs($p_ids)->delete();
|
||||
} else {
|
||||
throw new WebstreamNoPermissionException;
|
||||
}
|
||||
} else {
|
||||
CcWebstreamQuery::create()->findPKs($p_ids)->delete();
|
||||
}
|
||||
}
|
||||
|
||||
// This function returns that are not owen by $p_user_id among $p_ids
|
||||
private static function streamsNotOwnedByUser($p_ids, $p_userId)
|
||||
{
|
||||
$ownedByUser = CcWebstreamQuery::create()->filterByDbCreatorId($p_userId)->find()->getData();
|
||||
$ownedStreams = array();
|
||||
foreach ($ownedByUser as $pl) {
|
||||
if (in_array($pl->getDbId(), $p_ids)) {
|
||||
$ownedStreams[] = $pl->getDbId();
|
||||
}
|
||||
}
|
||||
|
||||
$leftOvers = array_diff($p_ids, $ownedStreams);
|
||||
|
||||
return $leftOvers;
|
||||
}
|
||||
|
||||
public static function analyzeFormData($parameters)
|
||||
{
|
||||
$valid = array("length" => array(true, ''),
|
||||
"url" => array(true, ''),
|
||||
"name" => array(true, ''));
|
||||
|
||||
$di = null;
|
||||
$length = $parameters["length"];
|
||||
$result = preg_match("/^(?:([0-9]{1,2})h)?\s*(?:([0-9]{1,2})m)?$/", $length, $matches);
|
||||
|
||||
$invalid_date_interval = false;
|
||||
if ($result == 1 && count($matches) == 2) {
|
||||
$hours = $matches[1];
|
||||
$minutes = 0;
|
||||
} elseif ($result == 1 && count($matches) == 3) {
|
||||
$hours = $matches[1];
|
||||
$minutes = $matches[2];
|
||||
} else {
|
||||
$invalid_date_interval = true;
|
||||
}
|
||||
|
||||
if (!$invalid_date_interval) {
|
||||
|
||||
//Due to the way our Regular Expression is set up, we could have $minutes or $hours
|
||||
//not set. Do simple test here
|
||||
if (!is_numeric($hours)) {
|
||||
$hours = 0;
|
||||
}
|
||||
if (!is_numeric($minutes)) {
|
||||
$minutes = 0;
|
||||
}
|
||||
|
||||
//minutes cannot be over 59. Need to convert anything > 59 minutes into hours.
|
||||
$hours += intval($minutes/60);
|
||||
$minutes = $minutes%60;
|
||||
|
||||
$di = new DateInterval("PT{$hours}H{$minutes}M");
|
||||
|
||||
$totalMinutes = $di->h * 60 + $di->i;
|
||||
|
||||
if ($totalMinutes == 0) {
|
||||
$valid['length'][0] = false;
|
||||
$valid['length'][1] = _('Length needs to be greater than 0 minutes');
|
||||
}
|
||||
|
||||
} else {
|
||||
$valid['length'][0] = false;
|
||||
$valid['length'][1] = _('Length should be of form "00h 00m"');
|
||||
}
|
||||
|
||||
$url = $parameters["url"];
|
||||
//simple validator that checks to make sure that the url starts with
|
||||
//http(s),
|
||||
//and that the domain is at least 1 letter long
|
||||
$result = preg_match("/^(http|https):\/\/.+/", $url, $matches);
|
||||
|
||||
$mime = null;
|
||||
$mediaUrl = null;
|
||||
if ($result == 0) {
|
||||
$valid['url'][0] = false;
|
||||
$valid['url'][1] = _('URL should be of form "http://domain"');
|
||||
} elseif (strlen($url) > 512) {
|
||||
$valid['url'][0] = false;
|
||||
$valid['url'][1] = _('URL should be 512 characters or less');
|
||||
} else {
|
||||
|
||||
try {
|
||||
list($mime, $content_length_found) = self::discoverStreamMime($url);
|
||||
if (is_null($mime)) {
|
||||
throw new Exception(_("No MIME type found for webstream."));
|
||||
}
|
||||
$mediaUrl = self::getMediaUrl($url, $mime, $content_length_found);
|
||||
|
||||
if (preg_match("/(x-mpegurl)|(xspf\+xml)|(pls\+xml)|(x-scpls)/", $mime)) {
|
||||
list($mime, $content_length_found) = self::discoverStreamMime($mediaUrl);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$valid['url'][0] = false;
|
||||
$valid['url'][1] = $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
$name = $parameters["name"];
|
||||
if (strlen($name) == 0) {
|
||||
$valid['name'][0] = false;
|
||||
$valid['name'][1] = _('Webstream name cannot be empty');
|
||||
}
|
||||
|
||||
$id = $parameters["id"];
|
||||
|
||||
return array($valid, $mime, $mediaUrl, $di);
|
||||
}
|
||||
|
||||
public static function isValid($analysis)
|
||||
{
|
||||
foreach ($analysis as $k => $v) {
|
||||
if ($v[0] === false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO : Fix this interface
|
||||
//This function should not be defined in the interface.
|
||||
public function setMetadata($key, $val)
|
||||
{
|
||||
throw new Exception("Not implemented.");
|
||||
}
|
||||
|
||||
public function setName($name)
|
||||
{
|
||||
$this->webstream->setDbName($name);
|
||||
}
|
||||
|
||||
public function setLastPlayed($timestamp)
|
||||
{
|
||||
$this->webstream->setDbLPtime($timestamp);
|
||||
$this->webstream->save();
|
||||
}
|
||||
|
||||
private static function getUrlData($url)
|
||||
{
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_HEADER, 0);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
|
||||
// grab URL and pass it to the browser
|
||||
//TODO: What if invalid url?
|
||||
$content = curl_exec($ch);
|
||||
|
||||
// close cURL resource, and free up system resources
|
||||
curl_close($ch);
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
private static function getXspfUrl($url)
|
||||
{
|
||||
$content = self::getUrlData($url);
|
||||
|
||||
$dom = new DOMDocument;
|
||||
//TODO: What if invalid xml?
|
||||
$dom->loadXML($content);
|
||||
$tracks = $dom->getElementsByTagName('track');
|
||||
|
||||
foreach ($tracks as $track) {
|
||||
$locations = $track->getElementsByTagName('location');
|
||||
foreach ($locations as $loc) {
|
||||
return $loc->nodeValue;
|
||||
}
|
||||
}
|
||||
|
||||
throw new Exception(_("Could not parse XSPF playlist"));
|
||||
}
|
||||
|
||||
private static function getPlsUrl($url)
|
||||
{
|
||||
$content = self::getUrlData($url);
|
||||
|
||||
$matches = array();
|
||||
$numStreams = 0; //Number of streams explicitly listed in the PLS.
|
||||
|
||||
if (preg_match("/NumberOfEntries=([0-9]*)/", $content, $matches) !== FALSE) {
|
||||
$numStreams = $matches[1];
|
||||
}
|
||||
|
||||
//Find all the stream URLs in the playlist
|
||||
if (preg_match_all("/File[0-9]*=(.*)/", $content, $matches) !== FALSE) {
|
||||
//This array contains all the streams! If we need fallback stream URLs in the future,
|
||||
//they're already in this array...
|
||||
return $matches[1][0];
|
||||
} else {
|
||||
throw new Exception(_("Could not parse PLS playlist"));
|
||||
}
|
||||
}
|
||||
|
||||
private static function getM3uUrl($url)
|
||||
{
|
||||
$content = self::getUrlData($url);
|
||||
|
||||
//split into lines:
|
||||
$delim = "\n";
|
||||
if (strpos($content, "\r\n") !== false) {
|
||||
$delim = "\r\n";
|
||||
}
|
||||
$lines = explode("$delim", $content);
|
||||
#$lines = preg_split('/$\R?^/m', $content);
|
||||
|
||||
if (count($lines) > 0) {
|
||||
return $lines[0];
|
||||
}
|
||||
|
||||
throw new Exception(_("Could not parse M3U playlist"));
|
||||
}
|
||||
|
||||
private static function getMediaUrl($url, $mime, $content_length_found)
|
||||
{
|
||||
|
||||
if (preg_match("/x-mpegurl/", $mime)) {
|
||||
$media_url = self::getM3uUrl($url);
|
||||
} elseif (preg_match("/xspf\+xml/", $mime)) {
|
||||
$media_url = self::getXspfUrl($url);
|
||||
} elseif (preg_match("/pls\+xml/", $mime) || preg_match("/x-scpls/", $mime)) {
|
||||
$media_url = self::getPlsUrl($url);
|
||||
} elseif (preg_match("/(mpeg|ogg|audio\/aacp|audio\/aac)/", $mime)) {
|
||||
if ($content_length_found) {
|
||||
throw new Exception(_("Invalid webstream - This appears to be a file download."));
|
||||
}
|
||||
$media_url = $url;
|
||||
} else {
|
||||
throw new Exception(sprintf(_("Unrecognized stream type: %s"), $mime));
|
||||
}
|
||||
|
||||
return $media_url;
|
||||
|
||||
}
|
||||
|
||||
/* PHP get_headers has an annoying property where if the passed in URL is
|
||||
* a redirect, then it goes to the new URL, and returns headers from both
|
||||
* requests. We only want the headers from the final request. Here's an
|
||||
* example:
|
||||
*
|
||||
* 0 => "HTTP/1.1 302 Moved Temporarily",
|
||||
* 1 => "X-Powered-By: Servlet/3.0 JSP/2.2 (GlassFish Server Open Source Edition 3.1.1 Java/Sun Microsystems Inc./1.6)",
|
||||
* 2 => "Server: GlassFish Server Open Source Edition 3.1.1",
|
||||
* 3 => "Location: http://3043.live.streamtheworld.com:80/SAM04AAC89_SC",
|
||||
* 4 => "Content-Type: text/html;charset=ISO-8859-1",
|
||||
* 5 => "Content-Language: en-US",
|
||||
* 6 => "Content-Length: 202",
|
||||
* 7 => "Date: Thu, 27 Dec 2012 21:52:59 GMT",
|
||||
* 8 => "Connection: close",
|
||||
* 9 => "HTTP/1.0 200 OK",
|
||||
* 10 => "Expires: Thu, 01 Dec 2003 16:00:00 GMT",
|
||||
* 11 => "Cache-Control: no-cache, must-revalidate",
|
||||
* 12 => "Pragma: no-cache",
|
||||
* 13 => "Content-Type: audio/aacp",
|
||||
* 14 => "icy-br: 68",
|
||||
* 15 => "Server: MediaGateway 3.2.1-04",
|
||||
* */
|
||||
private static function cleanHeaders($headers) {
|
||||
//find the position of HTTP/1 200 OK
|
||||
//
|
||||
$position = 0;
|
||||
foreach ($headers as $i => $v) {
|
||||
if (preg_match("/^HTTP.*200 OK$/i", $v)) {
|
||||
$position = $i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return array_slice($headers, $position);
|
||||
}
|
||||
|
||||
private static function discoverStreamMime($url)
|
||||
{
|
||||
try {
|
||||
$headers = @get_headers($url);
|
||||
|
||||
$mime = null;
|
||||
$content_length_found = false;
|
||||
|
||||
if ($headers !== false) {
|
||||
$headers = self::cleanHeaders($headers);
|
||||
foreach ($headers as $h) {
|
||||
if (preg_match("/^content-type:/i", $h)) {
|
||||
list(, $value) = explode(":", $h, 2);
|
||||
$mime = trim($value);
|
||||
}
|
||||
if (preg_match("/^content-length:/i", $h)) {
|
||||
$content_length_found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
Logging::info("Invalid stream URL");
|
||||
Logging::info($e->getMessage());
|
||||
}
|
||||
|
||||
return array($mime, $content_length_found);
|
||||
}
|
||||
|
||||
public static function save($parameters, $mime, $mediaUrl, $di)
|
||||
{
|
||||
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
|
||||
|
||||
$id = $parameters['id'];
|
||||
if ($id != -1) {
|
||||
$webstream = CcWebstreamQuery::create()->findPK($id);
|
||||
} else {
|
||||
$webstream = new CcWebstream();
|
||||
}
|
||||
|
||||
$webstream->setDbName($parameters["name"]);
|
||||
$webstream->setDbDescription($parameters["description"]);
|
||||
$webstream->setDbUrl($mediaUrl);
|
||||
|
||||
$dblength = $di->format("%H:%I");
|
||||
$webstream->setDbLength($dblength);
|
||||
$webstream->setDbCreatorId($userInfo->id);
|
||||
$webstream->setDbUtime(new DateTime("now", new DateTimeZone('UTC')));
|
||||
$webstream->setDbMtime(new DateTime("now", new DateTimeZone('UTC')));
|
||||
|
||||
$ws = new Application_Model_Webstream($webstream);
|
||||
|
||||
$webstream->setDbMime($mime);
|
||||
$webstream->save();
|
||||
|
||||
return $webstream->getDbId();
|
||||
}
|
||||
|
||||
/*
|
||||
* method is not used, webstreams aren't currently kept track of for isScheduled.
|
||||
*/
|
||||
public static function setIsScheduled($p_webstreamId, $p_status) {
|
||||
|
||||
$webstream = CcWebstreamQuery::create()->findPK($p_webstreamId);
|
||||
$updateIsScheduled = false;
|
||||
|
||||
if (isset($webstream) && !in_array($p_webstreamId,
|
||||
Application_Model_Schedule::getAllFutureScheduledWebstreams())) {
|
||||
//$webstream->setDbIsScheduled($p_status)->save();
|
||||
$updateIsScheduled = true;
|
||||
}
|
||||
|
||||
return $updateIsScheduled;
|
||||
}
|
||||
}
|
||||
|
||||
class WebstreamNoPermissionException extends Exception {}
|
||||
|
18
legacy/application/models/airtime/CcAccess.php
Normal file
18
legacy/application/models/airtime/CcAccess.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for representing a row from the 'cc_access' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcAccess extends BaseCcAccess {
|
||||
|
||||
} // CcAccess
|
18
legacy/application/models/airtime/CcAccessPeer.php
Normal file
18
legacy/application/models/airtime/CcAccessPeer.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_access' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcAccessPeer extends BaseCcAccessPeer {
|
||||
|
||||
} // CcAccessPeer
|
18
legacy/application/models/airtime/CcAccessQuery.php
Normal file
18
legacy/application/models/airtime/CcAccessQuery.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_access' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcAccessQuery extends BaseCcAccessQuery {
|
||||
|
||||
} // CcAccessQuery
|
18
legacy/application/models/airtime/CcBackup.php
Normal file
18
legacy/application/models/airtime/CcBackup.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for representing a row from the 'cc_backup' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcBackup extends BaseCcBackup {
|
||||
|
||||
} // CcBackup
|
18
legacy/application/models/airtime/CcBackupPeer.php
Normal file
18
legacy/application/models/airtime/CcBackupPeer.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_backup' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcBackupPeer extends BaseCcBackupPeer {
|
||||
|
||||
} // CcBackupPeer
|
18
legacy/application/models/airtime/CcBackupQuery.php
Normal file
18
legacy/application/models/airtime/CcBackupQuery.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_backup' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcBackupQuery extends BaseCcBackupQuery {
|
||||
|
||||
} // CcBackupQuery
|
106
legacy/application/models/airtime/CcBlock.php
Normal file
106
legacy/application/models/airtime/CcBlock.php
Normal file
|
@ -0,0 +1,106 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for representing a row from the 'cc_block' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcBlock extends BaseCcBlock {
|
||||
/**
|
||||
* Get the [optionally formatted] temporal [utime] column value.
|
||||
*
|
||||
*
|
||||
* @param string $format The date/time format string (either date()-style or strftime()-style).
|
||||
* If format is NULL, then the raw DateTime object will be returned.
|
||||
* @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL
|
||||
* @throws PropelException - if unable to parse/validate the date/time value.
|
||||
*/
|
||||
public function getDbUtime($format = 'Y-m-d H:i:s')
|
||||
{
|
||||
if ($this->utime === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
$dt = new DateTime($this->utime, new DateTimeZone("UTC"));
|
||||
} catch (Exception $x) {
|
||||
throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->utime, true), $x);
|
||||
}
|
||||
|
||||
if ($format === null) {
|
||||
// Because propel.useDateTimeClass is TRUE, we return a DateTime object.
|
||||
return $dt;
|
||||
} elseif (strpos($format, '%') !== false) {
|
||||
return strftime($format, $dt->format('U'));
|
||||
} else {
|
||||
return $dt->format($format);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the [optionally formatted] temporal [mtime] column value.
|
||||
*
|
||||
*
|
||||
* @param string $format The date/time format string (either date()-style or strftime()-style).
|
||||
* If format is NULL, then the raw DateTime object will be returned.
|
||||
* @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL
|
||||
* @throws PropelException - if unable to parse/validate the date/time value.
|
||||
*/
|
||||
public function getDbMtime($format = 'Y-m-d H:i:s')
|
||||
{
|
||||
if ($this->mtime === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
$dt = new DateTime($this->mtime, new DateTimeZone("UTC"));
|
||||
} catch (Exception $x) {
|
||||
throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->mtime, true), $x);
|
||||
}
|
||||
|
||||
if ($format === null) {
|
||||
// Because propel.useDateTimeClass is TRUE, we return a DateTime object.
|
||||
return $dt;
|
||||
} elseif (strpos($format, '%') !== false) {
|
||||
return strftime($format, $dt->format('U'));
|
||||
} else {
|
||||
return $dt->format($format);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the value of the aggregate column length
|
||||
* Overridden to provide a default of 00:00:00 if the block is empty.
|
||||
*
|
||||
* @param PropelPDO $con A connection object
|
||||
*
|
||||
* @return mixed The scalar result from the aggregate query
|
||||
*/
|
||||
public function computeDbLength(PropelPDO $con)
|
||||
{
|
||||
$sql = <<<SQL
|
||||
SELECT SUM(cliplength) FROM cc_blockcontents as bc
|
||||
JOIN cc_files as f ON bc.file_id = f.id
|
||||
WHERE BLOCK_ID = :b1
|
||||
AND f.file_exists = true
|
||||
SQL;
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindValue(':b1', $this->getDbId());
|
||||
$stmt->execute();
|
||||
$length = $stmt->fetchColumn();
|
||||
|
||||
if (is_null($length)) {
|
||||
$length = "00:00:00";
|
||||
}
|
||||
|
||||
return $length;
|
||||
}
|
||||
} // CcBlock
|
18
legacy/application/models/airtime/CcBlockPeer.php
Normal file
18
legacy/application/models/airtime/CcBlockPeer.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_block' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcBlockPeer extends BaseCcBlockPeer {
|
||||
|
||||
} // CcBlockPeer
|
18
legacy/application/models/airtime/CcBlockQuery.php
Normal file
18
legacy/application/models/airtime/CcBlockQuery.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_block' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcBlockQuery extends BaseCcBlockQuery {
|
||||
|
||||
} // CcBlockQuery
|
113
legacy/application/models/airtime/CcBlockcontents.php
Normal file
113
legacy/application/models/airtime/CcBlockcontents.php
Normal file
|
@ -0,0 +1,113 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for representing a row from the 'cc_blockcontents' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcBlockcontents extends BaseCcBlockcontents {
|
||||
/**
|
||||
* Get the [optionally formatted] temporal [fadein] column value.
|
||||
*
|
||||
* @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL
|
||||
* @throws PropelException - if unable to parse/validate the date/time value.
|
||||
*/
|
||||
public function getDbFadein($format = "s.u")
|
||||
{
|
||||
return parent::getDbFadein($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the [optionally formatted] temporal [fadein] column value.
|
||||
*
|
||||
* @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL
|
||||
* @throws PropelException - if unable to parse/validate the date/time value.
|
||||
*/
|
||||
public function getDbFadeout($format = "s.u")
|
||||
{
|
||||
return parent::getDbFadeout($format);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param String in format SS.uuuuuu, Datetime, or DateTime accepted string.
|
||||
*
|
||||
* @return CcBlockcontents The current object (for fluent API support)
|
||||
*/
|
||||
public function setDbFadein($v)
|
||||
{
|
||||
$microsecond = 0;
|
||||
if ($v instanceof DateTime) {
|
||||
$dt = $v;
|
||||
}
|
||||
else if (preg_match('/^[0-9]{1,2}(\.\d{1,6})?$/', $v)) {
|
||||
// in php 5.3.2 createFromFormat() with "u" is not supported(bug)
|
||||
// Hence we need to do parsing.
|
||||
$info = explode('.', $v);
|
||||
$microsecond = $info[1];
|
||||
$dt = DateTime::createFromFormat("s", $info[0]);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
$dt = new DateTime($v);
|
||||
} catch (Exception $x) {
|
||||
throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x);
|
||||
}
|
||||
}
|
||||
|
||||
if ($microsecond == 0) {
|
||||
$this->fadein = $dt->format('H:i:s.u');
|
||||
} else {
|
||||
$this->fadein = $dt->format('H:i:s').".".$microsecond;
|
||||
}
|
||||
$this->modifiedColumns[] = CcBlockcontentsPeer::FADEIN;
|
||||
|
||||
return $this;
|
||||
} // setDbFadein()
|
||||
|
||||
/**
|
||||
*
|
||||
* @param String in format SS.uuuuuu, Datetime, or DateTime accepted string.
|
||||
*
|
||||
* @return CcBlockcontents The current object (for fluent API support)
|
||||
*/
|
||||
public function setDbFadeout($v)
|
||||
{
|
||||
$microsecond = 0;
|
||||
if ($v instanceof DateTime) {
|
||||
$dt = $v;
|
||||
}
|
||||
else if (preg_match('/^[0-9]{1,2}(\.\d{1,6})?$/', $v)) {
|
||||
// in php 5.3.2 createFromFormat() with "u" is not supported(bug)
|
||||
// Hence we need to do parsing.
|
||||
$info = explode('.', $v);
|
||||
$microsecond = $info[1];
|
||||
$dt = DateTime::createFromFormat("s", $info[0]);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
$dt = new DateTime($v);
|
||||
} catch (Exception $x) {
|
||||
throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x);
|
||||
}
|
||||
}
|
||||
|
||||
if ($microsecond == 0) {
|
||||
$this->fadeout = $dt->format('H:i:s.u');
|
||||
} else {
|
||||
$this->fadeout = $dt->format('H:i:s').".".$microsecond;
|
||||
}
|
||||
$this->modifiedColumns[] = CcBlockcontentsPeer::FADEOUT;
|
||||
|
||||
return $this;
|
||||
} // setDbFadeout()
|
||||
|
||||
} // CcBlockcontents
|
18
legacy/application/models/airtime/CcBlockcontentsPeer.php
Normal file
18
legacy/application/models/airtime/CcBlockcontentsPeer.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_blockcontents' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcBlockcontentsPeer extends BaseCcBlockcontentsPeer {
|
||||
|
||||
} // CcBlockcontentsPeer
|
18
legacy/application/models/airtime/CcBlockcontentsQuery.php
Normal file
18
legacy/application/models/airtime/CcBlockcontentsQuery.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_blockcontents' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcBlockcontentsQuery extends BaseCcBlockcontentsQuery {
|
||||
|
||||
} // CcBlockcontentsQuery
|
18
legacy/application/models/airtime/CcBlockcriteria.php
Normal file
18
legacy/application/models/airtime/CcBlockcriteria.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for representing a row from the 'cc_blockcriteria' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcBlockcriteria extends BaseCcBlockcriteria {
|
||||
|
||||
} // CcBlockcriteria
|
18
legacy/application/models/airtime/CcBlockcriteriaPeer.php
Normal file
18
legacy/application/models/airtime/CcBlockcriteriaPeer.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_blockcriteria' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcBlockcriteriaPeer extends BaseCcBlockcriteriaPeer {
|
||||
|
||||
} // CcBlockcriteriaPeer
|
18
legacy/application/models/airtime/CcBlockcriteriaQuery.php
Normal file
18
legacy/application/models/airtime/CcBlockcriteriaQuery.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_blockcriteria' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcBlockcriteriaQuery extends BaseCcBlockcriteriaQuery {
|
||||
|
||||
} // CcBlockcriteriaQuery
|
18
legacy/application/models/airtime/CcCountry.php
Normal file
18
legacy/application/models/airtime/CcCountry.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for representing a row from the 'cc_country' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcCountry extends BaseCcCountry {
|
||||
|
||||
} // CcCountry
|
18
legacy/application/models/airtime/CcCountryPeer.php
Normal file
18
legacy/application/models/airtime/CcCountryPeer.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_country' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcCountryPeer extends BaseCcCountryPeer {
|
||||
|
||||
} // CcCountryPeer
|
18
legacy/application/models/airtime/CcCountryQuery.php
Normal file
18
legacy/application/models/airtime/CcCountryQuery.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_country' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcCountryQuery extends BaseCcCountryQuery {
|
||||
|
||||
} // CcCountryQuery
|
18
legacy/application/models/airtime/CcFileTag.php
Normal file
18
legacy/application/models/airtime/CcFileTag.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for representing a row from the 'cc_file_tag' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcFileTag extends BaseCcFileTag {
|
||||
|
||||
} // CcFileTag
|
18
legacy/application/models/airtime/CcFileTagPeer.php
Normal file
18
legacy/application/models/airtime/CcFileTagPeer.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_file_tag' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcFileTagPeer extends BaseCcFileTagPeer {
|
||||
|
||||
} // CcFileTagPeer
|
18
legacy/application/models/airtime/CcFileTagQuery.php
Normal file
18
legacy/application/models/airtime/CcFileTagQuery.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_file_tag' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcFileTagQuery extends BaseCcFileTagQuery {
|
||||
|
||||
} // CcFileTagQuery
|
556
legacy/application/models/airtime/CcFiles.php
Normal file
556
legacy/application/models/airtime/CcFiles.php
Normal file
|
@ -0,0 +1,556 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Skeleton subclass for representing a row from the 'cc_files' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.campcaster
|
||||
*/
|
||||
|
||||
class InvalidMetadataException extends Exception
|
||||
{
|
||||
}
|
||||
|
||||
class LibreTimeFileNotFoundException extends Exception
|
||||
{
|
||||
}
|
||||
|
||||
class OverDiskQuotaException extends Exception
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
class CcFiles extends BaseCcFiles {
|
||||
|
||||
const MUSIC_DIRS_STOR_PK = 1;
|
||||
|
||||
const IMPORT_STATUS_SUCCESS = 0;
|
||||
const IMPORT_STATUS_PENDING = 1;
|
||||
const IMPORT_STATUS_FAILED = 2;
|
||||
|
||||
|
||||
//fields that are not modifiable via our RESTful API
|
||||
private static $blackList = array(
|
||||
'id',
|
||||
'directory',
|
||||
'filepath',
|
||||
'file_exists',
|
||||
'mtime',
|
||||
'utime',
|
||||
'lptime',
|
||||
'silan_check',
|
||||
'is_scheduled',
|
||||
'is_playlist'
|
||||
);
|
||||
|
||||
//fields we should never expose through our RESTful API
|
||||
private static $privateFields = array(
|
||||
'file_exists',
|
||||
'silan_check',
|
||||
'is_scheduled',
|
||||
'is_playlist'
|
||||
);
|
||||
|
||||
/**
|
||||
* Retrieve a sanitized version of the file metadata, suitable for public access.
|
||||
* @param $fileId
|
||||
*/
|
||||
public static function getSanitizedFileById($fileId)
|
||||
{
|
||||
$file = CcFilesQuery::create()->findPk($fileId);
|
||||
if ($file) {
|
||||
return CcFiles::sanitizeResponse($file);
|
||||
} else {
|
||||
throw new LibreTimeFileNotFoundException();
|
||||
}
|
||||
}
|
||||
|
||||
/** Used to create a CcFiles object from an array containing metadata and a file uploaded by POST.
|
||||
* This is used by our Media REST API!
|
||||
* @param $fileArray An array containing metadata for a CcFiles object.
|
||||
*
|
||||
* @return object the sanitized response
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function createFromUpload($fileArray)
|
||||
{
|
||||
if (Application_Model_Systemstatus::isDiskOverQuota()) {
|
||||
throw new OverDiskQuotaException();
|
||||
}
|
||||
|
||||
/* If full_path is set, the post request came from ftp.
|
||||
* Users are allowed to upload folders via ftp. If this is the case
|
||||
* we need to include the folder name with the file name, otherwise
|
||||
* files won't get removed from the organize folder.
|
||||
*/
|
||||
|
||||
//Extract the original filename, which we set as the temporary title for the track
|
||||
//until it's finished being processed by the analyzer.
|
||||
$originalFilename = $fileArray['file']['name'];
|
||||
$tempFilePath = $fileArray['file']['tmp_name'];
|
||||
|
||||
try {
|
||||
return self::createAndImport($fileArray, $tempFilePath, $originalFilename);
|
||||
} catch (Exception $e) {
|
||||
if (file_exists($tempFilePath)) {
|
||||
unlink($tempFilePath);
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/** Import a music file to the library from a local file on disk (something pre-existing).
|
||||
* This function allows you to copy a file rather than move it, which is useful for importing
|
||||
* static music files (like sample tracks).
|
||||
* @param string $filePath The full path to the audio file to import.
|
||||
* @param bool $copyFile True if you want to just copy the false, false if you want to move it (default false)
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function createFromLocalFile($fileArray, $filePath, $copyFile=false)
|
||||
{
|
||||
$info = pathinfo($filePath);
|
||||
$fileName = basename($filePath).'.'.$info['extension'];
|
||||
self::createAndImport($fileArray, $filePath, $fileName, $copyFile);
|
||||
}
|
||||
|
||||
/** Create a new CcFiles object/row and import a file for it.
|
||||
* You shouldn't call this directly. Either use createFromUpload() or createFromLocalFile().
|
||||
* @param array $fileArray Any metadata to pre-fill for the audio file
|
||||
* @param string $filePath The full path to the audio file to import
|
||||
* @param string $originalFilename
|
||||
* @param bool $copyFile
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
* @throws PropelException
|
||||
*/
|
||||
private static function createAndImport($fileArray, $filePath, $originalFilename, $copyFile=false)
|
||||
{
|
||||
$file = new CcFiles();
|
||||
|
||||
try
|
||||
{
|
||||
//Only accept files with a file extension that we support.
|
||||
// Let the analyzer do the heavy lifting in terms of mime verification and playability
|
||||
$fileExtension = pathinfo($originalFilename, PATHINFO_EXTENSION);
|
||||
if (!in_array(strtolower($fileExtension), array_values(FileDataHelper::getAudioMimeTypeArray()))) {
|
||||
throw new Exception("Bad file extension.");
|
||||
}
|
||||
|
||||
$fileArray = self::removeBlacklistedFields($fileArray);
|
||||
|
||||
self::validateFileArray($fileArray);
|
||||
|
||||
$storDir = Application_Model_MusicDir::getStorDir();
|
||||
$importedStorageDir = $storDir->getDirectory() . "imported/" . self::getOwnerId() . "/";
|
||||
$importedDbPath = "imported/" . self::getOwnerId() . "/";
|
||||
$artwork = FileDataHelper::saveArtworkData($filePath, $originalFilename, $importedStorageDir, $importedDbPath);
|
||||
$trackType = FileDataHelper::saveTrackType();
|
||||
|
||||
$file->fromArray($fileArray);
|
||||
$file->setDbOwnerId(self::getOwnerId());
|
||||
$now = new DateTime("now", new DateTimeZone("UTC"));
|
||||
$file->setDbTrackTitle($originalFilename);
|
||||
$file->setDbArtwork($artwork);
|
||||
$file->setDbTrackType($trackType);
|
||||
$file->setDbUtime($now);
|
||||
$file->setDbHidden(true);
|
||||
$file->save();
|
||||
|
||||
$callbackUrl = Application_Common_HTTPHelper::getStationUrl() . "/rest/media/" . $file->getPrimaryKey();
|
||||
|
||||
Application_Service_MediaService::importFileToLibrary($callbackUrl, $filePath,
|
||||
$originalFilename, self::getOwnerId(), $copyFile);
|
||||
|
||||
return CcFiles::sanitizeResponse($file);
|
||||
|
||||
} catch (Exception $e) {
|
||||
$file->setDbImportStatus(self::IMPORT_STATUS_FAILED);
|
||||
$file->setDbHidden(true);
|
||||
$file->save();
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/** Update a file with metadata specified in an array.
|
||||
* @param $fileId string The ID of the file to update in the DB.
|
||||
* @param $fileArray array An associative array containing metadata. Replaces those fields if they exist.
|
||||
* @return array A sanitized version of the file metadata array.
|
||||
* @throws Exception
|
||||
* @throws LibreTimeFileNotFoundException
|
||||
* @throws PropelException
|
||||
*/
|
||||
public static function updateFromArray($fileId, $fileArray)
|
||||
{
|
||||
$file = CcFilesQuery::create()->findPk($fileId);
|
||||
|
||||
$fileArray = self::removeBlacklistedFields($fileArray);
|
||||
$fileArray = self::stripTimeStampFromYearTag($fileArray);
|
||||
|
||||
try {
|
||||
|
||||
self::validateFileArray($fileArray);
|
||||
if ($file && isset($fileArray["resource_id"])) {
|
||||
|
||||
$file->fromArray($fileArray, BasePeer::TYPE_FIELDNAME);
|
||||
|
||||
//store the original filename
|
||||
$file->setDbFilepath($fileArray["filename"]);
|
||||
|
||||
$fileSizeBytes = $fileArray["filesize"];
|
||||
if (!isset($fileSizeBytes) || $fileSizeBytes === false) {
|
||||
throw new LibreTimeFileNotFoundException("Invalid filesize for $fileId");
|
||||
}
|
||||
|
||||
$cloudFile = new CloudFile();
|
||||
$cloudFile->setStorageBackend($fileArray["storage_backend"]);
|
||||
$cloudFile->setResourceId($fileArray["resource_id"]);
|
||||
$cloudFile->setCcFiles($file);
|
||||
$cloudFile->save();
|
||||
|
||||
Application_Model_Preference::updateDiskUsage($fileSizeBytes);
|
||||
} else if ($file) {
|
||||
|
||||
// Since we check for this value when deleting files, set it first
|
||||
$file->setDbDirectory(self::MUSIC_DIRS_STOR_PK);
|
||||
|
||||
$file->fromArray($fileArray, BasePeer::TYPE_FIELDNAME);
|
||||
|
||||
//Our RESTful API takes "full_path" as a field, which we then split and translate to match
|
||||
//our internal schema. Internally, file path is stored relative to a directory, with the directory
|
||||
//as a foreign key to cc_music_dirs.
|
||||
if (isset($fileArray["full_path"])) {
|
||||
$fileSizeBytes = filesize($fileArray["full_path"]);
|
||||
if (!isset($fileSizeBytes) || $fileSizeBytes === false) {
|
||||
throw new LibreTimeFileNotFoundException("Invalid filesize for $fileId");
|
||||
}
|
||||
Application_Model_Preference::updateDiskUsage($fileSizeBytes);
|
||||
|
||||
$fullPath = $fileArray["full_path"];
|
||||
$storDir = Application_Model_MusicDir::getStorDir()->getDirectory();
|
||||
$pos = strpos($fullPath, $storDir);
|
||||
|
||||
if ($pos !== FALSE) {
|
||||
assert($pos == 0); //Path must start with the stor directory path
|
||||
|
||||
$filePathRelativeToStor = substr($fullPath, strlen($storDir));
|
||||
$file->setDbFilepath($filePathRelativeToStor);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new LibreTimeFileNotFoundException();
|
||||
}
|
||||
|
||||
$now = new DateTime("now", new DateTimeZone("UTC"));
|
||||
$file->setDbMtime($now);
|
||||
$file->save();
|
||||
}
|
||||
catch (LibreTimeFileNotFoundException $e)
|
||||
{
|
||||
$file->setDbImportStatus(self::IMPORT_STATUS_FAILED);
|
||||
$file->setDbHidden(true);
|
||||
$file->save();
|
||||
throw $e;
|
||||
}
|
||||
|
||||
return CcFiles::sanitizeResponse($file);
|
||||
}
|
||||
|
||||
/** Delete a file from the database and disk (or cloud).
|
||||
* @param $id The file ID
|
||||
* @throws DeleteScheduledFileException
|
||||
* @throws Exception
|
||||
* @throws FileNoPermissionException
|
||||
* @throws LibreTimeFileNotFoundException
|
||||
* @throws PropelException
|
||||
*/
|
||||
public static function deleteById($id)
|
||||
{
|
||||
$file = CcFilesQuery::create()->findPk($id);
|
||||
if ($file) {
|
||||
$con = Propel::getConnection();
|
||||
$storedFile = Application_Model_StoredFile::RecallById($id, $con);
|
||||
$storedFile->delete();
|
||||
} else {
|
||||
throw new LibreTimeFileNotFoundException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static function validateFileArray(&$fileArray)
|
||||
{
|
||||
// Sanitize any wildly incorrect metadata before it goes to be validated
|
||||
FileDataHelper::sanitizeData($fileArray);
|
||||
|
||||
// EditAudioMD form is used here for validation
|
||||
$fileForm = new Application_Form_EditAudioMD();
|
||||
$fileForm->startForm(0); //The file ID doesn't matter here
|
||||
$fileForm->populate($fileArray);
|
||||
|
||||
/*
|
||||
* Here we are truncating metadata of any characters greater than the
|
||||
* max string length set in the database. In the rare case a track's
|
||||
* genre is more than 64 chars, for example, we don't want to reject
|
||||
* tracks for that reason
|
||||
*/
|
||||
foreach($fileArray as $tag => &$value) {
|
||||
if ($fileForm->getElement($tag)) {
|
||||
$stringLengthValidator = $fileForm->getElement($tag)->getValidator('StringLength');
|
||||
//$stringLengthValidator will be false if the StringLength validator doesn't exist on the current element
|
||||
//in which case we don't have to truncate the extra characters
|
||||
if ($stringLengthValidator) {
|
||||
$value = substr($value, 0, $stringLengthValidator->getMax());
|
||||
}
|
||||
|
||||
$value = self::stripInvalidUtf8Characters($value);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$fileForm->isValidPartial($fileArray)) {
|
||||
$errors = $fileForm->getErrors();
|
||||
$messages = $fileForm->getMessages();
|
||||
Logging::error($messages);
|
||||
throw new Exception("Data validation failed: $errors - $messages");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public function getCueLength()
|
||||
{
|
||||
$cuein = $this->getDbCuein();
|
||||
$cueout = $this->getDbCueout();
|
||||
|
||||
$cueinSec = Application_Common_DateHelper::calculateLengthInSeconds($cuein);
|
||||
$cueoutSec = Application_Common_DateHelper::calculateLengthInSeconds($cueout);
|
||||
$lengthSec = bcsub($cueoutSec, $cueinSec, 6);
|
||||
|
||||
$length = Application_Common_DateHelper::secondsToPlaylistTime($lengthSec);
|
||||
|
||||
return $length;
|
||||
}
|
||||
|
||||
public function setDbTrackNumber($v)
|
||||
{
|
||||
$max = pow(2, 31)-1;
|
||||
$v = ($v > $max) ? $max : $v;
|
||||
|
||||
return parent::setDbTrackNumber($v);
|
||||
}
|
||||
|
||||
// returns true if the file exists and is not hidden
|
||||
public function visible() {
|
||||
return $this->getDbFileExists() && !$this->getDbHidden();
|
||||
}
|
||||
|
||||
public function reassignTo($user)
|
||||
{
|
||||
$this->setDbOwnerId( $user->getDbId() );
|
||||
$this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Strips out the private fields we do not want to send back in API responses
|
||||
*
|
||||
* @param CcFiles $file a CcFiles object
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
//TODO: rename this function?
|
||||
public static function sanitizeResponse($file) {
|
||||
$response = $file->toArray(BasePeer::TYPE_FIELDNAME);
|
||||
|
||||
foreach (self::$privateFields as $key) {
|
||||
unset($response[$key]);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file size in bytes.
|
||||
*/
|
||||
public function getFileSize()
|
||||
{
|
||||
return $this->getDbFilesize();
|
||||
}
|
||||
|
||||
public function getFilename()
|
||||
{
|
||||
$info = pathinfo($this->getAbsoluteFilePath());
|
||||
|
||||
//filename doesn't contain the extension because PHP is awful
|
||||
$mime = $this->getDbMime();
|
||||
$extension = FileDataHelper::getFileExtensionFromMime($mime);
|
||||
|
||||
return $info['filename'] . $extension;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file's absolute file path stored on disk.
|
||||
*/
|
||||
public function getURLsForTrackPreviewOrDownload()
|
||||
{
|
||||
return array($this->getAbsoluteFilePath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file's absolute file path stored on disk.
|
||||
*/
|
||||
public function getAbsoluteFilePath()
|
||||
{
|
||||
$music_dir = Application_Model_MusicDir::getDirByPK($this->getDbDirectory());
|
||||
if (!$music_dir) {
|
||||
throw new Exception("Invalid music_dir for file " . $this->getDbId() . " in database.");
|
||||
}
|
||||
$directory = $music_dir->getDirectory();
|
||||
$filepath = $this->getDbFilepath();
|
||||
return Application_Common_OsPath::join($directory, $filepath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the artwork's absolute file path stored on disk.
|
||||
*/
|
||||
public function getAbsoluteArtworkPath()
|
||||
{
|
||||
$music_dir = Application_Model_MusicDir::getDirByPK($this->getDbDirectory());
|
||||
if (!$music_dir) {
|
||||
throw new Exception("Invalid music_dir for file " . $this->getDbId() . " in database.");
|
||||
}
|
||||
$directory = $music_dir->getDirectory();
|
||||
$filepath = $this->getDbArtwork();
|
||||
|
||||
return Application_Common_OsPath::join($directory, $filepath);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Strips out fields from incoming request data that should never be modified
|
||||
* from outside of Airtime
|
||||
* @param array $data
|
||||
*/
|
||||
private static function removeBlacklistedFields($data)
|
||||
{
|
||||
foreach (self::$blackList as $key) {
|
||||
unset($data[$key]);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
private static function getOwnerId()
|
||||
{
|
||||
try {
|
||||
if (Zend_Auth::getInstance()->hasIdentity()) {
|
||||
$service_user = new Application_Service_UserService();
|
||||
return $service_user->getCurrentUser()->getDbId();
|
||||
} else {
|
||||
$defaultOwner = CcSubjsQuery::create()
|
||||
->filterByDbType('A')
|
||||
->orderByDbId()
|
||||
->findOne();
|
||||
if (!$defaultOwner) {
|
||||
// what to do if there is no admin user?
|
||||
// should we handle this case?
|
||||
return null;
|
||||
}
|
||||
return $defaultOwner->getDbId();
|
||||
}
|
||||
} catch(Exception $e) {
|
||||
Logging::info($e->getMessage());
|
||||
}
|
||||
}
|
||||
/*
|
||||
* It's possible that the year tag will be a timestamp but Airtime doesn't support this.
|
||||
* The year field in cc_files can only be 16 chars max.
|
||||
*
|
||||
* This functions strips the year field of it's timestamp, if one, and leaves just the year
|
||||
*/
|
||||
private static function stripTimeStampFromYearTag($metadata)
|
||||
{
|
||||
if (isset($metadata["year"])) {
|
||||
if (preg_match("/^(\d{4})-(\d{2})-(\d{2})(?:\s+(\d{2}):(\d{2}):(\d{2}))?$/", $metadata["year"])) {
|
||||
$metadata["year"] = substr($metadata["year"], 0, 4);
|
||||
}
|
||||
}
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
private static function stripInvalidUtf8Characters($string)
|
||||
{
|
||||
//Remove invalid UTF-8 characters
|
||||
//reject overly long 2 byte sequences, as well as characters above U+10000 and replace with ?
|
||||
$string = preg_replace('/[\x00-\x08\x10\x0B\x0C\x0E-\x19\x7F]'.
|
||||
'|[\x00-\x7F][\x80-\xBF]+'.
|
||||
'|([\xC0\xC1]|[\xF0-\xFF])[\x80-\xBF]*'.
|
||||
'|[\xC2-\xDF]((?![\x80-\xBF])|[\x80-\xBF]{2,})'.
|
||||
'|[\xE0-\xEF](([\x80-\xBF](?![\x80-\xBF]))|(?![\x80-\xBF]{2})|[\x80-\xBF]{3,})/S',
|
||||
'?', $string );
|
||||
|
||||
//reject overly long 3 byte sequences and UTF-16 surrogates and replace with ?
|
||||
$string = preg_replace('/\xE0[\x80-\x9F][\x80-\xBF]'.
|
||||
'|\xED[\xA0-\xBF][\x80-\xBF]/S','?', $string );
|
||||
|
||||
//Do a final encoding conversion to
|
||||
$string = mb_convert_encoding($string, 'UTF-8', 'UTF-8');
|
||||
return $string;
|
||||
}
|
||||
|
||||
private function removeEmptySubFolders($path)
|
||||
{
|
||||
exec("find $path -empty -type d -delete");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the file is a regular file that can be previewed and downloaded.
|
||||
*/
|
||||
public function isValidPhysicalFile()
|
||||
{
|
||||
return is_file($this->getAbsoluteFilePath());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Deletes the file from the stor directory on disk.
|
||||
*/
|
||||
public function deletePhysicalFile()
|
||||
{
|
||||
$filepath = $this->getAbsoluteFilePath();
|
||||
$artworkpath = $this->getAbsoluteArtworkPath();
|
||||
if (file_exists($filepath)) {
|
||||
unlink($filepath);
|
||||
// also delete related images (dataURI and jpeg files)
|
||||
foreach (glob("$artworkpath*", GLOB_NOSORT) as $filename) {
|
||||
unlink($filename);
|
||||
}
|
||||
unlink($artworkpath);
|
||||
} else {
|
||||
throw new Exception("Could not locate file ".$filepath);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* This function refers to the file's Amazon S3 resource id.
|
||||
* Returns null because cc_files are stored on local disk.
|
||||
*/
|
||||
public function getResourceId()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getCcFileId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
} // CcFiles
|
18
legacy/application/models/airtime/CcFilesPeer.php
Normal file
18
legacy/application/models/airtime/CcFilesPeer.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_files' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcFilesPeer extends BaseCcFilesPeer {
|
||||
|
||||
} // CcFilesPeer
|
18
legacy/application/models/airtime/CcFilesQuery.php
Normal file
18
legacy/application/models/airtime/CcFilesQuery.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_files' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcFilesQuery extends BaseCcFilesQuery {
|
||||
|
||||
} // CcFilesQuery
|
18
legacy/application/models/airtime/CcListenerCount.php
Normal file
18
legacy/application/models/airtime/CcListenerCount.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for representing a row from the 'cc_listener_count' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcListenerCount extends BaseCcListenerCount {
|
||||
|
||||
} // CcListenerCount
|
18
legacy/application/models/airtime/CcListenerCountPeer.php
Normal file
18
legacy/application/models/airtime/CcListenerCountPeer.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_listener_count' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcListenerCountPeer extends BaseCcListenerCountPeer {
|
||||
|
||||
} // CcListenerCountPeer
|
18
legacy/application/models/airtime/CcListenerCountQuery.php
Normal file
18
legacy/application/models/airtime/CcListenerCountQuery.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_listener_count' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcListenerCountQuery extends BaseCcListenerCountQuery {
|
||||
|
||||
} // CcListenerCountQuery
|
18
legacy/application/models/airtime/CcLiveLog.php
Normal file
18
legacy/application/models/airtime/CcLiveLog.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for representing a row from the 'cc_live_log' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcLiveLog extends BaseCcLiveLog {
|
||||
|
||||
} // CcLiveLog
|
18
legacy/application/models/airtime/CcLiveLogPeer.php
Normal file
18
legacy/application/models/airtime/CcLiveLogPeer.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_live_log' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcLiveLogPeer extends BaseCcLiveLogPeer {
|
||||
|
||||
} // CcLiveLogPeer
|
18
legacy/application/models/airtime/CcLiveLogQuery.php
Normal file
18
legacy/application/models/airtime/CcLiveLogQuery.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_live_log' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcLiveLogQuery extends BaseCcLiveLogQuery {
|
||||
|
||||
} // CcLiveLogQuery
|
18
legacy/application/models/airtime/CcLocale.php
Normal file
18
legacy/application/models/airtime/CcLocale.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for representing a row from the 'cc_locale' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcLocale extends BaseCcLocale {
|
||||
|
||||
} // CcLocale
|
18
legacy/application/models/airtime/CcLocalePeer.php
Normal file
18
legacy/application/models/airtime/CcLocalePeer.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_locale' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcLocalePeer extends BaseCcLocalePeer {
|
||||
|
||||
} // CcLocalePeer
|
18
legacy/application/models/airtime/CcLocaleQuery.php
Normal file
18
legacy/application/models/airtime/CcLocaleQuery.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_locale' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcLocaleQuery extends BaseCcLocaleQuery {
|
||||
|
||||
} // CcLocaleQuery
|
18
legacy/application/models/airtime/CcLoginAttempts.php
Normal file
18
legacy/application/models/airtime/CcLoginAttempts.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for representing a row from the 'cc_login_attempts' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcLoginAttempts extends BaseCcLoginAttempts {
|
||||
|
||||
} // CcLoginAttempts
|
18
legacy/application/models/airtime/CcLoginAttemptsPeer.php
Normal file
18
legacy/application/models/airtime/CcLoginAttemptsPeer.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_login_attempts' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcLoginAttemptsPeer extends BaseCcLoginAttemptsPeer {
|
||||
|
||||
} // CcLoginAttemptsPeer
|
18
legacy/application/models/airtime/CcLoginAttemptsQuery.php
Normal file
18
legacy/application/models/airtime/CcLoginAttemptsQuery.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_login_attempts' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcLoginAttemptsQuery extends BaseCcLoginAttemptsQuery {
|
||||
|
||||
} // CcLoginAttemptsQuery
|
18
legacy/application/models/airtime/CcMountName.php
Normal file
18
legacy/application/models/airtime/CcMountName.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for representing a row from the 'cc_mount_name' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcMountName extends BaseCcMountName {
|
||||
|
||||
} // CcMountName
|
18
legacy/application/models/airtime/CcMountNamePeer.php
Normal file
18
legacy/application/models/airtime/CcMountNamePeer.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_mount_name' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcMountNamePeer extends BaseCcMountNamePeer {
|
||||
|
||||
} // CcMountNamePeer
|
18
legacy/application/models/airtime/CcMountNameQuery.php
Normal file
18
legacy/application/models/airtime/CcMountNameQuery.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_mount_name' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcMountNameQuery extends BaseCcMountNameQuery {
|
||||
|
||||
} // CcMountNameQuery
|
18
legacy/application/models/airtime/CcMusicDirs.php
Normal file
18
legacy/application/models/airtime/CcMusicDirs.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for representing a row from the 'cc_music_dirs' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcMusicDirs extends BaseCcMusicDirs {
|
||||
|
||||
} // CcMusicDirs
|
18
legacy/application/models/airtime/CcMusicDirsPeer.php
Normal file
18
legacy/application/models/airtime/CcMusicDirsPeer.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_music_dirs' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcMusicDirsPeer extends BaseCcMusicDirsPeer {
|
||||
|
||||
} // CcMusicDirsPeer
|
18
legacy/application/models/airtime/CcMusicDirsQuery.php
Normal file
18
legacy/application/models/airtime/CcMusicDirsQuery.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_music_dirs' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcMusicDirsQuery extends BaseCcMusicDirsQuery {
|
||||
|
||||
} // CcMusicDirsQuery
|
18
legacy/application/models/airtime/CcPerms.php
Normal file
18
legacy/application/models/airtime/CcPerms.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for representing a row from the 'cc_perms' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcPerms extends BaseCcPerms {
|
||||
|
||||
} // CcPerms
|
18
legacy/application/models/airtime/CcPermsPeer.php
Normal file
18
legacy/application/models/airtime/CcPermsPeer.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_perms' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcPermsPeer extends BaseCcPermsPeer {
|
||||
|
||||
} // CcPermsPeer
|
18
legacy/application/models/airtime/CcPermsQuery.php
Normal file
18
legacy/application/models/airtime/CcPermsQuery.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_perms' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcPermsQuery extends BaseCcPermsQuery {
|
||||
|
||||
} // CcPermsQuery
|
107
legacy/application/models/airtime/CcPlaylist.php
Normal file
107
legacy/application/models/airtime/CcPlaylist.php
Normal file
|
@ -0,0 +1,107 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for representing a row from the 'cc_playlist' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.campcaster
|
||||
*/
|
||||
class CcPlaylist extends BaseCcPlaylist {
|
||||
|
||||
/**
|
||||
* Get the [optionally formatted] temporal [utime] column value.
|
||||
*
|
||||
*
|
||||
* @param string $format The date/time format string (either date()-style or strftime()-style).
|
||||
* If format is NULL, then the raw DateTime object will be returned.
|
||||
* @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL
|
||||
* @throws PropelException - if unable to parse/validate the date/time value.
|
||||
*/
|
||||
public function getDbUtime($format = 'Y-m-d H:i:s')
|
||||
{
|
||||
if ($this->utime === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
$dt = new DateTime($this->utime, new DateTimeZone("UTC"));
|
||||
} catch (Exception $x) {
|
||||
throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->utime, true), $x);
|
||||
}
|
||||
|
||||
if ($format === null) {
|
||||
// Because propel.useDateTimeClass is TRUE, we return a DateTime object.
|
||||
return $dt;
|
||||
} elseif (strpos($format, '%') !== false) {
|
||||
return strftime($format, $dt->format('U'));
|
||||
} else {
|
||||
return $dt->format($format);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the [optionally formatted] temporal [mtime] column value.
|
||||
*
|
||||
*
|
||||
* @param string $format The date/time format string (either date()-style or strftime()-style).
|
||||
* If format is NULL, then the raw DateTime object will be returned.
|
||||
* @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL
|
||||
* @throws PropelException - if unable to parse/validate the date/time value.
|
||||
*/
|
||||
public function getDbMtime($format = 'Y-m-d H:i:s')
|
||||
{
|
||||
if ($this->mtime === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
$dt = new DateTime($this->mtime, new DateTimeZone("UTC"));
|
||||
} catch (Exception $x) {
|
||||
throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->mtime, true), $x);
|
||||
}
|
||||
|
||||
if ($format === null) {
|
||||
// Because propel.useDateTimeClass is TRUE, we return a DateTime object.
|
||||
return $dt;
|
||||
} elseif (strpos($format, '%') !== false) {
|
||||
return strftime($format, $dt->format('U'));
|
||||
} else {
|
||||
return $dt->format($format);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the value of the aggregate column length
|
||||
* Overridden to provide a default of 00:00:00 if the playlist is empty.
|
||||
*
|
||||
* @param PropelPDO $con A connection object
|
||||
*
|
||||
* @return mixed The scalar result from the aggregate query
|
||||
*/
|
||||
public function computeDbLength(PropelPDO $con)
|
||||
{
|
||||
$sql = <<<SQL
|
||||
SELECT SUM(cliplength) FROM cc_playlistcontents as pc
|
||||
LEFT JOIN cc_files as f ON pc.file_id = f.id
|
||||
WHERE PLAYLIST_ID = :p1
|
||||
AND (f.file_exists is NUll or f.file_exists = true)
|
||||
SQL;
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindValue(':p1', $this->getDbId());
|
||||
$stmt->execute();
|
||||
$length = $stmt->fetchColumn();
|
||||
if (is_null($length)) {
|
||||
$length = "00:00:00";
|
||||
}
|
||||
|
||||
return $length;
|
||||
}
|
||||
|
||||
} // CcPlaylist
|
18
legacy/application/models/airtime/CcPlaylistPeer.php
Normal file
18
legacy/application/models/airtime/CcPlaylistPeer.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_playlist' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcPlaylistPeer extends BaseCcPlaylistPeer {
|
||||
|
||||
} // CcPlaylistPeer
|
18
legacy/application/models/airtime/CcPlaylistQuery.php
Normal file
18
legacy/application/models/airtime/CcPlaylistQuery.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_playlist' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcPlaylistQuery extends BaseCcPlaylistQuery {
|
||||
|
||||
} // CcPlaylistQuery
|
118
legacy/application/models/airtime/CcPlaylistcontents.php
Normal file
118
legacy/application/models/airtime/CcPlaylistcontents.php
Normal file
|
@ -0,0 +1,118 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Skeleton subclass for representing a row from the 'cc_playlistcontents' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.campcaster
|
||||
*/
|
||||
class CcPlaylistcontents extends BaseCcPlaylistcontents {
|
||||
|
||||
/**
|
||||
* Get the [optionally formatted] temporal [fadein] column value.
|
||||
*
|
||||
* @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL
|
||||
* @throws PropelException - if unable to parse/validate the date/time value.
|
||||
*/
|
||||
public function getDbFadein($format = "s.u")
|
||||
{
|
||||
return parent::getDbFadein($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the [optionally formatted] temporal [fadein] column value.
|
||||
*
|
||||
* @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL
|
||||
* @throws PropelException - if unable to parse/validate the date/time value.
|
||||
*/
|
||||
public function getDbFadeout($format = "s.u")
|
||||
{
|
||||
return parent::getDbFadeout($format);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param String in format SS.uuuuuu, Datetime, or DateTime accepted string.
|
||||
*
|
||||
* @return CcPlaylistcontents The current object (for fluent API support)
|
||||
*/
|
||||
public function setDbFadein($v)
|
||||
{
|
||||
$microsecond = 0;
|
||||
if ($v instanceof DateTime) {
|
||||
$dt = $v;
|
||||
}
|
||||
else if (preg_match('/^[0-9]{1,2}(\.\d{1,6})?$/', $v)) {
|
||||
// in php 5.3.2 createFromFormat() with "u" is not supported(bug)
|
||||
// Hence we need to do parsing.
|
||||
$info = explode('.', $v);
|
||||
$microsecond = $info[1];
|
||||
$dt = DateTime::createFromFormat("s", $info[0]);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
$dt = new DateTime($v);
|
||||
} catch (Exception $x) {
|
||||
throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x);
|
||||
}
|
||||
}
|
||||
|
||||
if ($microsecond == 0) {
|
||||
$this->fadein = $dt->format('H:i:s.u');
|
||||
} else {
|
||||
$this->fadein = $dt->format('H:i:s').".".$microsecond;
|
||||
}
|
||||
$this->modifiedColumns[] = CcPlaylistcontentsPeer::FADEIN;
|
||||
$this->save();
|
||||
|
||||
//FIXME(XXX): Propel silently drops the milliseconds from our fadein time. :(
|
||||
|
||||
return $this;
|
||||
} // setDbFadein()
|
||||
|
||||
/**
|
||||
*
|
||||
* @param String in format SS.uuuuuu, Datetime, or DateTime accepted string.
|
||||
*
|
||||
* @return CcPlaylistcontents The current object (for fluent API support)
|
||||
*/
|
||||
public function setDbFadeout($v)
|
||||
{
|
||||
$microsecond = 0;
|
||||
if ($v instanceof DateTime) {
|
||||
$dt = $v;
|
||||
}
|
||||
else if (preg_match('/^[0-9]{1,2}(\.\d{1,6})?$/', $v)) {
|
||||
// in php 5.3.2 createFromFormat() with "u" is not supported(bug)
|
||||
// Hence we need to do parsing.
|
||||
$info = explode('.', $v);
|
||||
$microsecond = $info[1];
|
||||
$dt = DateTime::createFromFormat("s", $info[0]);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
$dt = new DateTime($v);
|
||||
} catch (Exception $x) {
|
||||
throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x);
|
||||
}
|
||||
}
|
||||
|
||||
if ($microsecond == 0) {
|
||||
$this->fadeout = $dt->format('H:i:s.u');
|
||||
} else {
|
||||
$this->fadeout = $dt->format('H:i:s').".".$microsecond;
|
||||
}
|
||||
$this->modifiedColumns[] = CcPlaylistcontentsPeer::FADEOUT;
|
||||
$this->save();
|
||||
|
||||
//FIXME(XXX): Propel silently drops the milliseconds from our fadeout time. :(
|
||||
|
||||
return $this;
|
||||
} // setDbFadeout()
|
||||
|
||||
} // CcPlaylistcontents
|
18
legacy/application/models/airtime/CcPlaylistcontentsPeer.php
Normal file
18
legacy/application/models/airtime/CcPlaylistcontentsPeer.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_playlistcontents' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcPlaylistcontentsPeer extends BaseCcPlaylistcontentsPeer {
|
||||
|
||||
} // CcPlaylistcontentsPeer
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_playlistcontents' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcPlaylistcontentsQuery extends BaseCcPlaylistcontentsQuery {
|
||||
|
||||
} // CcPlaylistcontentsQuery
|
18
legacy/application/models/airtime/CcPlaylistcriteria.php
Normal file
18
legacy/application/models/airtime/CcPlaylistcriteria.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for representing a row from the 'cc_playlistcriteria' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcPlaylistcriteria extends BaseCcPlaylistcriteria {
|
||||
|
||||
} // CcPlaylistcriteria
|
18
legacy/application/models/airtime/CcPlaylistcriteriaPeer.php
Normal file
18
legacy/application/models/airtime/CcPlaylistcriteriaPeer.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_playlistcriteria' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcPlaylistcriteriaPeer extends BaseCcPlaylistcriteriaPeer {
|
||||
|
||||
} // CcPlaylistcriteriaPeer
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_playlistcriteria' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcPlaylistcriteriaQuery extends BaseCcPlaylistcriteriaQuery {
|
||||
|
||||
} // CcPlaylistcriteriaQuery
|
18
legacy/application/models/airtime/CcPlayoutHistory.php
Normal file
18
legacy/application/models/airtime/CcPlayoutHistory.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for representing a row from the 'cc_playout_history' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcPlayoutHistory extends BaseCcPlayoutHistory {
|
||||
|
||||
} // CcPlayoutHistory
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for representing a row from the 'cc_playout_history_metadata' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcPlayoutHistoryMetaData extends BaseCcPlayoutHistoryMetaData {
|
||||
|
||||
/**
|
||||
* Set the value of [value] column.
|
||||
*
|
||||
* @param string $v new value
|
||||
* @return CcPlayoutHistoryMetaData The current object (for fluent API support)
|
||||
*/
|
||||
public function setDbValue($v)
|
||||
{
|
||||
//make sure the metadata isn't longer than the DB field.
|
||||
$v = substr($v, 0, 128);
|
||||
|
||||
parent::setDbValue($v);
|
||||
|
||||
return $this;
|
||||
} // setDbValue()
|
||||
|
||||
} // CcPlayoutHistoryMetaData
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_playout_history_metadata' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcPlayoutHistoryMetaDataPeer extends BaseCcPlayoutHistoryMetaDataPeer {
|
||||
|
||||
} // CcPlayoutHistoryMetaDataPeer
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_playout_history_metadata' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcPlayoutHistoryMetaDataQuery extends BaseCcPlayoutHistoryMetaDataQuery {
|
||||
|
||||
} // CcPlayoutHistoryMetaDataQuery
|
18
legacy/application/models/airtime/CcPlayoutHistoryPeer.php
Normal file
18
legacy/application/models/airtime/CcPlayoutHistoryPeer.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_playout_history' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcPlayoutHistoryPeer extends BaseCcPlayoutHistoryPeer {
|
||||
|
||||
} // CcPlayoutHistoryPeer
|
18
legacy/application/models/airtime/CcPlayoutHistoryQuery.php
Normal file
18
legacy/application/models/airtime/CcPlayoutHistoryQuery.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_playout_history' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcPlayoutHistoryQuery extends BaseCcPlayoutHistoryQuery {
|
||||
|
||||
} // CcPlayoutHistoryQuery
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for representing a row from the 'cc_playout_history_template' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcPlayoutHistoryTemplate extends BaseCcPlayoutHistoryTemplate {
|
||||
|
||||
} // CcPlayoutHistoryTemplate
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for representing a row from the 'cc_playout_history_template_field' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcPlayoutHistoryTemplateField extends BaseCcPlayoutHistoryTemplateField {
|
||||
|
||||
} // CcPlayoutHistoryTemplateField
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_playout_history_template_field' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcPlayoutHistoryTemplateFieldPeer extends BaseCcPlayoutHistoryTemplateFieldPeer {
|
||||
|
||||
} // CcPlayoutHistoryTemplateFieldPeer
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_playout_history_template_field' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcPlayoutHistoryTemplateFieldQuery extends BaseCcPlayoutHistoryTemplateFieldQuery {
|
||||
|
||||
} // CcPlayoutHistoryTemplateFieldQuery
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_playout_history_template' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcPlayoutHistoryTemplatePeer extends BaseCcPlayoutHistoryTemplatePeer {
|
||||
|
||||
} // CcPlayoutHistoryTemplatePeer
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_playout_history_template' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcPlayoutHistoryTemplateQuery extends BaseCcPlayoutHistoryTemplateQuery {
|
||||
|
||||
} // CcPlayoutHistoryTemplateQuery
|
18
legacy/application/models/airtime/CcPref.php
Normal file
18
legacy/application/models/airtime/CcPref.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for representing a row from the 'cc_pref' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcPref extends BaseCcPref {
|
||||
|
||||
} // CcPref
|
18
legacy/application/models/airtime/CcPrefPeer.php
Normal file
18
legacy/application/models/airtime/CcPrefPeer.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_pref' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcPrefPeer extends BaseCcPrefPeer {
|
||||
|
||||
} // CcPrefPeer
|
18
legacy/application/models/airtime/CcPrefQuery.php
Normal file
18
legacy/application/models/airtime/CcPrefQuery.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_pref' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcPrefQuery extends BaseCcPrefQuery {
|
||||
|
||||
} // CcPrefQuery
|
262
legacy/application/models/airtime/CcSchedule.php
Normal file
262
legacy/application/models/airtime/CcSchedule.php
Normal file
|
@ -0,0 +1,262 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for representing a row from the 'cc_schedule' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcSchedule extends BaseCcSchedule {
|
||||
|
||||
/**
|
||||
* Get the [optionally formatted] temporal [starts] column value.
|
||||
*
|
||||
*
|
||||
* @param string $format The date/time format string (either date()-style or strftime()-style).
|
||||
* If format is NULL, then the raw DateTime object will be returned.
|
||||
* @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL
|
||||
* @throws PropelException - if unable to parse/validate the date/time value.
|
||||
*/
|
||||
public function getDbStarts($format = 'Y-m-d H:i:s.u')
|
||||
{
|
||||
if ($this->starts === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
$dt = new DateTime($this->starts, new DateTimeZone("UTC"));
|
||||
} catch (Exception $x) {
|
||||
throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->starts, true), $x);
|
||||
}
|
||||
|
||||
if ($format === null) {
|
||||
// Because propel.useDateTimeClass is TRUE, we return a DateTime object.
|
||||
return $dt;
|
||||
} elseif (strpos($format, '%') !== false) {
|
||||
return strftime($format, $dt->format('U'));
|
||||
} else {
|
||||
return $dt->format($format);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the [optionally formatted] temporal [ends] column value.
|
||||
*
|
||||
*
|
||||
* @param string $format The date/time format string (either date()-style or strftime()-style).
|
||||
* If format is NULL, then the raw DateTime object will be returned.
|
||||
* @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL
|
||||
* @throws PropelException - if unable to parse/validate the date/time value.
|
||||
*/
|
||||
public function getDbEnds($format = 'Y-m-d H:i:s.u')
|
||||
{
|
||||
if ($this->ends === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
$dt = new DateTime($this->ends, new DateTimeZone("UTC"));
|
||||
} catch (Exception $x) {
|
||||
throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->ends, true), $x);
|
||||
}
|
||||
|
||||
if ($format === null) {
|
||||
// Because propel.useDateTimeClass is TRUE, we return a DateTime object.
|
||||
return $dt;
|
||||
} elseif (strpos($format, '%') !== false) {
|
||||
return strftime($format, $dt->format('U'));
|
||||
} else {
|
||||
return $dt->format($format);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the [optionally formatted] temporal [fadein] column value.
|
||||
*
|
||||
* @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL
|
||||
* @throws PropelException - if unable to parse/validate the date/time value.
|
||||
*/
|
||||
public function getDbFadeIn($format = "s.u")
|
||||
{
|
||||
return parent::getDbFadein($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the [optionally formatted] temporal [fadein] column value.
|
||||
*
|
||||
* @return mixed Formatted date/time value as string or DateTime object (if format is NULL), NULL if column is NULL
|
||||
* @throws PropelException - if unable to parse/validate the date/time value.
|
||||
*/
|
||||
public function getDbFadeOut($format = "s.u")
|
||||
{
|
||||
return parent::getDbFadeout($format);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param String in format SS.uuuuuu, Datetime, or DateTime accepted string.
|
||||
*
|
||||
* @return CcPlaylistcontents The current object (for fluent API support)
|
||||
*/
|
||||
public function setDbFadeIn($v)
|
||||
{
|
||||
$microsecond = 0;
|
||||
if ($v instanceof DateTime) {
|
||||
$dt = $v;
|
||||
}
|
||||
else if (preg_match('/^[0-9]{1,2}(\.\d{1,6})?$/', $v)) {
|
||||
// in php 5.3.2 createFromFormat() with "u" is not supported(bug)
|
||||
// Hence we need to do parsing.
|
||||
$info = explode('.', $v);
|
||||
$microsecond = $info[1];
|
||||
$dt = DateTime::createFromFormat("s", $info[0]);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
$dt = new DateTime($v);
|
||||
} catch (Exception $x) {
|
||||
throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x);
|
||||
}
|
||||
}
|
||||
|
||||
if ($microsecond == 0) {
|
||||
$this->fade_in = $dt->format('H:i:s.u');
|
||||
} else {
|
||||
$this->fade_in = $dt->format('H:i:s').".".$microsecond;
|
||||
}
|
||||
$this->modifiedColumns[] = CcSchedulePeer::FADE_IN;
|
||||
|
||||
return $this;
|
||||
} // setDbFadein()
|
||||
|
||||
/**
|
||||
*
|
||||
* @param String in format SS.uuuuuu, Datetime, or DateTime accepted string.
|
||||
*
|
||||
* @return CcPlaylistcontents The current object (for fluent API support)
|
||||
*/
|
||||
public function setDbFadeOut($v)
|
||||
{
|
||||
$microsecond = 0;
|
||||
if ($v instanceof DateTime) {
|
||||
$dt = $v;
|
||||
}
|
||||
else if (preg_match('/^[0-9]{1,2}(\.\d{1,6})?$/', $v)) {
|
||||
// in php 5.3.2 createFromFormat() with "u" is not supported(bug)
|
||||
// Hence we need to do parsing.
|
||||
$info = explode('.', $v);
|
||||
$microsecond = $info[1];
|
||||
$dt = DateTime::createFromFormat("s", $info[0]);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
$dt = new DateTime($v);
|
||||
} catch (Exception $x) {
|
||||
throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x);
|
||||
}
|
||||
}
|
||||
|
||||
if ($microsecond == 0) {
|
||||
$this->fade_out = $dt->format('H:i:s.u');
|
||||
} else {
|
||||
$this->fade_out = $dt->format('H:i:s').".".$microsecond;
|
||||
}
|
||||
$this->modifiedColumns[] = CcSchedulePeer::FADE_OUT;
|
||||
|
||||
return $this;
|
||||
} // setDbFadeout()
|
||||
|
||||
/**
|
||||
* Sets the value of [starts] column to a normalized version of the date/time value specified.
|
||||
*
|
||||
* @param mixed $v string, integer (timestamp), or DateTime value. Empty string will
|
||||
* be treated as NULL for temporal objects.
|
||||
* @return CcSchedule The current object (for fluent API support)
|
||||
*/
|
||||
public function setDbStarts($v)
|
||||
{
|
||||
$utcTimeZone = new DateTimeZone('UTC');
|
||||
|
||||
if ($v instanceof DateTime) {
|
||||
$dt = $v;
|
||||
$dt->setTimezone($utcTimeZone);
|
||||
} else {
|
||||
// some string/numeric value passed; we normalize that so that we can
|
||||
// validate it.
|
||||
try {
|
||||
if (is_numeric($v)) { // if it's a unix timestamp
|
||||
$dt = new DateTime('@'.$v, $utcTimeZone);
|
||||
|
||||
} else {
|
||||
$dt = new DateTime($v, $utcTimeZone);
|
||||
}
|
||||
} catch (Exception $x) {
|
||||
throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x);
|
||||
}
|
||||
}
|
||||
|
||||
$this->starts = ($dt ? $dt->format('Y-m-d H:i:s.u') : null);
|
||||
$this->modifiedColumns[] = CcSchedulePeer::STARTS;
|
||||
|
||||
return $this;
|
||||
} // setDbStarts()
|
||||
|
||||
/**
|
||||
* Sets the value of [ends] column to a normalized version of the date/time value specified.
|
||||
*
|
||||
* @param mixed $v string, integer (timestamp), or DateTime value. Empty string will
|
||||
* be treated as NULL for temporal objects.
|
||||
* @return CcSchedule The current object (for fluent API support)
|
||||
*/
|
||||
public function setDbEnds($v)
|
||||
{
|
||||
$utcTimeZone = new DateTimeZone('UTC');
|
||||
|
||||
if ($v instanceof DateTime) {
|
||||
$dt = $v;
|
||||
$dt->setTimezone($utcTimeZone);
|
||||
} else {
|
||||
// some string/numeric value passed; we normalize that so that we can
|
||||
// validate it.
|
||||
try {
|
||||
if (is_numeric($v)) { // if it's a unix timestamp
|
||||
$dt = new DateTime('@'.$v, $utcTimeZone);
|
||||
|
||||
} else {
|
||||
$dt = new DateTime($v, $utcTimeZone);
|
||||
}
|
||||
} catch (Exception $x) {
|
||||
throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x);
|
||||
}
|
||||
}
|
||||
|
||||
$this->ends = ($dt ? $dt->format('Y-m-d H:i:s.u') : null);
|
||||
$this->modifiedColumns[] = CcSchedulePeer::ENDS;
|
||||
|
||||
return $this;
|
||||
} // setDbEnds()
|
||||
|
||||
public function isCurrentItem($epochNow = null) {
|
||||
|
||||
if (is_null($epochNow)) {
|
||||
$epochNow = microtime(true);
|
||||
}
|
||||
|
||||
$epochStart = floatval($this->getDbStarts('U.u'));
|
||||
$epochEnd = floatval($this->getDbEnds('U.u'));
|
||||
|
||||
if ($epochStart < $epochNow && $epochEnd > $epochNow) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // CcSchedule
|
18
legacy/application/models/airtime/CcSchedulePeer.php
Normal file
18
legacy/application/models/airtime/CcSchedulePeer.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Skeleton subclass for performing query and update operations on the 'cc_schedule' table.
|
||||
*
|
||||
*
|
||||
*
|
||||
* You should add additional methods to this class to meet the
|
||||
* application requirements. This class will only be generated as
|
||||
* long as it does not already exist in the output directory.
|
||||
*
|
||||
* @package propel.generator.airtime
|
||||
*/
|
||||
class CcSchedulePeer extends BaseCcSchedulePeer {
|
||||
|
||||
} // CcSchedulePeer
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue