Skip to content

Closes #883: Fix .htaccess permission notice shown twice and undefined variable in remove()#1069

Open
Miraeld wants to merge 5 commits into
enhancement/ai-workflow-improvementsfrom
fix/883-htaccess-not-writable-displayed
Open

Closes #883: Fix .htaccess permission notice shown twice and undefined variable in remove()#1069
Miraeld wants to merge 5 commits into
enhancement/ai-workflow-improvementsfrom
fix/883-htaccess-not-writable-displayed

Conversation

@Miraeld
Copy link
Copy Markdown
Contributor

@Miraeld Miraeld commented May 26, 2026

Description

Fixes #883

When .htaccess is not writable and the user enables the "Display next-gen" option, two bugs occur: the permission notice is shown twice in the settings UI, and disabling the option triggers a PHP Warning for an undefined variable.

This PR fixes both issues:

  1. The AbstractWriteDirConfFile::remove() method used $file_path without ever assigning it, causing PHP Warning: Undefined variable $file_path. A single line is added to call $this->get_file_path() before the variable is used — mirroring the pattern already present in add().
  2. Both Webp\RewriteRules\Display::maybe_add_webp_info() and Avif\RewriteRules\Display::maybe_add_avif_info() subscribe independently to the same imagify_settings_webp_info action and each printed the "file not writable" notice on their own. A shared static flag AbstractWriteDirConfFile::$writable_notice_printed is introduced so that whichever subscriber prints first will prevent the second from printing during the same request.

Type of change

  • New feature (non-breaking change which adds functionality).
  • Bug fix (non-breaking change which fixes an issue).
  • Enhancement (non-breaking change which improves an existing functionality).
  • Breaking change (fix or feature that would cause existing functionality to not work as before).
  • Sub-task of htaccess file is not writable is displayed twice since avif  #883
  • Chore
  • Release

Detailed scenario

What was tested

To be filled by QA.

How to test

Acceptance criterion 1 — Permission notice appears only once:

  1. Install Imagify 2.2.1+ on an Apache server.
  2. Change .htaccess permissions to 444 (read-only).
  3. Open Imagify settings and enable the "Display next-gen" option.
  4. Verify the notice ("If you choose to use rewrite rules, you will have to add the following lines manually...") appears exactly once on the page.

Acceptance criterion 2 — No PHP Warning when disabling:

  1. With .htaccess set to 444, enable Display next-gen (rewrite method).
  2. Disable Display next-gen and save.
  3. Verify no PHP Warning for Undefined variable $file_path appears in the PHP error log.

Affected Features & Quality Assurance Scope

  • Settings page — "Display next-gen images" option (WebP + AVIF rewrite rules section).
  • .htaccess / web.config / imagify.conf write operations when the display next-gen option is toggled.
  • Apache, IIS, and Nginx server configurations (the shared static flag applies to all).

Technical description

Documentation

Bug 1 fix (AbstractWriteDirConfFile::remove(), line ~101):
The remove() method built an error message using $file_path but the variable was never assigned in that method (unlike add() which correctly assigned it on the previous line). Fix: add $file_path = $this->get_file_path(); before the make_path_relative() call.

Bug 2 fix (shared static flag):
AbstractWriteDirConfFile gains a new public static bool $writable_notice_printed = false property. Both maybe_add_webp_info() and maybe_add_avif_info() check this flag on entry to the is_wp_error branch and return early if it is already true. The first subscriber to print sets it to true. Because the flag is on the shared abstract base class, it is truly shared across all concrete subclasses in the same request.

New dependencies

None.

Risks

  • The shared static flag is request-scoped (PHP's static property lifetime). It resets between requests.
  • If a third nextgen format is added in the future and its Display class hooks imagify_settings_webp_info, it will automatically benefit from the shared gate.
  • The Nginx "include file" info message in maybe_add_webp_info() lives in a separate elseif branch and is not affected by the flag.

Mandatory Checklist

Code validation

  • I validated all the Acceptance Criteria. If possible, provide screenshots or videos.
  • I triggered all changed lines of code at least once without new errors/warnings/notices.
  • I implemented built-in tests to cover the new/changed code.

Code style

  • I wrote a self-explanatory code about what it does.
  • I protected entry points against unexpected inputs.
  • I did not introduce unnecessary complexity.
  • Output messages (errors, notices, logs) are explicit enough for users to understand the issue and are actionnable.

Unticked items justification

N/A — all items checked.

Additional Checks

  • In the case of complex code, I wrote comments to explain it.
  • When possible, I prepared ways to observe the implemented system (logs, data, etc.)
  • I added error handling logic when using functions that could throw errors (HTTP/API request, filesystem, etc.)

Miraeld and others added 2 commits May 26, 2026 01:47
… .htaccess permission notice

Bug #883 introduced two issues when .htaccess is not writable:
1. AbstractWriteDirConfFile::remove() used \$file_path without assigning it first,
   triggering a PHP Warning: "Undefined variable \$file_path" on line 101.
2. Both Webp\RewriteRules\Display and Avif\RewriteRules\Display subscribe to the
   same imagify_settings_webp_info action and each printed the "file not writable"
   notice independently, causing it to appear twice. A static request-scoped flag
   now prevents the second subscriber from printing when the first already has.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The per-method static $notice_printed variables in each Display class were
independent — each class's static was reset independently, so the second
subscriber would still print. Move the flag to a public static property on
AbstractWriteDirConfFile so both Webp\RewriteRules\Display and
Avif\RewriteRules\Display share a single request-scoped gate.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Miraeld Miraeld self-assigned this May 26, 2026
@codacy-production
Copy link
Copy Markdown

codacy-production Bot commented May 26, 2026

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 0 duplication

Metric Results
Duplication 0

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

Miraeld and others added 3 commits May 26, 2026 12:14
- PR title: add hard negative in release-agent to prevent conventional commit format
- CRITICAL routing: give orchestrator discretion to attempt fix before escalating
- E2E suite: decouple from frontend agent, always run as regression check
- tools: add WebFetch + WebSearch to grooming, challenger, lead-reviewer, backend, frontend
- Collapsible step detail panels in HTML log format
- Step detail panel content documented per-step in orchestrator

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ent timeline

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Miraeld Miraeld marked this pull request as ready for review May 26, 2026 12:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant