├── LICENSE ├── README.md ├── composer.json └── lib ├── Converter ├── IConverter.php ├── LocalJar.php └── RemoteService.php ├── Diagram ├── ADiagram.php ├── Base │ ├── ACompositeElement.php │ ├── AElement.php │ ├── ARelation.php │ ├── Exception.php │ ├── Relation.php │ ├── Skin.php │ └── Stereotype.php ├── Component.php └── Component │ ├── BaseCompositeElement.php │ ├── BaseElement.php │ ├── ElementActor.php │ ├── ElementCloud.php │ ├── ElementComponent.php │ ├── ElementDatabase.php │ ├── ElementFolder.php │ ├── ElementFrame.php │ ├── ElementInterface.php │ ├── ElementNode.php │ ├── ElementPackage.php │ ├── ElementRectangle.php │ └── ElementUsecase.php ├── PlantUml.php └── bin ├── LICENSE └── plantuml.jar /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # php-plantuml-wrap 2 | Wrap for PlantUml on PHP. Quick generating UML diagrams. 3 | 4 | ### Installing with composer 5 | ``` 6 | "require": { 7 | "sufir/php-plantuml-wrap": "dev-master" 8 | }, 9 | ``` 10 | 11 | ## Example 1 12 | ```php 13 | $plantuml = new PlantUml(); 14 | 15 | // Create new component diagram 16 | $diagram = $plantuml->createDiagram('component') 17 | ->setUmlNotation(Component::NOTATION_UML1); 18 | 19 | // Create diagram elements 20 | $firstComponent = $plantuml->createElement('component', 'component', 'First Component') 21 | ->setNote("A note can also be\non several lines", 'right'); 22 | $da = $plantuml->createElement('component', 'interface', 'Data Access'); 23 | $http = $plantuml->createElement('component', 'interface', 'HTTP') 24 | ->setNote("Web Service only"); 25 | 26 | // Create relations 27 | $rel1 = $plantuml->createRelation($firstComponent, $da) 28 | ->setDirection(Relation::DIRECTION_LEFT); 29 | $rel2 = $plantuml->createRelation() 30 | ->setFrom($firstComponent) 31 | ->setTo($http, Relation::ARROW_ASSOCIATION) 32 | ->setDirection(Relation::DIRECTION_BOTTOM) 33 | ->setLineType(Relation::LINE_DOTTED); 34 | 35 | // Assembly diagram 36 | $diagram->addElement($firstComponent) 37 | ->addElement($da) 38 | ->addElement($http) 39 | ->addRelation($rel1) 40 | ->addRelation($rel2); 41 | 42 | // Render diagram 43 | echo $plantuml->convertDiagram($diagram); 44 | ``` 45 | 46 | 47 | 48 | ## Example 2 49 | ```php 50 | $plantuml = new PlantUml(); 51 | 52 | // Create new component diagram 53 | $diagram = $plantuml->createDiagram('component') 54 | ->setUmlNotation(Component::NOTATION_UML2); 55 | 56 | // Style for webservers 57 | $webserverSkin = $plantuml->createSkin() 58 | ->setBackgroundGradient('white', 'lightblue') 59 | ->setBorderColor('black'); 60 | 61 | // Create elements stereotype https://en.wikipedia.org/wiki/Stereotype_(UML) 62 | $webserverStereotype = $plantuml->createStereotype('Web Server') 63 | ->setSkin($webserverSkin); 64 | 65 | // Create diagram elements 66 | $firstComponent = $plantuml->createElement('component', 'component', 'First Component') 67 | ->setNote("A note can also be\non several lines", 'right'); 68 | $da = $plantuml->createElement('component', 'interface', 'Data Access'); 69 | $http = $plantuml->createElement('component', 'interface', 'HTTP') 70 | ->setNote("Web Service only"); 71 | $webserver1 = $plantuml->createElement('component', 'component', 'Apache') 72 | ->addStereotype($webserverStereotype); 73 | $webserver2 = $plantuml->createElement('component', 'component', 'Nginx') 74 | ->addStereotype($webserverStereotype); 75 | 76 | // Grouping components 77 | $webserversGroup = $plantuml->createElement('component', 'frame', 'Servers') 78 | ->addElement($webserver1) 79 | ->addElement($webserver2); 80 | 81 | // Create relations 82 | $rel1 = $plantuml->createRelation($firstComponent, $da) 83 | ->setDirection(Relation::DIRECTION_LEFT); 84 | $rel2 = $plantuml->createRelation() 85 | ->setFrom($firstComponent) 86 | ->setTo($http, Relation::ARROW_EXTENSION) 87 | ->setLabel('Rel label...') 88 | ->setDirection(Relation::DIRECTION_BOTTOM) 89 | ->setLineType(Relation::LINE_DOTTED); 90 | $rel3 = $plantuml->createRelation() 91 | ->setFrom($http) 92 | ->setTo($webserver1, Relation::ARROW_ASSOCIATION) 93 | ->setDirection(Relation::DIRECTION_RIGHT) 94 | ->setColor('darkgreen'); 95 | $rel4 = $plantuml->createRelation() 96 | ->setFrom($http) 97 | ->setTo($webserver2, Relation::ARROW_ASSOCIATION) 98 | ->setDirection(Relation::DIRECTION_RIGHT) 99 | ->setColor('darkgreen'); 100 | 101 | // Assembly diagram 102 | $diagram->addElement($firstComponent) 103 | ->addElement($da) 104 | ->addElement($http) 105 | ->addElement($webserversGroup) 106 | ->addRelation($rel1) 107 | ->addRelation($rel2) 108 | ->addRelation($rel3) 109 | ->addRelation($rel4); 110 | 111 | // Render diagram 112 | echo $plantuml->convertDiagram($diagram); 113 | ``` 114 | 115 | 116 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sufir/php-plantuml-wrap", 3 | "description": "Wrap for UML generation by PlantUml on PHP", 4 | "keywords": [ 5 | "php", 6 | "plantuml", 7 | "uml", 8 | "diagram" 9 | ], 10 | "type": "library", 11 | "license": "Public Domain", 12 | "authors": [ 13 | { 14 | "name": "Sufir", 15 | "email": "sufir@mihailovka.info" 16 | } 17 | ], 18 | "require": { 19 | "php": ">= 5.3" 20 | }, 21 | "autoload": { 22 | "psr-4": { 23 | "sufir\\PlantUml\\": "lib" 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /lib/Converter/IConverter.php: -------------------------------------------------------------------------------- 1 | 20 | * @package sufir\PlantUml\Converter 21 | */ 22 | interface IConverter 23 | { 24 | 25 | /** 26 | * @param \sufir\PlantUml\Diagram\ADiagram $diagram 27 | * @return string 28 | */ 29 | public function convertDiagram(ADiagram $diagram); 30 | 31 | public function setOutputFormat($outputFormat); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /lib/Converter/LocalJar.php: -------------------------------------------------------------------------------- 1 | 21 | * @package sufir\PlantUml\Converter 22 | */ 23 | class LocalJar implements IConverter 24 | { 25 | 26 | /** 27 | * @var string 28 | */ 29 | protected $outputFormat = PlantUml::OUTPUT_FORMAT_SVG; 30 | 31 | /** 32 | * 33 | * @param \sufir\PlantUml\Diagram\ADiagram $diagram 34 | * @return string 35 | */ 36 | public function convertDiagram(ADiagram $diagram) 37 | { 38 | $uml = $diagram->render(); 39 | $jar = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'plantuml.jar'; 40 | 41 | if (!file_exists($jar)) { 42 | throw new \InvalidArgumentException('plantuml.jar not found: ' . $jar); 43 | } 44 | 45 | $outputFormat = ($this->outputFormat === PlantUml::OUTPUT_FORMAT_SVG) ? '-tsvg' : ''; 46 | 47 | $tmpInputFile = tempnam(sys_get_temp_dir(), 'plantuml'); 48 | file_put_contents($tmpInputFile, $uml); 49 | 50 | $tmpOutputFile = tempnam(sys_get_temp_dir(), 'image'); 51 | 52 | if (stristr(PHP_OS, 'WIN')) { 53 | shell_exec('type "' . $tmpInputFile . '" | java -jar "' . $jar . '" ' . $outputFormat . ' -charset UTF-8 -pipe > "' . $tmpOutputFile . '"'); 54 | } elseif (stristr(PHP_OS, 'LINUX')) { 55 | shell_exec('cat "' . $tmpInputFile . '" | java -jar "' . $jar . '" ' . $outputFormat . ' -charset UTF-8 -pipe > "' . $tmpOutputFile . '"'); 56 | } 57 | 58 | $result = file_get_contents($tmpOutputFile); 59 | 60 | unlink($tmpInputFile); 61 | unlink($tmpOutputFile); 62 | 63 | return $result; 64 | } 65 | 66 | /** 67 | * 68 | * @param string $outputFormat 69 | * @return \sufir\PlantUml\PlantUml 70 | */ 71 | public function setOutputFormat($outputFormat) 72 | { 73 | $this->outputFormat = strtolower($outputFormat); 74 | return $this; 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /lib/Converter/RemoteService.php: -------------------------------------------------------------------------------- 1 | 21 | * @package sufir\PlantUml\Converter 22 | */ 23 | class RemoteService implements IConverter 24 | { 25 | 26 | /** 27 | * @var string 28 | */ 29 | protected $outputFormat = PlantUml::OUTPUT_FORMAT_SVG; 30 | 31 | public function convertDiagram(ADiagram $diagram) 32 | { 33 | return file_get_contents("http://www.plantuml.com:80/plantuml/{$this->outputFormat}/" . $this->encode64(gzdeflate($diagram->render(), 9))); 34 | } 35 | 36 | /** 37 | * 38 | * @param string $outputFormat 39 | * @return \sufir\PlantUml\PlantUml 40 | */ 41 | public function setOutputFormat($outputFormat) 42 | { 43 | $this->outputFormat = strtolower($outputFormat); 44 | return $this; 45 | } 46 | 47 | /** 48 | * Copy from http://plantuml.com/ 49 | * 50 | * @param string $b 51 | * @return string 52 | */ 53 | protected function encode6bit($b) 54 | { 55 | if ($b < 10) { 56 | return chr(48 + $b); 57 | } 58 | $b -= 10; 59 | if ($b < 26) { 60 | return chr(65 + $b); 61 | } 62 | $b -= 26; 63 | if ($b < 26) { 64 | return chr(97 + $b); 65 | } 66 | $b -= 26; 67 | if ($b == 0) { 68 | return '-'; 69 | } 70 | if ($b == 1) { 71 | return '_'; 72 | } 73 | return '?'; 74 | } 75 | 76 | /** 77 | * Copy from http://plantuml.com/ 78 | * 79 | * @param string $b1 80 | * @param string $b2 81 | * @param string $b3 82 | * @return string 83 | */ 84 | protected function append3bytes($b1, $b2, $b3) 85 | { 86 | $c1 = $b1 >> 2; 87 | $c2 = (($b1 & 0x3) << 4) | ($b2 >> 4); 88 | $c3 = (($b2 & 0xF) << 2) | ($b3 >> 6); 89 | $c4 = $b3 & 0x3F; 90 | $r = ""; 91 | $r .= $this->encode6bit($c1 & 0x3F); 92 | $r .= $this->encode6bit($c2 & 0x3F); 93 | $r .= $this->encode6bit($c3 & 0x3F); 94 | $r .= $this->encode6bit($c4 & 0x3F); 95 | return $r; 96 | } 97 | 98 | /** 99 | * Copy from http://plantuml.com/ 100 | * 101 | * @param string $c 102 | * @return string 103 | */ 104 | protected function encode64($c) 105 | { 106 | $str = ""; 107 | $len = strlen($c); 108 | for ($i = 0; $i < $len; $i+=3) { 109 | if ($i + 2 == $len) { 110 | $str .= $this->append3bytes(ord(substr($c, $i, 1)), ord(substr($c, $i + 1, 1)), 0); 111 | } else if ($i + 1 == $len) { 112 | $str .= $this->append3bytes(ord(substr($c, $i, 1)), 0, 0); 113 | } else { 114 | $str .= $this->append3bytes(ord(substr($c, $i, 1)), ord(substr($c, $i + 1, 1)), ord(substr($c, $i + 2, 1))); 115 | } 116 | } 117 | return $str; 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /lib/Diagram/ADiagram.php: -------------------------------------------------------------------------------- 1 | 22 | * @package sufir\PlantUml\Diagram 23 | */ 24 | abstract class ADiagram 25 | { 26 | 27 | /** 28 | * @var string 29 | */ 30 | protected $title, 31 | $header, 32 | $footer; 33 | 34 | /** 35 | * @var integer|float 36 | */ 37 | protected $scale; 38 | 39 | /** 40 | * @var boolean 41 | */ 42 | protected $monochrome = false; 43 | 44 | /** 45 | * 46 | * @var array|\sufir\PlantUml\Diagram\Base\Skin[] 47 | */ 48 | protected $skins = array(); 49 | 50 | /** 51 | * 52 | * @var array|\sufir\PlantUml\Diagram\Base\AElement[] 53 | */ 54 | protected $elements = array(); 55 | 56 | /** 57 | * 58 | * @var \SplObjectStorage|\sufir\PlantUml\Diagram\Base\AElement[] 59 | */ 60 | protected $relations; 61 | 62 | /** 63 | * 64 | * @var string 65 | */ 66 | protected $orientation = 'horisontal'; 67 | 68 | /** 69 | * 70 | * @var boolean 71 | */ 72 | protected $stereotypeVisible = true; 73 | 74 | public function __construct() 75 | { 76 | $this->relations = new SplObjectStorage; 77 | } 78 | 79 | /** 80 | * 81 | * @return string 82 | */ 83 | public function getHeader() 84 | { 85 | return $this->header; 86 | } 87 | 88 | /** 89 | * 90 | * @return string 91 | */ 92 | public function getFooter() 93 | { 94 | return $this->footer; 95 | } 96 | 97 | /** 98 | * 99 | * @return string 100 | */ 101 | public function getTitle() 102 | { 103 | return $this->title; 104 | } 105 | 106 | /** 107 | * Включен монохромный вывод? 108 | * 109 | * @return boolean 110 | */ 111 | public function isMonochrome() 112 | { 113 | return $this->monochrome; 114 | } 115 | 116 | /** 117 | * Нужно ли отображать стереотипы 118 | * 119 | * @return boolean 120 | */ 121 | public function isStereotypeVisible() 122 | { 123 | return $this->stereotypeVisible; 124 | } 125 | 126 | /** 127 | * 128 | * @return string 129 | */ 130 | public function isOrientationHorisontal() 131 | { 132 | return ($this->orientation === 'horisontal'); 133 | } 134 | 135 | /** 136 | * 137 | * @return string 138 | */ 139 | public function isOrientationVertical() 140 | { 141 | return ($this->orientation === 'vertical'); 142 | } 143 | 144 | /** 145 | * 146 | * @param string $orientation 147 | * @return \sufir\PlantUml\Diagram\ADiagram 148 | */ 149 | public function setOrientation($orientation) 150 | { 151 | if (in_array(strtolower($orientation), array('horisontal', 'vertical'))) { 152 | $this->orientation = strtolower($orientation); 153 | } 154 | 155 | return $this; 156 | } 157 | 158 | /** 159 | * 160 | * @param boolean $stereotypeVisible 161 | * @return \sufir\PlantUml\Diagram\ADiagram 162 | */ 163 | public function setStereotypeVisible($stereotypeVisible) 164 | { 165 | $this->stereotypeVisible = !!$stereotypeVisible; 166 | return $this; 167 | } 168 | 169 | 170 | /** 171 | * Принудительно задает использование черно-белого вывода 172 | * 173 | * @param boolean $monochrome 174 | * @return \sufir\PlantUml\Diagram\ADiagram 175 | */ 176 | public function setMonochrome($monochrome) 177 | { 178 | $this->monochrome = !!$monochrome; 179 | return $this; 180 | } 181 | 182 | /** 183 | * Устанавливает масштаб генерируемой диаграммы. 184 | *
185 | * Должно быть десятичной дробью или целым числом. По умолчанию 1. 186 | * 187 | * @param float|integer $scale 188 | * @return \sufir\PlantUml\Diagram\ADiagram 189 | */ 190 | public function setScale($scale) 191 | { 192 | $this->scale = (is_numeric($scale)) ? $scale : 1; 193 | return $this; 194 | } 195 | 196 | /** 197 | * 198 | * @param string $header 199 | * @return \sufir\PlantUml\Diagram\ADiagram 200 | */ 201 | public function setHeader($header) 202 | { 203 | $this->header = $header; 204 | return $this; 205 | } 206 | 207 | /** 208 | * 209 | * @param string $footer 210 | * @return \sufir\PlantUml\Diagram\ADiagram 211 | */ 212 | public function setFooter($footer) 213 | { 214 | $this->footer = $footer; 215 | return $this; 216 | } 217 | 218 | /** 219 | * 220 | * @param string $title 221 | * @return \sufir\PlantUml\Diagram\ADiagram 222 | */ 223 | public function setTitle($title) 224 | { 225 | $this->title = $title; 226 | return $this; 227 | } 228 | 229 | /** 230 | * Устанавливает оформление для указанного типа элементов. 231 | *
232 | * По умолчанию общее для всей диаграммы. 233 | * 234 | * @param \sufir\PlantUml\Diagram\Base\Skin $skin 235 | * @return \sufir\PlantUml\Diagram\ADiagram 236 | */ 237 | public function setSkin(\sufir\PlantUml\Diagram\Base\Skin $skin, $elementType = '_MAIN_') 238 | { 239 | $elementType = ($elementType) ? $elementType : '_MAIN_'; 240 | 241 | if ($elementType !== '_MAIN_' && !$this->isSupported($elementType)) { 242 | throw new \InvalidArgumentException('Недопустимый тип элемента: ' . $elementType); 243 | } 244 | 245 | $this->skins[$elementType] = $skin; 246 | return $this; 247 | } 248 | 249 | /** 250 | * Возвращает true, если указанный элемент поддерживается данным типом диаграмм. 251 | *
252 | * В качестве единственного параметра принимает объект реализующий интерфейс AElement или строку идентифицирующую тип элемента. 253 | * 254 | * @param string|\sufir\PlantUml\Diagram\Base\AElement $element 255 | * @return boolean 256 | */ 257 | abstract public function isSupported($element); 258 | 259 | /** 260 | * @param \sufir\PlantUml\Diagram\Base\AElement $element 261 | * @return \sufir\PlantUml\Diagram\ADiagram 262 | */ 263 | public function addElement(AElement $element) 264 | { 265 | $this->elements[$element->getUniqueId()] = $element; 266 | 267 | return $this; 268 | } 269 | 270 | /** 271 | * @param \sufir\PlantUml\Diagram\Base\Relation $relation 272 | * @return \sufir\PlantUml\Diagram\ADiagram 273 | */ 274 | public function addRelation(Relation $relation) 275 | { 276 | if (!$this->relations->contains($relation)) { 277 | $this->relations->attach($relation); 278 | } 279 | 280 | return $this; 281 | } 282 | 283 | /** 284 | * 285 | * @return string 286 | */ 287 | abstract public function render(); 288 | 289 | } 290 | -------------------------------------------------------------------------------- /lib/Diagram/Base/ACompositeElement.php: -------------------------------------------------------------------------------- 1 | 21 | * @package sufir\PlantUml\Diagram\Base 22 | */ 23 | abstract class ACompositeElement extends AElement 24 | { 25 | 26 | /** 27 | * 28 | * @var array|\sufir\PlantUml\Diagram\Base\AElement[] 29 | */ 30 | protected $elements = array(); 31 | 32 | /** 33 | * 34 | * @param \sufir\PlantUml\Diagram\Base\AElement $element 35 | * @return \sufir\PlantUml\Diagram\Base\ACompositeElement 36 | */ 37 | public function addElement(AElement $element) 38 | { 39 | $this->elements[$element->getUniqueId()] = $element; 40 | 41 | return $this; 42 | } 43 | 44 | /** 45 | * 46 | * @return \sufir\PlantUml\Diagram\Base\AElement[] 47 | */ 48 | public function getChilds() 49 | { 50 | return $this->elements; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /lib/Diagram/Base/AElement.php: -------------------------------------------------------------------------------- 1 | 18 | * @package sufir\PlantUml\Diagram\Base 19 | */ 20 | abstract class AElement 21 | { 22 | 23 | /** 24 | * @var string 25 | */ 26 | protected $uniqueId; 27 | 28 | /** 29 | * @var string 30 | */ 31 | protected $title; 32 | 33 | /** 34 | * @var string 35 | */ 36 | protected $color; 37 | 38 | /** 39 | * @var array|\sufir\PlantUml\Diagram\Base\Stereotype[] 40 | */ 41 | protected $stereotypes = array(); 42 | 43 | /** 44 | * @var string 45 | */ 46 | protected $link; 47 | 48 | /** 49 | * @var string 50 | */ 51 | protected $note; 52 | 53 | /** 54 | * @var string 55 | */ 56 | protected $notePosition = 'left'; 57 | 58 | public function __construct($title) 59 | { 60 | $this->setTitle($title); 61 | 62 | return $this; 63 | } 64 | 65 | /** 66 | * 67 | * @return string 68 | */ 69 | public function getUniqueId() 70 | { 71 | if (!$this->uniqueId) { 72 | $this->uniqueId = md5(time() . $this->getTitle() . uniqid()); 73 | } 74 | 75 | return $this->uniqueId; 76 | } 77 | 78 | /** 79 | * 80 | * @return string 81 | */ 82 | public function getTitle() 83 | { 84 | return $this->title; 85 | } 86 | 87 | /** 88 | * 89 | * @return string 90 | */ 91 | public function getColor() 92 | { 93 | return $this->color; 94 | } 95 | 96 | /** 97 | * 98 | * @return array 99 | */ 100 | public function getStereotypes() 101 | { 102 | return $this->stereotypes; 103 | } 104 | 105 | /** 106 | * 107 | * @return array 108 | */ 109 | public function hasStereotypes() 110 | { 111 | return !empty($this->stereotypes); 112 | } 113 | 114 | /** 115 | * 116 | * @return string 117 | */ 118 | public function getLink() 119 | { 120 | return $this->link; 121 | } 122 | 123 | /** 124 | * 125 | * @return string 126 | */ 127 | public function getNote() 128 | { 129 | return $this->note; 130 | } 131 | 132 | /** 133 | * 134 | * @param string $note 135 | * @return \sufir\PlantUml\Diagram\Base\AElement 136 | */ 137 | public function setNote($note, $position = 'left') 138 | { 139 | $this->note = $note; 140 | $this->notePosition = strtolower($position); 141 | 142 | return $this; 143 | } 144 | 145 | /** 146 | * 147 | * @param string $title 148 | * @return \sufir\PlantUml\Diagram\Base\AElement 149 | */ 150 | public function setTitle($title) 151 | { 152 | $this->title = $title; 153 | return $this; 154 | } 155 | 156 | /** 157 | * 158 | * @param string $color 159 | * @return \sufir\PlantUml\Diagram\Base\AElement 160 | */ 161 | public function setColor($color) 162 | { 163 | $this->color = $color; 164 | return $this; 165 | } 166 | 167 | /** 168 | * 169 | * @param string $from 170 | * @param string $to 171 | * @param string $direction 172 | * @return \sufir\PlantUml\Diagram\Base\Skin 173 | */ 174 | public function setGradient($from, $to, $direction = '/') 175 | { 176 | $this->color = $from . $direction . ltrim($to, '#'); 177 | 178 | return $this; 179 | } 180 | 181 | /** 182 | * 183 | * @param \sufir\PlantUml\Diagram\Base\Stereotype $stereotypes 184 | * @return \sufir\PlantUml\Diagram\Base\AElement 185 | */ 186 | public function addStereotype(Stereotype $stereotype) 187 | { 188 | $this->stereotypes[$stereotype->getName()] = $stereotype; 189 | return $this; 190 | } 191 | 192 | /** 193 | * 194 | * @param string $link 195 | * @return \sufir\PlantUml\Diagram\Base\AElement 196 | */ 197 | public function setLink($link) 198 | { 199 | $this->link = $link; 200 | return $this; 201 | } 202 | 203 | /** 204 | * Возвращает идентификатор типа элемента 205 | * 206 | * @return string Идентификатор типа элемента 207 | */ 208 | abstract public function getType(); 209 | 210 | /** 211 | * 212 | * @param string $offset 213 | * @return string 214 | */ 215 | abstract public function render($offset = 0); 216 | 217 | } 218 | -------------------------------------------------------------------------------- /lib/Diagram/Base/ARelation.php: -------------------------------------------------------------------------------- 1 | 18 | * @package sufir\PlantUml\Diagram\Base 19 | */ 20 | abstract class ARelation 21 | { 22 | 23 | const DIRECTION_LEFT = 'left', // <- 24 | DIRECTION_TOP = 'top', // <-- 25 | DIRECTION_BOTTOM = 'bottom', // --> 26 | DIRECTION_RIGHT = 'right'; // -> 27 | 28 | /** 29 | * 30 | * @var \sufir\PlantUml\Diagram\Base\AElement 31 | */ 32 | protected $from; 33 | 34 | /** 35 | * 36 | * @var \sufir\PlantUml\Diagram\Base\AElement 37 | */ 38 | protected $to; 39 | 40 | /** 41 | * 42 | * @var string 43 | */ 44 | protected $label; 45 | 46 | /** 47 | * 48 | * @var string 49 | */ 50 | protected $direction; 51 | 52 | /** 53 | * 54 | * @var string 55 | */ 56 | protected $color; 57 | 58 | /** 59 | * 60 | * @return \sufir\PlantUml\Diagram\Base\AElement 61 | */ 62 | public function getFrom() 63 | { 64 | return $this->from; 65 | } 66 | 67 | /** 68 | * 69 | * @return \sufir\PlantUml\Diagram\Base\AElement 70 | */ 71 | public function getTo() 72 | { 73 | return $this->to; 74 | } 75 | 76 | /** 77 | * 78 | * @return string 79 | */ 80 | public function getLabel() 81 | { 82 | return $this->label; 83 | } 84 | 85 | /** 86 | * 87 | * @return string 88 | */ 89 | public function getDirection() 90 | { 91 | return $this->direction; 92 | } 93 | 94 | /** 95 | * 96 | * @return string 97 | */ 98 | public function getColor() 99 | { 100 | return $this->color; 101 | } 102 | 103 | /** 104 | * 105 | * @param string $color 106 | * @return \sufir\PlantUml\Diagram\Base\ARelation 107 | */ 108 | public function setColor($color) 109 | { 110 | $this->color = $color; 111 | return $this; 112 | } 113 | 114 | /** 115 | * 116 | * @param \sufir\PlantUml\Diagram\Base\AElement $from 117 | * @return \sufir\PlantUml\Diagram\Base\ARelation 118 | */ 119 | public function setFrom(AElement $from) 120 | { 121 | $this->from = $from; 122 | return $this; 123 | } 124 | 125 | /** 126 | * 127 | * @param \sufir\PlantUml\Diagram\Base\AElement $to 128 | * @return \sufir\PlantUml\Diagram\Base\ARelation 129 | */ 130 | public function setTo(AElement $to) 131 | { 132 | $this->to = $to; 133 | return $this; 134 | } 135 | 136 | /** 137 | * 138 | * @param string $label 139 | * @return \sufir\PlantUml\Diagram\Base\ARelation 140 | */ 141 | public function setLabel($label) 142 | { 143 | $this->label = $label; 144 | return $this; 145 | } 146 | 147 | /** 148 | * 149 | * @param string $direction 150 | * @return \sufir\PlantUml\Diagram\Base\ARelation 151 | */ 152 | public function setDirection($direction) 153 | { 154 | $direction = strtolower($direction); 155 | 156 | if (in_array(strtolower($direction), array( 157 | self::DIRECTION_TOP, 158 | self::DIRECTION_BOTTOM, 159 | self::DIRECTION_LEFT, 160 | self::DIRECTION_RIGHT, 161 | ))) { 162 | throw new \InvalidArgumentException('Недопустимое значение направления связи: ' . $direction); 163 | } 164 | 165 | $this->direction = $direction; 166 | return $this; 167 | } 168 | 169 | } 170 | -------------------------------------------------------------------------------- /lib/Diagram/Base/Exception.php: -------------------------------------------------------------------------------- 1 | 18 | * @package Exception 19 | */ 20 | class Exception 21 | { 22 | //put your code here 23 | } 24 | -------------------------------------------------------------------------------- /lib/Diagram/Base/Relation.php: -------------------------------------------------------------------------------- 1 | 18 | * @package sufir\PlantUml\Diagram\Base 19 | */ 20 | class Relation 21 | { 22 | 23 | const DIRECTION_LEFT = 'left', // <- 24 | DIRECTION_TOP = 'top', // <-- 25 | DIRECTION_BOTTOM = 'bottom', // --> 26 | DIRECTION_RIGHT = 'right'; // -> 27 | 28 | const LINE_DOTTED = 'dotted', 29 | LINE_SIMPLE = 'simple', 30 | LINE_SOLID = 'solid'; 31 | 32 | const ARROW_NONE = 'none', 33 | ARROW_BRACKET = 'bracket', 34 | ARROW_EXTENSION = 'extension', 35 | ARROW_COMPOSITION = 'composition', 36 | ARROW_AGGREGATION = 'aggregation', 37 | ARROW_GENERALIZATION = 'generalization', 38 | ARROW_ASSOCIATION = 'association'; 39 | 40 | /** 41 | * @var \sufir\PlantUml\Diagram\Base\AElement 42 | */ 43 | protected $from; 44 | 45 | /** 46 | * @var \sufir\PlantUml\Diagram\Base\AElement 47 | */ 48 | protected $to; 49 | 50 | /** 51 | * @var string 52 | */ 53 | protected $label; 54 | 55 | /** 56 | * @var string 57 | */ 58 | protected $direction; 59 | 60 | /** 61 | * @var string 62 | */ 63 | protected $arrowFrom = self::ARROW_NONE; 64 | 65 | /** 66 | * @var string 67 | */ 68 | protected $arrowTo = self::ARROW_NONE; 69 | 70 | /** 71 | * @var string 72 | */ 73 | protected $color; 74 | 75 | /** 76 | * @var boolean 77 | */ 78 | protected $hidden = false; 79 | 80 | /** 81 | * @var string 82 | */ 83 | protected $line = self::LINE_SIMPLE; 84 | 85 | /** 86 | * @var length 87 | */ 88 | protected $length = 1; 89 | 90 | /** 91 | * @var array 92 | */ 93 | protected $lineSymbols = array( 94 | self::LINE_DOTTED => '.', 95 | self::LINE_SOLID => '=', 96 | self::LINE_SIMPLE => '-', 97 | ); 98 | 99 | /** 100 | * @var array 101 | */ 102 | protected $leftArrows = array( 103 | self::ARROW_NONE => '', 104 | self::ARROW_BRACKET => ')', 105 | self::ARROW_GENERALIZATION => '<<', 106 | self::ARROW_EXTENSION => '<|', 107 | self::ARROW_AGGREGATION => 'o', 108 | self::ARROW_ASSOCIATION => '<', 109 | self::ARROW_COMPOSITION => '*', 110 | ); 111 | 112 | /** 113 | * @var array 114 | */ 115 | protected $rightArrows = array( 116 | self::ARROW_NONE => '', 117 | self::ARROW_BRACKET => '(', 118 | self::ARROW_GENERALIZATION => '>>', 119 | self::ARROW_EXTENSION => '|>', 120 | self::ARROW_AGGREGATION => 'o', 121 | self::ARROW_ASSOCIATION => '>', 122 | self::ARROW_COMPOSITION => '*', 123 | ); 124 | 125 | public function __construct(AElement $from = null, AElement $to = null) 126 | { 127 | if ($from) { 128 | $this->setFrom($from); 129 | } 130 | 131 | if ($to) { 132 | $this->setTo($to); 133 | } 134 | 135 | return $this; 136 | } 137 | 138 | /** 139 | * 140 | * @return \sufir\PlantUml\Diagram\Base\AElement 141 | */ 142 | public function from() 143 | { 144 | return $this->from; 145 | } 146 | 147 | /** 148 | * 149 | * @return \sufir\PlantUml\Diagram\Base\AElement 150 | */ 151 | public function to() 152 | { 153 | return $this->to; 154 | } 155 | 156 | /** 157 | * 158 | * @return string 159 | */ 160 | public function getLabel() 161 | { 162 | return $this->label; 163 | } 164 | 165 | /** 166 | * 167 | * @return string 168 | */ 169 | public function getDirection() 170 | { 171 | return $this->direction; 172 | } 173 | 174 | /** 175 | * 176 | * @return string 177 | */ 178 | public function getColor() 179 | { 180 | return $this->color; 181 | } 182 | 183 | /** 184 | * 185 | * @return string 186 | */ 187 | public function getLineType() 188 | { 189 | return $this->line; 190 | } 191 | 192 | /** 193 | * 194 | * @return boolean 195 | */ 196 | public function isHidden() 197 | { 198 | return $this->hidden; 199 | } 200 | 201 | /** 202 | * 203 | * @param boolean $hidden 204 | * @return \sufir\PlantUml\Diagram\Base\Relation 205 | */ 206 | public function setHidden($hidden) 207 | { 208 | $this->hidden = !!$hidden; 209 | return $this; 210 | } 211 | 212 | 213 | /** 214 | * @param string $line 215 | * @return \sufir\PlantUml\Diagram\Base\Relation 216 | */ 217 | public function setLineType($line) 218 | { 219 | $this->line = strtolower($line); 220 | return $this; 221 | } 222 | 223 | /** 224 | * 225 | * @param string $color 226 | * @return \sufir\PlantUml\Diagram\Base\Relation 227 | */ 228 | public function setColor($color) 229 | { 230 | $this->color = $color; 231 | return $this; 232 | } 233 | 234 | /** 235 | * 236 | * @param \sufir\PlantUml\Diagram\Base\AElement $from 237 | * @param string $arrow 238 | * @return \sufir\PlantUml\Diagram\Base\Relation 239 | */ 240 | public function setFrom(AElement $from, $arrow = self::ARROW_NONE) 241 | { 242 | $this->from = $from; 243 | $this->arrowFrom = $arrow; 244 | 245 | return $this; 246 | } 247 | 248 | /** 249 | * 250 | * @param \sufir\PlantUml\Diagram\Base\AElement $to 251 | * @param string $arrow 252 | * @return \sufir\PlantUml\Diagram\Base\Relation 253 | */ 254 | public function setTo(AElement $to, $arrow = self::ARROW_NONE) 255 | { 256 | $this->to = $to; 257 | $this->arrowTo = $arrow; 258 | 259 | return $this; 260 | } 261 | 262 | /** 263 | * 264 | * @param string $label 265 | * @return \sufir\PlantUml\Diagram\Base\Relation 266 | */ 267 | public function setLabel($label) 268 | { 269 | $this->label = $label; 270 | return $this; 271 | } 272 | 273 | /** 274 | * 275 | * @param string $direction 276 | * @return \sufir\PlantUml\Diagram\Base\Relation 277 | */ 278 | public function setDirection($direction) 279 | { 280 | $direction = strtolower($direction); 281 | 282 | if (!in_array(strtolower($direction), array( 283 | self::DIRECTION_TOP, 284 | self::DIRECTION_BOTTOM, 285 | self::DIRECTION_LEFT, 286 | self::DIRECTION_RIGHT, 287 | ))) { 288 | throw new \InvalidArgumentException('Недопустимое значение направления связи: ' . $direction); 289 | } 290 | 291 | $this->direction = $direction; 292 | return $this; 293 | } 294 | 295 | /** 296 | * @return integer 297 | */ 298 | public function getLength() 299 | { 300 | return $this->length; 301 | } 302 | 303 | /** 304 | * Длинна связи (расстояние между элементами). 305 | *
306 | * Поддерживается только для вертикальных связей! 307 | * 308 | * @param integer $length 309 | * @return \sufir\PlantUml\Diagram\Base\Relation 310 | */ 311 | public function setLength($length) 312 | { 313 | $this->length = (int) $length; 314 | return $this; 315 | } 316 | 317 | public function render() { 318 | $line = $this->getLine(); 319 | 320 | if ($this->direction === self::DIRECTION_LEFT || $this->direction === self::DIRECTION_TOP) { 321 | $definition = $this->to()->getUniqueId() . ' ' . $this->getArrow($this->arrowTo, 'left') . $line . $this->getArrow($this->arrowFrom, 'right') . ' ' . $this->from()->getUniqueId(); 322 | } else { 323 | $definition = $this->from()->getUniqueId() . ' ' . $this->getArrow($this->arrowFrom, 'left') . $line . $this->getArrow($this->arrowTo, 'right') . ' ' . $this->to()->getUniqueId(); 324 | } 325 | 326 | if ($this->getLabel()) { 327 | $definition .= ' :"' . $this->getLabel() . '"'; 328 | } 329 | 330 | return $definition . "\n"; 331 | } 332 | 333 | /** 334 | * @param string $arrowType 335 | * @param string $direction 336 | * @return string 337 | */ 338 | protected function getArrow($arrowType, $position) 339 | { 340 | if ($position === 'left') { 341 | return (isset($this->leftArrows[$arrowType])) ? $this->leftArrows[$arrowType] : ''; 342 | } 343 | 344 | return (isset($this->rightArrows[$arrowType])) ? $this->rightArrows[$arrowType] : ''; 345 | } 346 | 347 | /** 348 | * 349 | * @return string 350 | */ 351 | protected function getLine() 352 | { 353 | $lineSymbol = (isset($this->lineSymbols[$this->getLineType()])) ? $this->lineSymbols[$this->getLineType()] : $this->lineSymbols[self::LINE_SIMPLE]; 354 | 355 | if ($this->direction === self::DIRECTION_LEFT || $this->direction === self::DIRECTION_RIGHT) { 356 | $line = $lineSymbol; 357 | } else { 358 | $line = str_pad($lineSymbol, $this->getLength()+1, $lineSymbol); 359 | } 360 | 361 | if ($this->isHidden()) { 362 | $line = $line . '[hidden]'; 363 | } elseif ($this->getColor()) { 364 | $line = $line . '[#' . ltrim($this->getColor(), '#') . ']'; 365 | } 366 | 367 | return $line; 368 | } 369 | 370 | } 371 | -------------------------------------------------------------------------------- /lib/Diagram/Base/Skin.php: -------------------------------------------------------------------------------- 1 | 18 | * @package sufir\PlantUml\Diagram\Base 19 | */ 20 | class Skin implements \IteratorAggregate 21 | { 22 | 23 | const GRADIENT_VTRTICAL = '-', 24 | GRADIENT_HORISONTAL = '|', 25 | GRADIENT_DIAGONAL_FROM_LEFT_TOP = '/', 26 | GRADIENT_DIAGONAL_FROM_LEFT_BOTTOM = '\\'; 27 | 28 | protected $style = array( 29 | 'backgroundColor' => null, 30 | 'borderColor' => null, 31 | 'lineColor' => null, 32 | 'fontColor' => null, 33 | 'fontSize' => null, 34 | 'fontStyle' => null, 35 | 'fontName' => null, 36 | 'align' => null, 37 | 'shadowing' => null, 38 | 'arrowColor' => null, 39 | 'arrowFontColor' => null, 40 | 'arrowFontName' => null, 41 | 'noteBackgroundColor' => null, 42 | 'noteBorderColor' => null, 43 | ); 44 | 45 | /** 46 | * 47 | * @return type 48 | */ 49 | public function getNoteBackgroundColor() 50 | { 51 | return $this->style['noteBackgroundColor']; 52 | } 53 | 54 | /** 55 | * 56 | * @return type 57 | */ 58 | public function getNoteBorderColor() 59 | { 60 | return $this->style['noteBorderColor']; 61 | } 62 | 63 | /** 64 | * 65 | * @return type 66 | */ 67 | public function getBackgroundColor() 68 | { 69 | return $this->style['backgroundColor']; 70 | } 71 | 72 | /** 73 | * 74 | * @return type 75 | */ 76 | public function getBorderColor() 77 | { 78 | return $this->style['borderColor']; 79 | } 80 | 81 | /** 82 | * 83 | * @return string 84 | */ 85 | public function getLineColor() 86 | { 87 | return $this->style['lineColor']; 88 | } 89 | 90 | /** 91 | * 92 | * @return string 93 | */ 94 | public function getFontColor() 95 | { 96 | return $this->style['fontColor']; 97 | } 98 | 99 | /** 100 | * 101 | * @return string 102 | */ 103 | public function getFontSize() 104 | { 105 | return $this->style['fontSize']; 106 | } 107 | 108 | /** 109 | * 110 | * @return string 111 | */ 112 | public function getFontStyle() 113 | { 114 | return $this->style['fontStyle']; 115 | } 116 | 117 | /** 118 | * 119 | * @return string 120 | */ 121 | public function getFontName() 122 | { 123 | return $this->style['fontName']; 124 | } 125 | 126 | /** 127 | * 128 | * @return string 129 | */ 130 | public function getAlign() 131 | { 132 | return $this->style['align']; 133 | } 134 | 135 | /** 136 | * 137 | * @return string 138 | */ 139 | public function getShadow() 140 | { 141 | return $this->style['shadowing']; 142 | } 143 | 144 | /** 145 | * 146 | * @return string 147 | */ 148 | public function getArrowColor() 149 | { 150 | return $this->style['arrowColor']; 151 | } 152 | 153 | /** 154 | * 155 | * @return string 156 | */ 157 | public function getArrowFontColor() 158 | { 159 | return $this->style['arrowFontColor']; 160 | } 161 | 162 | /** 163 | * 164 | * @return string 165 | */ 166 | public function getArrowFontName() 167 | { 168 | return $this->style['arrowFontName']; 169 | } 170 | 171 | /** 172 | * 173 | * @return \ArrayIterator 174 | */ 175 | public function getIterator() { 176 | return new \ArrayIterator($this->style); 177 | } 178 | 179 | /** 180 | * 181 | * @param string $from 182 | * @param string $to 183 | * @param string $direction 184 | * @return \sufir\PlantUml\Diagram\Base\Skin 185 | */ 186 | public function setBackgroundGradient($from, $to, $direction = Skin::GRADIENT_DIAGONAL_FROM_LEFT_TOP) 187 | { 188 | $this->style['backgroundColor'] = $from . $direction . ltrim($to, '#'); 189 | 190 | return $this; 191 | } 192 | 193 | /** 194 | * 195 | * @param string $arrowFontName 196 | * @return \sufir\PlantUml\Diagram\Base\Skin 197 | */ 198 | public function setArrowFontName($arrowFontName) 199 | { 200 | $this->style['arrowFontName'] = $arrowFontName; 201 | return $this; 202 | } 203 | 204 | /** 205 | * 206 | * @param string $backgroundColor 207 | * @return \sufir\PlantUml\Diagram\Base\Skin 208 | */ 209 | public function setNoteBackgroundColor($backgroundColor) 210 | { 211 | $this->style['noteBackgroundColor'] = $backgroundColor; 212 | return $this; 213 | } 214 | 215 | /** 216 | * 217 | * @param string $borderColor 218 | * @return \sufir\PlantUml\Diagram\Base\Skin 219 | */ 220 | public function setNoteBorderColor($borderColor) 221 | { 222 | $this->style['noteBorderColor'] = $borderColor; 223 | return $this; 224 | } 225 | 226 | /** 227 | * 228 | * @param string $backgroundColor 229 | * @return \sufir\PlantUml\Diagram\Base\Skin 230 | */ 231 | public function setBackgroundColor($backgroundColor) 232 | { 233 | $this->style['backgroundColor'] = $backgroundColor; 234 | return $this; 235 | } 236 | 237 | /** 238 | * 239 | * @param string $borderColor 240 | * @return \sufir\PlantUml\Diagram\Base\Skin 241 | */ 242 | public function setBorderColor($borderColor) 243 | { 244 | $this->style['borderColor'] = $borderColor; 245 | return $this; 246 | } 247 | 248 | /** 249 | * 250 | * @param string $lineColor 251 | * @return \sufir\PlantUml\Diagram\Base\Skin 252 | */ 253 | public function setLineColor($lineColor) 254 | { 255 | $this->style['lineColor'] = $lineColor; 256 | return $this; 257 | } 258 | 259 | /** 260 | * 261 | * @param string $fontColor 262 | * @return \sufir\PlantUml\Diagram\Base\Skin 263 | */ 264 | public function setFontColor($fontColor) 265 | { 266 | $this->style['fontColor'] = $fontColor; 267 | return $this; 268 | } 269 | 270 | /** 271 | * 272 | * @param string $fontSize 273 | * @return \sufir\PlantUml\Diagram\Base\Skin 274 | */ 275 | public function setFontSize($fontSize) 276 | { 277 | $this->style['fontSize'] = $fontSize; 278 | return $this; 279 | } 280 | 281 | /** 282 | * 283 | * @param string $fontStyle 284 | * @return \sufir\PlantUml\Diagram\Base\Skin 285 | */ 286 | public function setFontStyle($fontStyle) 287 | { 288 | $this->style['fontStyle'] = $fontStyle; 289 | return $this; 290 | } 291 | 292 | /** 293 | * 294 | * @param string $fontName 295 | * @return \sufir\PlantUml\Diagram\Base\Skin 296 | */ 297 | public function setFontName($fontName) 298 | { 299 | $this->style['fontName'] = $fontName; 300 | return $this; 301 | } 302 | 303 | /** 304 | * 305 | * @param string $align 306 | * @return \sufir\PlantUml\Diagram\Base\Skin 307 | */ 308 | public function setAlign($align) 309 | { 310 | $this->style['align'] = $align; 311 | return $this; 312 | } 313 | 314 | /** 315 | * 316 | * @param string $shadow 317 | * @return \sufir\PlantUml\Diagram\Base\Skin 318 | */ 319 | public function setShadow($shadow) 320 | { 321 | $this->style['shadowing'] = !!$shadow; 322 | return $this; 323 | } 324 | 325 | /** 326 | * 327 | * @param string $arrowColor 328 | * @return \sufir\PlantUml\Diagram\Base\Skin 329 | */ 330 | public function setArrowColor($arrowColor) 331 | { 332 | $this->style['arrowColor'] = $arrowColor; 333 | return $this; 334 | } 335 | 336 | /** 337 | * 338 | * @param string $arrowFontColor 339 | * @return \sufir\PlantUml\Diagram\Base\Skin 340 | */ 341 | public function setArrowFontColor($arrowFontColor) 342 | { 343 | $this->style['arrowFontColor'] = $arrowFontColor; 344 | return $this; 345 | } 346 | 347 | } 348 | -------------------------------------------------------------------------------- /lib/Diagram/Base/Stereotype.php: -------------------------------------------------------------------------------- 1 | 18 | * @package sufir\PlantUml\Diagram\Base 19 | */ 20 | class Stereotype 21 | { 22 | 23 | protected $name; 24 | 25 | /** 26 | * 27 | * @var \sufir\PlantUml\Diagram\Base\Skin 28 | */ 29 | protected $skin = null; 30 | 31 | public function __construct($name) 32 | { 33 | $clearName = trim($name, " \t\n\r\0\x0B<>"); 34 | if (strlen($clearName) <= 0) { 35 | throw new \InvalidArgumentException('Недопустимое имя стереотипа: "' . $name . '"'); 36 | } 37 | 38 | $this->name = $clearName; 39 | return $this; 40 | } 41 | 42 | /** 43 | * 44 | * @return string 45 | */ 46 | public function getName() 47 | { 48 | return $this->name; 49 | } 50 | 51 | /** 52 | * 53 | * @return \sufir\PlantUml\Diagram\Base\Skin 54 | */ 55 | public function getSkin() 56 | { 57 | return $this->skin; 58 | } 59 | 60 | /** 61 | * 62 | * @return string 63 | */ 64 | public function hasSkin() 65 | { 66 | return !!$this->skin; 67 | } 68 | 69 | /** 70 | * 71 | * @param \sufir\PlantUml\Diagram\Base\Skin $skin 72 | * @return \sufir\PlantUml\Diagram\Base\Stereotype 73 | */ 74 | public function setSkin(\sufir\PlantUml\Diagram\Base\Skin $skin) 75 | { 76 | $this->skin = $skin; 77 | return $this; 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /lib/Diagram/Component.php: -------------------------------------------------------------------------------- 1 | 22 | * @package sufir\PlantUml\Diagram 23 | */ 24 | class Component extends ADiagram 25 | { 26 | 27 | const NOTATION_UML1 = 'UML1'; 28 | const NOTATION_UML2 = 'UML2'; 29 | 30 | const ELEMENT_COMPONENT = 'component'; 31 | const ELEMENT_INTERFACE = 'interface'; 32 | const ELEMENT_USECASE = 'usecase'; 33 | const ELEMENT_ACTOR = 'actor'; 34 | const ELEMENT_PACKAGE = 'package'; 35 | const ELEMENT_NODE = 'node'; 36 | const ELEMENT_FOLDER = 'folder'; 37 | const ELEMENT_FRAME = 'frame'; 38 | const ELEMENT_CLOUD = 'cloud'; 39 | const ELEMENT_DATABASE = 'database'; 40 | const ELEMENT_RECTANGLE = 'rectangle'; 41 | 42 | protected $umlNotation = self::NOTATION_UML2; 43 | 44 | public function setUmlNotation($umlNotation) 45 | { 46 | if (!in_array(strtoupper($umlNotation), array(Component::NOTATION_UML1, Component::NOTATION_UML2))) { 47 | throw new \InvalidArgumentException('Недопустимое значение версии нотации UML: ' . $umlNotation); 48 | } 49 | 50 | $this->umlNotation = $umlNotation; 51 | 52 | return $this; 53 | } 54 | 55 | public function isSupported($element) 56 | { 57 | if ($element instanceof AElement) { 58 | $element = $element->getType(); 59 | } 60 | 61 | return in_array($element, array( 62 | Component::ELEMENT_ACTOR, 63 | Component::ELEMENT_CLOUD, 64 | Component::ELEMENT_COMPONENT, 65 | Component::ELEMENT_DATABASE, 66 | Component::ELEMENT_FOLDER, 67 | Component::ELEMENT_FRAME, 68 | Component::ELEMENT_INTERFACE, 69 | Component::ELEMENT_NODE, 70 | Component::ELEMENT_PACKAGE, 71 | Component::ELEMENT_RECTANGLE, 72 | )); 73 | } 74 | 75 | public function render() 76 | { 77 | $definition = "@startuml\n"; 78 | 79 | if ($this->scale && $this->scale != 1) { 80 | $definition .= "scale " . $this->scale . "\n"; 81 | } 82 | 83 | if (!$this->isStereotypeVisible()) { 84 | $definition .= "hide stereotype\n"; 85 | } 86 | 87 | if ($this->isOrientationVertical()) { 88 | $definition .= "left to right direction\n"; 89 | } 90 | 91 | if ($this->umlNotation) { 92 | $definition .= "skinparam componentStyle " . $this->umlNotation . "\n"; 93 | } 94 | 95 | if ($this->getTitle()) { 96 | $definition .= "title " . str_replace("\n", '\n', $this->getTitle()) . "\n"; 97 | } 98 | 99 | if ($this->getHeader()) { 100 | $definition .= "header\n" . $this->getHeader() . "\nendheader\n"; 101 | } 102 | 103 | if ($this->getFooter()) { 104 | $definition .= "footer\n" . $this->getFooter() . "\nendfooter\n"; 105 | } 106 | 107 | $definition .= "\n' Объявление элементов -------------------------------------------------------------------\n"; 108 | foreach ($this->elements as $element) { 109 | $definition .= $element->render(); 110 | } 111 | 112 | $definition .= "\n' Объявление отношений -------------------------------------------------------------------\n"; 113 | foreach ($this->relations as $relation) { 114 | $definition .= $relation->render(); 115 | } 116 | 117 | $definition .= "\n' Стилизация диаграммы -------------------------------------------------------------------\n"; 118 | foreach ($this->skins as $elementType => $skin) { 119 | $definition .= $this->renderSkin($skin, $elementType); 120 | } 121 | 122 | $definition .= "\n' Стили отдельных стереотипов\n"; 123 | $stereotypes = $this->findStereotypes($this->elements); 124 | //var_dump($stereotypes); die; 125 | 126 | foreach ($stereotypes as $elementType => $stereotypeList) { 127 | foreach ($stereotypeList as $stereotype) { 128 | if (!$stereotype->hasSkin()) { 129 | continue; 130 | } 131 | 132 | $definition .= $this->renderSkin($stereotype->getSkin(), $elementType, $stereotype->getName()); 133 | } 134 | } 135 | 136 | $definition .= "\n@enduml"; 137 | return $definition; 138 | } 139 | 140 | /** 141 | * @param Skin $skin 142 | * @param string $elementType 143 | * @param string $stereotypeName 144 | * @return string 145 | */ 146 | protected function renderSkin(Skin $skin, $elementType, $stereotypeName = null) 147 | { 148 | $elementType = ($elementType === '_MAIN_') ? '' : $elementType; 149 | 150 | $definition = "skinparam {$elementType} {\n"; 151 | 152 | foreach ($skin as $prop => $value) { 153 | if (is_bool($value)) { 154 | $value = ($value) ? 'true' : 'false'; 155 | } elseif (!$value) { 156 | continue; 157 | } 158 | 159 | $definition .= (!$stereotypeName) ? " {$prop} {$value}\n" : " {$prop}<<{$stereotypeName}>> {$value}\n"; 160 | } 161 | 162 | $definition .= "}\n"; 163 | return $definition; 164 | } 165 | 166 | /** 167 | * 168 | * @param AElement[] $elements 169 | * @param array $stereotypes 170 | * @return array 171 | */ 172 | protected function findStereotypes(array $elements, array &$stereotypes = array()) { 173 | 174 | foreach ($elements as $element) { 175 | 176 | if ($element instanceof ACompositeElement) { 177 | 178 | foreach ($element->getStereotypes() as $stereotype) { 179 | $stereotypes[$element->getType()][$stereotype->getName()] = $stereotype; 180 | } 181 | 182 | $this->findStereotypes($element->getChilds(), $stereotypes); 183 | 184 | } elseif ($element instanceof AElement) { 185 | 186 | foreach ($element->getStereotypes() as $stereotype) { 187 | $stereotypes[$element->getType()][$stereotype->getName()] = $stereotype; 188 | } 189 | 190 | } 191 | 192 | 193 | } 194 | 195 | return $stereotypes; 196 | } 197 | 198 | } 199 | -------------------------------------------------------------------------------- /lib/Diagram/Component/BaseCompositeElement.php: -------------------------------------------------------------------------------- 1 | 20 | * @package sufir\PlantUml\Diagram\Component 21 | */ 22 | class BaseCompositeElement extends ACompositeElement 23 | { 24 | 25 | public function getType() 26 | { 27 | $tmp = explode('\\', get_class($this)); 28 | 29 | return substr(strtolower(end($tmp)), 7); 30 | } 31 | 32 | public function render($offset = 0) 33 | { 34 | $definition = $this->getType() . ' "' . $this->getTitle() . '" as ' . $this->getUniqueId(); 35 | 36 | if (!empty($this->stereotypes)) { 37 | foreach ($this->stereotypes as $stereotype) { 38 | $definition .= ' <<' . $stereotype->getName() . '>>'; 39 | } 40 | } 41 | 42 | if ($this->getLink()) { 43 | $definition .= ' [[' . $this->getLink() . ']]'; 44 | } 45 | 46 | if ($this->getColor()) { 47 | 48 | if (strpos($this->getColor(), '#') !== 0) { 49 | $definition .= ' #' . $this->getColor(); 50 | } else { 51 | $definition .= ' ' . $this->getColor(); 52 | } 53 | 54 | } 55 | 56 | $definition = str_pad($definition, strlen($definition)+$offset, " ", STR_PAD_LEFT); 57 | 58 | if (!empty($this->elements)) { 59 | $definition .= " {\n"; 60 | 61 | foreach ($this->elements as $element) { 62 | $definition .= $element->render($offset+2); 63 | } 64 | 65 | $definition .= str_pad("}\n", strlen("}\n")+$offset, " ", STR_PAD_LEFT); 66 | } 67 | 68 | if ($this->getNote()) { 69 | $definition .= "\n" 70 | . str_pad("", $offset, " ", STR_PAD_LEFT) 71 | . "note {$this->notePosition} of " . $this->getUniqueId() . "\n" 72 | . trim($this->getNote()) . "\n" 73 | . str_pad("", $offset, " ", STR_PAD_LEFT) 74 | . "end note"; 75 | } 76 | 77 | return $definition . "\n"; 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /lib/Diagram/Component/BaseElement.php: -------------------------------------------------------------------------------- 1 | 20 | * @package sufir\PlantUml\Diagram\Component 21 | */ 22 | abstract class BaseElement extends AElement 23 | { 24 | 25 | public function getType() 26 | { 27 | $tmp = explode('\\', get_class($this)); 28 | 29 | return substr(strtolower(end($tmp)), 7); 30 | } 31 | 32 | public function render($offset = 0) 33 | { 34 | $definition = $this->getType() . ' "' . $this->getTitle() . '" as ' . $this->getUniqueId(); 35 | 36 | if (!empty($this->stereotypes)) { 37 | foreach ($this->stereotypes as $stereotype) { 38 | $definition .= ' <<' . $stereotype->getName() . '>>'; 39 | } 40 | } 41 | 42 | if ($this->getLink()) { 43 | $definition .= ' [[' . $this->getLink() . ']]'; 44 | } 45 | 46 | if ($this->getColor()) { 47 | 48 | if (strpos($this->getColor(), '#') !== 0) { 49 | $definition .= ' #' . $this->getColor(); 50 | } else { 51 | $definition .= ' ' . $this->getColor(); 52 | } 53 | 54 | } 55 | 56 | $definition = str_pad($definition, strlen($definition)+$offset, " ", STR_PAD_LEFT); 57 | 58 | if ($this->getNote()) { 59 | $definition .= "\n" 60 | . str_pad("", $offset, " ", STR_PAD_LEFT) 61 | . "note {$this->notePosition} of " . $this->getUniqueId() . "\n" 62 | . trim($this->getNote()) . "\n" 63 | . str_pad("", $offset, " ", STR_PAD_LEFT) 64 | . "end note"; 65 | } 66 | 67 | return $definition . "\n"; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /lib/Diagram/Component/ElementActor.php: -------------------------------------------------------------------------------- 1 | 18 | * @package sufir\PlantUml\Diagram\Component 19 | */ 20 | class ElementActor extends BaseElement 21 | { 22 | 23 | /*public function getType() 24 | { 25 | return 'actor'; 26 | }*/ 27 | 28 | } 29 | -------------------------------------------------------------------------------- /lib/Diagram/Component/ElementCloud.php: -------------------------------------------------------------------------------- 1 | 18 | * @package sufir\PlantUml\Diagram\Component 19 | */ 20 | class ElementCloud extends BaseCompositeElement 21 | { 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /lib/Diagram/Component/ElementComponent.php: -------------------------------------------------------------------------------- 1 | 18 | * @package sufir\PlantUml\Diagram\Component 19 | */ 20 | class ElementComponent extends BaseElement 21 | { 22 | public function getType() 23 | { 24 | return 'component'; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /lib/Diagram/Component/ElementDatabase.php: -------------------------------------------------------------------------------- 1 | 18 | * @package sufir\PlantUml\Diagram\Component 19 | */ 20 | class ElementDatabase extends BaseCompositeElement 21 | { 22 | 23 | } 24 | -------------------------------------------------------------------------------- /lib/Diagram/Component/ElementFolder.php: -------------------------------------------------------------------------------- 1 | 18 | * @package sufir\PlantUml\Diagram\Component 19 | */ 20 | class ElementFolder extends BaseCompositeElement 21 | { 22 | //put your code here 23 | } 24 | -------------------------------------------------------------------------------- /lib/Diagram/Component/ElementFrame.php: -------------------------------------------------------------------------------- 1 | 18 | * @package sufir\PlantUml\Diagram\Component 19 | */ 20 | class ElementFrame extends BaseCompositeElement 21 | { 22 | //put your code here 23 | } 24 | -------------------------------------------------------------------------------- /lib/Diagram/Component/ElementInterface.php: -------------------------------------------------------------------------------- 1 | 18 | * @package sufir\PlantUml\Diagram\Component 19 | */ 20 | class ElementInterface extends BaseElement 21 | { 22 | 23 | } 24 | -------------------------------------------------------------------------------- /lib/Diagram/Component/ElementNode.php: -------------------------------------------------------------------------------- 1 | 18 | * @package sufir\PlantUml\Diagram\Component 19 | */ 20 | class ElementNode extends BaseCompositeElement 21 | { 22 | //put your code here 23 | } 24 | -------------------------------------------------------------------------------- /lib/Diagram/Component/ElementPackage.php: -------------------------------------------------------------------------------- 1 | 18 | * @package sufir\PlantUml\Diagram\Component 19 | */ 20 | class ElementPackage extends BaseCompositeElement 21 | { 22 | //put your code here 23 | } 24 | -------------------------------------------------------------------------------- /lib/Diagram/Component/ElementRectangle.php: -------------------------------------------------------------------------------- 1 | 18 | * @package sufir\PlantUml\Diagram\Component 19 | */ 20 | class ElementRectangle extends BaseCompositeElement 21 | { 22 | //put your code here 23 | } 24 | -------------------------------------------------------------------------------- /lib/Diagram/Component/ElementUsecase.php: -------------------------------------------------------------------------------- 1 | 18 | * @package sufir\PlantUml\Diagram\Component 19 | */ 20 | class ElementUsecase extends BaseElement 21 | { 22 | 23 | } 24 | -------------------------------------------------------------------------------- /lib/PlantUml.php: -------------------------------------------------------------------------------- 1 | 24 | * @package sufir\PlantUml 25 | */ 26 | class PlantUml 27 | { 28 | 29 | const OUTPUT_FORMAT_PNG = 'png', 30 | OUTPUT_FORMAT_SVG = 'svg'; 31 | 32 | const DIAGRAM_COMPONENT = 'component'; 33 | 34 | /** 35 | * @var string 36 | */ 37 | protected $outputFormat = self::OUTPUT_FORMAT_SVG; 38 | 39 | /** 40 | * Создание связи между элементами 41 | * 42 | * @param \sufir\PlantUml\Diagram\Base\AElement $from 43 | * @param \sufir\PlantUml\Diagram\Base\AElement $to 44 | * @return \sufir\PlantUml\Diagram\Base\Relation 45 | */ 46 | public function createRelation(AElement $from = null, AElement $to = null) 47 | { 48 | return new Relation($from, $to); 49 | } 50 | 51 | /** 52 | * 53 | * @param string $diagramType 54 | * @param string $elementType 55 | * @param string $elementTitle 56 | * @return \sufir\PlantUml\Diagram\Base\AElement|\sufir\PlantUml\Diagram\Base\ACompositeElement 57 | * @throws \InvalidArgumentException 58 | */ 59 | public function createElement($diagramType, $elementType, $elementTitle) 60 | { 61 | $diagramClass = '\sufir\PlantUml\Diagram\\' . ucfirst($this->camelize($diagramType)); 62 | 63 | if (!class_exists($diagramClass)) { 64 | throw new \InvalidArgumentException('Неизвестный тип диаграммы: ' . $diagramType); 65 | } 66 | 67 | $elementClass = '\sufir\PlantUml\Diagram\\' . ucfirst($this->camelize($diagramType)) . '\\Element' . ucfirst($this->camelize($elementType)); 68 | 69 | if (!class_exists($elementClass)) { 70 | throw new \InvalidArgumentException('Неизвестный тип элемента диаграммы: ' . $elementType); 71 | } 72 | 73 | return new $elementClass($elementTitle); 74 | } 75 | 76 | /** 77 | * 78 | * @param string $diagramType 79 | * @return \sufir\PlantUml\Diagram\ADiagram 80 | * @throws \InvalidArgumentException 81 | */ 82 | public function createDiagram($diagramType) 83 | { 84 | $diagramClass = '\sufir\PlantUml\Diagram\\' . ucfirst($this->camelize($diagramType)); 85 | 86 | if (!class_exists($diagramClass)) { 87 | throw new \InvalidArgumentException('Неизвестный тип диаграммы: ' . $diagramType); 88 | } 89 | 90 | return new $diagramClass(); 91 | } 92 | 93 | /** 94 | * 95 | * @param string $name 96 | * @return \sufir\PlantUml\Diagram\Base\Stereotype 97 | */ 98 | public function createStereotype($name) 99 | { 100 | return new Stereotype($name); 101 | } 102 | 103 | /** 104 | * 105 | * @return \sufir\PlantUml\Diagram\Base\Skin 106 | */ 107 | public function createSkin() 108 | { 109 | return new Skin(); 110 | } 111 | 112 | /** 113 | * 114 | * @param string $outputFormat 115 | * @return \sufir\PlantUml\PlantUml 116 | */ 117 | public function setOutputFormat($outputFormat) 118 | { 119 | $this->outputFormat = strtolower($outputFormat); 120 | return $this; 121 | } 122 | 123 | /** 124 | * 125 | * @param \sufir\PlantUml\Diagram\ADiagram $diagram 126 | * @return string 127 | * 128 | * @param \sufir\PlantUml\Diagram\ADiagram $diagram 129 | * @param string|\sufir\PlantUml\Converter\IConverter $converter 130 | * @return string 131 | */ 132 | public function convertDiagram(ADiagram $diagram, $converter = 'LocalJar') 133 | { 134 | if (!is_object($converter)) { 135 | $converterClass = '\sufir\PlantUml\Converter\\' . ucfirst($this->camelize($converter)); 136 | 137 | if (!class_exists($converterClass)) { 138 | throw new \InvalidArgumentException('Класс конвертера не найден: ' . $converterClass); 139 | } 140 | 141 | $converter = new $converterClass; 142 | } 143 | 144 | if (!$converter instanceof \sufir\PlantUml\Converter\IConverter) { 145 | throw new \InvalidArgumentException('Класс конвертера должен имплементировать интерфейс IConverter: ' . get_class($converter)); 146 | } 147 | 148 | return $converter 149 | ->setOutputFormat($this->outputFormat) 150 | ->convertDiagram($diagram); 151 | } 152 | 153 | /** 154 | * Преобразует строку в lowerCamelCase 155 | * 156 | * @author Sklyarov Alexey 157 | * @param string $var 158 | * @return string 159 | */ 160 | protected static function camelize($var) { 161 | return lcfirst(str_replace(' ', '', ucwords(str_replace(array('_', '-'), ' ', $var)))); 162 | } 163 | 164 | } 165 | -------------------------------------------------------------------------------- /lib/bin/LICENSE: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | PlantUML : a free UML diagram generator 3 | ======================================================================== 4 | 5 | (C) Copyright 2009-2014, Arnaud Roques 6 | 7 | Project Info: http://plantuml.sourceforge.net 8 | 9 | PlantUML is free software; you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published by 11 | the Free Software Foundation, either version 3 of the License, or 12 | (at your option) any later version. 13 | 14 | PlantUML distributed in the hope that it will be useful, but 15 | WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 16 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 17 | License for more details. 18 | 19 | You should have received a copy of the GNU General Public 20 | License along with this library; if not, write to the Free Software 21 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 22 | USA. 23 | 24 | Note that images (whatever their format : PNG, SVG...) generated by running PlantUML 25 | are owned by the author of their corresponding sources code (that is, their 26 | textual description in PlantUML language). Those images are not covered by 27 | the GPL license. 28 | 29 | The generated images can then be used without any reference to the GPL license. 30 | It is not even necessary to stipulate that they have been generated with PlantUML, 31 | also this will be appreciate by PlantUML team. 32 | 33 | There is an exception : if the textual description in PlantUML language is also covered 34 | by a license (like the GPL), then the generated images are logically covered 35 | by the very same license. 36 | 37 | Icon provided by OpenIconic : https://useiconic.com/open/ -------------------------------------------------------------------------------- /lib/bin/plantuml.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sufir/php-plantuml-wrap/8ad9b76382740fe911343cc736ee02cc15fa599a/lib/bin/plantuml.jar --------------------------------------------------------------------------------