Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
erp5
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Laurent S
erp5
Commits
e7fd1555
Commit
e7fd1555
authored
Nov 30, 2011
by
Julien Muchembled
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
New Base.skinSuper method to reuse code from lower-priority skins
Purpose is to reduce code duplication.
parent
4e66566f
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
89 additions
and
52 deletions
+89
-52
product/ERP5Type/Base.py
product/ERP5Type/Base.py
+12
-0
product/ERP5Type/patches/CMFCoreSkinnable.py
product/ERP5Type/patches/CMFCoreSkinnable.py
+55
-52
product/ERP5Type/patches/CMFCoreSkinsTool.py
product/ERP5Type/patches/CMFCoreSkinsTool.py
+3
-0
product/ERP5Type/tests/testCachedSkinsTool.py
product/ERP5Type/tests/testCachedSkinsTool.py
+19
-0
No files found.
product/ERP5Type/Base.py
View file @
e7fd1555
...
...
@@ -59,6 +59,7 @@ from Products.ERP5Type import _dtmldir
from
Products.ERP5Type
import
PropertySheet
from
Products.ERP5Type
import
interfaces
from
Products.ERP5Type
import
Permissions
from
Products.ERP5Type.patches.CMFCoreSkinnable
import
SKINDATA
,
skinResolve
from
Products.ERP5Type.Utils
import
UpperCase
from
Products.ERP5Type.Utils
import
convertToUpperCase
,
convertToMixedCase
from
Products.ERP5Type.Utils
import
createExpressionContext
,
simple_decorator
...
...
@@ -2976,6 +2977,17 @@ class Base( CopyContainer,
if
fallback_script_id
is
not
None
:
return
getattr
(
self
,
fallback_script_id
)
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'skinSuper'
)
def
skinSuper
(
self
,
skin
,
id
):
self
.
pdb
()
if
id
[:
1
]
!=
'_'
and
id
[:
3
]
!=
'aq_'
:
skin_info
=
SKINDATA
.
get
(
thread
.
get_ident
())
if
skin_info
is
not
None
:
object
=
skinResolve
(
self
.
getPortalObject
(),
(
skin_info
[
0
],
skin
),
id
)
if
object
is
not
None
:
return
object
.
__of__
(
self
)
raise
AttributeError
(
id
)
# Predicate handling
security
.
declareProtected
(
Permissions
.
AccessContentsInformation
,
'asPredicate'
)
def
asPredicate
(
self
,
script_id
=
None
):
...
...
product/ERP5Type/patches/CMFCoreSkinnable.py
View file @
e7fd1555
...
...
@@ -30,6 +30,18 @@ from Acquisition import aq_base
during the same request.
"""
def
_initializeCache
(
skin_tool
,
skin_folder_id_list
):
skin_list
=
{}
for
skin_folder_id
in
skin_folder_id_list
[::
-
1
]:
try
:
skin_folder
=
getattr
(
skin_tool
,
skin_folder_id
)
except
AttributeError
:
LOG
(
__name__
,
WARNING
,
'Skin folder %s is in selection list'
' but does not exist.'
%
skin_folder_id
)
else
:
skin_list
.
update
(
dict
.
fromkeys
(
skin_folder
.
objectIds
(),
skin_folder_id
))
return
skin_list
def
CMFCoreSkinnableSkinnableObjectManager_initializeCache
(
self
):
'''
Initialize the cache on portal skins.
...
...
@@ -40,23 +52,50 @@ def CMFCoreSkinnableSkinnableObjectManager_initializeCache(self):
portal_skins
=
portal_skins
.
aq_base
skin_selection_mapping
=
{}
for
selection_name
,
skin_folder_id_string
in
portal_skins
.
_getSelections
().
iteritems
():
skin_list
=
{}
skin_folder_id_list
=
skin_folder_id_string
.
split
(
','
)
skin_folder_id_list
.
reverse
()
for
skin_folder_id
in
skin_folder_id_list
:
skin_folder
=
getattr
(
portal_skins
,
skin_folder_id
,
None
)
if
skin_folder
is
not
None
:
for
skin_id
in
skin_folder
.
objectIds
():
skin_list
[
skin_id
]
=
skin_folder_id
else
:
LOG
(
'__getattr__'
,
WARNING
,
'Skin folder %s is in selection list '
\
'but does not exist.'
%
(
skin_folder_id
,
))
skin_selection_mapping
[
selection_name
]
=
skin_list
skin_selection_mapping
[
selection_name
]
=
_initializeCache
(
portal_skins
,
skin_folder_id_string
.
split
(
','
))
portal_skins
.
_v_skin_location_list
=
skin_selection_mapping
return
skin_selection_mapping
Skinnable
.
SkinnableObjectManager
.
initializeCache
=
CMFCoreSkinnableSkinnableObjectManager_initializeCache
def
skinResolve
(
self
,
selection
,
name
):
try
:
portal_skins
=
aq_base
(
self
.
portal_skins
)
except
AttributeError
:
raise
AttributeError
,
name
try
:
skin_selection_mapping
=
portal_skins
.
_v_skin_location_list
reset
=
False
except
AttributeError
:
LOG
(
__name__
,
DEBUG
,
'Initial skin cache fill.'
' This should not happen often. Current thread id:%X'
%
get_ident
())
skin_selection_mapping
=
self
.
initializeCache
()
reset
=
True
while
True
:
try
:
skin_folder_id
=
skin_selection_mapping
[
selection
][
name
]
except
KeyError
:
if
selection
in
skin_selection_mapping
or
\
isinstance
(
selection
,
basestring
):
return
skin_list
=
portal_skins
.
_getSelections
()[
selection
[
0
]].
split
(
','
)
skin_selection_mapping
[
selection
]
=
skin_list
=
_initializeCache
(
portal_skins
,
skin_list
[
1
+
skin_list
.
index
(
selection
[
1
]):])
try
:
skin_folder_id
=
skin_list
[
name
]
except
KeyError
:
return
reset
=
True
try
:
return
aq_base
(
getattr
(
getattr
(
portal_skins
,
skin_folder_id
),
name
))
except
AttributeError
:
if
reset
:
return
# We cannot find a document referenced in the cache, so reset it.
skin_selection_mapping
=
self
.
initializeCache
()
reset
=
True
def
CMFCoreSkinnableSkinnableObjectManager___getattr__
(
self
,
name
):
'''
Looks for the name in an object with wrappers that only reach
...
...
@@ -71,46 +110,10 @@ def CMFCoreSkinnableSkinnableObjectManager___getattr__(self, name):
return
resolve
[
name
]
except
KeyError
:
if
name
not
in
ignore
:
try
:
portal_skins
=
aq_base
(
self
.
portal_skins
)
except
AttributeError
:
raise
AttributeError
,
name
try
:
skin_selection_mapping
=
portal_skins
.
_v_skin_location_list
except
AttributeError
:
LOG
(
'Skinnable Monkeypatch __getattr__'
,
DEBUG
,
'Initial skin cache fill. This should not happen often. Current thread id:%X'
%
(
get_ident
(),
))
skin_selection_mapping
=
self
.
initializeCache
()
try
:
skin_folder_id
=
skin_selection_mapping
[
skin_selection_name
][
name
]
except
KeyError
:
pass
else
:
object
=
getattr
(
getattr
(
portal_skins
,
skin_folder_id
),
name
,
None
)
if
object
is
not
None
:
resolve
[
name
]
=
object
.
aq_base
return
resolve
[
name
]
else
:
# We cannot find a document referenced in the cache.
# Try to find if there is any other candidate in another
# skin folder of lower priority.
selection_dict
=
portal_skins
.
_getSelections
()
candidate_folder_id_list
=
selection_dict
[
skin_selection_name
].
split
(
','
)
previous_skin_folder_id
=
skin_selection_mapping
[
skin_selection_name
][
name
]
del
skin_selection_mapping
[
skin_selection_name
][
name
]
if
previous_skin_folder_id
in
candidate_folder_id_list
:
previous_skin_index
=
candidate_folder_id_list
.
index
(
previous_skin_folder_id
)
candidate_folder_id_list
=
candidate_folder_id_list
[
previous_skin_index
+
1
:]
for
candidate_folder_id
in
candidate_folder_id_list
:
candidate_folder
=
getattr
(
portal_skins
,
candidate_folder_id
,
None
)
if
candidate_folder
is
not
None
:
object
=
getattr
(
candidate_folder
,
name
,
None
)
if
object
is
not
None
:
skin_selection_mapping
[
skin_selection_name
][
name
]
=
candidate_folder_id
resolve
[
name
]
=
object
.
aq_base
return
resolve
[
name
]
else
:
LOG
(
'__getattr__'
,
WARNING
,
'Skin folder %s is in selection list '
\
'but does not exist.'
%
(
candidate_folder_id
,
))
object
=
skinResolve
(
self
,
skin_selection_name
,
name
)
if
object
is
not
None
:
resolve
[
name
]
=
object
return
object
ignore
[
name
]
=
None
raise
AttributeError
(
name
)
...
...
product/ERP5Type/patches/CMFCoreSkinsTool.py
View file @
e7fd1555
...
...
@@ -55,6 +55,9 @@ def CMFCoreSkinsTool__updateCacheEntry(self, container_id, object_id):
skin_location_list
=
getattr
(
self
,
'_v_skin_location_list'
,
None
)
if
skin_location_list
is
not
None
:
self
.
_p_changed
=
1
for
selection_name
in
skin_location_list
.
keys
():
if
not
isinstance
(
selection_name
,
basestring
):
del
skin_location_list
[
selection_name
]
for
selection_name
,
skin_folder_id_string
in
self
.
_getSelections
().
iteritems
():
skin_folder_id_list
=
skin_folder_id_string
.
split
(
','
)
if
container_id
in
skin_folder_id_list
:
...
...
product/ERP5Type/tests/testCachedSkinsTool.py
View file @
e7fd1555
...
...
@@ -30,6 +30,7 @@ import unittest
import
transaction
from
Products.ERP5Type.tests.ERP5TypeTestCase
import
ERP5TypeTestCase
from
Products.ERP5Type.tests.utils
import
createZODBPythonScript
from
AccessControl.SecurityManagement
import
newSecurityManager
TESTED_SKIN_FOLDER_ID
=
'custom'
...
...
@@ -131,5 +132,23 @@ class TestCachedSkinsTool(ERP5TypeTestCase):
self
.
assertTrue
(
getattr
(
skinnable_object
,
searched_object_other_id
,
None
)
is
not
None
)
self
.
assertTrue
(
getattr
(
tested_skin_folder
,
searched_object_other_id
,
None
)
is
not
None
)
def
test_05_skinSuper
(
self
):
tested_skin_folder
=
self
.
getTestedSkinFolder
()
script_id
=
'Base_getOwnerId'
ob
=
self
.
portal
.
portal_activities
orig
=
getattr
(
ob
,
script_id
)()
self
.
assertEqual
(
orig
,
'ERP5TypeTestCase'
)
try
:
script
=
createZODBPythonScript
(
tested_skin_folder
,
script_id
,
''
,
'return not %r'
%
orig
)
self
.
assertEqual
(
getattr
(
ob
,
script_id
)(),
not
orig
)
script
.
ZPythonScript_edit
(
''
,
'return context.skinSuper(%r, %r)()'
%
(
TESTED_SKIN_FOLDER_ID
,
script_id
))
self
.
assertEqual
(
getattr
(
ob
,
script_id
)(),
orig
)
self
.
getSkinsTool
().
erp5_core
.
_delObject
(
script_id
)
self
.
assertRaises
(
AttributeError
,
getattr
(
ob
,
script_id
))
finally
:
transaction
.
abort
()
if
__name__
==
'__main__'
:
unittest
.
main
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment