PluginProbe
AI / trunk
AI vtrunk
1.3.0 1.2.0 1.1.0 1.0.2 1.0.1 1.0.0 0.9.0 trunk 0.1.1 0.2.0 0.2.1 0.3.0 0.3.1 0.4.0 0.4.1 0.5.0 0.6.0 0.7.0 0.8.0
ai / includes / Features / Loader.php

Loader.php in AI trunk, at includes/Features/Loader.php

213 lines 4.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Feature Loader class.
4 *
5 * @package WordPress\AI\Features
6 */
7
8 declare( strict_types=1 );
9
10 namespace WordPress\AI\Features;
11
12 use Throwable;
13 use WordPress\AI\Contracts\Feature;
14
15 // Exit if accessed directly.
16 defined( 'ABSPATH' ) || exit;
17
18 /**
19 * Orchestrates feature initialization and registration.
20 *
21 * This class is responsible for loading and initializing features from the registry.
22 * It decouples the initialization logic from the registry itself.
23 *
24 * @internal
25 *
26 * @since 0.6.0
27 */
28 final class Loader {
29 /**
30 * Feature registry instance.
31 *
32 * @since 0.6.0
33 * @var \WordPress\AI\Features\Registry
34 */
35 private \WordPress\AI\Features\Registry $registry;
36
37 /**
38 * Whether features have been initialized.
39 *
40 * @since 0.6.0
41 * @var bool
42 */
43 private bool $initialized = false;
44
45 /**
46 * Constructor.
47 *
48 * @since 0.6.0
49 *
50 * @param \WordPress\AI\Features\Registry $registry The feature registry instance.
51 */
52 public function __construct( Registry $registry ) {
53 $this->registry = $registry;
54 }
55
56 /**
57 * Initializes the Loader by registering and initializing features.
58 *
59 * @since 0.8.0
60 */
61 public function init(): void {
62 $this->register_features();
63 $this->initialize_features();
64 }
65
66 /**
67 * Registers features.
68 *
69 * Registers the default built-in features and fires the 'wpai_register_features' action hook for third-party usage.
70 *
71 * @since 0.6.0
72 */
73 private function register_features(): void {
74 $features = $this->get_default_features();
75
76 foreach ( $features as $feature ) {
77 $this->registry->register_feature( $feature );
78 }
79
80 /**
81 * Allows registration of custom features.
82 *
83 * Third-party developers can use this action to register their own features.
84 *
85 * Example:
86 * ```php
87 * add_action( 'wpai_register_features', function( $registry ) {
88 * $registry->register_feature( new My_Custom_Feature() );
89 * } );
90 * ```
91 *
92 * @since 0.6.0
93 *
94 * @param \WordPress\AI\Features\Registry $registry The feature registry instance.
95 */
96 do_action( 'wpai_register_features', $this->registry );
97 }
98
99 /**
100 * Gets default built-in features.
101 *
102 * @since 0.6.0
103 *
104 * @return array<\WordPress\AI\Contracts\Feature> Array of default feature instances.
105 */
106 private function get_default_features(): array {
107 $feature_classes = array(
108 \WordPress\AI\Features\Image_Generation\Image_Generation::get_id() => \WordPress\AI\Features\Image_Generation\Image_Generation::class,
109 );
110
111 /**
112 * Filters the list of default feature classes.
113 *
114 * Allows developers to add, remove, or replace default feature classes.
115 *
116 * @since 0.6.0
117 *
118 * @param array<string, class-string<\WordPress\AI\Contracts\Feature>> $feature_classes Array of feature class names, keyed by ID.
119 */
120 $items = apply_filters( 'wpai_default_feature_classes', $feature_classes );
121
122 $features = array();
123 foreach ( $items as $item ) {
124 if ( ! is_string( $item ) ) {
125 _doing_it_wrong(
126 __METHOD__,
127 esc_html__( 'Attempted to register invalid feature. Default features must be class-strings.', 'ai' ),
128 '0.6.0'
129 );
130 continue;
131 }
132
133 if ( ! is_a( $item, Feature::class, true ) ) {
134 _doing_it_wrong(
135 __METHOD__,
136 esc_html__( 'Attempted to register invalid feature. All features must implement the Feature interface.', 'ai' ),
137 '0.6.0'
138 );
139
140 continue;
141 }
142
143 try {
144 $feature = new $item();
145 $features[ $feature::get_id() ] = $feature;
146 } catch ( Throwable $e ) {
147 // Skip features that fail to instantiate.
148 _doing_it_wrong(
149 __METHOD__,
150 sprintf(
151 /* translators: 1: Feature class name, 2: Error message. */
152 esc_html__( 'Failed to instantiate feature "%1$s": %2$s', 'ai' ),
153 esc_html( $item ),
154 esc_html( $e->getMessage() ),
155 ),
156 '0.6.0'
157 );
158
159 continue;
160 }
161 }
162
163 return $features;
164 }
165
166 /**
167 * Initializes all enabled features.
168 *
169 * Loops through all registered features and calls their register() method
170 * if they are enabled.
171 *
172 * @since 0.6.0
173 */
174 private function initialize_features(): void {
175 if ( $this->initialized ) {
176 return;
177 }
178
179 /**
180 * Filters whether to enable AI features.
181 *
182 * @since 0.6.0
183 *
184 * @param bool $enabled Whether to enable AI features.
185 */
186 $features_enabled = (bool) apply_filters( 'wpai_features_enabled', true );
187
188 if ( ! $features_enabled ) {
189 $this->initialized = true;
190 return;
191 }
192
193 foreach ( $this->registry->get_all_features() as $feature ) {
194 // Skip if feature is disabled.
195 if ( ! $feature->is_enabled() ) {
196 continue;
197 }
198
199 // Register the feature.
200 $feature->register();
201 }
202
203 /**
204 * Fires after all features have been initialized.
205 *
206 * @since 0.6.0
207 */
208 do_action( 'wpai_features_initialized' );
209
210 $this->initialized = true;
211 }
212 }
213