Skip to content

FieldtypeComments: UNIX timestamp used in SQL comparison against TIMESTAMP column in vote cleanup routine #2202

@teppokoivula

Description

@teppokoivula

Short description of the issue

Ryan — this report was authored by Claude for me, but it seems to be just about correct. Also noticed that https://github.com/processwire/processwire-issues/blob/master/.github/ISSUE_TEMPLATE.md is not working, I don't get the issue template to new issues; something about old version?

Anyway, to the actual issue report:

The commentMaintenance() method in FieldtypeComments.module passes a raw UNIX timestamp integer to a SQL query that compares against a TIMESTAMP-typed column (created) in the _votes table. This causes a type mismatch that fails under MySQL strict mode.

Expected behavior

Old vote records should be silently deleted during comment maintenance, with no database errors.

Actual behavior

Every time a comment is added, the vote cleanup query fails because MySQL cannot compare a raw integer (e.g. 1775576425) against a TIMESTAMP column that expects datetime format (e.g. 2026-04-08 12:00:00). The error is caught by the try/catch block on line 386, so comment saving still succeeds, but:

  1. An error is logged on every comment insertion
  2. Expired vote records are never cleaned up

Optional: Screenshots/Links that demonstrate the issue

Relevant code in FieldtypeComments.module:

The votes table is created with a TIMESTAMP column (line 485):

`created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,

But the cleanup routine passes a UNIX timestamp integer (lines 382–385):

$expiredTime = time() - self::votesMaxAge;
$query = $database->prepare("DELETE FROM `{$table}_votes` WHERE created < :expiredTime");
$query->bindValue(":expiredTime", $expiredTime);

Optional: Suggestion for a possible fix

Line 383 in FieldtypeComments.module:

// Current (broken):
$expiredTime = time() - self::votesMaxAge;

// Fixed:
$expiredTime = date('Y-m-d H:i:s', time() - self::votesMaxAge);

The root cause is an inconsistency between the two tables: the main comments table defines created as int unsigned (line 565), while the votes table defines it as TIMESTAMP (line 485). The cleanup routine treats both the same way, but only the votes query breaks.

Steps to reproduce the issue

  1. Enable MySQL strict mode (default in MySQL 5.7+)
  2. Enable comment voting on a Comments field
  3. Add a comment to any page
  4. Check the error log — a database error from the vote cleanup query will be present

Setup/Environment

  • ProcessWire version: dev (current as of 2026-04-08)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions