Last active
January 25, 2019 21:31
-
-
Save beaucollins/802f6267fd4fc129fe2a86f109c2ce0e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| // snip | |
| function get_validator( $event_type ) { | |
| $class_name_default = 'Happytools\\Scheduler\\' . strtok( $event_type, ':' ) . '_Event_Validator'; | |
| $class_name_or_validator = apply_filters( 'happytools_event_validator', null, $event_type ); | |
| if ( $class_name_or_validator === null ) { | |
| $class_name_or_validator = $class_name_default; | |
| } | |
| /** | |
| * If the returned class_name_or_validator is an already | |
| * instantiated instance of Event_Validator return it as | |
| * is. | |
| */ | |
| if ( $class_name_or_validator instanceof Event_Validator ) { | |
| return $class_name_or_validator; | |
| } | |
| return class_exists( $class_name_or_validator ) ? new $class_name_or_validator() : false; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace Happytools\Events; | |
| use Happytools\Scheduler\Event_Validator; | |
| use Exception; | |
| /** | |
| * Creates a validator that can be used with the EventStore that uses a composed | |
| * set of validations in a single callable | |
| */ | |
| class Validation_Engine extends Event_Validator { | |
| /** | |
| * Creates a Validation_Engine instance for the given namespace and validator function. | |
| */ | |
| public static function namespace( string $event_namespace, callable $validations ): Event_Validator { | |
| return new self( $event_namespace, $validations ); | |
| } | |
| private $event_namespace; | |
| private $validations; | |
| function __construct( string $event_namespace, callable $validations ) { | |
| $this->event_namespace = $event_namespace; | |
| $this->validations = $validations; | |
| } | |
| /** | |
| * Callback to be used with `happytools_event_validator` hook. Returns itself as | |
| * the validator to use when the event_type matches the event_namespace _and_ there | |
| * is no existing validator registered. | |
| */ | |
| public function detect_event( $class_name, $event_type ) { | |
| // Someone already said they're validating this event | |
| // we aren't going to handle it. | |
| if ( $class_name !== null ) { | |
| return $class_name; | |
| } | |
| $parts = explode( ':', $event_type ); | |
| if ( $parts[0] === $this->event_namespace ) { | |
| return $this; | |
| } | |
| return null; | |
| } | |
| /** | |
| * Validates events for this event_namespace | |
| */ | |
| public function validate( $event ) { | |
| $prefix = $this->event_namespace . ':' ; | |
| if ( strpos( $event['type'], $prefix) !== 0 ) { | |
| return new WP_Error( 'happytools-validation-engine', 'Incorrect event namespace: ' . $event ); | |
| } | |
| /** | |
| * Run the base validations provided by Event_Validator. If `true` returned | |
| * we know that it passed the parent validations. If non-true literal returned | |
| * abort validations and return error. | |
| */ | |
| $result = parent::validate( $event ); | |
| if ($result !== true) { | |
| return $result; | |
| } | |
| /** | |
| * Run all of the validators by reducing them to true or a WP_Error. | |
| */ | |
| $validator = $this->validations; | |
| return $validator( $event ); | |
| } | |
| } | |
| /** | |
| * Creates a callable that receives an event source event and returns true if the | |
| * subtype of the event matches the provided $type | |
| * | |
| * @example | |
| * | |
| * subtype_is( 'my-subtype' )( [ 'type' => 'main-type:my-subtype' ] ); // => true | |
| * subtype_is( 'other-subtype' )( [ 'type' => 'main-type:my-subtype' ] ); // => false | |
| * | |
| * @return callable | |
| */ | |
| function subtype_is( string $type ): callable { | |
| return function( $event ) use ( $type ) { | |
| $event_subtype = substr($event['type'], strpos( $event['type'], ':' ) + 1); | |
| return $event_subtype === $type; | |
| }; | |
| } | |
| /** | |
| * Given a detect callable and a validate callable, first checks if $detect() | |
| * returns true and if so, returns the result of $validate | |
| * | |
| * @return callable function that receives an event source event and returns true if valid | |
| */ | |
| function validate_when( callable $detect, callable $validate ): callable { | |
| return function ( $event ) use ( $detect, $validate ) { | |
| if( $detect( $event ) ) { | |
| return $validate( $event ); | |
| } | |
| return true; | |
| }; | |
| } | |
| /** | |
| * Given a subtype string and a callable $validator runs the validator when | |
| * an event's subtype matches. | |
| * | |
| * @return callable that receives an event source event and returns true if valid | |
| */ | |
| function validate_subtype( string $subtype, callable $validator ): callable { | |
| return validate_when( subtype_is( $subtype ), $validator ); | |
| } | |
| /** | |
| * Given an associated array of validators, runs the corresponding validator when | |
| * the "subtype" of the event matches the key of the associative array | |
| * | |
| * A validator is any callable. | |
| * | |
| * @see { validate_subtype } | |
| * | |
| * @example | |
| * validate_subtypes([ | |
| * 'my-special-event' => 'function_to_call_for_special_event' | |
| * ]) | |
| */ | |
| function validate_subtypes(array $validators): callable { | |
| return function( $event ) use ( $validators ) { | |
| foreach( $validators as $subtype => $validator ) { | |
| $result = validate_subtype( $subtype, $validator)( $event ); | |
| if ( $result !== true ) { | |
| return $result; | |
| } | |
| } | |
| return true; | |
| }; | |
| } | |
| function validate_all(array $validators): callable { | |
| return function( $event ) use ( $validators ) { | |
| foreach( $validators as $validator ) { | |
| $result = $validator( $event ); | |
| if ( $result !== true ) { | |
| return $result; | |
| } | |
| } | |
| return true; | |
| }; | |
| } | |
| function validate_version_exists($event) { | |
| return new WP_Error( 'happytools-validation-engine', 'not implemented', [ | |
| 'event' => $event, | |
| ]); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace Happytools\Subscriptions; | |
| use Happytools\Events\Validation_Engine; | |
| class Subscription { | |
| static public function register_events() { | |
| $validator = self::validator(); | |
| add_filter( 'happytools_event_validator', [$validator, 'detect_event'], null, 2); | |
| } | |
| static function validator() { | |
| /** | |
| * Creates a validator for all events that have a type matching | |
| * | |
| * subscriptions:* | |
| */ | |
| return new Validation_Engine('subscriptions', \Happytools\Events\validate_subtypes([ | |
| /** | |
| * Validations for events of subsriptions:created | |
| */ | |
| 'created' => function( $event ) { | |
| return new \WP_Error('happytools', 'not implemented: ' . $event['type']); | |
| }, | |
| /** | |
| * Validations for events of subscriptions:delete | |
| */ | |
| 'deleted' => \Happytools\Events\validate_all([ | |
| /** | |
| * Function that checks for the aggregate_uuid has an existing | |
| * version. If there isn't an existing version then it's not | |
| * possible to delete. | |
| */ | |
| function() { | |
| return new WP_Error('happytools-subscriptions', 'Deleting not implemented'); | |
| } | |
| ]) | |
| ])); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment