web/views/editcontroller.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Mon, 21 Dec 2009 19:52:21 +0100
changeset 4160 3fbdeef9a610
parent 4110 8728d8c95985
child 4171 f1b9f0ed1253
permissions -rw-r--r--
cleanup
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     1
"""The edit controller, handling form submitting.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     2
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     3
:organization: Logilab
1977
606923dff11b big bunch of copyright / docstring update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1948
diff changeset
     4
:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     5
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
1977
606923dff11b big bunch of copyright / docstring update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1948
diff changeset
     6
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     7
"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     8
__docformat__ = "restructuredtext en"
1948
887ed691c635 cosmetic
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1940
diff changeset
     9
4160
3fbdeef9a610 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4110
diff changeset
    10
from rql.utils import rqlvar_maker
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    11
4160
3fbdeef9a610 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4110
diff changeset
    12
from logilab.common.textutils import splitstrip
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    13
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    14
from cubicweb import Binary, ValidationError, typed_eid
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    15
from cubicweb.web import INTERNAL_FIELD_VALUE, RequestError, NothingToEdit, ProcessFormError
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    16
from cubicweb.web.controller import parse_relations_descr
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    17
from cubicweb.web.views.basecontrollers import ViewController
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    18
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    19
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    20
class RqlQuery(object):
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    21
    def __init__(self):
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    22
        self.edited = []
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    23
        self.restrictions = []
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    24
        self.kwargs = {}
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    25
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    26
    def insert_query(self, etype):
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    27
        if self.edited:
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    28
            rql = 'INSERT %s X: %s' % (etype, ','.join(self.edited))
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    29
        else:
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    30
            rql = 'INSERT %s X' % etype
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    31
        if self.restrictions:
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    32
            rql += ' WHERE %s' % ','.join(self.restrictions)
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    33
        return rql
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    34
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    35
    def update_query(self, eid):
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    36
        varmaker = rqlvar_maker()
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    37
        var = varmaker.next()
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    38
        while var in self.kwargs:
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    39
            var = varmaker.next()
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    40
        rql = 'SET %s WHERE X eid %%(%s)s' % (','.join(self.edited), var)
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    41
        if self.restrictions:
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    42
            rql += ', %s' % ','.join(self.restrictions)
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    43
        self.kwargs[var] = eid
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    44
        return rql
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    45
4160
3fbdeef9a610 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4110
diff changeset
    46
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    47
class EditController(ViewController):
3377
dd9d292b6a6d use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3369
diff changeset
    48
    __regid__ = 'edit'
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    49
2255
c346af0727ca more generic way to detect json requests (not yet perfect though)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    50
    def publish(self, rset=None):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    51
        """edit / create / copy / delete entity / relations"""
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
    52
        for key in self._cw.form:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    53
            # There should be 0 or 1 action
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    54
            if key.startswith('__action_'):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    55
                cbname = key[1:]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    56
                try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    57
                    callback = getattr(self, cbname)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    58
                except AttributeError:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
    59
                    raise RequestError(self._cw._('invalid action %r' % key))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    60
                else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    61
                    return callback()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    62
        self._default_publish()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    63
        self.reset()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    64
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    65
    def _default_publish(self):
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
    66
        req = self._cw
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    67
        self.errors = []
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    68
        self.relations_rql = []
4007
91d11fda4aa0 more api renaming/fixing update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 3998
diff changeset
    69
        form = req.form
3921
4f24b6ef3da9 edit controller now informs server side about its main eid through transaction data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3689
diff changeset
    70
        # so we're able to know the main entity from the repository side
4f24b6ef3da9 edit controller now informs server side about its main eid through transaction data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3689
diff changeset
    71
        if '__maineid' in form:
3924
4347654979e8 don't type __maineid, it may not be an eid actually
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3921
diff changeset
    72
            req.set_shared_data('__maineid', form['__maineid'], querydata=True)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    73
        # no specific action, generic edition
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    74
        self._to_create = req.data['eidmap'] = {}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    75
        self._pending_relations = []
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
    76
        todelete = self._cw.get_pending_deletes()
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
    77
        toinsert = self._cw.get_pending_inserts()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    78
        try:
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    79
            methodname = req.form.pop('__method', None)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    80
            for eid in req.edited_eids():
3309
2538daa6651c we may have some entity forms with nothing to edit for an entity, no RequestError in that case
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3194
diff changeset
    81
                # __type and eid
2538daa6651c we may have some entity forms with nothing to edit for an entity, no RequestError in that case
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3194
diff changeset
    82
                formparams = req.extract_entity_params(eid, minparams=2)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    83
                if methodname is not None:
2680
66472d85d548 [R] use req.entity_from_eid
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
    84
                    entity = req.entity_from_eid(eid)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    85
                    method = getattr(entity, methodname)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    86
                    method(formparams)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    87
                eid = self.edit_entity(formparams)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    88
        except (RequestError, NothingToEdit):
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    89
            if '__linkto' in req.form and 'eid' in req.form:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    90
                self.execute_linkto()
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    91
            elif not ('__delete' in req.form or '__insert' in req.form or todelete or toinsert):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    92
                raise ValidationError(None, {None: req._('nothing to edit')})
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    93
        for querydef in self.relations_rql:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
    94
            self._cw.execute(*querydef)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    95
        # handle relations in newly created entities
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    96
        # XXX find a way to merge _pending_relations and relations_rql
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    97
        if self._pending_relations:
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    98
            for form, field, entity in self._pending_relations:
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
    99
                for querydef in self.handle_relation(form, field, entity, True):
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   100
                    self._cw.execute(*querydef)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   101
        # XXX this processes *all* pending operations of *all* entities
3384
f76a38731bc1 [forms] work-in-progress: get rid of edits- / edito-
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2680
diff changeset
   102
        if req.form.has_key('__delete'):
f76a38731bc1 [forms] work-in-progress: get rid of edits- / edito-
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2680
diff changeset
   103
            todelete += req.list_form_param('__delete', req.form, pop=True)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   104
        if todelete:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   105
            self.delete_relations(parse_relations_descr(todelete))
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   106
        if req.form.has_key('__insert'):
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   107
            toinsert = req.list_form_param('__insert', req.form, pop=True)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   108
        if toinsert:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   109
            self.insert_relations(parse_relations_descr(toinsert))
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   110
        self._cw.remove_pending_operations()
1753
ba01605cdd9a delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1361
diff changeset
   111
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   112
    def _insert_entity(self, etype, eid, rqlquery):
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   113
        rql = rqlquery.insert_query(etype)
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   114
        try:
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   115
            # get the new entity (in some cases, the type might have
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   116
            # changed as for the File --> Image mutation)
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   117
            entity = self._cw.execute(rql, rqlquery.kwargs).get_entity(0, 0)
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   118
            neweid = entity.eid
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   119
        except ValidationError, ex:
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   120
            self._to_create[eid] = ex.entity
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   121
            if self._cw.json_request: # XXX (syt) why?
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   122
                ex.entity = eid
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   123
            raise
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   124
        self._to_create[eid] = neweid
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   125
        return neweid
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   126
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   127
    def _update_entity(self, eid, rqlquery):
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   128
        rql = rqlquery.update_query(eid)
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   129
        self._cw.execute(rql, rqlquery.kwargs)
1753
ba01605cdd9a delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1361
diff changeset
   130
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   131
    def edit_entity(self, formparams, multiple=False):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   132
        """edit / create / copy an entity and return its eid"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   133
        etype = formparams['__type']
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   134
        entity = self._cw.vreg['etypes'].etype_class(etype)(self._cw)
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   135
        entity.eid = formparams['eid']
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   136
        eid = self._get_eid(entity.eid)
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   137
        is_main_entity = self._cw.form.get('__maineid') == formparams['eid']
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   138
        # let a chance to do some entity specific stuff.tn
