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 .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Normalize line endings to LF in the repository
* text=auto eol=lf

# Never convert line endings in binary files
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.webp binary
*.ico binary
38 changes: 38 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Lint

# PHP syntax check on the lowest PHP version this extension supports and the
# newest one phpBB 3.3 supports. tests.yml covers PHP 8.2 with phpBB's own
# checks (code sniffer, EPV).
on:
push:
branches:
- master
pull_request:
branches:
- master

permissions:
contents: read

jobs:
lint:
name: PHP ${{ matrix.php }} lint
runs-on: ubuntu-latest
strategy:
matrix:
php: ['7.4', '8.4']
steps:
- uses: actions/checkout@v4

- name: Set up PHP ${{ matrix.php }}
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
coverage: none
tools: composer:v2

- name: PHP syntax check
run: find . -name '*.php' -not -path './.git/*' -not -path './vendor/*' -print0 | xargs -0 -n1 php -l

- name: Validate composer.json
run: composer validate --no-check-all --no-check-publish
6 changes: 4 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,15 @@ jobs:
RUN_PGSQL_JOBS: 0

# Run MSSQL and SQLite3 tests? 1 (yes) or 0 (no)
RUN_MSSQL_JOBS: 0
# Needed to actually run the PHPUnit suite under tests/ (SQLite3 is
# bundled into this job group); MySQL/PostgreSQL stay off for now.
RUN_MSSQL_JOBS: 1

# Run Windows IIS & PostgreSQL tests? 1 (yes) or 0 (no)
RUN_WINDOWS_JOBS: 0

# Run functional tests if you have them? 1 (yes) or 0 (no)
RUN_FUNCTIONAL_TESTS: 0
RUN_FUNCTIONAL_TESTS: 1

# Install npm dependencies (if your extension relies on them)? 1 (yes) or 0 (no)
RUN_NPM_INSTALL: 0
Expand Down
45 changes: 35 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,48 @@
# ban-hammer
Ban Hammer for phpBB 3.3.x line (was One Click Ban)
# Ban Hammer

Gives moderators a one-click way to ban a user directly from their profile or from the MCP post-approval queue: ban the username, email, and/or IP, delete their posts, private messages, avatar, signature, and profile fields, optionally move them into a group, and optionally report them to Stop Forum Spam. As an alternative to banning outright, a moderator can instead restrict a user into a heavily-limited group for a set time (or permanently), with their original group automatically restored once the restriction expires. A "Ban email domain" action is also available from the MCP approve-details page.
[![Tests](https://github.com/phpbbmodders/ban-hammer/actions/workflows/tests.yml/badge.svg)](https://github.com/phpbbmodders/ban-hammer/actions/workflows/tests.yml) [![Lint](https://github.com/phpbbmodders/ban-hammer/actions/workflows/lint.yml/badge.svg)](https://github.com/phpbbmodders/ban-hammer/actions/workflows/lint.yml)

Requires PHP 7.4+ and phpBB 3.3.17+.
Ban a user straight from their profile, with options to clean up their content and report them to Stop Forum Spam.

## Features

- **Ban Hammer** form on member profiles, and on the MCP post-approval queue, for moderators with the right permissions.
- Ban by username, and optionally by email and IP.
- Optionally delete the user's avatar, posts and topics, private messages, signature and profile fields.
- Optionally move banned users into a chosen group.
- Instead of banning, restrict a user to a limited group for a set time (or permanently); their original group comes back automatically when it ends.
- A **Ban email domain** action on the MCP approve-details page.
- Optionally report the user to Stop Forum Spam (API key set in the ACP).

## Requirements

- phpBB 3.3.17 or later
- PHP 7.4 or later

## Installation

1. Copy (or clone) this extension to `phpBB/ext/phpbbmodders/banhammer`.
2. In the ACP, go to Customise → Manage Extensions and enable Ban Hammer.
3. Configure it under ACP → Ban Hammer: what a ban deletes, an optional group to move banned users into, an optional group to restrict users into instead of banning, ban length options, and (optionally) a Stop Forum Spam API key.
1. Copy the extension to `/ext/phpbbmodders/banhammer`
2. In the Administration Control Panel, go to **Customise → Manage extensions**
3. Enable the **Ban Hammer** extension
4. Choose the defaults under **ACP → Extensions → Ban Hammer**

## Automated testing
## Contributing

We use automated unit tests to prevent regressions. Check out our build below:
Contributions are welcome!

[![Tests](https://github.com/phpbbmodders/ban-hammer/actions/workflows/tests.yml/badge.svg)](https://github.com/phpbbmodders/ban-hammer/actions/workflows/tests.yml)
- **Bug reports**: [Open an issue](https://github.com/phpbbmodders/ban-hammer/issues).
- **Everything else** (questions, feature requests, ideas, general discussion): [Use Discussions](https://github.com/orgs/phpbbmodders/discussions), or the [community forum](https://www.phpbbmodders.com/community/).
- Pull requests are welcome for bug fixes or discussed features.

## Acknowledgments

- Based on the phpBB 3.0 **One Click Ban** MOD by phpbbmodders.net (co-authors Kailey and bonelifer; contributors EXreaction, RMcGirr83, Sniper_E and tumba25).
- Converted to a phpBB extension by Rich McGirr ([RMcGirr83](https://github.com/rmcgirr83)) and Jari Kanerva (tumba25).
- The avatar-deletion modernization ([PR #21](https://github.com/phpbbmodders/ban-hammer/pull/21)) is based on a fix by [Rich McGirr](https://github.com/rmcgirr83) in his fork, routing avatar deletion through phpBB's `avatar.manager` service instead of the legacy `avatar_delete()` function.
- Code review, bug fixes, and documentation assisted by [Claude](https://www.anthropic.com/claude).

## License

This extension is licensed under the **GNU General Public License v2.0**.

See [license.txt](license.txt) for more information.
14 changes: 10 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"name": "phpbbmodders/banhammer",
"type": "phpbb-extension",
"description": "Allows banning directly from a users profile. Option to ban email and/or IP, and delete avatar, posts, topics, private messages, signature, profile fields. Also option to add banned users to a selected user group and/or report them to Stop Forum Spam. Previously known as One Click Ban.",
"homepage": "https://phpbbmodders.net",
"description": "Ban a user straight from their profile, with options to clean up their content and report them to Stop Forum Spam.",
"homepage": "https://www.phpbbmodders.com/",
"version": "1.0.8",
"time": "2018-07-26",
"keywords": [
Expand All @@ -16,9 +16,15 @@
],
"license": "GPL-2.0-only",
"authors": [
{
"name": "phpBB Modders",
"email": "board@phpbbmodders.com",
"homepage": "https://www.phpbbmodders.com/",
"role": "Extension Developer"
},
{
"name": "Rich McGirr",
"role": "Developer"
"role": "Past Developer"
},
{
"name": "Jari Kanerva",
Expand All @@ -44,4 +50,4 @@
"filename": "version_check"
}
}
}
}
121 changes: 121 additions & 0 deletions docs/ai-validation-review-2026-09-22.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# AI extension validation — 2026-09-22

Read-only validation pass using the standard phpBB extension validator prompt
(`repos/misc/validate.prompt.md`), run against branch `codex-review-round-2`
at commit `3dbc19d` (master `fb99cd8` plus 15 commits) before this branch is
submitted anywhere or merged, as a check of what a junior EPV-style validator
would flag first.

**Scope note:** full mechanical checks (Step 1a) ran against the entire
repository. The manual guideline-conformance review (Steps 2-4) focused on
the 15 commits new in this branch, not a from-scratch re-audit of the whole,
already-published extension (v1.0.8) — the pre-existing code predates this
session and was presumably already through real validation.

## Step 1: Reference documentation

Read in full this session (not from recalled memory): `coding-guidelines-33x.txt`,
`validation-policy.txt`; cross-checked all four `core.*` events this
extension subscribes to (`core.permissions`, `core.memberlist_view_profile`,
`core.session_set_custom_ban`, `core.mcp_queue_approve_details_template`)
against `events_list.rst` — all four exist, are current, and are used with
the correct `$event[...]` argument names documented there. Cache is dated
09/03/2026 (per its own `README.md`); nothing checked here appeared to need
a fresher fetch.

## Step 1a: Mechanical checks

- `composer validate`: **passes** ("valid, but with a few warnings"). The
one warning (presence of the `version` field, which Composer recommends
omitting for Packagist-published packages) does not apply here — phpBB's
own extension skeleton (`composer.json.twig`) requires this field for
Customisation DB submissions, which don't use Packagist versioning. Not a
finding.
- `php -l` on every `.php` file in the repository (not just this branch's
changes): **all pass**, zero syntax errors.
- Trailing whitespace (`grep -nP '[ \t]+$'`) across `.php`/`.html`/`.js`/`.css`/`.yml`:
**none found**.
- Language key cross-reference, both directions, across all 64 keys defined
in `language/en/*.php`:
- Every defined key has at least one usage outside its own definition
file (checked individually, not sampled). No dead keys.
- Every language key *referenced* in PHP code that isn't itself defined
in this extension's language files resolves to a real phpBB core key
(`FORM_INVALID`, `COLON`, `NO_GROUP`, the ban-duration keys like
`1_DAY`/`7_DAYS`/`PERMANENT`, and the dynamically-built `G_<group_name>`
prefix) — none are missing custom-key definitions.

## Step 2-4: Guideline and security review (this branch's 15 commits)

No `[valdeny]` findings. Two `[valinfo]` items:

In `[c]cron/task/restriction_expiry.php[/c]`, `[c]migrations/restrict_dedupe.php[/c]`, `[c]migrations/restrict_membership_column.php[/c]`, `[c]migrations/ban_group.php[/c]`:

[code]
foreach ($expired as $row)
{
...
group_user_del($restrict_group_id, array($user_id));
...
group_user_attributes('default', $original_group_id, array($user_id));
...
$this->db->sql_query('DELETE FROM ' . $this->restrict_table . ' WHERE restrict_id = ' . (int) $row['restrict_id']);
}
[/code]

[valinfo]
Each of these methods calls a phpBB core group-membership function (or a
per-row `DELETE`) once per row inside a loop, rather than batching rows that
share the same target group into a single call — `group_user_del()`,
`group_user_add()`, and `group_user_attributes()` all already accept an
array of user IDs. This is a pre-existing pattern in `restriction_expiry.php`
(unchanged in shape by this branch, only extended consistently into the new
migrations for the same reason: restoring tracked rows one at a time). Given
these only run from a cron task capped at once every five minutes, or a
one-time migration/purge pass, the realistic number of rows processed per
invocation on a real moderation workload is small, so this doesn't rise to
a denial - flagging per the [c]validation-policy.txt[/c] guidance that "SQL
queries within loops should be avoided," for the maintainer's awareness if
a future release needs to handle much larger batches.
[/valinfo]

In `[c]migrations/restrict_group_id_column.php[/c]`:

[code]
public function revert_data()
{
return array(
array('custom', array(array($this, 'restore_active_restrictions_fallback'))),
);
}
[/code]

[valinfo]
This adds a `revert_data()` method (and a new `restore_active_restrictions_fallback()`)
to a migration that was already merged in a prior commit (`fb99cd8`, PR #36).
The validation policy states "Existing migration files from previously
released versions should never be altered or deleted." Two mitigating facts
worth the validator's judgment call rather than an automatic denial: (1)
only the *revert* path is touched, not `update_schema()`/`update_data()` -
the paths that would actually diverge between an already-migrated site and
a fresh install if altered; a revert only runs when a site purges the
extension, which hasn't happened anywhere yet since this functionality is
new. (2) `git tag` on this repository returns no tags at all, and
`composer.json`'s `version` field has read `1.0.8` since 2018, unchanged
by this migration's original addition - there is no evidence this specific
migration has ever shipped in a numbered Customisation DB release. Verified
directly against a real phpBB 3.3.x install: a purge before the newer
`restrict_membership_column` migration is ever installed (simulating an
upgrade-then-immediate-purge sequence) now correctly restores active
restrictions via this fallback, where it previously would have silently
dropped the tracking table with nothing restored.
[/valinfo]

## Recommendation

**Approve.** No `[valdeny]`-level issues found in this branch's changes;
both `[valinfo]` items are judgment calls with reasoning attached, not
guideline deviations requiring denial. Formatting is otherwise clean across
every file touched (tabs, brace placement, quoting, SQL layout, comment
style all consistent with the coding guidelines and the rest of the
existing codebase).
Loading
Loading