CC-5450 : Refactor Media Management

working on creating a function to return a proper JSON nested array structure.
This commit is contained in:
Naomi 2013-11-08 13:03:29 -05:00
parent 3950445acb
commit 6ae372d591
5 changed files with 12358 additions and 174 deletions

View File

@ -72,8 +72,13 @@ class LibraryController extends Zend_Controller_Action
//set audio columns for display of data. //set audio columns for display of data.
$mediaService = new Application_Service_MediaService(); $mediaService = new Application_Service_MediaService();
$columns = json_encode($mediaService->makeDatatablesColumns('Audio')); $columns = json_encode($mediaService->makeDatatablesColumns('AudioFile'));
$script = "localStorage.setItem( 'datatables-audiofile-aoColumns', JSON.stringify($columns) ); "; $script = "localStorage.setItem( 'datatables-audiofile-aoColumns', JSON.stringify($columns) ); ";
//set webstream columns for display of data.
$columns = json_encode($mediaService->makeDatatablesColumns('Webstream'));
$script .= "localStorage.setItem( 'datatables-webstream-aoColumns', JSON.stringify($columns) ); ";
$this->view->headScript()->appendScript($script); $this->view->headScript()->appendScript($script);
try { try {

View File

@ -8,6 +8,8 @@ class MediaController extends Zend_Controller_Action
$ajaxContext = $this->_helper->getHelper('AjaxContext'); $ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext $ajaxContext
->addActionContext('audio-file-feed', 'json') ->addActionContext('audio-file-feed', 'json')
->addActionContext('webstream-feed', 'json')
->addActionContext('playlist-feed', 'json')
->initContext(); ->initContext();
} }
@ -24,6 +26,36 @@ class MediaController extends Zend_Controller_Action
$this->view->sEcho = intval($params["sEcho"]); $this->view->sEcho = intval($params["sEcho"]);
$this->view->iTotalDisplayRecords = count($r); $this->view->iTotalDisplayRecords = count($r);
$this->view->iTotalRecords = count($r); $this->view->iTotalRecords = count($r);
$this->view->audiofiles = $r; $this->view->media = $r;
}
public function webstreamFeedAction()
{
$params = $this->getRequest()->getParams();
Logging::info($params);
$mediaService = new Application_Service_MediaService();
$r = $mediaService->getDatatablesWebstreams($params);
$this->view->sEcho = intval($params["sEcho"]);
$this->view->iTotalDisplayRecords = count($r);
$this->view->iTotalRecords = count($r);
$this->view->media = $r;
}
public function playlistFeedAction()
{
$params = $this->getRequest()->getParams();
Logging::info($params);
$mediaService = new Application_Service_MediaService();
$r = $mediaService->getDatatablesAudioFiles($params);
$this->view->sEcho = intval($params["sEcho"]);
$this->view->iTotalDisplayRecords = count($r);
$this->view->iTotalRecords = count($r);
$this->view->media = $r;
} }
} }

View File

