<?php
/**
* Base Step
*
* @package automattic/jetpack-crm
* @since 6.2.0
*/
namespace Automattic\Jetpack\CRM\Automation;
use Automattic\Jetpack\CRM\Automation\Data_Types\Data_Type;
/**
* Base Step.
*
* @since 6.2.0
* {@inheritDoc}
*/
abstract class Base_Step implements Step {
/**
* Step attributes.
*
* @since 6.2.0
* @var array
*/
protected $attributes;
/**
* Attributes definitions.
*
* @since 6.2.0
* @var array
*/
protected $attribute_definitions = array();
/**
* The next step if the current one is successful.
*
* @since 6.2.0
* @var int|string|null
*/
protected $next_step_true = null;
/**
* The next step if not successful.
*
* @since 6.2.0
* @var int|string|null
*/
protected $next_step_false = null;
/**
* Base_Step constructor.
*
* @since 6.2.0
*
* @param array $step_data An array of data for the current step.
*/
public function __construct( array $step_data ) {
$this->attributes = $step_data['attributes'] ?? array();
$this->next_step_true = $step_data['next_step_true'] ?? null;
$this->next_step_false = $step_data['next_step_false'] ?? null;
}
/**
* Get the data of the step.
*
* @since 6.2.0
*
* @return array The step data.
*/
public function get_attributes(): array {
return $this->attributes;
}
/**
* Set attributes of the step.
*
* @since 6.2.0
*
* @param array $attributes The attributes to set.
*/
public function set_attributes( array $attributes ) {
$this->attributes = $attributes;
}
/**
* Get attribute value.
*
* @since 6.2.0
*
* @param string $attribute The attribute to get.
* @param mixed $default The default value to return if the attribute is not set.
* @return mixed The attribute value.
*/
public function get_attribute( string $attribute, $default = null ) {
return $this->attributes[ $attribute ] ?? $default;
}
/**
* Set attribute value.
*
* @since 6.2.0
*
* @param string $attribute The attribute key.
* @param mixed $value The default value.
* @return void
*/
public function set_attribute( string $attribute, $value ): void {
$this->attributes[ $attribute ] = $value;
}
/**
* Get the step attribute definitions.
*
* @since 6.2.0
*
* @return Attribute_Definition[] The attribute definitions of the step.
*/
public function get_attribute_definitions(): array {
return $this->attribute_definitions;
}
/**
* Set the step attributes.
*
* @since 6.2.0
*
* @param Attribute_Definition[] $attribute_definitions Set the step attributes.
*/
public function set_attribute_definitions( array $attribute_definitions ) {
$this->attribute_definitions = $attribute_definitions;
}
/**
* Get the next step.
*
* Unless anything else is defined, then we assume to only continue with the
* next step if the current one is successful.
* One example of this will be conditions where a certain criteria has not been met.
*
* @since 6.2.0
*
* @return int|string|null The next linked step id.
*/
public function get_next_step_id() {
return $this->get_next_step_true();
}
/**
* Get the next step if the current one is successful.
*
* @since 6.2.0
*
* @return int|string|null The next linked step id.
*/
public function get_next_step_true() {
return $this->next_step_true;
}
/**
* Set the next step if the current one is successful.
*
* @since 6.2.0
*
* @param string|int|null $step_id The next linked step id.
* @return void
*/
public function set_next_step_true( $step_id ): void {
$this->next_step_true = $step_id;
}
/**
* Get the next step if the current one is falsy.
*
* @since 6.2.0
*
* @return int|string|null The next linked step id.
*/
public function get_next_step_false() {
return $this->next_step_false;
}
/**
* Set the next step if the current one is falsy.
*
* @since 6.2.0
*
* @param string|int|null $step_id The next linked step id.
* @return void
*/
public function set_next_step_false( $step_id ): void {
$this->next_step_false = $step_id;
}
/**
* Validate data passed to the step
*
* @since 6.2.0
*
* @param Data_Type $data Data type passed.
* @return void
*
* @throws Data_Type_Exception If the data type passed is not expected.
*/
public function validate( Data_Type $data ): void {
$data_type_class = static::get_data_type();
if ( ! $data instanceof $data_type_class ) {
throw new Data_Type_Exception(
sprintf( 'Invalid data type passed to step: %s', static::class ),
Data_Type_Exception::INVALID_DATA
);
}
}
/**
* Validate and execute the step.
*
* @since 6.2.0
*
* @param Data_Type $data Data type passed.
* @return void
*
* @throws Data_Type_Exception If the data type passed is not expected.
*/
public function validate_and_execute( Data_Type $data ): void {
$this->validate( $data );
$this->execute( $data );
}
/**
* Execute the step.
*
* @since 6.2.0
*
* @param Data_Type $data Data type passed from the trigger.
*/
abstract protected function execute( Data_Type $data );
/**
* Get the slug name of the step.
*
* @since 6.2.0
*
* @return string The slug name of the step.
*/
abstract public static function get_slug(): string;
/**
* Get the title of the step.
*
* @since 6.2.0
*
* @return string|null The title of the step.
*/
abstract public static function get_title(): ?string;
/**
* Get the description of the step.
*
* @since 6.2.0
*
* @return string|null The description of the step.
*/
abstract public static function get_description(): ?string;
/**
* Get the data type exepected by the step.
*
* @since 6.2.0
*
* @return string The data type expected by the step.
*/
abstract public static function get_data_type(): string;
/**
* Get the category of the step.
*
* @since 6.2.0
*
* @return string|null The category of the step.
*/
abstract public static function get_category(): ?string;
/**
* Get the step as an array.
*
* The main use-case to get the step as an array is to prepare
* the items for an API response.
*
* @since 6.2.0
*
* @return array The step as an array.
*/
public function to_array(): array {
$step = array(
'title' => static::get_title(),
'description' => static::get_description(),
'slug' => static::get_slug(),
'category' => static::get_category(),
'step_type' => is_subclass_of( $this, Action::class ) ? 'action' : 'condition',
'next_step_true' => $this->get_next_step_true(),
'next_step_false' => $this->get_next_step_false(),
'attributes' => $this->get_attributes(),
'attribute_definitions' => array(),
);
foreach ( $this->get_attribute_definitions() as $attribute_definition ) {
$step['attribute_definitions'][ $attribute_definition->get_slug() ] = $attribute_definition->to_array();
}
return $step;
}
}