This objective is hard to satisfy with our current adminhandler mechanism.
For example, I'd like to make a UserHandler object to handle POSTed
values from a user profile screen. This screen should allow the user to
update their email address, display name, and password. But it should
also report if the two new passwords they enter are not the same.
There's no easy way to get that error message to the user, unless the
profile page POSTs to itself, rather than to /admin/post/user or unless
the post handler redirects to "/admin/user?error=password" (or
"/admin/user/error/password", I suppose).
(I reject the notion that the /admin/post/user page could display the
error message: all user profile actions and messages should be through
/admin/user _only_)
So: are you folks open to the idea of pages POSTing to themselves, in
contravention of our current /admin/post/foo precedent, or would you
prefer to use querystrings for error messages and other status messages
that need to be displayed after a POST? A page POSTing to itself should
probably have the URL parser catch that early on in its processing and
dispatch to the appropriate handler...
--
ski...@skippy.net | http://skippy.net/
gpg --keyserver pgp.mit.edu --recv-keys 9CFA4B35
506C F8BB 17AE 8A05 0B49 3544 476A 7DEC 9CFA 4B35
Have a look at UserHandler::login().
UserHandler::login() executes when the user submits the login form.
Look at the line near the bottom:
new ThemeHandler( 'login', $settings );
Basically, the login form handler never redirects to the login page.
It simply calls the handler that would display the login page.
If there was an error in the login, those details are added into the
$url object as if they were in the querystring, even though they
really weren't. The ThemeHandler behaves as though that error was set
because, well, it was.
The same thing could be done with AdminHandler. Have AdminHandler
handle the post from the form, and then create a new AdminHandler from
inside that function targetted to produce the required output. No
redirection required. No querystrings mangled.
But the errors would appear under the posted URL, which...
> (I reject the notion that the /admin/post/user page could display the
> error message: all user profile actions and messages should be through
> /admin/user _only_)
Right, ok.
> So: are you folks open to the idea of pages POSTing to themselves, in
> contravention of our current /admin/post/foo precedent, or would you
> prefer to use querystrings for error messages and other status messages
> that need to be displayed after a POST? A page POSTing to itself should
> probably have the URL parser catch that early on in its processing and
> dispatch to the appropriate handler...
You want to execute a different method based on the
$_SERVER['request_method'] used? That shouldn't be a problem. We
could replace AdminHandler's constructor to do that.
public function __construct($action, $settings)
{
try {
switch( $_SERVER['REQUEST_METHOD'] ) {
'POST':
$fn = 'post_' . $action;
default:
$fn = $action;
}
call_user_func(array($this, $fn), $settings);
}
catch ( Exception $e ) {
$classname = get_class($this);
echo "\n{$classname}->{$action}() does not exist.\n";
}
}
That should call profile() when the URL is '/admin/profile' and the
request method is GET, and post_profile() when the URL is
'/admin/profile' and the request method is POST.
If you need to display the form again, you could call profile() from
within post_profile(). Add some additional values to $settings before
you call profile() if you need to display some messages.
post_profile() itself shouldn't display anything, just act on the
submission, then hand some settings back to profile().
Seem reasonable?
The thing I worry about (using either method) is having all of this
stuff inside of AdminHandler. There should be a way to spread this
out so that the UI and the processing are separate but related.
Using the post_*() method above for every admin form, we'll have a ton
of post processing member functions all sitting in AdminHandler, and
the UI all sitting in separate, nicely-parceled files in the admin
theme. Is that a good thing? If not, what do we do to smooth it out?
Owen
That looks like a very good solution.
> If you need to display the form again, you could call profile() from
> within post_profile(). Add some additional values to $settings before
> you call profile() if you need to display some messages.
> post_profile() itself shouldn't display anything, just act on the
> submission, then hand some settings back to profile().
>
> Seem reasonable?
Yes!
> The thing I worry about (using either method) is having all of this
> stuff inside of AdminHandler. There should be a way to spread this
> out so that the UI and the processing are separate but related.
>
> Using the post_*() method above for every admin form, we'll have a ton
> of post processing member functions all sitting in AdminHandler, and
> the UI all sitting in separate, nicely-parceled files in the admin
> theme. Is that a good thing? If not, what do we do to smooth it out?
Could we bundle the post handlers into the admin pages that trigger
them? So options.php contains both the form for displaying the options
_and_ the post_options() method for dealing with their submission?
The drawback to this is that either our admin "theme" files would live
in /system/classes, or some classes would live in /system/admin.
Inelegant either way.
Or maybe we could tuck the post_* classes into a sub-directory in
/system/classes, and autoload them as needed?
>
> So: are you folks open to the idea of pages POSTing to themselves, in
> contravention of our current /admin/post/foo precedent, or would you
> prefer to use querystrings for error messages and other status
> messages
> that need to be displayed after a POST? A page POSTing to itself
> should
> probably have the URL parser catch that early on in its processing and
> dispatch to the appropriate handler...
Since our parameters method doesn't care whether the data came in a
GET or a POST, I see no (technical) obstacle to doing this.