Passed
Push — master ( 8d29d2...4c4987 )
by Glynn
06:11 queued 04:18
created

Perique_Migrations::add_migration()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 7
rs 10
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * Abstract class for all Migrations
7
 *
8
 * @package PinkCrab\Perique\Migration\Plugin_Lifecycle
9
 * @author Glynn Quelch [email protected]
10
 * @since 1.0.0
11
 */
12
13
namespace PinkCrab\Perique\Migration\Module;
14
15
use PinkCrab\DB_Migration\Factory;
16
use PinkCrab\Perique\Migration\Event\Uninstall;
17
use PinkCrab\Perique\Migration\Migration_Exception;
18
use PinkCrab\Perique\Interfaces\Module;
19
use PinkCrab\Perique\Migration\Migration;
20
use PinkCrab\Perique\Interfaces\DI_Container;
21
use PinkCrab\Perique\Application\App_Config;
22
use PinkCrab\Loader\Hook_Loader;
23
use PinkCrab\Perique\Migration\Event\Activation;
24
use PinkCrab\Perique\Migration\Event\Deactivation;
25
use PinkCrab\Plugin_Lifecycle\Plugin_Life_Cycle;
26
use PinkCrab\DB_Migration\Migration_Manager;
27
use PinkCrab\Plugin_Lifecycle\Plugin_State_Change;
28
29
final class Perique_Migrations implements Module {
30
31
	/** @var class-string<Migration>[] */
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<Migration>[] at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<Migration>[].
Loading history...
32
	private array $migrations         = array();
33
	private string $migration_log_key = 'pinkcrab_migration_log';
34
35
	/**
36
	 * Add a migration to the list of migrations to run.
37
	 *
38
	 * @param class-string<Migration> $migration
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<Migration> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<Migration>.
Loading history...
39
	 * @return self
40
	 */
41
	public function add_migration( string $migration ): self {
42
		if ( ! is_subclass_of( $migration, Migration::class ) ) {
43
			throw Migration_Exception::none_migration_type( $migration );
44
		}
45
46
		$this->migrations[] = $migration;
47
		return $this;
48
	}
49
50
	/**
51
	 * Set the migration log key.
52
	 *
53
	 * @param string $migration_log_key
54
	 * @return self
55
	 */
56
	public function set_migration_log_key( string $migration_log_key ): self {
57
		$this->migration_log_key = \sanitize_title( $migration_log_key );
58
		return $this;
59
	}
60
61
	/**
62
	 * Get the migration log key.
63
	 *
64
	 * @return string
65
	 */
66
	public function get_migration_log_key(): string {
67
		return $this->migration_log_key;
68
	}
69
70
71
	/**
72
	 * Used to create the controller instance and register the hook call, to trigger.
73
	 *
74
	 * @pram App_Config $config
75
	 * @pram Hook_Loader $loader
76
	 * @pram DI_Container $di_container
77
	 * @return void
78
	 */
79
	public function pre_boot( App_Config $config, Hook_Loader $loader, DI_Container $di_container ): void { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceBeforeLastUsed
80
		// Set the migration manager.
81
		$migration_manager = Factory::manager_with_db_delta( $this->migration_log_key );
82
83
		// Add the migrations to the manager.
84
		foreach ( $this->generate_migrations( $di_container ) as $migration ) {
85
			$migration_manager->add_migration( $migration );
86
		}
87
88
		// Add to the events.
89
		if ( \class_exists( Plugin_Life_Cycle::class ) ) {
90
			add_filter( Plugin_Life_Cycle::EVENT_LIST, $this->generate_migration_events_callback( $migration_manager ) );
91
		}
92
93
	}
94
95
	/**
96
	 * Generates the callback for adding the migration events to the plugin life cycle.
97
	 *
98
	 * @param Migration_Manager $migration_manager
99
	 * @return \Closure(array<Plugin_State_Change>):array<Plugin_State_Change>
100
	 */
101
	protected function generate_migration_events_callback( Migration_Manager $migration_manager ): \Closure {
102
		/**
103
		 * @param array<Plugin_State_Change> $events
104
		 * @return array<Plugin_State_Change>
105
		 */
106
		return function( array $events ) use ( $migration_manager ): array {
107
			static $cached = null;
108
			if ( is_null( $cached ) ) {
109
				$cached = array(
110
					new Activation( $migration_manager ),
111
					new Deactivation( $migration_manager ),
112
					new Uninstall( $migration_manager ),
113
				);
114
			}
115
			return array_merge( $events, $cached );
116
		};
117
	}
118
119
	/**
120
	 * Generate Migrations from the list of migrations.
121
	 *
122
	 * @param DI_Container $container
123
	 * @return array<Migration>
124
	 * @throws Migration_Exception
125
	 */
126
	protected function generate_migrations( DI_Container $container ): array {
127
		$migrations = array();
128
		foreach ( $this->migrations as $migration ) {
129
			if ( is_string( $migration ) ) {
130
				try {
131
					$instance = $container->create( $migration );
132
				} catch ( \Throwable $th ) {
133
					throw Migration_Exception::failed_to_construct_migration( $migration );
134
				}
135
136
				// Add to the list if valid.
137
				if ( ! is_object( $instance ) || ! is_a( $instance, Migration::class ) ) {
138
					throw Migration_Exception::failed_to_construct_migration( $migration );
139
				}
140
141
				$migrations[] = $instance;
142
			}
143
		}
144
		return $migrations;
145
	}
146
147
	## Unused methods
148
149
	/** @inheritDoc */
150
	public function pre_register( App_Config $config, Hook_Loader $loader, DI_Container $di_container ): void {} // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceBeforeLastUsed
151
152
	/** @inheritDoc */
153
	public function post_register( App_Config $config, Hook_Loader $loader, DI_Container $di_container ): void {} // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceBeforeLastUsed
154
155
	/** @inheritDoc */
156
	public function get_middleware(): ?string {
157
		return null;
158
	}
159
}
160