get all states that match a possible regex state from the set of states
provided
public static getAllRegexMatchingStates ( |
||
$regex | a possible regex state. | |
$targets | all target State instances that we check the regex against. | |
리턴 | an array of State instances from the $targets State instances that matched the (negated) regex, or the $regex State if it was not a regex State after all. |
/** * Add a fully configured transition to the machine. * * It is possible to add transition that have 'regex' states: states that * have a name in the format of 'regex:/<regex-here>/' or 'not-regex:/<regex-here>/'. * When adding a transition with a regex state, it will be matched against all currently * known states if there is a match. If you just want to use regex transitions, * it might be preferable to store some states via 'addState' first, so the * * Self transitions for regex states are disallowed by default * since you would probably only want to do that explicitly. Regex states * can be both the 'to' and the 'from' state of a transition. * * Transitions from a 'final' type of state are not allowed. * * the order in which transitions are added matters insofar that when a * StateMachine::run() is called, the first Transition for the current State * will be tried first. * * Since a transition has complete knowledge about it's states, * the addition of a transition will also trigger the adding of the * to and from state on this class. * * this method can also be used to add a Transition directly (instead of via * a loader). Make sure that transitions that share a common State use the same * instance of that State object and vice versa. * * @param Transition $transition * @param boolean $allow_self_transition_by_regex optional: to allow regexes to set a self transition. * @return int a count of how many transitions were added. In case of a regex transition this might be * multiple and in case a transition already exists it might be 0. */ public function addTransition(Transition $transition, $allow_self_transition_by_regex = false) { $from = $transition->getStateFrom(); $to = $transition->getStateTo(); $all_states = $this->getStates(); // check if we have regex states in the transition and get either the // original state back if it's not a regex, or all currently known // states that match the regex. $all_from = Utils::getAllRegexMatchingStates($from, $all_states); $all_to = Utils::getAllRegexMatchingStates($to, $all_states); $contains_regex = $from->isRegex() || $to->isRegex(); $non_regex_transition = $transition; $count = 0; // loop trought all possible 'from' states foreach ($all_from as $from) { // loop through all possible 'to' states foreach ($all_to as $to) { if ($contains_regex && $from->getName() === $to->getName() && !$allow_self_transition_by_regex) { // disallow self transition for regexes and from final states unless it is explicitely allowed. continue; } if ($contains_regex) { /* * get a copy of the current transition that has a regex (so * we have a non-regex state) and delegate to $transition to * get that copy in case it's a subclass of transition and * we need to copy specific fields */ $non_regex_transition = $transition->getCopy($from, $to); } if ($this->addTransitionWithoutRegex($non_regex_transition)) { $count++; } } } return $count; }
/** * @test * @group regex */ public function shouldReturnArrayOfMatchedStates() { $a = new State('a'); $b = new State('ab'); $c = new State('ba'); $d = new State('abracadabra'); $e = new State('action-hero'); $f = new State('action-bad-guy'); $g = new State('ac'); $targets = array($a, $b, $c, $d, $e, $f, $g); $regex = new State('regex:/.*/'); $this->assertEquals($targets, Utils::getAllRegexMatchingStates($regex, $targets)); $regex = new State('regex:/^a.*/'); $this->assertEquals(array($a, $b, $d, $e, $f, $g), Utils::getAllRegexMatchingStates($regex, $targets)); $regex = new State('regex:/^a.+/'); $this->assertEquals(array($b, $d, $e, $f, $g), Utils::getAllRegexMatchingStates($regex, $targets)); $regex = new State('regex:/^a.*a.+$/'); $this->assertEquals(array($d, $f), Utils::getAllRegexMatchingStates($regex, $targets)); $regex = new State('regex:/^ac.*-.+$/'); $this->assertEquals(array($e, $f), Utils::getAllRegexMatchingStates($regex, $targets)); $regex = new State('ac'); $this->assertFalse($regex->isRegex()); $this->assertEquals(array($g), Utils::getAllRegexMatchingStates($regex, $targets), 'non regex state'); }