web/views/editcontroller.py
author Julien Cristau <julien.cristau@logilab.fr>
Tue, 16 Feb 2016 10:52:38 +0100
changeset 11114 468b91aabd9d
parent 11066 dcbb64d3a1d9
child 11118 0c645f09d96a
permissions -rw-r--r--
[web/views] fix editcontroller regression unittest_views_basecontrollers.py's EditControllerTC.test_edit_mandatory_inlined3_object regressed with changeset dcbb64d3a1d9 because it relied on POSTing nonexisting eids. This seems like a silly idea, but let's keep the behaviour unchanged.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
9177
5236d0e4c598 [editcontroller] req=self._cw makes things easier to read
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8848
diff changeset
     1
# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5061
diff changeset
     2
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5061
diff changeset
     3
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5061
diff changeset
     4
# This file is part of CubicWeb.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5061
diff changeset
     5
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5061
diff changeset
     6
# CubicWeb is free software: you can redistribute it and/or modify it under the
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5061
diff changeset
     7
# terms of the GNU Lesser General Public License as published by the Free
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5061
diff changeset
     8
# Software Foundation, either version 2.1 of the License, or (at your option)
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5061
diff changeset
     9
# any later version.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5061
diff changeset
    10
#
5424
8ecbcbff9777 replace logilab-common by CubicWeb in disclaimer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5421
diff changeset
    11
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5061
diff changeset
    12
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5061
diff changeset
    13
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5061
diff changeset
    14
# details.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5061
diff changeset
    15
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5061
diff changeset
    16
# You should have received a copy of the GNU Lesser General Public License along
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5061
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    18
"""The edit controller, automatically handling entity form submitting"""
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    19
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    20
__docformat__ = "restructuredtext en"
1948
887ed691c635 cosmetic
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1940
diff changeset
    21
4932
dce5ebe5d598 add missing warn imports
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
    22
from warnings import warn
9179
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
    23
from collections import defaultdict
4932
dce5ebe5d598 add missing warn imports
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
    24
8034
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 7990
diff changeset
    25
from logilab.common.deprecation import deprecated
9179
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
    26
from logilab.common.graph import ordered_nodes
8034
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 7990
diff changeset
    27
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    28
from rql.utils import rqlvar_maker
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    29
11114
468b91aabd9d [web/views] fix editcontroller regression
Julien Cristau <julien.cristau@logilab.fr>
parents: 11066
diff changeset
    30
from cubicweb import Binary, ValidationError, UnknownEid
9256
697a8181ba30 remove 3.9 bw compat
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9196
diff changeset
    31
from cubicweb.view import EntityAdapter
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8128
diff changeset
    32
from cubicweb.predicates import is_instance
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    33
from cubicweb.web import (INTERNAL_FIELD_VALUE, RequestError, NothingToEdit,
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    34
                          ProcessFormError)
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4359
diff changeset
    35
from cubicweb.web.views import basecontrollers, autoform
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    36
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    37
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    38
class IEditControlAdapter(EntityAdapter):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    39
    __regid__ = 'IEditControl'
5877
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5676
diff changeset
    40
    __select__ = is_instance('Any')
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    41
8034
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 7990
diff changeset
    42
    def __init__(self, _cw, **kwargs):
8041
81794aa0c8b4 [edit controller] only display warning on specific adapters
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
    43
        if self.__class__ is not IEditControlAdapter:
81794aa0c8b4 [edit controller] only display warning on specific adapters
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
    44
            warn('[3.14] IEditControlAdapter is deprecated, override EditController'
81794aa0c8b4 [edit controller] only display warning on specific adapters
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
    45
                 ' using match_edited_type or match_form_id selectors for example.',
81794aa0c8b4 [edit controller] only display warning on specific adapters
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8034
diff changeset
    46
                 DeprecationWarning)
8034
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 7990
diff changeset
    47
        super(IEditControlAdapter, self).__init__(_cw, **kwargs)
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 7990
diff changeset
    48
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    49
    def after_deletion_path(self):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    50
        """return (path, parameters) which should be used as redirect
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    51
        information when this entity is being deleted
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    52
        """
5569
cb14af012a96 [adapters] refactoring fixes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5557
diff changeset
    53
        parent = self.entity.cw_adapt_to('IBreadCrumbs').parent_entity()
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    54
        if parent is not None:
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    55
            return parent.rest_path(), {}
5569
cb14af012a96 [adapters] refactoring fixes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5557
diff changeset
    56
        return str(self.entity.e_schema).lower(), {}
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    57
8034
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 7990
diff changeset
    58
    def pre_web_edit(self):
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    59
        """callback called by the web editcontroller when an entity will be
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    60
        created/modified, to let a chance to do some entity specific stuff.
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    61
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    62
        Do nothing by default.
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    63
        """
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    64
        pass
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    65
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    66
5038
90493551b1eb [form] fix validation error handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4940
diff changeset
    67
def valerror_eid(eid):
90493551b1eb [form] fix validation error handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4940
diff changeset
    68
    try:
