Просмотр исходного кода

Optimisation recherche et pagination

* Optimisation recherche SQL avec utilisation de HAVING plutôt que WHERE
* Simplification et amélioration des performances en supprimant de
RSSPaginator qui n'aidait plus vraiment et nécessitait plus de code et
des copies de données.
* Correction d'un bug dans le titre de la page introduit récemment, et
simplification
Alexandre Alapetite 12 лет назад
Родитель
Сommit
1e077160fc

+ 0 - 1
app/App_FrontController.php

@@ -33,7 +33,6 @@ class App_FrontController extends FrontController {
 		include (APP_PATH . '/models/Category.php');
 		include (APP_PATH . '/models/Feed.php');
 		include (APP_PATH . '/models/Entry.php');
-		include (APP_PATH . '/models/RSSPaginator.php');
 		include (APP_PATH . '/models/Log_Model.php');
 	}
 

+ 15 - 18
app/controllers/indexController.php

@@ -46,8 +46,6 @@ class indexController extends ActionController {
 			'params' => $params
 		);
 
-		$this->view->rss_title = View::title();
-
 		if ($output === 'rss') {
 			// no layout for RSS output
 			$this->view->_useLayout (false);
@@ -67,19 +65,6 @@ class indexController extends ActionController {
 		$this->view->get_c = '';
 		$this->view->get_f = '';
 
-		// mise à jour des titres
-		$this->view->nb_not_read = HelperCategory::CountUnreads($this->view->cat_aside, 1);
-		if ($this->view->nb_not_read > 0) {
-			View::appendTitle (' (' . $this->view->nb_not_read . ')');
-		}
-		View::prependTitle (' - ');
-
-		$this->view->rss_title = $this->view->currentName . ' - ' . $this->view->rss_title;
-		View::prependTitle (
-			$this->view->currentName .
-			($this->nb_not_read_cat > 0 ? ' (' . $this->nb_not_read_cat . ')' : '')
-		);
-
 		$get = Request::param ('get', 'a');
 		$getType = $get[0];
 		$getId = substr ($get, 2);
@@ -92,6 +77,18 @@ class indexController extends ActionController {
 			return;
 		}
 
+		$this->view->nb_not_read = HelperCategory::CountUnreads($this->view->cat_aside, 1);
+
+		// mise à jour des titres
+		if ($this->view->nb_not_read > 0) {
+			View::appendTitle (' (' . $this->view->nb_not_read . ')');
+		}
+		View::prependTitle (
+			$this->view->currentName .
+			($this->nb_not_read_cat > 0 ? ' (' . $this->nb_not_read_cat . ')' : '') .
+			' - '
+		);
+
 		// On récupère les différents éléments de filtrage
 		$this->view->state = $state = Request::param ('state', $this->view->conf->defaultView ());
 		$filter = Request::param ('search', '');
@@ -138,13 +135,13 @@ class indexController extends ActionController {
 			}
 
 			if (count($entries) <= $nb) {
-				$next = '';
+				$this->view->nextId  = '';
 			} else {	//We have more elements for pagination
 				$lastEntry = array_pop($entries);
-				$next = $lastEntry->id();
+				$this->view->nextId  = $lastEntry->id();
 			}
 
-			$this->view->entryPaginator = new RSSPaginator ($entries, $next);
+			$this->view->entries = $entries;
 		} catch (EntriesGetterException $e) {
 			Minz_Log::record ($e->getMessage (), Minz_Log::NOTICE);
 			Error::error (

+ 2 - 3
app/layout/layout.phtml

@@ -10,10 +10,9 @@
 <?php $this->renderHelper ('javascript_vars'); ?>
 		//]]></script>
 <?php
-	$next = isset($this->entryPaginator) ? $this->entryPaginator->next() : '';
-	if (!empty($next)) {
+	if (!empty($this->nextId)) {
 		$params = Request::params ();
-		$params['next'] = $next;
+		$params['next'] = $this->nextId;
 ?>
 		<link id="prefetch" rel="next prefetch" href="<?php echo Url::display (array ('c' => Request::controllerName (), 'a' => Request::actionName (), 'params' => $params)); ?>" />
 <?php } ?>

+ 2 - 2
app/layout/nav_menu.phtml

@@ -17,8 +17,6 @@
 			$string_mark = Translate::t ('mark_cat_read');
 		}
 		$nextGet = $get;
-		$p = $this->entryPaginator->peek();
-		$idMax = $p === null ? '0' : $p->id();
 		if (($this->conf->onread_jump_next () === 'yes') && (strlen ($get) > 2)) {
 			$anotherUnreadId = '';
 			$foundCurrent = false;
@@ -54,6 +52,8 @@
 					break;
 			}
 		}
+		$p = isset($this->entries[0]) ? $this->entries[0] : null;
+		$idMax = $p === null ? '0' : $p->id();
 		$markReadUrl = _url ('entry', 'read', 'is_read', 1, 'get', $get, 'nextGet', $nextGet, 'idMax', $idMax);
 		Session::_param ('markReadUrl', $markReadUrl);
 	?>

+ 8 - 3
app/models/Entry.php

@@ -504,14 +504,18 @@ class EntryDAO extends Model_pdo {
 		if ($firstId > 0) {
 			$where .= 'AND e.id ' . ($order === 'DESC' ? '<=' : '>=') . $firstId . ' ';
 		}
-		$terms = explode(' ', trim($filter));
+		$terms = array_unique(explode(' ', trim($filter)));
 		sort($terms);	//Put #tags first
+		$having = '';
 		foreach ($terms as $word) {
 			if (!empty($word)) {
 				if ($word[0] === '#' && isset($word[1])) {
-					$where .= 'AND tags LIKE "%' . $word . '%" ';
+					$having .= 'AND tags LIKE ? ';
+					$values[] = '%' . $word .'%';
 				} elseif (!empty($word)) {
-					$where .= 'AND (e.title LIKE "%' . $word . '%" OR UNCOMPRESS(e.content_bin) LIKE "%' . $word . '%") ';
+					$having .= 'AND (e.title LIKE ? OR content LIKE ?) ';
+					$values[] = '%' . $word .'%';
+					$values[] = '%' . $word .'%';
 				}
 			}
 		}
@@ -519,6 +523,7 @@ class EntryDAO extends Model_pdo {
 		$sql = 'SELECT e.id, e.guid, e.title, e.author, UNCOMPRESS(e.content_bin) AS content, e.link, e.date, e.is_read, e.is_favorite, e.id_feed, e.tags '
 		     . 'FROM `' . $this->prefix . 'entry` e '
 		     . 'INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed = f.id WHERE ' . $where
+		     . (empty($having) ? '' : 'HAVING' . substr($having, 3))
 		     . 'ORDER BY e.id ' . $order;
 
 		if ($limit > 0) {

+ 0 - 37
app/models/RSSPaginator.php

@@ -1,37 +0,0 @@
-<?php
-
-// Un système de pagination beaucoup plus simple que Paginator
-// mais mieux adapté à nos besoins
-class RSSPaginator {
-	private $items = array ();
-	private $next = '';
-
-	public function __construct ($items, $next) {
-		$this->items = $items;
-		$this->next = $next;
-	}
-
-	public function isEmpty () {
-		return empty ($this->items);
-	}
-
-	public function items () {
-		return $this->items;
-	}
-
-	public function next () {
-		return $this->next;
-	}
-
-	public function peek () {
-		return isset($this->items[0]) ? $this->items[0] : null;
-	}
-
-	public function render ($view, $getteur) {
-		$view = APP_PATH . '/views/helpers/'.$view;
-
-		if (file_exists ($view)) {
-			include ($view);
-		}
-	}
-}

+ 2 - 2
app/views/helpers/pagination.phtml

@@ -8,8 +8,8 @@
 
 <ul class="pagination">
 	<li class="item pager-next">
-	<?php if ($this->next != '') { ?>
-	<?php $params[$getteur] = $this->next; ?>
+	<?php if (!empty($this->nextId)) { ?>
+	<?php $params['next'] = $this->nextId; ?>
 	<a id="load_more" href="<?php echo Url::display (array ('c' => $c, 'a' => $a, 'params' => $params)); ?>"><?php echo Translate::t ('load_more'); ?></a>
 	<?php } elseif ($markReadUrl) { ?>
 	<a id="bigMarkAsRead" href="<?php echo $markReadUrl; ?>">

+ 3 - 5
app/views/helpers/view/normal_view.phtml

@@ -3,8 +3,7 @@
 $this->partial ('aside_flux');
 $this->partial ('nav_menu');
 
-if (isset ($this->entryPaginator) && !$this->entryPaginator->isEmpty ()) {
-	$items = $this->entryPaginator->items ();
+if (!empty($this->entries)) {
 ?>
 
 <div id="stream" class="normal<?php echo $this->conf->displayPosts () === 'no' ? ' hide_posts' : ''; ?>">
@@ -23,8 +22,7 @@ if (isset ($this->entryPaginator) && !$this->entryPaginator->isEmpty ()) {
 		$email = $this->conf->sharing ('email');
 		$print = $this->conf->sharing ('print');
 	?>
-
-	<?php foreach ($items as $item) { ?>
+	<?php foreach ($this->entries as $item) { ?>
 
 	<?php if ($display_today && $item->isDay (Days::TODAY)) { ?>
 	<div class="day" id="day_today">
@@ -199,7 +197,7 @@ if (isset ($this->entryPaginator) && !$this->entryPaginator->isEmpty ()) {
 	</div>
 	<?php } ?>
 
-	<?php $this->entryPaginator->render ('pagination.phtml', 'next'); ?>
+	<?php $this->renderHelper('pagination'); ?>
 </div>
 
 <?php $this->partial ('nav_entries'); ?>

+ 3 - 4
app/views/helpers/view/reader_view.phtml

@@ -1,12 +1,11 @@
 <?php
 $this->partial ('nav_menu');
 
-if (isset ($this->entryPaginator) && !$this->entryPaginator->isEmpty ()) {
-	$items = $this->entryPaginator->items ();
+if (!empty($this->entries)) {
 ?>
 
 <div id="stream" class="reader">
-	<?php foreach ($items as $item) { ?>
+	<?php foreach ($this->entries as $item) { ?>
 
 	<div class="flux<?php echo !$item->isRead () ? ' not_read' : ''; ?><?php echo $item->isFavorite () ? ' favorite' : ''; ?>" id="flux_<?php echo $item->id (); ?>">
 		<div class="flux_content">
@@ -38,7 +37,7 @@ if (isset ($this->entryPaginator) && !$this->entryPaginator->isEmpty ()) {
 	</div>
 	<?php } ?>
 
-	<?php $this->entryPaginator->render ('pagination.phtml', 'next'); ?>
+	<?php $this->renderHelper('pagination'); ?>
 </div>
 
 <?php } else { ?>

+ 1 - 2
app/views/helpers/view/rss_view.phtml

@@ -8,8 +8,7 @@
 		<lastBuildDate><?php echo gmdate('D, d M Y H:i:s'); ?> GMT</lastBuildDate>
 		<atom:link href="<?php echo Url::display ($this->rss_url, 'html', true); ?>" rel="self" type="application/rss+xml" />
 <?php
-$items = $this->entryPaginator->items ();
-foreach ($items as $item) {
+foreach ($this->entries as $item) {
 ?>
 		<item>
 			<title><?php echo $item->title (); ?></title>