Пример #1
0
 def reindex(self, fields=None, unindex=False):
     """Asks a direct object reindexing. In most cases you don't have to
        reindex objects "manually" with this method. When an object is
        modified after some user action has been performed, Appy reindexes
        this object automatically. But if your code modifies other objects,
        Appy may not know that they must be reindexed, too. So use this
        method in those cases.
     """
     if fields:
         # Get names of indexes from field names.
         indexes = [Search.getIndexName(name) for name in fields]
     else:
         indexes = None
     self.o.reindex(indexes=indexes, unindex=unindex)
Пример #2
0
 def reindex(self, fields=None, unindex=False):
     '''Asks a direct object reindexing. In most cases you don't have to
        reindex objects "manually" with this method. When an object is
        modified after some user action has been performed, Appy reindexes
        this object automatically. But if your code modifies other objects,
        Appy may not know that they must be reindexed, too. So use this
        method in those cases.
     '''
     if fields:
         # Get names of indexes from field names.
         indexes = [Search.getIndexName(name) for name in fields]
     else:
         indexes = None
     self.o.reindex(indexes=indexes, unindex=unindex)
Пример #3
0
    def executeQuery(self, contentType, searchName=None, startNumber=0,
                     search=None, remember=False, brainsOnly=False,
                     maxResults=None, noSecurity=False, sortBy=None,
                     sortOrder='asc', filterKey=None, filterValue=None,
                     refField=None):
        '''Executes a query on a given p_contentType (or several, separated
           with commas) in Plone's portal_catalog. If p_searchName is specified,
           it corresponds to:
             1) a search defined on p_contentType: additional search criteria
                will be added to the query, or;
             2) "_advanced": in this case, additional search criteria will also
                be added to the query, but those criteria come from the session
                (in key "searchCriteria") and were created from search.pt.

           We will retrieve objects from p_startNumber. If p_search is defined,
           it corresponds to a custom Search instance (instead of a predefined
           named search like in p_searchName). If both p_searchName and p_search
           are given, p_search is ignored.

           This method returns a list of objects in the form of the
           __dict__ attribute of an instance of SomeObjects (see in
           appy.gen.utils). We return the __dict__ attribute instead of real
           instance: that way, it can be used in ZPTs without security problems.
           If p_brainsOnly is True, it returns a list of brains instead (can be
           useful for some usages like knowing the number of objects without
           needing to get information about them). If no p_maxResults is
           specified, the method returns maximum
           self.numberOfResultsPerPage. The method returns all objects if
           p_maxResults equals string "NO_LIMIT".

           If p_noSecurity is True, it gets all the objects, even those that the
           currently logged user can't see.

           The result is sorted according to the potential sort key defined in
           the Search instance (Search.sortBy). But if parameter p_sortBy is
           given, it defines or overrides the sort. In this case, p_sortOrder
           gives the order (*asc*ending or *desc*ending).

           If p_filterKey is given, it represents an additional search parameter
           to take into account: the corresponding search value is in
           p_filterValue.

           If p_refField is given, the query is limited to the objects that are
           referenced through it.'''
        # Is there one or several content types ?
        if contentType.find(',') != -1:
            portalTypes = contentType.split(',')
        else:
            portalTypes = contentType
        params = {'portal_type': portalTypes}
        if not brainsOnly: params['batch'] = True
        # Manage additional criteria from a search when relevant
        if searchName:
            # In this case, contentType must contain a single content type.
            appyClass = self.getAppyClass(contentType)
            if searchName != '_advanced':
                search = ClassDescriptor.getSearch(appyClass, searchName)
            else:
                fields = self.REQUEST.SESSION['searchCriteria']
                search = Search('customSearch', **fields)
        if search:
            # Add additional search criteria
            for fieldName, fieldValue in search.fields.iteritems():
                # Management of searches restricted to objects linked through a
                # Ref field: not implemented yet.
                if fieldName == '_ref': continue
                # Make the correspondance between the name of the field and the
                # name of the corresponding index.
                attrName = Search.getIndexName(fieldName)
                # Express the field value in the way needed by the index
                params[attrName] = Search.getSearchValue(fieldName, fieldValue)
            # Add a sort order if specified
            sortKey = search.sortBy
            if sortKey:
                params['sort_on'] = Search.getIndexName(sortKey, usage='sort')
        # Determine or override sort if specified.
        if sortBy:
            params['sort_on'] = Search.getIndexName(sortBy, usage='sort')
            if sortOrder == 'desc': params['sort_order'] = 'reverse'
            else:                   params['sort_order'] = None
        # If defined, add the filter among search parameters.
        if filterKey:
            filterKey = Search.getIndexName(filterKey)
            filterValue = Search.getSearchValue(filterKey, filterValue)
            params[filterKey] = filterValue
            # TODO This value needs to be merged with an existing one if already
            # in params, or, in a first step, we should avoid to display the
            # corresponding filter widget on the screen.
        # Determine what method to call on the portal catalog
        if noSecurity: catalogMethod = 'unrestrictedSearchResults'
        else:          catalogMethod = 'searchResults'
        exec 'brains = self.portal_catalog.%s(**params)' % catalogMethod
        if brainsOnly:
            # Return brains only.
            if not maxResults: return brains
            else: return brains[:maxResults]
        if not maxResults:
            if refField: maxResults = refField.maxPerPage
            else:        maxResults = self.appy().numberOfResultsPerPage
        elif maxResults == 'NO_LIMIT': maxResults = None
        res = SomeObjects(brains, maxResults, startNumber,noSecurity=noSecurity)
        res.brainsToObjects()
        # In some cases (p_remember=True), we need to keep some information
        # about the query results in the current user's session, allowing him
        # to navigate within elements without re-triggering the query every
        # time a page for an element is consulted.
        if remember:
            if not searchName:
                # It is the global search for all objects pf p_contentType
                searchName = contentType
            uids = {}
            i = -1
            for obj in res.objects:
                i += 1
                uids[startNumber+i] = obj.UID()
            self.REQUEST.SESSION['search_%s' % searchName] = uids
        return res.__dict__