1753
ba01605cdd9a delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1361
diff changeset
   139
        entity.pre_web_edit()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   140
        # create a rql query from parameters
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   141
        rqlquery = RqlQuery()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   142
        # process inlined relations at the same time as attributes
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   143
        # this will generate less rql queries and might be useful in
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   144
        # a few dark corners
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   145
        formid = self._cw.form.get('__form_id', 'edition')
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   146
        form = self._cw.vreg['forms'].select(formid, self._cw, entity=entity)
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   147
        for field in form.fields:
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   148
            if form.form_field_modified(field):
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   149
                self.handle_formfield(form, field, entity, rqlquery)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   150
        if eid is None: # creation or copy
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   151
            entity.eid = self._insert_entity(etype, formparams['eid'], rqlquery)
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   152
        elif rqlquery.edited: # edition of an existant entity
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   153
            self._update_entity(eid, rqlquery)
3386
ab797c5374b7 [editcontroller] rename is_edited variable into is_main_entity to make things clearer
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3384
diff changeset
   154
        if is_main_entity:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   155
            self.notify_edited(entity)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   156
        if formparams.has_key('__delete'):
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   157
            todelete = self._cw.list_form_param('__delete', formparams, pop=True)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   158
            self.delete_relations(parse_relations_descr(todelete))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   159
        if formparams.has_key('__cloned_eid'):
