1
0
Fork 0
mirror of https://github.com/Yetangitu/ampache synced 2025-10-04 10:19:25 +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'),
'sql' => '>'
);
$this->basetypes['multiple'] = array_merge($this->basetypes['text'], $this->basetypes['numeric']);
switch ($searchtype) {
case 'song':
@ -386,6 +387,19 @@ class Search extends playlist_object
'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();
foreach (License::get_licenses() as $license_id) {
$license = new License($license_id);
@ -399,18 +413,7 @@ class Search extends playlist_object
'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;
case 'album':
$this->types[] = array(
@ -751,7 +754,8 @@ class Search extends playlist_object
$this->rules[] = array(
$value,
$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) {
$js .= '<script type="text/javascript">' .
'SearchRow.add("' . $rule[0] . '","' .
$rule[1] . '","' . $rule[2] . '"); </script>';
$rule[1] . '","' . $rule[2] . '", "' . $rule[3] . '"); </script>';
}
return $js;
}
@ -1179,18 +1183,20 @@ class Search extends playlist_object
case 'updated':
$input = strtotime($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:
// NOSSINK!
break;
} // 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
$join['catalog'] = AmpConfig::get('catalog_disable');

View file

@ -21,7 +21,7 @@ var rowIter = 1;
var rowCount = 0;
var SearchRow = {
add: function(ruleType, operator, input) {
add: function (ruleType, operator, input, subtype) {
if (typeof(ruleType) != 'string') {
ruleType = 0;
}
@ -56,6 +56,10 @@ var SearchRow = {
}
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[2].appendChild(SearchRow.constructInput(ruleType, rowIter, input));
cells[3].innerHTML = removeIcon;
@ -104,6 +108,13 @@ var SearchRow = {
inputNode.appendChild(option);
});
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;
@ -159,8 +170,26 @@ var SearchRow = {
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') {
var oldinput = input.value;
}
@ -168,5 +197,28 @@ var SearchRow = {
var input_cell = input.parent();
input.remove();
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];
}
}
};