Changes to how the playlist works, from files to database.

This commit is contained in:
naomiaro 2010-09-21 15:52:35 -04:00
parent 1d20c0bc27
commit 5a84cee98d
11 changed files with 576 additions and 621 deletions

View File

@ -322,7 +322,7 @@ if ($uiBrowser->userid) {
break;
case "editItem":
$uiBrowser->SCRATCHPAD->addItem($_REQUEST['id']);
//$uiBrowser->SCRATCHPAD->addItem($_REQUEST['id']);
$Smarty->assign('editItem', array('type' => $uiBrowser->type, 'id' => $_REQUEST['id'], 'folderId' => $uiBrowser->fid, 'curr_langid' => $_REQUEST['curr_langid']));
break;

View File

@ -301,12 +301,12 @@ switch ($_REQUEST['act']) {
break;
case "PL.create":
$ids = (isset($_REQUEST['id']) ? $_REQUEST['id'] : null);
if (($ui_tmpid = $uiHandler->PLAYLIST->create($ids)) !== FALSE) {
//$ids = (isset($_REQUEST['id']) ? $_REQUEST['id'] : null);
if (($ui_tmpid = $uiHandler->PLAYLIST->create()) !== FALSE) {
if ($ids) {
$uiHandler->SCRATCHPAD->addItem($ids);
//$uiHandler->SCRATCHPAD->addItem($ids);
}
$uiHandler->SCRATCHPAD->addItem($ui_tmpid);
//$uiHandler->SCRATCHPAD->addItem($ui_tmpid);
}
$uiHandler->PLAYLIST->setRedirect('_2PL.editMetaData');
break;
@ -366,7 +366,7 @@ switch ($_REQUEST['act']) {
break;
case "PL.moveItem":
$uiHandler->PLAYLIST->moveItem($_REQUEST['id'], $_REQUEST['pos']);
$uiHandler->PLAYLIST->moveItem($_REQUEST['oldPos'], $_REQUEST['newPos']);
$uiHandler->PLAYLIST->setReload();
break;
@ -382,12 +382,12 @@ switch ($_REQUEST['act']) {
case "PL.editMetaData":
$uiHandler->PLAYLIST->editMetaData($_REQUEST);
$uiHandler->SCRATCHPAD->addItem($_REQUEST['id']);
//$uiHandler->SCRATCHPAD->addItem($_REQUEST['id']);
break;
case "PL.deleteActive":
if (($ui_tmpid = $uiHandler->PLAYLIST->deleteActive()) !== FALSE) {
$uiHandler->SCRATCHPAD->removeItems($ui_tmpid);
//$uiHandler->SCRATCHPAD->removeItems($ui_tmpid);
}
$uiHandler->PLAYLIST->setReload();
break;

View File

@ -19,50 +19,56 @@
<td style="width: 30px"><input type="checkbox" name="all" onClick="collector_switchAll('PL')"></td>
<td style="width: 200px">##Title##</td>
<td style="white-space: nowrap">##Clip length##</td>
<td> ##Original##</td>
<td>##Cue In##</td>
<td>##Cue Out##</td>
<td style="width: 200px">##Artist##</td>
<td style="width: 30px;">##Type##</td>
<td style="width: 30px; border: 0">##Move##</td>
</tr>
<!-- end repeat after 14 columns -->
<!-- start item -->
{foreach from=$PL->getFlat($PL->activeId) key='pos' item='i'}
{*
{foreach from=$PL->getActiveArr($PL->activeId) key='pos' item='i'}
<!-- fade information -->
<tr onClick="return contextmenu('{$i.attrs.id}', {if $i.firstInList == 1}'PL.changeFadeIn'{else}'PL.changeTransition'{/if})" style="background-color: #bbb">
<td></td>
<td colspan="5" style="border: 0; cursor: pointer">##Fade## {$i.fadein_ms|string_format:"%d"} ms</td>
<td colspan="7" style="border: 0; cursor: pointer">##Fade In## {$i.fadein|string_format:"%d"} ms</td>
</tr>
<!-- /fade information -->
*}
<tr class="{cycle values='blue1, blue2'}">
<td><input type="checkbox" class="checkbox" name="{$i.attrs.id}"/></td>
<td {include file="playlist/actionhandler.tpl"}>{$i.title}</td>
<td><input type="checkbox" class="checkbox" name="{$pos}"/></td>
<td {include file="playlist/actionhandler.tpl"}>{$i.track_title}</td>
<td {include file="playlist/actionhandler.tpl"} style="text-align: right">
{assign var="_playlength" value=$i.attrs.clipLength}{niceTime in=$_playlength}
{assign var="_playlength" value=$i.cliplength}{niceTime in=$_playlength}
</td>
<td {include file="playlist/actionhandler.tpl"} style="text-align: right">
{assign var="_duration" value=$i.playlength}{niceTime in=$_duration}
{assign var="_duration" value=$i.cuein}{niceTime in=$_duration}
</td>
<td {include file="playlist/actionhandler.tpl"}>{$i.creator}</td>
<td {include file="playlist/actionhandler.tpl"} style="text-align: right">
{assign var="_duration" value=$i.cueout}{niceTime in=$_duration}
</td>
<td {include file="playlist/actionhandler.tpl"}>{$i.artist_name}</td>
<td {include file="playlist/actionhandler.tpl"}>
<img src="img/{$i.type}.png" border="0" alt="{$i.type|capitalize}" {* include file="sub/alttext.tpl" *} />
<img src="img/{$i.type}.png" border="0" alt="{$i.ftype|capitalize}" {* include file="sub/alttext.tpl" *} />
</td>
<td style="border: 0">
<a href="#" onClick="hpopup('{$UI_HANDLER}?act=PL.moveItem&id={$i.attrs.id}&pos={$pos-1}')"><img src="img/bt_top_xsm.png" alt="##move up##" vspace=1 hspace=1/></a>
<a href="#" onClick="hpopup('{$UI_HANDLER}?act=PL.moveItem&id={$i.attrs.id}&pos={$pos+1}')"><img src="img/bt_bottom_xsm.png" alt="##move down##" vspace=1 hspace=1/></a>
<a href="#" onClick="hpopup('{$UI_HANDLER}?act=PL.moveItem&id=&oldPos={$pos}&newPos={$pos-1}')"><img src="img/bt_top_xsm.png" alt="##move up##" vspace=1 hspace=1/></a>
<a href="#" onClick="hpopup('{$UI_HANDLER}?act=PL.moveItem&oldPos={$pos}&newPos={$pos+1}')"><img src="img/bt_bottom_xsm.png" alt="##move down##" vspace=1 hspace=1/></a>
</td>
</tr>
{/foreach}
{if isset($pos)}
{*
<!-- fade information -->
<!-- fade information -->
<tr onClick="return contextmenu('{$i.attrs.id}', 'PL.changeFadeOut')" style="background-color: #bbb">
<td></td>
<td colspan="5" style="border: 0; cursor: pointer">##Fade## {$i.fadeout_ms|string_format:"%d"} ms</td>
<td colspan="7" style="border: 0; cursor: pointer">##Fade Out## {$i.fadeout|string_format:"%d"} ms</td>
</tr>
<!-- /fade information -->
*}
{/foreach}
{if isset($pos)}
{else}
<tr class="{cycle values='blue1, blue2'}">
<td style="border: 0" colspan="7" align="center">##Empty playlist##</td>
@ -78,8 +84,6 @@
<input type="button" class="button_large" onClick="collector_clearAll('PL', 'PL.removeItem')" value="##Clear Playlist##" />
</div>
<div class="container_button">
<input type="button" class="button_large" value="##Save Playlist##" onClick="hpopup('{$UI_HANDLER}?act=PL.save')">
<input type="button" class="button_large" value="##Revert to Saved##" onClick="popup('{$UI_BROWSER}?popup[]=PL.confirmRevert', 'PL.revertChanges', 400, 50)">
<input type="button" class="button_large" value="##Delete Playlist##" onClick="popup('{$UI_BROWSER}?popup[]=PL.confirmDelete', 'PL.deleteActive', 400, 50)">
</div>
<div class="container_button">

View File

@ -92,140 +92,120 @@ class uiHandler extends uiBase {
// --- files ---
function processFile($audio_file, $caller){
function processFile($audio_file, $caller){
global $CC_CONFIG;
global $CC_CONFIG;
if ($this->testForAudioType($audio_file) === FALSE) {
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "uses an unsupported file type."}}');
}
$md5 = md5_file($audio_file);
$duplicate = StoredFile::RecallByMd5($md5);
if ($duplicate) {
$_SESSION['plupload'] = "is duplicate";
if (PEAR::isError($duplicate)) {
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": ' . $duplicate->getMessage() .'}}');
}
else {
$duplicateName = $this->gb->getMetadataValue($duplicate->getId(), UI_MDATA_KEY_TITLE, $this->sessid);
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "An identical audioclip named ' . $duplicateName . ' already exists in the storage server."}}');
}
}
$metadata = camp_get_audio_metadata($audio_file);
if (PEAR::isError($metadata)) {
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": ' + $metadata->getMessage() + '}}');
}
// #2196 no id tag -> use the original filename
if (basename($audio_file) == $metadata['dc:title']) {
$metadata['dc:title'] = basename($audio_file);
$metadata['ls:filename'] = basename($audio_file);
}
// bsSetMetadataBatch doesnt like these values
unset($metadata['audio']);
unset($metadata['playtime_seconds']);
$values = array(
"filename" => basename($audio_file),
"filepath" => $audio_file,
"filetype" => "audioclip",
"mime" => $metadata["dc:format"],
"md5" => $md5
);
$storedFile = $this->gb->putFile($values, $this->sessid);
if (PEAR::isError($storedFile)) {
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": ' + $storedFile->getMessage() + '}}');
}
$result = $this->gb->bsSetMetadataBatch($storedFile->getId(), $metadata);
return $storedFile->getId();
if ($this->testForAudioType($audio_file) === FALSE) {
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "uses an unsupported file type."}}');
}
function pluploadFile($data)
{
header('Content-type: text/plain; charset=UTF-8');
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
// Settings
$targetDir = ini_get("upload_tmp_dir") . DIRECTORY_SEPARATOR . "plupload";
$cleanupTargetDir = false; // Remove old files
$maxFileAge = 60 * 60; // Temp file age in seconds
// 5 minutes execution time
@set_time_limit(5 * 60);
// Get parameters
$chunk = isset($_REQUEST["chunk"]) ? $_REQUEST["chunk"] : 0;
$chunks = isset($_REQUEST["chunks"]) ? $_REQUEST["chunks"] : 0;
$fileName = isset($_REQUEST["name"]) ? $_REQUEST["name"] : '';
// Clean the fileName for security reasons
//$fileName = preg_replace('/[^\w\._]+/', '', $fileName);
// Create target dir
if (!file_exists($targetDir)) {
@mkdir($targetDir);
}
// Remove old temp files
if (is_dir($targetDir) && ($dir = opendir($targetDir))) {
while (($file = readdir($dir)) !== false) {
$filePath = $targetDir . DIRECTORY_SEPARATOR . $file;
// Remove temp files if they are older than the max age
if (preg_match('/\\.tmp$/', $file) && (filemtime($filePath) < time() - $maxFileAge))
@unlink($filePath);
}
closedir($dir);
$md5 = md5_file($audio_file);
$duplicate = StoredFile::RecallByMd5($md5);
if ($duplicate) {
if (PEAR::isError($duplicate)) {
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": ' . $duplicate->getMessage() .'}}');
}
else {
die('{"jsonrpc" : "2.0", "error" : {"code": 100, "message": "Failed to open temp directory."}, "id" : "id"}');
$duplicateName = $this->gb->getMetadataValue($duplicate->getId(), UI_MDATA_KEY_TITLE, $this->sessid);
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "An identical audioclip named ' . $duplicateName . ' already exists in the storage server."}}');
}
}
$metadata = camp_get_audio_metadata($audio_file);
if (PEAR::isError($metadata)) {
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": ' + $metadata->getMessage() + '}}');
}
// #2196 no id tag -> use the original filename
if (basename($audio_file) == $metadata['dc:title']) {
$metadata['dc:title'] = basename($audio_file);
$metadata['ls:filename'] = basename($audio_file);
}
// bsSetMetadataBatch doesnt like these values
unset($metadata['audio']);
unset($metadata['playtime_seconds']);
$values = array(
"filename" => basename($audio_file),
"filepath" => $audio_file,
"filetype" => "audioclip",
"mime" => $metadata["dc:format"],
"md5" => $md5
);
$storedFile = $this->gb->putFile($values, $this->sessid);
if (PEAR::isError($storedFile)) {
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": ' + $storedFile->getMessage() + '}}');
}
$result = $this->gb->bsSetMetadataBatch($storedFile->getId(), $metadata);
return $storedFile->getId();
}
function pluploadFile($data)
{
header('Content-type: text/plain; charset=UTF-8');
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
// Settings
$targetDir = ini_get("upload_tmp_dir") . DIRECTORY_SEPARATOR . "plupload";
$cleanupTargetDir = false; // Remove old files
$maxFileAge = 60 * 60; // Temp file age in seconds
// 5 minutes execution time
@set_time_limit(5 * 60);
// Get parameters
$chunk = isset($_REQUEST["chunk"]) ? $_REQUEST["chunk"] : 0;
$chunks = isset($_REQUEST["chunks"]) ? $_REQUEST["chunks"] : 0;
$fileName = isset($_REQUEST["name"]) ? $_REQUEST["name"] : '';
// Clean the fileName for security reasons
//$fileName = preg_replace('/[^\w\._]+/', '', $fileName);
// Create target dir
if (!file_exists($targetDir)) {
@mkdir($targetDir);
}
// Remove old temp files
if (is_dir($targetDir) && ($dir = opendir($targetDir))) {
while (($file = readdir($dir)) !== false) {
$filePath = $targetDir . DIRECTORY_SEPARATOR . $file;
// Remove temp files if they are older than the max age
if (preg_match('/\\.tmp$/', $file) && (filemtime($filePath) < time() - $maxFileAge))
@unlink($filePath);
}
// Look for the content type header
if (isset($_SERVER["HTTP_CONTENT_TYPE"]))
$contentType = $_SERVER["HTTP_CONTENT_TYPE"];
closedir($dir);
}
else {
die('{"jsonrpc" : "2.0", "error" : {"code": 100, "message": "Failed to open temp directory."}, "id" : "id"}');
}
if (isset($_SERVER["CONTENT_TYPE"]))
$contentType = $_SERVER["CONTENT_TYPE"];
// Look for the content type header
if (isset($_SERVER["HTTP_CONTENT_TYPE"]))
$contentType = $_SERVER["HTTP_CONTENT_TYPE"];
if (strpos($contentType, "multipart") !== false) {
if (isset($_FILES['file']['tmp_name']) && is_uploaded_file($_FILES['file']['tmp_name'])) {
// Open temp file
$out = fopen($targetDir . DIRECTORY_SEPARATOR . $fileName, $chunk == 0 ? "wb" : "ab");
if ($out) {
// Read binary input stream and append it to temp file
$in = fopen($_FILES['file']['tmp_name'], "rb");
if (isset($_SERVER["CONTENT_TYPE"]))
$contentType = $_SERVER["CONTENT_TYPE"];
if ($in) {
while ($buff = fread($in, 4096))
fwrite($out, $buff);
} else
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');
fclose($out);
unlink($_FILES['file']['tmp_name']);
} else
die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');
} else
die('{"jsonrpc" : "2.0", "error" : {"code": 103, "message": "Failed to move uploaded file."}, "id" : "id"}');
} else {
if (strpos($contentType, "multipart") !== false) {
if (isset($_FILES['file']['tmp_name']) && is_uploaded_file($_FILES['file']['tmp_name'])) {
// Open temp file
$out = fopen($targetDir . DIRECTORY_SEPARATOR . $fileName, $chunk == 0 ? "wb" : "ab");
if ($out) {
// Read binary input stream and append it to temp file
$in = fopen("php://input", "rb");
$in = fopen($_FILES['file']['tmp_name'], "rb");
if ($in) {
while ($buff = fread($in, 4096))
@ -234,16 +214,35 @@ class uiHandler extends uiBase {
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');
fclose($out);
return $this->processFile($targetDir . DIRECTORY_SEPARATOR . $fileName);
unlink($_FILES['file']['tmp_name']);
} else
die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');
}
} else
die('{"jsonrpc" : "2.0", "error" : {"code": 103, "message": "Failed to move uploaded file."}, "id" : "id"}');
} else {
// Open temp file
$out = fopen($targetDir . DIRECTORY_SEPARATOR . $fileName, $chunk == 0 ? "wb" : "ab");
if ($out) {
// Read binary input stream and append it to temp file
$in = fopen("php://input", "rb");
// Return JSON-RPC response
die('{"jsonrpc" : "2.0", "result" : null, "id" : "id"}');
if ($in) {
while ($buff = fread($in, 4096))
fwrite($out, $buff);
} else
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');
fclose($out);
return $this->processFile($targetDir . DIRECTORY_SEPARATOR . $fileName);
} else
die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');
}
// Return JSON-RPC response
die('{"jsonrpc" : "2.0", "result" : null, "id" : "id"}');
}
/**
* Provides file upload and store it to the storage
*

View File

@ -11,23 +11,19 @@ class uiPlaylist
public $activeId;
public $title;
public $duration;
public $changed;
public $token;
private $Base;
private $reloadUrl;
private $redirectUrl;
private $returnUrl;
private $flat;
public function __construct(&$uiBase)
public function __construct($uiBase)
{
$this->Base =& $uiBase;
$this->Base = $uiBase;
$this->activeId =& $_SESSION[UI_PLAYLIST_SESSNAME]['activeId'];
$this->changed =& $_SESSION[UI_PLAYLIST_SESSNAME]['changed'];
$this->title = $this->Base->getMetadataValue($this->activeId, UI_MDATA_KEY_TITLE);
$this->duration = $this->Base->getMetadataValue($this->activeId, UI_MDATA_KEY_DURATION);
$this->token =& $_SESSION[UI_PLAYLIST_SESSNAME]['token'];
$this->title = $this->Base->gb->getPLMetadataValue($this->activeId, UI_MDATA_KEY_TITLE);
$this->duration = $this->Base->gb->getPLMetadataValue($this->activeId, UI_MDATA_KEY_DURATION);
$this->reloadUrl = UI_BROWSER.'?popup[]=_reload_parent&popup[]=_close';
$this->redirectUrl = UI_BROWSER.'?popup[]=_2PL.simpleManagement&popup[]=_close';
$this->returnUrl = UI_BROWSER.'?act=PL.simpleManagement';
@ -58,12 +54,13 @@ class uiPlaylist
private function getPLArray($id)
{
return $this->Base->gb->getPlaylistArray($id, $this->Base->sessid);
$res = $this->Base->gb->getPlaylistArray($id);
return $res;
} // fn getPLArray
public function getActiveArr()
{
{
if (!$this->activeId) {
return FALSE;
}
@ -86,7 +83,7 @@ class uiPlaylist
// look PL
// store access token to ls_pref abd session
// load PL into session
if ($this->token) {
if ($this->activeId) {
if (UI_WARNING) {
$this->Base->_retMsg('You already have an open playlist. Close it first.');
}
@ -99,17 +96,19 @@ class uiPlaylist
}
return FALSE;
}
$token = $this->Base->gb->lockPlaylistForEdit($plid, $this->Base->sessid);
if (PEAR::isError($token)) {
$res = $this->Base->gb->lockPlaylistForEdit($plid, $this->Base->sessid);
if (PEAR::isError($res)) {
if (UI_VERBOSE === TRUE) {
print_r($token);
print_r($res);
}
$this->Base->_retMsg('Unable to open playlist "$1".', $this->Base->getMetadataValue($plid, UI_MDATA_KEY_TITLE));
return FALSE;
}
$this->token = $token;
$this->Base->gb->savePref($this->Base->sessid, UI_PL_ACCESSTOKEN_KEY, $plid.':'.$this->token);
$this->Base->gb->savePref($this->Base->sessid, UI_PL_ACCESSTOKEN_KEY, $plid);
$this->activeId = $plid;
$_SESSION['pl'] = "Activating playlist with id: " . $this->activeId;
if ($msg && UI_VERBOSE) {
$this->Base->_retMsg('Playlist "$1" opened.', $this->Base->getMetadataValue($plid, UI_MDATA_KEY_TITLE));
}
@ -119,21 +118,19 @@ class uiPlaylist
public function release($msg=TRUE)
{
// get token from ls_pref
{
// release PL
// delete PL from session
// remove token from ls_pref
if (!$this->token) {
if (!$this->activeId) {
if (UI_WARNING) {
$this->Base->_retMsg('There is no playlist available to unlock.');
}
return FALSE;
}
$plgunid = $this->Base->gb->releaseLockedPlaylist($this->token, $this->Base->sessid);
if (PEAR::isError($plgunid)) {
$res = $this->Base->gb->releaseLockedPlaylist($this->activeId, $this->Base->sessid);
if (PEAR::isError($res)) {
if (UI_VERBOSE === TRUE) {
print_r($plgunid);
print_r($res);
}
if (UI_WARNING) {
$this->Base->_retMsg('Unable to release playlist.');
@ -144,64 +141,12 @@ class uiPlaylist
$this->Base->_retMsg('Playlist "$1" released.', $this->Base->getMetadataValue(BasicStor::IdFromGunid($plgunid), UI_MDATA_KEY_TITLE));
}
$this->activeId = NULL;
$this->token = NULL;
$this->Base->gb->delPref($this->Base->sessid, UI_PL_ACCESSTOKEN_KEY);
$this->changed = FALSE;
return TRUE;
} // fn release
public function save()
{
$tmpid = $this->activeId;
$this->release(FALSE);
$this->activate($tmpid, FALSE);
$this->changed = FALSE;
if (UI_VERBOSE) {
$this->Base->_retMsg('Playlist "$1" saved.', $this->Base->getMetadataValue($tmpid, UI_MDATA_KEY_TITLE));
}
$this->Base->SCRATCHPAD->reloadMetadata();
return $this->activeId;
} // fn save
public function revert()
{
if (!$this->token) {
if (UI_WARNING) {
$this->Base->_retMsg('No playlists have been locked by you.');
}
return FALSE;
}
$plgunid = $this->Base->gb->revertEditedPlaylist($this->token, $this->Base->sessid);
if (PEAR::isError($plgunid)) {
if (UI_VERBOSE === TRUE) {
print_r($plgunid);
}
if (UI_WARNING) {
$this->Base->_retMsg('Unable to revert to locked state.');
}
return FALSE;
}
if (UI_VERBOSE) {
$this->Base->_retMsg('Playlist "$1" reverted.', $this->Base->getMetadataValue(BasicStor::IdFromGunid($plgunid), UI_MDATA_KEY_TITLE));
}
$this->activeId = NULL;
$this->token = NULL;
$this->Base->gb->delPref($this->Base->sessid, UI_PL_ACCESSTOKEN_KEY);
if ($this->activate(BasicStor::IdFromGunid($plgunid), FALSE) !== TRUE) {
return FALSE;
}
$this->changed = FALSE;
return $this->activeId;
} // fn revert
public function reportLookedPL($setMsg=FALSE)
{
if (is_string($this->Base->gb->loadPref($this->Base->sessid, UI_PL_ACCESSTOKEN_KEY))) {
@ -216,20 +161,17 @@ class uiPlaylist
public function loadLookedFromPref()
{
$this->changed = TRUE;
if (is_string($saved = $this->Base->gb->loadPref($this->Base->sessid, UI_PL_ACCESSTOKEN_KEY))) {
list ($plid, $token) = explode (':', $saved);
if (!$this->Base->gb->existsPlaylist($plid, $this->Base->sessid)) {
if (is_string($plid = $this->Base->gb->loadPref($this->Base->sessid, UI_PL_ACCESSTOKEN_KEY))) {
if (!$this->Base->gb->existsPlaylist($plid)) {
$this->Base->gb->delPref($this->Base->sessid, UI_PL_ACCESSTOKEN_KEY);
$this->Base->_retMsg('Playlist not found in database.');
$this->Base->redirUrl = UI_BROWSER.'?popup[]=_2PL.simpleManagement&popup[]=_close';
return FALSE;
}
$this->activeId = $plid;
$this->token = $token;
$this->Base->redirUrl = UI_BROWSER.'?popup[]=_2PL.simpleManagement&popup[]=_close';
return TRUE;
}
@ -244,14 +186,14 @@ class uiPlaylist
* @param array $duration
* @return unknown
*/
public function addItem($elemIds, $duration=NULL)
public function addItem($elemIds, $pos=NULL, $duration=NULL)
{
$this->changed = TRUE;
$fadeIn = NULL;
$fadeOut = NULL;
$length = NULL;
$clipstart = NULL;
$cliplength = NULL;
$cueIn = NULL;
$cueIn = NULL;
/*
gstreamer bug:
Warning: The clipEnd can't be bigger than ninety nine percent (99%) of the clipLength,
@ -264,15 +206,16 @@ class uiPlaylist
$this->Base->_retMsg('No item(s) selected.');
}
return FALSE;
}
}
if (!is_array($elemIds)) {
$elemIds = array($elemIds);
}
}
if (isset($duration)) {
$length = sprintf('%02d', $duration['H']).':'.sprintf('%02d', $duration['i']).':'.sprintf('%02d', $duration['s']).'.000000';
}
foreach ($elemIds as $elemId) {
$r = $this->Base->gb->addAudioClipToPlaylist($this->token, $elemId, $this->Base->sessid, $fadeIn, $fadeOut, $length, $clipstart, $clipend);
$r = $this->Base->gb->addAudioClipToPlaylist($this->activeId, $elemId, $pos, $fadeIn, $fadeOut, $cliplength, $cueIn, $cueOut);
if (PEAR::isError($r)) {
if (UI_VERBOSE === TRUE) {
print_r($r);
@ -285,21 +228,23 @@ class uiPlaylist
} // fn addItem
public function removeItem($elemIds)
public function removeItem($positions)
{
$this->changed = TRUE;
if (!$elemIds) {
if (!$positions) {
if (UI_WARNING) {
$this->Base->_retMsg('No item(s) selected.');
}
return FALSE;
}
if (!is_array($elemIds))
$elemIds = array($elemIds);
foreach ($elemIds as $elemId) {
if ($this->Base->gb->delAudioClipFromPlaylist($this->token, $elemId, $this->Base->sessid) !== TRUE) {
if (!is_array($positions))
$positions = array($positions);
//so the automatic updating of playlist positioning doesn't affect removal.
sort($positions);
$positions = array_reverse($positions);
foreach ($positions as $pos) {
if ($this->Base->gb->delAudioClipFromPlaylist($this->activeId, $pos) !== TRUE) {
$this->Base->_retMsg('Cannot remove item from playlist.');
return FALSE;
}
@ -321,23 +266,25 @@ class uiPlaylist
// create PL
// activate
// add clip if $id is set
$this->changed = TRUE;
if (is_array($this->activeId)) {
if ($this->activeId) {
$this->Base->_retMsg('A playlist is already opened.');
return FALSE;
}
$datetime = strftime('%Y-%m-%d %H:%M:%S');
$plid = $this->Base->gb->createPlaylist($datetime, $this->Base->sessid);
if (!$plid) {
$this->Base->_retMsg('Cannot create playlist.');
return FALSE;
}
$this->Base->setMetadataValue($plid, UI_MDATA_KEY_CREATOR, $this->Base->login);
$this->Base->setMetadataValue($plid, UI_MDATA_KEY_DESCRIPTION, tra('created at $1', $datetime));
$this->Base->gb->setPLMetadataValue($plid, UI_MDATA_KEY_CREATOR, $this->Base->login);
$this->Base->gb->setPLMetadataValue($plid, UI_MDATA_KEY_DESCRIPTION, tra('created at $1', $datetime));
if ($this->activate($plid)===FALSE) {
$this->Base->_retMsg('Cannot activate playlist.');
return FALSE;
}
if ($ids) {
@ -345,6 +292,7 @@ class uiPlaylist
return FALSE;
}
}
return $plid;
} // fn create
@ -400,7 +348,6 @@ class uiPlaylist
public function changeTransition($id, $type, $duration)
{
$this->changed = TRUE;
$pause = $pause;
$xfade = Playlist::secondsToPlaylistTime($duration/1000);
@ -467,12 +414,10 @@ class uiPlaylist
} // fn changeTransition
public function moveItem($id, $pos)
public function moveItem($oldPos, $newPos)
{
$this->changed = TRUE;
$r = $this->Base->gb->moveAudioClipInPlaylist($this->token, $id, $pos, $this->Base->sessid);
if (PEAR::isError($r)) {
$r = $this->Base->gb->moveAudioClipInPlaylist($this->activeId, $oldPos, $newPos);
if (PEAR::isError($r) || $r === FALSE) {
if (UI_VERBOSE === TRUE) {
print_r($r);
}
@ -485,8 +430,6 @@ class uiPlaylist
public function reorder($items)
{
$this->changed = TRUE;
// just to be sure items are in right order
asort($items);
$pos = 0;
@ -647,7 +590,9 @@ class uiPlaylist
foreach ($mask['playlist'] as $k=>$v) {
$mask['playlist'][$k]['element'] = uiBase::formElementEncode($v['element']);
if ($getval = $this->Base->getMetadataValue($id, $v['element'], $langid)) {
$getval = $this->Base->gb->getPLMetadataValue($id, $v['element'], $langid);
if ($getval) {
$mask['playlist'][$k]['default'] = $getval;
$mask['playlist'][$k]['attributes']['onFocus'] = 'MData_confirmChange(this)';
};
@ -679,8 +624,6 @@ class uiPlaylist
public function editMetaData($formdata)
{
$this->changed = TRUE;
include(dirname(__FILE__).'/formmask/metadata.inc.php');
$id = $this->activeId;
@ -692,8 +635,9 @@ class uiPlaylist
} else {
$this->Base->redirUrl = UI_BROWSER."?act=PL.editMetaData&id=$id&curr_langid=".$formdata['target_langid'];
}
foreach ($mask['playlist'] as $k=>$v) {
$formdata[uiBase::formElementEncode($v['element'])] ? $mData[uiBase::formElementDecode($v['element'])] = $formdata[uiBase::formElementEncode($v['element'])] : NULL;
}
@ -702,7 +646,7 @@ class uiPlaylist
}
foreach ($mData as $key => $val) {
$r = $this->Base->gb->setMetadataValue($id, $key, $this->Base->sessid, $val, $curr_langid);
$r = $this->Base->gb->setPLMetadataValue($id, $key, $val, $curr_langid);
if (PEAR::isError($r)) {
if (UI_VERBOSE === TRUE) {
print_r($r);
@ -712,7 +656,7 @@ class uiPlaylist
}
if (UI_VERBOSE) {
$this->Base->_retMsg('Metadata saved.');
}
}
} // fn editMetadata
@ -720,9 +664,12 @@ class uiPlaylist
{
$id = $this->activeId;
$this->release(FALSE);
if ($this->Base->delete($id)) {
$res = $this->Base->gb->deletePlaylist($id);
if ($res === TRUE) {
return $id;
}
$this->Base->_retMsg('Cannot delete this playlist.');
return FALSE;
} // fn deleteActive

View File

@ -1432,7 +1432,7 @@ class BasicStor {
*/
public static function GetObjType($oid)
{
$type = "unknown";
$type = "unknown";
$gunid = BasicStor::GunidFromId($oid);
if (PEAR::isError($gunid)) {
return $gunid;
@ -1662,13 +1662,12 @@ class BasicStor {
$res = preg_match("|^([0-9a-fA-F]{16})?$|", $p_gunid);
return $res;
}
/**
* Set playlist edit flag
*
* @param string $p_playlistId
* Playlist global unique ID
* Playlist unique ID
* @param boolean $p_val
* Set/clear of edit flag
* @param string $p_sessid
@ -1686,15 +1685,15 @@ class BasicStor {
return $p_subjid;
}
}
$storedFile = StoredFile::RecallByGunid($p_playlistId);
if (is_null($storedFile) || PEAR::isError($storedFile)) {
return $storedFile;
$pl = Playlist::Recall($p_playlistId);
if (is_null($pl) || PEAR::isError($pl)) {
return $pl;
}
$state = $storedFile->getState();
$state = $pl->getState();
if ($p_val) {
$r = $storedFile->setState('edited', $p_subjid);
$r = $pl->setState('edited', $p_subjid);
} else {
$r = $storedFile->setState('ready', 'NULL');
$r = $pl->setState('ready', 'NULL');
}
if (PEAR::isError($r)) {
return $r;
@ -1713,14 +1712,14 @@ class BasicStor {
*/
public function isEdited($p_playlistId)
{
$storedFile = StoredFile::RecallByGunid($p_playlistId);
if (is_null($storedFile) || PEAR::isError($storedFile)) {
return $storedFile;
$pl = Playlist::Recall($p_playlistId);
if (is_null($pl) || PEAR::isError($pl)) {
return $pl;
}
if (!$storedFile->isEdited($p_playlistId)) {
if (!$pl->isEdited($p_playlistId)) {
return FALSE;
}
return $storedFile->isEditedBy($p_playlistId);
return $pl->isEditedBy($p_playlistId);
}

View File

@ -472,21 +472,35 @@ class GreenBox extends BasicStor {
*/
public function createPlaylist($fname, $sessid='')
{
global $CC_CONFIG, $CC_DBC;
$gunid = StoredFile::CreateGunid();
$lc = new LocStor($CC_DBC, $CC_CONFIG);
$gunid2 = $lc->createPlaylist($sessid, $gunid, $fname);
if (PEAR::isError($gunid2)) {
return $gunid2;
}
// get local id:
$id = BasicStor::IdFromGunid($gunid2);
if (PEAR::isError($id)) {
return $id;
}
return $id;
$pl = new Playlist();
$pl = $pl->create($fname);
return $pl;
} // fn createPlaylist
public function setPLMetadataValue($id, $category, $value, $lang=NULL, $mid=NULL)
{
$pl = Playlist::Recall($id);
if($pl === FALSE)
return FALSE;
$res = $pl->setMetaData($category, $value, $lang);
return $res;
}
public function getPLMetadataValue($id, $category, $langId=NULL)
{
$pl = Playlist::Recall($id);
if($pl === FALSE)
return FALSE;
$res = $pl->getPLMetaData($category);
return $res;
}
/**
* Return playlist as XML string
@ -513,15 +527,19 @@ class GreenBox extends BasicStor {
* session ID
* @return array
*/
public function getPlaylistArray($id, $sessid)
public function getPlaylistArray($id)
{
$gunid = BasicStor::GunidFromId($id);
$pl = StoredFile::Recall($id);
if (is_null($pl) || PEAR::isError($pl)) {
return $pl;
$pl = Playlist::Recall($id);
if ($pl === FALSE) {
return FALSE;
}
$gunid = $pl->gunid;
return $pl->md->genPhpArray();
$res = $pl->getContents();
if(is_null($res))
return array();
return $res;
} // fn getPlaylistArray
@ -535,45 +553,32 @@ class GreenBox extends BasicStor {
* @return string
* playlist access token
*/
public function lockPlaylistForEdit($id, $sessid)
{
global $CC_CONFIG, $CC_DBC;
$gunid = BasicStor::GunidFromId($id);
$lc = new LocStor($CC_DBC, $CC_CONFIG);
$res = $lc->editPlaylist($sessid, $gunid);
if (PEAR::isError($res)) {
return $res;
}
return $res['token'];
} // fn lockPlaylistForEdit
public function lockPlaylistForEdit($id, $sessid) {
$pl = Playlist::Recall($id);
if($pl === FALSE)
return;
$res = $pl->lock($sessid);
}
/**
* Release token, regenerate XML from DB and clear edit flag.
* clear edit flag.
*
* @param string $token
* playlist access token
* @param string $sessid
* session ID
* @return string gunid
*/
public function releaseLockedPlaylist($token, $sessid)
{
$gunid = $this->bsCloseDownload($token, 'metadata');
if (PEAR::isError($gunid)) {
return $gunid;
}
$storedFile = StoredFile::RecallByGunid($gunid);
if (is_null($storedFile) || PEAR::isError($storedFile)) {
return $storedFile;
}
// $r = $storedFile->md->regenerateXmlFile();
// if (PEAR::isError($r)) {
// return $r;
// }
$this->setEditFlag($gunid, FALSE, $sessid);
return $gunid;
} // fn releaseLockedPlaylist
public function releaseLockedPlaylist($id, $sessid) {
$pl = Playlist::Recall($id);
if($pl === FALSE)
return FALSE;
$res = $pl->unlock($sessid);
return $res;
}
/**
@ -596,32 +601,17 @@ class GreenBox extends BasicStor {
* optional clipstart time format hh:mm:ss.ssssss - relative to begin
* @param string $clipend
* optional $clipend time format hh:mm:ss.ssssss - relative to begin
* @return string, generated playlistElement gunid
* @return boolean, true if added.
*/
public function addAudioClipToPlaylist($token, $acId, $sessid,
$fadeIn=NULL, $fadeOut=NULL, $length=NULL, $clipstart=NULL, $clipend=NULL)
public function addAudioClipToPlaylist($id, $acId, $pos=NULL, $fadeIn=NULL, $fadeOut=NULL, $cliplength=NULL, $cueIn=NULL, $cueOut=NULL)
{
require_once("Playlist.php");
$pl = StoredFile::RecallByToken($token);
if (is_null($pl) || PEAR::isError($pl)) {
return $pl;
}
$acGunid = BasicStor::GunidFromId($acId);
if ($pl->cyclicRecursion($acGunid)){
return PEAR::raiseError(
"GreenBox::addAudioClipToPlaylist: cyclic-recursion detected".
" ($type)"
);
}
$res = $pl->addAudioClip($acId, $fadeIn, $fadeOut, NULL, $length, $clipstart, $clipend);
if (PEAR::isError($res)) {
return $res;
}
// recalculate offsets and total length:
$r = $pl->recalculateTimes();
if (PEAR::isError($r)) {
return $r;
$pl = Playlist::Recall($id);
if ($pl === FALSE) {
return FALSE;
}
$res = $pl->addAudioClip($acId, $pos, $fadeIn, $fadeOut, $cliplength, $cueIn, $cueOut);
return $res;
} // fn addAudioClipToPlaylist
@ -629,159 +619,100 @@ class GreenBox extends BasicStor {
/**
* Remove audioclip from playlist
*
* @param string $token
* playlist access token
* @param string $plElGunid
* global id of deleted playlistElement
* @param string $sessid
* session ID
* @return boolean
* @param string $id
* playlist id
* @param int $pos
* position of element in playlist to delete.
* @return boolean, true if deleted.
* @todo rename this function to "deleteAudioClipFromPlaylist"
*/
public function delAudioClipFromPlaylist($token, $plElGunid, $sessid)
public function delAudioClipFromPlaylist($id, $pos)
{
require_once("Playlist.php");
$pl = StoredFile::RecallByToken($token);
if (is_null($pl) || PEAR::isError($pl)) {
return $pl;
}
$res = $pl->delAudioClip($plElGunid);
if (PEAR::isError($res)) {
return $res;
}
// recalculate offsets and total length:
$r = $pl->recalculateTimes();
if (PEAR::isError($r)) {
return $r;
$pl = Playlist::Recall($id);
if ($pl === FALSE) {
return FALSE;
}
$res = $pl->delAudioClip($pos);
return $res;
} // fn delAudioClipFromPlaylist
}
/**
* Move audioClip to the new position in the playlist.
*
* This method may change id attributes of playlistElements and/or
* fadeInfo.
*
* @param string $id
* playlist id
* @param id $oldPos
* old position in playlist
* @param int $newPos
* new position in playlist
* @return boolean
*/
public function moveAudioClipInPlaylist($id, $oldPos, $newPos)
{
$pl = Playlist::Recall($id);
if ($pl === FALSE) {
return FALSE;
}
$res = $pl->moveAudioClip($oldPos, $newPos);
return $res;
}
/**
* Change fadeInfo values
*
* @param string $token
* playlist access token
* @param string $plElGunid
* global id of deleted playlistElement
* @param string $id
* playlist id
* @param string $fadeIn
* in time format hh:mm:ss.ssssss
* @param string $fadeOut
* in time format hh:mm:ss.ssssss
* @param sessid $string
* session ID
* @return boolean
*/
public function changeFadeInfo($token, $plElGunid, $fadeIn, $fadeOut, $sessid)
public function changeFadeInfo($id, $pos, $fadeIn, $fadeOut)
{
require_once("Playlist.php");
$pl = StoredFile::RecallByToken($token);
if (is_null($pl) || PEAR::isError($pl)) {
return $pl;
$pl = Playlist::Recall($id);
if ($pl === FALSE) {
return FALSE;
}
$res = $pl->changeFadeInfo($plElGunid, $fadeIn, $fadeOut);
if (PEAR::isError($res)) {
return $res;
}
// recalculate offsets and total length:
$r = $pl->recalculateTimes();
if (PEAR::isError($r)) {
return $r;
}
return TRUE;
} // fn changeFadeInfo
$res = $pl->changeFadeInfo($pos, $fadeIn, $fadeOut);
return $res;
}
/**
* Change cueIn/curOut values for playlist element
* Change cueIn/cueOut values for playlist element
*
* @param string $token
* playlist access token
* @param string $plElGunid
* global id of deleted playlistElement
* @param string $clipStart
* @param string $id
* playlist id
* @param string $cueIn
* in time format hh:mm:ss.ssssss
* @param string $clipEnd
* @param string $cueOut
* in time format hh:mm:ss.ssssss
* relative to begin
* @param sessid $string
* session ID
* @return boolean or pear error object
*/
public function changeClipLength($token, $plElGunid, $clipStart, $clipEnd, $sessid)
public function changeClipLength($id, $cueIn, $cueOut)
{
require_once("Playlist.php");
$pl = StoredFile::RecallByToken($token);
if (is_null($pl) || PEAR::isError($pl)) {
return $pl;
$pl = Playlist::Recall($id);
if ($pl === FALSE) {
return FALSE;
}
$res = $pl->changeClipLength($plElGunid, $clipStart, $clipEnd);
if (PEAR::isError($res)) {
return $res;
}
// recalculate offsets and total length:
$r = $pl->recalculateTimes();
if (PEAR::isError($r)) {
return $r;
}
return TRUE;
} // fn changeFadeInfo
/**
* Move audioClip to the new position in the playlist.
*
* This method may change id attributes of playlistElements and/or
* fadeInfo.
*
* @param string $token
* playlist access token
* @param string $plElGunid
* global id of deleted playlistElement
* @param int $newPos
* new position in playlist
* @param string $sessid
* session ID
* @return boolean
*/
public function moveAudioClipInPlaylist($token, $plElGunid, $newPos, $sessid)
{
require_once("Playlist.php");
$pl = StoredFile::RecallByToken($token);
if (is_null($pl) || PEAR::isError($pl)) {
return $pl;
}
$res = $pl->moveAudioClip($plElGunid, $newPos);
if (PEAR::isError($res)) {
return $res;
}
// recalculate offsets and total length:
$r = $pl->recalculateTimes();
if (PEAR::isError($r)) {
return $r;
}
return TRUE;
} // fn moveAudioClipInPlaylist
/**
* RollBack playlist changes to the locked state
*
* @param string $token
* playlist access token
* @param string $sessid
* session ID
* @return string
* gunid of playlist
*/
public function revertEditedPlaylist($token, $sessid='')
{
global $CC_CONFIG, $CC_DBC;
$lc = new LocStor($CC_DBC, $CC_CONFIG);
return $lc->revertEditedPlaylist($token, $sessid);
} // fn revertEditedPlaylist
$res = $pl->changeClipLength($pos, $cueIn, $cueOut);
return $res;
}
/**
* Delete a Playlist metafile.
*
@ -791,14 +722,11 @@ class GreenBox extends BasicStor {
* session ID
* @return boolean
*/
public function deletePlaylist($id, $sessid)
public function deletePlaylist($id)
{
global $CC_CONFIG, $CC_DBC;
$gunid = BasicStor::GunidFromId($id);
$lc = new LocStor($CC_DBC, $CC_CONFIG);
return $lc->deletePlaylist($sessid, $gunid);
} // fn deletePlaylist
return Playlist::Delete($id);
}
/**
* Find info about clip at specified offset in playlist.
@ -951,12 +879,14 @@ class GreenBox extends BasicStor {
* session ID
* @return boolean
*/
public function existsPlaylist($id, $sessid)
public function existsPlaylist($id)
{
global $CC_CONFIG, $CC_DBC;
$gunid = BasicStor::GunidFromId($id);
$lc = new LocStor($CC_DBC, $CC_CONFIG);
return $lc->existsPlaylist($sessid, $gunid);
$pl = Playlist::Recall($id);
if ($pl === FALSE) {
return FALSE;
}
return TRUE;
} // fn existsPlaylist
@ -974,10 +904,17 @@ class GreenBox extends BasicStor {
*/
public function playlistIsAvailable($id, $sessid)
{
global $CC_CONFIG, $CC_DBC;
$gunid = BasicStor::GunidFromId($id);
$lc = new LocStor($CC_DBC, $CC_CONFIG);
return $lc->playlistIsAvailable($sessid, $gunid, TRUE);
$pl = Playlist::Recall($id);
if ($pl === FALSE) {
return FALSE;
}
$res = $pl->isEdited();
if($res !== FALSE)
return $res;
return TRUE;
} // fn playlistIsAvailable

View File

@ -988,15 +988,15 @@ class LocStor extends BasicStor {
*/
public function playlistIsAvailable($sessid, $playlistId, $getUid=FALSE)
{
// $ex = $this->existsPlaylist($sessid, $playlistId);
// if (PEAR::isError($ex)) {
// return $ex;
// }
// if (!$ex) {
// return PEAR::raiseError(
// 'LocStor::playlistIsAvailable: playlist not exists'
// );
// }
$ex = $this->existsPlaylist($sessid, $playlistId);
if (PEAR::isError($ex)) {
return $ex;
}
if (!$ex) {
return PEAR::raiseError(
'LocStor::playlistIsAvailable: playlist not exists'
);
}
$ie = $this->isEdited($playlistId);
if ($ie === FALSE) {
return TRUE;

View File

@ -53,6 +53,8 @@ class Playlist {
*/
public $md;
private $categories = array("dc:title" => "name", "dc:creator" => "creator", "dc:description" => "description", "dcterms:extent" => "length");
public function __construct($p_gunid=NULL)
{
@ -102,8 +104,30 @@ class Playlist {
}
// Recall the object to get all the proper values
$storedPlaylist = Playlist::Recall($storedPlaylist->id);
return $storedPlaylist;
//$storedPlaylist = Playlist::Recall($storedPlaylist->id);
return $storedPlaylist->id;
}
public static function Delete($id) {
global $CC_CONFIG, $CC_DBC;
$CC_DBC->query("BEGIN");
$sql = "DELETE FROM ".$CC_CONFIG['playListTable']. " WHERE id='{$id}'";
$res = $CC_DBC->query($sql);
if (PEAR::isError($res)) {
$CC_DBC->query("ROLLBACK");
return $res;
}
// Commit changes
$res = $CC_DBC->query("COMMIT");
if (PEAR::isError($res)) {
$CC_DBC->query("ROLLBACK");
return $res;
}
return TRUE;
}
/**
@ -113,25 +137,24 @@ class Playlist {
* @return StoredFile|Playlist|NULL
* Return NULL if the object doesnt exist in the DB.
*/
public static function Recall($id)
{
global $CC_DBC;
global $CC_CONFIG;
$cond = "id='$id'";
public static function Recall($id) {
global $CC_DBC, $CC_CONFIG;
$escapedID = pg_escape_string($id);
$sql = "SELECT id,"
." name, state, currentlyaccessing, editedby, "
." mtime"
." FROM ".$CC_CONFIG['playListTable']
." WHERE $cond";
." WHERE id ='{$escapedID}'";
$row = $CC_DBC->getRow($sql);
if (PEAR::isError($row)) {
return $row;
return FALSE;
}
if (is_null($row)) {
return null;
return FALSE;
}
$storedPlaylist = new Playlist($id);
@ -272,53 +295,58 @@ class Playlist {
}
return ($ca > 0);
}
/**
* Returns true if virtual file is edited
*
* @param string $p_playlistId
* playlist global unique ID
* @return boolean
*/
public function isEdited($p_playlistId=NULL)
{
if (is_null($p_playlistId)) {
return ($this->state == 'edited');
}
$state = $this->getState($p_playlistId);
if ($state != 'edited') {
return FALSE;
}
return TRUE;
}
/**
/**
* Returns id of user editing playlist
*
* @param string $p_playlistId
* playlist global unique ID
* @return int|null|PEAR_Error
* id of user editing it
* @return int id of user editing playlist
*/
public function isEditedBy($p_playlistId=NULL)
{
global $CC_CONFIG, $CC_DBC;
if (is_null($p_playlistId)) {
$p_playlistId = $this->id;
}
$sql = "SELECT editedBy FROM ".$CC_CONFIG['playListTable']
." WHERE id='$p_playlistId'";
$ca = $CC_DBC->getOne($sql);
if (PEAR::isError($ca)) {
return $ca;
}
if (is_null($ca)) {
return $ca;
}
return intval($ca);
public function isEdited() {
if($this->state === 'edited') {
return $this->editedby;
}
return FALSE;
}
/**
* Set playlist edit flag
*
* @param string $p_playlistId
* Playlist unique ID
* @param boolean $p_val
* Set/clear of edit flag
* @param string $p_sessid
* Session id
* @param int $p_subjid
* Subject id (if sessid is not specified)
* @return boolean
* previous state
*/
public function setEditFlag($p_val=TRUE, $p_sessid=NULL, $p_subjid=NULL) {
if (!is_null($p_sessid)) {
$p_subjid = Alib::GetSessUserId($p_sessid);
if (PEAR::isError($p_subjid)) {
return $p_subjid;
}
}
$state = $this->state;
if ($p_val) {
$r = $this->setState('edited', $p_subjid);
} else {
$r = $this->setState('ready', 'NULL');
}
if (PEAR::isError($r)) {
return $r;
}
return ($state == 'edited');
}
/**
* Return local ID of virtual file.
*
@ -328,12 +356,33 @@ class Playlist {
return $this->id;
}
private function getNextPos() {
global $CC_CONFIG, $CC_DBC;
$sql = "SELECT MAX(position) AS nextPos
FROM cc_playlistcontents
WHERE playlist_id='{$this->getId()}'";
$res = $CC_DBC->getOne($sql);
if(is_null($res))
return 0;
if(PEAR::isError($res)){
return $res;
}
return $res + 1;
}
public function getContents() {
global $CC_CONFIG, $CC_DBC;
$sql = "SELECT * FROM ".$CC_CONFIG['playListContentsTable']
." WHERE playlist_id ='{$this->getId()}' ORDER BY position";
$sql = "SELECT *
FROM cc_playlistcontents C JOIN cc_files F ON C.file_id = F.id
WHERE C.playlist_id='{$this->getId()}' ORDER BY C.position";
return $CC_DBC->getAll($sql);
}
@ -350,6 +399,9 @@ class Playlist {
return $res;
}
if(is_null($res))
return '00:00:00.000000';
return $res['length'];
}
@ -363,29 +415,19 @@ class Playlist {
public function create($fname=NULL)
{
$values = array("filename" => $fname);
$pl = Playlist::Insert($values);
if (PEAR::isError($pl)) {
return $pl;
$pl_id = Playlist::Insert($values);
if (PEAR::isError($pl_id)) {
return $pl_id;
}
/**
* TODO deal with metadata.
*/
/*
$res = $pl->setAuxMetadata();
if (PEAR::isError($res)) {
return $res;
}
*/
return $pl;
return $pl_id;
}
/**
* Lock playlist for edit
*
* @param GreenBox $gb
* reference to GreenBox object
* @param string $sessid
* session id
* @param int $subjid
* local subject (user) id
* @param boolean $val
@ -393,39 +435,29 @@ class Playlist {
* @return boolean
* previous state or error object
*/
public function lock($gb, $subjid=NULL, $val=TRUE)
public function lock($sessid, $subjid=NULL, $val=TRUE)
{
if ($val && $gb->isEdited($this->id) !== FALSE) {
if ($val && $this->isEdited() !== FALSE) {
return PEAR::raiseError(
'Playlist::lock: playlist already locked'
);
}
$r = $gb->setEditFlag($this->id, $val, NULL, $subjid);
$r = $this->setEditFlag($val, $sessid, $subjid);
return $r;
}
/**
* Unlock playlist (+recalculate and pregenerate XML)
* Unlock playlist
*
* @param GreenBox $gb
* @param sessId
* reference to GreenBox object
* @return boolean
* previous state or error object
*/
public function unlock($gb)
{
/**
* TODO deal with playlist length.
*/
/*
$r = $this->recalculateTimes();
if (PEAR::isError($r)) {
return $r;
}
*/
$r = $this->lock($gb, $this->id, NULL, FALSE);
public function unlock($sessid)
{
$r = $this->lock($sessid, NULL, FALSE);
return $r;
}
@ -451,7 +483,7 @@ class Playlist {
* @return string
* generated playlistElement gunid
*/
public function addAudioClip($acId, $pos, $fadeIn=NULL, $fadeOut=NULL, $cliplength=NULL, $cuein=NULL, $cueout=NULL)
public function addAudioClip($acId, $pos=NULL, $fadeIn=NULL, $fadeOut=NULL, $cliplength=NULL, $cuein=NULL, $cueout=NULL)
{
//get audio clip.
$ac = StoredFile::Recall($acId);
@ -467,7 +499,14 @@ class Playlist {
if (!is_null($cliplength)) {
$acLen = $cliplength;
}
//insert at end of playlist.
if(is_null($pos))
$pos = $this->getNextPos();
if (PEAR::isError($pos)) {
return $pos;
}
// insert default values if parameter was empty
$cuein = !is_null($cuein) ? $cuein : '00:00:00.000000';
$cueout = !is_null($cueout) ? $cueout : $acLen;
@ -641,7 +680,43 @@ class Playlist {
{
}
public function getPLMetaData($category)
{
global $CC_CONFIG, $CC_DBC;
$cat = $this->categories[$category];
if($cat === 'length') {
return $this->getLength();
}
$sql = "SELECT {$cat} AS mdata FROM ".$CC_CONFIG['playListTable'].
" WHERE id='{$this->getId()}'";
$res = $CC_DBC->getOne($sql);
if (PEAR::isError($res)) {
return FALSE;
}
return $res;
}
public function setMetaData($category, $value)
{
global $CC_CONFIG, $CC_DBC;
$cat = $this->categories[$category];
$sql = "UPDATE ".$CC_CONFIG['playListTable']. " SET {$cat}='{$value}'" .
" WHERE id='{$this->getId()}'";
$res = $CC_DBC->query($sql);
if (PEAR::isError($res)) {
return $res;
}
return TRUE;
}
/**
* Return array with gunids of all sub-playlists and clips used in

View File

@ -459,6 +459,7 @@ class StoredFile {
}
}
}
/* ========= 'factory' methods - should be called to construct StoredFile */
/**
@ -586,7 +587,6 @@ class StoredFile {
return $storedFile;
}
/**
* Fetch instance of StoreFile object.<br>
* Should be supplied with only ONE parameter, all the rest should
@ -1063,7 +1063,6 @@ class StoredFile {
return TRUE;
}
/**
* Set mime-type of virtual file
*
@ -1161,7 +1160,10 @@ class StoredFile {
/**
* Returns gunIds of the playlists the stored file is in.
* TODO update this to work with new tables.
*/
/*
public function getPlaylists() {
global $CC_CONFIG, $CC_DBC;
@ -1176,17 +1178,7 @@ class StoredFile {
return $playlists;
}
public function isScheduled() {
global $CC_CONFIG, $CC_DBC;
$sql = "SELECT * "
." FROM ".$CC_CONFIG['scheduleTable']
." WHERE ends > now() and playlist=x'{$this->gunid}'::bigint";
$scheduled = $CC_DBC->getAll($sql);
return $scheduled;
}
*/
/**

View File

@ -171,7 +171,7 @@ if (!camp_db_table_exists($CC_CONFIG['filesTable'])) {
bit_rate character varying(32),
sample_rate character varying(32),
format character varying(128),
length character(16),
length time without time zone,
album_title character varying(512),
genre character varying(64),
comments text,
@ -220,6 +220,8 @@ if (!camp_db_table_exists($CC_CONFIG['playListTable'])) {
currentlyaccessing integer NOT NULL DEFAULT 0,
editedby integer,
mtime timestamp(6) with time zone,
creator character varying(32),
description character varying(512),
CONSTRAINT cc_playlist_pkey PRIMARY KEY (id),
CONSTRAINT cc_playlist_editedby_fkey FOREIGN KEY (editedby)
REFERENCES cc_subjs (id) MATCH SIMPLE
@ -249,10 +251,10 @@ if (!camp_db_table_exists($CC_CONFIG['playListContentsTable'])) {
CONSTRAINT cc_playlistcontents_pkey PRIMARY KEY (id),
CONSTRAINT cc_playlistcontents_playlist_id_fkey FOREIGN KEY (playlist_id)
REFERENCES ".$CC_CONFIG['playListTable']." (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
ON UPDATE NO ACTION ON DELETE CASCADE,
CONSTRAINT cc_playlistcontents_file_id_fkey FOREIGN KEY (file_id)
REFERENCES ".$CC_CONFIG['filesTable']." (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
ON UPDATE NO ACTION ON DELETE CASCADE
);
CREATE OR REPLACE FUNCTION calculate_position() RETURNS trigger AS