*/ private array $integrations; /** * What each condition object answered, so a condition shared by several * integrations is asked once. Keyed by the object itself: an object id * can be reused once a condition that was built on the fly is gone. * * @var \WeakMap */ private \WeakMap $answers; /** * Whether load() has run. * * @var bool */ private bool $loaded = false; /** * Constructor. * * @param Integration[] $integrations The integrations to register, in order. */ public function __construct( array $integrations = array() ) { $this->integrations = $integrations; $this->answers = new \WeakMap(); } /** * Registers every integration whose conditions are all met. Runs once. */ public function load(): void { if ( $this->loaded ) { return; } $this->loaded = true; foreach ( $this->integrations as $integration ) { try { if ( $this->conditions_are_met( $integration ) ) { $integration->register(); } } catch ( \Throwable $e ) { $this->report( $integration, $e ); } } } /** * Whether every condition of the integration is met, stopping at the * first that is not. * * @param Integration $integration The integration to check. */ private function conditions_are_met( Integration $integration ): bool { foreach ( $integration->conditions() as $condition ) { if ( ! $this->is_met( $condition ) ) { return false; } } return true; } /** * A condition's answer, asked once per condition object. * * @param Condition $condition The condition. */ private function is_met( Condition $condition ): bool { if ( ! isset( $this->answers[ $condition ] ) ) { $this->answers[ $condition ] = $condition->is_met(); } return $this->answers[ $condition ]; } /** * Logs a skipped integration through wp_trigger_error(), which WordPress * only prints or writes to the log when WP_DEBUG is on. * * @param Integration $integration The integration that failed. * @param \Throwable $error What it threw. */ private function report( Integration $integration, \Throwable $error ): void { wp_trigger_error( 'tagsmith_loader', sprintf( '%1$s was skipped: %2$s: %3$s', get_class( $integration ), get_class( $error ), $error->getMessage() ), E_USER_WARNING ); } }