source: products/quintagroup.referencedatagridfield/trunk/quintagroup/referencedatagridfield/_field.py @ 2279

Last change on this file since 2279 was 2278, checked in by mylan, 14 years ago

Split link_uid on link and uid columns

  • Property svn:eol-style set to native
File size: 5.6 KB
RevLine 
[2259]1#from Products.Archetypes import atapi
[2263]2import re
[2260]3import logging
[2263]4import urlparse
5from urllib import quote
6from types import ListType, TupleType
7
[2260]8from AccessControl import ClassSecurityInfo
[2263]9
10from Products.CMFCore.utils import getToolByName
11from Products.validation import validation #validators import baseValidators
[2266]12from Products.Archetypes.Field import encode, ReferenceField
[2259]13from Products.Archetypes.Registry import registerField, registerWidget
14
[2266]15from Products.ATReferenceBrowserWidget.ATReferenceBrowserWidget import ReferenceBrowserWidget
16
[2259]17from Products.DataGridField.DataGridField import DataGridField
18from Products.DataGridField.DataGridWidget import DataGridWidget
19
[2263]20
[2260]21# Logger object
22#logger = logging.getLogger('ReferenceDataGridField')
23#logger.debug("ReferenceDataGrid loading")
24
[2266]25class ReferenceDataGridWidget(DataGridWidget, ReferenceBrowserWidget):
26    _properties = ReferenceBrowserWidget._properties.copy()
27    _properties.update(DataGridWidget._properties.copy())
[2260]28    _properties.update({
[2266]29        'macro': "referencedatagridwidget",
[2278]30        'column_names': ["Title", "Link", "UID"],
[2266]31        'helper_css': ('datagridwidget.css',),
32        'helper_js': ('referencebrowser.js', 'datagridwidget.js',),
[2274]33        'force_close_on_insert': True,
[2260]34        })
[2259]35
[2263]36isURL = validation.validatorFor('isURL')
37
[2266]38class ReferenceDataGridField(DataGridField, ReferenceField):
39    _properties = ReferenceField._properties.copy()
40    _properties.update(DataGridField._properties.copy())
[2259]41    _properties.update({
[2278]42        'columns': ('title', 'link', 'uid'),
[2259]43        'widget': ReferenceDataGridWidget,
[2274]44        'multiValued' : True,
[2259]45        })
46
[2263]47    security = ClassSecurityInfo()
48
49    security.declarePrivate('isRemoteURL')
50    def isRemoteURL(self, url):
[2264]51        return isURL(url) == 1 and True or False
[2263]52
53    security.declarePrivate('set')
54    def set(self, instance, value, **kwargs):
55        """
56        The passed in object should be a records object, or a sequence of dictionaries
[2278]57        About link data:
[2263]58          * interpretations:
[2278]59            * if data not starts with standard protocol names (http://, ftp://) than
60              *uid* field data will be used as reference
[2263]61          * record removed if:
62            * no data;
63            * data contains UID of not existent object
64        About title:
[2278]65          * if there is UID of existent object and record has same title to the original
66            object - title will not be saved.
[2263]67        """
68        catalog = getToolByName(instance, "uid_catalog")
69
70        if value is None:
71            value = ()
72
73        if not isinstance(value, (ListType, TupleType)):
74            value = value,
75
76        result = []
77        for row in value:
[2278]78            data = {"title":"", "link":"", "uid":""}
[2263]79
[2278]80            uid = str(row.get("uid", "")).strip()
81            link = str(row.get("link", "")).strip()
[2263]82            title = str(row.get('title', "")).strip()
[2278]83
[2263]84            if not title == "":
85                data["title"] = title
86
[2278]87            if link == "":
[2263]88                continue
[2278]89            elif self.isRemoteURL(link):
90                data["link"] = urlparse.urlunparse(urlparse.urlparse(link))
[2263]91            else:
[2278]92                if uid == '':
93                    continue
94
95                brains = catalog(UID=uid)
[2263]96                if len(brains) == 0:
97                    continue
[2274]98                # Found objects with pointed UID
99                brain = brains[0]
[2278]100                data["uid"] = uid
101                # Fix title for uid
102                if data['title'] == getattr(brain, "Title", ""):
103                    data['title'] = ""
[2263]104            result.append(data)
105
106        DataGridField.set(self, instance, result, **kwargs)
[2278]107
108        uids = [r['uid'] for r in result if r['uid']!=""]
[2274]109        ReferenceField.set(self, instance, uids, **kwargs)
110       
[2263]111    security.declarePrivate('get')
112    def get(self, instance, **kwargs):
113        """ Return DataGridField value
114
115        Value is a list object of rows.
[2278]116        Row id dictionary object with standard 'link', 'uid' and 'title' keys
117        plus extra informal *url* and *url_title* keys
[2263]118        """
119        purl = getToolByName(instance, "portal_url")
[2278]120        # use portal_catalog to hide protected object for the logged in user.
[2275]121        catalog = getToolByName(instance, "portal_catalog")
[2263]122
123        result = []
[2275]124        uids = {}
[2263]125        rows = DataGridField.get(self, instance, **kwargs)
126        for row in rows:
[2276]127            result.append({
128                # DataGridField row data
[2278]129                "uid": row["uid"],
130                "link": row["link"],
[2276]131                "title": row["title"],
132                # View data
[2278]133                "url": "",
134                "url_title": row["title"]})
[2275]135            data = result[-1]
136            # Process remote URL and collect UIDs
[2278]137            if row["link"]:
138                data["url"] = quote(row["link"], safe='?$#@/:=+;$,&%')
[2275]139                # if title not set for remote url - set it equals to url
[2278]140                if not data["url_title"]:
141                    data["url_title"] = row["link"]
[2263]142            else:
[2278]143                uids[row["uid"]] = data
[2275]144        # Process UIDs
145        if uids:
146            brains = catalog(UID=uids.keys())
147            for b in brains:
148                data = uids[b.UID]
[2278]149                data["url"] = b.getURL()
[2275]150                # If title not set - get it from the brain
[2278]151                if not data["url_title"]:
152                    data["url_title"] = self._brains_title_or_id(b, instance)
[2263]153
154        return result
155
[2274]156
[2259]157registerWidget(
158    ReferenceDataGridWidget,
159    title='DataGrid Reference',
160    used_for=('quintagroup.referencedatagridfield.ReferenceDataGridField',)
161    )
162
163registerField(
164    ReferenceDataGridField,
165    title="DataGrid Reference Field",
166    description=("Reference DataGrid field.")
167    )
Note: See TracBrowser for help on using the repository browser.