@ -1,30 +1,35 @@
<?php <?php
use Airtime\MediaItem\AudioFileQuery; use Airtime\CcSubjsPeer;
use Airtime\MediaItem\WebstreamPeer;
use Airtime\MediaItem\PlaylistPeer;
use Airtime\MediaItem\AudioFilePeer; use Airtime\MediaItem\AudioFilePeer;
use Airtime\MediaItem\AudioFileQuery;
use Airtime\MediaItem\WebstreamQuery;
use Airtime\MediaItem\PlaylistQuery;
class Application_Service_MediaService class Application_Service_MediaService
{ {
private function getAudioColumnDetails() { private function getAudioFileColumnDetails() {
return array( return array(
AudioFilePeer::ID => array( "Id" => array(
"isColumn" => false "isColumn" => false
), ),
AudioFilePeer::TRACK_TITLE => array( "TrackTitle" => array(
"isColumn" => true, "isColumn" => true,
"title" => _("Title"), "title" => _("Title"),
"width" => "170px", "width" => "170px",
"class" => "library_title" "class" => "library_title"
), ),
AudioFilePeer::ARTIST_NAME => array( "ArtistName" => array(
"isColumn" => true, "isColumn" => true,
"title" => _("Creator"), "title" => _("Creator"),
"width" => "160px", "width" => "160px",
"class" => "library_creator" "class" => "library_creator"
), ),
AudioFilePeer::ALBUM_TITLE => array( "AlbumTitle" => array(
"isColumn" => true, "isColumn" => true,
"title" => _("Album"), "title" => _("Album"),
"width" => "150px", "width" => "150px",
@ -33,12 +38,41 @@ class Application_Service_MediaService
); );
} }
private function getAudioDatatableColumnOrder() { private function getWebstreamColumnDetails() {
return array(
"Id" => array(
"isColumn" => false
),
"Name" => array(
"isColumn" => true,
"title" => _("Title"),
"width" => "170px",
"class" => "library_title"
),
"CcSubjs.DbLogin" => array(
"isColumn" => true,
"title" => _("Owner"),
"width" => "160px",
"class" => "library_owner"
)
);
}
private function getAudioFileDatatableColumnOrder() {
return array (
"TrackTitle",
"ArtistName",
"AlbumTitle",
);
}
private function getWebstreamDatatableColumnOrder() {
return array ( return array (
AudioFilePeer::TRACK_TITLE, "Name",
AudioFilePeer::ARTIST_NAME, "CcSubjs.DbLogin",
AudioFilePeer::ALBUM_TITLE,
); );
} }
@ -59,10 +93,12 @@ class Application_Service_MediaService
for ($i = 0; $i < count($columnOrder); $i++) { for ($i = 0; $i < count($columnOrder); $i++) {
$data = $columnInfo[$columnOrder[$i]]; $data = $columnInfo[$columnOrder[$i]];
$datatablesColumns[] = array( $datatablesColumns[] = array(
"sTitle" => $data["title"], "sTitle" => $data["title"],
"mDataProp" => AudioFilePeer::translateFieldName($columnOrder[$i], BasePeer::TYPE_COLNAME, BasePeer::TYPE_PHPNAME), //replacing the dots because datatables will expect a nested array for joined tables
//and propel is giving us a single dimension array.
"mDataProp" => $columnOrder[$i],
"bSortable" => isset($data["sortable"]) ? $data["sortable"] : true, "bSortable" => isset($data["sortable"]) ? $data["sortable"] : true,
"bSearchable" => isset($data["searchable"]) ? $data["searchable"] : true, "bSearchable" => isset($data["searchable"]) ? $data["searchable"] : true,
"bVisible" => isset($data["visible"]) ? $data["visible"] : true, "bVisible" => isset($data["visible"]) ? $data["visible"] : true,
@ -74,20 +110,171 @@ class Application_Service_MediaService
return $datatablesColumns; return $datatablesColumns;
} }
private function buildQuery($query, $params) {
$alias = "media";
$selectColumns = array();
$len = intval($params["iColumns"]);
for ($i = 0; $i < $len; $i++) {
$selectColumns[] = $params["mDataProp_{$i}"];
}
//$query->select($selectColumns);
//$query->setFormatter('PropelArrayFormatter');
$query->setFormatter('PropelOnDemandFormatter');
//all media join this table for the "Owner" column;
//removing the "." access since PropelSimpleArrayFormatter returns a flat array
//Datatables is expecting a nested object if there is a "." in the name.
//would be nice to extend class PropelSimpleArrayFormatter if possible to include
//nested associative arrays in the output.
$query->joinWith("CcSubjs");
//take care of WHERE clause
$search = $params["sSearch"];
$searchTerms = $search == "" ? array() : explode(" ", $search);
$andConditions = array();
$orConditions = array();
//namespacing seems to cause a problem in the WHERE clause
//if we don't prefix the PHP name with the model or alias.
$modelName = $query->getModelName();
foreach ($searchTerms as $term) {
$orConditions = array();
$len = intval($params["iColumns"]);
for ($i = 0; $i < $len; $i++) {
$whereTerm = $params["mDataProp_{$i}"];
if (strrpos($whereTerm, ".") === false) {
$whereTerm = $modelName.".".$whereTerm;
}
$name = "{$term}{$i}";
$cond = "{$whereTerm} iLIKE ?";
$param = "{$term}%";
$query->condition($name, $cond, $param);
$orConditions[] = $name;
}
if (count($searchTerms) > 1) {
$query->combine($orConditions, 'or', $term);
$andConditions[] = $term;
}
else {
$query->where($orConditions, 'or');
}
}
if (count($andConditions) > 1) {
$query->where($andConditions, 'and');
}
//ORDER BY statements
$len = intval($params["iSortingCols"]);
for ($i = 0; $i < $len; $i++) {
$colNum = $params["iSortCol_{$i}"];
$colName = $params["mDataProp_{$colNum}"];
$colDir = $params["sSortDir_{$i}"] === "asc" ? Criteria::ASC : Criteria::DESC;
$query->orderBy($colName, $colDir);
}
//LIMIT OFFSET statements
$limit = intval($params["iDisplayLength"]);
$offset = intval($params["iDisplayStart"]);
$query
->limit($limit)
->offset($offset);
Logging::info($query->toString());
return $query;
}
private function columnMapCallback($class) {
$func = function ($column) use ($class) {
return $class::translateFieldName($column, BasePeer::TYPE_COLNAME, BasePeer::TYPE_PHPNAME);
};
return $func;
}
/*
* @param $coll PropelCollection formatted on demand.
*
* @return $output, an array of data with the columns needed for datatables.
*/
private function createOutput($coll, $columns) {
$output = array();
$item;
foreach ($coll as $media) {
$item = array();
foreach ($columns as $column) {
$x = $media;
$a = $item;
$getters = explode(".", $column);
foreach ($getters as $attr) {
$k = $attr;
$method = "get{$attr}";
$x = $x->$method();
}
$item[$column] = $x;
}
$output[] = $item;
}
return $output;
}
public function getDatatablesAudioFiles($params) { public function getDatatablesAudioFiles($params) {
$func = function ($column) { $columns = self::getAudioFileDatatableColumnOrder();
return AudioFilePeer::translateFieldName($column, BasePeer::TYPE_COLNAME, BasePeer::TYPE_PHPNAME);
};
$columns = array_keys(self::getAudioColumnDetails());
$selectColumns = array_map($func, $columns);
$q = AudioFileQuery::create(); $q = AudioFileQuery::create();
$q->select($selectColumns); $q = self::buildQuery($q, $params);
$coll = $q->find(); $coll = $q->find();
return $coll->toArray(); return self::createOutput($coll, $columns);
}
public function getDatatablesWebstreams($params) {
$columns = self::getWebstreamDatatableColumnOrder();
$q = WebstreamQuery::create();
$q = self::buildQuery($q, $params);
$coll = $q->find();
return self::createOutput($coll, $columns);
}
public function getDatatablesPlaylists($params) {
$columns = self::getPlaylistDatatableColumnOrder();
$q = PlaylistQuery::create();
$q = self::buildQuery($q, $params);
$coll = $q->find();
return self::createOutput($coll, $columns);
} }
} }

View File

@ -7,12 +7,12 @@ var AIRTIME = (function(AIRTIME) {
function createDatatable(config) { function createDatatable(config) {
$("#"+config.id).dataTable({ var table = $("#"+config.id).dataTable({
"aoColumns": config.columns, "aoColumns": config.columns,
"bProcessing": true, "bProcessing": true,
"bServerSide": true, "bServerSide": true,
"sAjaxSource": config.source, "sAjaxSource": config.source,
"sAjaxDataProp": config.prop, "sAjaxDataProp": "media",
"fnServerData": function ( sSource, aoData, fnCallback ) { "fnServerData": function ( sSource, aoData, fnCallback ) {
aoData.push( { name: "format", value: "json"} ); aoData.push( { name: "format", value: "json"} );
@ -33,6 +33,8 @@ var AIRTIME = (function(AIRTIME) {
"bAutoWidth": true, "bAutoWidth": true,
"sDom": 'Rl<"#library_display_type">f<"dt-process-rel"r><"H"<"library_toolbar"C>><"dataTables_scrolling"t><"F"ip>', "sDom": 'Rl<"#library_display_type">f<"dt-process-rel"r><"H"<"library_toolbar"C>><"dataTables_scrolling"t><"F"ip>',
}); });
table.fnSetFilteringDelay(350);
} }
mod.onReady = function () { mod.onReady = function () {
@ -51,8 +53,22 @@ var AIRTIME = (function(AIRTIME) {
}, },
localColumns: "datatables-audiofile-aoColumns", localColumns: "datatables-audiofile-aoColumns",
tableId: "audio_table", tableId: "audio_table",
source: baseUrl+"media/audio-file-feed", source: baseUrl+"media/audio-file-feed"
dataprop: "audiofiles" },
"lib_webstreams": {
initialized: false,
initialize: function() {
},
navigate: function() {
},
always: function() {
},
localColumns: "datatables-webstream-aoColumns",
tableId: "webstream_table",
source: baseUrl+"media/webstream-feed"
} }
}; };

File diff suppressed because it is too large Load Diff