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:
parent
af03777cc8
commit
7ee67d721e
2 changed files with 90 additions and 32 deletions
|
@ -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');
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue