MediaWiki
REL1_24
|
00001 <?php 00037 abstract class Action { 00038 00044 protected $page; 00045 00051 protected $context; 00052 00058 protected $fields; 00059 00067 final private static function getClass( $action, array $overrides ) { 00068 global $wgActions; 00069 $action = strtolower( $action ); 00070 00071 if ( !isset( $wgActions[$action] ) ) { 00072 return null; 00073 } 00074 00075 if ( $wgActions[$action] === false ) { 00076 return false; 00077 } elseif ( $wgActions[$action] === true && isset( $overrides[$action] ) ) { 00078 return $overrides[$action]; 00079 } elseif ( $wgActions[$action] === true ) { 00080 return ucfirst( $action ) . 'Action'; 00081 } else { 00082 return $wgActions[$action]; 00083 } 00084 } 00085 00095 final public static function factory( $action, Page $page, IContextSource $context = null ) { 00096 $classOrCallable = self::getClass( $action, $page->getActionOverrides() ); 00097 00098 if ( is_string( $classOrCallable ) ) { 00099 $obj = new $classOrCallable( $page, $context ); 00100 return $obj; 00101 } 00102 00103 if ( is_callable( $classOrCallable ) ) { 00104 return call_user_func_array( $classOrCallable, array( $page, $context ) ); 00105 } 00106 00107 return $classOrCallable; 00108 } 00109 00119 final public static function getActionName( IContextSource $context ) { 00120 global $wgActions; 00121 00122 $request = $context->getRequest(); 00123 $actionName = $request->getVal( 'action', 'view' ); 00124 00125 // Check for disabled actions 00126 if ( isset( $wgActions[$actionName] ) && $wgActions[$actionName] === false ) { 00127 $actionName = 'nosuchaction'; 00128 } 00129 00130 // Workaround for bug #20966: inability of IE to provide an action dependent 00131 // on which submit button is clicked. 00132 if ( $actionName === 'historysubmit' ) { 00133 if ( $request->getBool( 'revisiondelete' ) ) { 00134 $actionName = 'revisiondelete'; 00135 } else { 00136 $actionName = 'view'; 00137 } 00138 } elseif ( $actionName == 'editredlink' ) { 00139 $actionName = 'edit'; 00140 } 00141 00142 // Trying to get a WikiPage for NS_SPECIAL etc. will result 00143 // in WikiPage::factory throwing "Invalid or virtual namespace -1 given." 00144 // For SpecialPages et al, default to action=view. 00145 if ( !$context->canUseWikiPage() ) { 00146 return 'view'; 00147 } 00148 00149 $action = Action::factory( $actionName, $context->getWikiPage(), $context ); 00150 if ( $action instanceof Action ) { 00151 return $action->getName(); 00152 } 00153 00154 return 'nosuchaction'; 00155 } 00156 00164 final public static function exists( $name ) { 00165 return self::getClass( $name, array() ) !== null; 00166 } 00167 00173 final public function getContext() { 00174 if ( $this->context instanceof IContextSource ) { 00175 return $this->context; 00176 } elseif ( $this->page instanceof Article ) { 00177 // NOTE: $this->page can be a WikiPage, which does not have a context. 00178 wfDebug( __METHOD__ . ": no context known, falling back to Article's context.\n" ); 00179 return $this->page->getContext(); 00180 } 00181 00182 wfWarn( __METHOD__ . ': no context known, falling back to RequestContext::getMain().' ); 00183 return RequestContext::getMain(); 00184 } 00185 00192 final public function getRequest() { 00193 return $this->getContext()->getRequest(); 00194 } 00195 00202 final public function getOutput() { 00203 return $this->getContext()->getOutput(); 00204 } 00205 00212 final public function getUser() { 00213 return $this->getContext()->getUser(); 00214 } 00215 00222 final public function getSkin() { 00223 return $this->getContext()->getSkin(); 00224 } 00225 00231 final public function getLanguage() { 00232 return $this->getContext()->getLanguage(); 00233 } 00234 00241 final public function getTitle() { 00242 return $this->page->getTitle(); 00243 } 00244 00251 final public function msg() { 00252 $params = func_get_args(); 00253 return call_user_func_array( array( $this->getContext(), 'msg' ), $params ); 00254 } 00255 00264 public function __construct( Page $page, IContextSource $context = null ) { 00265 if ( $context === null ) { 00266 wfWarn( __METHOD__ . ' called without providing a Context object.' ); 00267 // NOTE: We could try to initialize $context using $page->getContext(), 00268 // if $page is an Article. That however seems to not work seamlessly. 00269 } 00270 00271 $this->page = $page; 00272 $this->context = $context; 00273 } 00274 00281 abstract public function getName(); 00282 00290 public function getRestriction() { 00291 return null; 00292 } 00293 00303 protected function checkCanExecute( User $user ) { 00304 $right = $this->getRestriction(); 00305 if ( $right !== null ) { 00306 $errors = $this->getTitle()->getUserPermissionsErrors( $right, $user ); 00307 if ( count( $errors ) ) { 00308 throw new PermissionsError( $right, $errors ); 00309 } 00310 } 00311 00312 if ( $this->requiresUnblock() && $user->isBlocked() ) { 00313 $block = $user->getBlock(); 00314 throw new UserBlockedError( $block ); 00315 } 00316 00317 // This should be checked at the end so that the user won't think the 00318 // error is only temporary when he also don't have the rights to execute 00319 // this action 00320 if ( $this->requiresWrite() && wfReadOnly() ) { 00321 throw new ReadOnlyError(); 00322 } 00323 } 00324 00331 public function requiresWrite() { 00332 return true; 00333 } 00334 00341 public function requiresUnblock() { 00342 return true; 00343 } 00344 00350 protected function setHeaders() { 00351 $out = $this->getOutput(); 00352 $out->setRobotPolicy( "noindex,nofollow" ); 00353 $out->setPageTitle( $this->getPageTitle() ); 00354 $out->setSubtitle( $this->getDescription() ); 00355 $out->setArticleRelated( true ); 00356 } 00357 00363 protected function getPageTitle() { 00364 return $this->getTitle()->getPrefixedText(); 00365 } 00366 00373 protected function getDescription() { 00374 return $this->msg( strtolower( $this->getName() ) )->escaped(); 00375 } 00376 00385 abstract public function show(); 00386 }