/** * Render state diagram */ public static function renderStateMachine(\Smalldb\StateMachine\AbstractBackend $smalldb, $machine, $format) { $dot = $smalldb->getMachine($machine)->exportDot(); if ($format == 'dot') { header('Content-Type: text/plain; encoding=utf8'); echo $dot; } else { if ($format == 'png' || $format == 'pdf' || $format == 'svg') { $image = FALSE; // Check cache $dot_hash = md5($dot) . '_' . $format; if (function_exists('apcu_fetch')) { $image = apcu_fetch($dot_hash); } if ($image === FALSE) { // Render diagram using Graphviz $p = proc_open('dot -T' . $format, [['pipe', 'r'], ['pipe', 'wb'], ['file', 'php://stdout', 'a']], $fp); fwrite($fp[0], $dot); fclose($fp[0]); $image = stream_get_contents($fp[1]); fclose($fp[1]); $err = proc_close($p); if ($err != 0) { // Failed - drop corrupt image data $image = FALSE; } else { if (function_exists('apcu_store')) { // Store image in cache apcu_store($dot_hash, $image, 3600); } } } if ($image) { // Send image switch ($format) { case 'png': header('Content-Type: image/png'); break; case 'svg': header('Content-Type: image/svg+xml'); break; case 'pdf': header('Content-Type: application/pdf'); break; } echo $image; } } else { throw new \InvalidArgumentException('Unknown format'); } } }