From 3f731dd4bcd3f75d952067fa95f0502807ad3896 Mon Sep 17 00:00:00 2001
From: Alex Arnaud <alex.arnaud@biblibre.com>
Date: Thu, 13 Feb 2025 16:15:20 +0100
Subject: [PATCH 1/4] hotline#211010 : sort calendar events by next starting
 date

---
 library/Class/Article/SelectWithTimings.php | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/library/Class/Article/SelectWithTimings.php b/library/Class/Article/SelectWithTimings.php
index 3e4d0b603a0..adb232123fe 100644
--- a/library/Class/Article/SelectWithTimings.php
+++ b/library/Class/Article/SelectWithTimings.php
@@ -30,7 +30,8 @@ class Class_Article_SelectWithTimings extends Class_Article_Select {
 
     $this->_select
       ->joinLeft('cms_article_timings',
-                 'cms_article.id_article=cms_article_timings.article_id',
+                 'cms_article.id_article=cms_article_timings.article_id'
+                 . ' AND cms_article_timings.start >= NOW()',
                  ['min(cms_article_timings.start) as start', 'min(cms_article_timings.end) as end'])
       ->group('id_article');
 
@@ -83,4 +84,16 @@ class Class_Article_SelectWithTimings extends Class_Article_Select {
     $this->_select->where('EVENTS_FIN IS NOT NULL OR END IS NOT NULL');
     return $this;
   }
+
+
+  protected function _orderAndLimit()
+  {
+    if ($this->getSortOrder() == 'EventDebut')
+      $this->_select->order(['start', 'events_debut']);
+
+    if ($this->getSortOrder() == 'DebutPublicationDesc')
+      $this->_select->order(['debut desc', 'events_debut desc']);
+
+    return $this;
+  }
 }
-- 
GitLab


From 3fb4daadbda11cbca7bcceb14e65790e195af8d0 Mon Sep 17 00:00:00 2001
From: Alex Arnaud <alex.arnaud@biblibre.com>
Date: Thu, 13 Feb 2025 17:43:53 +0100
Subject: [PATCH 2/4] hotline#211010: unit tests

---
 library/Class/Article/SelectWithTimings.php        |  3 +++
 .../ArticlesMultipleTimingsLoaderTest.php          | 14 +++++++-------
 2 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/library/Class/Article/SelectWithTimings.php b/library/Class/Article/SelectWithTimings.php
index adb232123fe..9cb077731fb 100644
--- a/library/Class/Article/SelectWithTimings.php
+++ b/library/Class/Article/SelectWithTimings.php
@@ -94,6 +94,9 @@ class Class_Article_SelectWithTimings extends Class_Article_Select {
     if ($this->getSortOrder() == 'DebutPublicationDesc')
       $this->_select->order(['debut desc', 'events_debut desc']);
 
+    if (!$this->_select->getPart('order'))
+      return parent::_orderAndLimit();
+
     return $this;
   }
 }
diff --git a/tests/scenarios/ArticlesMultipleTimings/ArticlesMultipleTimingsLoaderTest.php b/tests/scenarios/ArticlesMultipleTimings/ArticlesMultipleTimingsLoaderTest.php
index 9cb13bc3955..87cefd0cac7 100644
--- a/tests/scenarios/ArticlesMultipleTimings/ArticlesMultipleTimingsLoaderTest.php
+++ b/tests/scenarios/ArticlesMultipleTimings/ArticlesMultipleTimingsLoaderTest.php
@@ -50,7 +50,7 @@ class ArticlesMultipleTimingsLoaderSqlTest
   /** @test */
   public function withEventsOnlyShouldFilterOnEventsDates() {
     $this->getArticles(['events_only' => true]);
-    $this->assertSelect(sprintf('LEFT JOIN `cms_article_timings` ON cms_article.id_article=cms_article_timings.article_id WHERE %s AND (EVENTS_DEBUT IS NOT NULL OR START IS NOT NULL) AND (EVENTS_FIN IS NOT NULL OR (END IS NOT NULL AND END >= CURDATE())) AND (PARENT_ID=0) GROUP BY `id_article` ORDER BY `DATE_CREATION` DESC', self::WHERE_VISIBLE_CLAUSE));
+    $this->assertSelect(sprintf('LEFT JOIN `cms_article_timings` ON cms_article.id_article=cms_article_timings.article_id AND cms_article_timings.start >= NOW() WHERE %s AND (EVENTS_DEBUT IS NOT NULL OR START IS NOT NULL) AND (EVENTS_FIN IS NOT NULL OR (END IS NOT NULL AND END >= CURDATE())) AND (PARENT_ID=0) GROUP BY `id_article` ORDER BY `DATE_CREATION` DESC', self::WHERE_VISIBLE_CLAUSE));
   }
 
 
