Skip to content

Commit aaa6af7

Browse files
committed
Add a new exporter GvConvert to export a Graphviz script into another format.
1 parent 5ba5f85 commit aaa6af7

File tree

3 files changed

+206
-0
lines changed

3 files changed

+206
-0
lines changed

composer.json

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"php": ">=7.1"
2020
},
2121
"require-dev": {
22+
"drupol/launcher": "^1.0",
2223
"drupol/php-conventions": "^1",
2324
"drupol/phpspec-annotation": "^1",
2425
"graphp/graphviz": "^0.2",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace spec\drupol\phptree\Exporter;
6+
7+
use drupol\phptree\Exporter\GvConvert;
8+
use drupol\phptree\Node\ValueNode;
9+
use PhpSpec\ObjectBehavior;
10+
11+
class GvConvertSpec extends ObjectBehavior
12+
{
13+
public function it_can_convert_a_tree_into_a_file()
14+
{
15+
$tree = new ValueNode('root');
16+
17+
$this
18+
->export($tree)
19+
->shouldBeString();
20+
}
21+
22+
public function it_can_set_and_get_the_executable()
23+
{
24+
$this
25+
->getExecutable()
26+
->shouldBe('dot');
27+
28+
$this
29+
->setExecutable('foo')
30+
->shouldReturn($this);
31+
32+
$this
33+
->getExecutable()
34+
->shouldBe('foo');
35+
}
36+
37+
public function it_can_set_and_get_the_format()
38+
{
39+
$this
40+
->getFormat()
41+
->shouldReturn('svg');
42+
43+
$this
44+
->setFormat('png')
45+
->shouldReturn($this);
46+
47+
$this
48+
->getFormat()
49+
->shouldReturn('png');
50+
}
51+
public function it_is_initializable()
52+
{
53+
$this->shouldHaveType(GvConvert::class);
54+
55+
$this
56+
->getExecutable()
57+
->shouldReturn('dot');
58+
}
59+
}

src/Exporter/GvConvert.php

+146
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
namespace drupol\phptree\Exporter;
6+
7+
use drupol\phptree\Node\NodeInterface;
8+
9+
/**
10+
* Class GvConvert.
11+
*/
12+
class GvConvert extends Gv
13+
{
14+
/**
15+
* @var string
16+
*/
17+
private $executable = 'dot';
18+
/**
19+
* @var string
20+
*/
21+
private $format = 'svg';
22+
23+
/**
24+
* GvDisplay constructor.
25+
*/
26+
public function __construct()
27+
{
28+
if (0 === \stripos(PHP_OS, 'WIN')) {
29+
$this->executable = 'dot.exe';
30+
}
31+
}
32+
33+
/**
34+
* @param \drupol\phptree\Node\NodeInterface $node
35+
*
36+
* @throws \Exception
37+
*
38+
* @return string
39+
*/
40+
public function export(NodeInterface $node): string
41+
{
42+
$path = $this->getTemporaryFile();
43+
44+
$this->writeToFile($path, parent::export($node));
45+
46+
\system($this->getConvertCommand($path));
47+
48+
return \sprintf('%s.%s', $path, $this->getFormat());
49+
}
50+
51+
/**
52+
* Get the executable to use.
53+
*
54+
* @return string
55+
*/
56+
public function getExecutable(): string
57+
{
58+
return $this->executable;
59+
}
60+
61+
/**
62+
* @return string
63+
*/
64+
public function getFormat(): string
65+
{
66+
return $this->format;
67+
}
68+
69+
/**
70+
* Change the executable to use.
71+
*
72+
* @param string $executable
73+
*
74+
* @return \drupol\phptree\Exporter\GvConvert
75+
*/
76+
public function setExecutable(string $executable): GvConvert
77+
{
78+
$this->executable = $executable;
79+
80+
return $this;
81+
}
82+
83+
/**
84+
* @param string $format
85+
*
86+
* @return \drupol\phptree\Exporter\GvConvert
87+
*/
88+
public function setFormat(string $format): GvConvert
89+
{
90+
$this->format = $format;
91+
92+
return $this;
93+
}
94+
95+
/**
96+
* @param string $path
97+
*
98+
* @return string
99+
*/
100+
private function getConvertCommand(string $path): string
101+
{
102+
return \sprintf(
103+
'%s -T%s %s -o %s.%s',
104+
$this->getExecutable(),
105+
$this->getFormat(),
106+
$path,
107+
$path,
108+
$this->getFormat()
109+
);
110+
}
111+
112+
/**
113+
* @throws \Exception
114+
*
115+
* @return string
116+
*/
117+
private function getTemporaryFile(): string
118+
{
119+
$path = \tempnam(\sys_get_temp_dir(), 'graphviz');
120+
121+
if (false === $path) {
122+
throw new \Exception('Unable to get temporary file name for graphviz script');
123+
}
124+
125+
return $path;
126+
}
127+
128+
/**
129+
* @param string $path
130+
* @param string $content
131+
*
132+
* @throws \Exception
133+
*
134+
* @return bool
135+
*/
136+
private function writeToFile(string $path, string $content): bool
137+
{
138+
$ret = \file_put_contents($path, $content, LOCK_EX);
139+
140+
if (false === $ret) {
141+
throw new \Exception('Unable to write graphviz script to temporary file');
142+
}
143+
144+
return true;
145+
}
146+
}

0 commit comments

Comments
 (0)