3631
6176ef2f6488 give correctly typed eid
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3309
diff changeset
   160
            entity.copy_relations(typed_eid(formparams['__cloned_eid']))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   161
        if formparams.has_key('__insert'):
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   162
            toinsert = self._cw.list_form_param('__insert', formparams, pop=True)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   163
            self.insert_relations(parse_relations_descr(toinsert))
3386
ab797c5374b7 [editcontroller] rename is_edited variable into is_main_entity to make things clearer
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3384
diff changeset
   164
        if is_main_entity: # only execute linkto for the main entity
4073
03681ba6da0b cw 3.6 api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4053
diff changeset
   165
            self.execute_linkto(entity.eid)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   166
        return eid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   167
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   168
    def handle_formfield(self, form, field, entity, rqlquery):
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   169
        eschema = entity.e_schema
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   170
        try:
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   171
            for attr, value in field.process_posted(form):
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   172
                if not (
4053
7cc66b1d9183 more api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4045
diff changeset
   173
                    (field.role == 'subject' and field.name in eschema.subjrels)
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   174
                    or
4053
7cc66b1d9183 more api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4045
diff changeset
   175
                    (field.role == 'object' and field.name in eschema.objrels)):
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   176
                    continue
4045
f4a52abb6f4f cw 3.6 api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4007
diff changeset
   177
                rschema = self._cw.vreg.schema.rschema(field.name)
