# WYSIWYG Image Synchronization for CMS Content in OpenMage Image Cleaner

> Learn how OpenMage Image Cleaner syncs WYSIWYG images across CMS content by scanning media assets and cross-referencing them with pages blocks and templates to identify unused images for safe removal.

- Repository: [Fabrizio Balliano/openmage-image-cleaner](https://github.com/fballiano/openmage-image-cleaner)
- Tags: how-to-guide
- Published: 2026-03-01

---

**OpenMage Image Cleaner identifies orphaned WYSIWYG assets by scanning the `media/wysiwyg` directory and cross-referencing every file against HTML content from CMS pages, static blocks, and email templates, plus all frontend CSS files, then persists unused images to a module-specific database table for safe removal.**

The OpenMage Image Cleaner extension provides a robust mechanism to prevent media bloat by detecting unused assets across the platform. Its WYSIWYG image synchronization feature specifically targets images uploaded through the WYSIWYG editor, ensuring that only truly orphaned files—those no longer referenced by any CMS content, email template, or stylesheet—are flagged for deletion.

## Entry Point and Controller Architecture

The synchronization process initiates via the admin UI route that resolves to `FbimagecleanerController::syncwysiwygAction()` in [`app/code/community/Fballiano/ImageCleaner/controllers/Adminhtml/FbimagecleanerController.php`](https://github.com/fballiano/openmage-image-cleaner/blob/main/app/code/community/Fballiano/ImageCleaner/controllers/Adminhtml/FbimagecleanerController.php) (starting at line 163).

The controller prepares the execution environment by setting `entity_type_id = -98`, a hardcoded internal identifier that categorizes WYSIWYG assets distinctly from product or category images. It then resolves the physical directory path to `media/wysiwyg` and loads the module helper and Magento core resources.

## Aggregating Content References

### Database HTML Content

At line 177, the controller executes a single SQL query that unions content columns from three core Magento tables to capture all potential image references:

- `cms_page.content` – HTML bodies of CMS pages
- `cms_block.content` – HTML content of static blocks  
- `core_email_template.template_text` and `core_email_template.template_styles` – Email template bodies and inline styles

The result set (`$db_images`) contains every HTML fragment stored in the CMS and email system that may contain WYSIWYG image URLs.

### CSS Stylesheet Content

Beyond database content, the synchronization captures image references embedded in stylesheets. The controller calls `$helper->getAllCSSFilesContents()`, implemented in [`app/code/community/Fballiano/ImageCleaner/Helper/Data.php`](https://github.com/fballiano/openmage-image-cleaner/blob/main/app/code/community/Fballiano/ImageCleaner/Helper/Data.php) at lines 46-55.

This helper method recursively traverses the `skin/frontend` directory structure, identifies all `*.css` files, reads their contents into memory, and returns them as an array of strings. This ensures that background images and other CSS-referenced assets are accounted for in the usage analysis.

## Filesystem Enumeration and Usage Detection

### Scanning Physical Assets

Using the helper’s `scandirRecursive()` method, the controller performs a recursive directory scan of `media/wysiwyg`. It strips the base media path so every entry is relative to the `wysiwyg/` directory, producing the complete inventory of physical assets (`$fs_images`).

### Determining Used Images

The core logic employs a three-tier validation process to classify images as **used**:

1. **Swatch Exclusion**: If system configuration `configswatches/general/enabled` is active, any image matching the pattern `wysiwyg/swatches/*` is automatically marked as used, preventing the deletion of product color swatches.

2. **HTML Content Matching**: For each filesystem image, the controller performs case-insensitive substring searches (`stripos()`) against every entry in the aggregated HTML content from CMS pages, blocks, and email templates.

3. **CSS Content Matching**: Similarly, each CSS file string is searched via `stripos()` for the image filename.

Images that fail all three checks are collected via `array_diff($fs_images, $used_images)` and classified as unused.

## Persisting Results to Database

The final stage stores orphaned assets in the module’s `fb_imagecleaner_image` table. The controller strips the `wysiwyg/` prefix from each unused path and executes an `INSERT IGNORE` query (lines 200-215 in the controller), recording the relative path with `entity_type_id = -98`.

This idempotent insertion prevents duplicate entries if the synchronization runs multiple times. After processing, the controller redirects to the admin grid where the new unused WYSIWYG entries are displayed for deletion or export.

## Triggering Synchronization via Admin URL

Administrators initiate the scan through the backend interface. The action URL resolves to:

```php
// Admin route triggering the WYSIWYG sync
Mage::helper('adminhtml')->getUrl('adminhtml/fbimagecleaner/syncwysiwyg');

```

Accessing this endpoint executes the complete workflow and redirects to the image cleaner grid, displaying newly identified unused WYSIWYG assets alongside other entity types.

## Summary

- **WYSIWYG image synchronization** identifies orphaned media by comparing physical files in `media/wysiwyg` against database content and CSS references from the entire frontend skin directory.
- The process initiates via `syncwysiwygAction()` in [`FbimagecleanerController.php`](https://github.com/fballiano/openmage-image-cleaner/blob/main/FbimagecleanerController.php), utilizing `entity_type_id = -98` to categorize WYSIWYG assets distinctly from product or category images.
- Database scanning aggregates HTML from `cms_page`, `cms_block`, and `core_email_template` tables via a single UNION query to capture all potential image references.
- CSS analysis recursively loads all stylesheets from `skin/frontend` to detect background images and other stylesheet-referenced assets.
- Usage determination employs case-insensitive substring matching (`stripos()`) against HTML and CSS content, with automatic exclusion for product swatches in `wysiwyg/swatches/`.
- Unused images are persisted to `fb_imagecleaner_image` via `INSERT IGNORE` to prevent duplicates, enabling safe bulk deletion through the admin interface.

## Frequently Asked Questions

### How does the synchronization distinguish between used and unused WYSIWYG images?

The system employs a three-tier validation process. First, it checks if the image resides in the `wysiwyg/swatches/` directory and if product color swatches are enabled in system configuration; these are automatically preserved. For all other images, it performs case-insensitive substring searches (`stripos()`) against the aggregated HTML content from CMS pages, blocks, and email templates, as well as the contents of all CSS files in the frontend skin directory. Images absent from all these sources are classified as unused.

### Which database tables are scanned during WYSIWYG synchronization?

The synchronization queries union the content columns from three core Magento tables: `cms_page` (specifically the `content` column), `cms_block` (the `content` column), and `core_email_template` (both the `template_text` and `template_styles` columns). This comprehensive scan ensures that image references embedded in page content, static blocks, and transactional email templates are all captured for cross-referencing against the filesystem.

### What is the purpose of the `entity_type_id = -98` value used in the code?

The value `-98` serves as a hardcoded internal identifier within the OpenMage Image Cleaner module to categorize WYSIWYG assets distinctly from other entity types such as product images or category images. This constant allows the controller, helper methods, and database insertion logic to consistently reference and filter WYSIWYG-specific records when storing unused images in the `fb_imagecleaner_image` table or displaying them in the admin grid.

### How are CSS files included in the usage analysis?

The helper class located at [`app/code/community/Fballiano/ImageCleaner/Helper/Data.php`](https://github.com/fballiano/openmage-image-cleaner/blob/main/app/code/community/Fballiano/ImageCleaner/Helper/Data.php) provides the `getAllCSSFilesContents()` method, which recursively traverses the `skin/frontend` directory structure. It identifies all files with the `.css` extension, reads their contents into memory, and returns them as an array of strings. During synchronization, the controller searches these CSS strings for image filenames using case-insensitive substring matching, ensuring that background images and other stylesheet-referenced assets are not mistakenly flagged as unused.