mirror of
https://github.com/Piwigo/Piwigo.git
synced 2026-07-20 00:23:40 +02:00
bug 3069: add quick search as filter in batch manager
git-svn-id: http://piwigo.org/svn/trunk@28087 68402e56-0260-453c-a942-63ccdbb3a9ee
This commit is contained in:
+31
-19
@@ -85,14 +85,14 @@ if (isset($_POST['submitFilter']))
|
||||
if (in_array($_POST['filter_level'], $conf['available_permission_levels']))
|
||||
{
|
||||
$_SESSION['bulk_manager_filter']['level'] = $_POST['filter_level'];
|
||||
|
||||
|
||||
if (isset($_POST['filter_level_include_lower']))
|
||||
{
|
||||
$_SESSION['bulk_manager_filter']['level_include_lower'] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (isset($_POST['filter_dimension_use']))
|
||||
{
|
||||
foreach (array('min_width','max_width','min_height','max_height') as $type)
|
||||
@@ -110,34 +110,39 @@ if (isset($_POST['submitFilter']))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_POST['filter_search_use']))
|
||||
{
|
||||
$_SESSION['bulk_manager_filter']['search']['q'] = $_POST['q'];
|
||||
}
|
||||
}
|
||||
// filters from url
|
||||
else if (isset($_GET['filter']))
|
||||
elseif (isset($_GET['filter']))
|
||||
{
|
||||
if (!is_array($_GET['filter']))
|
||||
{
|
||||
$_GET['filter'] = explode(',', $_GET['filter']);
|
||||
}
|
||||
|
||||
|
||||
$_SESSION['bulk_manager_filter'] = array();
|
||||
|
||||
|
||||
foreach ($_GET['filter'] as $filter)
|
||||
{
|
||||
list($type, $value) = explode('-', $filter);
|
||||
|
||||
|
||||
switch ($type)
|
||||
{
|
||||
case 'prefilter':
|
||||
$_SESSION['bulk_manager_filter']['prefilter'] = $value;
|
||||
break;
|
||||
|
||||
|
||||
case 'album':
|
||||
if (is_numeric($value))
|
||||
{
|
||||
$_SESSION['bulk_manager_filter']['category'] = $value;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 'tag':
|
||||
if (is_numeric($value))
|
||||
{
|
||||
@@ -145,7 +150,7 @@ else if (isset($_GET['filter']))
|
||||
$_SESSION['bulk_manager_filter']['tag_mode'] = 'AND';
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 'level':
|
||||
if (is_numeric($value) && in_array($value, $conf['available_permission_levels']))
|
||||
{
|
||||
@@ -178,7 +183,7 @@ SELECT element_id
|
||||
WHERE user_id = '.$user['id'].'
|
||||
;';
|
||||
$filter_sets[] = array_from_query($query, 'element_id');
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case 'favorites':
|
||||
@@ -188,7 +193,7 @@ SELECT image_id
|
||||
WHERE user_id = '.$user['id'].'
|
||||
;';
|
||||
$filter_sets[] = array_from_query($query, 'image_id');
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case 'last_import':
|
||||
@@ -206,7 +211,7 @@ SELECT id
|
||||
;';
|
||||
$filter_sets[] = array_from_query($query, 'id');
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case 'no_virtual_album':
|
||||
@@ -234,7 +239,7 @@ SELECT id
|
||||
}
|
||||
|
||||
$filter_sets[] = array_diff($all_elements, $linked_to_virtual);
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case 'no_album':
|
||||
@@ -246,7 +251,7 @@ SELECT
|
||||
WHERE category_id is null
|
||||
;';
|
||||
$filter_sets[] = array_from_query($query, 'id');
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case 'no_tag':
|
||||
@@ -258,7 +263,7 @@ SELECT
|
||||
WHERE tag_id is null
|
||||
;';
|
||||
$filter_sets[] = array_from_query($query, 'id');
|
||||
|
||||
|
||||
break;
|
||||
|
||||
|
||||
@@ -280,7 +285,7 @@ SELECT id
|
||||
WHERE file IN (\''.implode("','", array_map('pwg_db_real_escape_string', $duplicate_files)).'\')
|
||||
;';
|
||||
$filter_sets[] = array_from_query($query, 'id');
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case 'all_photos':
|
||||
@@ -290,7 +295,7 @@ SELECT id
|
||||
'.$conf['order_by'];
|
||||
|
||||
$filter_sets[] = array_from_query($query, 'id');
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -325,7 +330,7 @@ if (isset($_SESSION['bulk_manager_filter']['level']))
|
||||
{
|
||||
$operator = '<=';
|
||||
}
|
||||
|
||||
|
||||
$query = '
|
||||
SELECT id
|
||||
FROM '.IMAGES_TABLE.'
|
||||
@@ -374,7 +379,7 @@ if (isset($_SESSION['bulk_manager_filter']['dimension']))
|
||||
// max_ratio is a floor value, so must be a bit increased
|
||||
$where_clause[] = 'width/height < '.($_SESSION['bulk_manager_filter']['dimension']['max_ratio']+0.01);
|
||||
}
|
||||
|
||||
|
||||
$query = '
|
||||
SELECT id
|
||||
FROM '.IMAGES_TABLE.'
|
||||
@@ -384,6 +389,13 @@ SELECT id
|
||||
$filter_sets[] = array_from_query($query, 'id');
|
||||
}
|
||||
|
||||
if (isset($_SESSION['bulk_manager_filter']['search']))
|
||||
{
|
||||
include_once( PHPWG_ROOT_PATH .'include/functions_search.inc.php' );
|
||||
$res = get_quick_search_results($_SESSION['bulk_manager_filter']['search']['q'], array('permissions'=>false));
|
||||
$filter_sets[] = $res['items'];
|
||||
}
|
||||
|
||||
$current_set = array_shift($filter_sets);
|
||||
foreach ($filter_sets as $set)
|
||||
{
|
||||
|
||||
@@ -86,7 +86,7 @@ if (isset($_POST['submit']))
|
||||
}
|
||||
|
||||
$action = $_POST['selectAction'];
|
||||
|
||||
|
||||
if ('remove_from_caddie' == $action)
|
||||
{
|
||||
$query = '
|
||||
@@ -147,7 +147,7 @@ DELETE
|
||||
$_SESSION['page_infos'] = array(
|
||||
l10n('Information data registered in database')
|
||||
);
|
||||
|
||||
|
||||
// let's refresh the page because we the current set might be modified
|
||||
if ('no_album' == $page['prefilter'])
|
||||
{
|
||||
@@ -171,7 +171,7 @@ DELETE
|
||||
$_SESSION['page_infos'] = array(
|
||||
l10n('Information data registered in database')
|
||||
);
|
||||
|
||||
|
||||
// let's refresh the page because we the current set might be modified
|
||||
if ('no_album' == $page['prefilter'])
|
||||
{
|
||||
@@ -224,7 +224,7 @@ DELETE
|
||||
$_SESSION['page_infos'] = array(
|
||||
l10n('Information data registered in database')
|
||||
);
|
||||
|
||||
|
||||
// let's refresh the page because the current set might be modified
|
||||
redirect($redirect_url);
|
||||
}
|
||||
@@ -237,7 +237,7 @@ DELETE
|
||||
{
|
||||
$_POST['author'] = null;
|
||||
}
|
||||
|
||||
|
||||
$datas = array();
|
||||
foreach ($collection as $image_id)
|
||||
{
|
||||
@@ -261,7 +261,7 @@ DELETE
|
||||
{
|
||||
$_POST['title'] = null;
|
||||
}
|
||||
|
||||
|
||||
$datas = array();
|
||||
foreach ($collection as $image_id)
|
||||
{
|
||||
@@ -277,7 +277,7 @@ DELETE
|
||||
$datas
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// date_creation
|
||||
if ('date_creation' == $action)
|
||||
{
|
||||
@@ -308,7 +308,7 @@ DELETE
|
||||
$datas
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// privacy_level
|
||||
if ('level' == $action)
|
||||
{
|
||||
@@ -335,13 +335,13 @@ DELETE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// add_to_caddie
|
||||
if ('add_to_caddie' == $action)
|
||||
{
|
||||
fill_caddie($collection);
|
||||
}
|
||||
|
||||
|
||||
// delete
|
||||
if ('delete' == $action)
|
||||
{
|
||||
@@ -664,11 +664,11 @@ if (count($page['cat_elements_id']) > 0)
|
||||
$query = '
|
||||
SELECT id,path,representative_ext,file,filesize,level,name,width,height,rotation
|
||||
FROM '.IMAGES_TABLE;
|
||||
|
||||
|
||||
if ($is_category)
|
||||
{
|
||||
$category_info = get_cat_info($_SESSION['bulk_manager_filter']['category']);
|
||||
|
||||
|
||||
$conf['order_by'] = $conf['order_by_inside_category'];
|
||||
if (!empty($category_info['image_order']))
|
||||
{
|
||||
|
||||
@@ -665,6 +665,15 @@ $(document).ready(function() {
|
||||
<input type="hidden" name="filter_dimension_min_ratio" value="{$dimensions.selected.min_ratio}">
|
||||
<input type="hidden" name="filter_dimension_max_ratio" value="{$dimensions.selected.max_ratio}">
|
||||
</li>
|
||||
|
||||
<li id="filter_search"{if !isset($filter.search)} style="display:none"{/if}>
|
||||
<a href="#" class="removeFilter" title="remove this filter"><span>[x]</span></a>
|
||||
<input type="checkbox" name="filter_search_use" class="useFilterCheckbox"{if isset($filter.search)} checked="checked"{/if}>
|
||||
{'Search'|@translate}
|
||||
<input name="q" size=40 value="{$filter.search.q|stripslashes|htmlspecialchars}">
|
||||
{combine_script id='core.scripts' load='async' path='themes/default/js/scripts.js'}
|
||||
<a href="admin/popuphelp.php?page=quick_search"onclick="popuphelp(this.href);return false;" title="{'Help'|@translate}"><span class="icon-help-circled"></span></a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p class="actionButtons">
|
||||
@@ -676,6 +685,7 @@ $(document).ready(function() {
|
||||
<option value="filter_tags" {if isset($filter.tags)}disabled="disabled"{/if}>{'Tags'|@translate}</option>
|
||||
<option value="filter_level" {if isset($filter.level)}disabled="disabled"{/if}>{'Privacy level'|@translate}</option>
|
||||
<option value="filter_dimension" {if isset($filter.dimension)}disabled="disabled"{/if}>{'Dimensions'|@translate}</option>
|
||||
<option value="filter_search"{if isset($filter.search)} disabled="disabled"{/if}>{'Search'|@translate}</option>
|
||||
</select>
|
||||
<a id="removeFilters" href="">{'Remove all filters'|@translate}</a>
|
||||
</p>
|
||||
|
||||
@@ -1193,7 +1193,7 @@ function qsearch_eval(QMultiToken $expr, QResults $qsr, &$qualifies, &$ignored_t
|
||||
* @param string $images_where optional additional restriction on images table
|
||||
* @return array
|
||||
*/
|
||||
function get_quick_search_results($q, $super_order_by, $images_where='')
|
||||
function get_quick_search_results($q, $options)
|
||||
{
|
||||
global $conf;
|
||||
//@TODO: maybe cache for 10 minutes the result set to avoid many expensive sql calls when navigating the pictures
|
||||
@@ -1254,26 +1254,35 @@ function get_quick_search_results($q, $super_order_by, $images_where='')
|
||||
return $search_results;
|
||||
}
|
||||
|
||||
$permissions = !isset($options['permissions']) ? true : $options['permissions'];
|
||||
|
||||
$where_clauses = array();
|
||||
$where_clauses[]='i.id IN ('. implode(',', $ids) . ')';
|
||||
if (!empty($images_where))
|
||||
if (!empty($options['images_where'))
|
||||
{
|
||||
$where_clauses[]='('.$images_where.')';
|
||||
}
|
||||
$where_clauses[] = get_sql_condition_FandF(
|
||||
array
|
||||
(
|
||||
'forbidden_categories' => 'category_id',
|
||||
'visible_categories' => 'category_id',
|
||||
'visible_images' => 'i.id'
|
||||
),
|
||||
null,true
|
||||
);
|
||||
if ($permissions)
|
||||
{
|
||||
$where_clauses[] = get_sql_condition_FandF(
|
||||
array
|
||||
(
|
||||
'forbidden_categories' => 'category_id',
|
||||
'visible_categories' => 'category_id',
|
||||
'visible_images' => 'i.id'
|
||||
),
|
||||
null,true
|
||||
);
|
||||
}
|
||||
|
||||
$query = '
|
||||
SELECT DISTINCT(id)
|
||||
FROM '.IMAGES_TABLE.' i
|
||||
INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON id = ic.image_id
|
||||
SELECT DISTINCT(id) FROM '.IMAGES_TABLE.' i';
|
||||
if ($permissions)
|
||||
{
|
||||
$query .= '
|
||||
INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON id = ic.image_id';
|
||||
}
|
||||
$query .= '
|
||||
WHERE '.implode("\n AND ", $where_clauses)."\n".
|
||||
$conf['order_by'];
|
||||
|
||||
@@ -1305,7 +1314,7 @@ function get_search_results($search_id, $super_order_by, $images_where='')
|
||||
}
|
||||
else
|
||||
{
|
||||
return get_quick_search_results($search['q'], $super_order_by, $images_where);
|
||||
return get_quick_search_results($search['q'], array('super_order_by'=>$super_order_by, 'images_where'=>$images_where) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -294,7 +294,7 @@ function remove_chunks($original_sum, $type)
|
||||
* @option string content
|
||||
* @option string key
|
||||
*/
|
||||
function ws_images_addComment($params, &$service)
|
||||
function ws_images_addComment($params, $service)
|
||||
{
|
||||
$query = '
|
||||
SELECT DISTINCT image_id
|
||||
@@ -354,7 +354,7 @@ SELECT DISTINCT image_id
|
||||
* @option int comments_page
|
||||
* @option int comments_per_page
|
||||
*/
|
||||
function ws_images_getInfo($params, &$service)
|
||||
function ws_images_getInfo($params, $service)
|
||||
{
|
||||
global $user, $conf;
|
||||
|
||||
@@ -579,7 +579,7 @@ SELECT id, date, author, content
|
||||
* @option int image_id
|
||||
* @option float rate
|
||||
*/
|
||||
function ws_images_rate($params, &$service)
|
||||
function ws_images_rate($params, $service)
|
||||
{
|
||||
$query = '
|
||||
SELECT DISTINCT id
|
||||
@@ -620,7 +620,7 @@ SELECT DISTINCT id
|
||||
* @option int page
|
||||
* @option string order (optional)
|
||||
*/
|
||||
function ws_images_search($params, &$service)
|
||||
function ws_images_search($params, $service)
|
||||
{
|
||||
include_once(PHPWG_ROOT_PATH .'include/functions_search.inc.php');
|
||||
|
||||
@@ -638,8 +638,10 @@ function ws_images_search($params, &$service)
|
||||
|
||||
$search_result = get_quick_search_results(
|
||||
$params['query'],
|
||||
$super_order_by,
|
||||
implode(' AND ', $where_clauses)
|
||||
array(
|
||||
'super_order_by' => $super_order_by,
|
||||
'images_where' => implode(' AND ', $where_clauses)
|
||||
)
|
||||
);
|
||||
|
||||
$image_ids = array_slice(
|
||||
@@ -704,7 +706,7 @@ SELECT *
|
||||
* @option int image_id
|
||||
* @option int level
|
||||
*/
|
||||
function ws_images_setPrivacyLevel($params, &$service)
|
||||
function ws_images_setPrivacyLevel($params, $service)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
@@ -737,7 +739,7 @@ UPDATE '. IMAGES_TABLE .'
|
||||
* @option int category_id
|
||||
* @option int rank
|
||||
*/
|
||||
function ws_images_setRank($params, &$service)
|
||||
function ws_images_setRank($params, $service)
|
||||
{
|
||||
// does the image really exist?
|
||||
$query = '
|
||||
@@ -820,7 +822,7 @@ UPDATE '. IMAGE_CATEGORY_TABLE .'
|
||||
* @option string type = 'file'
|
||||
* @option int position
|
||||
*/
|
||||
function ws_images_add_chunk($params, &$service)
|
||||
function ws_images_add_chunk($params, $service)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
@@ -877,7 +879,7 @@ function ws_images_add_chunk($params, &$service)
|
||||
* @option string type = 'file'
|
||||
* @option string sum
|
||||
*/
|
||||
function ws_images_addFile($params, &$service)
|
||||
function ws_images_addFile($params, $service)
|
||||
{
|
||||
ws_logfile(__FUNCTION__.', input : '.var_export($params, true));
|
||||
|
||||
@@ -970,7 +972,7 @@ SELECT
|
||||
* @option bool check_uniqueness
|
||||
* @option int image_id (optional)
|
||||
*/
|
||||
function ws_images_add($params, &$service)
|
||||
function ws_images_add($params, $service)
|
||||
{
|
||||
global $conf, $user;
|
||||
|
||||
@@ -1133,7 +1135,7 @@ SELECT id, name, permalink
|
||||
* @option string|string[] tags
|
||||
* @option int image_id (optional)
|
||||
*/
|
||||
function ws_images_addSimple($params, &$service)
|
||||
function ws_images_addSimple($params, $service)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
@@ -1247,7 +1249,7 @@ SELECT id, name, permalink
|
||||
* @option string md5sum_list (optional)
|
||||
* @option string filename_list (optional)
|
||||
*/
|
||||
function ws_images_exist($params, &$service)
|
||||
function ws_images_exist($params, $service)
|
||||
{
|
||||
ws_logfile(__FUNCTION__.' '.var_export($params, true));
|
||||
|
||||
@@ -1320,7 +1322,7 @@ SELECT id, file
|
||||
* @option int image_id
|
||||
* @option string file_sum
|
||||
*/
|
||||
function ws_images_checkFiles($params, &$service)
|
||||
function ws_images_checkFiles($params, $service)
|
||||
{
|
||||
ws_logfile(__FUNCTION__.', input : '.var_export($params, true));
|
||||
|
||||
@@ -1392,7 +1394,7 @@ SELECT path
|
||||
* @option string single_value_mode
|
||||
* @option string multiple_value_mode
|
||||
*/
|
||||
function ws_images_setInfo($params, &$service)
|
||||
function ws_images_setInfo($params, $service)
|
||||
{
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
|
||||
|
||||
@@ -1528,7 +1530,7 @@ SELECT *
|
||||
* @option int|int[] image_id
|
||||
* @option string pwg_token
|
||||
*/
|
||||
function ws_images_delete($params, &$service)
|
||||
function ws_images_delete($params, $service)
|
||||
{
|
||||
if (get_pwg_token() != $params['pwg_token'])
|
||||
{
|
||||
@@ -1565,7 +1567,7 @@ function ws_images_delete($params, &$service)
|
||||
* Checks if Piwigo is ready for upload
|
||||
* @param mixed[] $params
|
||||
*/
|
||||
function ws_images_checkUpload($params, &$service)
|
||||
function ws_images_checkUpload($params, $service)
|
||||
{
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/functions_upload.inc.php');
|
||||
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
<h2>Search</h2>
|
||||
<style>
|
||||
q {
|
||||
font-family: Courier, Fixed;
|
||||
font-weight: bold;
|
||||
}
|
||||
q:before {
|
||||
content: '\'';
|
||||
color: green;
|
||||
}
|
||||
q:after {
|
||||
content: '\'';
|
||||
color: green;
|
||||
}
|
||||
TD {
|
||||
border: 1px solid
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<p>By default all searched terms must match. Searches are case-insesitive.</p>
|
||||
|
||||
<table style="border-collapse:collapse;text-align:left">
|
||||
<tr>
|
||||
<td>quoted phrase<br>
|
||||
<q>"search"</q>
|
||||
</td>
|
||||
<td>Use quotes to search for an exact word or phrase.<br>
|
||||
<q>"george washington"</q></td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td>either term<br>
|
||||
<q>OR search</q><br>
|
||||
</td>
|
||||
<td>Add a OR between words.<br>
|
||||
<q>john OR bill</q></td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td>exclude<br>
|
||||
<q>NOT search</q><br>
|
||||
<q>-search</q>
|
||||
</td>
|
||||
<td>Add a dash (-) or NOT before a word to exclude from search. Note that NOT acts as a filtering operator so you cannot have a search containing only NOT operators. You cannot combine OR with NOT (<q>john OR NOT bill</q> is not valid)<br>
|
||||
<q>george washington NOT bush</q></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>grouping<br>
|
||||
<q>()</q><br>
|
||||
</td>
|
||||
<td><br>
|
||||
<q>(mother OR father) AND (daugther OR son)</q></td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<br>
|
||||
|
||||
<table style="border-collapse:collapse;text-align:left">
|
||||
|
||||
<tr>
|
||||
<td><q>tag:</q>
|
||||
</td>
|
||||
<td>Searches only in tag names without looking at photo titles or descriptions.<br>
|
||||
<q>tag:john</q>, <q>tag:(john OR bill)</q></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><q>photo:</q>
|
||||
</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><q>file:</q>
|
||||
</td>
|
||||
<td>Searches by file name.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><q>created:</q><br>
|
||||
<q>taken:</q>
|
||||
</td>
|
||||
<td>Searches photos by taken date<br>
|
||||
<q>taken:2003</q> photos taken in 2003<br>
|
||||
<q>taken:20035</q>,<q>taken:2003-5</q>,<q>taken:2003-05</q> photos from may 2003<br>
|
||||
<q>taken:2003..2008</q> photos from 2003 to 2008<br>
|
||||
<q>taken:>2008</q>,<q>taken:2008*</q>,<q>taken:2008..</q> photos afteer Jan 1st 2008<br>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><q>posted:</q>
|
||||
</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><q>width:</q><br>
|
||||
<q>height:</q>
|
||||
</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><q>size:</q>
|
||||
</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><q>ratio:</q>
|
||||
</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><q>hits:</q>
|
||||
</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><q>score:</q>
|
||||
</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
Reference in New Issue
Block a user