Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/instructions/php.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,16 @@ See Manual:Coding conventions#Indenting and alignment.

For anonymous functions, prefer arrow functions when the anonymous function consists only of one line. Arrow functions are more concise and readable than regular anonymous functions and neatly side-steps formatting issues that arise with single-line anonymous functions.

### Type declarations for variables
Avoid using PHPDoc comments to declare types for local variables. Instead, use native type declarations for function parameters and return types, and use static analysis tools (like PHPStan or Psalm) to infer types of local variables.

Example:

```php
private static string $nameOfVariable = '';
```


### Type declarations in function parameters

Use native type declarations and return type declarations when applicable. (But see #Don't add type declarations for "big" legacy classes below.)
Expand Down
152 changes: 152 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
*.manifest
*.spec

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/

# Virtual environments
venv/
ENV/
env/
.venv/
.env

# IDE specific files
.idea/
.vscode/
*.swp
*.swo
*~
.project
.pydevproject
.settings/
*.sublime-project
*.sublime-workspace

# OS specific files
.DS_Store
Thumbs.db
*.bak

# Logs
*.log
logs/
*.log.*

# Database files
*.db
*.sqlite
*.sqlite3

# Environment variables
.env
.env.local
.env.*.local

# Temporary files
*.tmp
*.temp
tmp/
temp/

# Jupyter Notebook
.ipynb_checkpoints

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# Project specific
data/
output/
*.pkl
*.pickle
*.model
*.h5
*.weights

# PHP
*.php~
*.php.swp
*.php.swo

# Composer
vendor/
composer.phar
composer.lock

# PHP error logs
php_errors.log
php_error.log
error_log
access_log

# PHP sessions
sess_*

# PHP uploads
uploads/
upload/

# PHPUnit
.phpunit.result.cache
phpunit.xml
.phpunit.cache/

# PHP CS Fixer
.php_cs
.php_cs.cache
.php-cs-fixer.cache

# PHP CodeSniffer
phpcs.xml
.phpcs-cache

# PHPStan
phpstan.neon
phpstan-baseline.neon
19 changes: 19 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"require-dev": {
"phpunit/phpunit": "^9.0"
},
"autoload": {
"psr-4": {
"MediaWiki\\Extension\\CrawlerProtection\\": "includes/"
}
},
"autoload-dev": {
"psr-4": {
"MediaWiki\\Extension\\CrawlerProtection\\Tests\\": "tests/phpunit/unit/"
},
"files": [
"tests/phpunit/stubs.php",
"tests/phpunit/namespaced-stubs.php"
]
}
}
10 changes: 5 additions & 5 deletions includes/Hooks.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ public function onMediaWikiPerformAction(
$request,
$mediaWiki
) {
$type = $request->getVal( 'type' );
$type = $request->getVal( 'type' );
$action = $request->getVal( 'action' );
$diffId = (int)$request->getVal( 'diff' );
$oldId = (int)$request->getVal( 'oldid' );
$oldId = (int)$request->getVal( 'oldid' );

if (
!$user->isRegistered()
Expand All @@ -83,7 +83,7 @@ public function onMediaWikiPerformAction(
}

/**
* Block Special:RecentChangesLinked and Special:WhatLinksHere for anonymous users.
* Block Special:RecentChangesLinked, Special:WhatLinksHere, and Special:MobileDiff for anonymous users.
*
* @param SpecialPage $special
* @param string|null $subPage
Expand All @@ -97,7 +97,7 @@ public function onSpecialPageBeforeExecute( $special, $subPage ) {
}

$name = strtolower( $special->getName() );
if ( in_array( $name, [ 'recentchangeslinked', 'whatlinkshere' ], true ) ) {
if ( in_array( $name, [ 'recentchangeslinked', 'whatlinkshere', 'mobilediff' ], true ) ) {
$out = $special->getContext()->getOutput();
$this->denyAccess( $out );
return false;
Expand All @@ -112,7 +112,7 @@ public function onSpecialPageBeforeExecute( $special, $subPage ) {
* @param OutputPage $output
* @return void
*/
protected function denyAccess( OutputPage $output ): void {
protected function denyAccess( $output ): void {
$output->setStatusCode( 403 );
$output->addWikiTextAsInterface( wfMessage( 'crawlerprotection-accessdenied-text' )->plain() );

Expand Down
70 changes: 70 additions & 0 deletions tests/phpunit/namespaced-stubs.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

// Hook interfaces
namespace MediaWiki\Hook {
interface MediaWikiPerformActionHook {
public function onMediaWikiPerformAction( $output, $article, $title, $user, $request, $mediaWiki );
}
}

namespace MediaWiki\SpecialPage\Hook {
interface SpecialPageBeforeExecuteHook {
public function onSpecialPageBeforeExecute( $special, $subPage );
}
}

// Core classes in their proper namespaces
namespace MediaWiki\Output {
class OutputPage {
public function setStatusCode( $code ) {
}
public function addWikiTextAsInterface( $text ) {
}
public function setPageTitle( $title ) {
}
public function setPageTitleMsg( $msg ) {
}
}
}

namespace MediaWiki\SpecialPage {
class SpecialPage {
public function getName() {
return '';
}
public function getContext() {
return null;
}
}
}

namespace MediaWiki\User {
class User {
public function isRegistered() {
return false;
}
}
}

namespace MediaWiki\Request {
class WebRequest {
public function getVal( $name, $default = null ) {
return $default;
}
}
}

namespace MediaWiki\Title {
class Title {
}
}

namespace MediaWiki\Page {
class Article {
}
}

namespace MediaWiki\Actions {
class ActionEntryPoint {
}
}
19 changes: 19 additions & 0 deletions tests/phpunit/stubs.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

// Basic stubs for MediaWiki testing

// Stub constant - set to newer version to avoid class_alias issues
if ( !defined( 'MW_VERSION' ) ) {
define( 'MW_VERSION', '1.45.0' );
}

// Stub function for wfMessage - only define if not already defined
if ( !function_exists( 'wfMessage' ) ) {
function wfMessage( $key ) {
return new class() {
public function plain() {
return 'Mock message';
}
};
}
}
Loading
Loading