web/views/editcontroller.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Tue, 13 Apr 2010 12:19:24 +0200
changeset 5223 6abd6e3599f4
parent 5174 78438ad513ca
child 5423 e15abfdcce38
permissions -rw-r--r--
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
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
4212
ab6573088b4a update copyright: welcome 2010
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3924
diff changeset
     4
:copyright: 2001-2010 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
4932
dce5ebe5d598 add missing warn imports
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
    10
from warnings import warn
dce5ebe5d598 add missing warn imports
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
    11
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    12
from rql.utils import rqlvar_maker
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    13
4160
3fbdeef9a610 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4110
diff changeset
    14
from logilab.common.textutils import splitstrip
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    15
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    16
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
    17
from cubicweb.web import INTERNAL_FIELD_VALUE, RequestError, NothingToEdit, ProcessFormError
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4359
diff changeset
    18
from cubicweb.web.views import basecontrollers, autoform
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    19
5038
90493551b1eb [form] fix validation error handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4940
diff changeset
    20
def valerror_eid(eid):
90493551b1eb [form] fix validation error handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4940
diff changeset
    21
    try:
90493551b1eb [form] fix validation error handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4940
diff changeset
    22
        return typed_eid(eid)
90493551b1eb [form] fix validation error handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4940
diff changeset
    23
    except (ValueError, TypeError):
90493551b1eb [form] fix validation error handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4940
diff changeset
    24
        return eid
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    25
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
    26
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
    27
    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
    28
        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
        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
    30
        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
    31
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
    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
    33
        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
    34
            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
    35
        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
    36
            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
    37
        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
    38
            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
    39
        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
    40
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
    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
    42
        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
    43
        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
    44
        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
    45
            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
    46
        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
    47
        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
    48
            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
    49
        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
    50
        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
    51
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    52
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4359
diff changeset
    53