@@ -61,7 +61,7 @@ class ArticlesMultipleTimingsLoaderSqlTest
                         'id_categorie' => '',
                         'event_date' => '2011-03-15',
                         'id_bib' => 0]);
-    $this->assertSelect(sprintf("LEFT JOIN `cms_article_timings` ON cms_article.id_article=cms_article_timings.article_id WHERE %s AND (EVENTS_DEBUT IS NOT NULL OR START IS NOT NULL) AND (EVENTS_FIN IS NOT NULL OR END IS NOT NULL) AND (left(EVENTS_DEBUT,10) <= '2011-03-15' OR left(START,10) <= '2011-03-15') AND (left(EVENTS_FIN,10) >= '2011-03-15' OR left(END,10) >= '2011-03-15') AND (PARENT_ID=0) GROUP BY `id_article` ORDER BY `DATE_CREATION` DESC",
+    $this->assertSelect(sprintf("LEFT JOIN `cms_article_timings` ON cms_article.id_article=cms_article_timings.article_id AND cms_article_timings.start >= NOW() WHERE %s AND (EVENTS_DEBUT IS NOT NULL OR START IS NOT NULL) AND (EVENTS_FIN IS NOT NULL OR END IS NOT NULL) AND (left(EVENTS_DEBUT,10) <= '2011-03-15' OR left(START,10) <= '2011-03-15') AND (left(EVENTS_FIN,10) >= '2011-03-15' OR left(END,10) >= '2011-03-15') AND (PARENT_ID=0) GROUP BY `id_article` ORDER BY `start` ASC, `events_debut` ASC",
                                 self::WHERE_VISIBLE_CLAUSE));
   }
 
@@ -69,7 +69,7 @@ class ArticlesMultipleTimingsLoaderSqlTest
   /** @test */
   public function withEventEndAfterSqlShouldFilterOnEventsFin() {
     $this->getArticles(['event_end_after' => '2011-03-15']);
-    $this->assertSelect(sprintf("LEFT JOIN `cms_article_timings` ON cms_article.id_article=cms_article_timings.article_id WHERE %s AND (EVENTS_FIN IS NOT NULL OR END IS NOT NULL) AND (left(EVENTS_FIN,10) >= '2011-03-15' OR left(END,10) >= '2011-03-15') AND (PARENT_ID=0) GROUP BY `id_article` ORDER BY `DATE_CREATION` DESC",  self::WHERE_VISIBLE_CLAUSE));
+    $this->assertSelect(sprintf("LEFT JOIN `cms_article_timings` ON cms_article.id_article=cms_article_timings.article_id AND cms_article_timings.start >= NOW() WHERE %s AND (EVENTS_FIN IS NOT NULL OR END IS NOT NULL) AND (left(EVENTS_FIN,10) >= '2011-03-15' OR left(END,10) >= '2011-03-15') AND (PARENT_ID=0) GROUP BY `id_article` ORDER BY `DATE_CREATION` DESC",  self::WHERE_VISIBLE_CLAUSE));
   }
 
 
@@ -80,7 +80,7 @@ class ArticlesMultipleTimingsLoaderSqlTest
                         'id_categorie' => '',
                         'event_date' => '2011-03',
                         'id_bib' => 0]);
-    $this->assertSelect(sprintf("LEFT JOIN `cms_article_timings` ON cms_article.id_article=cms_article_timings.article_id WHERE %s AND (EVENTS_DEBUT IS NOT NULL OR START IS NOT NULL) AND (EVENTS_FIN IS NOT NULL OR END IS NOT NULL) AND (left(EVENTS_DEBUT,7) <= '2011-03' OR left(START,7) <= '2011-03') AND (left(EVENTS_FIN,7) >= '2011-03' OR left(END,7) >= '2011-03') AND (PARENT_ID=0) GROUP BY `id_article` ORDER BY `DATE_CREATION` DESC",
+    $this->assertSelect(sprintf("LEFT JOIN `cms_article_timings` ON cms_article.id_article=cms_article_timings.article_id AND cms_article_timings.start >= NOW() WHERE %s AND (EVENTS_DEBUT IS NOT NULL OR START IS NOT NULL) AND (EVENTS_FIN IS NOT NULL OR END IS NOT NULL) AND (left(EVENTS_DEBUT,7) <= '2011-03' OR left(START,7) <= '2011-03') AND (left(EVENTS_FIN,7) >= '2011-03' OR left(END,7) >= '2011-03') AND (PARENT_ID=0) GROUP BY `id_article` ORDER BY `start` ASC, `events_debut` ASC",
                                 self::WHERE_VISIBLE_CLAUSE));
   }
 
@@ -93,7 +93,7 @@ class ArticlesMultipleTimingsLoaderSqlTest
                         'events_only' => true,
                         'event_date' => '2011-03',
                         'id_bib' => 0]);
-    $this->assertSelect(sprintf("LEFT JOIN `cms_article_timings` ON cms_article.id_article=cms_article_timings.article_id WHERE %s AND (EVENTS_DEBUT IS NOT NULL OR START IS NOT NULL) AND (EVENTS_FIN IS NOT NULL OR END IS NOT NULL) AND (left(EVENTS_DEBUT,7) <= '2011-03' OR left(START,7) <= '2011-03') AND (left(EVENTS_FIN,7) >= '2011-03' OR left(END,7) >= '2011-03') AND (PARENT_ID=0) GROUP BY `id_article` ORDER BY `DATE_CREATION` DESC",
+    $this->assertSelect(sprintf("LEFT JOIN `cms_article_timings` ON cms_article.id_article=cms_article_timings.article_id AND cms_article_timings.start >= NOW() WHERE %s AND (EVENTS_DEBUT IS NOT NULL OR START IS NOT NULL) AND (EVENTS_FIN IS NOT NULL OR END IS NOT NULL) AND (left(EVENTS_DEBUT,7) <= '2011-03' OR left(START,7) <= '2011-03') AND (left(EVENTS_FIN,7) >= '2011-03' OR left(END,7) >= '2011-03') AND (PARENT_ID=0) GROUP BY `id_article` ORDER BY `start` ASC, `events_debut` ASC",
                                 self::WHERE_VISIBLE_CLAUSE));
   }
 
@@ -107,7 +107,7 @@ class ArticlesMultipleTimingsLoaderSqlTest
                         'events_only' => true,
                         'event_date' => '2011-03',
                         'id_bib' => 0]);
-    $this->assertSelect(sprintf("LEFT JOIN `cms_article_timings` ON cms_article.id_article=cms_article_timings.article_id WHERE %s AND (EVENTS_DEBUT IS NOT NULL OR START IS NOT NULL) AND (EVENTS_FIN IS NOT NULL OR END IS NOT NULL) AND (left(EVENTS_DEBUT,7) <= '2011-03' OR left(START,7) <= '2011-03') AND (left(EVENTS_FIN,7) >= '2011-03' OR (left(END,7) >= '2011-03' AND END >= CURDATE())) AND (PARENT_ID=0) GROUP BY `id_article` ORDER BY `DATE_CREATION` DESC",
+    $this->assertSelect(sprintf("LEFT JOIN `cms_article_timings` ON cms_article.id_article=cms_article_timings.article_id AND cms_article_timings.start >= NOW() WHERE %s AND (EVENTS_DEBUT IS NOT NULL OR START IS NOT NULL) AND (EVENTS_FIN IS NOT NULL OR END IS NOT NULL) AND (left(EVENTS_DEBUT,7) <= '2011-03' OR left(START,7) <= '2011-03') AND (left(EVENTS_FIN,7) >= '2011-03' OR (left(END,7) >= '2011-03' AND END >= CURDATE())) AND (PARENT_ID=0) GROUP BY `id_article` ORDER BY `start` ASC, `events_debut` ASC",
                                 self::WHERE_VISIBLE_CLAUSE));
   }
 
@@ -117,7 +117,7 @@ class ArticlesMultipleTimingsLoaderSqlTest
     $this->getArticles(['event_date' => 'trololo',
                         'event_start_after' => 'test',
                         'event_end_after' => 'raté']);
-    $this->assertSelect(sprintf("LEFT JOIN `cms_article_timings` ON cms_article.id_article=cms_article_timings.article_id WHERE %s AND (PARENT_ID=0) GROUP BY `id_article` ORDER BY `DATE_CREATION` DESC",
+    $this->assertSelect(sprintf("LEFT JOIN `cms_article_timings` ON cms_article.id_article=cms_article_timings.article_id AND cms_article_timings.start >= NOW() WHERE %s AND (PARENT_ID=0) GROUP BY `id_article` ORDER BY `DATE_CREATION` DESC",
                                 self::WHERE_VISIBLE_CLAUSE));
   }
 }
-- 
GitLab


From cdc084d754c27eafc417d0159e68492f6ba5f944 Mon Sep 17 00:00:00 2001
From: Alex Arnaud <alex.arnaud@biblibre.com>
Date: Fri, 21 Feb 2025 11:28:39 +0100
Subject: [PATCH 3/4] RT fix

---
 library/Class/Article/Select.php            | 2 +-
 library/Class/Article/SelectWithTimings.php | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/library/Class/Article/Select.php b/library/Class/Article/Select.php
index 22feea5d098..3b0a903d4ff 100644
--- a/library/Class/Article/Select.php
+++ b/library/Class/Article/Select.php
@@ -288,7 +288,7 @@ class Class_Article_Select {
   }
 
 
-  protected function _orderAndLimit() {
+  protected function _orderAndLimit(): self {
     if(!$this->_select)
       return $this;
 
diff --git a/library/Class/Article/SelectWithTimings.php b/library/Class/Article/SelectWithTimings.php
index 9cb077731fb..02230ff6b8a 100644
--- a/library/Class/Article/SelectWithTimings.php
+++ b/library/Class/Article/SelectWithTimings.php
@@ -86,7 +86,7 @@ class Class_Article_SelectWithTimings extends Class_Article_Select {
   }
 
 
-  protected function _orderAndLimit()
+  protected function _orderAndLimit(): self
   {
     if ($this->getSortOrder() == 'EventDebut')
       $this->_select->order(['start', 'events_debut']);
-- 
GitLab


From bebe4cfaeb57c4f0b58e4a576e8a2c153422179e Mon Sep 17 00:00:00 2001
From: Alex Arnaud <alex.arnaud@biblibre.com>
Date: Fri, 21 Feb 2025 14:25:12 +0100
Subject: [PATCH 4/4] hotline#211010 : Version file

---
 VERSIONS_HOTLINE/211010 | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 VERSIONS_HOTLINE/211010

diff --git a/VERSIONS_HOTLINE/211010 b/VERSIONS_HOTLINE/211010
new file mode 100644
index 00000000000..280eace798b
--- /dev/null
+++ b/VERSIONS_HOTLINE/211010
@@ -0,0 +1 @@
+- correctif #211010 : Agenda : tri des articles par ordre du prochain évènement.
\ No newline at end of file
-- 
GitLab