4053
7cc66b1d9183 more api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4045
diff changeset
   178
                if rschema.final:
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   179
                    rqlquery.kwargs[attr] = value
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   180
                    rqlquery.edited.append('X %s %%(%s)s' % (attr, attr))
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   181
                elif rschema.inlined:
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   182
                    self.handle_inlined_relation(form, field, entity, rqlquery)
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   183
                else:
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   184
                    self.relations_rql += self.handle_relation(
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   185
                        form, field, entity)
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   186
        except ProcessFormError, exc:
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   187
            self.errors.append((field, exc))
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   188
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   189
    def _action_apply(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   190
        self._default_publish()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   191
        self.reset()
1753
ba01605cdd9a delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1361
diff changeset
   192
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   193
    def _action_cancel(self):
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   194
        errorurl = self._cw.form.get('__errorurl')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   195
        if errorurl:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   196
            self._cw.cancel_edition(errorurl)
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   197
        self._cw.message = self._cw._('edit canceled')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   198
        return self.reset()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   199
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   200
    def _action_delete(self):
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   201
        self.delete_entities(self._cw.edited_eids(withtype=True))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   202
        return self.reset()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   203
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   204
    def _relation_values(self, form, field, entity, late=False):
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   205
        """handle edition for the (rschema, x) relation of the given entity
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   206
        """
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   207
        values = set()
3463
bc2ee1d059fd [editcontroller] fix bad method name: s/process_form_data/process_form_value
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3451
diff changeset
   208
        for eid in field.process_form_value(form):
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   209
            if not eid: # AutoCompletionWidget
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   210
                continue
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   211
            typed_eid = self._get_eid(eid)
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   212
            if typed_eid is None:
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   213
                if late:
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   214
                    # eid is still None while it's already a late call
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   215
                    # this mean that the associated entity has not been created
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   216
                    raise Exception("eid %s is still not created" % eid)
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   217
                self._pending_relations.append( (form, field, entity) )
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   218
                return None
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   219
            values.add(typed_eid)
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   220
        return values
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   221
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   222
    def handle_inlined_relation(self, form, field, entity, rqlquery):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   223
        """handle edition for the (rschema, x) relation of the given entity
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   224
        """
4110
8728d8c95985 [mq]: fix_for_forms
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 4073
diff changeset
   225
        if entity.has_eid():
8728d8c95985 [mq]: fix_for_forms
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 4073
diff changeset
   226
            origvalues = set(row[0] for row in entity.related(field.name, field.role))
8728d8c95985 [mq]: fix_for_forms
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 4073
diff changeset
   227
        else:
8728d8c95985 [mq]: fix_for_forms
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 4073
diff changeset
   228
            origvalues = set()
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   229
        values  = self._relation_values(form, field, entity)
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   230
        if values is None or values == origvalues:
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   231
            return # not edited / not modified / to do later
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   232
        attr = field.name
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   233
        if values:
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   234
            rqlquery.kwargs[attr] = iter(values).next()
4110
8728d8c95985 [mq]: fix_for_forms
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 4073
diff changeset
   235
            rqlquery.edited.append('X %s %s' % (attr, attr.upper()))
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   236
            rqlquery.restrictions.append('%s eid %%(%s)s' % (attr.upper(), attr))
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   237
        elif entity.has_eid():
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   238
            self.relations_rql += self.handle_relation(form, field, entity)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   239
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   240
    def handle_relation(self, form, field, entity, late=False):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   241
        """handle edition for the (rschema, x) relation of the given entity
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   242
        """
4110
8728d8c95985 [mq]: fix_for_forms
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 4073
diff changeset
   243
        if entity.has_eid():
8728d8c95985 [mq]: fix_for_forms
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 4073
diff changeset
   244
            origvalues = set(row[0] for row in entity.related(field.name, field.role))
8728d8c95985 [mq]: fix_for_forms
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 4073
diff changeset
   245
        else:
8728d8c95985 [mq]: fix_for_forms
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 4073
diff changeset
   246
            origvalues = set()
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   247
        values  = self._relation_values(form, field, entity, late)
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   248
        if values is None or values == origvalues:
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   249
            return # not edited / not modified / to do later
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   250
        etype = entity.e_schema
4045
f4a52abb6f4f cw 3.6 api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4007
diff changeset
   251
        rschema = self._cw.vreg.schema.rschema(field.name)
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   252
        if field.role == 'subject':
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   253
            desttype = rschema.objects(etype)[0]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   254
            card = rschema.rproperty(etype, desttype, 'cardinality')[0]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   255
            subjvar, objvar = 'X', 'Y'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   256
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   257
            desttype = rschema.subjects(etype)[0]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   258
            card = rschema.rproperty(desttype, etype, 'cardinality')[1]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   259
            subjvar, objvar = 'Y', 'X'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   260
        eid = entity.eid
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   261
        if field.role == 'object' or not rschema.inlined or not values:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   262
            # this is not an inlined relation or no values specified,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   263
            # explicty remove relations
1798
cc86fe8efaaa pass default values along the whole call chain, fix hidden field update bug
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1765
diff changeset
   264
            rql = 'DELETE %s %s %s WHERE X eid %%(x)s, Y eid %%(y)s' % (
cc86fe8efaaa pass default values along the whole call chain, fix hidden field update bug
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1765
diff changeset
   265
                subjvar, rschema, objvar)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   266
            for reid in origvalues.difference(values):
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   267
                yield (rql, {'x': eid, 'y': reid}, ('x', 'y'))
1798
cc86fe8efaaa pass default values along the whole call chain, fix hidden field update bug
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1765
diff changeset
   268
        seteids = values.difference(origvalues)
cc86fe8efaaa pass default values along the whole call chain, fix hidden field update bug
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1765
diff changeset
   269
        if seteids:
cc86fe8efaaa pass default values along the whole call chain, fix hidden field update bug
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1765
diff changeset
   270
            rql = 'SET %s %s %s WHERE X eid %%(x)s, Y eid %%(y)s' % (
cc86fe8efaaa pass default values along the whole call chain, fix hidden field update bug
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1765
diff changeset
   271
                subjvar, rschema, objvar)
cc86fe8efaaa pass default values along the whole call chain, fix hidden field update bug
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1765
diff changeset
   272
            for reid in seteids:
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   273
                yield (rql, {'x': eid, 'y': reid}, ('x', 'y'))
1753
ba01605cdd9a delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1361
diff changeset
   274
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   275
    def _get_eid(self, eid):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   276
        # should be either an int (existant entity) or a variable (to be
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   277
        # created entity)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   278
        assert eid or eid == 0, repr(eid) # 0 is a valid eid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   279
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   280
            return typed_eid(eid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   281
        except ValueError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   282
            try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   283
                return self._to_create[eid]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   284
            except KeyError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   285
                self._to_create[eid] = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   286
                return None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   287
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   288
    def _linked_eids(self, eids, late=False):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   289
        """return a list of eids if they are all known, else raise ToDoLater
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   290
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   291
1753
ba01605cdd9a delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1361
diff changeset
   292