Example #1
0
    def _edit(self, text):
        """ Edit the Document and cook the body.
        """
        self._size = len(text)

        text_format = self.text_format
        if not text_format:
            text_format = self.text_format

        if text_format != 'html':
            normalizer = queryUtility(ILinebreakNormalizer)

            if normalizer is not None:
                self.text = normalizer.normalizeIncoming(self, text)
            else:
                self.text = text
        else:
            self.text = text

        if text_format == 'html':
            self.cooked_text = text
        elif text_format == 'plain':
            self.cooked_text = html_quote(text).replace('\n', '<br />')
        elif text_format == 'restructured-text':
            self.cooked_text = ReST(text,
                                    initial_header_level=self._rest_level)
        else:
            self.cooked_text = stx2html(text, level=self._stx_level, header=0)
Example #2
0
    def CookedBody(self, stx_level=None, setlevel=0, rest_level=None):
        """ Get the "cooked" (ready for presentation) form of the text.

        The prepared basic rendering of an object.  For Documents, this
        means pre-rendered structured text, or what was between the
        <BODY> tags of HTML.

        If the format is html, and 'stx_level' or 'rest_level' are not 
        passed in or is the same as the object's current settings, return 
        the cached cooked text.  Otherwise, recook.  If we recook and 
        'setlevel' is true, then set the recooked text and stx_level or 
        rest_level on the object.
        """
        if ((self.text_format == 'html' or self.text_format == 'plain' or
             (stx_level is None) or (stx_level == self._stx_level)) and
            ((rest_level is None) or (rest_level == self._rest_level))):
            return self.cooked_text
        elif rest_level is not None:
            cooked = ReST(self.text, initial_header_level=rest_level)
            if setlevel:
                self._rest_level = rest_level
                self.cooked_text = cooked
            return cooked
        else:
            cooked = stx2html(self.text, level=stx_level, header=0)
            if setlevel:
                self._stx_level = stx_level
                self.cooked_text = cooked
            return cooked
Example #3
0
def structured_text_view(context, request):
    """ Filesystem-based STX view
    """
    result = stx2html(context.source)
    response = Response(result)
    response.content_type = 'text/html'
    return response
Example #4
0
    def _edit(self, text):
        """ Edit the Document and cook the body.
        """
        self._size = len(text)

        text_format = self.text_format
        if not text_format:
            text_format = self.text_format

        if text_format != 'html':
            normalizer = queryUtility(ILinebreakNormalizer)
            
            if normalizer is not None:
                self.text = normalizer.normalizeIncoming(self, text)
            else:
                self.text = text
        else:
            self.text = text
            
        if text_format == 'html':
            self.cooked_text = text
        elif text_format == 'plain':
            self.cooked_text = html_quote(text).replace('\n', '<br />')
        elif text_format == 'restructured-text':
            self.cooked_text = ReST(text, initial_header_level=self._rest_level)
        else:
            self.cooked_text = stx2html(text, level=self._stx_level, header=0)
Example #5
0
    def CookedBody(self, stx_level=None, setlevel=0, rest_level=None):
        """ Get the "cooked" (ready for presentation) form of the text.

        The prepared basic rendering of an object.  For Documents, this
        means pre-rendered structured text, or what was between the
        <BODY> tags of HTML.

        If the format is html, and 'stx_level' or 'rest_level' are not 
        passed in or is the same as the object's current settings, return 
        the cached cooked text.  Otherwise, recook.  If we recook and 
        'setlevel' is true, then set the recooked text and stx_level or 
        rest_level on the object.
        """
        if (
            (self.text_format == 'html' or self.text_format == 'plain'
            or (stx_level is None)
            or (stx_level == self._stx_level))
            and 
            ((rest_level is None) 
            or (rest_level == self._rest_level))
            ):
            return self.cooked_text
        elif rest_level is not None:
            cooked = ReST(self.text, initial_header_level=rest_level)
            if setlevel:
                self._rest_level = rest_level
                self.cooked_text = cooked
            return cooked
        else:
            cooked = stx2html(self.text, level=stx_level, header=0)
            if setlevel:
                self._stx_level = stx_level
                self.cooked_text = cooked
            return cooked
Example #6
0
 def cook(self):
     if not hasattr(self, '_v_cooked'):
         self._v_cooked = stx2html(self.raw, level=1, header=0)
     return self._v_cooked
