| 1 |
<?php |
| 2 |
/** |
| 3 |
* The contract every contributed cleanup implements. |
| 4 |
* |
| 5 |
* @package Templately |
| 6 |
*/ |
| 7 |
|
| 8 |
namespace Templately\Modules\Utilities\Cleanup; |
| 9 |
|
| 10 |
/** |
| 11 |
* Implement this, hand the class name to the registry from your own module's |
| 12 |
* `init_hooks()`, and you get scheduling, retention policy, guarded deletion, |
| 13 |
* estimation, dry-run, journalling and a UI entry. The engine never names you. |
| 14 |
* |
| 15 |
* FOUR OBLIGATIONS ON THE IMPLEMENTER — these are not style notes: |
| 16 |
* |
| 17 |
* 1. NEVER DELETE ANYTHING YOURSELF. Every removal goes through {@see Remover}. |
| 18 |
* Calling `unlink()` or `rmdir()` directly bypasses path containment, symlink |
| 19 |
* refusal, the guard-file denylist and the live-log exclusion. The engine |
| 20 |
* deliberately exposes no other deletion surface. |
| 21 |
* 2. RESPECT THE BUDGET. Check `$context->has_budget()` at your own item |
| 22 |
* boundary and return `stopped_on_budget()` with work left rather than |
| 23 |
* running to completion regardless. A run that overshoots gets killed |
| 24 |
* mid-delete by the host. |
| 25 |
* 3. RE-CHECK ACTIVITY IMMEDIATELY BEFORE REMOVING, not when you built the |
| 26 |
* candidate list. The engine cannot do this for you — only the feature that |
| 27 |
* produced the data knows what "still in use" means for it. |
| 28 |
* 4. DO NOT THROW FOR ONE BAD ITEM. Collect per-item failures into |
| 29 |
* `TaskResult::fail()` so one failure does not abort the whole run. |
| 30 |
*/ |
| 31 |
interface CleanupTask { |
| 32 |
|
| 33 |
/** |
| 34 |
* Self-description. See {@see TaskDescriptor::from_array()} for the fields |
| 35 |
* and their validation. |
| 36 |
* |
| 37 |
* Translate the label HERE, not at registration: this is called lazily, once |
| 38 |
* the textdomain is loaded. A `__()` call during `plugins_loaded` returns the |
| 39 |
* untranslated string forever. |
| 40 |
* |
| 41 |
* @return array |
| 42 |
*/ |
| 43 |
public function descriptor(): array; |
| 44 |
|
| 45 |
/** |
| 46 |
* What this task WOULD remove. MUST NOT mutate anything. |
| 47 |
* |
| 48 |
* The engine calls this to populate the confirmation dialog, so it runs on |
| 49 |
* an ordinary page load — keep it cheap, or report a bounded figure. |
| 50 |
*/ |
| 51 |
public function estimate( Context $context ): TaskResult; |
| 52 |
|
| 53 |
/** |
| 54 |
* Perform the removal. |
| 55 |
* |
| 56 |
* MUST honour `$context->dry_run` by behaving exactly as `estimate()`. The |
| 57 |
* engine forces that flag on an unactivated site and on an unconfirmed |
| 58 |
* manual request, and it does not re-check afterwards — a task that ignores |
| 59 |
* it deletes data the user never approved. |
| 60 |
*/ |
| 61 |
public function run( Context $context ): TaskResult; |
| 62 |
} |
| 63 |
|