From 58884580ebf1deac384ba6511ffa6668f3e23aff Mon Sep 17 00:00:00 2001 From: addshore Date: Wed, 26 Feb 2014 20:49:12 +0100 Subject: [PATCH] Split the rest of Action.php into /actions/ Change-Id: I071ac5778af63a5cffffd59d804c99b2c799d4e5 --- includes/AutoLoader.php | 6 +- includes/{ => actions}/Action.php | 220 ---------------------------- includes/actions/FormAction.php | 168 +++++++++++++++++++++ includes/actions/FormlessAction.php | 100 +++++++++++++ 4 files changed, 271 insertions(+), 223 deletions(-) rename includes/{ => actions}/Action.php (64%) create mode 100644 includes/actions/FormAction.php create mode 100644 includes/actions/FormlessAction.php diff --git a/includes/AutoLoader.php b/includes/AutoLoader.php index c511b4b2b1..a6733ad021 100644 --- a/includes/AutoLoader.php +++ b/includes/AutoLoader.php @@ -29,7 +29,6 @@ global $wgAutoloadLocalClasses; $wgAutoloadLocalClasses = array( # Includes - 'Action' => 'includes/Action.php', 'AjaxDispatcher' => 'includes/AjaxDispatcher.php', 'AjaxResponse' => 'includes/AjaxResponse.php', 'AlphabeticPager' => 'includes/Pager.php', @@ -80,8 +79,6 @@ $wgAutoloadLocalClasses = array( 'FeedUtils' => 'includes/FeedUtils.php', 'FileDeleteForm' => 'includes/FileDeleteForm.php', 'ForkController' => 'includes/ForkController.php', - 'FormlessAction' => 'includes/Action.php', - 'FormAction' => 'includes/Action.php', 'FormOptions' => 'includes/FormOptions.php', 'FormSpecialPage' => 'includes/specialpage/FormSpecialPage.php', 'GitInfo' => 'includes/GitInfo.php', @@ -237,10 +234,13 @@ $wgAutoloadLocalClasses = array( 'XmlSelect' => 'includes/Xml.php', # includes/actions + 'Action' => 'includes/actions/Action.php', 'CachedAction' => 'includes/actions/CachedAction.php', 'CreditsAction' => 'includes/actions/CreditsAction.php', 'DeleteAction' => 'includes/actions/DeleteAction.php', 'EditAction' => 'includes/actions/EditAction.php', + 'FormlessAction' => 'includes/actions/FormlessAction.php', + 'FormAction' => 'includes/actions/FormAction.php', 'HistoryAction' => 'includes/actions/HistoryAction.php', 'HistoryPage' => 'includes/actions/HistoryAction.php', 'HistoryPager' => 'includes/actions/HistoryAction.php', diff --git a/includes/Action.php b/includes/actions/Action.php similarity index 64% rename from includes/Action.php rename to includes/actions/Action.php index 72be46f0bb..1180c5e57a 100644 --- a/includes/Action.php +++ b/includes/actions/Action.php @@ -378,223 +378,3 @@ abstract class Action { */ abstract public function execute(); } - -/** - * An action which shows a form and does something based on the input from the form - */ -abstract class FormAction extends Action { - - /** - * Get an HTMLForm descriptor array - * @return Array - */ - abstract protected function getFormFields(); - - /** - * Add pre- or post-text to the form - * @return String HTML which will be sent to $form->addPreText() - */ - protected function preText() { - return ''; - } - - /** - * @return string - */ - protected function postText() { - return ''; - } - - /** - * Play with the HTMLForm if you need to more substantially - * @param $form HTMLForm - */ - protected function alterForm( HTMLForm $form ) { - } - - /** - * Get the HTMLForm to control behavior - * @return HTMLForm|null - */ - protected function getForm() { - $this->fields = $this->getFormFields(); - - // Give hooks a chance to alter the form, adding extra fields or text etc - wfRunHooks( 'ActionModifyFormFields', array( $this->getName(), &$this->fields, $this->page ) ); - - $form = new HTMLForm( $this->fields, $this->getContext(), $this->getName() ); - $form->setSubmitCallback( array( $this, 'onSubmit' ) ); - - // Retain query parameters (uselang etc) - $form->addHiddenField( 'action', $this->getName() ); // Might not be the same as the query string - $params = array_diff_key( - $this->getRequest()->getQueryValues(), - array( 'action' => null, 'title' => null ) - ); - $form->addHiddenField( 'redirectparams', wfArrayToCgi( $params ) ); - - $form->addPreText( $this->preText() ); - $form->addPostText( $this->postText() ); - $this->alterForm( $form ); - - // Give hooks a chance to alter the form, adding extra fields or text etc - wfRunHooks( 'ActionBeforeFormDisplay', array( $this->getName(), &$form, $this->page ) ); - - return $form; - } - - /** - * Process the form on POST submission. If you return false from getFormFields(), - * this will obviously never be reached. If you don't want to do anything with the - * form, just return false here - * @param $data Array - * @return Bool|Array true for success, false for didn't-try, array of errors on failure - */ - abstract public function onSubmit( $data ); - - /** - * Do something exciting on successful processing of the form. This might be to show - * a confirmation message (watch, rollback, etc) or to redirect somewhere else (edit, - * protect, etc). - */ - abstract public function onSuccess(); - - /** - * The basic pattern for actions is to display some sort of HTMLForm UI, maybe with - * some stuff underneath (history etc); to do some processing on submission of that - * form (delete, protect, etc) and to do something exciting on 'success', be that - * display something new or redirect to somewhere. Some actions have more exotic - * behavior, but that's what subclassing is for :D - */ - public function show() { - $this->setHeaders(); - - // This will throw exceptions if there's a problem - $this->checkCanExecute( $this->getUser() ); - - $form = $this->getForm(); - if ( $form->show() ) { - $this->onSuccess(); - } - } - - /** - * @see Action::execute() - * - * @param $data array|null - * @param $captureErrors bool - * @throws ErrorPageError|Exception - * @return bool - */ - public function execute( array $data = null, $captureErrors = true ) { - try { - // Set a new context so output doesn't leak. - $this->context = clone $this->getContext(); - - // This will throw exceptions if there's a problem - $this->checkCanExecute( $this->getUser() ); - - $fields = array(); - foreach ( $this->fields as $key => $params ) { - if ( isset( $data[$key] ) ) { - $fields[$key] = $data[$key]; - } elseif ( isset( $params['default'] ) ) { - $fields[$key] = $params['default']; - } else { - $fields[$key] = null; - } - } - $status = $this->onSubmit( $fields ); - if ( $status === true ) { - // This might do permanent stuff - $this->onSuccess(); - return true; - } else { - return false; - } - } - catch ( ErrorPageError $e ) { - if ( $captureErrors ) { - return false; - } else { - throw $e; - } - } - } -} - -/** - * An action which just does something, without showing a form first. - */ -abstract class FormlessAction extends Action { - - /** - * Show something on GET request. - * @return String|null will be added to the HTMLForm if present, or just added to the - * output if not. Return null to not add anything - */ - abstract public function onView(); - - /** - * We don't want an HTMLForm - * @return bool - */ - protected function getFormFields() { - return false; - } - - /** - * @param $data Array - * @return bool - */ - public function onSubmit( $data ) { - return false; - } - - /** - * @return bool - */ - public function onSuccess() { - return false; - } - - public function show() { - $this->setHeaders(); - - // This will throw exceptions if there's a problem - $this->checkCanExecute( $this->getUser() ); - - $this->getOutput()->addHTML( $this->onView() ); - } - - /** - * Execute the action silently, not giving any output. Since these actions don't have - * forms, they probably won't have any data, but some (eg rollback) may do - * @param array $data values that would normally be in the GET request - * @param bool $captureErrors whether to catch exceptions and just return false - * @throws ErrorPageError|Exception - * @return Bool whether execution was successful - */ - public function execute( array $data = null, $captureErrors = true ) { - try { - // Set a new context so output doesn't leak. - $this->context = clone $this->getContext(); - if ( is_array( $data ) ) { - $this->context->setRequest( new FauxRequest( $data, false ) ); - } - - // This will throw exceptions if there's a problem - $this->checkCanExecute( $this->getUser() ); - - $this->onView(); - return true; - } - catch ( ErrorPageError $e ) { - if ( $captureErrors ) { - return false; - } else { - throw $e; - } - } - } -} diff --git a/includes/actions/FormAction.php b/includes/actions/FormAction.php new file mode 100644 index 0000000000..974ee94f52 --- /dev/null +++ b/includes/actions/FormAction.php @@ -0,0 +1,168 @@ +addPreText() + */ + protected function preText() { + return ''; + } + + /** + * @return string + */ + protected function postText() { + return ''; + } + + /** + * Play with the HTMLForm if you need to more substantially + * @param $form HTMLForm + */ + protected function alterForm( HTMLForm $form ) { + } + + /** + * Get the HTMLForm to control behavior + * @return HTMLForm|null + */ + protected function getForm() { + $this->fields = $this->getFormFields(); + + // Give hooks a chance to alter the form, adding extra fields or text etc + wfRunHooks( 'ActionModifyFormFields', array( $this->getName(), &$this->fields, $this->page ) ); + + $form = new HTMLForm( $this->fields, $this->getContext(), $this->getName() ); + $form->setSubmitCallback( array( $this, 'onSubmit' ) ); + + // Retain query parameters (uselang etc) + $form->addHiddenField( 'action', $this->getName() ); // Might not be the same as the query string + $params = array_diff_key( + $this->getRequest()->getQueryValues(), + array( 'action' => null, 'title' => null ) + ); + $form->addHiddenField( 'redirectparams', wfArrayToCgi( $params ) ); + + $form->addPreText( $this->preText() ); + $form->addPostText( $this->postText() ); + $this->alterForm( $form ); + + // Give hooks a chance to alter the form, adding extra fields or text etc + wfRunHooks( 'ActionBeforeFormDisplay', array( $this->getName(), &$form, $this->page ) ); + + return $form; + } + + /** + * Process the form on POST submission. If you return false from getFormFields(), + * this will obviously never be reached. If you don't want to do anything with the + * form, just return false here + * @param $data Array + * @return Bool|Array true for success, false for didn't-try, array of errors on failure + */ + abstract public function onSubmit( $data ); + + /** + * Do something exciting on successful processing of the form. This might be to show + * a confirmation message (watch, rollback, etc) or to redirect somewhere else (edit, + * protect, etc). + */ + abstract public function onSuccess(); + + /** + * The basic pattern for actions is to display some sort of HTMLForm UI, maybe with + * some stuff underneath (history etc); to do some processing on submission of that + * form (delete, protect, etc) and to do something exciting on 'success', be that + * display something new or redirect to somewhere. Some actions have more exotic + * behavior, but that's what subclassing is for :D + */ + public function show() { + $this->setHeaders(); + + // This will throw exceptions if there's a problem + $this->checkCanExecute( $this->getUser() ); + + $form = $this->getForm(); + if ( $form->show() ) { + $this->onSuccess(); + } + } + + /** + * @see Action::execute() + * + * @param $data array|null + * @param $captureErrors bool + * @throws ErrorPageError|Exception + * @return bool + */ + public function execute( array $data = null, $captureErrors = true ) { + try { + // Set a new context so output doesn't leak. + $this->context = clone $this->getContext(); + + // This will throw exceptions if there's a problem + $this->checkCanExecute( $this->getUser() ); + + $fields = array(); + foreach ( $this->fields as $key => $params ) { + if ( isset( $data[$key] ) ) { + $fields[$key] = $data[$key]; + } elseif ( isset( $params['default'] ) ) { + $fields[$key] = $params['default']; + } else { + $fields[$key] = null; + } + } + $status = $this->onSubmit( $fields ); + if ( $status === true ) { + // This might do permanent stuff + $this->onSuccess(); + return true; + } else { + return false; + } + } + catch ( ErrorPageError $e ) { + if ( $captureErrors ) { + return false; + } else { + throw $e; + } + } + } +} diff --git a/includes/actions/FormlessAction.php b/includes/actions/FormlessAction.php new file mode 100644 index 0000000000..6cab4d1d04 --- /dev/null +++ b/includes/actions/FormlessAction.php @@ -0,0 +1,100 @@ +setHeaders(); + + // This will throw exceptions if there's a problem + $this->checkCanExecute( $this->getUser() ); + + $this->getOutput()->addHTML( $this->onView() ); + } + + /** + * Execute the action silently, not giving any output. Since these actions don't have + * forms, they probably won't have any data, but some (eg rollback) may do + * @param array $data values that would normally be in the GET request + * @param bool $captureErrors whether to catch exceptions and just return false + * @throws ErrorPageError|Exception + * @return Bool whether execution was successful + */ + public function execute( array $data = null, $captureErrors = true ) { + try { + // Set a new context so output doesn't leak. + $this->context = clone $this->getContext(); + if ( is_array( $data ) ) { + $this->context->setRequest( new FauxRequest( $data, false ) ); + } + + // This will throw exceptions if there's a problem + $this->checkCanExecute( $this->getUser() ); + + $this->onView(); + return true; + } + catch ( ErrorPageError $e ) { + if ( $captureErrors ) { + return false; + } else { + throw $e; + } + } + } +} -- 2.20.1