def is_restorable(self): parent = aq_parent(aq_inner(self.context)) if ITrashed.providedBy(parent): # Cannot restore an object when the parent is still trashed. return False if not getMultiAdapter( (self.context, self.context.REQUEST), IIsRestoreAllowedAdapter): return False return ITrashed.providedBy(self.context)
def getRawActionAdapter(self, *args, **kwargs): adapter_ids = self._old_getRawActionAdapter(*args, **kwargs) adapter_result = [] for adapter_id in adapter_ids: if not ITrashed.providedBy(self.get(adapter_id)): adapter_result.append(adapter_id) return tuple(adapter_result)
def prevent_accessing_trashed_content_after_traversal(event): context = filter(lambda item: IItem.providedBy(item), event.request.PARENTS)[0] if not ITrashed.providedBy(context): return if getSecurityManager().getUser().has_role('Manager'): IStatusMessage(event.request).addStatusMessage( _(u'statusmessage_content_trashed', default=u'The content "${title}" is trashed.', mapping={u'title': safe_unicode(context.Title())}), type='warning') return raise NotFound()
def restore(self, REQUEST, uuid): """Restore an item by uid. """ catalog = getToolByName(self.context, 'portal_catalog') brains = catalog({'UID': uuid, 'trashed': True}) if len(brains) != 1: raise BadRequest() obj = brains[0].getObject() parent = aq_parent(aq_inner(obj)) if ITrashed.providedBy(parent): IStatusMessage(self.request).addStatusMessage(_( u'statusmessage_content_restore_error_parent_trashed', default= (u'"${title}" cannot be restored because the parent container' u' "${parent}" is also trashed.' u' You need to restore the parent first.'), mapping={ u'title': safe_unicode(obj.Title()), u'parent': safe_unicode(parent.Title()) }), type='error') return self.request.response.redirect(self.context.absolute_url() + '/trash') trasher = Trasher(obj) if not trasher.is_restorable(): IStatusMessage(self.request).addStatusMessage(_( u'statusmessage_content_restore_not_allowed', default= (u'You are not allowed to restore "${title}".' u' You may need to change the workflow state of the parent content.' ), mapping={u'title': safe_unicode(obj.Title())}), type='error') return self.request.response.redirect(self.context.absolute_url() + '/trash') trasher.restore() IStatusMessage(self.request).addStatusMessage(_( u'statusmessage_content_restored', default=u'The content "${title}" has been restored.', mapping={u'title': safe_unicode(obj.Title())}), type='info') target_url = obj.restrictedTraverse('@@plone_context_state').view_url() self.request.response.redirect(target_url)
def test_ploneformgen_removes_trashed_fields(self, browser): form_folder = create(Builder('FormFolder')) reply_to = form_folder.get('replyto') self.assertIn(reply_to, form_folder._getFieldObjects()) browser.login().visit(form_folder) self.assertTrue(browser.find('Your E-Mail Address')) form_folder.manage_delObjects([reply_to.id]) transaction.commit() self.assertTrue(ITrashed.providedBy(reply_to)) self.assertNotIn(reply_to, form_folder._getFieldObjects()) browser.reload() self.assertFalse(browser.find('Your E-Mail Address'))
def is_sl_contentish(context): """This method returns True when the object is considered simplelayout contentish. Being simplelayout contentish means that the object, usually a block, has the same publishing cycle as the parent (page). This behavior may be recursive (e.g. files in filelistingblocks). An object is considered simplelayout contentish when: - it has no workflow and it is a simplelayout block - it has no workflow and the parent is a simplelayout block without workflow When a SL contentish object is deleted on the sender side (redaction), it is not directly deleted with a push job, since it is part of the content. When the SL container (page) is published, it will be removed. """ if IPloneSiteRoot.providedBy(context): # Abort recursion when site root reached. return False if HAS_FTW_TRASH and ITrashed.providedBy(context): return False if filter(lambda x, c=context: x.providedBy(c), sl_pages): # Abort recursion when simplelayout page reached. return False wftool = getToolByName(context, 'portal_workflow') if wftool.getWorkflowsFor(context): # The object has a workflow and is therefore not considered sl # contentish, since it has its own publishing cycle. return False if filter(lambda x, c=context: x.providedBy(c), sl_blocks): # A block without workflow is always considered sl contentish. return True # We have an object whithout a workflow. # It is considered sl contentish when the parent is sl contentish. # It is not considered sl contentish when it is directly in the page. parent = aq_parent(aq_inner(context)) return is_sl_contentish(parent)
def after_restoring(object, event): self.assertEqual(folder, object) self.assertEqual(folder, event.object) self.assertFalse(ITrashed.providedBy(object)) fired_events.append(type(event).__name__)
def contentItems(self, filter=None): items = self._old_contentItems(filter=filter) items = [item for item in items if not ITrashed.providedBy(item[1])] return items
def _getFieldObjects(self, *args, **kwargs): return filter(lambda obj: not ITrashed.providedBy(obj), self._old__getFieldObjects(*args, **kwargs))
def trashed_indexer(obj): """Indexer for the `trashed` index, this index is used to filter trashed objects from catalog search results by default. """ return ITrashed.providedBy(obj)