Example #7
0
class FactoryTool(PloneBaseTool, UniqueObject, SimpleItem):
    """ """
    id = 'portal_factory'
    meta_type = 'Plone Factory Tool'
    toolicon = 'skins/plone_images/add_icon.png'
    security = ClassSecurityInfo()
    isPrincipiaFolderish = 0

    manage_options = (
        ({'label': 'Overview', 'action': 'manage_overview'},
         {'label': 'Documentation', 'action': 'manage_docs'},
         {'label': 'Factory Types', 'action': 'manage_portal_factory_types'}) +
        SimpleItem.manage_options)

    wwwpath = os.path.join(package_home(GLOBALS), 'www')

    security.declareProtected(ManagePortal, 'manage_overview')
    manage_overview = PageTemplateFile(
        os.path.join(wwwpath, 'portal_factory_manage_overview'), globals())
    manage_overview.__name__ = 'manage_overview'
    manage_overview._need__name__ = 0

    security.declareProtected(ManagePortal, 'manage_portal_factory_types')
    manage_portal_factory_types = PageTemplateFile(
        os.path.join(wwwpath, 'portal_factory_manage_types'), globals())
    manage_portal_factory_types.__name__ = 'manage_portal_factory_types'
    manage_portal_factory_types._need__name__ = 0

    manage_main = manage_overview

    security.declareProtected(ManagePortal, 'manage_docs')
    manage_docs = PageTemplateFile(
        os.path.join(wwwpath, 'portal_factory_manage_docs'), globals())
    manage_docs.__name__ = 'manage_docs'

    f = open(os.path.join(wwwpath, 'portal_factory_docs.stx'), 'r')
    _docs = f.read()
    f.close()
    _docs = stx2html(_docs)

    @security.public
    def docs(self):
        """Returns FactoryTool docs formatted as HTML"""
        return self._docs

    def getFactoryTypes(self):
        if not hasattr(self, '_factory_types'):
            self._factory_types = {}
        return self._factory_types

    @security.protected(ManagePortal)
    def manage_setPortalFactoryTypes(self, REQUEST=None, listOfTypeIds=None):
        """Set the portal types that should use the factory."""
        if listOfTypeIds is not None:
            dict = {}
            for l in listOfTypeIds:
                dict[l] = 1
        elif REQUEST is not None:
            dict = REQUEST.form
        if dict is None:
            dict = {}
        self._factory_types = {}
        types_tool = getToolByName(self, 'portal_types')
        for t in types_tool.listContentTypes():
            if t in dict:
                self._factory_types[t] = 1
        self._p_changed = 1
        if REQUEST:
            REQUEST.RESPONSE.redirect('manage_main')

    def doCreate(self, obj, id=None, **kw):
        # Create a real object from a temporary object.
        if self.isTemporary(obj=obj):
            if id is not None:
                id = id.strip()
            if not id:
                if hasattr(obj, 'getId') and callable(getattr(obj, 'getId')):
                    id = obj.getId()
                else:
                    id = getattr(obj, 'id', None)
            # get the ID of the TempFolder
            type_name = aq_parent(aq_inner(obj)).id
            folder = aq_parent(aq_parent(aq_parent(aq_inner(obj))))
            folder.invokeFactory(id=id, type_name=type_name)
            obj = getattr(folder, id)

            # give ownership to currently authenticated member if not anonymous
            # TODO is this necessary?
            membership_tool = getToolByName(self, 'portal_membership')
            if not membership_tool.isAnonymousUser():
                member = membership_tool.getAuthenticatedMember()
                obj.changeOwnership(member.getUser(), 1)
            if hasattr(aq_base(obj), 'manage_afterPortalFactoryCreate'):
                obj.manage_afterPortalFactoryCreate()
        return obj

    def _fixRequest(self):
        # Our before_publishing_traverse call mangles URL0.
        # This fixes up the REQUEST.
        # Everything seems to work without this method being called at all...
        factory_info = self.REQUEST.get(FACTORY_INFO, None)
        if not factory_info:
            return
        stack = factory_info['stack']
        FACTORY_URL = self.REQUEST.URL
        URL = '/'.join([FACTORY_URL] + stack)
        self.REQUEST.set('URL', URL)

        url_list = URL.split('/')
        n = 0
        while len(url_list) > 0 and url_list[-1] != '':
            self.REQUEST.set('URL%d' % n, '/'.join(url_list))
            url_list = url_list[:-1]
            n = n + 1

        # BASE1 is the url of the Zope App object
        n = len(self.REQUEST._steps) + 2
        base = FACTORY_URL
        for part in stack:
            base = '%s/%s' % (base, part)
            self.REQUEST.set('BASE%d' % n, base)
            n += 1
        # TODO fix URLPATHn, BASEPATHn here too

    def isTemporary(self, obj):
        # Check to see if an object is temporary.
        ob = aq_base(aq_parent(aq_inner(obj)))
        return hasattr(ob, 'meta_type') \
            and ob.meta_type == TempFolder.meta_type

    def __before_publishing_traverse__(self, other, REQUEST):

        if REQUEST.get(FACTORY_INFO, None):
            del REQUEST[FACTORY_INFO]

        stack = REQUEST.get('TraversalRequestNameStack')
        # convert from unicode if necessary (happens in Epoz for some weird
        # reason)
        stack = [str(s) for s in stack]

        # need 2 more things on the stack at least for portal_factory to
        # kick in:
        #    (1) a type, and (2) an id
        if len(stack) < 2:  # ignore
            return

        # Keep track of how many path elements we want to eat
        gobbled_length = 0

        type_name = stack[-1]
        types_tool = getToolByName(self, 'portal_types')
        # make sure this is really a type name
        if type_name not in types_tool.listContentTypes():
            return  # nope -- do nothing

        gobbled_length += 1

        id = stack[-2]
        intended_parent = aq_parent(self)
        if hasattr(intended_parent, id):
            return  # do normal traversal via __bobo_traverse__

        gobbled_length += 1

        # about to create an object

        # before halting traversal, check for method aliases
        # stack should be [...optional stuff..., id, type_name]
        key = len(stack) >= 3 and stack[-3] or '(Default)'
        ti = types_tool.getTypeInfo(type_name)
        method_id = ti and ti.queryMethodID(key)
        if method_id:
            if key != '(Default)':
                del(stack[-3])
            if method_id != '(Default)':
                stack.insert(-2, method_id)
                gobbled_length += 1
            REQUEST._hacked_path = 1
        else:
            gobbled_length += 1

        # Pevent further traversal if we are doing a normal factory request,
        # but allow it if there is a traversal sub-path beyond the (edit)
        # view on the content item. In this case, portal_factory will not
        # be responsible for rendering the object.
        if len(stack) <= gobbled_length:
            REQUEST.set('TraversalRequestNameStack', [])

        stack.reverse()
        factory_info = {'stack': stack}
        REQUEST.set(FACTORY_INFO, factory_info)

    def __bobo_traverse__(self, REQUEST, name):
        # __bobo_traverse__ can be invoked directly by a restricted_traverse
        # method call in which case the traversal stack will not have been
        # cleared by __before_publishing_traverse__
        name = str(name)  # fix unicode weirdness
        types_tool = getToolByName(self, 'portal_types')
        if name not in types_tool.listContentTypes():
            # not a type name -- do the standard thing
            return getattr(self, name)
        # a type name -- return a temp folder
        return self._getTempFolder(str(name))

    @security.public
    def __call__(self, *args, **kwargs):
        """call method"""
        self._fixRequest()
        factory_info = self.REQUEST.get(FACTORY_INFO, {})
        stack = factory_info['stack']
        type_name = stack[0]
        id = stack[1]

        # do a passthrough if parent contains the id
        if id in aq_parent(self):
            return aq_parent(self).restrictedTraverse(
                '/'.join(stack[1:]))(*args, **kwargs)

        tempFolder = self._getTempFolder(type_name)
        # Mysterious hack that fixes some problematic interactions with
        # SpeedPack:
        #   Get the first item in the stack by explicitly calling __getitem__
        temp_obj = tempFolder.__getitem__(id)
        stack = stack[2:]
        if stack:
            try:
                obj = temp_obj.restrictedTraverse('/'.join(stack))
            except AttributeError:
                raise NotFound

            # Mimic URL traversal, sort of
            if getattr(aq_base(obj), 'index_html', None):
                obj = obj.restrictedTraverse('index_html')
            else:
                obj = getattr(obj, 'GET', obj)

        else:
            obj = temp_obj
        return mapply(obj, self.REQUEST.args, self.REQUEST,
                      call_object, 1, missing_name,
                      dont_publish_class, self.REQUEST, bind=1)

    index_html = None  # call __call__, not index_html

    def _getTempFolder(self, type_name):
        factory_info = self.REQUEST.get(FACTORY_INFO, {})
        tempFolder = factory_info.get(type_name, None)
        if tempFolder is not None:
            tempFolder = aq_inner(tempFolder).__of__(self)
            return tempFolder

        # make sure we can add an object of this type to the temp folder
        types_tool = getToolByName(self, 'portal_types')
        if type_name not in types_tool.TempFolder.allowed_content_types:
            # update allowed types for tempfolder
            types_tool.TempFolder.allowed_content_types = \
                (types_tool.listContentTypes())

        tempFolder = TempFolder(type_name).__of__(self)

        factory_info[type_name] = tempFolder
        self.REQUEST.set(FACTORY_INFO, factory_info)
        return tempFolder
Example #8
0
def structured_text(txt):
    return stx2html(txt,
                    level=int(os.environ.get('STX_DEFAULT_LEVEL', 3)),
                    header=0)
 def convert(self, orig, data, level=None, **kwargs):
     if level is None:
         level = STX_LEVEL
     data.setData(stx2html(orig, level=level, header=0))
     return data
Example #10
0
 def cook(self):
     if not hasattr(self, '_v_cooked'):
         self._v_cooked = stx2html(self.raw, level=1, header=0)
     return self._v_cooked
Example #11
0
 def convert(self, orig, data, level=None, **kwargs):
     if level is None:
         level = STX_LEVEL
     data.setData(stx2html(orig, level=level, header=0))
     return data
Example #12
0
class FormController(UniqueObject, SimpleItemWithProperties):
    """ """

    security = ClassSecurityInfo()

    id = 'portal_form_controller'
    title = 'Manages form validation and post-validation actions'
    meta_type = 'Form Controller Tool'

    manage_options = ((
        {
            'label': 'Overview',
            'action': 'manage_overview'
        },
        {
            'label': 'Documentation',
            'action': 'manage_docs'
        },
        {
            'label': 'Validation',
            'action': 'manage_formValidatorsForm'
        },
        {
            'label': 'Actions',
            'action': 'manage_formActionsForm'
        },
        {
            'label': 'Purge',
            'action': 'manage_purgeForm'
        },
    ) + SimpleItemWithProperties.manage_options)

    security.declareProtected(ManagePortal, 'manage_overview')
    manage_overview = PageTemplateFile(os.path.join('www', 'manage_overview'),
                                       globals())
    manage_overview.__name__ = 'manage_overview'
    manage_overview._need__name__ = 0

    security.declareProtected(ManagePortal, 'manage_docs')
    manage_docs = PageTemplateFile(os.path.join('www', 'manage_docs'),
                                   globals())
    manage_docs.__name__ = 'manage_docs'

    security.declareProtected(ManagePortal, 'manage_formActionsForm')
    manage_formActionsForm = PageTemplateFile(
        os.path.join('www', 'manage_formActionsForm'), globals())
    manage_formActionsForm.__name__ = 'manage_formActionsForm'

    security.declareProtected(ManagePortal, 'manage_formValidatorsForm')
    manage_formValidatorsForm = PageTemplateFile(
        os.path.join('www', 'manage_formValidatorsForm'), globals())
    manage_formValidatorsForm.__name__ = 'manage_formValidatorsForm'

    security.declareProtected(ManagePortal, 'manage_purgeForm')
    manage_purgeForm = PageTemplateFile(
        os.path.join('www', 'manage_purgeForm'), globals())
    manage_purgeForm.__name__ = 'manage_purgeForm'

    # some aliases
    security.declareProtected(ManagePortal, 'manage_main')
    manage_main = manage_overview

    security.declareProtected(ManagePortal, 'index_html')
    index_html = None

    wwwpath = os.path.join(package_home(fc_globals), 'www')
    f = open(os.path.join(wwwpath, 'docs.stx'), 'r')
    _docs = f.read()
    f.close()
    _docs = stx2html(_docs)

    def __init__(self):
        self.actions = FormActionContainer()
        self.validators = FormValidatorContainer()

    security.declarePublic('docs')

    def docs(self):
        """Returns FormController docs formatted as HTML"""
        return self._docs

    def view(self, REQUEST, RESPONSE):
        """Invokes the default view."""
        return self.__call__(REQUEST, RESPONSE)

    def __call__(self, REQUEST, RESPONSE):
        """Invokes the default view."""
        if RESPONSE is not None:
            RESPONSE.redirect('%s/manage_main' % self.absolute_url())

    def _checkId(self, id):
        """See if an id is valid CMF/Plone id"""
        portal = getToolByName(self, 'portal_url').getPortalObject()
        if not id:
            return 'Empty id'
        s = bad_id(id)
        if s:
            return '\'%s\' is not a valid id' % (id)
        # extra checks for Plone sites
        if portal.__class__.__name__ == 'PloneSite':
            props = getToolByName(portal, 'portal_properties', None)
            if props is not None:
                if hasattr(props, 'site_properties') and \
                   hasattr(props.site_properties, 'invalid_ids'):
                    if id in props.site_properties.invalid_ids:
                        return '\'%s\' is a reserved id' % (id)

    # Web-accessible methods
    security.declareProtected(ManagePortal, 'listActionTypes')

    def listActionTypes(self):
        """Return a list of available action types."""
        keys = form_action_types.keys()
        keys.sort()
        action_types = []
        for k in keys:
            action_types.append(form_action_types.get(k))
        return action_types

    def validActionTypes(self):
        return form_action_types.keys()

    security.declareProtected(ManagePortal, 'listContextTypes')

    def listContextTypes(self):
        """Return list of possible types for template context objects"""
        types_tool = getToolByName(self, 'portal_types')
        return types_tool.listContentTypes()

    security.declareProtected(ManagePortal, 'listFormValidators')

    def listFormValidators(self, override=None, **kwargs):
        """Return a list of existing validators.  Validators can be filtered by
           specifying required attributes via kwargs"""
        return self.validators.getFiltered(**kwargs)

    security.declareProtected(ManagePortal, 'listFormActions')

    def listFormActions(self, override=None, **kwargs):
        """Return a list of existing actions.  Actions can be filtered by
           specifying required attributes via kwargs"""
        return self.actions.getFiltered(**kwargs)

    security.declareProtected(ManagePortal, 'manage_editFormValidators')

    def manage_editFormValidators(self, REQUEST):
        """Process form validator edit form"""
        self._editFormValidators(self.validators, REQUEST)
        return REQUEST.RESPONSE.redirect(self.absolute_url() +
                                         '/manage_formValidatorsForm')

    security.declarePrivate('_editFormValidators')

    def _editFormValidators(self, container, REQUEST):
        for k in REQUEST.form.keys():
            if k.startswith('old_object_id_'):
                n = k[len('old_object_id_'):]
                old_object_id = REQUEST.form.get('old_object_id_' + n)
                old_context_type = REQUEST.form.get('old_context_type_' + n)
                old_button = REQUEST.form.get('old_button_' + n)
                container.delete(
                    FormValidatorKey(old_object_id, old_context_type,
                                     old_button, self))
                object_id = REQUEST.form.get('object_id_' + n)
                context_type = REQUEST.form.get('context_type_' + n)
                button = REQUEST.form.get('button_' + n)
                validators = REQUEST.form.get('validators_' + n)
                container.set(
                    FormValidator(object_id, context_type, button, validators,
                                  self))

    # Method for programmatically adding validators
    security.declareProtected(ManagePortal, 'addFormValidators')

    def addFormValidators(self, object_id, context_type, button, validators):
        self.validators.set(
            FormValidator(object_id, context_type, button, validators, self))

    security.declareProtected(ManagePortal, 'manage_addFormValidators')

    def manage_addFormValidators(self, REQUEST):
        """Process form validator add form"""
        self._addFormValidators(self.validators, REQUEST)
        return REQUEST.RESPONSE.redirect(self.absolute_url() +
                                         '/manage_formValidatorsForm')

    security.declarePrivate('_addFormValidators')

    def _addFormValidators(self, container, REQUEST):
        object_id = REQUEST.form.get('new_object_id')
        context_type = REQUEST.form.get('new_context_type')
        button = REQUEST.form.get('new_button')
        validators = REQUEST.form.get('new_validators')
        container.set(
            FormValidator(object_id, context_type, button, validators, self))

    security.declareProtected(ManagePortal, 'manage_delFormValidators')

    def manage_delFormValidators(self, REQUEST):
        """Process form validator delete form"""
        self._delFormValidators(self.validators, REQUEST)
        return REQUEST.RESPONSE.redirect(self.absolute_url() +
                                         '/manage_formValidatorsForm')

    security.declarePrivate('_delFormValidators')

    def _delFormValidators(self, container, REQUEST):
        for k in REQUEST.form.keys():
            if k.startswith('del_id_'):
                n = k[len('del_id_'):]
                old_object_id = REQUEST.form.get('old_object_id_' + n)
                old_context_type = REQUEST.form.get('old_context_type_' + n)
                old_button = REQUEST.form.get('old_button_' + n)
                container.delete(
                    FormValidatorKey(old_object_id, old_context_type,
                                     old_button, self))

    security.declareProtected(ManagePortal, 'manage_editFormActions')

    def manage_editFormActions(self, REQUEST):
        """Process form action edit form"""
        self._editFormActions(self.actions, REQUEST)
        return REQUEST.RESPONSE.redirect(self.absolute_url() +
                                         '/manage_formActionsForm')

    security.declarePrivate('_editFormActions')

    def _editFormActions(self, container, REQUEST):
        for k in REQUEST.form.keys():
            if k.startswith('old_object_id_'):
                n = k[len('old_object_id_'):]
                old_object_id = REQUEST.form.get('old_object_id_' + n)
                old_status = REQUEST.form.get('old_status_' + n)
                old_context_type = REQUEST.form.get('old_context_type_' + n)
                old_button = REQUEST.form.get('old_button_' + n)
                container.delete(
                    FormActionKey(old_object_id, old_status, old_context_type,
                                  old_button, self))
                object_id = REQUEST.form.get('object_id_' + n)
                status = REQUEST.form.get('status_' + n)
                context_type = REQUEST.form.get('context_type_' + n)
                button = REQUEST.form.get('button_' + n)
                action_type = REQUEST.form.get('action_type_' + n)
                action_arg = REQUEST.form.get('action_arg_' + n)
                container.set(
                    FormAction(object_id, status, context_type, button,
                               action_type, action_arg, self))

    # Method for programmatically adding actions
    security.declareProtected(ManagePortal, 'addFormAction')

    def addFormAction(self, object_id, status, context_type, button,
                      action_type, action_arg):
        self.actions.set(
            FormAction(object_id, status, context_type, button, action_type,
                       action_arg, self))

    security.declareProtected(ManagePortal, 'manage_addFormAction')

    def manage_addFormAction(self, REQUEST):
        """Process form action add form"""
        self._addFormAction(self.actions, REQUEST)
        return REQUEST.RESPONSE.redirect(self.absolute_url() +
                                         '/manage_formActionsForm')

    security.declarePrivate('_addFormAction')

    def _addFormAction(self, container, REQUEST):
        object_id = REQUEST.form.get('new_object_id')
        status = REQUEST.form.get('new_status').strip()
        context_type = REQUEST.form.get('new_context_type').strip()
        button = REQUEST.form.get('new_button').strip()
        action_type = REQUEST.form.get('new_action_type').strip()
        action_arg = REQUEST.form.get('new_action_arg').strip()
        container.set(
            FormAction(object_id, status, context_type, button, action_type,
                       action_arg, self))

    security.declareProtected(ManagePortal, 'manage_delFormActions')

    def manage_delFormActions(self, REQUEST):
        """Process form action delete form"""
        self._delFormActions(self.actions, REQUEST)
        return REQUEST.RESPONSE.redirect(self.absolute_url() +
                                         '/manage_formActionsForm')

    security.declarePrivate('_delFormActions')

    def _delFormActions(self, container, REQUEST):
        for k in REQUEST.form.keys():
            if k.startswith('del_id_'):
                n = k[len('del_id_'):]
                old_object_id = REQUEST.form.get('old_object_id_' + n)
                old_status = REQUEST.form.get('old_status_' + n)
                old_context_type = REQUEST.form.get('old_context_type_' + n)
                old_button = REQUEST.form.get('old_button_' + n)
                container.delete(
                    FormActionKey(old_object_id, old_status, old_context_type,
                                  old_button, self))

    def getValidators(self, id, context_type, button):
        return self.validators.match(id, context_type, button)

    def getAction(self, id, status, context_type, button):
        return self.actions.match(id, status, context_type, button)

    def getState(self, obj, is_validator):
        id = obj.id
        controller_state = self.REQUEST.get('controller_state', None)
        # The variable 'env' is a dictionary that is passed
        # along using record variables on forms so that you can keep
        # some state between different forms.
        env = self.REQUEST.get('form_env', {})
        # Make sure controller_state is something generated by us, not something submitted via POST or GET
        if controller_state and getattr(controller_state, '__class__',
                                        None) != ControllerState:
            controller_state = None

        if not is_validator:
            # Construct a new controller state object or clear out the existing
            # one unless we are in a validator script.
            if controller_state is None:
                # XXX - errors={} shouldn't need to be set here, but without it
                # I encountered what looks like a weird Zope caching bug.
                # To reproduce, install CMFFormControllerDemo, go to portal_skins
                # then to CMFFormControllerDemo, then click on test_form and
                # click the Test tab.  Submit the form with an empty text box.
                # Now back up to the ZMI and click the Test tab again.  If
                # errors={} is left out in the line below, ControllerState.__init__()
                # gets called with errors set to a non-empty value (more
                # precisely, it is set to the value that was in REQUEST.controller_state.
                # Yikes!
                controller_state = ControllerState(errors={})
            else:
                # clear out values we don't want to carry over from previous states.
                controller_state.setStatus('success')
                controller_state.setNextAction(None)
                #controller_state.setButton(None)
            controller_state.set(id=id, context=obj.__parent__)
        else:
            if controller_state is None:
                raise ValueError, 'No controller state available.  ' + \
                    'This commonly occurs when a ControllerValidator (.vpy) ' + \
                    'script is invoked via the validation mechanism in the ' + \
                    'portal_form tool.  If you are using a package designed to ' + \
                    'be used with portal_form, you are probably inadvertently ' + \
                    'invoking a validator designed for use with CMFFormController (e.g. validate_id).  ' + \
                    'If you are using a package designed to be used with CMFFormController, you probably ' + \
                    'have a "portal_form" in your URL that needs to be removed.'
        controller_state._setValidating(is_validator)
        # Pass environment along, with care so we don't override
        # existing variables.
        for k, v in env.items():
            controller_state.kwargs.setdefault(k, v)
        self.REQUEST.set('controller_state', controller_state)
        return controller_state

    def validate(self, controller_state, REQUEST, validators, argdict=None):
        if argdict is None:
            args = REQUEST.args
            kwargs = REQUEST
        else:
            args = ()
            if REQUEST is None:
                kwargs = argdict
            else:
                kwargs = {}
                for k in REQUEST.keys():
                    if k in ('SESSION', ):
                        continue
                    kwargs[k] = REQUEST[k]
                kwargs.update(argdict)
        context = controller_state.getContext()
        if validators is None:
            REQUEST.set('controller_state', controller_state)
            return controller_state
        for v in validators:
            REQUEST.set('controller_state', controller_state)
            if controller_state.hasValidated(v):
                continue
            try:
                # make sure validator exists
                obj = context.restrictedTraverse(v, default=None)
                if obj is None:
                    raise ValueError, 'Unable to find validator %s\n' % str(v)
                if not getattr(obj, 'is_validator', 1):
                    raise ValueError, '%s is not a CMFFormController validator' % str(
                        v)
                REQUEST = controller_state.getContext().REQUEST
                controller_state = mapply(obj,
                                          args,
                                          kwargs,
                                          call_object,
                                          1,
                                          missing_name,
                                          dont_publish_class,
                                          REQUEST,
                                          bind=1)
                if controller_state is None or getattr(
                        controller_state, '__class__',
                        None) != ControllerState:
                    raise ValueError, 'Validator %s did not return the state object' % str(
                        v)
                controller_state._addValidator(v)
            except ValidationError, e:
                # if a validator raises a ValidatorException, execution of
                # validators is halted and the controller_state is set to
                # the controller_state embedded in the exception
                controller_state = e.controller_state
                state_class = getattr(controller_state, '__class__', None)
                if state_class != ControllerState:
                    raise Exception, 'Bad ValidationError state (type = %s)' % str(
                        state_class)
                break
            state_class = getattr(controller_state, '__class__', None)
            if state_class != ControllerState:
                raise Exception, 'Bad validator return type from validator %s (%s)' % (
                    str(v), str(state_class))
            REQUEST.set('controller_state', controller_state)

        REQUEST.set('controller_state', controller_state)
        return controller_state
Example #13
0
def structured_text(txt):
    return stx2html(txt,
                level=int(os.environ.get('STX_DEFAULT_LEVEL',3)),
                header=0)