class EditController(basecontrollers.ViewController):
3377
dd9d292b6a6d use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3369
diff changeset
    54
    __regid__ = 'edit'
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    55
2255
c346af0727ca more generic way to detect json requests (not yet perfect though)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    56
    def publish(self, rset=None):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    57
        """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
    58
        for key in self._cw.form:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    59
            # There should be 0 or 1 action
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    60
            if key.startswith('__action_'):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    61
                cbname = key[1:]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    62
                try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    63
                    callback = getattr(self, cbname)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    64
                except AttributeError:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
    65
                    raise RequestError(self._cw._('invalid action %r' % key))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    66
                else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    67
                    return callback()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    68
        self._default_publish()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    69
        self.reset()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    70
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    71
    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
    72
        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
    73
        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
    74
        self.relations_rql = []
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    75
        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
    76
        # 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
    77
        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
    78
            req.set_shared_data('__maineid', form['__maineid'], querydata=True)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    79
        # no specific action, generic edition
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    80
        self._to_create = req.data['eidmap'] = {}
4226
67dd296f864d should use a set for pending fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4224
diff changeset
    81
        self._pending_fields = req.data['pendingfields'] = set()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    82
        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
    83
            methodname = req.form.pop('__method', None)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    84
            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
    85
                # __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
    86
                formparams = req.extract_entity_params(eid, minparams=2)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    87
                if methodname is not None:
2680
66472d85d548 [R] use req.entity_from_eid
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
    88
                    entity = req.entity_from_eid(eid)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    89
                    method = getattr(entity, methodname)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    90
                    method(formparams)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    91
                eid = self.edit_entity(formparams)
4171
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
    92
        except (RequestError, NothingToEdit), ex:
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
            if '__linkto' in req.form and 'eid' in req.form:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    94
                self.execute_linkto()
4277
35cd057339b2 turn all the stuff used to handle 'generic relations' in forms into proper
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
    95
            elif not ('__delete' in req.form or '__insert' in req.form):
4171
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
    96
                raise ValidationError(None, {None: unicode(ex)})
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    97
        # handle relations in newly created entities
4171
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
    98
        if self._pending_fields:
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
    99
            for form, field in self._pending_fields:
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   100
                self.handle_formfield(form, field)
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   101
        # execute rql to set all 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
   102
        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
   103
            self._cw.execute(*querydef)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   104
        # 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
   105
        if req.form.has_key('__delete'):
4277
35cd057339b2 turn all the stuff used to handle 'generic relations' in forms into proper
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   106
            todelete = req.list_form_param('__delete', req.form, pop=True)
35cd057339b2 turn all the stuff used to handle 'generic relations' in forms into proper
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   107
            if todelete:
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4359
diff changeset
   108
                autoform.delete_relations(self._cw, 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
   109
        if req.form.has_key('__insert'):
4277
35cd057339b2 turn all the stuff used to handle 'generic relations' in forms into proper
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   110
            warn('[3.6] stop using __insert, support will be removed',
35cd057339b2 turn all the stuff used to handle 'generic relations' in forms into proper
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   111
                 DeprecationWarning)
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
            toinsert = req.list_form_param('__insert', req.form, pop=True)
4277
35cd057339b2 turn all the stuff used to handle 'generic relations' in forms into proper
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   113
            if toinsert:
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4359
diff changeset
   114
                autoform.insert_relations(self._cw, toinsert)
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   115
        self._cw.remove_pending_operations()
4171
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   116
        if self.errors:
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   117
            errors = dict((f.name, unicode(ex)) for f, ex in self.errors)
5038
90493551b1eb [form] fix validation error handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4940
diff changeset
   118
            raise ValidationError(valerror_eid(form.get('__maineid')), errors)
1753
ba01605cdd9a delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1361
diff changeset
   119
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
   120
    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
   121
        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
   122
        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
   123
            # 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
   124
            # 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
   125
            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
   126
            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
   127
        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
   128
            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
   129
            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
   130
                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
   131
            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
   132
        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
   133
        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
   134
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
    def _update_entity(self, eid, rqlquery):
4171
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   136
        self._cw.execute(rqlquery.update_query(eid), rqlquery.kwargs)
1753
ba01605cdd9a delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1361
diff changeset
   137
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   138
    def edit_entity(self, formparams, multiple=False):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   139
        """edit / create / copy an entity and return its eid"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   140
        etype = formparams['__type']
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   141
        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
   142
        entity.eid = formparams['eid']
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   143
        is_main_entity = self._cw.form.get('__maineid') == formparams['eid']
4171
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   144
        # let a chance to do some entity specific stuff
1753
ba01605cdd9a delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1361
diff changeset
   145
        entity.pre_web_edit()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   146
        # 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
   147
        rqlquery = RqlQuery()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   148
        # 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
   149
        # 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
   150
        # 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
   151
        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
   152
        form = self._cw.vreg['forms'].select(formid, self._cw, entity=entity)
4171
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   153
        eid = form.actual_eid(entity.eid)
4359
fabc680bb0bf fix Bytes submission pb on POST, due to multiple call to field.process_form_value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4277
diff changeset
   154
        form.formvalues = {} # init fields value cache
4171
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   155
        try:
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   156
            editedfields = formparams['_cw_edited_fields']
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   157
        except KeyError:
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   158
            raise RequestError(self._cw._('no edited fields specified for entity %s' % entity.eid))
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   159
        for editedfield in splitstrip(editedfields):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   160
            try:
4171
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   161
                name, role = editedfield.split('-')
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   162
            except:
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   163
                name = editedfield
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   164
                role = None
4231
d55cac808b08 iirk reminder
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4226
diff changeset
   165
            if form.field_by_name.im_func.func_code.co_argcount == 4: # XXX
4171
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   166
                field = form.field_by_name(name, role, eschema=entity.e_schema)
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   167
            else:
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   168
                field = form.field_by_name(name, role)
4665
873ebd160954 when validating a form, we should properly call 'actual_fields(form) on edited field else compound field are not correctly processed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4387
diff changeset
   169
            for field in field.actual_fields(form):
873ebd160954 when validating a form, we should properly call 'actual_fields(form) on edited field else compound field are not correctly processed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4387
diff changeset
   170
                if field.has_been_modified(form):
873ebd160954 when validating a form, we should properly call 'actual_fields(form) on edited field else compound field are not correctly processed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4387
diff changeset
   171
                    self.handle_formfield(form, field, rqlquery)
