Commit 93da8ed3 authored by Vincent Pelletier's avatar Vincent Pelletier

erp5_web: Take effective_date into account when looking content up.

effective_date, when defined, prevents a document from being visible even
if it is in the correct workflow state.
Note that this is orthogonal with workflow states: a document which must
not be visible should not be in a workflow state which makes it visible to
begin with. effective_date only affects website-style document listing and
lookup.
parent ea784a3b
...@@ -50,7 +50,9 @@ ...@@ -50,7 +50,9 @@
</item> </item>
<item> <item>
<key> <string>_body</string> </key> <key> <string>_body</string> </key>
<value> <string>"""\n <value> <string encoding="cdata"><![CDATA[
"""\n
This script is part of ERP5 Web\n This script is part of ERP5 Web\n
\n \n
ERP5 Web is a business template of ERP5 which provides a way\n ERP5 Web is a business template of ERP5 which provides a way\n
...@@ -70,6 +72,7 @@ ...@@ -70,6 +72,7 @@
fix acquisition issues within the _aq_dynamic\n fix acquisition issues within the _aq_dynamic\n
lookup from WebSection class.\n lookup from WebSection class.\n
"""\n """\n
from Products.ZSQLCatalog.SQLCatalog import SimpleQuery, ComplexQuery\n
if portal is None: portal = context.getPortalObject()\n if portal is None: portal = context.getPortalObject()\n
portal_catalog = portal.portal_catalog\n portal_catalog = portal.portal_catalog\n
# The list of portal types here should be large enough to include\n # The list of portal types here should be large enough to include\n
...@@ -85,30 +88,50 @@ if validation_state is None:\n ...@@ -85,30 +88,50 @@ if validation_state is None:\n
validation_state = (\'released\', \'released_alive\', \'published\', \'published_alive\',\n validation_state = (\'released\', \'released_alive\', \'published\', \'published_alive\',\n
\'shared\', \'shared_alive\', \'public\', \'validated\')\n \'shared\', \'shared_alive\', \'public\', \'validated\')\n
\n \n
if effective_date is None:\n
if now is None:\n
now = DateTime()\n
effective_date = ComplexQuery(\n
SimpleQuery(effective_date=None),\n
SimpleQuery(effective_date=now, comparison_operator=\'<=\'),\n
logical_operator=\'or\',\n
)\n
\n
# Note: In sorts, NULL is considered lesser than non-NULL. So in descending\n
# sort, NULLs will be listed after non-NULLs, which is perfect for\n
# effective_date, which defines the date at which content becomes effective.\n
# None (NULL) effective date hence means "effective since infinite in te past".\n
base_sort = ((\'effective_date\', \'descending\'), )\n
\n
# Search the catalog for all documents matching the reference\n # Search the catalog for all documents matching the reference\n
# this will only return documents which are accessible by the user\n # this will only return documents which are accessible by the user\n
web_page_list = portal_catalog(reference=name,\n web_page_list = portal_catalog(reference=name,\n
effective_date=effective_date,\n
portal_type=valid_portal_type_list,\n portal_type=valid_portal_type_list,\n
validation_state=validation_state,\n validation_state=validation_state,\n
language=(language, \'\'),\n language=(language, \'\'),\n
sort_on=[(\'language\', \'descending\'), ],\n sort_on=((\'language\', \'descending\'), ) + base_sort,\n
limit=1,\n limit=1,\n
**kw)\n **kw)\n
\n \n
if len(web_page_list) == 0 and language != \'en\':\n if len(web_page_list) == 0 and language != \'en\':\n
# Search again with English as a fallback.\n # Search again with English as a fallback.\n
web_page_list = portal_catalog(reference=name,\n web_page_list = portal_catalog(reference=name,\n
effective_date=effective_date,\n
portal_type=valid_portal_type_list,\n portal_type=valid_portal_type_list,\n
validation_state=validation_state,\n validation_state=validation_state,\n
language=\'en\',\n language=\'en\',\n
sort_on=base_sort,\n
limit=1,\n limit=1,\n
**kw)\n **kw)\n
\n \n
if len(web_page_list) == 0:\n if len(web_page_list) == 0:\n
# Search again without the language\n # Search again without the language\n
web_page_list = portal_catalog(reference=name,\n web_page_list = portal_catalog(reference=name,\n
effective_date=effective_date,\n
portal_type=valid_portal_type_list,\n portal_type=valid_portal_type_list,\n
validation_state=validation_state,\n validation_state=validation_state,\n
sort_on=base_sort,\n
limit=1,\n limit=1,\n
**kw)\n **kw)\n
\n \n
...@@ -122,11 +145,13 @@ else:\n ...@@ -122,11 +145,13 @@ else:\n
\n \n
# return the web page\n # return the web page\n
return web_page\n return web_page\n
</string> </value>
]]></string> </value>
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>name, portal=None, language=None, validation_state=None, **kw</string> </value> <value> <string>name, portal=None, language=None, validation_state=None, effective_date=None, now=None, **kw</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
......
...@@ -50,7 +50,9 @@ ...@@ -50,7 +50,9 @@
</item> </item>
<item> <item>
<key> <string>_body</string> </key> <key> <string>_body</string> </key>
<value> <string>"""\n <value> <string encoding="cdata"><![CDATA[
"""\n
This script is part of ERP5 Web\n This script is part of ERP5 Web\n
\n \n
ERP5 Web is a business template of ERP5 which provides a way\n ERP5 Web is a business template of ERP5 which provides a way\n
...@@ -97,6 +99,7 @@ ...@@ -97,6 +99,7 @@
\n \n
- Display only the latest version and the appropriate language.\n - Display only the latest version and the appropriate language.\n
"""\n """\n
from Products.ZSQLCatalog.SQLCatalog import SimpleQuery, ComplexQuery\n
from zExceptions import Unauthorized\n from zExceptions import Unauthorized\n
\n \n
try:\n try:\n
...@@ -125,6 +128,16 @@ try:\n ...@@ -125,6 +128,16 @@ try:\n
if \'sort_on\' not in kw:\n if \'sort_on\' not in kw:\n
# XXX Do not sort by default, as it increases query time\n # XXX Do not sort by default, as it increases query time\n
kw[\'sort_on\'] = [(\'int_index\', \'DESC\'), (\'reference\', \'DESC\')]\n kw[\'sort_on\'] = [(\'int_index\', \'DESC\'), (\'reference\', \'DESC\')]\n
\n
if effective_date is None:\n
if now is None:\n
now = DateTime()\n
effective_date = ComplexQuery(\n
SimpleQuery(effective_date=None),\n
SimpleQuery(effective_date=now, comparison_operator=\'<=\'),\n
logical_operator=\'or\',\n
)\n
kw[\'effective_date\'] = effective_date\n
\n \n
if not all_versions:\n if not all_versions:\n
return current_section.WebSection_zGetDocumentValueList(language=language,\n return current_section.WebSection_zGetDocumentValueList(language=language,\n
...@@ -138,11 +151,13 @@ try:\n ...@@ -138,11 +151,13 @@ try:\n
\n \n
except Unauthorized:\n except Unauthorized:\n
return []\n return []\n
</string> </value>
]]></string> </value>
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>language=None, validation_state=None, all_languages=None, all_versions=None, src__=0, **kw</string> </value> <value> <string>language=None, validation_state=None, all_languages=None, all_versions=None, effective_date=None, now=None, src__=0, **kw</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
......
1110 1111
...@@ -32,6 +32,7 @@ import re ...@@ -32,6 +32,7 @@ import re
import unittest import unittest
from AccessControl import Unauthorized from AccessControl import Unauthorized
from Testing import ZopeTestCase from Testing import ZopeTestCase
from DateTime import DateTime
from Products.ERP5Type.TransactionalVariable import getTransactionalVariable from Products.ERP5Type.TransactionalVariable import getTransactionalVariable
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from Products.ERP5Type.tests.utils import DummyLocalizer from Products.ERP5Type.tests.utils import DummyLocalizer
...@@ -1361,6 +1362,76 @@ Hé Hé Hé!""", page.asText().strip()) ...@@ -1361,6 +1362,76 @@ Hé Hé Hé!""", page.asText().strip())
[x['translated_title'] for x in site_map]) [x['translated_title'] for x in site_map])
self.assertEqual(None, site_map[0]['subsection']) self.assertEqual(None, site_map[0]['subsection'])
def test_future_publication_date_not_visible(self):
portal = self.portal
reference = 'test_future_publication_date_not_visible'
newContent = portal.web_page_module.newContent
date1 = DateTime()
date2 = date1 + 1
date3 = date2 + 1
date4 = date3 + 1
def new(**kw):
result = newContent(
portal_type='Web Page',
reference=reference,
**kw
)
self.tic()
result.publish()
self.tic()
return result
document1 = new(version=1)
document2 = new(version=2, effective_date=date2)
# Some more documents which should never be visible.
# Bind them to local variables for quicker debugging, if needed.
# Later than document2.
document3 = new(version=3, effective_date=date4)
# Like document1, but not published
document4 = newContent(
portal_type='Web Page',
reference=reference,
)
# Like document2, but not published
document5 = newContent(
portal_type='Web Page',
reference=reference,
effective_date=date2,
)
self.tic()
site = portal.web_site_module.newContent(
portal_type='Web Site',
)
site.publish()
section = site.newContent(
portal_type='Web Section',
)
section.setCriterionProperty('reference')
section.setCriterion(
'reference',
max='',
identity=[reference],
min='',
)
self.tic()
self.assertEqual(document1.getValidationState(), 'published')
self.assertEqual(document2.getValidationState(), 'published')
self.assertEqual(document3.getValidationState(), 'published')
self.assertEqual(document4.getValidationState(), 'draft')
self.assertEqual(document5.getValidationState(), 'draft')
def check(expected_document, date):
document = section.WebSection_getDocumentValue(reference, now=date)
self.assertNotEqual(document, None)
self.assertEqual(document.getPath(), expected_document.getPath())
document_list = section.WebSection_getDocumentValueList(now=date)
self.assertEqual(len(document_list), 1)
self.assertEqual(document_list[0].getPath(), expected_document.getPath())
# document1 is visible & listed before date2
check(document1, date1)
# document2 is visible & listed at and above date2
check(document2, date2)
check(document2, date3)
class TestERP5WebWithSimpleSecurity(ERP5TypeTestCase): class TestERP5WebWithSimpleSecurity(ERP5TypeTestCase):
""" """
......
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