1<?php 2 3/* 4 * This file is part of the Symfony package. 5 * 6 * (c) Fabien Potencier <fabien@symfony.com> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace Symfony\Component\Workflow; 13 14use Symfony\Component\Workflow\Exception\InvalidArgumentException; 15use Symfony\Component\Workflow\Exception\LogicException; 16 17/** 18 * @author Fabien Potencier <fabien@symfony.com> 19 * @author Grégoire Pineau <lyrixx@lyrixx.info> 20 * @author Tobias Nyholm <tobias.nyholm@gmail.com> 21 */ 22final class Definition 23{ 24 private $places = []; 25 private $transitions = []; 26 private $initialPlace; 27 28 /** 29 * @param string[] $places 30 * @param Transition[] $transitions 31 * @param string|null $initialPlace 32 */ 33 public function __construct(array $places, array $transitions, $initialPlace = null) 34 { 35 foreach ($places as $place) { 36 $this->addPlace($place); 37 } 38 39 foreach ($transitions as $transition) { 40 $this->addTransition($transition); 41 } 42 43 $this->setInitialPlace($initialPlace); 44 } 45 46 /** 47 * @return string|null 48 */ 49 public function getInitialPlace() 50 { 51 return $this->initialPlace; 52 } 53 54 /** 55 * @return string[] 56 */ 57 public function getPlaces() 58 { 59 return $this->places; 60 } 61 62 /** 63 * @return Transition[] 64 */ 65 public function getTransitions() 66 { 67 return $this->transitions; 68 } 69 70 private function setInitialPlace($place) 71 { 72 if (null === $place) { 73 return; 74 } 75 76 if (!isset($this->places[$place])) { 77 throw new LogicException(sprintf('Place "%s" cannot be the initial place as it does not exist.', $place)); 78 } 79 80 $this->initialPlace = $place; 81 } 82 83 private function addPlace($place) 84 { 85 if (!preg_match('{^[\w_-]+$}', $place)) { 86 throw new InvalidArgumentException(sprintf('The place "%s" contains invalid characters.', $place)); 87 } 88 89 if (!\count($this->places)) { 90 $this->initialPlace = $place; 91 } 92 93 $this->places[$place] = $place; 94 } 95 96 private function addTransition(Transition $transition) 97 { 98 $name = $transition->getName(); 99 100 foreach ($transition->getFroms() as $from) { 101 if (!isset($this->places[$from])) { 102 throw new LogicException(sprintf('Place "%s" referenced in transition "%s" does not exist.', $from, $name)); 103 } 104 } 105 106 foreach ($transition->getTos() as $to) { 107 if (!isset($this->places[$to])) { 108 throw new LogicException(sprintf('Place "%s" referenced in transition "%s" does not exist.', $to, $name)); 109 } 110 } 111 112 $this->transitions[] = $transition; 113 } 114} 115