Back to index

plone3  3.1.7
ControllerState.py
Go to the documentation of this file.
00001 import Globals
00002 import AccessControl
00003 from AccessControl import ClassSecurityInfo
00004 from Products.CMFCore.utils import getToolByName
00005 from FormAction import FormAction
00006 from globalVars import ANY_CONTEXT, ANY_BUTTON
00007 
00008 class ControllerState(AccessControl.Role.RoleManager):
00009     security = ClassSecurityInfo()
00010     security.declareObjectPublic()
00011     security.setDefaultAccess('allow')
00012 
00013     id = None
00014 
00015     # The status variable used for determining state transitions
00016     status = 'success'
00017 
00018     # A set of i18n-friendly error messages.  Each key corresponds to a tuple
00019     # of the form (default_error_message, msgid), where msgid is used for i18n,
00020     # if present.
00021     errors = {}
00022 
00023     # The new context (use None if the context should remain the same)
00024     context = None
00025 
00026     # The button that was pressed (None if no named button was pressed)
00027     button = None
00028 
00029     # The default next action.  This can be overridden by values in the form
00030     # controller.
00031     next_action = None
00032 
00033     # A dict of variables.
00034     kwargs = {}
00035 
00036     # a dict of ids of validators already executed
00037     _validators = {}
00038 
00039     def __init__(self, id=None, context=None, button=None, status='success', \
00040                  errors={}, next_action=None, **kwargs):
00041         self.setId(id)
00042         self.setButton(button)
00043         self.setStatus(status)
00044         self.setErrors(errors)
00045         self.setContext(context)
00046         self.setKwargs(kwargs)
00047         self.setNextAction(next_action)
00048         self._is_validating = 0
00049         self._validators = {}
00050 
00051 
00052     def set(self, **kwargs):
00053         """Set state object properties"""
00054         if kwargs.has_key('id'):
00055             self.setId(kwargs['id'])
00056             del kwargs['id']
00057         if kwargs.has_key('button'):
00058             self.setButton(kwargs['button'])
00059             del kwargs['button']
00060         if kwargs.has_key('status'):
00061             self.setStatus(kwargs['status'])
00062             del kwargs['status']
00063         if kwargs.has_key('errors'):
00064             self.setErrors(kwargs['errors'])
00065             del kwargs['errors']
00066         if kwargs.has_key('context'):
00067             self.setContext(kwargs['context'])
00068             del kwargs['context']
00069         if kwargs.has_key('next_action'):
00070             self.setNextAction(kwargs['next_action'])
00071             del kwargs['next_action']
00072         self.kwargs.update(kwargs)
00073         return self
00074 
00075 
00076     def setError(self, id, message, msgid=None, new_status=None):
00077         """Add an error message to the current state object.  The new_status
00078         argument allows you to optionally change the object's status."""
00079         self.errors[id] = (message, msgid)
00080         if new_status:
00081             self.status = new_status
00082 
00083     def getError(self, id):
00084         """Return the error message associated with the form variable id"""
00085         err = self.errors.get(id, None)
00086         if err:
00087             return err[0]
00088         return None
00089 
00090     def getI18NError(self, id):
00091         """Return the error message and i18n msgid associated with the form
00092         variable id.  The return value is the tuple (errmsg, i18n_msgid)."""
00093         return self.errors.get(id, None)
00094 
00095     def getId(self):
00096         """Get the id of the calling script/page template"""
00097         return self.id
00098 
00099     def setId(self, id):
00100         """Set the id of the calling script/page template"""
00101         self.id = id
00102 
00103     def getButton(self):
00104         """Get the name of the named button pressed.  You can name a button NAME
00105         in a template by giving it the name form.button.NAME"""
00106         return self.button
00107 
00108     def setButton(self, button):
00109         """Set the name of the named button pressed.  You can name a button NAME
00110         in a template by giving it the name form.button.NAME"""
00111         self.button = button
00112 
00113     def getStatus(self):
00114         """Get the current status"""
00115         return self.status
00116 
00117     def setStatus(self, status):
00118         """Get the current status"""
00119         self.status = status
00120 
00121     def getErrors(self):
00122         """Return all errors in a dict of the form dict['name'] = errmsg"""
00123         err = {}
00124         for k,v in self.errors.items():
00125             # make allowances for old-style string errors
00126             if isinstance(v, basestring):
00127                 err[k] = v
00128             else:
00129                 err[k] = v[0]
00130         return err
00131 
00132     def getI18NErrors(self):
00133         """Return all errors in a dict of the form dict['name'] = (errmsg, i18n_msgid)"""
00134         err = {}
00135         for k,v in self.errors.items():
00136             # make allowances for old-style string errors
00137             if isinstance(v, basestring):
00138                 err[k] = (v, None)
00139             else:
00140                 err[k] = v
00141         return err
00142 
00143     def setErrors(self, errors):
00144         """Set the error dictionary.  The dictionary should have entries of the
00145         form dict['name'] = (errmsg, i18n_msgid).  The msgid can be None"""
00146         self.errors = {}
00147         # make allowances for old-style errors
00148         for k,v in errors.items():
00149             if isinstance(v, basestring):
00150                 self.errors[k] = (v, None)
00151             else:
00152                 self.errors[k] = v
00153 
00154     def getContext(self):
00155         """Get the context of the current form/script"""
00156         if self.context is None:
00157             return self.context
00158         return self.context[0]
00159         #return aq_inner(self.context)
00160 
00161     def setContext(self, context):
00162         """Set the context of the current form/script"""
00163         # Store the context in a list so that we don't nuke its acquisition chain.
00164         # This is kind of an evil hack, but since we aren't persisting
00165         # ControllerState objects, it shouldn't cause any big problems.
00166         self.context = [context]
00167         # self.context = context
00168 
00169     def getKwargs(self):
00170         """Get any extra arguments that should be passed along to the
00171         next template/script"""
00172         return self.kwargs
00173 
00174     def setKwargs(self, kwargs):
00175         """Set any extra arguments that should be passed along to the
00176         next template/script"""
00177         self.kwargs = kwargs
00178 
00179     def getNextAction(self):
00180         """Get the default next action (this action can be overridden in
00181         portal_form_controller).  The action will have the form
00182         {'action_type':action_type, 'args':args} where action_type is a string
00183         (from portal_form_controller.validActionTypes), and args is a string
00184         that will be passed to the constructor when generating an action object"""
00185         return self.next_action
00186 
00187     def setNextAction(self, action):
00188         """Set the default next action (this action can be overridden in
00189         portal_form_controller).  setNextAction can be called either with a
00190         dictionary argument of the form {'action_type':action_type, 'args':args}
00191         or with a string of the form 'action_type:args'.  Here action_type is a
00192         string (from form_controller.validActionTypes) and args is a string that
00193         will be passed to the constructor when generating an action object"""
00194         if action is None:
00195             self.next_action = action
00196             return
00197         if isinstance(action, dict):
00198             action_type = action['action_type']
00199             args = action['args']
00200         else:
00201             split_action = action.split(':',1)
00202             action_type = split_action[0].strip()
00203             if len(split_action) == 2:
00204                 args = split_action[1].strip()
00205             else:
00206                 args = None
00207         controller = getToolByName(self.getContext(), 'portal_form_controller')
00208         if not action_type in controller.validActionTypes():
00209             raise KeyError, 'Unknown action type %s\n' % action_type
00210         self.next_action = FormAction(self.getId(), self.getStatus(), ANY_CONTEXT, ANY_BUTTON, action_type, args, controller)
00211 
00212     # indicate that a validator has been executed
00213     def _addValidator(self, validator):
00214         self._validators[validator] = 1
00215 
00216     # remove a validator from the list of already-executed validators
00217     def clearValidator(self, validator):
00218         if self._validators.has_key(validator):
00219             del self._validators[validator]
00220 
00221     # clear the list of already-executed validators
00222     def clearValidators(self):
00223         self._validators = {}
00224 
00225     # see if given validators have been executed
00226     def hasValidated(self, validators=[]):
00227         if validators is None:
00228             validators = []
00229         elif not isinstance(validators, list):
00230             validators = [validators]
00231         for v in validators:
00232             if not self._validators.has_key(v):
00233                 return 0
00234         return 1
00235 
00236     def _setValidating(self, is_validating):
00237         self._is_validating = is_validating
00238 
00239     def _isValidating(self):
00240         return self._is_validating
00241 
00242     def __str__(self):
00243         return 'id = %s\nstatus = %s\nbutton=%s\nerrors=%s\ncontext=%s\nkwargs=%s\nnext_action=%s\n' % \
00244             (self.id, str(self.getStatus()), str(self.getButton()),
00245              str(self.getErrors()), repr(self.getContext()),
00246              str(self.kwargs), str(self.next_action))
00247 
00248 Globals.InitializeClass(ControllerState)