4171
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   172
        if self.errors:
4224
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4171
diff changeset
   173
            errors = dict((f.role_name(), unicode(ex)) for f, ex in self.errors)
5038
90493551b1eb [form] fix validation error handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4940
diff changeset
   174
            raise ValidationError(valerror_eid(entity.eid), errors)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   175
        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
   176
            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
   177
        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
   178
            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
   179
        if is_main_entity:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   180
            self.notify_edited(entity)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   181
        if formparams.has_key('__delete'):
4277
35cd057339b2 turn all the stuff used to handle 'generic relations' in forms into proper
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   182
            # XXX deprecate?
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   183
            todelete = self._cw.list_form_param('__delete', formparams, pop=True)
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4359
diff changeset
   184
            autoform.delete_relations(self._cw, todelete)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   185
        if formparams.has_key('__cloned_eid'):
3631
6176ef2f6488 give correctly typed eid
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3309
diff changeset
   186
            entity.copy_relations(typed_eid(formparams['__cloned_eid']))
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
   187
        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
   188
            self.execute_linkto(entity.eid)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   189
        return eid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   190
4171
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   191
    def handle_formfield(self, form, field, rqlquery=None):
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   192
        eschema = form.edited_entity.e_schema
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
   193
        try:
4171
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   194
            for field, value in field.process_posted(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
   195
                if not (
4053
7cc66b1d9183 more api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4045
diff changeset
   196
                    (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
   197
                    or
4053
7cc66b1d9183 more api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4045
diff changeset
   198
                    (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
   199
                    continue
4045
f4a52abb6f4f cw 3.6 api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4007
diff changeset
   200
                rschema = self._cw.vreg.schema.rschema(field.name)
4053
7cc66b1d9183 more api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4045
diff changeset
   201
                if rschema.final:
4171
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   202
                    rqlquery.kwargs[field.name] = value
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   203
                    rqlquery.edited.append('X %s %%(%s)s' % (rschema, rschema))
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
                else:
4171
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   205
                    if form.edited_entity.has_eid():
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   206
                        origvalues = set(entity.eid for entity in form.edited_entity.related(field.name, field.role, entities=True))
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   207
                    else:
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   208
                        origvalues = set()
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   209
                    if value is None or value == origvalues:
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   210
                        continue # not edited / not modified / to do later
4249
222fbf826604 don't call handle_inlined_relation where we're not on the relation'subject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4231
diff changeset
   211
                    if rschema.inlined and rqlquery is not None and field.role == 'subject':
4171
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   212
                        self.handle_inlined_relation(form, field, value, origvalues, rqlquery)
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   213
                    elif form.edited_entity.has_eid():
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   214
                        self.handle_relation(form, field, value, origvalues)
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   215
                    else:
4226
67dd296f864d should use a set for pending fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4224
diff changeset
   216
                        self._pending_fields.add( (form, field) )
4171
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   217
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
   218
        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
   219
            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
   220
4171
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   221
    def handle_inlined_relation(self, form, field, values, origvalues, rqlquery):
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   222
        """handle edition for the (rschema, x) relation of the given entity
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   223
        """
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   224
        attr = field.name
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   225
        if values:
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   226
            rqlquery.kwargs[attr] = iter(values).next()
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   227
            rqlquery.edited.append('X %s %s' % (attr, attr.upper()))
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   228
            rqlquery.restrictions.append('%s eid %%(%s)s' % (attr.upper(), attr))
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   229
        elif form.edited_entity.has_eid():
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   230
            self.handle_relation(form, field, values, origvalues)
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   231
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   232
    def handle_relation(self, form, field, values, origvalues):
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   233
        """handle edition for the (rschema, x) relation of the given entity
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   234
        """
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   235
        etype = form.edited_entity.e_schema
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   236
        rschema = self._cw.vreg.schema.rschema(field.name)
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   237
        if field.role == 'subject':
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   238
            desttype = rschema.objects(etype)[0]
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   239
            card = rschema.rdef(etype, desttype).cardinality[0]
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   240
            subjvar, objvar = 'X', 'Y'
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   241
        else:
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   242
            desttype = rschema.subjects(etype)[0]
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   243
            card = rschema.rdef(desttype, etype).cardinality[1]
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   244
            subjvar, objvar = 'Y', 'X'
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   245
        eid = form.edited_entity.eid
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   246
        if field.role == 'object' or not rschema.inlined or not values:
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   247
            # this is not an inlined relation or no values specified,
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   248
            # explicty remove relations
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   249
            rql = 'DELETE %s %s %s WHERE X eid %%(x)s, Y eid %%(y)s' % (
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   250
                subjvar, rschema, objvar)
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   251
            for reid in origvalues.difference(values):
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5061
diff changeset
   252
                self.relations_rql.append((rql, {'x': eid, 'y': reid}))
4171
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   253
        seteids = values.difference(origvalues)
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   254
        if seteids:
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   255
            rql = 'SET %s %s %s WHERE X eid %%(x)s, Y eid %%(y)s' % (
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   256
                subjvar, rschema, objvar)
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   257
            for reid in seteids:
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5061
diff changeset
   258
                self.relations_rql.append((rql, {'x': eid, 'y': reid}))
4171
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   259
4883
11899d28337f [web] cleanup: move delete_entities to the edit controller
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
   260
    def delete_entities(self, eidtypes):
11899d28337f [web] cleanup: move delete_entities to the edit controller
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
   261
        """delete entities from the repository"""
11899d28337f [web] cleanup: move delete_entities to the edit controller
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
   262
        redirect_info = set()
11899d28337f [web] cleanup: move delete_entities to the edit controller
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
   263
        eidtypes = tuple(eidtypes)
11899d28337f [web] cleanup: move delete_entities to the edit controller
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
   264
        for eid, etype in eidtypes:
11899d28337f [web] cleanup: move delete_entities to the edit controller
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
   265
            entity = self._cw.entity_from_eid(eid, etype)
11899d28337f [web] cleanup: move delete_entities to the edit controller
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
   266
            path, params = entity.after_deletion_path()
11899d28337f [web] cleanup: move delete_entities to the edit controller
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
   267
            redirect_info.add( (path, tuple(params.iteritems())) )
11899d28337f [web] cleanup: move delete_entities to the edit controller
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
   268
            entity.delete()
11899d28337f [web] cleanup: move delete_entities to the edit controller
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
   269
        if len(redirect_info) > 1:
11899d28337f [web] cleanup: move delete_entities to the edit controller
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
   270
            # In the face of ambiguity, refuse the temptation to guess.
11899d28337f [web] cleanup: move delete_entities to the edit controller
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
   271
            self._after_deletion_path = 'view', ()
11899d28337f [web] cleanup: move delete_entities to the edit controller
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
   272
        else:
11899d28337f [web] cleanup: move delete_entities to the edit controller
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
   273
            self._after_deletion_path = iter(redirect_info).next()
11899d28337f [web] cleanup: move delete_entities to the edit controller
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
   274
        if len(eidtypes) > 1:
11899d28337f [web] cleanup: move delete_entities to the edit controller
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
   275
            self._cw.set_message(self._cw._('entities deleted'))
11899d28337f [web] cleanup: move delete_entities to the edit controller
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
   276
        else:
11899d28337f [web] cleanup: move delete_entities to the edit controller
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
   277
            self._cw.set_message(self._cw._('entity deleted'))
11899d28337f [web] cleanup: move delete_entities to the edit controller
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
   278
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   279
    def _action_apply(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   280
        self._default_publish()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   281
        self.reset()
1753
ba01605cdd9a delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1361
diff changeset
   282
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   283
    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
   284
        errorurl = self._cw.form.get('__errorurl')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   285
        if errorurl:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   286
            self._cw.cancel_edition(errorurl)
4940
3143a1258d62 [web deletion] must use set_message
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4934
diff changeset
   287
        self._cw.set_message(self._cw._('edit canceled'))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   288
        return self.reset()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   289
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   290
    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
   291
        self.delete_entities(self._cw.edited_eids(withtype=True))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   292
        return self.reset()