Skip to content

Refactor: Extract CBT_Theme_Save service from rest_save_theme #829

@bph

Description

@bph

Part of #828 (which fulfills #688).

Goal

Move the orchestration logic out of rest_save_theme() (in includes/class-create-block-theme-api.php) into a new service class. No behavior change at the REST boundary.

Scope

New file: includes/create-theme/theme-save.php

New class: CBT_Theme_Save with one public static method:

public static function run( array $options ): true|WP_Error;

Behavior: identical to the current rest_save_theme() orchestration — handle saveFonts, saveTemplates + processOnlySavedTemplates, saveStyle, savePatterns. Honor is_child_theme() for scope selection. Invalidate the theme cache once at the end. Propagate WP_Error from CBT_Theme_Patterns::add_patterns_to_theme.

REST endpoint update: rest_save_theme() becomes a thin wrapper — call CBT_Theme_Save::run(), return its WP_Error directly or wrap success in the existing WP_REST_Response shape (status, message). The URL, permissions, and response shape do not change.

Bug fixes that fall out of the refactor

  • The current code dereferences $options['processOnlySavedTemplates'] without isset() — fix by normalizing all flags through a single ! empty() check at the top of run().
  • Strict true === flag comparisons are replaced with truthy checks, accepting true, 1, "true" consistently.

Tests (PHPUnit, in this PR)

  • Each flag in isolation persists the right thing
  • saveTemplates without processOnlySavedTemplates does not warn
  • Scope selection for 'user' / 'current' / 'all' across child-theme on/off
  • WP_Error from patterns step propagates out of run()
  • Empty options → no-op success
  • Cache invalidation fires exactly once

Out of scope

  • Any change to the utility classes (CBT_Theme_Fonts, CBT_Theme_Templates, etc.)
  • Any change to the REST URL, permissions, or response shape
  • Promoting silent filesystem failures to WP_Error
  • Any CLI work — that's a follow-up issue tracked in [Tracking] WP-CLI support: phased implementation #828

Acceptance

  • All existing REST tests pass unchanged
  • New PHPUnit tests cover the cases above
  • lint:php, test:php, test:unit all green

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestwp-clihandling wp-cli commands in this plugin

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions