web/views/editcontroller.py
author Julien Cristau <julien.cristau@logilab.fr>
Tue, 13 Mar 2012 14:20:16 +0100
branchstable
changeset 8301 1385e05afe52
parent 8041 81794aa0c8b4
child 8128 0a927fe4541b
permissions -rw-r--r--
[uilib] don't print timedeltas between 0 and 23h as negative (closes #2236352)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
     1
# copyright 2003-2011 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
dce5ebe5d598 add missing warn imports
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
    23
8034
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 7990
diff changeset
    24
from logilab.common.deprecation import deprecated
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 7990
diff changeset
    25
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    26
from rql.utils import rqlvar_maker
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    27
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    28
from cubicweb import Binary, ValidationError, typed_eid
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    29
from cubicweb.view import EntityAdapter, implements_adapter_compat
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
    30
from cubicweb.selectors import is_instance
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    31
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
    32
                          ProcessFormError)
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4359
diff changeset
    33
from cubicweb.web.views import basecontrollers, autoform
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    34
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    35
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    36
class IEditControlAdapter(EntityAdapter):
6864
ea95004494a2 [adapters] fix #1424467 caused by precedence of bw compat method while the adapter is concret for a given class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6400
diff changeset
    37
    __needs_bw_compat__ = True
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    38
    __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
    39
    __select__ = is_instance('Any')
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    40
8034
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 7990
diff changeset
    41
    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
    42
        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
    43
            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
    44
                 ' 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
    45
                 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
    46
        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
    47
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    48
    @implements_adapter_compat('IEditControl')
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
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    58
    @implements_adapter_compat('IEditControl')
8034
b07d61090706 replace adapter by simple selector to ease edit controller overloading; fixes #2042349
Florent Cayré <florent.cayre@gmail.com>
parents: 7990
diff changeset
    59
    def pre_web_edit(self):
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    60
        """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
    61
        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
    62
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    63
        Do nothing by default.
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    64
        """
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    65
        pass
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    66
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    67
5038
90493551b1eb [form] fix validation error handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4940
diff changeset
    68
def valerror_eid(eid):
90493551b1eb [form] fix validation error handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4940
diff changeset
    69
    try:
90493551b1eb [form] fix validation error handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4940
diff changeset
    70
        return typed_eid(eid)
90493551b1eb [form] fix validation error handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4940
diff changeset
    71
    except (ValueError, TypeError):
90493551b1eb [form] fix validation error handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4940
diff changeset
    72
        return eid
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    73
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
    74
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
    75
    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
    76
        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
    77
        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
    78
        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
    79
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
    80
    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
    81
        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
    82
            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
    83
        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
    84
            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
    85
        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
    86
            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
    87
        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
    88
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
    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
    90
        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
    91
        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
    92
        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
    93
            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
    94
        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
    95
        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
    96
            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
    97
        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
    98
        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
    99
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   100
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4359
diff changeset
   101
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
   102
    __regid__ = 'edit'
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   103
2255
c346af0727ca more generic way to detect json requests (not yet perfect though)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   104
    def publish(self, rset=None):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   105
        """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
   106
        for key in self._cw.form:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   107
            # There should be 0 or 1 action
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   108
            if key.startswith('__action_'):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   109
                cbname = key[1:]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   110
                try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   111
                    callback = getattr(self, cbname)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   112
                except AttributeError:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   113
                    raise RequestError(self._cw._('invalid action %r' % key))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   114
                else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   115
                    return callback()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   116
        self._default_publish()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   117
        self.reset()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   118
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   119
    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
   120
        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
   121
        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
   122
        self.relations_rql = []
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   123
        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
   124
        # 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
   125
        if '__maineid' in form:
6015
ee76e8e72776 [dbapi] update renamed argument
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   126
            req.set_shared_data('__maineid', form['__maineid'], txdata=True)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   127
        # no specific action, generic edition
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   128
        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
   129
        self._pending_fields = req.data['pendingfields'] = set()
6400
21468682f688 restore vital block of code (gone in 6384:89d5b339ebdd)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6384
diff changeset
   130
        try:
21468682f688 restore vital block of code (gone in 6384:89d5b339ebdd)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6384
diff changeset
   131
            for eid in req.edited_eids():
21468682f688 restore vital block of code (gone in 6384:89d5b339ebdd)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6384
diff changeset
   132
                # __type and eid
21468682f688 restore vital block of code (gone in 6384:89d5b339ebdd)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6384
diff changeset
   133
                formparams = req.extract_entity_params(eid, minparams=2)
21468682f688 restore vital block of code (gone in 6384:89d5b339ebdd)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6384
diff changeset
   134
                eid = self.edit_entity(formparams)
21468682f688 restore vital block of code (gone in 6384:89d5b339ebdd)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6384
diff changeset
   135
        except (RequestError, NothingToEdit), ex:
21468682f688 restore vital block of code (gone in 6384:89d5b339ebdd)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6384
diff changeset
   136
            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
   137
                self.execute_linkto()
21468682f688 restore vital block of code (gone in 6384:89d5b339ebdd)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6384
diff changeset
   138
            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
   139
                raise ValidationError(None, {None: unicode(ex)})
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   140
        # 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
   141
        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
   142
            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
   143
                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
   144
        # 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
   145
        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
   146
            self._cw.execute(*querydef)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   147
        # 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
   148
        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
   149
            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
   150
            if todelete:
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4359
diff changeset
   151
                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
   152
        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
   153
        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
   154
            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
   155
            raise ValidationError(valerror_eid(form.get('__maineid')), errors)
1753
ba01605cdd9a delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1361
diff changeset
   156
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
   157
    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
   158
        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
   159
        try:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   160
            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
   161
            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
   162
        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
   163
            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
   164
            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
   165
                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
   166
            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
   167
        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
   168
        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
   169
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   170
    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
   171
        self._cw.execute(rqlquery.update_query(eid), rqlquery.kwargs)
1753
ba01605cdd9a delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1361
diff changeset
   172
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   173
    def edit_entity(self, formparams, multiple=False):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   174
        """edit / create / copy an entity and return its eid"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   175
        etype = formparams['__type']
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   176
        entity = self._cw.vreg['etypes'].etype_class(etype)(self._cw)
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
   177
        entity.eid = valerror_eid(formparams['eid'])
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   178
        is_main_entity = self._cw.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
   179
        # 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
   180
        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
   181
        # 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
   182
        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
   183
        # 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
   184
        # 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
   185
        # 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
   186
        if is_main_entity:
09454384fff8 [edit controller] fix subform formid in EditController (would need further improvement)
Florent Cayré <florent.cayre@gmail.com>
parents: 6864
diff changeset
   187
            formid = self._cw.form.get('__form_id', 'edition')
09454384fff8 [edit controller] fix subform formid in EditController (would need further improvement)
Florent Cayré <florent.cayre@gmail.com>
parents: 6864
diff changeset
   188
        else:
09454384fff8 [edit controller] fix subform formid in EditController (would need further improvement)
Florent Cayré <florent.cayre@gmail.com>
parents: 6864
diff changeset
   189
            # 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
   190
            # 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
   191
            formid = 'edition'
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   192
        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
   193
        eid = form.actual_eid(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
   194
        try:
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
   195
            editedfields = formparams['_cw_entity_fields']
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
   196
        except KeyError:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   197
            try:
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
   198
                editedfields = formparams['_cw_edited_fields']
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
   199
                warn('[3.13] _cw_edited_fields has been renamed _cw_entity_fields',
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
   200
                     DeprecationWarning)
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
   201
            except KeyError:
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
   202
                raise RequestError(self._cw._('no edited fields specified for entity %s' % entity.eid))
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
   203
        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
   204
        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
   205
            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
   206
        if self.errors:
4224
5998df006968 refactor form error handling:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4171
diff changeset
   207
            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
   208
            raise ValidationError(valerror_eid(entity.eid), errors)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   209
        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
   210
            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
   211
        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
   212
            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
   213
        if is_main_entity:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   214
            self.notify_edited(entity)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   215
        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
   216
            # XXX deprecate?
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   217
            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
   218
            autoform.delete_relations(self._cw, todelete)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   219
        if formparams.has_key('__cloned_eid'):
3631
6176ef2f6488 give correctly typed eid
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3309
diff changeset
   220
            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
   221
        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
   222
            self.execute_linkto(entity.eid)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   223
        return eid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   224
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
   225
    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
   226
        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
   227
        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
   228
            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
   229
                if not (
4053
7cc66b1d9183 more api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4045
diff changeset
   230
                    (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
   231
                    or
4053
7cc66b1d9183 more api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4045
diff changeset
   232
                    (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
   233
                    continue
4045
f4a52abb6f4f cw 3.6 api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4007
diff changeset
   234
                rschema = self._cw.vreg.schema.rschema(field.name)
4053
7cc66b1d9183 more api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4045
diff changeset
   235
                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
   236
                    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
   237
                    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
   238
                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
   239
                    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
   240
                        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
   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
                        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
   243
                    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
   244
                        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
   245
                    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
   246
                        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
   247
                    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
   248
                        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
   249
                    else:
4226
67dd296f864d should use a set for pending fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4224
diff changeset
   250
                        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
   251
3387
a357d4147eee [forms] work-in-progress, big editcontroller refactoring: let fields/widgets process posted data
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3386
diff changeset
   252
        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
   253
            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
   254
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
   255
    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
   256
        """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
   257
        """
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   258
        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
   259
        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
   260
            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
   261
            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
   262
            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
   263
        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
   264
            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
   265
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   266
    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
   267
        """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
   268
        """
f1b9f0ed1253 make new editcontroller works, based on a _cw_edited_fields hidden input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4160
diff changeset
   269
        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
   270
        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
   271
        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
   272
            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
   273
            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
   274
            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
   275
        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
   276
            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
   277
            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
   278
            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
   279
        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
   280
        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
   281
            # 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
   282
            # 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
   283
            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
   284
                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
   285
            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
   286
                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
   287
        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
   288
        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
   289
            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
   290
                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
   291
            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
   292
                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
   293
4883
11899d28337f [web] cleanup: move delete_entities to the edit controller
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
   294
    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
   295
        """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
   296
        redirect_info = set()
11899d28337f [web] cleanup: move delete_entities to the edit controller
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
   297
        eidtypes = tuple(eidtypes)
11899d28337f [web] cleanup: move delete_entities to the edit controller
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
   298
        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
   299
            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
   300
            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
   301
            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
   302
            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
   303
        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
   304
            # 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
   305
            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
   306
        else:
11899d28337f [web] cleanup: move delete_entities to the edit controller
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
   307
            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
   308
        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
   309
            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
   310
        else:
11899d28337f [web] cleanup: move delete_entities to the edit controller
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4665
diff changeset
   311
            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
   312
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   313
    def _action_apply(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   314
        self._default_publish()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   315
        self.reset()
1753
ba01605cdd9a delete-trailing-spaces
sylvain.thenault@logilab.fr
parents: 1361
diff changeset
   316
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   317
    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
   318
        errorurl = self._cw.form.get('__errorurl')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   319
        if errorurl:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
   320
            self._cw.cancel_edition(errorurl)
4940
3143a1258d62 [web deletion] must use set_message
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4934
diff changeset
   321
        self._cw.set_message(self._cw._('edit canceled'))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   322
        return self.reset()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   323
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   324
    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
   325
        self.delete_entities(self._cw.edited_eids(withtype=True))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   326
        return self.reset()