Пример #4
0
    def executeQuery(self,
                     className,
                     searchName=None,
                     startNumber=0,
                     search=None,
                     remember=False,
                     brainsOnly=False,
                     maxResults=None,
                     noSecurity=False,
                     sortBy=None,
                     sortOrder='asc',
                     filterKey=None,
                     filterValue=None,
                     refObject=None,
                     refField=None):
        '''Executes a query on instances of a given p_className (or several,
           separated with commas) in the catalog. If p_searchName is specified,
           it corresponds to:
             1) a search defined on p_className: additional search criteria
                will be added to the query, or;
             2) "_advanced": in this case, additional search criteria will also
                be added to the query, but those criteria come from the session
                (in key "searchCriteria") and were created from search.pt.

           We will retrieve objects from p_startNumber. If p_search is defined,
           it corresponds to a custom Search instance (instead of a predefined
           named search like in p_searchName). If both p_searchName and p_search
           are given, p_search is ignored.

           This method returns a list of objects in the form of the
           __dict__ attribute of an instance of SomeObjects (see in
           appy.gen.utils). We return the __dict__ attribute instead of real
           instance: that way, it can be used in ZPTs without security problems.
           If p_brainsOnly is True, it returns a list of brains instead (can be
           useful for some usages like knowing the number of objects without
           needing to get information about them). If no p_maxResults is
           specified, the method returns maximum
           self.numberOfResultsPerPage. The method returns all objects if
           p_maxResults equals string "NO_LIMIT".

           If p_noSecurity is True, it gets all the objects, even those that the
           currently logged user can't see.

           The result is sorted according to the potential sort key defined in
           the Search instance (Search.sortBy). But if parameter p_sortBy is
           given, it defines or overrides the sort. In this case, p_sortOrder
           gives the order (*asc*ending or *desc*ending).

           If p_filterKey is given, it represents an additional search parameter
           to take into account: the corresponding search value is in
           p_filterValue.

           If p_refObject and p_refField are given, the query is limited to the
           objects that are referenced from p_refObject through p_refField.'''
        # Is there one or several content types ?
        if className.find(',') != -1:
            classNames = className.split(',')
        else:
            classNames = className
        params = {'ClassName': classNames}
        if not brainsOnly: params['batch'] = True
        # Manage additional criteria from a search when relevant
        if searchName:
            # In this case, className must contain a single content type.
            appyClass = self.getAppyClass(className)
            if searchName != '_advanced':
                search = ClassDescriptor.getSearch(appyClass, searchName)
            else:
                fields = self.REQUEST.SESSION['searchCriteria']
                search = Search('customSearch', **fields)
        if search:
            # Add additional search criteria
            for fieldName, fieldValue in search.fields.iteritems():
                # Management of searches restricted to objects linked through a
                # Ref field: not implemented yet.
                if fieldName == '_ref': continue
                # Make the correspondance between the name of the field and the
                # name of the corresponding index.
                attrName = Search.getIndexName(fieldName)
                # Express the field value in the way needed by the index
                params[attrName] = Search.getSearchValue(fieldName, fieldValue)
            # Add a sort order if specified
            sortKey = search.sortBy
            if sortKey:
                params['sort_on'] = Search.getIndexName(sortKey, usage='sort')
        # Determine or override sort if specified.
        if sortBy:
            params['sort_on'] = Search.getIndexName(sortBy, usage='sort')
            if sortOrder == 'desc': params['sort_order'] = 'reverse'
            else: params['sort_order'] = None
        # If defined, add the filter among search parameters.
        if filterKey:
            filterKey = Search.getIndexName(filterKey)
            filterValue = Search.getSearchValue(filterKey, filterValue)
            params[filterKey] = filterValue
            # TODO This value needs to be merged with an existing one if already
            # in params, or, in a first step, we should avoid to display the
            # corresponding filter widget on the screen.
        if refObject:
            refField = refObject.getAppyType(refField)
            params['UID'] = getattr(refObject, refField.name).data
        # Use index "Allowed" if noSecurity is False
        if not noSecurity: params['Allowed'] = self.getAllowedValue()
        brains = self.getPath("/catalog")(**params)
        if brainsOnly:
            # Return brains only.
            if not maxResults: return brains
            else: return brains[:maxResults]
        if not maxResults:
            if refField: maxResults = refField.maxPerPage
            else: maxResults = self.appy().numberOfResultsPerPage
        elif maxResults == 'NO_LIMIT': maxResults = None
        res = SomeObjects(brains,
                          maxResults,
                          startNumber,
                          noSecurity=noSecurity)
        res.brainsToObjects()
        # In some cases (p_remember=True), we need to keep some information
        # about the query results in the current user's session, allowing him
        # to navigate within elements without re-triggering the query every
        # time a page for an element is consulted.
        if remember:
            if not searchName:
                # It is the global search for all objects pf p_className
                searchName = className
            uids = {}
            i = -1
            for obj in res.objects:
                i += 1
                uids[startNumber + i] = obj.UID()
            self.REQUEST.SESSION['search_%s' % searchName] = uids
        return res.__dict__