web/controller.py
brancholdstable
changeset 5422 0865e1e90674
parent 5421 8167de96c523
child 5424 8ecbcbff9777
equal deleted inserted replaced
4985:02b52bf9f5f8 5422:0865e1e90674
       
     1 # copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
       
     2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
       
     3 #
       
     4 # This file is part of CubicWeb.
       
     5 #
       
     6 # CubicWeb is free software: you can redistribute it and/or modify it under the
       
     7 # terms of the GNU Lesser General Public License as published by the Free
       
     8 # Software Foundation, either version 2.1 of the License, or (at your option)
       
     9 # any later version.
       
    10 #
       
    11 # logilab-common is distributed in the hope that it will be useful, but WITHOUT
       
    12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
       
    13 # FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
       
    14 # details.
       
    15 #
       
    16 # You should have received a copy of the GNU Lesser General Public License along
       
    17 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
     1 """abstract controller classe for CubicWeb web client
    18 """abstract controller classe for CubicWeb web client
     2 
    19 
     3 
    20 
     4 :organization: Logilab
       
     5 :copyright: 2001-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
       
     6 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
       
     7 :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
       
     8 """
    21 """
     9 __docformat__ = "restructuredtext en"
    22 __docformat__ = "restructuredtext en"
       
    23 
       
    24 from logilab.mtconverter import xml_escape
    10 
    25 
    11 from cubicweb.selectors import yes
    26 from cubicweb.selectors import yes
    12 from cubicweb.appobject import AppObject
    27 from cubicweb.appobject import AppObject
    13 from cubicweb.web import LOGGER, Redirect, RequestError
    28 from cubicweb.web import LOGGER, Redirect, RequestError
    14 
    29 
    77             pp = self._cw.vreg['components'].select_or_none('magicsearch', self._cw)
    92             pp = self._cw.vreg['components'].select_or_none('magicsearch', self._cw)
    78             if pp is not None:
    93             if pp is not None:
    79                 self.cw_rset = pp.process_query(rql)
    94                 self.cw_rset = pp.process_query(rql)
    80         return self.cw_rset
    95         return self.cw_rset
    81 
    96 
    82     def check_expected_params(self, params):
       
    83         """check that the given list of parameters are specified in the form
       
    84         dictionary
       
    85         """
       
    86         missing = []
       
    87         for param in params:
       
    88             if not self._cw.form.get(param):
       
    89                 missing.append(param)
       
    90         if missing:
       
    91             raise RequestError('missing required parameter(s): %s'
       
    92                                % ','.join(missing))
       
    93 
       
    94 
       
    95     def notify_edited(self, entity):
    97     def notify_edited(self, entity):
    96         """called by edit_entity() to notify which entity is edited"""
    98         """called by edit_entity() to notify which entity is edited"""
    97         # NOTE: we can't use entity.rest_path() at this point because
    99         # NOTE: we can't use entity.rest_path() at this point because
    98         #       rest_path() could rely on schema constraints (such as a required
   100         #       rest_path() could rely on schema constraints (such as a required
    99         #       relation) that might not be satisfied yet (in case of creations)
   101         #       relation) that might not be satisfied yet (in case of creations)
   100         if not self._edited_entity:
   102         if not self._edited_entity:
   101             self._edited_entity = entity
   103             self._edited_entity = entity
   102 
   104 
   103     # XXX move to EditController (only customer)
       
   104     def delete_entities(self, eidtypes):
       
   105         """delete entities from the repository"""
       
   106         redirect_info = set()
       
   107         eidtypes = tuple(eidtypes)
       
   108         for eid, etype in eidtypes:
       
   109             entity = self._cw.entity_from_eid(eid, etype)
       
   110             path, params = entity.after_deletion_path()
       
   111             redirect_info.add( (path, tuple(params.iteritems())) )
       
   112             entity.delete()
       
   113         if len(redirect_info) > 1:
       
   114             # In the face of ambiguity, refuse the temptation to guess.
       
   115             self._after_deletion_path = 'view', ()
       
   116         else:
       
   117             self._after_deletion_path = iter(redirect_info).next()
       
   118         if len(eidtypes) > 1:
       
   119             self._cw.set_message(self._cw._('entities deleted'))
       
   120         else:
       
   121             self._cw.set_message(self._cw._('entity deleted'))
       
   122 
       
   123     def validate_cache(self, view):
   105     def validate_cache(self, view):
   124         view.set_http_cache_headers()
   106         view.set_http_cache_headers()
   125         self._cw.validate_cache()
   107         self._cw.validate_cache()
   126 
   108 
   127     # XXX is that used AT ALL ?
       
   128     def reset(self):
   109     def reset(self):
   129         """reset form parameters and redirect to a view determinated by given
   110         """reset form parameters and redirect to a view determinated by given
   130         parameters
   111         parameters
   131         """
   112         """
   132         newparams = {}
   113         newparams = {}
   133         # sets message if needed
   114         # sets message if needed
   134         if self._cw.message:
   115         if self._cw.message:
   135             newparams['__message'] = self._cw.message
   116             newparams['_cwmsgid'] = self._cw.set_redirect_message(self._cw.message)
   136         if self._cw.form.has_key('__action_apply'):
   117         if self._cw.form.has_key('__action_apply'):
   137             self._return_to_edition_view(newparams)
   118             self._return_to_edition_view(newparams)
   138         if self._cw.form.has_key('__action_cancel'):
   119         if self._cw.form.has_key('__action_cancel'):
   139             self._return_to_lastpage(newparams)
   120             self._return_to_lastpage(newparams)
   140         else:
   121         else:
   141             self._return_to_original_view(newparams)
   122             self._return_to_original_view(newparams)
   142 
   123 
   143 
       
   144     # XXX is that used AT ALL ?
       
   145     def _return_to_original_view(self, newparams):
   124     def _return_to_original_view(self, newparams):
   146         """validate-button case"""
   125         """validate-button case"""
   147         # transforms __redirect[*] parameters into regular form parameters
   126         # transforms __redirect[*] parameters into regular form parameters
   148         newparams.update(redirect_params(self._cw.form))
   127         newparams.update(redirect_params(self._cw.form))
   149         # find out if we have some explicit `rql` needs
   128         # find out if we have some explicit `rql` needs
   154             path = 'view'
   133             path = 'view'
   155             newparams['rql'] = rql
   134             newparams['rql'] = rql
   156         elif '__redirectpath' in self._cw.form:
   135         elif '__redirectpath' in self._cw.form:
   157             # if redirect path was explicitly specified in the form, use it
   136             # if redirect path was explicitly specified in the form, use it
   158             path = self._cw.form['__redirectpath']
   137             path = self._cw.form['__redirectpath']
   159             if self._edited_entity and path != self._edited_entity.rest_path():
   138             if (self._edited_entity and path != self._edited_entity.rest_path()
   160                 # XXX may be here on modification? if yes the message should be
   139                 and '_cwmsgid' in newparams):
   161                 # modified where __createdpath is detected (cw.web.request)
   140                 # XXX may be here on modification?
   162                 newparams['__createdpath'] = self._edited_entity.rest_path()
   141                 msg = u'(<a href="%s">%s</a>)' % (
       
   142                     xml_escape(self._edited_entity.absolute_url()),
       
   143                     self._cw._('click here to see created entity'))
       
   144                 self._cw.append_to_redirect_message(msg)
   163         elif self._after_deletion_path:
   145         elif self._after_deletion_path:
   164             # else it should have been set during form processing
   146             # else it should have been set during form processing
   165             path, params = self._after_deletion_path
   147             path, params = self._after_deletion_path
   166             params = dict(params) # params given as tuple
   148             params = dict(params) # params given as tuple
   167             params.update(newparams)
   149             params.update(newparams)
   168             newparams = params
   150             newparams = params
   169         elif self._edited_entity:
   151         elif self._edited_entity:
       
   152             # clear caches in case some attribute participating to the rest path
       
   153             # has been modified
       
   154             self._edited_entity.clear_all_caches()
   170             path = self._edited_entity.rest_path()
   155             path = self._edited_entity.rest_path()
   171         else:
   156         else:
   172             path = 'view'
   157             path = 'view'
   173         url = self._cw.build_url(path, **newparams)
   158         url = self._cw.build_url(path, **newparams)
   174         url = append_url_params(url, self._cw.form.get('__redirectparams'))
   159         url = append_url_params(url, self._cw.form.get('__redirectparams'))
   175         raise Redirect(url)
   160         raise Redirect(url)
   176 
   161 
   177     # XXX is that used AT ALL ?
       
   178     def _return_to_edition_view(self, newparams):
   162     def _return_to_edition_view(self, newparams):
   179         """apply-button case"""
   163         """apply-button case"""
   180         form = self._cw.form
   164         form = self._cw.form
   181         if self._edited_entity:
   165         if self._edited_entity:
   182             path = self._edited_entity.rest_path()
   166             path = self._edited_entity.rest_path()
   184         # else, fallback on the old `view?rql=...` url form
   168         # else, fallback on the old `view?rql=...` url form
   185         elif 'rql' in self._cw.form:
   169         elif 'rql' in self._cw.form:
   186             path = 'view'
   170             path = 'view'
   187             newparams['rql'] = form['rql']
   171             newparams['rql'] = form['rql']
   188         else:
   172         else:
   189             self.warning("the edited data seems inconsistent")
   173             self.warning('the edited data seems inconsistent')
   190             path = 'view'
   174             path = 'view'
   191         # pick up the correction edition view
   175         # pick up the correction edition view
   192         if form.get('__form_id'):
   176         if form.get('__form_id'):
   193             newparams['vid'] = form['__form_id']
   177             newparams['vid'] = form['__form_id']
   194         # re-insert copy redirection parameters
   178         # re-insert copy redirection parameters
   196             if redirectparam in form:
   180             if redirectparam in form:
   197                 newparams[redirectparam] = form[redirectparam]
   181                 newparams[redirectparam] = form[redirectparam]
   198         raise Redirect(self._cw.build_url(path, **newparams))
   182         raise Redirect(self._cw.build_url(path, **newparams))
   199 
   183 
   200 
   184 
   201     # XXX is that used AT ALL ?
       
   202     def _return_to_lastpage(self, newparams):
   185     def _return_to_lastpage(self, newparams):
   203         """cancel-button case: in this case we are always expecting to go back
   186         """cancel-button case: in this case we are always expecting to go back
   204         where we came from, and this is not easy. Currently we suppose that
   187         where we came from, and this is not easy. Currently we suppose that
   205         __redirectpath is specifying that place if found, else we look in the
   188         __redirectpath is specifying that place if found, else we look in the
   206         request breadcrumbs for the last visited page.
   189         request breadcrumbs for the last visited page.