X-Git-Url: https://scm.cri.minesparis.psl.eu/git/MosaicDocument.git/blobdiff_plain/155c6ba3d7e8e9693d30b3cf70f591f0153610b6..99b3ba92670e19c1f86f5de83b8e6bbe4fdc297f:/Products/MosaicDocument/MosaicBlockInformation.py diff --git a/Products/MosaicDocument/MosaicBlockInformation.py b/Products/MosaicDocument/MosaicBlockInformation.py new file mode 100755 index 0000000..444c791 --- /dev/null +++ b/Products/MosaicDocument/MosaicBlockInformation.py @@ -0,0 +1,306 @@ +# -*- coding: utf-8 -*- +# (c) 2003 Centre de Recherche en Informatique ENSMP Fontainebleau +# (c) 2003 Benoît PIN +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as published +# by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. +# + + +from OFS.ObjectManager import ObjectManager +from OFS.SimpleItem import SimpleItem +from OFS.PropertyManager import PropertyManager +from Globals import InitializeClass, DTMLFile +from Products.CMFCore.TypesTool import FactoryTypeInformation +from Products.CMFCore.utils import getToolByName +from types import InstanceType +import config + +from AccessControl import ClassSecurityInfo, Unauthorized +from Products.CMFCore.permissions import View, ModifyPortalContent, \ + ManagePortal + + +class RuleError(Exception) : + def __init__(self, errorMessage) : + self.errorMessage = errorMessage + + def __str__(self) : + return self.errorMessage + +addMosaicBlockInformationForm = DTMLFile('dtml/addMosaicBlockForm', globals()) + +def addMosaicBlockInformation(self, id=None, blockType = '', metaFti = None, REQUEST=None) : + """Add a MosaicBlock""" + if blockType : + metaFtis = config.getDefaultBlockMetaFtis() + if not metaFtis.has_key(blockType) : + raise ValueError, "Unknown block type : %s" % blockType + else : + blockFti = metaFtis[blockType] + elif metaFti : + blockFti = metaFti.copy() + else : + raise AttributeError, """ + You must specify a default block type or a meta factory type information + """ + if not id : + id = blockFti['id'] + else : + blockFti['id'] = id + + mb = MosaicBlockInformation(blockFti) + self._setObject(id, mb) + + if REQUEST is not None: + REQUEST.RESPONSE.redirect('%s/manage_main' % self.absolute_url()) + return id + + +class MosaicBlockInformation(ObjectManager, FactoryTypeInformation) : + """Base Block""" + + meta_type = "Mosaic Block Information" + + isPrincipiaFolderish = 0 + + security = ClassSecurityInfo() + + _fti_properties = FactoryTypeInformation._properties + + _properties = (_fti_properties[:5] + + ({'id':'template', 'type': 'string', 'mode':'w', + 'label':'Template'}, + {'id':'notify_wf', 'type': 'boolean', 'mode':'w', + 'label':'Notify Workflow Created'},) + + _fti_properties[5:] + ) + + + manage_slotsForm = DTMLFile('dtml/slotsForm', globals()) + manage_rulesForm = DTMLFile('dtml/rulesForm', globals()) + manage_options = (FactoryTypeInformation.manage_options[:1] + + ({'label' : 'Slots', 'action' : 'manage_slotsForm'},) + + ({'label' : 'Rules', 'action' : 'manage_rulesForm'},) + + FactoryTypeInformation.manage_options[1:] + ) + + + def __init__(self, blockFti) : + FactoryTypeInformation.__init__(self, **blockFti) + + # init Slots informations + for slot in blockFti['slots'] : + slotInfo = SlotInfo(slot['id'], slot['type'], slotArgs = slot['args']) + self._setObject(slot['id'], slotInfo) + + # init Rules informations + for rule in blockFti['rules'] : + ruleInfo = RuleInfo(rule['blockType'], rule['maxNbInstance'], rule['allowMove'], rule['mode']) + self._setObject(rule['blockType'], ruleInfo) + + + security.declareProtected(ManagePortal, 'manage_addSlot') + def manage_addSlot(self, id, type, REQUEST=None) : + """Add a slot contruction information""" + slotInfo = SlotInfo(id, type) + self._setObject(id, slotInfo) + if REQUEST : + return REQUEST.RESPONSE.redirect(REQUEST['HTTP_REFERER']) + + security.declareProtected(ManagePortal, 'saveSlots') + def saveSlots(self, REQUEST=None, **kw) : + """Save slots from ZMI form""" + # actualy the ':record' casting in an input form create an InstanceType instead of DictType + kw.update(REQUEST.form) + dicArgsListItems = [ (argKey, kw[argKey]) for argKey in kw.keys() if type(kw[argKey]) == InstanceType ] + for key, args in dicArgsListItems : + slotToEdit = getattr(self, key) + if key != args['id'] : + self.manage_renameObject(key, args['id']) + slotToEdit.id = args['id'] + slotToEdit.type = args['type'] + if REQUEST is not None: + return REQUEST.RESPONSE.redirect(REQUEST['URL1'] + '/manage_slotsForm?manage_tabs_message=Saved changes.') + + security.declareProtected(ManagePortal, 'deleteSlots') + def deleteSlots(self, slotSelection=None, REQUEST=None) : + """Delete slots""" + if slotSelection : + self.manage_delObjects(ids=slotSelection) + if REQUEST : + return REQUEST.RESPONSE.redirect(REQUEST['HTTP_REFERER']) + + + + security.declareProtected(ManagePortal, 'manage_addSlot') + def manage_addRule(self, id, maxNbInstance, allowMove, mode, REQUEST=None) : + """Add a rule information""" + ruleInfo = RuleInfo(id, maxNbInstance, allowMove, mode) + self._setObject(id, ruleInfo) + if REQUEST : + return REQUEST.RESPONSE.redirect(REQUEST['HTTP_REFERER']) + + security.declareProtected(ManagePortal, 'saveSlots') + def saveRules(self, REQUEST=None, **kw) : + """Save rules from ZMI form""" + # actualy the ':record' casting in an input form create an InstanceType instead of DictType + kw.update(REQUEST.form) + dicArgsListItems = [ (argKey, kw[argKey]) for argKey in kw.keys() if type(kw[argKey]) == InstanceType ] + for key, kwords in dicArgsListItems : + ruleToEdit = getattr(self, key) + if key != kwords['id'] : + self.manage_renameObject(key, kwords['id']) + #slotToEdit.id = args['id'] + kwArgs = {} + + for k in kwords.keys() : #kwords is an InstanceType not a DictType... + kwArgs[k] = kwords[k] + + ruleToEdit.edit(**kwArgs) + + if REQUEST is not None: + return REQUEST.RESPONSE.redirect(REQUEST['URL1'] + '/manage_rulesForm?manage_tabs_message=Saved changes.') + + security.declareProtected(ManagePortal, 'deleteSlots') + def deleteRules(self, ruleSelection=None, REQUEST=None) : + """Delete rules""" + if ruleSelection : + self.manage_delObjects(ids=ruleSelection) + if REQUEST : + return REQUEST.RESPONSE.redirect(REQUEST['HTTP_REFERER']) + + + def _checkConstructionRules(self, container) : + """Check """ + typesTool = getToolByName(self, 'mosaic_tool') + container_ti = typesTool.getTypeInfo(container) + rules = container_ti.objectValues(['Rule Information',]) + container_subObjs = container.objectValues() + + if self.getId() in map(lambda x : x.getId(), rules) : + maxNbInstance = container_ti._getOb(self.getId()).maxNbInstance + if maxNbInstance : + if maxNbInstance <= len( [sob for sob in container_subObjs if sob.portal_type == self.getId()]) : + raise RuleError, "It's not allowed to add a new '%s', the quota is exceeded in this block" % \ + self.getId() + else : + return 1 + else : + return 1 # pas de limitation du nombre d'instance + else : + raise RuleError, "'%s' block type construction is not authorized in '%s'" % \ + (self.getId(), container_ti.getId()) + + + security.declarePublic('isConstructionAllowed') + def isConstructionAllowed ( self, container ): + """ + check factory, permissions and rules + """ + if FactoryTypeInformation.isConstructionAllowed ( self, container ) : + typesTool = getToolByName(self, 'mosaic_tool') + container_ti = typesTool.getTypeInfo(container) + if hasattr(container_ti, '_checkConstructionRules') : + try : + return self._checkConstructionRules(container) + except RuleError : + return 0 + return 1 + else : + return 0 + + + def _getFactoryMethod(self, container, check_security=1): + # pas très beau cette surcharge mais + # FactoryTypeInformation ne vérifie pas la + # possibilité de création par un appel à isConstructionAllowed. + + if not check_security : return FactoryTypeInformation._getFactoryMethod(self, container) + + if self.isConstructionAllowed(container) : + return FactoryTypeInformation._getFactoryMethod(self, container) + + raise Unauthorized, ('Cannot create %s' % self.getId()) + + + security.declarePrivate('_constructInstance') + def _constructInstance(self, container, id, *args, **kw): + ob = super(MosaicBlockInformation, self)._constructInstance(container, id, *args, **kw) + typesTool = getToolByName(self, 'portal_types') + + # Add and init slots in block + for si in self.objectValues(['Slot Information',]) : + kw = {} + for key, value in si.propertyItems() : + kw[key] = value + + typesTool.constructContent(si.type, ob, si.id, **kw) + return ob + + +InitializeClass(MosaicBlockInformation) + +def addSlotInfo(dispatcher, id, type, slotArgs) : + pass + +class SlotInfo(SimpleItem, PropertyManager) : + """Encapsulate slot informations""" + meta_type="Slot Information" + _properties = () + property_extensible_schema__ = 1 + + manage_propertiesForm = DTMLFile('dtml/properties', globals()) + manage_options = PropertyManager.manage_options + SimpleItem.manage_options + + def __init__(self, id, type, slotArgs={}) : + self.id = id + self.type = type + for argId in slotArgs.keys() : + self.manage_addProperty(argId, slotArgs[argId]['value'], slotArgs[argId]['type']) + +InitializeClass(PropertyManager) + + +def addRuleInfo(dispatcher, id, **kw) : + pass + +class RuleInfo(SimpleItem): + """Encapsulate block rule informations""" + meta_type = 'Rule Information' + + def __init__(self, id, maxNbInstance, + allowMove, mode, + allowMoveUpAndDown=0, + allowMoveRightAndLeft=0) : + self.id = id # actualy Block Type name info + self.maxNbInstance = maxNbInstance + if allowMove : + self.allowMoveUpAndDown = 1 + self.allowMoveRightAndLeft = 1 + else : + self.allowMoveUpAndDown = allowMoveUpAndDown + self.allowMoveRightAndLeft = allowMoveRightAndLeft + self.allowMove = allowMove + self.mode = mode + + security = ClassSecurityInfo() + + security.declareProtected(ManagePortal, 'edit') + def edit(self, **kw) : + for key in kw.keys() : + if hasattr(self, key) : + setattr(self, key, kw[key]) + +InitializeClass(RuleInfo)