def publishTraverse(self, request, name): context = aq_inner(self.context) # If we are trying to traverse to the folder "body" pseudo-object # returned by listDAVObjects(), return that immediately if getattr(request, 'maybe_webdav_client', False) \ and name == DAV_FOLDER_DATA_ID: return FolderDataResource( DAV_FOLDER_DATA_ID, context ).__of__(context) defaultTraversal = super( DexterityPublishTraverse, self).publishTraverse(request, name) # If this is a WebDAV PUT/PROPFIND/PROPPATCH request, don't acquire # things. If we did, we couldn't create a new object with PUT, for # example, because the acquired object would shadow the NullResource if getattr(request, 'maybe_webdav_client', False) \ and request.get('REQUEST_METHOD', 'GET') not in ('GET', 'POST',) \ and IAcquirer.providedBy(defaultTraversal): parent = aq_parent(aq_inner(defaultTraversal)) if parent is not None and parent is not context: return NullResource( self.context, name, request).__of__(self.context) return defaultTraversal
def monkeypatch_plone_formwidget_namedfile_widget_download__call__(self): """ Patches to plone.formwidget.namedfile.widget.Download.__call__ """ if self.context.ignoreContext: raise NotFound('Cannot get the data file from a widget with no context') if self.context.form is not None: content = aq_inner(self.context.form.getContent()) else: content = aq_inner(self.context.context) field = aq_inner(self.context.field) dm = getMultiAdapter((content, field,), IDataManager) file_ = dm.get() if file_ is None: raise NotFound(self, self.filename, self.request) if not self.filename: self.filename = getattr(file_, 'filename', None) set_headers(file_, self.request.response, filename=self.filename) if IBlobby.providedBy(file): zodb_blob = file_._blob else: zodb_blob = file_ if set_xsendfile_header(self.request, self.request.response, zodb_blob): return 'collective.xsendfile - proxy missing?' else: return stream_data(file_)
def __getitem__(self, key): """Overloads the object's item access. """ # Don't allow key access to hidden attributes if key.startswith('_'): raise Unauthorized, key schema = self.Schema() keys = schema.keys() if key not in keys and not key.startswith('_'): # XXX Fix this in AT 1.4 value= getattr(aq_inner(self).aq_explicit, key, _marker) or \ getattr(aq_parent(aq_inner(self)).aq_explicit, key, _marker) if value is _marker: raise KeyError, key else: return value field = schema[key] accessor = field.getEditAccessor(self) if not accessor: accessor = field.getAccessor(self) # This is the access mode used by external editor. We need the # handling provided by BaseUnit when its available kw = {'raw':1, 'field': field.__name__} value = mapply(accessor, **kw) return value
def is_portal(self): context = aq_inner(self.context) request = aq_inner(self.request) context_state = getMultiAdapter((context, request), name=u'plone_context_state') is_portal_root = context_state.is_portal_root() return is_portal_root
def __call__(self): """ """ request = aq_inner(self.request) form = request.form if not 'form.button.Delete' in form: return super(PatchedManageAssignments, self).__call__() context = aq_inner(self.context) assignable = IRuleAssignmentManager(context) storage = getUtility(IRuleStorage) status = IStatusMessage(self.request) rule_ids = form.get('rule_ids', ()) path = '/'.join(context.getPhysicalPath()) for r in rule_ids: del assignable[r] assignments = get_assignments(storage[r]) if path in assignments: msg = 'Try to remove from %r' % ( assignments ) logger.info(msg) try: assignments.remove(path, None) except: assignments.remove(path) status.addStatusMessage(_(u"Assignments deleted."), type='info') return self.template()
def __call__(self): context = aq_inner(self.context) request = aq_inner(self.request) walker = self.walker() options = dict(target_type=walker.src_portal_type) clicked = request.form.has_key portal_url = getToolByName(context, 'portal_url')() if not haveContentMigrations: msg = _(u'Please install contentmigrations to be able to migrate to blobs.') IStatusMessage(request).addStatusMessage(msg, type='warning') options['nomigrations'] = 42 elif clicked('migrate'): output = self.migration() # Only count actual migration lines lines = output.split('\n') count = len([l for l in lines if l.startswith('Migrating')]) msg = _(u'blob_migration_info', default=u'Blob migration performed for ${count} item(s).', mapping={'count': count}) IStatusMessage(request).addStatusMessage(msg, type='info') options['count'] = count options['output'] = output elif clicked('cancel'): msg = _(u'Blob migration cancelled.') IStatusMessage(request).addStatusMessage(msg, type='info') request.RESPONSE.redirect(portal_url) else: options['available'] = len(list(walker.walk())) return self.index(**options)
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 getBreadcrumbs(self, path=None): """ Get breadcrumbs """ result = [] root_url = getNavigationRoot(self.obj) root = aq_inner(self.obj.restrictedTraverse(root_url)) root_url = root.absolute_url() if path is not None: root_abs_url = root.absolute_url() path = path.replace(root_abs_url, '', 1) path = path.strip('/') root = aq_inner(root.restrictedTraverse(path)) relative = aq_inner(self.obj).getPhysicalPath()[len(root.getPhysicalPath()):] if path is None: # Add siteroot result.append({'title': root.title_or_id(), 'url': '/'.join(root.getPhysicalPath())}) for i in range(len(relative)): now = relative[:i + 1] obj = aq_inner(root.restrictedTraverse(now)) if IFolderish.providedBy(obj): if not now[-1] == 'talkback': result.append({'title': obj.title_or_id(), 'url': root_url + '/' + '/'.join(now)}) return result
def upgrade(tool): # Hack prevent out-of-date upgrading # Related: PR #1484 # https://github.com/bikalabs/Bika-LIMS/pull/1484 from bika.lims.upgrade import skip_pre315 if skip_pre315(aq_parent(aq_inner(tool))): return True portal = aq_parent(aq_inner(tool)) setup = portal.portal_setup setup.runImportStepFromProfile('profile-bika.lims:default', 'typeinfo') stub('bika.lims.content.pricelistlineitem', 'PricelistLineItem', BaseContent) for pl in portal['pricelists'].objectValues(): pl.pricelist_lineitems = [] for pli in pl.objectValues(): item = dict( title=pli.title, ItemDescription=pli.ItemDescription, Accredited=pli.Accredited, Subtotal="%d.%d" % (pli.Subtotal[0], pli.Subtotal[1]), VATAmount="%d.%d" % (pli.VATAmount[0], pli.VATAmount[1]), Total="%d.%d" % (pli.Total[0], pli.Total[1]), CategoryTitle=pli.CategoryTitle, ) pl.pricelist_lineitems.append(item) return True
def find_user(context, userid): """Walk up all of the possible acl_users to find the user with the given userid. """ track = set() acl_users = aq_inner(cmfutils.getToolByName(context, 'acl_users')) path = '/'.join(acl_users.getPhysicalPath()) logger.debug('Visited acl_users "%s"' % path) track.add(path) user = acl_users.getUserById(userid) while user is None and acl_users is not None: context = aq_parent(aq_parent(aq_inner(acl_users))) acl_users = aq_inner(cmfutils.getToolByName(context, 'acl_users')) if acl_users is not None: path = '/'.join(acl_users.getPhysicalPath()) logger.debug('Visited acl_users "%s"' % path) if path in track: logger.warn('Tried searching an already visited acl_users, ' '"%s". All visited are: %r' % (path, list(track))) break track.add(path) user = acl_users.getUserById(userid) if user is not None: user = user.__of__(acl_users) return user
def execute(self): portal_url = getToolByName(aq_inner(self.context), "portal_url") portal = portal_url.getPortalObject() self.mailhost = getToolByName(aq_inner(self.context), "MailHost") if not self.mailhost: raise ComponentLookupError, 'You must have a Mailhost utility to execute this action' # first construct all replacement variables values = Values() # the object values.set('title', safe_unicode(self.object.Title())) values.set('url', self.object.absolute_url()) # user try: user = self.context.portal_membership.getAuthenticatedMember() values.set('loggeduserid', user.getId()) values.set('loggeduserfullname', safe_unicode(user.getProperty('fullname'))) values.set('loggeduseremail', user.getProperty('email')) except AttributeError, e: logger.error("class %s" % user.__class__) logger.error(" %s" % dir(user) ) raise e
def _setUID(self, uid): old_uid = IUUID(self, None) if old_uid is None: # Nothing to be done. return # Update forward references fw_refs = self.getReferenceImpl() for ref in fw_refs: assert ref.sourceUID == old_uid ref.sourceUID = uid item = ref container = aq_parent(aq_inner(ref)) # We call manage_afterAdd to inform the # reference catalog about changes. ref.manage_afterAdd(item, container) # Update back references back_refs = self.getBackReferenceImpl() for ref in back_refs: assert ref.targetUID == old_uid ref.targetUID = uid item = ref container = aq_parent(aq_inner(ref)) # We call manage_afterAdd to inform the # reference catalog about changes. ref.manage_afterAdd(item, container) setattr(self, config.UUID_ATTR, uid) item = self container = aq_parent(aq_inner(item)) # We call manage_afterAdd to inform the # reference catalog about changes. self.manage_afterAdd(item, container)
def add(self, object): fti = getUtility(IDexterityFTI, name=self.portal_type) container = aq_inner(self.context) container = aq_inner(container) container_fti = container.getTypeInfo() if not fti.isConstructionAllowed(container): raise Unauthorized("Cannot create %s" % self.portal_type) if container_fti is not None and not container_fti.allowType(self.portal_type): raise ValueError("Disallowed subobject type: %s" % self.portal_type) target = aq_inner(object._target) name = None if target is not None: name = target.getId() name = INameChooser(container).chooseName(name, object) object.id = name new_name = container._setObject(name, object) # XXX: When we move to CMF 2.2, an event handler will take care of this new_object = container._getOb(new_name) new_object.notifyWorkflowCreated() immediate_view = fti.immediate_view or 'view' self.immediate_view = "%s/%s/%s" % (container.absolute_url(), new_object.id, immediate_view,)
def get_proposal(self): """Return the proposal to which this document belongs. This may return a "proposal" or a "submitted proposal". """ parent = aq_parent(aq_inner(self)) if IProposal.providedBy(parent): return parent # Find submitted proposal when self is an excerpt document in the # meeting dossier. for relation in getUtility(ICatalog).findRelations({ 'to_id': getUtility(IIntIds).getId(aq_inner(self)), 'from_attribute': 'excerpts'}): # We expect that there are 0 or 1 relation, because this document # cannot be the excerpt of multiple proposals. submitted_proposal = relation.from_object if api.user.has_permission('View', obj=submitted_proposal): return submitted_proposal # Find proposal when self is an excerpt in the case dossier. generated_excerpts = GeneratedExcerpt.query.by_document(self).all() if generated_excerpts: proposal = generated_excerpts[0].proposal.resolve_proposal() if api.user.has_permission('View', obj=proposal): return proposal return None
def __call__(self): # TODO: Security check on form view/widget if self.context.ignoreContext: raise NotFound( "Cannot get the data file from a widget with no context") if self.context.form is not None: content = aq_inner(self.context.form.getContent()) else: content = aq_inner(self.context.context) field = aq_inner(self.context.field) dm = getMultiAdapter((content, field,), IDataManager) file_ = dm.get() file_ = _make_namedfile(file_, field, self.context) if file_ is None: raise NotFound(self, self.filename, self.request) if not self.filename: self.filename = getattr(file_, 'filename', None) set_headers(file_, self.request.response, filename=self.filename) return stream_data(file_)
def parent_url(self): """ This method is copied from plone.app.content.browser.foldercontents view """ portal_membership = getToolByName(self.context, 'portal_membership') obj = self.context checkPermission = portal_membership.checkPermission # Abort if we are at the root of the portal if IPloneSiteRoot.providedBy(self.context): return None # Get the parent. If we can't get it (unauthorized), use the portal parent = aq_parent(aq_inner(obj)) # # We may get an unauthorized exception if we're not allowed to access# # the parent. In this case, return None try: if getattr(parent, 'getId', None) is None or \ parent.getId() == 'talkback': # Skip any Z3 views that may be in the acq tree; # Skip past the talkback container if that's where we are parent = aq_parent(aq_inner(parent)) if not checkPermission('List folder contents', parent): return None return parent.absolute_url() except Unauthorized: return None
def setSEOCustomMetaTags(self, custommetatags): """ Set seo custom metatags properties. """ aq_inner(self.context) for tag in custommetatags: self.setProperty('%s%s' % (PROP_CUSTOM_PREFIX, tag['meta_name']), tag['meta_content'])
def searchCards(self): context = aq_inner(self.context) request = aq_inner(self.request) criterias = ['portal_type', 'category', 'Title', 'cardInfos'] arguments = {'meta_type': 'Card'} portal_type = context.getProperty('portaltype') if portal_type: arguments['portal_type'] = portal_type for key in criterias: value = request.get(key, '') if value: arguments[key] = value catalog = api.portal.get_tool('portal_catalog') result = [] sort = request.get('sort', '') if sort == 'category': categories_display = self.getCategories() for category in self.getCardCategories(): arguments['category'] = category[0] cards = catalog(arguments, sort_on='sortable_title') if cards: result.append({'title': categories_display[category[0]]}) result.extend(cards) elif sort == 'letter': result = catalog(arguments, sort_on='sortable_title') result = self.insertAlphabeticalTitleRows(result) else: result = catalog(arguments, sort_on='sortable_title') if not portal_type: result = sorted(result, key=lambda brain: brain.portal_type) return result
def getLexicon(self): """Get the lexicon for this index """ if hasattr(aq_base(self), 'lexicon'): # Fix up old ZCTextIndexes by removing direct lexicon ref # and changing it to an ID lexicon = getattr(aq_parent(aq_inner(self)), self.lexicon.getId()) self.lexicon_id = lexicon.getId() del self.lexicon if getattr(aq_base(self), 'lexicon_path', None): # Fix up slightly less old ZCTextIndexes by removing # the physical path and changing it to an ID. # There's no need to use a physical path, which otherwise # makes it difficult to move or rename ZCatalogs. self.lexicon_id = self.lexicon_path[-1] del self.lexicon_path try: return self._v_lexicon except AttributeError: lexicon = getattr(aq_parent(aq_inner(self)), self.lexicon_id) if not (ILexicon.providedBy(lexicon) or z2ILexicon.isImplementedBy(lexicon)): raise TypeError('Object "%s" is not a ZCTextIndex Lexicon' % repr(lexicon)) self._v_lexicon = lexicon return lexicon
def upgrade(tool): # Hack prevent out-of-date upgrading # Related: PR #1484 # https://github.com/bikalabs/Bika-LIMS/pull/1484 from bika.lims.upgrade import skip_pre315 if skip_pre315(aq_parent(aq_inner(tool))): return True portal = aq_parent(aq_inner(tool)) setup = portal.portal_setup mp = portal.bika_setup.manage_permission mp('Access contents information', ['Authenticated', 'Analyst'], 1) mp(permissions.View, ['Authenticated', 'Analyst'], 1) portal.bika_setup.reindexObject() for obj in portal.bika_setup.bika_analysisservices.objectValues(): mp = obj.manage_permission mp(permissions.View, ['Manager', 'LabManager', 'Analyst'], 0) mp('Access contents information', ['Manager', 'LabManager', 'Member', 'LabClerk', 'Analyst', 'Sampler', 'Preserver', 'Owner'], 0) obj.reindexObject() wf = getToolByName(portal, 'portal_workflow') # update affected tools setup.runImportStepFromProfile('profile-bika.lims:default', 'typeinfo') setup.runImportStepFromProfile('profile-bika.lims:default', 'workflow-csv') wf.updateRoleMappings() return True
def parent_info(self): """query parent url for back to overview link""" portal_url = getToolByName(self.context, 'portal_url') plone_utils = getToolByName(self.context, 'plone_utils') portal_membership = getToolByName(self.context, 'portal_membership') obj = self.context checkPermission = portal_membership.checkPermission # There is no parent if we are at the root of the portal if IPloneSiteRoot.providedBy(self.context): return None # Get the parent: we may get an unauthorized exception if we are # not allowed to access the parent. In this case, use the portal parent = aq_parent(aq_inner(obj)) try: if getattr(parent, 'getId', None) is None or parent.getId() == 'talkback': # Skip past the discussion items, aka the talkback container parent = aq_parent(aq_inner(parent)) if not checkPermission('List folder contents', parent): return None return [dict(title=parent.Title, url=parent.absolute_url)] except Unauthorized: return None
def get_portlet_assingment(context, uid): context_orgin = context for name in [u"plone.leftcolumn", u"plone.rightcolumn", u"collective.teaser.portletmanager"]: manager = getUtility(IPortletManager, name=name) for category in manager.values(): for group in category.values(): for assignment in group.values(): if ITeaserPortlet.providedBy(assignment): if uid == str(assignment.uid): return assignment context = aq_inner(context_orgin) while True: try: assignment_mapping = getMultiAdapter( (context, manager), IPortletAssignmentMapping ) except: return for assignment in assignment_mapping.values(): if ITeaserPortlet.providedBy(assignment): if uid == str(assignment.uid): return assignment if IPloneSiteRoot.providedBy(context): break context = aq_parent(aq_inner(context)) raise KeyError(u"Portlet assignment for uid '%s' not found." % uid)
def __init__(self, context, request): super(CompetitionDetail, self).__init__(context, request) if IBaseFolder.providedBy(context): self.parent = aq_parent(aq_inner(context)) else: self.parent = aq_parent(aq_parent(aq_inner(context))) self.parent = '/'.join(self.parent.getPhysicalPath())
def update(self): super(LogoViewlet, self).update() context = aq_inner(self.context) registry = getUtility(IRegistry) portal = self.portal_state.portal() bprops = portal.restrictedTraverse('base_properties', None) title = None logo_id = registry.get('collective.folderlogo.logo_id', u'logo') context = aq_inner(self.context) catalog = getToolByName(context, 'portal_catalog') folders = [folder for folder in aq_chain(context) if IFolderish.providedBy(folder)] logos = [] for folder in folders: path = '/'.join(folder.getPhysicalPath()) brains = catalog( path=dict(query=path, depth=1), id=logo_id, object_provides=IATImage.__identifier__) if len(brains) != 0: logos.append(brains[0]) if len(logos) != 0: logoName = logo_id title = logos[0].Title portal = aq_parent(logos[0].getObject()) elif bprops is not None: logoName = bprops.logoName else: logoName = 'logo.jpg' self.logo_tag = portal.restrictedTraverse(str(logoName)).tag() self.portal_title = title or self.portal_state.portal_title()
def upgrade(tool): # Hack prevent out-of-date upgrading # Related: PR #1484 # https://github.com/bikalabs/Bika-LIMS/pull/1484 from bika.lims.upgrade import skip_pre315 if skip_pre315(aq_parent(aq_inner(tool))): return True portal = aq_parent(aq_inner(tool)) setup = portal.portal_setup # update affected tools setup.runImportStepFromProfile('profile-bika.lims:default', 'workflow-csv') # /supplyorders folder permissions mp = portal.supplyorders.manage_permission mp(CancelAndReinstate, ['Manager', 'LabManager', 'LabClerk'], 0) mp(ManagePricelists, ['Manager', 'LabManager', 'Owner'], 1) mp(permissions.ListFolderContents, ['Member'], 1) mp(permissions.AddPortalContent, ['Manager', 'LabManager', 'Owner'], 0) mp(permissions.DeleteObjects, ['Manager', 'LabManager', 'Owner'], 0) mp(permissions.View, ['Manager', 'LabManager'], 0) portal.supplyorders.reindexObject() wf = getToolByName(portal, 'portal_workflow') wf.updateRoleMappings() return True
def upgrade(tool): # Hack prevent out-of-date upgrading # Related: PR #1484 # https://github.com/bikalabs/Bika-LIMS/pull/1484 from bika.lims.upgrade import skip_pre315 if skip_pre315(aq_parent(aq_inner(tool))): return True portal = aq_parent(aq_inner(tool)) # Fix Analysis Services IMM incoherences for service in portal.bika_setup.bika_analysisservices.objectValues('AnalysisService'): if (service.getInstrumentEntryOfResults() == False): # Remove any assigned instrument service.setInstruments([]) service.setInstrument(None) if (service.getManualEntryOfResults() == False): # Remove any assigned manual method service.setMethods([]) service.set_Method(None) service.reindexObject() return True
def mark_section(self, element): if self.already_marked(element, 'section'): return catalog = getToolByName(self.context, 'portal_catalog') # search *only* in this section existing = catalog(object_provides=ISectionArticle.__identifier__, section=element.section) # existe el caso donde se puede marcar una nota para una seccion, # luego cambiarle manualmente la misma, lo que nos dejaria con mas de # una *nota de seccion* por seccion for article in existing: elem = article.getObject() context = aq_inner(elem) noLongerProvides(context, ISectionArticle) context.reindexObject(idxs=['object_provides']) context = aq_inner(element) alsoProvides(context, ISectionArticle) context.reindexObject(idxs=['object_provides']) # Disparo un evento sobre el objeto para que se purge desde # el handler del policy. notify(ObjectModifiedEvent(element))
def upgrade(tool): """ Sort by Type in instruments """ # Hack prevent out-of-date upgrading # Related: PR #1484 # https://github.com/bikalabs/Bika-LIMS/pull/1484 from bika.lims.upgrade import skip_pre315 if skip_pre315(aq_parent(aq_inner(tool))): return True portal = aq_parent(aq_inner(tool)) bsc = getToolByName(portal, 'bika_setup_catalog', None) if 'getInstrumentType' not in bsc.indexes(): bsc.addIndex('getInstrumentType', 'FieldIndex') bsc.addColumn('getInstrumentType') bsc.addIndex('getInstrumentTypeName','FieldIndex') bsc.addColumn('getInstrumentTypeName') #Del old "getType" Index, it's not used now. if 'getType' in bsc.indexes(): bsc.delIndex('getType') if 'getType' in bsc.indexes(): bsc.delColumn('getType') setup = portal.portal_setup logger.info("Reindex added indexes in bika_setup_catalog") bsc.manage_reindexIndex( ids=['getInstrumentType', 'getInstrumentTypeName', ]) return True
def getPageSiteLayout(context): """Get the path to the site layout for a page. This is generally only appropriate for the view of this page. For a generic template or view, use getDefaultSiteLayout(context) instead. """ layoutAware = ILayoutAware(context, None) if layoutAware is not None: if getattr(layoutAware, 'pageSiteLayout', None): return layoutAware.pageSiteLayout # Note: the sectionSiteLayout on context is for pages *under* context, not # necessarily context itself parent = aq_parent(aq_inner(context)) while parent is not None: layout = ILayoutAware(parent, None) if layout is not None: if getattr(layout, 'sectionSiteLayout', None): return layout.sectionSiteLayout parent = aq_parent(aq_inner(parent)) fti = queryUtility(IDexterityFTI, name=context.portal_type) if fti is not None and IPageFTI.providedBy(fti): if fti.default_site_layout: return fti.default_site_layout registry = queryUtility(IRegistry) if registry is None: return None return registry.get(DEFAULT_SITE_LAYOUT_REGISTRY_KEY)
def inherited_portlets(self): """Return the list of portlets inherited by the current context. Invisible (hidden) portlets are excluded. """ context = aq_inner(self.context) data = [] while not IPloneSiteRoot.providedBy(context): if IAcquirer.providedBy(context): context = aq_parent(aq_inner(context)) else: context = context.__parent__ # we get the contextual portlets view to access its utility methods view = queryMultiAdapter((context, self.request), name=self.__parent__.__name__) if view is not None: assignments = view.getAssignmentsForManager(self.manager) is_visible = lambda a: IPortletAssignmentSettings(a).get('visible', True) assignments_to_show = [a for a in assignments if is_visible(a)] base_url = view.getAssignmentMappingUrl(self.manager) data.extend(self.portlets_for_assignments(assignments_to_show, self.manager, base_url)) assignable = queryMultiAdapter((context, self.manager), ILocalPortletAssignmentManager) if assignable is not None and assignable.getBlacklistStatus(CONTEXT_CATEGORY): # Current context has blocked inherited portlets, stop. break return data
def prepareObjectTabs(self, default_tab='view', sort_first=['folderContents']): """Prepare the object tabs by determining their order and working out which tab is selected. Used in global_contentviews.pt """ context = aq_inner(self.context) context_url = context.absolute_url() context_fti = context.getTypeInfo() context_state = getMultiAdapter( (context, self.request), name=u'plone_context_state' ) actions = context_state.actions action_list = [] if context_state.is_structural_folder(): action_list = actions('folder') action_list.extend(actions('object')) tabs = [] found_selected = False fallback_action = None try: request_url = self.request['ACTUAL_URL'] except KeyError: # not a real request, could be a test. Let's not fail. request_url = context_url request_url_path = request_url[len(context_url):] if request_url_path.startswith('/'): request_url_path = request_url_path[1:] for item in action_list: item.update({'selected': False}) action_url = item['url'].strip() starts = action_url.startswith if starts('http') or starts('javascript'): item['url'] = action_url else: item['url'] = '%s/%s' % (context_url, action_url) item['url'] = addTokenToUrl(item['url'], self.request) action_method = item['url'].split('/')[-1].split('?')[0] # Action method may be a method alias: # Attempt to resolve to a template. action_method = context_fti.queryMethodID( action_method, default=action_method ) if action_method: request_action = unquote(request_url_path).split('?')[0] request_action = context_fti.queryMethodID( request_action, default=request_action ) if action_method == request_action: item['selected'] = True found_selected = True current_id = item['id'] if current_id == default_tab: fallback_action = item modal = item.get('modal', None) item['cssClass'] = '' if modal: item['cssClass'] += ' pat-plone-modal' item['url'] += '?ajax_load=1' tabs.append(item) if not found_selected and fallback_action is not None: fallback_action['selected'] = True def sortOrder(tab): try: return sort_first.index(tab['id']) except ValueError: return 255 tabs.sort(key=sortOrder) return tabs
def can_delete_response(self): context = aq_inner(self.context) return self.memship.checkPermission('Delete objects', context)
def can_edit_response(self): context = aq_inner(self.context) return self.memship.checkPermission('Poi: Edit response', context)
def memship(self): context = aq_inner(self.context) return getToolByName(context, 'portal_membership')
def portal_url(self): context = aq_inner(self.context) plone = context.restrictedTraverse('@@plone_portal_state') return plone.portal_url()
def getWorkflow(self): return aq_parent(aq_inner(aq_parent(aq_inner(self))))
def folderitems(self, full_objects=False): """ """ context = aq_inner(self.context) plone_layout = getMultiAdapter((context, self.request), name=u'plone_layout') plone_utils = getToolByName(context, 'plone_utils') plone_view = getMultiAdapter((context, self.request), name=u'plone') portal_properties = getToolByName(context, 'portal_properties') portal_types = getToolByName(context, 'portal_types') workflow = getToolByName(context, 'portal_workflow') site_properties = portal_properties.site_properties norm = getUtility(IIDNormalizer).normalize show_all = self.request.get('show_all', '').lower() == 'true' pagenumber = int(self.request.get('pagenumber', 1) or 1) pagesize = self.pagesize start = (pagenumber - 1) * pagesize end = start + pagesize if (hasattr(self, 'And') and self.And) \ or (hasattr(self, 'Or') and self.Or): # if contentsMethod is capable, we do an AdvancedQuery. if hasattr(self.contentsMethod, 'makeAdvancedQuery'): aq = self.contentsMethod.makeAdvancedQuery(self.contentFilter) if hasattr(self, 'And') and self.And: tmpAnd = And() for q in self.And: tmpAnd.addSubquery(q) aq &= tmpAnd if hasattr(self, 'Or') and self.Or: tmpOr = Or() for q in self.Or: tmpOr.addSubquery(q) aq &= tmpOr brains = self.contentsMethod.evalAdvancedQuery(aq) else: # otherwise, self.contentsMethod must handle contentFilter brains = self.contentsMethod(self.contentFilter) else: brains = self.contentsMethod(self.contentFilter) results = [] self.page_start_index = "" for i, obj in enumerate(brains): # we don't know yet if it's a brain or an object path = hasattr(obj, 'getPath') and obj.getPath() or \ "/".join(obj.getPhysicalPath()) # avoid creating unnecessary info for items outside the current # batch; only the path is needed for the "select all" case... if not show_all and not start <= i < end: if hasattr(obj, 'getObject'): uid = obj.UID else: uid = obj.UID() results.append(dict(path=path, uid=uid)) continue if self.page_start_index == "": self.page_start_index = i if hasattr(obj, 'getObject'): obj = obj.getObject() uid = obj.UID() title = obj.Title() description = obj.Description() icon = plone_layout.getIcon(obj) url = obj.absolute_url() relative_url = obj.absolute_url(relative=True) fti = portal_types.get(obj.portal_type) if fti is not None: type_title_msgid = fti.Title() else: type_title_msgid = obj.portal_type url_href_title = u'%s at %s: %s' % \ (translate(type_title_msgid, context = self.request), path, safe_unicode(description)) modified = TimeOrDate(self.context, obj.ModificationDate, long_format=1) # element css classes type_class = 'contenttype-' + \ plone_utils.normalizeString(obj.portal_type) state_class = '' states = {} for w in workflow.getWorkflowsFor(obj): state = w._getWorkflowStateOf(obj).id states[w.state_var] = state state_class += "state-%s " % state results_dict = dict( obj=obj, id=obj.getId, title=title, uid=uid, path=path, url=url, fti=fti, item_data=json.dumps([]), url_href_title=url_href_title, obj_type=obj.Type, size=obj.getObjSize, modified=modified, icon=icon.html_tag(), type_class=type_class, # a list of lookups for single-value-select fields choices={}, state_class=state_class, relative_url=relative_url, view_url=url, table_row_class="", # a list of names of fields that may be edited on this item allow_edit=[], # a list of names of fields that are compulsory (if editable) required=[], # "before", "after" and replace: dictionary (key is column ID) # A snippet of HTML which will be rendered # before/after/instead of the table cell content. before={}, # { before : "<a href=..>" } after={}, replace={}, ) try: review_state = workflow.getInfoFor(obj, 'review_state') state_title = workflow.getTitleForStateOnType( review_state, obj.portal_type) except: review_state = 'active' state_title = None if review_state: results_dict['review_state'] = review_state for state_var, state in states.items(): if not state_title: state_title = workflow.getTitleForStateOnType( state, obj.portal_type) results_dict[state_var] = state results_dict['state_title'] = state_title # XXX add some kind of out-of-date indicator to bika listing ## if App.config.getConfiguration().debug_mode: ## from Products.CMFEditions.utilities import dereference ## pr = getToolByName(self.context, 'portal_repository') ## o = hasattr(obj, 'getObject') and obj.getObject() or obj ## if pr.isVersionable(o): ## pa = getToolByName(self.context, 'portal_archivist') ## history_id = str(dereference(o)[1]) ## version_id = hasattr(o, 'version_id') \ ## and str(o.version_id) or None ## if not 'version_id' in self.columns.keys(): ## self.columns['version_id'] = {'title':'version'} ## for x in range(len(self.review_states)): ## if self.review_states[x]['id'] == 'all': ## self.review_states[x]['columns'].append('version_id') ## results_dict['version_id'] = '%s/%s' % (version_id, history_id) # extra classes for individual fields on this item { field_id : "css classes" } results_dict['class'] = {} # Search for values for all columns in obj for key in self.columns.keys(): if hasattr(obj, key): # if the key is already in the results dict # then we don't replace it's value if results_dict.has_key(key): continue value = getattr(obj, key) if callable(value): value = value() results_dict[key] = value results.append(results_dict) return results
def __init__(self, context, request, *args, **kwargs): super(CookiePolicy, self).__init__(context, request, *args, **kwargs) context = aq_inner(context) self.context = context pp = getToolByName(context, 'portal_properties') self.sheet = getattr(pp, 'tlspu_cookiepolicy_properties', None)
def can_review(comment): """Returns true if current user has the 'Review comments' permission.""" return bool(getSecurityManager().checkPermission("Review comments", aq_inner(comment)))
def update(self): plone_utils = getToolByName(self.context, 'plone_utils') context = aq_inner(self.context) self.metatags = plone_utils.listMetaTags(context).items()
def portal_state(self): context = aq_inner(self.context) return getMultiAdapter((context, self.request), name=u'plone_portal_state')
def title(self): site = queryUtility(ISiteRoot) if site is None: # fallback return aq_parent(aq_inner(self)).title return site.title
def dbSize(self): context = aq_inner(self.context) cpanel = context.unrestrictedTraverse('/Control_Panel') return cpanel.db_size()
def validate(self, request, auth='', roles=_noroles): """ Validation using Cookies """ req_has = request.has_key resp = request['RESPONSE'] has_cookie = '__ac' in request.keys() login_doc = getattr(self, 'login', self.docLogin) v = request['PUBLISHED'] # the published object a, c, n, v = self._getobcontext(v, request) if has_cookie: # Do we have the cookie? cookie = request['__ac'] cookie = urllib.unquote(cookie) try: cookie = decodestring(cookie) name, password = tuple(string.split(cookie, ':')) except: resp.expireCookie('__ac', path='/') raise 'LoginRequired', login_doc(self, request) elif req_has('__ac_name') and req_has('__ac_password'): name = request['__ac_name'] password = request['__ac_password'] try: del request['__ac_name'] del request['__ac_password'] except: pass else: name, password = self.identify(auth) login_status = self.getLoginStatus() if login_status == 'LOCKED': return None elif login_status == 'CAPTCHA': # validated = request.SESSION.get('captcha_validated') captcha = request.get('__ac_captcha') expected = request.SESSION.get('captcha_word') # if not validated and (not captcha or captcha != expected): if (not captcha or captcha != expected): return None # request.SESSION.set('captcha_validated', True) user = self.authenticate(name, password, request) # user will be None if we can't authenticate him or if we can't find # his username in this user database. if user is not None: emergency = self._emergency_user if emergency and user is emergency: if self._isTop(): # we do not need to authorize the # emergency user against the # published object. if not has_cookie: token = '%s:%s' % (name, password) token = encodestring(token) token = urllib.quote(token) resp.setCookie('__ac', token, path='/') return emergency.__of__(self) else: # we're not the top-level user folder return None else: # We found a user, his password was correct, and the user # wasn't the emergency user. We need to authorize the user # against the published object. if self.authorize(user.__of__(self), a, c, n, v, roles): if not has_cookie: token = '%s:%s' % (name, password) token = encodestring(token) token = urllib.quote(token) resp.setCookie('__ac', token, path='/') return user.__of__(self) # That didn't work. Try to authorize the anonymous user. elif (self._isTop() and self.authorize(self._nobody.__of__(self), a, c, n, v, roles)): return self._nobody.__of__(self) else: raise 'LoginRequired', login_doc(self, request) else: # either we didn't find the username, or the user's password # was incorrect. try to authorize and return the anonymous user. if self._isTop() and self.authorize(self._nobody.__of__(self), a, c, n, v, roles): return self._nobody.__of__(self) elif not self._isTop(): # We cannot authorize the user and we are not toplevel if self.authorize(self._nobody, a, c, n, v, roles): # This place can be visited by anonymous users # Must hand off authentication because the # current user could be someone legit and not # just anonymous. Any user folder can deal with # anonymous so that is not a problem return None else: # This place is not accessible by anonymous. # Make a pathetic attempt at authenticating # above me... :( # This code *will* fail with multiple user # folders above this one. WAAA! parent = aq_parent(aq_inner(self)) grandparent = aq_parent(aq_inner(parent)) acl = getattr(grandparent, 'acl_users', None) if acl is None: # This should never happen raise 'LoginRequired', login_doc(self, request) else: user = acl.authenticate(name, password, request) if user is None: raise 'LoginRequired', login_doc(self, request) if not has_cookie: token = '%s:%s' % (name, password) token = encodestring(token) token = urllib.quote(token) resp.setCookie('__ac', token, path='/') return user.__of__(acl) else: # anonymous can't authorize or we're not top-level user folder raise 'LoginRequired', login_doc(self, request)
def _getDiscussable( self, outer=0 ): """ """ tb = outer and aq_inner( self ) or self return getattr( tb, 'aq_parent', None )
def available(self): root = aq_inner(self.context).getPhysicalRoot() sm = getSecurityManager() return sm.checkPermission(view_management_screens, root)
def _get__roles__(self): imp = getattr(aq_parent(aq_inner(self)), '%s__roles__' % self.__name__) if hasattr(imp, '__of__'): return imp.__of__(self) return imp
def processTime(self): context = aq_inner(self.context) cpanel = context.unrestrictedTraverse('/Control_Panel') return cpanel.process_time()
def getPhysicalPath(self): p = aq_parent(aq_inner(self)) path = (self._id, ) if p is not None: path = p.getPhysicalPath() + path return path
def getCustomizableObject(self): ob = aq_parent(aq_inner(self)) while getattr(ob, '_isDirectoryView', 0): ob = aq_parent(aq_inner(ob)) return ob
def widget_item_records(self): context = aq_inner(self.context) storage = IContentWidgets(context) records = storage.read_widget(self.configuration['widget_id']) return records
def getPortalObject(self): return aq_parent(aq_inner(self))
def render(self): context = aq_inner(self.context) node_uid = self._content_widget_factory() next_url = '{0}/@@content-widget-item-edit?nid={1}'.format( context.absolute_url(), node_uid) return self.request.response.redirect(addTokenToUrl(next_url))
def _update_panel_editor(self, editor_data): context = aq_inner(self.context) tool = getUtility(IPanelEditor) return tool.update(key=context.UID(), data=editor_data)
def get_committee_container(self): return aq_parent(aq_inner(self))
def configuration(self): context = aq_inner(self.context) return self.panel_editor()[context.UID()]
def getMenuPaste(self): """Return menu item entries in a TAL-friendly form.""" copyDict = getCopyObjectsUID(self.request) portal_type = self.query and self.query.get( 'portal_type') or self.query.get('Type', None) portal_types = [] if not copyDict: return [] if portal_type and isinstance(portal_type, (tuple, list)): portal_types = portal_type elif portal_type: portal_types = [ portal_type, ] item = None try: item = self.portal.restrictedTraverse(copyDict['url']) except: pass if item and not item.portal_type in portal_types: return [] results = [] actions_tool = getToolByName(self.portal, 'portal_actions') pasteAction = [ a for a in actions_tool.listActionInfos( object=aq_inner(self.addContext), categories=('object_buttons', )) if a['id'] == 'paste' ] plone_utils = getToolByName(self.portal, 'plone_utils') context_url = self.addContext.absolute_url() for action in pasteAction: if action['allowed']: cssClass = 'actionicon-object_buttons-%s' % action['id'] icon = plone_utils.getIconFor('object_buttons', action['id'], None) if icon: icon = '%s/%s' % (self.addContext.absolute_url(), icon) start_date = quote_plus(str(self.startDate)) results.append({ 'title': action['title'], 'description': '', 'action': '%s/SFJsonEventPaste?startDate=%s%s' % (context_url, start_date, self.ReqAllDay), 'selected': False, 'icon': icon, 'extra': { 'id': action['id'], 'separator': None, 'class': cssClass }, 'submenu': None, }) return results
def _update_panel_editor(self, settings): context = aq_inner(self.context) tool = getUtility(IPanelEditor) editor_data = tool.get()[context.UID()] editor_data["widget_node"] = settings["node_id"] return tool.update(key=context.UID(), data=editor_data)
def __call__(self): portal = getToolByName(self.context, 'portal_url').getPortalObject() portal_types = getToolByName(portal, 'portal_types') context = aq_inner(self.context) target_folder = getattr( interfaces.ISolgemaFullcalendarProperties(context, None), 'target_folder', None) target_folder = target_folder \ and portal.unrestrictedTraverse('/'+ portal.id + target_folder) \ or aq_parent(context) if not getSecurityManager().checkPermission('Add portal content', target_folder): raise Unauthorized, "You can't add an event on %s" % str( target_folder) query = hasattr(self.context, 'buildQuery') and self.context.buildQuery() or {} query = normalize_type_query(query, portal) copyDict = getCopyObjectsUID(self.request) # The 'Item Type' criteria uses the 'Type' index while the 'Item Type # (internal)' criteria uses the 'portal_type' index. # # We need to check for both, portal_type first, because it's more # specific than 'Type', which just indexes the content type's Title # property (which can be non-unique). index = query.get('portal_type', query.get('Type')) self.request.response.setHeader("Content-type", "application/json") if index: if isinstance(index, (list, tuple)) and len(index) > 1: return json.dumps({'display': True}) portal_type = isinstance(index, (tuple, list)) and index[0] or index if copyDict and portal.restrictedTraverse( copyDict['url']).portal_type == portal_type: return json.dumps({'display': True}) elif query.get('Type'): portal_type = isinstance( query['Type'], (tuple, list)) and query['Type'][0] or query['Type'] if copyDict and portal.restrictedTraverse( copyDict['url']).portal_type == portal_type: return json.dumps({'display': True}) else: portal_type = getattr( interfaces.ISolgemaFullcalendarProperties(context, None), 'eventType', 'Event') pTypes = [ a for a in portal_types.listTypeInfo() if a.id == portal_type ] pTypeTitle = pTypes and pTypes[0].Title() or portal_type typeTitle = translate(pTypeTitle, context=self.request) if HAS_PLONE40: title = PLMF(u'heading_add_item', default='Add ${itemtype}', mapping={'itemtype': typeTitle}) else: title = PLMF(u'label_add_type', default='Add ${type}', mapping={'type': typeTitle}) is_dx = False if HAS_DEXTERITY: is_dx = pTypes and IDexterityFTI.providedBy(pTypes[0]) or False return json.dumps({ 'display': False, 'type': portal_type, 'title': translate(title, context=self.request), 'is_dx': is_dx })
def is_subtemplatefolder(self): parent = aq_parent(aq_inner(self)) return bool(ITemplateFolder.providedBy(parent))