Skip to content

Commit

Permalink
dev: scaffold Experimental classes
Browse files Browse the repository at this point in the history
  • Loading branch information
justlevine committed Apr 11, 2024
1 parent 0de7266 commit 9245c75
Show file tree
Hide file tree
Showing 6 changed files with 473 additions and 0 deletions.
Empty file added src/Experimental/Admin.php
Empty file.
183 changes: 183 additions & 0 deletions src/Experimental/Experiment/AbstractExperiment.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
<?php
/**
* Abstract class for creating new experiments.
*
* ALL experiments should extend this class.
*
* @package WPGraphQL\Experimental\Experiment
* @since @todo
*/

namespace WPGraphQL\Experimental\Experiment;

use WPGraphQL\Experimental\ExperimentRegistry;

/**
* Class - Abstract Experiment
*/
abstract class AbstractExperiment {
/**
* The experiment unique slug.
*
* @var ?string
*/
protected static $slug;
/**
* The experiment's configuration.
*
* @var ?array<string,mixed>
*/
protected static $config;

/**
* Whether the experiment is active.
*
* @var ?bool
*/
protected $is_active;

/**
* The class constructor
*/
public function __construct() {
}

/**
* Defines the experiment slug.
*/
abstract protected static function slug(): string;

/**
* Defines the experiment configuration.
*
* @return array<string,mixed>
*/
abstract protected static function config(): array;

/**
* Initializes the experiment.
*
* I.e where you put your hooks.
*/
abstract protected function init(): void;

/**
* Loads the experiment.
*
* @uses AbstractExperiment::init() to initialize the experiment.
*/
public function load(): void {
if ( ! $this->is_active() ) {
return;
}

$this->init();

/**
* Fires after the experiment is loaded.
*
* @param \WPGraphQL\Experimental\Experiment\AbstractExperiment $instance The experiment instance.
*/
do_action( 'wp_graphql_experiment_' . $this->get_slug() . '_loaded', $this );
}

/**
* Gets the experiment's configuration array.
*
* @return array<string,mixed>
*/
public static function get_config(): array {
if ( ! isset( static::$config ) ) {
static::$config = static::prepare_config();
}

return static::$config;
}

/**
* Returns the experiment's slug.
*
* This is static so it can be accessed outside of the class instantiation.
*
* @throws \Exception If the experiment is missing a slug.
*/
public static function get_slug(): string {
if ( ! isset( static::$slug ) ) {
$slug = static::slug();

if ( empty( $slug ) ) {
throw new \Exception(
sprintf(
/* translators: %s: The experiment's class name. */
esc_html__( 'The experiment %s is missing a slug. Ensure a valid `slug` is defined in the ::slug() method.', 'wp-graphql' ),
static::class
)
);
}

static::$slug = $slug;
}

return static::$slug;
}

/**
* Whether the experiment is active.
*/
public function is_active(): bool {
if ( isset( $this->is_active ) ) {
return $this->is_active;
}

$settings = ExperimentRegistry::get_options();

$this->is_active = isset( $settings[ static::get_slug() ] ) ? (bool) $settings[ static::get_slug() ] : false;

return $this->is_active;
}

/**
* Prepares the configuration.
*
* @return array<string,mixed>
*
* @throws \Exception If the experiment is missing a slug.
*/
protected static function prepare_config(): array {
$config = static::config();
$slug = static::get_slug();

/**
* Filters the experiment configuration.
*
* @param array<string,mixed> $config The experiment configuration.
* @param string $slug The experiment's slug.
*/
$config = apply_filters( 'wp_graphql_experiment_config', $config, $slug );
$config = apply_filters( 'wp_graphql_experiment_' . $slug . '_config', $config );

// Validate the config.
static::validate_config( $config );

return $config;
}

/**
* Validates the $config array, throwing an exception if it's invalid.
*
* @param array<string,mixed> $config The experiment configuration.
*
* @throws \Exception If the config is invalid.
*/
protected static function validate_config( array $config ): void {
if ( empty( $config ) ) {
throw new \Exception(
sprintf(
/* translators: %s: The experiment's class name. */
esc_html__( 'The experiment %s is missing a configuration. Ensure a valid `config` is defined in the ::config() method.', 'wp-graphql' ),
static::class
)
);
}
}
}
1 change: 1 addition & 0 deletions src/Experimental/Experiment/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@todo

0 comments on commit 9245c75

Please sign in to comment.