1
0
Fork 0
mirror of https://github.com/Yetangitu/ampache synced 2025-10-04 18:29:40 +02:00

[FEATURE] #280 Add possibility to search for metadata

This commit is contained in:
René Bigler 2015-01-10 00:19:45 +01:00
parent af03777cc8
commit 7ee67d721e
2 changed files with 90 additions and 32 deletions

View file

@ -193,6 +193,7 @@ class Search extends playlist_object
'description' => T_('after'), 'description' => T_('after'),
'sql' => '>' 'sql' => '>'
); );
$this->basetypes['multiple'] = array_merge($this->basetypes['text'], $this->basetypes['numeric']);
switch ($searchtype) { switch ($searchtype) {
case 'song': case 'song':
@ -362,7 +363,7 @@ class Search extends playlist_object
$this->types[] = array( $this->types[] = array(
'name' => 'playlist', 'name' => 'playlist',
'label' => T_('Playlist'), 'label' => T_('Playlist'),
'type' => 'boolean_numeric', 'type' => 'boolean_numeric',
'widget' => array('select', $playlists) 'widget' => array('select', $playlists)
); );
@ -386,6 +387,19 @@ class Search extends playlist_object
'widget' => array('select', $playlists) 'widget' => array('select', $playlists)
); );
$metadataFields = array();
$metadataFieldRepository = new \lib\Metadata\Repository\MetadataField();
foreach ($metadataFieldRepository->findAll() as $metadata) {
$metadataFields[$metadata->getId()] = $metadata->getName();
}
$this->types[] = array(
'name' => 'metadata',
'label' => T_('Metadata'),
'type' => 'multiple',
'subtypes' => $metadataFields,
'widget' => array('subtypes', array('input', 'text'))
);
$licenses = array(); $licenses = array();
foreach (License::get_licenses() as $license_id) { foreach (License::get_licenses() as $license_id) {
$license = new License($license_id); $license = new License($license_id);
@ -399,18 +413,7 @@ class Search extends playlist_object
'widget' => array('select', $licenses) 'widget' => array('select', $licenses)
); );
} }
$metadataFieldRepository = new \lib\Metadata\Repository\MetadataField();
foreach($metadataFieldRepository->findAll() as $field) {
/* @var $field \lib\Metadata\Model\MetadataField */
if($field->isPublic()) {
$this->types[] = array(
'name' => 'metadata[' . $field->getId() . ']',
'label' => $field->getName(),
'type' => 'text',
'widget' => array('input', 'text')
);
}
}
break; break;
case 'album': case 'album':
$this->types[] = array( $this->types[] = array(
@ -751,7 +754,8 @@ class Search extends playlist_object
$this->rules[] = array( $this->rules[] = array(
$value, $value,
$this->basetypes[$this->name_to_basetype($value)][$data['rule_' . $ruleID . '_operator']]['name'], $this->basetypes[$this->name_to_basetype($value)][$data['rule_' . $ruleID . '_operator']]['name'],
$input $input,
$data['rule_' . $ruleID . '_subtype']
); );
} }
} }
@ -795,7 +799,7 @@ class Search extends playlist_object
foreach ($this->rules as $rule) { foreach ($this->rules as $rule) {
$js .= '<script type="text/javascript">' . $js .= '<script type="text/javascript">' .
'SearchRow.add("' . $rule[0] . '","' . 'SearchRow.add("' . $rule[0] . '","' .
$rule[1] . '","' . $rule[2] . '"); </script>'; $rule[1] . '","' . $rule[2] . '", "' . $rule[3] . '"); </script>';
} }
return $js; return $js;
} }
@ -1179,18 +1183,20 @@ class Search extends playlist_object
case 'updated': case 'updated':
$input = strtotime($input); $input = strtotime($input);
$where[] = "`song`.`update_time` $sql_match_operator $input"; $where[] = "`song`.`update_time` $sql_match_operator $input";
break;
case 'metadata':
// Need to create a join for every field so we can create and / or queries with only one table
$tableAlias = 'metadata' . uniqid();
$field = (int) $rule[3];
$join[$tableAlias] = true;
$parsedInput = is_numeric($input) ? $input : '"' . $input . '"';
$where[] = "(`$tableAlias`.`field` = {$field} AND `$tableAlias`.`data` $sql_match_operator $parsedInput)";
$table[$tableAlias] = 'LEFT JOIN `metadata` AS ' . $tableAlias . ' ON `song`.`id` = `' . $tableAlias . '`.`object_id`';
break;
default: default:
// NOSSINK! // NOSSINK!
break; break;
} // switch on type } // switch on type
if(preg_match('/metadata\[(\d+?)\]/', $rule[0], $matches)) {
// Need to create a join for every field so we can create and / or queries with only one table
$tableAlias = 'metadata' . $matches[1];
$join[$tableAlias] = true;
$where[] = "`$tableAlias`.`field` = {$matches[1]} AND `$tableAlias`.`data` $sql_match_operator '$input'";
$table[$tableAlias] = 'LEFT JOIN `metadata` AS ' . $tableAlias . ' ON `song`.`id` = `' . $tableAlias . '`.`object_id`';
}
} // foreach over rules } // foreach over rules
$join['catalog'] = AmpConfig::get('catalog_disable'); $join['catalog'] = AmpConfig::get('catalog_disable');

View file

@ -21,7 +21,7 @@ var rowIter = 1;
var rowCount = 0; var rowCount = 0;
var SearchRow = { var SearchRow = {
add: function(ruleType, operator, input) { add: function (ruleType, operator, input, subtype) {
if (typeof(ruleType) != 'string') { if (typeof(ruleType) != 'string') {
ruleType = 0; ruleType = 0;
} }
@ -56,6 +56,10 @@ var SearchRow = {
} }
cells[0].appendChild(SearchRow.constructOptions(ruleType, rowIter)); cells[0].appendChild(SearchRow.constructOptions(ruleType, rowIter));
var select = SearchRow.createSubtypeOptions(ruleType, rowIter, subtype);
if (select) {
cells[0].appendChild(select);
}
cells[1].appendChild(SearchRow.constructOperators(ruleType, rowIter, operator)); cells[1].appendChild(SearchRow.constructOperators(ruleType, rowIter, operator));
cells[2].appendChild(SearchRow.constructInput(ruleType, rowIter, input)); cells[2].appendChild(SearchRow.constructInput(ruleType, rowIter, input));
cells[3].innerHTML = removeIcon; cells[3].innerHTML = removeIcon;
@ -86,7 +90,7 @@ var SearchRow = {
case 'input': case 'input':
inputNode.setAttribute('type', widget['1']); inputNode.setAttribute('type', widget['1']);
inputNode.setAttribute('value', input); inputNode.setAttribute('value', input);
break; break;
case 'select': case 'select':
jQuery.each(widget['1'], function(i) { jQuery.each(widget['1'], function(i) {
var option = document.createElement('option'); var option = document.createElement('option');
@ -103,7 +107,14 @@ var SearchRow = {
option.innerHTML = widget['1'][i]; option.innerHTML = widget['1'][i];
inputNode.appendChild(option); inputNode.appendChild(option);
}); });
break; break;
case 'subtypes':
inputNode = document.createElement(widget[1][0]);
inputNode.id = 'rule_' + ruleNumber + '_input';
inputNode.name = 'rule_' + ruleNumber + '_input';
inputNode.setAttribute('type', widget[1][1]);
inputNode.setAttribute('value', input);
break;
} }
return inputNode; return inputNode;
@ -159,8 +170,26 @@ var SearchRow = {
operator_cell.append(SearchRow.constructOperators(this.selectedIndex, targetID)); operator_cell.append(SearchRow.constructOperators(this.selectedIndex, targetID));
} }
var input = $('#rule_' + targetID + '_input'); var type = $(this).val();
jQuery.each(types, function (index, value) {
if (value.name == type) {
type = value
return false;
}
});
if (type['widget'][0] == 'subtypes') {
var $select = SearchRow.createSelect({
name: 'rule_' + targetID + '_subtype'
}, type['subtypes']);
$(this).after($select);
}
else {
$(this).closest('tr').find('select[name="subtype"]').remove();
}
var input = $('#rule_' + targetID + '_input');
if (input.type == 'text') { if (input.type == 'text') {
var oldinput = input.value; var oldinput = input.value;
} }
@ -168,5 +197,28 @@ var SearchRow = {
var input_cell = input.parent(); var input_cell = input.parent();
input.remove(); input.remove();
input_cell.append(SearchRow.constructInput(this.selectedIndex, targetID, oldinput)); input_cell.append(SearchRow.constructInput(this.selectedIndex, targetID, oldinput));
} },
createSelect: function (attributes, options, selected) {
var $select = $('<select>');
$.each(attributes, function (key, value) {
$select.attr(key, value);
});
$.each(options, function (key, value) {
$('<option>').attr('value', key).text(value).appendTo($select);
});
$select.val(selected);
return $select;
},
createSubtypeOptions: function (ruleType, ruleNumber, subtype) {
var type = types[ruleType];
var input;
if (type['widget'][0] == 'subtypes') {
var $input = SearchRow.createSelect({
name: 'rule_' + ruleNumber + '_subtype'
}, type['subtypes'], subtype);
return $input[0];
}
}
}; };