8748
f5027f8d2478 drop typed_eid() in favour of int() (closes #2742462)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8697
diff changeset
    69
        return int(eid)
5038
90493551b1eb [form] fix validation error handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4940
diff changeset
    70
    except (ValueError, TypeError):
90493551b1eb [form] fix validation error handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4940
diff changeset
    71
        return eid
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    72
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
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
    74
    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
    75
        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
    76
        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
    77
        self.kwargs = {}
11064
113e9da47afc [edit controller] Cancel RQL queries to be performed on entities to be deleted
Florent Cayré <florent.cayre@logilab.fr>
parents: 11063
diff changeset
    78
        self.canceled = False
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
8827
0d81a474c0fe [editcontroller] a small debugging help (closes #2518980)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8697
diff changeset
    80
    def __repr__(self):
0d81a474c0fe [editcontroller] a small debugging help (closes #2518980)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8697
diff changeset
    81
        return ('Query <edited=%r restrictions=%r kwargs=%r>' % (
0d81a474c0fe [editcontroller] a small debugging help (closes #2518980)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8697
diff changeset
    82
            self.edited, self.restrictions, self.kwargs))
0d81a474c0fe [editcontroller] a small debugging help (closes #2518980)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8697
diff changeset
    83
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
    84
    def insert_query(self, etype):
11064
113e9da47afc [edit controller] Cancel RQL queries to be performed on entities to be deleted
Florent Cayré <florent.cayre@logilab.fr>
parents: 11063
diff changeset
    85
        assert not self.canceled
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
    86
        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
    87
            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
    88
        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
    89
            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
    90
        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
    91
            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
    92
        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
    93
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
    94
    def update_query(self, eid):
11064
113e9da47afc [edit controller] Cancel RQL queries to be performed on entities to be deleted
Florent Cayré <florent.cayre@logilab.fr>
parents: 11063
diff changeset
    95
        assert not self.canceled
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
        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
    97
        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
    98
        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
    99
            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
   100
        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
   101
        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
   102
            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
   103
        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
   104
        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
   105
9178
b5762ac9a82e [editcontroller] extract RQLQuery.set_attribute/set_inlined methods from handle_field/handle_inlined_relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9177
diff changeset
   106
    def set_attribute(self, attr, value):
b5762ac9a82e [editcontroller] extract RQLQuery.set_attribute/set_inlined methods from handle_field/handle_inlined_relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9177
diff changeset
   107
        self.kwargs[attr] = value
b5762ac9a82e [editcontroller] extract RQLQuery.set_attribute/set_inlined methods from handle_field/handle_inlined_relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9177
diff changeset
   108
        self.edited.append('X %s %%(%s)s' % (attr, attr))
b5762ac9a82e [editcontroller] extract RQLQuery.set_attribute/set_inlined methods from handle_field/handle_inlined_relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9177
diff changeset
   109
b5762ac9a82e [editcontroller] extract RQLQuery.set_attribute/set_inlined methods from handle_field/handle_inlined_relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9177
diff changeset
   110
    def set_inlined(self, relation, value):
b5762ac9a82e [editcontroller] extract RQLQuery.set_attribute/set_inlined methods from handle_field/handle_inlined_relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9177
diff changeset
   111
        self.kwargs[relation] = value
b5762ac9a82e [editcontroller] extract RQLQuery.set_attribute/set_inlined methods from handle_field/handle_inlined_relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9177
diff changeset
   112
        self.edited.append('X %s %s' % (relation, relation.upper()))
b5762ac9a82e [editcontroller] extract RQLQuery.set_attribute/set_inlined methods from handle_field/handle_inlined_relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9177
diff changeset
   113
        self.restrictions.append('%s eid %%(%s)s' % (relation.upper(), relation))
b5762ac9a82e [editcontroller] extract RQLQuery.set_attribute/set_inlined methods from handle_field/handle_inlined_relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9177
diff changeset
   114
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   115
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4359
diff changeset
   116
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
   117
    __regid__ = 'edit'
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   118
2255
c346af0727ca more generic way to detect json requests (not yet perfect though)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   119
    def publish(self, rset=None):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   120
        """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
   121
        for key in self._cw.form:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   122
            # There should be 0 or 1 action
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   123
            if key.startswith('__action_'):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   124
                cbname = key[1:]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   125
                try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   126
                    callback = getattr(self, cbname)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   127
                except AttributeError:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   128
                    raise RequestError(self._cw._('invalid action %r' % key))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   129
                else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   130
                    return callback()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   131
        self._default_publish()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   132
        self.reset()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   133
9179
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   134
    def _ordered_formparams(self):
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   135
        """ Return form parameters dictionaries for each edited entity.
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   136
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   137
        We ensure that entities can be created in this order accounting for
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   138
        mandatory inlined relations.
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   139
        """
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   140
        req = self._cw
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   141
        graph = {}
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   142
        get_rschema = self._cw.vreg.schema.rschema
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   143
        # minparams = 2, because at least __type and eid are needed
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   144
        values_by_eid = dict((eid, req.extract_entity_params(eid, minparams=2))
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   145
                             for eid in req.edited_eids())
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   146
        # iterate over all the edited entities
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   147
        for eid, values in values_by_eid.iteritems():
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   148
            # add eid to the dependency graph
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   149
            graph.setdefault(eid, set())
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   150
            # search entity's edited fields for mandatory inlined relation
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   151
            for param in values['_cw_entity_fields'].split(','):
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   152
                try:
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   153
                    rtype, role = param.split('-')
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   154
                except ValueError:
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   155
                    # e.g. param='__type'
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   156
                    continue
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   157
                rschema = get_rschema(rtype)
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   158
                if rschema.inlined:
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   159
                    for target in rschema.targets(values['__type'], role):
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   160
                        rdef = rschema.role_rdef(values['__type'], target, role)
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   161
                        # if cardinality is 1 and if the target entity is being
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   162
                        # simultaneously edited, the current entity must be
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   163
                        # created before the target one
9439
549c999d06d2 [editcontroller] fix cardinality computation (closes #3120495)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9256
diff changeset
   164
                        if rdef.cardinality[0 if role == 'subject' else 1] == '1':
9179
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   165
                            target_eid = values[param]
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   166
                            if target_eid in values_by_eid:
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   167
                                # add dependency from the target entity to the
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   168
                                # current one
9196
13461cb8ff40 [editcontrollers] Account for role in the ordering of entities (Complements #3031719)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9179
diff changeset
   169
                                if role == 'object':
13461cb8ff40 [editcontrollers] Account for role in the ordering of entities (Complements #3031719)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9179
diff changeset
   170
                                    graph.setdefault(target_eid, set()).add(eid)
13461cb8ff40 [editcontrollers] Account for role in the ordering of entities (Complements #3031719)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9179
diff changeset
   171
                                else:
13461cb8ff40 [editcontrollers] Account for role in the ordering of entities (Complements #3031719)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9179
diff changeset
   172
                                    graph.setdefault(eid, set()).add(target_eid)
9179
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   173
                                break
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   174
        for eid in reversed(ordered_nodes(graph)):
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   175
            yield values_by_eid[eid]
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   176
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   177
    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
   178
        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
   179
        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
   180
        self.relations_rql = []
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   181
        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
   182
        # 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
   183
        if '__maineid' in form:
9774
b7b71be569cf deprecate get/set_shared_data API
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9635
diff changeset
   184
            req.transaction_data['__maineid'] = form['__maineid']
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   185
        # no specific action, generic edition
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   186
        self._to_create = req.data['eidmap'] = {}
9179
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   187
        # those two data variables are used to handle relation from/to entities
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   188
        # which doesn't exist at time where the entity is edited and that
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   189
        # deserves special treatment
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   190
        req.data['pending_inlined'] = defaultdict(set)
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   191
        req.data['pending_others'] = set()
11063
de20b0903d7d [edit controller] fix handling of removal of subentities from an edit form
Florent Cayré <florent.cayre@logilab.fr>
parents: 11061
diff changeset
   192
        req.data['pending_composite_delete'] = set()
6400
21468682f688 restore vital block of code (gone in 6384:89d5b339ebdd)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6384
diff changeset
   193
        try:
9179
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   194
            for formparams in self._ordered_formparams():
6400
21468682f688 restore vital block of code (gone in 6384:89d5b339ebdd)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6384
diff changeset
   195
                eid = self.edit_entity(formparams)
8695
358d8bed9626 [toward-py3k] rewrite to "except AnException as exc:" (part of #2711624)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8556
diff changeset
   196
        except (RequestError, NothingToEdit) as ex:
6400
21468682f688 restore vital block of code (gone in 6384:89d5b339ebdd)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6384
diff changeset
   197
            if '__linkto' in req.form and 'eid' in req.form:
21468682f688 restore vital block of code (gone in 6384:89d5b339ebdd)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6384
diff changeset
   198
                self.execute_linkto()
21468682f688 restore vital block of code (gone in 6384:89d5b339ebdd)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6384
diff changeset
   199
            elif not ('__delete' in req.form or '__insert' in req.form):
21468682f688 restore vital block of code (gone in 6384:89d5b339ebdd)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6384
diff changeset
   200
                raise ValidationError(None, {None: unicode(ex)})
9179
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   201
        # all pending inlined relations to newly created entities have been
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   202
        # treated now (pop to ensure there are no attempt to add new ones)
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   203
        pending_inlined = req.data.pop('pending_inlined')
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   204
        assert not pending_inlined, pending_inlined
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   205
        # handle all other remaining relations now
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   206
        for form_, field in req.data.pop('pending_others'):
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   207
            self.handle_formfield(form_, field)
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   208
        # then 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
   209
        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
   210
            self._cw.execute(*querydef)
11063
de20b0903d7d [edit controller] fix handling of removal of subentities from an edit form
Florent Cayré <florent.cayre@logilab.fr>
parents: 11061
diff changeset
   211
        # delete pending composite
11066
dcbb64d3a1d9 [edit controller] Fix composite entity reparenting when inlined
Florent Cayré <florent.cayre@logilab.fr>
parents: 11064
diff changeset
   212
        for entity in req.data['pending_composite_delete']:
dcbb64d3a1d9 [edit controller] Fix composite entity reparenting when inlined
Florent Cayré <florent.cayre@logilab.fr>
parents: 11064
diff changeset
   213
            entity.cw_delete()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   214
        # XXX this processes *all* pending operations of *all* entities
8697
574bb05e40a4 [toward py3k] rewrite has_key() (part of #2711624)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8695
diff changeset
   215
        if '__delete' in req.form:
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
   216
            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
   217
            if todelete:
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4359
diff changeset
   218
                autoform.delete_relations(self._cw, todelete)
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   219
        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
   220
        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
   221
            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
   222
            raise ValidationError(valerror_eid(form.get('__maineid')), errors)
1753
ba01605cdd9a delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1361
diff changeset
   223
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
   224
    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
   225
        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
   226
        try:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   227
            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
   228
            neweid = entity.eid
8695
358d8bed9626 [toward-py3k] rewrite to "except AnException as exc:" (part of #2711624)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8556
diff changeset
   229
        except ValidationError as 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
   230
            self._to_create[eid] = ex.entity
8128
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 8041
diff changeset
   231
            if self._cw.ajax_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
   232
                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
   233
            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
   234
        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
   235
        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
   236
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
    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
   238
        self._cw.execute(rqlquery.update_query(eid), rqlquery.kwargs)
1753
ba01605cdd9a delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1361
diff changeset
   239
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   240
    def edit_entity(self, formparams, multiple=False):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   241
        """edit / create / copy an entity and return its eid"""
9177
5236d0e4c598 [editcontroller] req=self._cw makes things easier to read
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8848
diff changeset
   242
        req = self._cw
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   243
        etype = formparams['__type']
9177
5236d0e4c598 [editcontroller] req=self._cw makes things easier to read
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8848
diff changeset
   244
        entity = req.vreg['etypes'].etype_class(etype)(req)
6029
aac5dba278c7 [editcontroller] turn eid into an int if possible, avoiding pbs. further down (case: preview cube)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5877
diff changeset
   245
        entity.eid = valerror_eid(formparams['eid'])
9177
5236d0e4c598 [editcontroller] req=self._cw makes things easier to read
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8848
diff changeset
   246
        is_main_entity = req.form.get('__maineid') == formparams['eid']
8034
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 7990
diff changeset
   247
        # let a chance to do some entity specific stuff
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 7990
diff changeset
   248
        entity.cw_adapt_to('IEditControl').pre_web_edit()
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 7990
diff changeset
   249
        # create a rql query from parameters
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 7990
diff changeset
   250
        rqlquery = RqlQuery()
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 7990
diff changeset
   251
        # process inlined relations at the same time as attributes
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 7990
diff changeset
   252
        # this will generate less rql queries and might be useful in
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 7990
diff changeset
   253
        # a few dark corners
7182
09454384fff8 [edit controller] fix subform formid in EditController (would need further improvement)
Florent Cayré <florent.cayre@gmail.com>
parents: 6864
diff changeset
   254
        if is_main_entity:
9177
5236d0e4c598 [editcontroller] req=self._cw makes things easier to read
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8848
diff changeset
   255
            formid = req.form.get('__form_id', 'edition')
7182
09454384fff8 [edit controller] fix subform formid in EditController (would need further improvement)
Florent Cayré <florent.cayre@gmail.com>
parents: 6864
diff changeset
   256
        else:
09454384fff8 [edit controller] fix subform formid in EditController (would need further improvement)
Florent Cayré <florent.cayre@gmail.com>
parents: 6864
diff changeset
   257
            # XXX inlined forms formid should be saved in a different formparams entry
09454384fff8 [edit controller] fix subform formid in EditController (would need further improvement)
Florent Cayré <florent.cayre@gmail.com>
parents: 6864
diff changeset
   258
            # inbetween, use cubicweb standard formid for inlined forms
09454384fff8 [edit controller] fix subform formid in EditController (would need further improvement)
Florent Cayré <florent.cayre@gmail.com>
parents: 6864
diff changeset
   259
            formid = 'edition'
9177
5236d0e4c598 [editcontroller] req=self._cw makes things easier to read
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8848
diff changeset
   260
        form = req.vreg['forms'].select(formid, req, 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
   261
        eid = form.actual_eid(entity.eid)
9520
78702b55c089 Drop 3.13 incomplete backward compat in edit controller.
Florent Cayré <florent.cayre@logilab.fr>
parents: 9439
diff changeset
   262
        editedfields = formparams['_cw_entity_fields']
7584
e1881933f366 [form, controller] closes #1787233: form should provide a method to process posted content
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7182
diff changeset
   263
        form.formvalues = {} # init fields value cache
e1881933f366 [form, controller] closes #1787233: form should provide a method to process posted content
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7182
diff changeset
   264
        for field in form.iter_modified_fields(editedfields, entity):
e1881933f366 [form, controller] closes #1787233: form should provide a method to process posted content
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7182
diff changeset
   265
            self.handle_formfield(form, field, rqlquery)
9179
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   266
        # if there are some inlined field which were waiting for this entity's
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   267
        # creation, add relevant data to the rqlquery
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   268
        for form_, field in req.data['pending_inlined'].pop(entity.eid, ()):
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9178
diff changeset
   269
            rqlquery.set_inlined(field.name, form_.edited_entity.eid)
11064
113e9da47afc [edit controller] Cancel RQL queries to be performed on entities to be deleted
Florent Cayré <florent.cayre@logilab.fr>
parents: 11063
diff changeset
   270
        if not rqlquery.canceled:
113e9da47afc [edit controller] Cancel RQL queries to be performed on entities to be deleted
Florent Cayré <florent.cayre@logilab.fr>
parents: 11063
diff changeset
   271
            if self.errors:
113e9da47afc [edit controller] Cancel RQL queries to be performed on entities to be deleted
Florent Cayré <florent.cayre@logilab.fr>
parents: 11063
diff changeset
   272
                errors = dict((f.role_name(), unicode(ex)) for f, ex in self.errors)
113e9da47afc [edit controller] Cancel RQL queries to be performed on entities to be deleted
Florent Cayré <florent.cayre@logilab.fr>
parents: 11063
diff changeset
   273
                raise ValidationError(valerror_eid(entity.eid), errors)
113e9da47afc [edit controller] Cancel RQL queries to be performed on entities to be deleted
Florent Cayré <florent.cayre@logilab.fr>
parents: 11063
diff changeset
   274
            if eid is None: # creation or copy
113e9da47afc [edit controller] Cancel RQL queries to be performed on entities to be deleted
Florent Cayré <florent.cayre@logilab.fr>
parents: 11063
diff changeset
   275
                entity.eid = eid = self._insert_entity(etype, formparams['eid'], rqlquery)
113e9da47afc [edit controller] Cancel RQL queries to be performed on entities to be deleted
Florent Cayré <florent.cayre@logilab.fr>
parents: 11063
diff changeset
   276
            elif rqlquery.edited: # edition of an existant entity
113e9da47afc [edit controller] Cancel RQL queries to be performed on entities to be deleted
Florent Cayré <florent.cayre@logilab.fr>
parents: 11063
diff changeset
   277
                self._update_entity(eid, rqlquery)
113e9da47afc [edit controller] Cancel RQL queries to be performed on entities to be deleted
Florent Cayré <florent.cayre@logilab.fr>
parents: 11063
diff changeset
   278
        else:
113e9da47afc [edit controller] Cancel RQL queries to be performed on entities to be deleted
Florent Cayré <florent.cayre@logilab.fr>
parents: 11063
diff changeset
   279
            self.errors = []
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
   280
        if is_main_entity:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   281
            self.notify_edited(entity)
8697
574bb05e40a4 [toward py3k] rewrite has_key() (part of #2711624)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8695
diff changeset
   282
        if '__delete' in formparams:
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
   283
            # XXX deprecate?
9177
5236d0e4c598 [editcontroller] req=self._cw makes things easier to read
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8848
diff changeset
   284
            todelete = req.list_form_param('__delete', formparams, pop=True)
5236d0e4c598 [editcontroller] req=self._cw makes things easier to read
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8848
diff changeset
   285
            autoform.delete_relations(req, todelete)
8697
574bb05e40a4 [toward py3k] rewrite has_key() (part of #2711624)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8695
diff changeset
   286
        if '__cloned_eid' in formparams:
8748
f5027f8d2478 drop typed_eid() in favour of int() (closes #2742462)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8697
diff changeset
   287
            entity.copy_relations(int(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
   288
        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
   289
            self.execute_linkto(entity.eid)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   290
        return eid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   291
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
   292
    def handle_formfield(self, form, field, rqlquery=None):
11061
c01325774d21 [editcontroller] a slight code reorganisation, in preparation for a fix
Aurelien Campeas <aurelien.campeas@pythonian.fr>
parents: 9774
diff changeset
   293
        entity = form.edited_entity
c01325774d21 [editcontroller] a slight code reorganisation, in preparation for a fix
Aurelien Campeas <aurelien.campeas@pythonian.fr>
parents: 9774
diff changeset
   294
        eschema = 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
   295
        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
   296
            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
   297
                if not (
4053
7cc66b1d9183 more api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4045
diff changeset
   298
                    (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
   299
                    or
4053
7cc66b1d9183 more api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4045
diff changeset
   300
                    (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
   301
                    continue
11061
c01325774d21 [editcontroller] a slight code reorganisation, in preparation for a fix
Aurelien Campeas <aurelien.campeas@pythonian.fr>
parents: 9774
diff changeset
   302
4045
f4a52abb6f4f cw 3.6 api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4007
diff changeset
   303
                rschema = self._cw.vreg.schema.rschema(field.name)
4053
7cc66b1d9183 more api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4045
diff changeset
   304
                if rschema.final:
9178
b5762ac9a82e [editcontroller] extract RQLQuery.set_attribute/set_inlined methods from handle_field/handle_inlined_relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9177
diff changeset
   305
                    rqlquery.set_attribute(field.name, value)
11061
c01325774d21 [editcontroller] a slight code reorganisation, in preparation for a fix
Aurelien Campeas <aurelien.campeas@pythonian.fr>
parents: 9774
diff changeset
   306
                    continue
c01325774d21 [editcontroller] a slight code reorganisation, in preparation for a fix
Aurelien Campeas <aurelien.campeas@pythonian.fr>
parents: 9774
diff changeset
   307
c01325774d21 [editcontroller] a slight code reorganisation, in preparation for a fix
Aurelien Campeas <aurelien.campeas@pythonian.fr>
parents: 9774
diff changeset
   308
                if entity.has_eid():
c01325774d21 [editcontroller] a slight code reorganisation, in preparation for a fix
Aurelien Campeas <aurelien.campeas@pythonian.fr>
parents: 9774
diff changeset
   309
                    origvalues = set(data[0] for data in entity.related(field.name, field.role).rows)
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
   310
                else:
11061
c01325774d21 [editcontroller] a slight code reorganisation, in preparation for a fix
Aurelien Campeas <aurelien.campeas@pythonian.fr>
parents: 9774
diff changeset
   311
                    origvalues = set()
c01325774d21 [editcontroller] a slight code reorganisation, in preparation for a fix
Aurelien Campeas <aurelien.campeas@pythonian.fr>
parents: 9774
diff changeset
   312
                if value is None or value == origvalues:
c01325774d21 [editcontroller] a slight code reorganisation, in preparation for a fix
Aurelien Campeas <aurelien.campeas@pythonian.fr>
parents: 9774
diff changeset
   313
                    continue # not edited / not modified / to do later
c01325774d21 [editcontroller] a slight code reorganisation, in preparation for a fix
Aurelien Campeas <aurelien.campeas@pythonian.fr>
parents: 9774
diff changeset
   314
11063
de20b0903d7d [edit controller] fix handling of removal of subentities from an edit form
Florent Cayré <florent.cayre@logilab.fr>
parents: 11061
diff changeset
   315
                unlinked_eids = origvalues - value
11066
dcbb64d3a1d9 [edit controller] Fix composite entity reparenting when inlined
Florent Cayré <florent.cayre@logilab.fr>
parents: 11064
diff changeset
   316
11063
de20b0903d7d [edit controller] fix handling of removal of subentities from an edit form
Florent Cayré <florent.cayre@logilab.fr>
parents: 11061
diff changeset
   317
                if unlinked_eids:
de20b0903d7d [edit controller] fix handling of removal of subentities from an edit form
Florent Cayré <florent.cayre@logilab.fr>
parents: 11061
diff changeset
   318
                    # Special handling of composite relation removal
de20b0903d7d [edit controller] fix handling of removal of subentities from an edit form
Florent Cayré <florent.cayre@logilab.fr>
parents: 11061
diff changeset
   319
                    self.handle_composite_removal(
11066
dcbb64d3a1d9 [edit controller] Fix composite entity reparenting when inlined
Florent Cayré <florent.cayre@logilab.fr>
parents: 11064
diff changeset
   320
                        form, field, unlinked_eids, value, rqlquery)
11063
de20b0903d7d [edit controller] fix handling of removal of subentities from an edit form
Florent Cayré <florent.cayre@logilab.fr>
parents: 11061
diff changeset
   321
11061
c01325774d21 [editcontroller] a slight code reorganisation, in preparation for a fix
Aurelien Campeas <aurelien.campeas@pythonian.fr>
parents: 9774
diff changeset
   322
                if rschema.inlined and rqlquery is not None and field.role == 'subject':
c01325774d21 [editcontroller] a slight code reorganisation, in preparation for a fix
Aurelien Campeas <aurelien.campeas@pythonian.fr>
parents: 9774
diff changeset
   323
                    self.handle_inlined_relation(form, field, value, origvalues, rqlquery)
c01325774d21 [editcontroller] a slight code reorganisation, in preparation for a fix
Aurelien Campeas <aurelien.campeas@pythonian.fr>
parents: 9774
diff changeset
   324
                elif form.edited_entity.has_eid():
c01325774d21 [editcontroller] a slight code reorganisation, in preparation for a fix
Aurelien Campeas <aurelien.campeas@pythonian.fr>
parents: 9774
diff changeset
   325
                    self.handle_relation(form, field, value, origvalues)
c01325774d21 [editcontroller] a slight code reorganisation, in preparation for a fix
Aurelien Campeas <aurelien.campeas@pythonian.fr>
parents: 9774
diff changeset
   326
                else:
c01325774d21 [editcontroller] a slight code reorganisation, in preparation for a fix
Aurelien Campeas <aurelien.campeas@pythonian.fr>
parents: 9774
diff changeset
   327
                    form._cw.data['pending_others'].add( (form, field) )
c01325774d21 [editcontroller] a slight code reorganisation, in preparation for a fix
Aurelien Campeas <aurelien.campeas@pythonian.fr>
parents: 9774
diff changeset
   328
8695
358d8bed9626 [toward-py3k] rewrite to "except AnException as exc:" (part of #2711624)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8556
diff changeset
   329
        except ProcessFormError as exc:
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
   330
            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
   331
11066
dcbb64d3a1d9 [edit controller] Fix composite entity reparenting when inlined
Florent Cayré <florent.cayre@logilab.fr>
parents: 11064
diff changeset
   332
    def handle_composite_removal(self, form, field,
dcbb64d3a1d9 [edit controller] Fix composite entity reparenting when inlined
Florent Cayré <florent.cayre@logilab.fr>
parents: 11064
diff changeset
   333
                                 removed_values, new_values, rqlquery):
11063
de20b0903d7d [edit controller] fix handling of removal of subentities from an edit form
Florent Cayré <florent.cayre@logilab.fr>
parents: 11061
diff changeset
   334
        """
de20b0903d7d [edit controller] fix handling of removal of subentities from an edit form
Florent Cayré <florent.cayre@logilab.fr>
parents: 11061
diff changeset
   335
        In EditController-handled forms, when the user removes a composite
de20b0903d7d [edit controller] fix handling of removal of subentities from an edit form
Florent Cayré <florent.cayre@logilab.fr>
parents: 11061
diff changeset
   336
        relation, it triggers the removal of the related entity in the
de20b0903d7d [edit controller] fix handling of removal of subentities from an edit form
Florent Cayré <florent.cayre@logilab.fr>
parents: 11061
diff changeset
   337
        composite. This is where this happens.
de20b0903d7d [edit controller] fix handling of removal of subentities from an edit form
Florent Cayré <florent.cayre@logilab.fr>
parents: 11061
diff changeset
   338
de20b0903d7d [edit controller] fix handling of removal of subentities from an edit form
Florent Cayré <florent.cayre@logilab.fr>
parents: 11061
diff changeset
   339
        See for instance test_subject_subentity_removal in
de20b0903d7d [edit controller] fix handling of removal of subentities from an edit form
Florent Cayré <florent.cayre@logilab.fr>
parents: 11061
diff changeset
   340
        web/test/unittest_application.py.
de20b0903d7d [edit controller] fix handling of removal of subentities from an edit form
Florent Cayré <florent.cayre@logilab.fr>
parents: 11061
diff changeset
   341
        """
de20b0903d7d [edit controller] fix handling of removal of subentities from an edit form
Florent Cayré <florent.cayre@logilab.fr>
parents: 11061
diff changeset
   342
        rschema = self._cw.vreg.schema.rschema(field.name)
11114
468b91aabd9d [web/views] fix editcontroller regression
Julien Cristau <julien.cristau@logilab.fr>
parents: 11066
diff changeset
   343
        new_value_etypes = set()
468b91aabd9d [web/views] fix editcontroller regression
Julien Cristau <julien.cristau@logilab.fr>
parents: 11066
diff changeset
   344
        # the user could have included nonexisting eids in the POST; don't crash.
468b91aabd9d [web/views] fix editcontroller regression
Julien Cristau <julien.cristau@logilab.fr>
parents: 11066
diff changeset
   345
        for eid in new_values:
468b91aabd9d [web/views] fix editcontroller regression
Julien Cristau <julien.cristau@logilab.fr>
parents: 11066
diff changeset
   346
            try:
468b91aabd9d [web/views] fix editcontroller regression
Julien Cristau <julien.cristau@logilab.fr>
parents: 11066
diff changeset
   347
                new_value_etypes.add(self._cw.entity_from_eid(eid).cw_etype)
468b91aabd9d [web/views] fix editcontroller regression
Julien Cristau <julien.cristau@logilab.fr>
parents: 11066
diff changeset
   348
            except UnknownEid:
468b91aabd9d [web/views] fix editcontroller regression
Julien Cristau <julien.cristau@logilab.fr>
parents: 11066
diff changeset
   349
                continue
11063
de20b0903d7d [edit controller] fix handling of removal of subentities from an edit form
Florent Cayré <florent.cayre@logilab.fr>
parents: 11061
diff changeset
   350
        for unlinked_eid in removed_values:
de20b0903d7d [edit controller] fix handling of removal of subentities from an edit form
Florent Cayré <florent.cayre@logilab.fr>
parents: 11061
diff changeset
   351
            unlinked_entity = self._cw.entity_from_eid(unlinked_eid)
de20b0903d7d [edit controller] fix handling of removal of subentities from an edit form
Florent Cayré <florent.cayre@logilab.fr>
parents: 11061
diff changeset
   352
            rdef = rschema.role_rdef(form.edited_entity.cw_etype,
de20b0903d7d [edit controller] fix handling of removal of subentities from an edit form
Florent Cayré <florent.cayre@logilab.fr>
parents: 11061
diff changeset
   353
                                     unlinked_entity.cw_etype,
de20b0903d7d [edit controller] fix handling of removal of subentities from an edit form
Florent Cayré <florent.cayre@logilab.fr>
parents: 11061
diff changeset
   354
                                     field.role)
de20b0903d7d [edit controller] fix handling of removal of subentities from an edit form
Florent Cayré <florent.cayre@logilab.fr>
parents: 11061
diff changeset
   355
            if rdef.composite is not None:
de20b0903d7d [edit controller] fix handling of removal of subentities from an edit form
Florent Cayré <florent.cayre@logilab.fr>
parents: 11061
diff changeset
   356
                if rdef.composite == field.role:
de20b0903d7d [edit controller] fix handling of removal of subentities from an edit form
Florent Cayré <florent.cayre@logilab.fr>
parents: 11061
diff changeset
   357
                    to_be_removed = unlinked_entity
de20b0903d7d [edit controller] fix handling of removal of subentities from an edit form
Florent Cayré <florent.cayre@logilab.fr>
parents: 11061
diff changeset
   358
                else:
11066
dcbb64d3a1d9 [edit controller] Fix composite entity reparenting when inlined
Florent Cayré <florent.cayre@logilab.fr>
parents: 11064
diff changeset
   359
                    if unlinked_entity.cw_etype in new_value_etypes:
dcbb64d3a1d9 [edit controller] Fix composite entity reparenting when inlined
Florent Cayré <florent.cayre@logilab.fr>
parents: 11064
diff changeset
   360
                        # This is a same-rdef re-parenting: do not remove the entity
dcbb64d3a1d9 [edit controller] Fix composite entity reparenting when inlined
Florent Cayré <florent.cayre@logilab.fr>
parents: 11064
diff changeset
   361
                        continue
11063
de20b0903d7d [edit controller] fix handling of removal of subentities from an edit form
Florent Cayré <florent.cayre@logilab.fr>
parents: 11061
diff changeset
   362
                    to_be_removed = form.edited_entity
11064
113e9da47afc [edit controller] Cancel RQL queries to be performed on entities to be deleted
Florent Cayré <florent.cayre@logilab.fr>
parents: 11063
diff changeset
   363
                    self.info('Edition of %s is cancelled (deletion requested)',
113e9da47afc [edit controller] Cancel RQL queries to be performed on entities to be deleted
Florent Cayré <florent.cayre@logilab.fr>
parents: 11063
diff changeset
   364
                              to_be_removed)
113e9da47afc [edit controller] Cancel RQL queries to be performed on entities to be deleted
Florent Cayré <florent.cayre@logilab.fr>
parents: 11063
diff changeset
   365
                    rqlquery.canceled = True
11063
de20b0903d7d [edit controller] fix handling of removal of subentities from an edit form
Florent Cayré <florent.cayre@logilab.fr>
parents: 11061
diff changeset
   366
                self.info('Scheduling removal of %s as composite relation '
de20b0903d7d [edit controller] fix handling of removal of subentities from an edit form
Florent Cayré <florent.cayre@logilab.fr>
parents: 11061
diff changeset
   367
                          '%s was removed', to_be_removed, rdef)
11066
dcbb64d3a1d9 [edit controller] Fix composite entity reparenting when inlined
Florent Cayré <florent.cayre@logilab.fr>
parents: 11064
diff changeset
   368
                form._cw.data['pending_composite_delete'].add(to_be_removed)
11063
de20b0903d7d [edit controller] fix handling of removal of subentities from an edit form
Florent Cayré <florent.cayre@logilab.fr>
parents: 11061
diff changeset
   369
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
   370
    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
   371
        """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
   372
        """
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   373
        if values:
9178
b5762ac9a82e [editcontroller] extract RQLQuery.set_attribute/set_inlined methods from handle_field/handle_inlined_relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9177
diff changeset
   374
            rqlquery.set_inlined(field.name, iter(values).next())
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
   375
        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
   376
            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
   377
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   378
    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
   379
        """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
   380
        """
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   381
        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
   382
        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
   383
        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
   384
            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
   385
            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
   386
            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
   387
        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
   388
            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
   389
            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
   390
            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
   391
        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
   392
        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
   393
            # 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
   394
            # 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
   395
            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
   396
                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
   397
            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
   398
                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
   399
        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
   400
        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
   401
            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
   402
                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
   403
            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
   404
                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
   405
4883
11899d28337f [web] cleanup: move delete_entities to the edit controller
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
   406
    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
   407
        """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
   408
        redirect_info = set()
11899d28337f [web] cleanup: move delete_entities to the edit controller
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
   409
        eidtypes = tuple(eidtypes)
11899d28337f [web] cleanup: move delete_entities to the edit controller
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
   410
        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
   411
            entity = self._cw.entity_from_eid(eid, etype)
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   412
            path, params = entity.cw_adapt_to('IEditControl').after_deletion_path()
4883
11899d28337f [web] cleanup: move delete_entities to the edit controller
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
   413
            redirect_info.add( (path, tuple(params.iteritems())) )
5557
1a534c596bff [entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5556
diff changeset
   414
            entity.cw_delete()
4883
11899d28337f [web] cleanup: move delete_entities to the edit controller
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
   415
        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
   416
            # 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
   417
            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
   418
        else:
11899d28337f [web] cleanup: move delete_entities to the edit controller
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
   419
            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
   420
        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
   421
            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
   422
        else:
11899d28337f [web] cleanup: move delete_entities to the edit controller
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
   423
            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
   424
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   425
    def _action_apply(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   426
        self._default_publish()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   427
        self.reset()
1753
ba01605cdd9a delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1361
diff changeset
   428
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   429
    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
   430
        errorurl = self._cw.form.get('__errorurl')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   431
        if errorurl:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   432
            self._cw.cancel_edition(errorurl)
4940
3143a1258d62 [web deletion] must use set_message
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4934
diff changeset
   433
        self._cw.set_message(self._cw._('edit canceled'))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   434
        return self.reset()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   435
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   436
    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
   437
        self.delete_entities(self._cw.edited_eids(withtype=True))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   438
        return self.reset()