Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
0.00% |
0 / 155 |
|
0.00% |
0 / 14 |
CRAP | |
0.00% |
0 / 1 |
| PFHooks | |
0.00% |
0 / 155 |
|
0.00% |
0 / 14 |
1482 | |
0.00% |
0 / 1 |
| registerExtension | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
30 | |||
| initialize | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
| registerModules | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
6 | |||
| registerNamespaces | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
6 | |||
| registerFunctions | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
2 | |||
| setGlobalJSVariables | |
0.00% |
0 / 21 |
|
0.00% |
0 / 1 |
2 | |||
| registerPageSchemasClass | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| addToAdminLinks | |
0.00% |
0 / 19 |
|
0.00% |
0 / 1 |
12 | |||
| addToCargoTablesColumns | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
12 | |||
| addToCargoTablesLinks | |
0.00% |
0 / 29 |
|
0.00% |
0 / 1 |
110 | |||
| addToCargoTablesRow | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
6 | |||
| showFormPreview | |
0.00% |
0 / 17 |
|
0.00% |
0 / 1 |
12 | |||
| setPostEditCookie | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
6 | |||
| handleForceReload | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
6 | |||
| 1 | <?php |
| 2 | /** |
| 3 | * Static functions called by various outside hooks, as well as by |
| 4 | * extension.json. |
| 5 | * |
| 6 | * @author Yaron Koren |
| 7 | * @file |
| 8 | * @ingroup PF |
| 9 | */ |
| 10 | |
| 11 | use MediaWiki\EditPage\EditPage; |
| 12 | use MediaWiki\Html\Html; |
| 13 | use MediaWiki\MediaWikiServices; |
| 14 | use MediaWiki\ResourceLoader\ResourceLoader; |
| 15 | use MediaWiki\StubObject\StubObject; |
| 16 | use MediaWiki\Title\Title; |
| 17 | |
| 18 | class PFHooks { |
| 19 | |
| 20 | /** |
| 21 | * Used for caching by addToCargoTablesLinks(). |
| 22 | */ |
| 23 | private static $mMultiPageEditPage = null; |
| 24 | |
| 25 | public static function registerExtension() { |
| 26 | if ( defined( 'PF_VERSION' ) ) { |
| 27 | // Do not load Page Forms more than once. |
| 28 | return 1; |
| 29 | } |
| 30 | |
| 31 | define( 'PF_VERSION', '6.0.5' ); |
| 32 | |
| 33 | $GLOBALS['wgPageFormsIP'] = dirname( __DIR__ ) . '/../'; |
| 34 | |
| 35 | /** |
| 36 | * This is a delayed init that makes sure that MediaWiki is set |
| 37 | * up properly before we add our stuff. |
| 38 | */ |
| 39 | |
| 40 | if ( defined( 'SMW_VERSION' ) || ExtensionRegistry::getInstance()->isLoaded( 'SemanticMediaWiki' ) ) { |
| 41 | $GLOBALS['wgSpecialPages']['CreateProperty'] = 'PFCreateProperty'; |
| 42 | $GLOBALS['wgAutoloadClasses']['PFCreateProperty'] = __DIR__ . '/../specials/PF_CreateProperty.php'; |
| 43 | $GLOBALS['smwgEnabledSpecialPage'][] = 'RunQuery'; |
| 44 | } |
| 45 | |
| 46 | // @TODO - rename this variable to something like $wgPageFormsEDValues. |
| 47 | // (This was formerly an External Data global variable.) |
| 48 | if ( method_exists( 'EDParserFunctions', 'getAllValues' ) ) { |
| 49 | $GLOBALS['edgValues'] = EDParserFunctions::getAllValues(); |
| 50 | } else { |
| 51 | $GLOBALS['edgValues'] = []; |
| 52 | } |
| 53 | |
| 54 | // Allow for popup windows for file upload |
| 55 | $GLOBALS['wgEditPageFrameOptions'] = 'SAMEORIGIN'; |
| 56 | } |
| 57 | |
| 58 | public static function initialize() { |
| 59 | $GLOBALS['wgPageFormsScriptPath'] = $GLOBALS['wgExtensionAssetsPath'] . '/PageForms'; |
| 60 | |
| 61 | // This global variable is needed so that other |
| 62 | // extensions can hook into it to add their own |
| 63 | // input types. |
| 64 | $GLOBALS['wgPageFormsFormPrinter'] = new StubObject( 'wgPageFormsFormPrinter', 'PFFormPrinter' ); |
| 65 | } |
| 66 | |
| 67 | /** |
| 68 | * Called by ResourceLoaderRegisterModules hook. |
| 69 | * |
| 70 | * @see https://www.mediawiki.org/wiki/Manual:Hooks/ResourceLoaderRegisterModules |
| 71 | * |
| 72 | * @param ResourceLoader $resourceLoader The ResourceLoader object |
| 73 | */ |
| 74 | public static function registerModules( ResourceLoader $resourceLoader ) { |
| 75 | // These used to use a value of __DIR__ for 'localBasePath', |
| 76 | // but apparently in some installations that had a value of |
| 77 | // /PageForms/libs and in others just /PageForms, so we'll set |
| 78 | // the value here instead. |
| 79 | $pageFormsDir = __DIR__ . '/..'; |
| 80 | |
| 81 | $mapsModuleAttrs = [ |
| 82 | 'localBasePath' => $pageFormsDir, |
| 83 | 'remoteExtPath' => 'PageForms', |
| 84 | 'dependencies' => [ 'oojs-ui.styles.icons-location' ] |
| 85 | ]; |
| 86 | |
| 87 | if ( ExtensionRegistry::getInstance()->isLoaded( 'OpenLayers' ) ) { |
| 88 | $mapsModuleAttrs['scripts'] = '/libs/PF_maps.offline.js'; |
| 89 | $mapsModuleAttrs['dependencies'][] = 'ext.openlayers.main'; |
| 90 | } else { |
| 91 | $mapsModuleAttrs['scripts'] = '/libs/PF_maps.js'; |
| 92 | } |
| 93 | |
| 94 | $resourceLoader->register( [ 'ext.pageforms.maps' => $mapsModuleAttrs ] ); |
| 95 | } |
| 96 | |
| 97 | /** |
| 98 | * Register the namespaces for Page Forms. |
| 99 | * @see https://www.mediawiki.org/wiki/Manual:Hooks/CanonicalNamespaces |
| 100 | * |
| 101 | * @since 2.4.1 |
| 102 | * |
| 103 | * @param array &$list |
| 104 | */ |
| 105 | public static function registerNamespaces( array &$list ) { |
| 106 | global $wgNamespacesWithSubpages; |
| 107 | |
| 108 | if ( !defined( 'PF_NS_FORM' ) ) { |
| 109 | define( 'PF_NS_FORM', 106 ); |
| 110 | define( 'PF_NS_FORM_TALK', 107 ); |
| 111 | } |
| 112 | |
| 113 | $list[PF_NS_FORM] = 'Form'; |
| 114 | $list[PF_NS_FORM_TALK] = 'Form_talk'; |
| 115 | |
| 116 | // Support subpages only for talk pages by default |
| 117 | $wgNamespacesWithSubpages[PF_NS_FORM_TALK] = true; |
| 118 | } |
| 119 | |
| 120 | /** |
| 121 | * Called by the ParserFirstCallInit hook. |
| 122 | * |
| 123 | * @param Parser $parser |
| 124 | */ |
| 125 | static function registerFunctions( Parser $parser ) { |
| 126 | $parser->setFunctionHook( 'default_form', [ 'PFDefaultForm', 'run' ] ); |
| 127 | $parser->setFunctionHook( 'forminput', [ 'PFFormInputParserFunction', 'run' ] ); |
| 128 | $parser->setFunctionHook( 'formlink', [ 'PFFormLink', 'run' ] ); |
| 129 | $parser->setFunctionHook( 'formredlink', [ 'PFFormRedLink', 'run' ] ); |
| 130 | $parser->setFunctionHook( 'queryformlink', [ 'PFQueryFormLink', 'run' ] ); |
| 131 | $parser->setFunctionHook( 'arraymap', [ 'PFArrayMap', 'run' ], Parser::SFH_OBJECT_ARGS ); |
| 132 | $parser->setFunctionHook( 'arraymaptemplate', [ 'PFArrayMapTemplate', 'run' ], Parser::SFH_OBJECT_ARGS ); |
| 133 | |
| 134 | $parser->setFunctionHook( 'autoedit', [ 'PFAutoEdit', 'run' ] ); |
| 135 | $parser->setFunctionHook( 'autoedit_rating', [ 'PFAutoEditRating', 'run' ] ); |
| 136 | $parser->setFunctionHook( 'template_params', [ 'PFTemplateParams', 'run' ] ); |
| 137 | $parser->setFunctionHook( 'template_display', [ 'PFTemplateDisplay', 'run' ], Parser::SFH_OBJECT_ARGS ); |
| 138 | } |
| 139 | |
| 140 | /** |
| 141 | * Called by the MakeGlobalVariablesScript hook. |
| 142 | * |
| 143 | * @param array &$vars |
| 144 | */ |
| 145 | static function setGlobalJSVariables( &$vars ) { |
| 146 | global $wgPageFormsTargetName; |
| 147 | global $wgPageFormsAutocompleteValues, $wgPageFormsAutocompleteOnAllChars; |
| 148 | global $wgPageFormsFieldProperties, $wgPageFormsCargoFields, $wgPageFormsDependentFields; |
| 149 | global $wgPageFormsGridValues, $wgPageFormsGridParams; |
| 150 | global $wgPageFormsCalendarValues, $wgPageFormsCalendarParams, $wgPageFormsCalendarHTML; |
| 151 | global $wgPageFormsContLangYes, $wgPageFormsContLangNo, $wgPageFormsContLangMonths; |
| 152 | global $wgPageFormsHeightForMinimizingInstances, $wgPageFormsDelayReload; |
| 153 | global $wgPageFormsShowOnSelect, $wgPageFormsScriptPath; |
| 154 | global $edgValues, $wgPageFormsEDSettings; |
| 155 | global $wgAmericanDates; |
| 156 | |
| 157 | $vars['wgPageFormsTargetName'] = $wgPageFormsTargetName; |
| 158 | $vars['wgPageFormsAutocompleteValues'] = $wgPageFormsAutocompleteValues; |
| 159 | $vars['wgPageFormsAutocompleteOnAllChars'] = $wgPageFormsAutocompleteOnAllChars; |
| 160 | $vars['wgPageFormsFieldProperties'] = $wgPageFormsFieldProperties; |
| 161 | $vars['wgPageFormsCargoFields'] = $wgPageFormsCargoFields; |
| 162 | $vars['wgPageFormsDependentFields'] = $wgPageFormsDependentFields; |
| 163 | $vars['wgPageFormsCalendarValues'] = $wgPageFormsCalendarValues; |
| 164 | $vars['wgPageFormsCalendarParams'] = $wgPageFormsCalendarParams; |
| 165 | $vars['wgPageFormsCalendarHTML'] = $wgPageFormsCalendarHTML; |
| 166 | $vars['wgPageFormsGridValues'] = $wgPageFormsGridValues; |
| 167 | $vars['wgPageFormsGridParams'] = $wgPageFormsGridParams; |
| 168 | $vars['wgPageFormsContLangYes'] = $wgPageFormsContLangYes; |
| 169 | $vars['wgPageFormsContLangNo'] = $wgPageFormsContLangNo; |
| 170 | $vars['wgPageFormsContLangMonths'] = $wgPageFormsContLangMonths; |
| 171 | $vars['wgPageFormsHeightForMinimizingInstances'] = $wgPageFormsHeightForMinimizingInstances; |
| 172 | $vars['wgPageFormsDelayReload'] = $wgPageFormsDelayReload; |
| 173 | $vars['wgPageFormsShowOnSelect'] = $wgPageFormsShowOnSelect; |
| 174 | $vars['wgPageFormsScriptPath'] = $wgPageFormsScriptPath; |
| 175 | $vars['edgValues'] = $edgValues; |
| 176 | $vars['wgPageFormsEDSettings'] = $wgPageFormsEDSettings; |
| 177 | $vars['wgAmericanDates'] = $wgAmericanDates; |
| 178 | } |
| 179 | |
| 180 | /** |
| 181 | * Called by the PageSchemasRegisterHandlers hook. |
| 182 | */ |
| 183 | public static function registerPageSchemasClass() { |
| 184 | global $wgPageSchemasHandlerClasses; |
| 185 | $wgPageSchemasHandlerClasses[] = 'PFPageSchemas'; |
| 186 | } |
| 187 | |
| 188 | /** |
| 189 | * Called by the AdminLinks hook. |
| 190 | * |
| 191 | * @param ALTree &$admin_links_tree |
| 192 | */ |
| 193 | public static function addToAdminLinks( &$admin_links_tree ) { |
| 194 | $data_structure_label = wfMessage( 'pf-adminlinks-datastructure' )->escaped(); |
| 195 | $data_structure_section = $admin_links_tree->getSection( $data_structure_label ); |
| 196 | if ( $data_structure_section === null ) { |
| 197 | $data_structure_section = new ALSection( wfMessage( 'pf-adminlinks-datastructure' )->escaped() ); |
| 198 | } |
| 199 | |
| 200 | $pf_row = new ALRow( 'pageforms' ); |
| 201 | $pf_row->addItem( ALItem::newFromSpecialPage( 'Categories' ) ); |
| 202 | $data_structure_section->addRow( $pf_row ); |
| 203 | $pf_admin_row = new ALRow( 'pageforms_admin' ); |
| 204 | $data_structure_section->addRow( $pf_admin_row ); |
| 205 | |
| 206 | $admin_links_tree->addSection( $data_structure_section, wfMessage( 'adminlinks_browsesearch' )->escaped() ); |
| 207 | |
| 208 | $pf_row->addItem( ALItem::newFromSpecialPage( 'Templates' ), 'Properties' ); |
| 209 | $pf_row->addItem( ALItem::newFromSpecialPage( 'Forms' ), 'SemanticStatistics' ); |
| 210 | $pf_row->addItem( ALItem::newFromSpecialPage( 'MultiPageEdit' ) ); |
| 211 | $pf_admin_row->addItem( ALItem::newFromSpecialPage( 'CreateClass' ), 'SMWAdmin' ); |
| 212 | if ( class_exists( 'PFCreateProperty' ) ) { |
| 213 | $pf_admin_row->addItem( ALItem::newFromSpecialPage( 'CreateProperty' ), 'SMWAdmin' ); |
| 214 | } |
| 215 | $pf_admin_row->addItem( ALItem::newFromSpecialPage( 'CreateTemplate' ), 'SMWAdmin' ); |
| 216 | $pf_admin_row->addItem( ALItem::newFromSpecialPage( 'CreateForm' ), 'SMWAdmin' ); |
| 217 | $pf_admin_row->addItem( ALItem::newFromSpecialPage( 'CreateCategory' ), 'SMWAdmin' ); |
| 218 | } |
| 219 | |
| 220 | /** |
| 221 | * Called by the CargoTablesSetAllowedActions hook. |
| 222 | * |
| 223 | * @param SpecialPage $cargoTablesPage |
| 224 | * @param array &$allowedActions |
| 225 | */ |
| 226 | public static function addToCargoTablesColumns( $cargoTablesPage, &$allowedActions ) { |
| 227 | if ( !$cargoTablesPage->getUser()->isAllowed( 'multipageedit' ) ) { |
| 228 | return; |
| 229 | } |
| 230 | |
| 231 | $cargoTablesPage->getOutput()->addModuleStyles( [ 'oojs-ui.styles.icons-editing-core' ] ); |
| 232 | |
| 233 | $editColumn = [ 'edit' => [ 'ooui-icon' => 'edit', 'ooui-title' => 'edit' ] ]; |
| 234 | $indexOfDrilldown = array_search( 'drilldown', array_keys( $allowedActions ) ); |
| 235 | $pos = $indexOfDrilldown === false ? count( $allowedActions ) : $indexOfDrilldown + 1; |
| 236 | $allowedActions = array_merge( array_slice( $allowedActions, 0, $pos ), $editColumn, array_slice( $allowedActions, $pos ) ); |
| 237 | } |
| 238 | |
| 239 | /** |
| 240 | * Called by the CargoTablesActionLinks hook. |
| 241 | * |
| 242 | * Adds an "Edit" link to Special:CargoTables, pointing to Special:MultiPageEdit. |
| 243 | * |
| 244 | * @param array &$actionLinks Action links |
| 245 | * @param string $tableName Cargo table name |
| 246 | * @param bool $isReplacementTable Whether this table is a replacement table |
| 247 | * @param bool $hasReplacementTable Whether this table has a replacement table |
| 248 | * @param int[][] $templatesThatDeclareTables |
| 249 | * @param string[] $templatesThatAttachToTables |
| 250 | * @param User|null $user The current user |
| 251 | * |
| 252 | * @since 4.4 |
| 253 | */ |
| 254 | public static function addToCargoTablesLinks( &$actionLinks, $tableName, $isReplacementTable, $hasReplacementTable, $templatesThatDeclareTables, $templatesThatAttachToTables, $user = null ) { |
| 255 | // If it has a "replacement table", it's read-only and can't |
| 256 | // be edited (though the replacement table can). |
| 257 | if ( $hasReplacementTable ) { |
| 258 | return; |
| 259 | } |
| 260 | |
| 261 | // Check permissions. |
| 262 | if ( $user == null ) { |
| 263 | // For Cargo versions < 3.1. |
| 264 | $user = RequestContext::getMain()->getUser(); |
| 265 | } |
| 266 | |
| 267 | if ( !$user->isAllowed( 'multipageedit' ) ) { |
| 268 | return; |
| 269 | } |
| 270 | // Only put in an "Edit" link if there's exactly one template |
| 271 | // for this Cargo table, and one form for that template. |
| 272 | if ( !array_key_exists( $tableName, $templatesThatDeclareTables ) ) { |
| 273 | return; |
| 274 | } |
| 275 | if ( array_key_exists( $tableName, $templatesThatAttachToTables ) ) { |
| 276 | return; |
| 277 | } |
| 278 | $templateIDs = $templatesThatDeclareTables[$tableName]; |
| 279 | if ( count( $templateIDs ) > 1 ) { |
| 280 | return; |
| 281 | } |
| 282 | |
| 283 | $templateTitle = Title::newFromID( $templateIDs[0] ); |
| 284 | $templateName = $templateTitle->getText(); |
| 285 | if ( self::$mMultiPageEditPage == null ) { |
| 286 | self::$mMultiPageEditPage = new PFMultiPageEdit(); |
| 287 | self::$mMultiPageEditPage->setTemplateList(); |
| 288 | } |
| 289 | $formName = self::$mMultiPageEditPage->getFormForTemplate( $templateName ); |
| 290 | if ( $formName == null ) { |
| 291 | return; |
| 292 | } |
| 293 | |
| 294 | $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer(); |
| 295 | $sp = PFUtils::getSpecialPage( 'MultiPageEdit' ); |
| 296 | $editMsg = wfMessage( 'edit' )->text(); |
| 297 | $linkParams = [ 'template' => $templateName, 'form' => $formName ]; |
| 298 | $text = $linkRenderer->makeKnownLink( $sp->getPageTitle(), $editMsg, [], $linkParams ); |
| 299 | |
| 300 | $indexOfDrilldown = array_search( 'drilldown', array_keys( $actionLinks ) ); |
| 301 | $pos = $indexOfDrilldown === false ? count( $actionLinks ) : $indexOfDrilldown + 1; |
| 302 | $actionLinks = array_merge( array_slice( $actionLinks, 0, $pos ), [ 'edit' => $text ], array_slice( $actionLinks, $pos ) ); |
| 303 | } |
| 304 | |
| 305 | /** |
| 306 | * Called by the CargoTablesSetActionLinks hook. |
| 307 | * |
| 308 | * Adds an "Edit" link to Special:CargoTables, pointing to Special:MultiPageEdit. |
| 309 | * |
| 310 | * @param SpecialPage $cargoTablesPage |
| 311 | * @param array &$actionLinks Action links |
| 312 | * @param string $tableName Cargo table name |
| 313 | * @param bool $isReplacementTable Whether this table iss a replacement table |
| 314 | * @param bool $hasReplacementTable Whether this table has a replacement table |
| 315 | * @param int[][] $templatesThatDeclareTables |
| 316 | * @param string[] $templatesThatAttachToTables |
| 317 | * @param string[] $actionList |
| 318 | * @param User|null $user The current user |
| 319 | * |
| 320 | * @since 4.8.1 |
| 321 | */ |
| 322 | public static function addToCargoTablesRow( $cargoTablesPage, &$actionLinks, $tableName, $isReplacementTable, $hasReplacementTable, $templatesThatDeclareTables, $templatesThatAttachToTables, $actionList, $user = null ) { |
| 323 | $cargoTablesPage->getOutput()->addModuleStyles( [ 'oojs-ui.styles.icons-editing-core' ] ); |
| 324 | |
| 325 | // For the sake of simplicity, this function basically just |
| 326 | // wraps around the previous hook function, for Cargo <= 2.4. |
| 327 | // That's why there's this awkward behavior of parsing links |
| 328 | // to get their URL. Hopefully this won't cause problems. |
| 329 | self::addToCargoTablesLinks( $actionLinks, $tableName, $isReplacementTable, $hasReplacementTable, $templatesThatDeclareTables, $templatesThatAttachToTables, $user ); |
| 330 | |
| 331 | if ( array_key_exists( 'edit', $actionLinks ) ) { |
| 332 | preg_match( '/href="(.*?)"/', $actionLinks['edit'], $matches ); |
| 333 | $mpeURL = html_entity_decode( $matches[1] ); |
| 334 | $actionLinks['edit'] = $cargoTablesPage->getActionButton( 'edit', $mpeURL ); |
| 335 | } |
| 336 | } |
| 337 | |
| 338 | /** |
| 339 | * Called by the EditPage::importFormData hook. |
| 340 | * |
| 341 | * @param EditPage $editpage |
| 342 | * @param WebRequest $request |
| 343 | */ |
| 344 | public static function showFormPreview( EditPage $editpage, WebRequest $request ) { |
| 345 | global $wgOut, $wgPageFormsFormPrinter; |
| 346 | |
| 347 | wfDebug( __METHOD__ . ": enter.\n" ); |
| 348 | |
| 349 | // Exit if we're not in preview mode. |
| 350 | if ( !$editpage->preview ) { |
| 351 | return; |
| 352 | } |
| 353 | // Exit if we aren't in the "Form" namespace. |
| 354 | if ( $editpage->getArticle()->getTitle()->getNamespace() != PF_NS_FORM ) { |
| 355 | return; |
| 356 | } |
| 357 | |
| 358 | // Needed in case there are any OOUI-based input types in the form. |
| 359 | $wgOut->enableOOUI(); |
| 360 | |
| 361 | $previewNote = $wgOut->parseAsInterface( wfMessage( 'pf-preview-note' )->text() ); |
| 362 | // The "pfForm" ID is there so the form JS will be activated. |
| 363 | $editpage->previewTextAfterContent .= Html::element( 'h2', null, wfMessage( 'pf-preview-header' )->text() ) . "\n" . |
| 364 | '<div id="pfForm" class="previewnote" style="font-weight: bold">' . $previewNote . "</div>\n<hr />\n"; |
| 365 | |
| 366 | $form_definition = StringUtils::delimiterReplace( '<noinclude>', '</noinclude>', '', $editpage->textbox1 ); |
| 367 | [ $form_text, $data_text, $form_page_title, $generated_page_name ] = |
| 368 | $wgPageFormsFormPrinter->formHTML( $form_definition, null, false, null, null, "Page Forms form preview dummy title", null ); |
| 369 | |
| 370 | $parserOutput = PFUtils::getParser()->getOutput(); |
| 371 | $wgOut->addParserOutputMetadata( $parserOutput ); |
| 372 | |
| 373 | PFUtils::addFormRLModules(); |
| 374 | $editpage->previewTextAfterContent .= |
| 375 | '<div style="margin-top: 15px">' . $form_text . "</div>"; |
| 376 | } |
| 377 | |
| 378 | /** |
| 379 | * Called by the PageSaveComplete hook. |
| 380 | * |
| 381 | * Set a cookie after the page save so that a "Your edit was saved" |
| 382 | * popup will appear after form-based saves, just as it does after |
| 383 | * standard saves. This code will be called after all saves, which |
| 384 | * means that it will lead to redundant cookie-setting after normal |
| 385 | * saves. However, there doesn't appear to be a way to to set the |
| 386 | * cookie correctly only after form-based saves, unfortunately. |
| 387 | * |
| 388 | * @param WikiPage $wikiPage |
| 389 | * @param MediaWiki\User\UserIdentity $user |
| 390 | * @param string $summary |
| 391 | * @param int $flags |
| 392 | * @param MediaWiki\Revision\RevisionRecord $revisionRecord |
| 393 | * @param MediaWiki\Storage\EditResult $editResult |
| 394 | */ |
| 395 | public static function setPostEditCookie( WikiPage $wikiPage, MediaWiki\User\UserIdentity $user, string $summary, int $flags, |
| 396 | MediaWiki\Revision\RevisionRecord $revisionRecord, MediaWiki\Storage\EditResult $editResult |
| 397 | ) { |
| 398 | // Have this take effect only if the save came from a form - |
| 399 | // we need to use a global variable to determine that. |
| 400 | global $wgPageFormsFormPrinter; |
| 401 | if ( !property_exists( $wgPageFormsFormPrinter, 'mInputTypeHooks' ) ) { |
| 402 | return; |
| 403 | } |
| 404 | |
| 405 | // Code based loosely on EditPage::setPostEditCookie(). |
| 406 | $postEditKey = EditPage::POST_EDIT_COOKIE_KEY_PREFIX . $revisionRecord->getID(); |
| 407 | $response = RequestContext::getMain()->getRequest()->response(); |
| 408 | $response->setCookie( $postEditKey, 'saved', time() + EditPage::POST_EDIT_COOKIE_DURATION ); |
| 409 | } |
| 410 | |
| 411 | /** |
| 412 | * Called by the BeforePageDisplay hook. |
| 413 | * |
| 414 | * Reload the page if "forceReload=true" exists in the URL query string. |
| 415 | * This is a @hack done so that the $wgPageFormsDelayReload setting |
| 416 | * (itself a hack) can take effect - in some cases, having a #formlink |
| 417 | * call with "returnto=" and "reload" both set does not actually |
| 418 | * refresh the queries on the original page in time, so we use this to |
| 419 | * then reload the original page, which does seem to work. There may |
| 420 | * well be a better solution for this, though. |
| 421 | * |
| 422 | * @param MediaWiki\Output\OutputPage $out |
| 423 | * @param Skin $skin |
| 424 | */ |
| 425 | public static function handleForceReload( $out, Skin $skin ) { |
| 426 | global $wgRequest, $wgPageFormsScriptPath; |
| 427 | |
| 428 | if ( $wgRequest->getVal( 'forceReload' ) !== 'true' ) { |
| 429 | return; |
| 430 | } |
| 431 | |
| 432 | $out->clearHTML(); |
| 433 | $loadingImage = Html::element( 'img', [ 'src' => "$wgPageFormsScriptPath/skins/loading.gif" ] ); |
| 434 | $text = "\t" . Html::rawElement( 'p', [ 'style' => "position: absolute; left: 45%; top: 45%;" ], $loadingImage ); |
| 435 | $reloadURL = $out->getTitle()->getFullURL(); |
| 436 | $text .= Html::element( 'meta', [ 'http-equiv' => 'refresh', 'content' => "0; url=$reloadURL" ] ); |
| 437 | |
| 438 | $out->addHTML( $text ); |
| 439 | } |
| 440 | |
| 441 | } |