izzum\statemachine\utils\PlantUml::createStateDiagram PHP Метод

createStateDiagram() публичный Метод

creates plantuml state output for a statemachine
public createStateDiagram ( StateMachine $machine ) : string
$machine izzum\statemachine\StateMachine
Результат string plant uml code, this can be used to render an image
    public function createStateDiagram(StateMachine $machine)
    {
        $transitions = $machine->getTransitions();
        // all states are aliased so the plantuml parser can handle the names
        $aliases = array();
        $end_states = array();
        $EOL = "\\n\\" . PHP_EOL;
        /* for multiline stuff in plantuml */
        $NEWLINE = PHP_EOL;
        // start with declaration
        $uml = "@startuml" . PHP_EOL;
        // skins for colors etc.
        $uml .= $this->getPlantUmlSkins() . PHP_EOL;
        // the order in which transitions are executed
        $order = array();
        // create the diagram by drawing all transitions
        foreach ($transitions as $t) {
            // get states and state aliases (plantuml cannot work with certain
            // characters, so therefore we create an alias for the state name)
            $from = $t->getStateFrom();
            $from_alias = $this->plantUmlStateAlias($from->getName());
            $to = $t->getStateTo();
            $to_alias = $this->plantUmlStateAlias($to->getName());
            // get some names to display
            $command = $t->getCommandName();
            $rule = self::escape($t->getRuleName());
            $name_transition = $t->getName();
            $description = $t->getDescription() ? "description: '" . $t->getDescription() . "'" . $EOL : '';
            $event = $t->getEvent() ? "event: '" . $t->getEvent() . "'" . $EOL : '';
            $f_description = $from->getDescription();
            $t_description = $to->getDescription();
            $f_exit = $from->getExitCommandName();
            $f_entry = $from->getEntryCommandName();
            $t_exit = $to->getExitCommandName();
            $t_entry = $to->getEntryCommandName();
            // only write aliases if not done before
            if (!isset($aliases[$from_alias])) {
                $uml .= 'state "' . $from . '" as ' . $from_alias . PHP_EOL;
                $uml .= "{$from_alias}: description: '" . $f_description . "'" . PHP_EOL;
                $uml .= "{$from_alias}: entry / '" . $f_entry . "'" . PHP_EOL;
                $uml .= "{$from_alias}: exit / '" . $f_exit . "'" . PHP_EOL;
                $aliases[$from_alias] = $from_alias;
            }
            // store order in which transitions will be handled
            if (!isset($order[$from_alias])) {
                $order[$from_alias] = 1;
            } else {
                $order[$from_alias] = $order[$from_alias] + 1;
            }
            // get 'to' alias
            if (!isset($aliases[$to_alias])) {
                $uml .= 'state "' . $to . '" as ' . $to_alias . PHP_EOL;
                $aliases[$to_alias] = $to_alias;
                $uml .= "{$to_alias}: description: '" . $t_description . "'" . PHP_EOL;
                $uml .= "{$to_alias}: entry / '" . $t_entry . "'" . PHP_EOL;
                $uml .= "{$to_alias}: exit / '" . $t_exit . "'" . PHP_EOL;
            }
            // write transition information
            $uml .= $from_alias . ' --> ' . $to_alias;
            $uml .= " : <b><size:10>{$name_transition}</size></b>" . $EOL;
            $uml .= $event;
            $uml .= "transition order from '{$from}': <b>" . $order[$from_alias] . "</b>" . $EOL;
            $uml .= "rule/guard: '{$rule}'" . $EOL;
            $uml .= "command/action: '{$command}'" . $EOL;
            $uml .= $description;
            $uml .= PHP_EOL;
            // store possible end states aliases
            if ($t->getStateFrom()->isFinal()) {
                $end_states[$from_alias] = $from_alias;
            }
            if ($t->getStateTo()->isFinal()) {
                $end_states[$to_alias] = $to_alias;
            }
        }
        // only one begin state
        $initial = $machine->getInitialState();
        $initial = $initial->getName();
        $initial_alias = $this->plantUmlStateAlias($initial);
        if (!isset($aliases[$initial_alias])) {
            $uml .= 'state "' . $initial . '" as ' . $initial_alias . PHP_EOL;
        }
        $uml .= "[*] --> {$initial_alias}" . PHP_EOL;
        // note for initial alias with explanation
        $uml .= "note right of {$initial_alias} {$NEWLINE}";
        $uml .= "state diagram for machine '" . $machine->getContext()->getMachine() . "'{$NEWLINE}";
        $uml .= "created by izzum plantuml generator {$NEWLINE}";
        $uml .= "@link http://plantuml.sourceforge.net/state.html\"" . $NEWLINE;
        $uml .= "end note" . $NEWLINE;
        // add end states to diagram
        foreach ($end_states as $end) {
            $uml .= "{$end} --> [*]" . PHP_EOL;
        }
        // close plantuml
        $uml .= "@enduml" . PHP_EOL;
        return $uml;
    }

Usage Example

use izzum\statemachine\utils\PlantUml;
require_once '../autoload.php';
/**
 * Example script that uses the 'delegation mode' as one of the four usage models for the statemachine.
 * The other three usage models being inheritance, composition and standalone.
 *
 * This example shows the usage of using a factory to get the machine and makes use of Rules and Command classes.
 * This is the most formal way to use the statemachine:
 * using domain models/rules/commands that are tested seperately and strong use of polymorphism and uniformity of code
 * by using these rules and commands.
 *
 * run this script from the command line:
 * php -f index.php
 * and stop it with ctrl+c
 */
//create the factory
$factory = new TrafficLightFactory();
//get the machine from the factory, for traffic light 1
$machine = $factory->getStateMachine(1);
//generate the uml diagram
$uml = new PlantUml();
$output = $uml->createStateDiagram($machine);
echo PHP_EOL . PHP_EOL . PHP_EOL;
echo $output;
echo PHP_EOL . PHP_EOL . PHP_EOL;
//loop the machine
while (true) {
    $machine->run();
    sleep(1);
}