|
*/
-$autoload['language'] = array('ui');
+$autoload['language'] = array('ui', 'error');
/*
| DO NOT CHANGE THIS UNLESS YOU FULLY UNDERSTAND THE REPERCUSSIONS!!
|
*/
-$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-';
+$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-+';
/*
$this->load->view('html_end');
}
- public function category($category_name, $offset = 0)
+ public function category($category_name, $ordering = 'hottest', $offset = 0)
{
// **
// ** LOADING MODEL
$this->load->model('videos_model');
$vs_data['videos'] = $this->videos_model->get_videos_summary(
$vs_data['category_id'], intval($offset),
- $this->config->item('videos_per_page'));
+ $this->config->item('videos_per_page'), $ordering);
+
+ $vs_data['ordering'] = $ordering;
// Pagination
$this->load->library('pagination');
- $pg_config['base_url'] = site_url("catalog/category/$category_name/");
- $pg_config['uri_segment'] = 4;
+ $pg_config['base_url'] = site_url("catalog/category/$category_name/$ordering/");
+ $pg_config['uri_segment'] = 5;
$pg_config['total_rows'] = $this->videos_model->get_videos_count(
$vs_data['category_id']);
$pg_config['per_page'] = $this->config->item('videos_per_page');
// ** LOADING VIEWS
// **
$this->load->view('html_begin', $this->html_head_params);
- $this->load->view('header');
+ $this->load->view('header', array(
+ 'search_category_name'=>$vs_data['category_name'],
+ 'search_category_title'=>$vs_data['category_title']
+ ));
// $main_params['content'] = $this->load->view('catalog/category_view', $data, TRUE);
$main_params['content'] =
$str_post_search = $this->input->post('search', TRUE);
if ($search_query === "" && $str_post_search !== FALSE)
redirect('catalog/search/'. $this->input->post('search', TRUE));
+
+ $this->load->model('videos_model');
// **
// ** LOADING MODEL
// **
+ // Search query is encoded for URL and must be decoded.
+ $enc_search_query = $search_query;
+ $search_query = $this->videos_model->decode_search_query($search_query);
+ $results_data['search_query'] = $search_query;
+
// Category
$results_data = $this->_get_category_data($category_name);
if ($results_data === NULL)
$results_data = array('category_id'=>NULL);
- $results_data['search_query'] = $search_query;
+ // Page header data
+ $header_data['search_query'] = $search_query;
+ if ($category_name !== NULL)
+ {
+ $header_data['search_category_name'] = $results_data['category_name'];
+ $header_data['search_category_title'] = $results_data['category_title'];
+ }
// Check if search string is valid.
if (strlen($search_query) < 4)
{
- $results_data['videos'] = NULL;
+ //$results_data['videos'] = NULL;
+ $this->error($this->lang->line('error_search_query_too_short'),
+ $header_data);
+ return;
}
else
{
// Retrieve search results.
- $this->load->model('videos_model');
$results_data['count'] = $this->videos_model->search_videos(
- $search_query);
+ $search_query, 0, 0, $results_data['category_id']);
$results_data['videos'] = $this->videos_model->search_videos(
$search_query, intval($offset),
$this->config->item('search_results_per_page'),
// Pagination
$this->load->library('pagination');
- $pg_config['base_url'] = site_url("catalog/search/$search_query/");
+ $pg_config['base_url'] = site_url("catalog/search/$enc_search_query/");
$pg_config['uri_segment'] = 4;
$pg_config['total_rows'] = $results_data['count'];
$pg_config['per_page'] =
$this->pagination->initialize($pg_config);
$results_data['pagination'] = $this->pagination->create_links();
}
-
+
+ // HTML head parameters
$params = array( 'title' => $this->config->item('site_name'),
'css' => array(
'catalog.css'
// ** LOADING VIEWS
// **
$this->load->view('html_begin', $this->html_head_params);
- $this->load->view('header');
+ $this->load->view('header', $header_data);
// Search Results
$main_params['content'] =
$this->load->view('html_end');
}
+ public function error($msg, $header_data)
+ {
+ $params = array( 'title' => 'Error - '. $this->config->item('site_name'),
+ //'css' => array(),
+ //'js' => array(),
+ //'metas' => array('description'=>'','keywords'=>'')
+ );
+ $this->load->library('html_head_params', $params);
+
+ // **
+ // ** LOADING VIEWS
+ // **
+ $this->load->view('html_begin', $this->html_head_params);
+ $this->load->view('header', $header_data);
+
+ $main_params['content'] = $this->load->view('error_view', array('msg'=>$msg), TRUE);
+ $main_params['side'] = $this->load->view('side_default', NULL, TRUE);
+ $this->load->view('main', $main_params);
+
+ $this->load->view('footer');
+ $this->load->view('html_end');
+ }
+
public function _get_category_data($category_name)
{
if ($category_name === NULL)
--- /dev/null
+<?php
+
+$lang['error_search_query_too_short'] = 'The search query is too short! You must enter at least 4 characters.';
+
+/* End of file error_lang.php */
+/* Location: ./application/language/english/error_lang.php */
\ No newline at end of file
// Search
$lang['ui_search'] = 'Search';
+$lang['ui_search_in'] = 'Search in';
$lang['ui_search_results_for'] = 'Search Results for';
$lang['ui_results'] = 'result(s)';
$lang['ui_categ_events'] = 'Events';
$lang['ui_categ_karaoke'] = 'Karaoke';
+// Ordering
+$lang['ui_show_hottest'] = "Show Hottest";
+$lang['ui_show_newest'] = "Show Newest";
+$lang['ui_sort_alphabetically'] = "Sort Alphabetically";
+
// Pagination
$lang['ui_page_first'] = 'First';
$lang['ui_page_previous'] = 'Previous';
* Retrieves information about a set of videos which are going to be
* displayed in the catalog.
*
- * TODO: filter, limit, ordering parameters
* @param int $category_id DB category ID
* @param int $offset
* @param int $count
+ * @param string $ordering control videos ording by these
+ * possibilities:
+ * <ul>
+ * <li><strong>'hottest':</strong> newest most appreciated first. An
+ * appreciated video is one which has a bigger
+ * score = views + likes - dislikes.</li>
+ * <li><strong>'newest':</strong> newest first.</li>
+ * <li><strong>'alphabetically':</strong> sort alphabetically.</li>
+ * </ul>
* @return array a list of videos, each one being an assoc array with:
* <ul>
* <li>id, name, title, duration, thumbs_count, default_thumb, views => from DB</li>
* <li>thumbs => thumbnail images' URLs</li>
* </ul>
*/
- public function get_videos_summary($category_id, $offset, $count)
+ public function get_videos_summary($category_id, $offset, $count, $ordering = 'hottest')
{
$this->load->helper('text');
+ // Ordering
+ switch ($ordering)
+ {
+ case 'hottest':
+ $order_statement = "ORDER BY date DESC, score DESC, RAND()";
+ break;
+ case 'newest':
+ $order_statement = "ORDER BY date DESC";
+ break;
+ case 'alphabetically':
+ $order_statement = "ORDER BY title";
+ break;
+
+ default:
+ $order_statement = "";
+ }
+
$query = $this->db->query(
- 'SELECT id, name, title, duration, user_id, views, thumbs_count,
- default_thumb
+ "SELECT id, name, title, duration, user_id, views, thumbs_count,
+ default_thumb, (views + likes - dislikes) AS score
FROM `videos`
WHERE category_id = ?
- ORDER BY name
- LIMIT ?, ?', // TODO summary order
+ $order_statement
+ LIMIT ?, ?",
array(intval($category_id), $offset, $count));
if ($query->num_rows() > 0)
*/
public function search_videos($search_query, $offset = 0, $count = 0,
$category_id = NULL)
- {
+ {
+ if (! $this->is_advanced_search_query($search_query)) // if natural language mode
+ {
+ $search_cond = "MATCH (title, description, tags)
+ AGAINST ('$search_query')";
+ $relevance = "$search_cond AS relevance";
+ } // if boolean mode
+ else
+ {
+ $against = "AGAINST ('$search_query' IN BOOLEAN MODE)";
+ $search_cond = "MATCH (title, description, tags)
+ $against";
+ $relevance = "( (0.5 * (MATCH(title) $against))
+ + (0.3 * (MATCH(tags) $against))
+ + (0.2 * (MATCH(description) $against)) ) AS relevance";
+ }
+
if ($count === 0)
{
$selected_columns = "COUNT(*) count";
+ $order = "";
$limit = "";
}
else
{
- $selected_columns = "id, name, title, duration, user_id, views, thumbs_count, default_thumb, date, description";
+ $selected_columns = "id, name, title, duration, user_id, views,
+ thumbs_count, default_thumb, date, description,
+ (views + likes - dislikes) AS score,
+ $relevance";
+ $order = "ORDER BY relevance DESC, score DESC";
$limit = "LIMIT $offset, $count";
}
$search_query = trim($search_query);
- $query = $this->db->query(
- "SELECT $selected_columns
+ $str_query = "SELECT $selected_columns
FROM `videos`
- WHERE $category_cond MATCH (title, description, tags) AGAINST (?)
- $limit",
- array($search_query));
+ WHERE $category_cond $search_cond
+ $order
+ $limit";
+ $query = $this->db->query($str_query);
if ($query->num_rows() > 0)
{
return $videos;
}
+
+ public function decode_search_query($search_query)
+ {
+ $search_query = urldecode($search_query);
+
+ $search_query = str_replace('_AST_', '*', $search_query);
+ $search_query = str_replace('_AND_', '+', $search_query);
+ $search_query = str_replace('_GT_', '>', $search_query);
+ $search_query = str_replace('_LT_', '<', $search_query);
+ $search_query = str_replace('_PO_', '(', $search_query);
+ $search_query = str_replace('_PC_', ')', $search_query);
+ $search_query = str_replace('_LOW_', '~', $search_query);
+ $search_query = str_replace('_QUO_', '"', $search_query);
+
+ return $search_query;
+ }
+
+ /**
+ * Return TRUE if it contains any special caracter from an advanced search
+ * query.
+ * @param string $search_query
+ * @return boolean
+ */
+ public function is_advanced_search_query($search_query)
+ {
+ return (preg_match('/\*|\+|\-|>|\<|\(|\)|~|"/', $search_query) == 0
+ ? FALSE : TRUE);
+ }
}
/* End of file videos_model.php */
<div class="search_results">
<h1><?php echo $this->lang->line('ui_search_results_for')
- . " «$search_query»" ?></h1>
+ . " <em>«" . htmlentities($search_query) . "»</em>" ?></h1>
<p><?php echo "$count ". $this->lang->line('ui_results'); ?></p>
<?php echo $category_title ?>
</a>
</h1>
+
+ <?php
+ if ( isset($ordering))
+ {
+ $ordering_opts = array(
+ 'hottest'=> $this->lang->line('ui_show_hottest'),
+ 'newest'=> $this->lang->line('ui_show_newest'),
+ 'alphabetically'=> $this->lang->line('ui_sort_alphabetically')
+ );
+
+ echo '<p>';
+ echo form_dropdown('ordering', $ordering_opts, $ordering, 'id="ordering"');
+ echo '</p>';
+ }
+ ?>
<?php echo $pagination ?>
<div style="clear: both"></div>
-</div>
\ No newline at end of file
+</div>
+
+<script type="text/javascript">
+ $(function() {
+ $('#ordering').change(function(e) {
+ var uri = "<?php echo site_url("catalog/category/$category_name") ?>";
+
+ // Default ordering
+ if ($(this).val() != "hottest")
+ uri += "/" + $(this).val();
+
+ window.location = uri;
+ });
+ });
+
+</script>
\ No newline at end of file
--- /dev/null
+<div class="ui-state-error ui-corner-all" style="padding: 0 .7em;">
+ <p style="text-align: center">
+ <span class="ui-icon ui-icon-alert" style="float: left; margin-right: .3em;"></span>
+ <span><?php echo $msg ?></span>
+ </p>
+</div>
\ No newline at end of file
-<?php if (! isset($selected_menu)):
-$selected_menu = '';
-endif ?>
+<?php
+ if (! isset($selected_menu))
+ $selected_menu = '';
+ if (! isset($search_query))
+ $search_query = '';
+ if (! isset($search_category_name))
+ $search_category_name = NULL;
+?>
<ul
id="nav-menu">
<?php echo form_open('catalog/search', array('id'=>'quick-search')); ?>
- <input type="text" id="search" name="search" value="" />
+ <label for="search"><?php
+ if ($search_category_name === NULL)
+ echo $this->lang->line('ui_search') . ':';
+ else
+ echo $this->lang->line('ui_search_in') . ' <em>'
+ . $search_category_title . '</em>:';
+ ?>
+ </label>
+ <input type="text" id="search" name="search" value="<?php echo $search_query ?>" />
<input type="submit" id="button-quick-search" value="<?php echo $this->lang->line('ui_search') ?>" />
<a href="#" id="button-js-quick-search" style="display:none">
<?php echo $this->lang->line('ui_search') ?>
// Fake JS submit via CI URI segments
var fakeSubmit = function() {
var searchQuery = $('#search').val();
- searchQuery = searchQuery.replace(/\*/g, '*2A'); // *
- searchQuery = searchQuery.replace(/\+/g, '*2B'); // +
+
+ if (searchQuery.length < 4)
+ {
+ alert('<?php echo $this->lang->line('error_search_query_too_short') ?>');
+ return;
+ }
+
+ searchQuery = searchQuery.replace(/\*/g, '_AST_'); // *
+ searchQuery = searchQuery.replace(/\+/g, '_AND_'); // +
+ //searchQuery = searchQuery.replace(/\-/g, '_'); // -
searchQuery = searchQuery.replace(/\s/g, '+'); // <white spaces>
- searchQuery = searchQuery.replace(/>/g, '*3E'); // >
- searchQuery = searchQuery.replace(/\</g, '*3C'); // <
- searchQuery = searchQuery.replace(/\(/g, '*28'); // (
- searchQuery = searchQuery.replace(/\)/g, '*29'); // )
- searchQuery = searchQuery.replace(/~/g, '*7E'); // ~
- searchQuery = searchQuery.replace(/"/g, '*22'); // "
+ searchQuery = searchQuery.replace(/>/g, '_GT_'); // >
+ searchQuery = searchQuery.replace(/\</g, '_LT_'); // <
+ searchQuery = searchQuery.replace(/\(/g, '_PO_'); // (
+ searchQuery = searchQuery.replace(/\)/g, '_PC_'); // )
+ searchQuery = searchQuery.replace(/~/g, '_LOW_'); // ~
+ searchQuery = searchQuery.replace(/"/g, '_QUO_'); // "
searchQuery = encodeURI(searchQuery);
- searchQuery = searchQuery.replace(/\*/g, '%'); // *
-
- alert(searchQuery);
window.location = "<?php echo site_url('catalog/search') ?>/"
- + searchQuery;
+ + searchQuery + '/0'
+ + "<?php echo ($search_category_name === NULL ? '' : '/'. $search_category_name) ?>";
};
$('#button-js-quick-search')
margin-bottom: 1em;
}
+.search-result
+{
+ position: relative;
+}
+
+.search-result-info
+{
+ position: absolute;
+ left : 154px;
+ margin-left: 8px;
+}
+
.category-title
{
/* border-bottom: 1px solid rgb(108,162,222); */
{
clear: both;
word-spacing: 0.5em;
+ margin-bottom: 0.5em;
}