diff --git a/campcaster/src/modules/htmlUI/var/html/styles_livesupport.css b/campcaster/src/modules/htmlUI/var/html/styles_livesupport.css index 62add869a..d4eadec11 100644 --- a/campcaster/src/modules/htmlUI/var/html/styles_livesupport.css +++ b/campcaster/src/modules/htmlUI/var/html/styles_livesupport.css @@ -370,7 +370,7 @@ table { table td { font-size: 12px; - padding: 0 6px 0 12px; + padding: 2px 6px 0px 6px; border-right: 1px solid #333; height: 19px; vertical-align: top; diff --git a/campcaster/src/modules/htmlUI/var/html/styles_popup.css b/campcaster/src/modules/htmlUI/var/html/styles_popup.css index 0dd47c7ce..e5c54ad0e 100644 --- a/campcaster/src/modules/htmlUI/var/html/styles_popup.css +++ b/campcaster/src/modules/htmlUI/var/html/styles_popup.css @@ -1,11 +1,11 @@ -body { +body { font-family: Arial, Verdana, Helvetica, sans-serif; font-size: 12px; color: #2C2C2C; margin: 10px; } -img { +img { border: none; } @@ -137,7 +137,8 @@ table tr.blue_head td { font-size: 12px; } -A#blue_head { font-size: 12px; +A#blue_head { + font-size: 12px; color:#fff; } @@ -230,7 +231,7 @@ table tr.red td { font-size: 12px; margin-left: 200px; } -label { +label { display: block; float: left; width: 100px; @@ -370,14 +371,15 @@ table td { font-size: 12px; vertical-align: top; } -table tr.blue_head td { font-size: 12px; +table tr.blue_head td { + font-size: 12px; background-color: #8baed1; color: #FFF; font-weight: bold; - } -A#blue_head { font-size: 12px; +A#blue_head { + font-size: 12px; color:#fff; } diff --git a/campcaster/src/modules/htmlUI/var/templates/library/results.tpl b/campcaster/src/modules/htmlUI/var/templates/library/results.tpl index 96ac10177..f4ed91522 100644 --- a/campcaster/src/modules/htmlUI/var/templates/library/results.tpl +++ b/campcaster/src/modules/htmlUI/var/templates/library/results.tpl @@ -8,13 +8,15 @@ {if $_results.cnt > 0}
 
-
+
- + + + @@ -30,6 +32,8 @@ {/if} + +
##Title## ##Creator####Album####Track## ##Duration## ##Type##
{$i.creator}{$i.source}{$i.track_num} {assign var="_duration" value=$i.duration}{niceTime in=$_duration} {$i.type|lower|capitalize} diff --git a/campcaster/src/modules/htmlUI/var/ui_browse.class.php b/campcaster/src/modules/htmlUI/var/ui_browse.class.php index b397f6481..adb0e1b33 100644 --- a/campcaster/src/modules/htmlUI/var/ui_browse.class.php +++ b/campcaster/src/modules/htmlUI/var/ui_browse.class.php @@ -7,9 +7,47 @@ class uiBrowse { public $Base; // uiBase object + + /** + * @var string + */ private $prefix; + + /** + * A pointer to the SESSION variable: ['UI_BROWSE_SESSNAME']['col'] + * + * It has the following structure: + * The first index denotes which column you are referring to. + * There are three possible columns. + * + * For each column, the following keys are possible: + * ['category'] --> selected category + * ['value'] --> an array of one value, the selected value + * ['values']['cnt'] --> number of values + * ['values']['results'] --> array of values, indexed numerically + * ['criteria'] --> criteria for one column, see top of DataEngine.php + * for description of these values. The criteria of all three + * columns are merged together to make $this->criteria. + * ['form_value'] --> the value as used in the HTML form + * + * @var array + */ private $col; + + /** + * A pointer to the SESSION variable: ['UI_BROWSE_SESSNAME']['criteria'] + * + * This array ultimately is passed to DataEngine::localSearch(). Look + * at the top of the DataEngine.php class for the structure of this + * variable. + * + * @var array + */ private $criteria; + + /** + * @var string + */ private $reloadUrl; @@ -42,6 +80,12 @@ class uiBrowse } // fn setReload + /** + * Initialize $this->col. Each column contains + * + * @param boolean $reload + * @return void + */ public function setDefaults($reload=FALSE) { $this->col[1]['category'] = UI_BROWSE_DEFAULT_KEY_1; @@ -69,12 +113,18 @@ class uiBrowse } // fn setDefaults + /** + * @return array + */ public function getCriteria() { return $this->criteria; } // fn getCriteria + /** + * @return array + */ public function getResult() { $this->searchDB(); @@ -85,7 +135,6 @@ class uiBrowse public function browseForm($id, $mask2) { include(dirname(__FILE__).'/formmask/metadata.inc.php'); - #$mask2['browse_columns']['category']['options'][0] = tra('Select a Value'); foreach ($mask['pages'] as $key => $val) { foreach ($mask['pages'][$key] as $v){ if (isset($v['type']) && $v['type']) { @@ -93,7 +142,7 @@ class uiBrowse $mask2['browse_columns']['category']['options'][$tmp] = tra($v['label']); } } - }; + } for ($n = 1; $n <= 3; $n++) { $form = new HTML_QuickForm('col'.$n, UI_STANDARD_FORM_METHOD, UI_HANDLER); @@ -109,7 +158,7 @@ class uiBrowse $output['col'.$n]['dynform'] = $renderer->toArray(); } - ## form to change limit and file-type + // form to change limit and file-type $form = new HTML_QuickForm('switch', UI_STANDARD_FORM_METHOD, UI_HANDLER); uiBase::parseArrayToForm($form, $mask2['browse_global']); $form->setDefaults(array('limit' => $this->criteria['limit'], @@ -124,68 +173,101 @@ class uiBrowse /** * Set the category for audio file browser. There are three columns - * you can set the category for. + * you can set the category for. All columns greater than the current + * one will be cleared of their values. * - * @param array $parm + * @param array $p_param * Has keys: * int ['col'] - the column you are setting the category for * string ['category'] - the category for the given column - * string ['value'] - the search value for the given category * @return void */ - public function setCategory($parm) + public function setCategory($p_param) { - $columnNumber = $parm['col']; - $category = $parm['category']; + // input values + $columnNumber = $p_param['col']; + $category = uiBase::formElementDecode($p_param['category']); - $this->col[$columnNumber]['category'] = uiBase::formElementDecode($category); - $criteria = isset($this->col[$columnNumber]['criteria']) ? $this->col[$columnNumber]['criteria'] : null; - $this->col[$columnNumber]['values'] = $this->Base->gb->browseCategory($this->col[$columnNumber]['category'], $criteria, $this->Base->sessid); + // Set the new values for this column. + $this->col[$columnNumber]['category'] = $category; + $this->col[$columnNumber]['criteria'] = NULL; + $this->col[$columnNumber]['form_value'] = '%%all%%'; + + // Get the values of this category based on the criteria in the + // other columns. + $this->setCriteria(); + $tmpCriteria = $this->criteria; + // We put a limit here to because some categories will select + // way too many values. + $tmpCriteria["limit"] = 1000; + $tmpCriteria["offset"] = 0; + $browseValues = $this->Base->gb->browseCategory( + $category, $tmpCriteria, $this->Base->sessid); + if (!PEAR::isError($browseValues)) { + $this->col[$columnNumber]['values'] = $browseValues; + } $this->Base->redirUrl = UI_BROWSER.'?act='.$this->prefix; - $this->clearHierarchy($columnNumber); } // fn setCategory /** + * Set the value for a category. This will cause the + * search results to change. + * * @param array $parm * contains the following indexes: * int ['col']: column number * string ['value'][0]: the search value for the given category * string ['category']: the category to search + * @see DataEngine + * See the top of that file for a description of the search + * criteria structure. */ - public function setValue($parm) + public function setValue($p_param) { - $this->criteria['offset'] = 0; - $columnNumber = $parm['col']; - $next = $columnNumber + 1; - $this->col[$columnNumber]['form_value'] = $parm['value'][0]; - $tmpFiletype = isset($this->criteria['filetype'])?$this->criteria['filetype']:UI_FILETYPE_ANY; - if ($parm['value'][0] == '%%all%%') { - $this->col[$next]['criteria'] = array('operator' => 'and', - 'filetype' => $tmpFiletype); - } else { - $conditions = array( - array('cat' => uiBase::formElementDecode($parm['category']), - 'op' => '=', - 'val' => $parm['value'][0] - )); - if (isset($this->col[$columnNumber]['criteria']['conditions']) - && is_array($this->col[$columnNumber]['criteria']['conditions'])) { - $conditions = array_merge($conditions, - $this->col[$columnNumber]['criteria']['conditions']); - } - $this->col[$next]['criteria'] = array( - 'operator' => 'and', - 'filetype' => $this->criteria['filetype'], - 'conditions' => $conditions); - } - $nextCriteria = isset($this->col[$next]['criteria']) ? $this->col[$next]['criteria'] : null; - $category = isset($this->col[$next]['category']) ? $this->col[$next]['category'] : null; - $this->col[$next]['values'] = $this->Base->gb->browseCategory($category, $nextCriteria, $this->Base->sessid); + $columnNumber = $p_param['col']; + $value = $p_param['value'][0]; + $category = $p_param['category']; + $this->criteria['offset'] = 0; + $this->col[$columnNumber]['form_value'] = $value; + + if ($value == '%%all%%') { + unset($this->col[$columnNumber]['criteria']['conditions']); + } else { + $conditions = array('cat' => uiBase::formElementDecode($category), + 'op' => '=', + 'val' => $value); + $this->col[$columnNumber]['criteria']['conditions'] = $conditions; + } + + // Update the criteria $this->setCriteria(); - $this->clearHierarchy($next); + $tmpCriteria = $this->criteria; + // We put a limit here to because some categories will select + // way too many values. + $tmpCriteria["limit"] = 1000; + $tmpCriteria["offset"] = 0; + + // We need to update all other column values for any column + // that does not have a selected value. + for ($tmpColNum = 1; $tmpColNum <= 3; $tmpColNum++) { + // Make sure not to update current column + if ($tmpColNum != $columnNumber) { + // if the column does not have a selected value + if ($this->col[$tmpColNum]['criteria'] == NULL) { + $tmpCategory = $this->col[$tmpColNum]['category']; + $browseValues = $this->Base->gb->browseCategory( + $tmpCategory, $tmpCriteria, $this->Base->sessid); + if (!PEAR::isError($browseValues)) { + $this->col[$tmpColNum]['values'] = $browseValues; + $this->col[$tmpColNum]['criteria'] = NULL; + $this->col[$tmpColNum]['form_value'] = '%%all%%'; + } + } + } + } $this->Base->redirUrl = UI_BROWSER.'?act='.$this->prefix; } // fn setValue @@ -211,31 +293,18 @@ class uiBrowse /** - * Clear all categories from the given column number to column 3. - * - * @param int $columnNumber + * Reload the conditions as set in the three columns. * @return void */ - private function clearHierarchy($columnNumber) - { - $this->col[$columnNumber]['form_value'] = NULL; - $columnNumber++; - for ($col = $columnNumber; $col <= 3; $col++) { - $this->col[$col]['criteria'] = NULL; - $this->col[$col]['values'] = NULL; - $this->col[$col]['form_value'] = NULL; - } - } // fn clearHierarchy - - public function setCriteria() { unset($this->criteria['conditions']); + $conditions = array(); for ($col = 3; $col >= 1; $col--) { - if (is_array($this->col[$col]['criteria'])) { - $this->criteria = array_merge($this->col[$col]['criteria'], $this->criteria); - break; + if (is_array($this->col[$col]['criteria']['conditions'])) { + $conditions[] = $this->col[$col]['criteria']['conditions']; } } + $this->criteria['conditions'] = $conditions; } // fn setCriteria @@ -247,34 +316,9 @@ class uiBrowse if (!is_array($results) || !count($results)) { return false; } - $this->results['cnt'] = $results['cnt']; - foreach ($results['results'] as $rec) { - $tmpId = BasicStor::IdFromGunid($rec["gunid"]); - $this->results['items'][] = $this->Base->getMetaInfo($tmpId); - } - - /* - ## test - for ($n=0; $n<=$this->criteria['limit']; $n++) { - $this->results['items'][] = Array - ( - 'id' => 24, - 'gunid' => '1cc472228d0cb2ac', - 'title' => 'Item '.$n, - 'creator' => 'Sebastian', - 'duration' => '   10:00', - 'type' => 'webstream' - ); - } - $results['cnt'] = 500; - $this->results['cnt'] = $results['cnt']; - ## end test - */ - + $this->results['items'] = $results['results']; $this->pagination($results); - #print_r($this->criteria); - #print_r($this->results); return TRUE; } // fn searchDB @@ -370,18 +414,31 @@ class uiBrowse } // fn setLimit - public function setFiletype($filetype) + public function setFiletype($p_filetype) { - $this->criteria['filetype'] = $filetype; + $this->criteria['filetype'] = $p_filetype; $this->criteria['offset'] = 0; for ($n = 1; $n <= 3; $n++) { - $this->col[$n]['criteria']['filetype'] = $filetype; - $this->col[$n]['values'] = $this->Base->gb->browseCategory($this->col[$n]['category'], $this->col[$n]['criteria'], $this->Base->sessid); - $this->clearHierarchy($n); + $this->col[$n]['form_value'] = '%%all%%'; + $this->col[$n]['criteria'] = null; + } + $this->setCriteria(); + $tmpCriteria = $this->criteria; + $tmpCriteria["limit"] = 1000; + + for ($n = 1; $n <= 3; $n++) { + $browseValues = $this->Base->gb->browseCategory( + $this->col[$n]['category'], + $tmpCriteria, + $this->Base->sessid); + if (!PEAR::isError($browseValues)) { + $this->col[$n]['values'] = $browseValues; + } } $this->setReload(); } // fn setFiletype + } // class uiBrowse ?> \ No newline at end of file diff --git a/campcaster/src/modules/htmlUI/var/ui_search.class.php b/campcaster/src/modules/htmlUI/var/ui_search.class.php index fa2060e1d..d56db1132 100644 --- a/campcaster/src/modules/htmlUI/var/ui_search.class.php +++ b/campcaster/src/modules/htmlUI/var/ui_search.class.php @@ -116,7 +116,6 @@ class uiSearch function newSearch(&$formdata) { - #print_r($formdata); $this->results = NULL; $this->criteria['conditions'] = NULL; $this->criteria['offset'] = NULL; @@ -170,7 +169,9 @@ class uiSearch $this->criteria['filetype'] = UI_SIMPLESEARCH_FILETYPE; $this->criteria['limit'] = UI_SIMPLESEARCH_LIMIT; $this->criteria['counter'] = UI_SIMPLESEARCH_ROWS; - $this->criteria['form']['operator'] = 'OR'; ## $criteria['form'] is used for retransfer to form ## + + // $criteria['form'] is used for retransfer to form + $this->criteria['form']['operator'] = 'OR'; $this->criteria['form']['filetype'] = UI_SIMPLESEARCH_FILETYPE; $this->criteria['form']['limit'] = UI_SIMPLESEARCH_LIMIT; diff --git a/campcaster/src/modules/storageServer/var/DataEngine.php b/campcaster/src/modules/storageServer/var/DataEngine.php index 741d563d1..b28570a58 100644 --- a/campcaster/src/modules/storageServer/var/DataEngine.php +++ b/campcaster/src/modules/storageServer/var/DataEngine.php @@ -87,39 +87,41 @@ class DataEngine { 'prefix'=>"like '%s%%'", '<'=>"< '%s'", '='=>"= '%s'", '>'=>"> '%s'", '<='=>"<= '%s'", '>='=>">= '%s'" ); - $whereArr = array(); + $whereArr = array(); if (is_array($conditions)) { foreach ($conditions as $cond) { $catQn = $cond['cat']; $op = strtolower($cond['op']); $value = strtolower($cond['val']); - $splittedQn = XML_Util::splitQualifiedName($catQn); - $catNs = $splittedQn['namespace']; - $cat = $splittedQn['localPart']; - $opVal = sprintf($ops[$op], pg_escape_string($value)); - // retype for timestamp value - if ($cat == 'mtime') { - switch ($op) { - case 'partial': - case 'prefix': - break; - default: - $retype = "::timestamp with time zone"; - $opVal = "$retype $opVal$retype"; + if (!empty($value)) { + $splittedQn = XML_Util::splitQualifiedName($catQn); + $catNs = $splittedQn['namespace']; + $cat = $splittedQn['localPart']; + $opVal = sprintf($ops[$op], pg_escape_string($value)); + // retype for timestamp value + if ($cat == 'mtime') { + switch ($op) { + case 'partial': + case 'prefix': + break; + default: + $retype = "::timestamp with time zone"; + $opVal = "$retype $opVal$retype"; + } } + // escape % for sprintf in whereArr construction: + $cat = str_replace("%", "%%", $cat); + $opVal = str_replace("%", "%%", $opVal); + $sqlCond = + " %s.predicate = '{$cat}' AND". + " %s.objns='_L' AND %s.predxml='T'". + " AND lower(%s.object) {$opVal}\n"; + if (!is_null($catNs)) { + $catNs = str_replace("%", "%%", $catNs); + $sqlCond = " %s.predns = '{$catNs}' AND $sqlCond"; + } + $whereArr[] = $sqlCond; } - // escape % for sprintf in whereArr construction: - $cat = str_replace("%", "%%", $cat); - $opVal = str_replace("%", "%%", $opVal); - $sqlCond = - " %s.predicate = '{$cat}' AND". - " %s.objns='_L' AND %s.predxml='T'". - " AND lower(%s.object) {$opVal}\n"; - if (!is_null($catNs)) { - $catNs = str_replace("%", "%%", $catNs); - $sqlCond = " %s.predns = '{$catNs}' AND $sqlCond"; - } - $whereArr[] = $sqlCond; } } return $whereArr; @@ -209,33 +211,33 @@ class DataEngine { foreach ($whereArr as $i => $v) { $whereArr[$i] = sprintf($v, "md$i", "md$i", "md$i", "md$i", "md$i"); $isectBlocks[] = - " SELECT gunid FROM ".$CC_CONFIG['mdataTable']." md$i\n". - " WHERE\n {$whereArr[$i]}"; + " SELECT gunid FROM ".$CC_CONFIG['mdataTable']." md$i \n". + " WHERE {$whereArr[$i]}"; } // query construcion: - if (count($isectBlocks)>0) { + if (count($isectBlocks) > 0) { $isectBlock = - "FROM\n(\n".join("INTERSECT\n", $isectBlocks).") sq\n". - "INNER JOIN ".$CC_CONFIG['filesTable']." f ON f.gunid = sq.gunid"; + "FROM (".join("INTERSECT\n", $isectBlocks).") sq \n". + " INNER JOIN ".$CC_CONFIG['filesTable']." f ON f.gunid = sq.gunid"; } else { - $isectBlock = "FROM ".$CC_CONFIG['filesTable']." f"; + $isectBlock = "FROM ".$CC_CONFIG['filesTable']." f \n"; } - $sql = "SELECT $fldsPart\n".$isectBlock; + $sql = "SELECT $fldsPart ".$isectBlock; if ($browse) { - $sql .= "\nINNER JOIN ".$CC_CONFIG['mdataTable']." br ON br.gunid = f.gunid\n". - "WHERE br.objns='_L' AND br.predxml='T' AND br.predicate='{$brFld}'"; + $sql .= " INNER JOIN ".$CC_CONFIG['mdataTable']." br ON br.gunid = f.gunid \n". + " WHERE br.objns='_L' AND br.predxml='T' AND br.predicate='{$brFld}'"; if (!is_null($brFldNs)) { $sql .= " AND br.predns='{$brFldNs}'"; } $glue = " AND"; } else { - $glue = "WHERE"; + $glue = " WHERE "; } if (!is_null($fileCond)) { - $sql .= "\n$glue $fileCond"; + $sql .= " $glue $fileCond"; } if ($browse) { - $sql .= "\nORDER BY br.object"; + $sql .= " ORDER BY br.object"; } return $sql; } @@ -326,10 +328,6 @@ class DataEngine { * Limit for result arrays (0 means unlimited) * @param int $offset * Starting point (0 means without offset) - * @param string $brFldNs - * Namespace prefix of category for browse - * @param string $brFld - * Metadata category identifier for browse * @return array * arrays of hashes, fields: * cnt : integer - number of matching gunids @@ -344,10 +342,11 @@ class DataEngine { * OR (in browse mode) * results: array of strings - browsed values */ - private function _localGenSearch($criteria, $limit=0, $offset=0, - $brFldNs=NULL, $brFld=NULL) + private function _localGenSearch($criteria, $limit=0, $offset=0) { global $CC_CONFIG, $CC_DBC; + + // Input values $filetype = (isset($criteria['filetype']) ? $criteria['filetype'] : 'all'); $filetype = strtolower($filetype); if (!array_key_exists($filetype, $this->filetypes)) { @@ -359,71 +358,108 @@ class DataEngine { $operator = (isset($criteria['operator']) ? $criteria['operator'] : 'and'); $operator = strtolower($operator); $conditions = (isset($criteria['conditions']) ? $criteria['conditions'] : array()); + + // Create the WHERE clause - this is the actual search part $whereArr = $this->_makeWhereArr($conditions); + + // Metadata values to fetch + $metadataNames = array('dc:creator', 'dc:source', 'ls:track_num', 'dc:title', 'dcterms:extent'); + + // Order by clause $orderby = TRUE; if ((!isset($criteria['orderby'])) || (is_array($criteria['orderby']) && (count($criteria['orderby'])==0))) { // default ORDER BY - $orderbyQns = array('dc:creator', 'dc:source', 'dc:title'); + $orderbyQns = array('dc:creator', 'dc:source', 'ls:track_num', 'dc:title'); } else { $orderbyQns = $criteria['orderby']; } if (!is_array($orderbyQns)) { $orderbyQns = array($orderbyQns); } + $descA = (isset($criteria['desc']) ? $criteria['desc'] : NULL); if (!is_array($descA)) { $descA = array($descA); } - $orderJoinSql = array(); + + // This section of code adds the metadata values to the results. + // Each metadata value is LEFT JOINED to the results, and has the + // name of its qualified name with ":" replaced with "_". + // Here we also make the ORDER BY clause. + $metadataJoinSql = array(); $orderBySql = array(); - foreach ($orderbyQns as $j => $orderbyQn) { + // $dataName contains the names of the metadata columns we want to + // fetch. It is indexed numerically starting from 1, and the value + // in the array is the qualified name with ":" replaced with "_". + // e.g. "dc:creator" becomes "dc_creator". + $dataName = array(); + foreach ($metadataNames as $j => $qname) { $i = $j + 1; - $obSplitQn = XML_Util::splitQualifiedName($orderbyQn); + $obSplitQn = XML_Util::splitQualifiedName($qname); $obNs = $obSplitQn['namespace']; $obLp = $obSplitQn['localPart']; $desc = (isset($descA[$j]) ? $descA[$j] : NULL); $retype = ($obLp == 'mtime' ? '::timestamp with time zone' : '' ); - $orderJoinSql[] = + $metadataJoinSql[] = "LEFT JOIN ".$CC_CONFIG['mdataTable']." m$i\n". " ON m$i.gunid = sq2.gunid AND m$i.predicate='$obLp'". " AND m$i.objns='_L' AND m$i.predxml='T'". (!is_null($obNs)? " AND m$i.predns='$obNs'":''); - $orderBySql[] = - "m$i.object".$retype.($desc? ' DESC':''); - } - $browse = !is_null($brFld); - if (!$browse) { - if (!$orderby) { - $fldsPart = "DISTINCT to_hex(f.gunid)as gunid, f.ftype, f.id"; - } else { - $fldsPart = "DISTINCT f.gunid, f.ftype, f.id"; + + $dataName[$qname] = str_replace(":", "_", $qname); + if (in_array($qname, $orderbyQns)) { + $orderBySql[] = $dataName[$qname].$retype.($desc? ' DESC':''); } - } else { - $fldsPart = "DISTINCT br.object as txt"; } - $limitPart = ($limit != 0 ? " LIMIT $limit" : '' ). - ($offset != 0 ? " OFFSET $offset" : '' ); + + if (!$orderby) { + $fldsPart = "DISTINCT to_hex(f.gunid)as gunid, f.ftype, f.id "; + } else { + $fldsPart = "DISTINCT f.gunid, f.ftype, f.id "; + } + $fileCond = "f.state='ready'"; if (!is_null($filetype)) { $fileCond .= " AND f.ftype='$filetype'"; } - if ($operator == 'and') { // operator: and - $sql = $this->_makeAndSql($fldsPart, $whereArr, $fileCond, $browse, $brFldNs, $brFld); - } else { // operator: or - $sql = $this->_makeOrSql($fldsPart, $whereArr, $fileCond, $browse, $brFldNs, $brFld); + if ($operator == 'and') { + $sql = $this->_makeAndSql($fldsPart, $whereArr, $fileCond, false); + } else { + $sql = $this->_makeOrSql($fldsPart, $whereArr, $fileCond, false); } - if (!$browse && $orderby) { - $sql = "SELECT to_hex(sq2.gunid)as gunid, m1.object, sq2.ftype, sq2.id\n". - "FROM (\n$sql\n)sq2\n". - join("\n", $orderJoinSql). + + // the actual values to fetch + if ($orderby) { + $tmpSql = "SELECT to_hex(sq2.gunid)as gunid, sq2.ftype, sq2.id"; + $i = 1; + foreach ($metadataNames as $qname) { + // Special case for track number because if we use text + // sorting of this value, then 10 comes right after 1. + // So we convert track number to an integer for ordering. + if ($qname == "ls:track_num") { + $tmpSql .= ", CAST(m$i.object as integer) as ls_track_num"; + } else { + $tmpSql .= ", m$i.object as ".$dataName[$qname]; + } + $i++; + } + + $tmpSql .= "\nFROM (\n$sql\n)sq2\n". + join("\n", $metadataJoinSql). "ORDER BY ".join(",", $orderBySql)."\n"; + $sql = $tmpSql; } - // echo "\n---\n$sql\n---\n"; + + // Get the number of results $cnt = $this->_getNumRows($sql); if (PEAR::isError($cnt)) { return $cnt; } + + // Get actual results + $limitPart = ($limit != 0 ? " LIMIT $limit" : '' ). + ($offset != 0 ? " OFFSET $offset" : '' ); $res = $CC_DBC->getAll($sql.$limitPart); if (PEAR::isError($res)) { return $res; @@ -432,26 +468,19 @@ class DataEngine { $res = array(); } $eres = array(); - // echo "\n---\n"; var_dump($res); echo"\n---\n"; - //$categoryNames = array('dc:title', 'dc:creator', 'dc:source', 'dcterms:extent'); foreach ($res as $it) { - if (!$browse) { - $gunid = StoredFile::NormalizeGunid($it['gunid']); - //$values = $this->gb->bsGetMetadataValue($it['id'], $categoryNames); - $values = $this->gb->bsGetMetadataValue($it['id']); - $eres[] = array( - 'id' => $it['id'], - 'gunid' => $gunid, - 'type' => $it['ftype'], - 'title' => $values['dc:title']["object"], - 'creator' => (isset($values['dc:creator']) ? $values['dc:creator']["object"] : NULL ), - 'duration' => $values['dcterms:extent']["object"], - 'length' => $values['dcterms:extent']["object"], - 'source' => (isset($values['dc:source']) ? $values['dc:source']["object"] : NULL ), - ); - } else { - $eres[] = $it['txt']; - } + $gunid = StoredFile::NormalizeGunid($it['gunid']); + $eres[] = array( + 'id' => $it['id'], + 'gunid' => $gunid, + 'type' => strtolower($it['ftype']), + 'title' => $it['dc_title'], + 'creator' => $it['dc_creator'], + 'duration' => $it['dcterms_extent'], + 'length' => $it['dcterms_extent'], + 'source' => $it['dc_source'], + 'track_num' => $it['ls_track_num'], + ); } return array('results'=>$eres, 'cnt'=>$cnt); } @@ -461,7 +490,8 @@ class DataEngine { * Return values of specified metadata category * * @param string $category - * metadata category name, with or without namespace prefix (dc:title, author) + * metadata category name, with or without namespace prefix + * (dc:title, author) * @param int $limit * limit for result arrays (0 means unlimited) * @param int $offset @@ -480,7 +510,7 @@ class DataEngine { $catNs = $r['namespace']; $cat = $r['localPart']; if (is_array($criteria) && count($criteria) > 0) { - return $this->_localGenSearch($criteria, $limit, $offset, $catNs, $cat); + return $this->_browseCategory($criteria, $limit, $offset, $catNs, $cat); } $sqlCond = "m.predicate='$cat' AND m.objns='_L' AND m.predxml='T'"; if (!is_null($catNs)) { @@ -491,7 +521,6 @@ class DataEngine { $sql = "SELECT DISTINCT m.object FROM ".$CC_CONFIG['mdataTable']." m\n". "WHERE $sqlCond"; - // echo "\n---\n$sql\n---\n"; $cnt = $this->_getNumRows($sql); if (PEAR::isError($cnt)) { return $cnt; @@ -507,6 +536,74 @@ class DataEngine { } + /** + * Fetching the list of metadata values for a particular category. + * + * @param array $criteria + * @param int $limit + * @param int $offset + * @param string $brFldNs + * Namespace prefix of category for browse + * @param string $brFld + * Metadata category identifier for browse. + * @return array|PEAR_Error + */ + private function _browseCategory($criteria, $limit=0, $offset=0, + $brFldNs=NULL, $brFld=NULL) + { + global $CC_CONFIG, $CC_DBC; + + // Input values + $filetype = (isset($criteria['filetype']) ? $criteria['filetype'] : 'all'); + $filetype = strtolower($filetype); + if (!array_key_exists($filetype, $this->filetypes)) { + return PEAR::raiseError( + 'DataEngine::_browseCategory: unknown filetype in search criteria' + ); + } + $filetype = $this->filetypes[$filetype]; + $operator = (isset($criteria['operator']) ? $criteria['operator'] : 'and'); + $operator = strtolower($operator); + $conditions = (isset($criteria['conditions']) ? $criteria['conditions'] : array()); + + // Create the WHERE clause - this is the actual search part + $whereArr = $this->_makeWhereArr($conditions); + + $fldsPart = "DISTINCT br.object as txt"; + $fileCond = "f.state='ready'"; + if (!is_null($filetype)) { + $fileCond .= " AND f.ftype='$filetype'"; + } + if ($operator == 'and') { + $sql = $this->_makeAndSql($fldsPart, $whereArr, $fileCond, true, $brFldNs, $brFld); + } else { + $sql = $this->_makeOrSql($fldsPart, $whereArr, $fileCond, true, $brFldNs, $brFld); + } + + // Get the number of results + $cnt = $this->_getNumRows($sql); + if (PEAR::isError($cnt)) { + return $cnt; + } + + // Get actual results + $limitPart = ($limit != 0 ? " LIMIT $limit" : '' ). + ($offset != 0 ? " OFFSET $offset" : '' ); + $res = $CC_DBC->getAll($sql.$limitPart); + if (PEAR::isError($res)) { + return $res; + } + if (!is_array($res)) { + $res = array(); + } + $eres = array(); + foreach ($res as $it) { + $eres[] = $it['txt']; + } + return array('results'=>$eres, 'cnt'=>$cnt); + } + + /** * Get number of rows in query result * diff --git a/campcaster/src/modules/storageServer/var/GreenBox.php b/campcaster/src/modules/storageServer/var/GreenBox.php index 9363e0c43..4f97660cb 100644 --- a/campcaster/src/modules/storageServer/var/GreenBox.php +++ b/campcaster/src/modules/storageServer/var/GreenBox.php @@ -511,7 +511,7 @@ class GreenBox extends BasicStor { * cnt : integer - number of matching values * @see BasicStor::bsBrowseCategory */ - public function browseCategory($category, $criteria, $sessid = '') + public function browseCategory($category, $criteria = null, $sessid = '') { $limit = 0; $offset = 0;