Commit ee18c898 authored by Richard Mansfield's avatar Richard Mansfield
Browse files

Add view/artefacttype filter to tag search

parent 58ef85d5
......@@ -104,6 +104,12 @@ class PluginArtefactBlog extends PluginArtefact {
));
$blog->commit();
}
public static function get_artefact_type_content_types() {
return array(
'blogpost' => array('text'),
);
}
}
/**
......
......@@ -200,6 +200,14 @@ class PluginArtefactFile extends PluginArtefact {
public static function can_be_disabled() {
return false;
}
public static function get_artefact_type_content_types() {
return array(
'file' => array('file'),
'image' => array('file', 'image'),
'profileicon' => array('image'),
);
}
}
abstract class ArtefactTypeFileBase extends ArtefactType {
......
......@@ -127,6 +127,12 @@ class PluginArtefactInternal extends PluginArtefact {
public static function can_be_disabled() {
return false;
}
public static function get_artefact_type_content_types() {
return array(
'introduction' => array('text'),
);
}
}
class ArtefactTypeProfile extends ArtefactType {
......
......@@ -94,6 +94,18 @@ abstract class PluginArtefact extends Plugin {
public static function view_export_extra_artefacts($viewids) {
return array();
}
/**
* When filtering searches, some artefact types are classified the same way
* even when they come from different artefact plugins. This function allows
* artefact plugins to declare which search filter content type each of their
* artefact types belong to.
* @return array of artefacttype => array of filter content types
*/
public static function get_artefact_type_content_types() {
return array();
}
}
/**
......@@ -1219,4 +1231,34 @@ function artefact_type_installed($type) {
return isset($types[$type]);
}
function artefact_get_types_from_filter($filter) {
static $contenttype_artefacttype = null;
if (is_null($contenttype_artefacttype)) {
$contenttype_artefacttype = array();
foreach (plugins_installed('artefact') as $plugin) {
safe_require('artefact', $plugin->name);
$classname = generate_class_name('artefact', $plugin->name);
if (!is_callable($classname . '::get_artefact_type_content_types')) {
continue;
}
$artefacttypetypes = call_static_method($classname, 'get_artefact_type_content_types');
foreach ($artefacttypetypes as $artefacttype => $contenttypes) {
if (!empty($contenttypes)) {
foreach ($contenttypes as $ct) {
$contenttype_artefacttype[$ct][] = $artefacttype;
}
}
}
}
}
if (empty($contenttype_artefacttype[$filter])) {
return null;
}
return $contenttype_artefacttype[$filter];
}
?>
......@@ -79,6 +79,18 @@ class PluginArtefactResume extends Plugin {
);
}
public static function get_artefact_type_content_types() {
return array(
'coverletter' => array('text'),
'interest' => array('text'),
'personalgoal' => array('text'),
'academicgoal' => array('text'),
'careergoal' => array('text'),
'personalskill' => array('text'),
'academicskill' => array('text'),
'workskill' => array('text'),
);
}
}
class ArtefactTypeResume extends ArtefactType {
......
......@@ -31,12 +31,13 @@ require(dirname(dirname(__FILE__)) . '/init.php');
require('searchlib.php');
$tag = param_variable('tag');
$limit = param_integer('limit', 10);
$offset = param_integer('offset', 0);
$sort = param_alpha('sort', 'name');
$limit = param_integer('limit', 10);
$type = param_alpha('type', null);
$owner = (object) array('type' => 'user', 'id' => $USER->get('id'));
$data = get_portfolio_items_by_tag($tag, $owner, $limit, $offset, $sort);
$data = get_portfolio_items_by_tag($tag, $owner, $limit, $offset, $sort, $type);
build_portfolio_search_html($data);
$data->tagdisplay = hsc($tag);
......
......@@ -93,6 +93,13 @@ $string['sortalpha'] = 'Sort tags alphabetically';
$string['sortfreq'] = 'Sort tags by frequency';
$string['sortresultsby'] = 'Sort results by:';
$string['date'] = 'Date';
$string['filterresultsby'] = 'Filter results by:';
$string['tagfilter_all'] = 'All';
$string['tagfilter_file'] = 'Files';
$string['tagfilter_image'] = 'Images';
$string['tagfilter_text'] = 'Text';
$string['tagfilter_view'] = 'Views';
$string['selfsearch'] = 'Search My Portfolio';
......
......@@ -2178,6 +2178,13 @@ function build_portfolio_search_html(&$data) {
$data->baseurl = get_config('wwwroot') . 'tags.php?tag=' . urlencode($data->tag);
$data->sortcols = array('name', 'date');
$data->filtercols = array(
'all' => get_string('tagfilter_all'),
'file' => get_string('tagfilter_file'),
'image' => get_string('tagfilter_image'),
'text' => get_string('tagfilter_text'),
'view' => get_string('tagfilter_view'),
);
$smarty = smarty_core();
$smarty->assign_by_ref('data', $data->data);
......@@ -2185,7 +2192,7 @@ function build_portfolio_search_html(&$data) {
$pagination = build_pagination(array(
'id' => 'results_pagination',
'class' => 'center',
'url' => $data->baseurl . ($data->sort == 'name' ? '' : '&sort=' . $data->sort),
'url' => $data->baseurl . ($data->sort == 'name' ? '' : '&sort=' . $data->sort) . ($data->filter == 'all' ? '' : '&type=' . $data->filter),
'jsonscript' => 'json/tagsearch.php',
'datatable' => 'results',
'count' => $data->count,
......
......@@ -441,7 +441,18 @@ function search_selfsearch($query_string, $limit, $offset, $type = 'all') {
return call_static_method(generate_class_name('search', $plugin), 'self_search', $query_string, $limit, $offset, $type);
}
function get_portfolio_items_by_tag($tag, $owner, $limit, $offset, $sort='name', $returntags=true) {
function get_portfolio_types_from_param($filter) {
if (is_null($filter) || $filter == 'all') {
return null;
}
if ($filter == 'view') {
return array('view' => true, 'artefact' => false);
}
require_once(get_config('docroot') . 'artefact/lib.php');
return array('view' => false, 'artefact' => artefact_get_types_from_filter($filter));
}
function get_portfolio_items_by_tag($tag, $owner, $limit, $offset, $sort='name', $type=null, $returntags=true) {
// For now, can only be used to search a user's portfolio
if (empty($owner->id) || empty($owner->type)) {
throw new SystemException('get_views_and_artefacts_by_tag: invalid owner');
......@@ -450,10 +461,14 @@ function get_portfolio_items_by_tag($tag, $owner, $limit, $offset, $sort='name',
throw new SystemException('get_views_and_artefacts_by_tag only implemented for users');
}
$types = get_portfolio_types_from_param($type);
$plugin = 'internal';
safe_require('search', $plugin);
return call_static_method(generate_class_name('search', $plugin), 'portfolio_search_by_tag', $tag, $owner, $limit, $offset, $sort, $returntags);
$result = call_static_method(generate_class_name('search', $plugin), 'portfolio_search_by_tag', $tag, $owner, $limit, $offset, $sort, $types, $returntags);
$result->filter = $result->type = $type ? $type : 'all';
return $result;
}
function get_search_plugins() {
......
......@@ -845,17 +845,29 @@ class PluginSearchInternal extends PluginSearch {
* @param integer $limit
* @param integer $offset
* @param string $sort
* @param array $types view/artefacttype filters
* @param boolean $returntags Return all the tags that have been attached to each result
*/
public static function portfolio_search_by_tag($tag, $owner, $limit, $offset, $sort, $returntags) {
public static function portfolio_search_by_tag($tag, $owner, $limit, $offset, $sort, $types, $returntags) {
$viewfilter = is_null($types) || $types['view'] == true ? 'TRUE' : 'FALSE';
if (is_null($types)) {
$artefacttypefilter = '';
}
else if (!empty($types['artefact'])) {
$artefacttypefilter = ' AND a.artefacttype IN (' . join(',', array_map('db_quote', $types['artefact'])) . ')';
}
else {
$artefacttypefilter = ' AND FALSE';
}
$from = "FROM (
(SELECT a.id, a.title, a.description, 'artefact' AS type, a.artefacttype, " . db_format_tsfield('a.ctime', 'ctime') . "
FROM {artefact} a JOIN {artefact_tag} at ON (a.id = at.artefact AND at.tag = ?)
WHERE a.owner = ?)
WHERE a.owner = ?" . $artefacttypefilter . ")
UNION
(SELECT v.id, v.title, v.description, 'view' AS type, NULL AS artefacttype, " . db_format_tsfield('v.ctime', 'ctime') . "
FROM {view} v JOIN {view_tag} vt ON (v.id = vt.view AND vt.tag = ?)
WHERE v.owner = ?)
WHERE v.owner = ? AND " . $viewfilter . ")
) p";
$values = array($tag, $owner->id, $tag, $owner->id);
......
......@@ -33,7 +33,6 @@ define('TITLE', get_string('mytags'));
$tagsort = param_alpha('ts', null) != 'freq' ? 'alpha' : 'freq';
$tags = get_my_tags(null, false, $tagsort);
$tagsstr = json_encode($tags);
$tag = param_variable('tag', null);
......@@ -42,17 +41,29 @@ $js = '';
$limit = param_integer('limit', 10);
$offset = param_integer('offset', 0);
$sort = param_alpha('sort', 'name');
$type = param_alpha('type', null);
$owner = (object) array('type' => 'user', 'id' => $USER->get('id'));
$data = get_portfolio_items_by_tag($tag, $owner, $limit, $offset, $sort);
$data = get_portfolio_items_by_tag($tag, $owner, $limit, $offset, $sort, $type);
build_portfolio_search_html($data);
$str = array();
foreach (array('tags', 'tag', 'sort', 'type') as $v) {
$str[$v] = json_encode($$v);
}
$hidepagination = $tag ? '' : "addElementClass('results_pagination', 'hidden');";
$js = <<<EOF
var p = null;
var mytags_container = null;
var inittags = {$tagsstr};
var inittags = {$str['tags']};
var mytags = {};
var params = {
'tag': {$str['tag']},
'sort': {$str['sort']},
'type': {$str['type']}
};
function sortTagAlpha(a, b) {
var aid = getNodeAttribute(a, 'id');
var bid = getNodeAttribute(b, 'id');
......@@ -85,22 +96,36 @@ function rewriteTagSortLink(elem) {
});
}
function rewriteTagLink(elem) {
function rewriteTagLink(elem, keep, replace) {
disconnectAll(elem);
connect(elem, 'onclick', function(e) {
e.stop();
var href = getNodeAttribute(this, 'href');
var params = parseQueryString(href.substring(href.indexOf('?')+1, href.length));
sendjsonrequest(config.wwwroot + 'json/tagsearch.php', params, 'POST', function(data) {
var hrefparams = parseQueryString(href.substring(href.indexOf('?')+1, href.length));
var reqparams = {};
reqparams[replace] = hrefparams[replace];
for (var i = 0; i < keep.length; i++) {
if (params[keep[i]]) {
reqparams[keep[i]] = params[keep[i]];
}
}
for (var i in reqparams) {
log(i + ' ' + reqparams[i]);
}
sendjsonrequest(config.wwwroot + 'json/tagsearch.php', reqparams, 'POST', function(data) {
p.updateResults(data);
if (data.data.tag != params.tag) {
// Update tag links in the My Tags list:
forEach(getElementsByTagAndClassName('a', 'selected', mytags_container), function(selected) {
removeElementClass(selected, 'selected');
});
// Mark the selected tag in the My Tags list:
addElementClass('tag:' + params.tag, 'selected');
addElementClass('tag:' + data.data.tag, 'selected');
// Replace the tag in the Search Results heading
var heading_tag = getFirstElementByTagAndClassName('a', 'tag', 'results_heading');
......@@ -110,24 +135,42 @@ function rewriteTagLink(elem) {
}
removeElementClass('results_container', 'hidden');
params.tag = data.data.tag;
}
// Rewrite tag links in the results list:
forEach(getElementsByTagAndClassName('a', 'tag', 'results'), rewriteTagLink);
forEach(getElementsByTagAndClassName('a', 'tag', 'results'), function (elem) {rewriteTagLink(elem, [], 'tag')});
// Rewrite Sort By links above the Search results:
// Change selected Sort By links above the Search results:
if (data.data.sort != params.sort) {
forEach(getElementsByTagAndClassName('a', null, 'results_sort'), function (a) {
var href = getNodeAttribute(a, 'href');
var params = parseQueryString(href.substring(href.indexOf('?')+1, href.length));
params.tag = data.data.tag;
setNodeAttribute(a, 'href', config.wwwroot + 'tags.php?' + queryString(params));
if (hasElementClass(a, 'selected') && data.data.sort != params.sort) {
var hrefparams = parseQueryString(href.substring(href.indexOf('?')+1, href.length));
if (hasElementClass(a, 'selected') && data.data.sort != hrefparams.sort) {
removeElementClass(a, 'selected');
}
else if (!hasElementClass(a, 'selected') && data.data.sort == hrefparams.sort) {
addElementClass(a, 'selected');
}
});
params.sort = data.data.sort;
}
// Change selected Filter By links above the Search results:
if (data.data.type != params.type) {
forEach(getElementsByTagAndClassName('a', null, 'results_filter'), function (a) {
var href = getNodeAttribute(a, 'href');
var hrefparams = parseQueryString(href.substring(href.indexOf('?')+1, href.length));
if (hasElementClass(a, 'selected') && data.data.type != hrefparams.type) {
removeElementClass(a, 'selected');
}
else if (!hasElementClass(a, 'selected') && data.data.sort == params.sort) {
else if (!hasElementClass(a, 'selected') && data.data.type == hrefparams.type) {
addElementClass(a, 'selected');
}
rewriteTagLink(a);
});
params.type = data.data.type;
}
});
return false;
});
......@@ -141,10 +184,11 @@ addLoadEvent(function() {
mytags_container = getFirstElementByTagAndClassName(null, 'mytags', 'main-column-container');
p = {$data->pagination_js}
forEach(getElementsByTagAndClassName('a', 'tag', mytags_container), rewriteTagLink);
forEach(getElementsByTagAndClassName('a', 'tag', 'sb-mytags'), rewriteTagLink);
forEach(getElementsByTagAndClassName('a', 'tag', 'results'), rewriteTagLink);
forEach(getElementsByTagAndClassName('a', null, 'results_sort'), rewriteTagLink);
forEach(getElementsByTagAndClassName('a', 'tag', mytags_container), function (elem) {rewriteTagLink(elem, [], 'tag')});
forEach(getElementsByTagAndClassName('a', 'tag', 'sb-mytags'), function (elem) {rewriteTagLink(elem, [], 'tag')});
forEach(getElementsByTagAndClassName('a', 'tag', 'results'), function (elem) {rewriteTagLink(elem, [], 'tag')});
forEach(getElementsByTagAndClassName('a', null, 'results_sort'), function (elem) {rewriteTagLink(elem, ['tag', 'type'], 'sort')});
forEach(getElementsByTagAndClassName('a', null, 'results_filter'), function (elem) {rewriteTagLink(elem, ['tag', 'sort'], 'type')});
{$hidepagination}
});
EOF;
......
......@@ -19,7 +19,12 @@
<h2 id="results_heading">{str tag=searchresultsfor} <a class="tag" href="{$WWWROOT}tags.php?tag={$tag|urlencode}">{$tag|escape}</a></h4>
<div id="results_sort">{str tag=sortresultsby}
{foreach from=$results->sortcols item=sortfield name=sortcols}
<a href="{$results->baseurl}&sort={$sortfield}"{if $results->sort == $sortfield} class="selected"{/if}>{str tag=$sortfield}</a>{if !$smarty.foreach.sortcols.last} | {/if}
<a href="{$results->baseurl}&type={$results->filter}&sort={$sortfield}"{if $results->sort == $sortfield} class="selected"{/if}>{str tag=$sortfield}</a>{if !$smarty.foreach.sortcols.last} | {/if}
{/foreach}
</div>
<div id="results_filter">{str tag=filterresultsby}
{foreach from=$results->filtercols key=filtername item=filterdisplay name=filtercols}
<a href="{$results->baseurl}&sort={$results->sort}&type={$filtername}"{if $results->filter == $filtername} class="selected"{/if}>{$filterdisplay}</a>{if !$smarty.foreach.filtercols.last} | {/if}
{/foreach}
</div>
<table id="results" class="tablerenderer fullwidth">
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment