Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 41400107

Von Moritz Bunkus vor fast 14 Jahren hinzugefügt

  • ID 41400107ec8929d6ea107de7f5238006e9de029c
  • Vorgänger 95ecb428
  • Nachfolger eb1efd21

Neuer Routingmechanismus für Controller, die als Package implementiert sind

Voraussetzungen:

  • Controller liegt in SL/Controller/Class.pm und ist von
    SL::Controller::Base abgeleitet.
  • Der Name von Subs, die als Action aufgerufen werden sollen, muss mit
    "action_" beginnen. Alle Versuche, andere (auch existierende) Subs
    aufzurufen, werden entsprechend mit Fehlermeldungen quittiert.
  • Pro Request wird eine Instanz der Klasse erzeugt und danach vom
    garbage collector entsorgt.
  • Im Controller "$self->parse_html_template()" verwenden, dann ist im
    Template $self als SELF verfügbar, z.B. "[% FOREACH message =
    SELF.messages %]".
  • Form-Parameter "action" muss das Format "Controller::action"
    besitzen. "Controller" ist der Packagename ohne die Präfixe, sprich
    der Basisdateiname. "action" ist der Name der aufzurufenden Sub ohne
    das "action_"-Präfix. Aus "Message::list" würde also grob gesehen
    "SL::Controller::Message->new->action_list()".
  • Das Script in der URL muss 'controller.pl' heißen.

Conflicts:

SL/Dispatcher.pm
scripts/locales.pl

Unterschiede anzeigen:

SL/Controller/Base.pm
1
package SL::Controller::Base;
2

  
3
use parent qw(Rose::Object);
4

  
5
use List::Util qw(first);
6

  
7
sub parse_html_template {
8
  my $self = shift;
9
  my $name = shift;
10

  
11
  return $::form->parse_html_template($name, { @_, SELF => $self });
12
}
13

  
14
sub url_for {
15
  my $self = shift;
16

  
17
  return $_[0] if scalar(@_) == 1;
18

  
19
  my %params      = @_;
20
  my $controller  = delete($params{controller}) || $self->_controller_name;
21
  my $action      = delete($params{action})     || 'dispatch';
22
  $params{action} = "${controller}::${action}";
23
  my $query       = join('&', map { $::form->escape($_) . '=' . $::form->escape($params{$_}) } keys %params);
24

  
25
  return "controller.pl?${query}";
26
}
27

  
28
sub _run_action {
29
  my $self   = shift;
30
  my $action = "action_" . shift;
31

  
32
  return $self->_dispatch(@_) if $action eq 'action_dispatch';
33

  
34
  $::form->error("Invalid action ${action} for controller " . ref($self)) if !$self->can($action);
35
  $self->$action(@_);
36
}
37

  
38
sub _controller_name {
39
  return (split(/::/, ref($_[0])))[-1];
40
}
41

  
42
sub _dispatch {
43
  my $self    = shift;
44

  
45
  my @actions = grep { m/^action_/ } keys %{ ref($self) . "::" };
46
  my $action  = first { $::form->{$_} } @actions;
47

  
48
  $self->$action(@_);
49
}
50

  
51
1;
SL/Dispatcher.pm
123 123
  $::lxdebug->leave_sub;
124 124
}
125 125

  
126
sub _require_controller {
127
  my $controller =  shift;
128
  $controller    =~ s|[^A-Za-z0-9_]||g;
129

  
130
  eval {
131
    package main;
132
    require "SL/Controller/${controller}.pm";
133
  } or die $EVAL_ERROR;
134
}
135

  
136
sub _run_controller {
137
  "SL::Controller::$_[0]"->new->_run_action($_[1]);
138
}
139

  
126 140
sub handle_request {
127 141
  $::lxdebug->enter_sub;
128 142
  $::lxdebug->begin_request;
129 143

  
130 144
  my $interface = lc(shift || 'cgi');
131
  my ($script_name, $action);
145
  my ($script, $path, $suffix, $script_name, $action, $routing_type);
132 146

  
133 147
  $script_name = $ENV{SCRIPT_NAME};
134 148

  
......
139 153
  $::form        = Form->new;
140 154
  %::called_subs = ();
141 155

  
142
  eval { ($script_name, $action) = _route_request($script_name); 1; } or return;
156
  eval { ($routing_type, $script_name, $action) = _route_request($script_name); 1; } or return;
143 157

  
144
  my ($script, $path, $suffix) = fileparse($script_name, ".pl");
145
  require_main_code($script, $suffix);
158
  if ($routing_type eq 'old') {
159
    $::form->{action}  =  lc $::form->{action};
160
    $::form->{action}  =~ s/( |-|,|\#)/_/g;
146 161

  
147
  $::form->{script} = $script . $suffix;
162
   ($script, $path, $suffix) = fileparse($script_name, ".pl");
163
    require_main_code($script, $suffix);
164

  
165
    $::form->{script} = $script . $suffix;
166

  
167
  } else {
168
    _require_controller($script_name);
169
    $::form->{script} = "controller.pl";
170
  }
148 171

  
149 172
  pre_request_checks();
150 173

  
......
178 201
          unless $action eq 'save' && $::form->{type} eq 'preferences';
179 202

  
180 203
        $::form->set_standard_title;
181
        ::call_sub('::' . $::locale->findsub($action));
204
        if ($routing_type eq 'old') {
205
          ::call_sub('::' . $::locale->findsub($action));
206
        } else {
207
          _run_controller($script_name, $action);
208
        }
182 209
      } else {
183 210
        $::form->error($::locale->text('action= not defined!'));
184 211
      }
......
216 243
sub _route_request {
217 244
  my $script_name = shift;
218 245

  
219
  return $script_name =~ m/dispatcher\.pl$/ ? _route_dispatcher_request() : ($script_name, $::form->{action});
246
  return $script_name =~ m/dispatcher\.pl$/ ? ('old',        _route_dispatcher_request())
247
       : $script_name =~ m/controller\.pl/  ? ('controller', _route_controller_request())
248
       :                                      ('old',        $script_name, $::form->{action});
220 249
}
221 250

  
222 251
sub _route_dispatcher_request {
......
249 278
  return ($script_name, $action);
250 279
}
251 280

  
281
sub _route_controller_request {
282
  my ($controller, $action);
283

  
284
  eval {
285
    $::form->{action}      =~ m|^ ( [A-Z] [A-Za-z0-9_]* ) :: ( [a-z] [a-z0-9_]* ) $|x || die "Unroutable request -- inavlid controller/action.\n";
286
    ($controller, $action) =  ($1, $2);
287
    delete $::form->{action};
288

  
289
    1;
290
  } or do {
291
    $::form->{label_error} = $::cgi->pre($EVAL_ERROR);
292
    show_error('generic/error');
293
  };
294

  
295
  return ($controller, $action);
296
}
297

  
252 298
package main;
253 299

  
254 300
use strict;
SL/Form.pm
263 263

  
264 264
  _recode_recursively(SL::Iconv->new($encoding, $db_charset), $self);
265 265

  
266
  $self->{action}  =  lc $self->{action};
267
  $self->{action}  =~ s/( |-|,|\#)/_/g;
268

  
269 266
  #$self->{version} =  "2.6.1";                 # Old hardcoded but secure style
270 267
  open VERSION_FILE, "VERSION";                 # New but flexible code reads version from VERSION-file
271 268
  $self->{version} =  <VERSION_FILE>;
scripts/locales.pl
31 31
my $basedir      = "../..";
32 32
my $locales_dir  = ".";
33 33
my $bindir       = "$basedir/bin/mozilla";
34
my @progdirs     = ( "$basedir/SL/Template/Plugin" );
34
my @progdirs     = ( "$basedir/SL/Controller", "$basedir/SL/Template/Plugin" );
35 35
my $dbupdir      = "$basedir/sql/Pg-upgrade";
36 36
my $dbupdir2     = "$basedir/sql/Pg-upgrade2";
37 37
my $menufile     = "menu.ini";

Auch abrufbar als: Unified diff