Zoo for Craft CMS

Free · Craft CMS 5

Nobody deletes it, because nobody can prove it is unused

The images from a campaign that ended in 2022. The entries a section was restructured around. The tags somebody typo’d once and never used again. None of it is visible, all of it is in the nightly backup, and it stays there for years — because the only honest answer to “is this still used?” has always been “probably, but I am not deleting it to find out”. Zoo answers the question properly, and shows you its working.

Zoo

The screen never says “nothing points at this”

It says how hard Zoo looked before saying so. Every finding carries the list of probes that ran — and a probe that could not run is shown as a probe that could not run, never as a clean result. “Nothing points at this” and “nothing I was able to check points at this” are different claims, and only one of them is a reason to delete something.

bash
$ php craft zoo/census/run

  unused-assets              312  of 4,109 scanned, 3,790 referenced, 1.4 GB reclaimable
  unrelated-entries           18  of 2,204 scanned, 2,186 referenced
  orphaned-nested-entries      0  of 8,812 scanned
  unused-tags                 44  of 391 scanned, 347 referenced

Census #12: 374 unreferenced, 1.4 GB reclaimable, 6.1s.

How hard Zoo looked:
  ✓ Relational fields                  8,331 found
  ✓ Nested-entry ownership               612 found
  ✓ Structure parentage                   88 found
  ✓ Reference tags in stored content       41 found
  ✓ URLs in stored markup                 196 found
  ✓ Twig templates and config               7 found across 412 places
  – Other tables keyed into elements    Foreign-key scanning is turned off in settings.

Features

Seven ways of looking, eleven enclosures, and five things standing between a click and a permanent delete.

Seven probes, not one query

A relation row is one of at least seven ways one piece of content can point at another, and it is the only one most cleanup tools look at. An image dragged into a rich-text field creates no relation row at all — so a relations-only check will offer to delete it while it is visibly on the page.

  • Relations, nested-entry ownership, structure parentage, reference tags, markup, templates, keyed columns
  • The last three are in no table Craft can be asked about

It reads your templates

craft.entries.id(412) in a Twig file is a reference that no database column records anywhere, and it is exactly the kind a bulk delete destroys silently. Zoo walks your templates and your config looking for ids used as ids, and for quoted literals matching a slug, a URI or a filename.

  • Integers only where they are being used as ids, so a loop index keeps nothing alive
  • Says how many files it read, so a failed walk cannot look like a clean result

It reads the schema, not a list of plugins

Zoo has never heard of Commerce. It asks information_schema for every column with a foreign key into elements, and queries each one — a couple of dozen on a plain install, over a hundred and fifty on a site with Commerce, Formie and Navigation on it.

  • A variant sitting in a five-year-old order keeps itself alive automatically
  • Craft’s own bookkeeping is excluded by a list published on the settings screen

Eleven enclosures

Unused assets, unreferenced entries, orphaned Matrix blocks, abandoned drafts, empty categories, unused tags, empty folders, dormant users, dangling relations, fields in no layout and unused entry types.

  • The schema and account audits are off by default — what they delete is project config, not content
  • Add your own with one method and an event

Nothing is deleted from a stored list

A finding is a claim about the site at the moment the census ran. Between then and now somebody may have dragged that image into a page. So every element is proved again immediately before it goes, through the same call the census used, against an index built from the site as it is now.

  • Anything that has picked up a reference is marked “left alone” and shown with the reference that saved it
  • Never skipped silently, and never deleted on trust

A keep list, with reasons

Every site has content that is meant to be unreferenced — a press-kit PDF linked only from an email campaign, an entry an integration fetches by handle. Mark it kept and no census reports it again. An audit that reports the same false positive every month is one people stop reading.

  • The reason is required: whoever reads the keep list next will not be you
  • Anything on it can be put back in circulation in one click

Frequently Asked Questions

The questions worth answering before you point a deletion tool at your content.

Find out what your site is carrying

Free, no editions, no licence key. Install it, take a census, and read the evidence before you delete a single thing.