From 2e22ce4e3016ae91c0d0ba16f43702dfb37d736d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9rome=20Perrin?= <jerome@nexedi.com>
Date: Fri, 30 Nov 2007 12:22:41 +0000
Subject: [PATCH] support a list as local_sort_id

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@17919 20353a03-c40f-0410-a6d1-a30d3c3de9de
---
 product/CMFCategory/Category.py              | 36 ++++++++++++++++----
 product/CMFCategory/tests/testCMFCategory.py | 15 ++++++++
 2 files changed, 44 insertions(+), 7 deletions(-)

diff --git a/product/CMFCategory/Category.py b/product/CMFCategory/Category.py
index 12b0aa716f..cd542be595 100644
--- a/product/CMFCategory/Category.py
+++ b/product/CMFCategory/Category.py
@@ -250,7 +250,9 @@ class Category(Folder):
 
           local_sort_id     - When using the default preorder traversal, sort
                               objects of the same depth by comparing their
-                              'local_sort_id' property.
+                              'local_sort_id' property. local_sort_id can be a
+                              list, in this case properties are compared in the
+                              same order than this list.
 
           Renderer parameters are also supported here.
       """
@@ -263,8 +265,17 @@ class Category(Folder):
 
       child_value_list = self.objectValues(self.allowed_types)
       if local_sort_id:
-        local_sort_method = lambda a, b: cmp(a.getProperty(local_sort_id, 0),
-                                             b.getProperty(local_sort_id, 0))
+        if isinstance(local_sort_id, (tuple, list)):
+          def sort_method(a, b):
+            for sort_id in local_sort_id:
+              diff = cmp(a.getProperty(sort_id, 0), b.getProperty(sort_id, 0))
+              if diff != 0:
+                return diff
+            return 0
+          local_sort_method = sort_method
+        else:
+          local_sort_method = lambda a, b: cmp(a.getProperty(local_sort_id, 0),
+                                               b.getProperty(local_sort_id, 0))
       if local_sort_method:
         # sort objects at the current level
         child_value_list = list(child_value_list)
@@ -272,8 +283,8 @@ class Category(Folder):
 
       if recursive:
         for c in child_value_list:
-          # Do not global pass sort parameters intentionally, because sorting
-          # needs to be done only at the end of recursive calls.
+          # Do not pass sort_on / sort_order parameters intentionally, because
+          # sorting needs to be done only at the end of recursive calls.
           value_list.extend(c.getCategoryChildValueList(recursive=1,
                                        is_self_excluded=0,
                                        include_if_child=include_if_child,
@@ -758,7 +769,9 @@ class BaseCategory(Category):
           
           local_sort_id     - When using the default preorder traversal, sort
                               objects of the same depth by comparing their
-                              'local_sort_id' property.
+                              'local_sort_id' property. local_sort_id can be a
+                              list, in this case properties are compared in the
+                              same order than this list.
           
           Renderer parameters are also supported here.
 
@@ -770,7 +783,16 @@ class BaseCategory(Category):
 
       child_value_list = self.objectValues(self.allowed_types)
       if local_sort_id:
-        local_sort_method = lambda a, b: cmp(a.getProperty(local_sort_id, 0),
+        if isinstance(local_sort_id, (tuple, list)):
+          def sort_method(a, b):
+            for sort_id in local_sort_id:
+              diff = cmp(a.getProperty(sort_id, 0), b.getProperty(sort_id, 0))
+              if diff != 0:
+                return diff
+            return 0
+          local_sort_method = sort_method
+        else:
+          local_sort_method = lambda a, b: cmp(a.getProperty(local_sort_id, 0),
                                              b.getProperty(local_sort_id, 0))
       if local_sort_method:
         # sort objects at the current level
diff --git a/product/CMFCategory/tests/testCMFCategory.py b/product/CMFCategory/tests/testCMFCategory.py
index e534012335..d683df770c 100644
--- a/product/CMFCategory/tests/testCMFCategory.py
+++ b/product/CMFCategory/tests/testCMFCategory.py
@@ -899,6 +899,21 @@ class TestCMFCategory(ERP5TypeTestCase):
     self.assertEquals(list(c1.getCategoryChildValueList(
                               local_sort_id='int_index')), [c12, c11, c111])
 
+    # local_sort_id can be a list, in this case document are sorted with the
+    # first sort_id in the list, then the second, and so on.
+
+    # When we use those category properties:
+    #        int_index     title
+    #   c1                   C
+    #   c2                   B
+    #   c3      1            A
+    c1.setIntIndex(None)
+    c2.setIntIndex(None)
+    # and we sort on int_index then title, we should have this order:
+    self.assertEquals(list(bc.getCategoryChildValueList(
+                          local_sort_id=['int_index', 'title'])),
+                      [c2, c1, c12, c11, c111, c3])
+
   
   def test_25_getCategoryChildItemList_base_parameter(self):
     pc = self.getCategoriesTool()
-- 
2.30.9