def available(self):
     """
     Check if we have a collectionwidget criterion
     """
     try:
         getCollectionLinkCriterion(self.context)
     except NotDashboardContextException:
         return False
     return super(DashboardDocumentGeneratorLinksViewlet, self).available()
 def test_getCollectionLinkCriterion(self):
     """This method will return the Collection-link widget defined on a folder if ever."""
     # self.folder is faceted enabled
     self.assertEquals(getCollectionLinkCriterion(self.folder).widget,
                       CollectionWidget.widget_type)
     # remove the criterion then try to get it again
     ICriteria(self.folder).delete(getCollectionLinkCriterion(self.folder).getId())
     with self.assertRaises(NoCollectionWidgetDefinedException):
         getCollectionLinkCriterion(self.folder)
     # trying to get collection-link widget on a folder that is not
     # faceted enabled will raise a NoFacetedViewDefinedException
     folder3_id = self.portal.invokeFactory('Folder', 'folder3', title='Folder3')
     folder3 = getattr(self.portal, folder3_id)
     self.assertRaises(NoFacetedViewDefinedException, getCollectionLinkCriterion, folder3)
Пример #3
0
 def get_value(self):
     try:
         criterion = getCollectionLinkCriterion(self.context)
     except NoCollectionWidgetDefinedException:
         return ''
     attr = '{}[]'.format(criterion.__name__)
     return self.request.form.get(attr, '')
 def __call__(self):
     criteria_holder = self._criteriaHolder
     criterion = None
     try:
         criterion = getCollectionLinkCriterion(criteria_holder)
     except NoCollectionWidgetDefinedException:
         pass
     if criterion:
         # if we have the collection UID in the REQUEST, return self.index()
         # so we avoid the portal_catalog search for collection
         collectionUID = self.context.REQUEST.form.get('{0}[]'.format(criterion.__name__))
         if collectionUID or not criterion.default:
             return self.index()
         if not self.request['HTTP_REFERER'].endswith('configure_faceted.html') and \
            not self.request['URL'].endswith('folder_contents') and \
            not self.request.get('no_redirect', '0') == '1':
             catalog = api.portal.get_tool('portal_catalog')
             brains = catalog(UID=criterion.default)
             if brains:
                 collection = brains[0].getObject()
                 container = collection.aq_inner.aq_parent
                 if not container == criteria_holder and \
                    IFacetedNavigable.providedBy(container):
                     self.request.RESPONSE.redirect(container.absolute_url())
                     return ''
     return self.index()
    def test_can_be_generated(self):
        """Using same condition than ConfigurablePODTemplate and check
           also field 'dashboard_collections'."""
        # if not restricted to any 'dashboard_collections', available everywhere
        self.dashboardtemplate.dashboard_collections = []
        dashboardcollection1 = api.content.create(
            id='dc1',
            type='DashboardCollection',
            title='Dashboard collection 1',
            container=self.folder
        )
        dashboardcollection2 = api.content.create(
            id='dc2',
            type='DashboardCollection',
            title='Dashboard collection 2',
            container=self.folder
        )

        criterion_name = getCollectionLinkCriterion(self.folder).__name__
        self.request.form['{0}[]'.format(criterion_name)] = dashboardcollection1.UID()
        self.assertTrue(self.dashboardtemplate.can_be_generated(self.folder))

        # now if restricted to dashboardcollection2, it is no more generable
        self.dashboardtemplate.dashboard_collections = [dashboardcollection2.UID()]
        self.assertFalse(self.dashboardtemplate.can_be_generated(self.folder))
        # except if it is the current collection
        self.request.form['{0}[]'.format(criterion_name)] = dashboardcollection2.UID()
        # clear cache for collectionwidget.utils.getCurrentCollection
        cache_key = 'collectionwidget-utils-getCurrentCollection-{0}'.format(self.folder.UID())
        del IAnnotations(self.request)[cache_key]
        self.assertTrue(self.dashboardtemplate.can_be_generated(self.folder))
Пример #6
0
def projectspace_moved(obj, event):
    """ When a projectspace is renamed, we correct collections """
    if IObjectRemovedEvent.providedBy(event):
        return
    portal = api.portal.get()
    path = '/'.join(obj.getPhysicalPath())
    # correct path criteria in collections
    for brain in portal.portal_catalog(path=path,
                                       portal_type='DashboardCollection'):
        ob = brain.getObject()
        query = ob.query
        for elt in query:
            if elt['i'] == 'path':
                elt['v'] = path
        ob.query = query
    # correct default collection
    for brain in portal.portal_catalog(
            path=path, object_provides=ICollectionCategories.__identifier__):
        ob = brain.getObject()
        criterion = getCollectionLinkCriterion(ob)
        criterias = ICriteria(ob)
        old_uid = criterias.get(criterion.__name__).get('default')
        old_path = uuidToPhysicalPath(old_uid)
        old_id = os.path.basename(old_path)
        if old_path.endswith('/{}/{}'.format(ob.id, old_id)):
            default_col = ob[old_id].UID()
            _updateDefaultCollectionFor(ob, default_col)
            logger.info('Replaced default col {} by {} on {}'.format(
                old_uid, default_col, ob.absolute_url()))
        else:
            raise ValueError("Cannot update default col on {}".format(
                ob.absolute_url()))
Пример #7
0
 def get_value(self):
     try:
         criterion = getCollectionLinkCriterion(self.context)
     except NoCollectionWidgetDefinedException:
         return ''
     attr = '{}[]'.format(criterion.__name__)
     return self.request.form.get(attr, '')
Пример #8
0
 def test_enableFacetedDashboardFor_with_default_UID(self):
     """ """
     collection_uid = self.collection.UID()
     enableFacetedDashboardFor(self.portal.folder,
                               default_UID=collection_uid)
     self.assertEqual(
         getCollectionLinkCriterion(self.portal.folder).default,
         collection_uid)
    def getPortletTitle(self):
        """Return the collection widget display name"""
        try:
            criterion = getCollectionLinkCriterion(self._criteriaHolder)
        except NoFacetedViewDefinedException:
            return DEFAULT_PORTLET_TITLE

        title = criterion and criterion.title or DEFAULT_PORTLET_TITLE
        return title
    def test_updateDefaultCollectionFor(self):
        """This method will define the default collection used by the collection-link
           widget defined in a faceted enabled folder."""
        # get the collection-link and check that it has no default
        criterion = getCollectionLinkCriterion(self.folder)
        self.assertFalse(criterion.default)
        # right, do things correctly, add a DashboardCollection and use it as default
        dashcoll_id = self.folder.invokeFactory('DashboardCollection', 'dashcoll', title='Dashboard Collection')
        dashcoll = getattr(self.folder, dashcoll_id)
        dashcoll.reindexObject()
        _updateDefaultCollectionFor(self.folder, dashcoll.UID())
        self.assertEquals(criterion.default, dashcoll.UID())

        # calling it on a non faceted enabled folder will raise a NoFacetedViewDefinedException
        nonfacetedfolder_id = self.portal.invokeFactory('Folder', 'notnacetedfolder', title='Non Faceted Folder')
        nonfacetedfolder = getattr(self.portal, nonfacetedfolder_id)
        nonfacetedfolder.reindexObject()
        self.assertRaises(NoFacetedViewDefinedException, _updateDefaultCollectionFor, nonfacetedfolder, 'anUID')
    def test_getCurrentCollection(self):
        """Returns the Collection currently used by the CollectionWidget in a faceted."""
        dashcoll = self.collection1

        # current collection is get with collectionLink id in the REQUEST, not set for now
        criterion = getCollectionLinkCriterion(self.folder)
        criterion_name = '{0}[]'.format(criterion.__name__)
        request = self.portal.REQUEST
        self.assertFalse(criterion_name in request)
        self.assertIsNone(getCurrentCollection(self.folder))

        # set a correct collection in the REQUEST
        request.form[criterion_name] = dashcoll.UID()
        self.assertEquals(getCurrentCollection(self.folder), dashcoll)

        # it works also with 'facetedQuery' build in the REQUEST when generating
        # a template on a dashboard
        del request.form[criterion_name]
        self.assertIsNone(getCurrentCollection(self.folder))
        request.form['facetedQuery'] = '{{"c3":["20"],"b_start":["0"],"{0}":["{1}"]}}'.format(
            criterion.__name__, dashcoll.UID())
        self.assertEquals(getCurrentCollection(self.folder), dashcoll)
    def test_FacetedDashboardView(self):
        subtyper = getMultiAdapter((self.category1, self.request),
                                   name=u'faceted_subtyper')
        subtyper.enable()
        # enabling a faceted will redirect to it, so, cancel this
        self.request.RESPONSE.status = 200

        # when default in self.folder, not redirected already at the right place
        view = getMultiAdapter((self.folder, self.request), name=u'facetednavigation_view')
        crit = getCollectionLinkCriterion(self.folder)
        crit.default = self.collection2.UID()
        ret = view()
        self.assertIn('Base collections', ret)
        self.assertEquals(self.request.RESPONSE.status, 200)

        # now set default on a collection of the subfolder
        crit.default = self.collection1.UID()

        # not redirected if we are on folder/folder_contents or folder/configure_faceted.html
        # or it is no more possible to access the folder actions, always redirected to subfolder...
        self.request['URL'] = self.folder.absolute_url() + '/folder_contents'
        ret = view()
        self.assertIn('Base collections', ret)
        self.assertEquals(self.request.RESPONSE.status, 200)
        folderURL = self.folder.absolute_url()
        self.request['URL'] = folderURL
        self.request['HTTP_REFERER'] = self.folder.absolute_url() + '/configure_faceted.html'
        ret = view()
        self.assertIn('Base collections', ret)
        self.assertEquals(self.request.RESPONSE.status, 200)

        # we are redirected to the subfolder if accessing directly folder
        self.request['URL'] = folderURL
        self.request['HTTP_REFERER'] = folderURL
        ret = view()
        self.assertFalse(ret)
        self.assertEquals(self.request.RESPONSE.status, 302)
        self.assertEquals(self.request.RESPONSE.getHeader('location'), self.category1.absolute_url())
 def __call__(self):
     # view may be called on a faceted context or a sub-element, if it is a sub-element
     # get the first parent that is a faceted
     res = {}
     faceted_context = self.get_context(self.context)
     if faceted_context.meta_type != 'Plone Site':
         data = getCollectionLinkCriterion(faceted_context)
         widget = CollectionWidget(faceted_context, self.request, data)
         voc = widget._generate_vocabulary()
         info = []
         portal = api.portal.get()
         for category in voc.itervalues():
             for term in category['collections']:
                 collection = portal.unrestrictedTraverse(term.value)
                 if IDashboardCollection.providedBy(collection) \
                         and collection.showNumberOfItems:
                     view = collection.unrestrictedTraverse(
                         '@@render_collection_widget_term_portlet')
                     info.append({
                         'uid': term.token,
                         'count': view.number_of_items()
                     })
         res = {'criterionId': data.__name__, 'countByCollection': info}
     return json.dumps(res)
Пример #14
0
    def test_combined_index(self):
        """We made an index that index portal_type and review_state
           of contained elements, here we will query folders containing
           'Document' in state 'private'."""
        # set a correct collection in the REQUEST
        criterion = getCollectionLinkCriterion(self.folder)
        criterion_name = '{0}[]'.format(criterion.__name__)
        self.request.form[criterion_name] = self.dashboardcollection.UID()
        # add new widgets
        # c10 and c11 widgets are missing for now
        self.assertFalse(ICriteria(self.folder).get('c10'))
        self.assertFalse(ICriteria(self.folder).get('c11'))
        xmlpath = os.path.dirname(
            __file__) + '/faceted_conf/combined_index_widgets.xml'
        self.folder.unrestrictedTraverse('@@faceted_exportimport').import_xml(
            import_file=open(xmlpath))
        self.assertEquals(
            ICriteria(self.folder).get('c10').index,
            u'contained_types_and_states')
        self.assertEquals(
            ICriteria(self.folder).get('c11').index,
            COMBINED_INDEX_PREFIX + u'contained_types_and_states')
        # by default the dashboardcollection will return the every found folders, aka 6
        faceted_query = self.folder.restrictedTraverse('@@faceted_query')
        self.assertEquals(len(faceted_query.query()), 5)

        # filter on 'review_state', get the private elements
        self.request.form['c10[]'] = ''
        self.request.form['c11[]'] = 'private'
        self.assertEquals(
            faceted_query.criteria()['contained_types_and_states']['query'],
            'private')
        # we get folder1 and folder3
        uids = [brain.UID for brain in faceted_query.query()]
        self.assertEquals(len(faceted_query.query()), 2)
        self.assertTrue(self.folder1.UID() in uids
                        and self.folder3.UID() in uids)
        # filter on 'portal_type', get 'Document'
        self.request.form['c10[]'] = 'Document'
        self.request.form['c11[]'] = ''
        self.assertEquals(
            faceted_query.criteria()['contained_types_and_states']['query'],
            'Document')
        # we get folder1 and folder3
        uids = [brain.UID for brain in faceted_query.query()]
        self.assertEquals(len(faceted_query.query()), 2)
        self.assertTrue(self.folder1.UID() in uids
                        and self.folder3.UID() in uids)
        # but if we filter 'review_state' published, we only get folder1
        self.request.form['c10[]'] = 'Document'
        self.request.form['c11[]'] = 'published'
        self.assertEquals(
            faceted_query.criteria()['contained_types_and_states']['query'],
            ['Document__published'])
        uids = [brain.UID for brain in faceted_query.query()]
        self.assertEquals(len(faceted_query.query()), 1)
        self.assertTrue(self.folder1.UID() in uids)

        # query 'review_state' private and portal_type 'Document' and 'Folder'
        self.request.form['c10[]'] = ['Document', 'Folder']
        self.request.form['c11[]'] = 'private'
        self.assertEquals(
            faceted_query.criteria()['contained_types_and_states']['query'],
            ['Document__private', 'Folder__private'])
        uids = [brain.UID for brain in faceted_query.query()]
        self.assertEquals(len(faceted_query.query()), 2)
        self.assertTrue(self.folder1.UID() in uids
                        and self.folder3.UID() in uids)
Пример #15
0
    def test_combined_index(self):
        """We made an index that index portal_type and review_state
           of contained elements, here we will query folders containing
           'Document' in state 'private'."""
        # set a correct collection in the REQUEST
        criterion = getCollectionLinkCriterion(self.folder)
        criterion_name = '{0}[]'.format(criterion.__name__)
        self.request.form[criterion_name] = self.dashboardcollection.UID()
        # add new widgets
        # c10 and c11 widgets are missing for now
        self.assertFalse(ICriteria(self.folder).get('c10'))
        self.assertFalse(ICriteria(self.folder).get('c11'))
        xmlpath = os.path.dirname(__file__) + '/faceted_conf/combined_index_widgets.xml'
        self.folder.unrestrictedTraverse('@@faceted_exportimport').import_xml(
            import_file=open(xmlpath))
        self.assertEquals(ICriteria(self.folder).get('c10').index,
                          u'contained_types_and_states')
        self.assertEquals(ICriteria(self.folder).get('c11').index,
                          COMBINED_INDEX_PREFIX + u'contained_types_and_states')
        # by default the dashboardcollection will return the every found folders, aka 6
        faceted_query = self.folder.restrictedTraverse('@@faceted_query')
        self.assertEquals(len(faceted_query.query()), 5)

        # filter on 'review_state', get the private elements
        self.request.form['c10[]'] = ''
        self.request.form['c11[]'] = 'private'
        self.assertEquals(faceted_query.criteria()['contained_types_and_states']['query'],
                          'private')
        # we get folder1 and folder3
        uids = [brain.UID for brain in faceted_query.query()]
        self.assertEquals(len(faceted_query.query()), 2)
        self.assertTrue(self.folder1.UID() in uids and
                        self.folder3.UID() in uids)
        # filter on 'portal_type', get 'Document'
        self.request.form['c10[]'] = 'Document'
        self.request.form['c11[]'] = ''
        self.assertEquals(faceted_query.criteria()['contained_types_and_states']['query'],
                          'Document')
        # we get folder1 and folder3
        uids = [brain.UID for brain in faceted_query.query()]
        self.assertEquals(len(faceted_query.query()), 2)
        self.assertTrue(self.folder1.UID() in uids and
                        self.folder3.UID() in uids)
        # but if we filter 'review_state' published, we only get folder1
        self.request.form['c10[]'] = 'Document'
        self.request.form['c11[]'] = 'published'
        self.assertEquals(faceted_query.criteria()['contained_types_and_states']['query'],
                          ['Document__published'])
        uids = [brain.UID for brain in faceted_query.query()]
        self.assertEquals(len(faceted_query.query()), 1)
        self.assertTrue(self.folder1.UID() in uids)

        # query 'review_state' private and portal_type 'Document' and 'Folder'
        self.request.form['c10[]'] = ['Document', 'Folder']
        self.request.form['c11[]'] = 'private'
        self.assertEquals(faceted_query.criteria()['contained_types_and_states']['query'],
                          ['Document__private', 'Folder__private'])
        uids = [brain.UID for brain in faceted_query.query()]
        self.assertEquals(len(faceted_query.query()), 2)
        self.assertTrue(self.folder1.UID() in uids and
                        self.folder3.UID() in uids)
Пример #16
0
 def getCollectionWidgetId(self):
     """Returns the collection widget id to be used in the URL generated on the collection link."""
     criterion = getCollectionLinkCriterion(self._criteriaHolder)
     if criterion:
         return criterion.getId()
     return ''
Пример #17
0
    def test_portlet_widget_render(self):
        """The portlet will render collection-link widgets defined
           on the faceted config.  This portlet has 2 behaviours :
           - classic faceted widget behaviour when displayed directly on the folder
             on which the faceted is applied : it uses the faceted js onclick to update the faceted;
           - 'fake' widget displayed as the real widget but instead of controlling the faceted
             it has a link on every disiplayed collection that will move to the faceted
             correctly initialized."""
        self.subtyper.enable()
        criteria = ICriteria(self.renderer._criteriaHolder)
        # remove the collection-link widget
        collcriterion = getCollectionLinkCriterion(self.renderer._criteriaHolder)
        ICriteria(self.renderer._criteriaHolder).delete(collcriterion.getId())
        # by defaut no collection-link widget so nothing is rendered
        self.assertTrue(not [criterion for criterion in criteria.values()
                             if criterion.widget == CollectionWidget.widget_type])
        with self.assertRaises(NoCollectionWidgetDefinedException):
            getCollectionLinkCriterion(self.renderer._criteriaHolder)
        self.assertTrue(not self.renderer.widget_render)
        # add a collection-link widget
        data = {'vocabulary': 'collective.eeafaceted.collectionwidget.collectionvocabulary',
                'hidealloption': True}
        ICriteria(self.folder).add('collection-link', 'top', **data)
        # still displaying nothing as the collection widget does not find any collection
        self.assertTrue(not self.renderer.widget_render.strip())
        # add a DashboardCollection in self.folder
        collection = api.content.create(
            id='dashboardcollection1',
            type='DashboardCollection',
            title='Dashboard collection 1',
            container=self.folder,
            query='',
            sort_on='',
            sort_reversed=False,
            showNumberOfItems=True,
            tal_condition=u'',
            roles_bypassing_talcondition=[])
        # clean memoize for widget.categories,
        # it was memoized when calling _generate_vocabulary here above
        del IAnnotations(self.request)['plone.memoize']
        # now it is displayed and as we are on the faceted, it behaves like the collection widget
        # a <form> with an action
        # get the '<ul>' displaying collections
        # update renderer
        self.renderer = self._get_portlet_renderer()
        self.assertTrue("<form" in self.renderer.widget_render)
        ul_tag = lxml.html.fromstring(self.renderer.widget_render)[0][0]
        # only 1 children, the collection and the href is as special javascript call that does nothing
        self.assertTrue(len(ul_tag.getchildren()) == 1)
        div_tag = ul_tag.getchildren()[0]
        li_tag = div_tag.getchildren()[0]
        self.assertTrue(li_tag.attrib['value'] == collection.UID())
        self.assertTrue(len(li_tag.getchildren()) == 1)
        a_tag = li_tag.getchildren()[0]
        self.assertTrue(a_tag.attrib['href'] == 'javascript:;')

        # now get the portlet from a sub element so it behaves differently
        # it is no more a faceted widget but and the href will redirect to the faceted with default parameters
        subrenderer = getMultiAdapter((collection,
                                       self.request,
                                       self.view,
                                       self.manager,
                                       self.assignment),
                                      IPortletRenderer)
        # no more <form> this time
        self.assertTrue("<form" not in subrenderer.widget_render)
        ul_tag = lxml.html.fromstring(subrenderer.widget_render)[0]
        # only 1 children, the collection and the href is a link back to the href with correct default parameters
        self.assertTrue(len(ul_tag.getchildren()) == 1)
        li_tag = ul_tag.getchildren()[0]
        self.assertTrue(li_tag.attrib['value'] == collection.UID())
        self.assertTrue(len(li_tag.getchildren()) == 1)
        a_tag = li_tag.getchildren()[0]
        # the URL is generated and contains every default values and relevant collection UID
        url = "http://nohost/plone/folder#c3=20&c1={0}".format(collection.UID())
        self.assertEquals(a_tag.attrib['href'], url)