-
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a new exporter GvConvert to export a Graphviz script into another…
… format.
- Loading branch information
Showing
3 changed files
with
206 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
<?php | ||
|
||
declare(strict_types = 1); | ||
|
||
namespace spec\drupol\phptree\Exporter; | ||
|
||
use drupol\phptree\Exporter\GvConvert; | ||
use drupol\phptree\Node\ValueNode; | ||
use PhpSpec\ObjectBehavior; | ||
|
||
class GvConvertSpec extends ObjectBehavior | ||
{ | ||
public function it_can_convert_a_tree_into_a_file() | ||
{ | ||
$tree = new ValueNode('root'); | ||
|
||
$this | ||
->export($tree) | ||
->shouldBeString(); | ||
} | ||
|
||
public function it_can_set_and_get_the_executable() | ||
{ | ||
$this | ||
->getExecutable() | ||
->shouldBe('dot'); | ||
|
||
$this | ||
->setExecutable('foo') | ||
->shouldReturn($this); | ||
|
||
$this | ||
->getExecutable() | ||
->shouldBe('foo'); | ||
} | ||
|
||
public function it_can_set_and_get_the_format() | ||
{ | ||
$this | ||
->getFormat() | ||
->shouldReturn('svg'); | ||
|
||
$this | ||
->setFormat('png') | ||
->shouldReturn($this); | ||
|
||
$this | ||
->getFormat() | ||
->shouldReturn('png'); | ||
} | ||
public function it_is_initializable() | ||
{ | ||
$this->shouldHaveType(GvConvert::class); | ||
|
||
$this | ||
->getExecutable() | ||
->shouldReturn('dot'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
<?php | ||
|
||
declare(strict_types = 1); | ||
|
||
namespace drupol\phptree\Exporter; | ||
|
||
use drupol\phptree\Node\NodeInterface; | ||
|
||
/** | ||
* Class GvConvert. | ||
*/ | ||
class GvConvert extends Gv | ||
{ | ||
/** | ||
* @var string | ||
*/ | ||
private $executable = 'dot'; | ||
/** | ||
* @var string | ||
*/ | ||
private $format = 'svg'; | ||
|
||
/** | ||
* GvDisplay constructor. | ||
*/ | ||
public function __construct() | ||
{ | ||
if (0 === \stripos(PHP_OS, 'WIN')) { | ||
$this->executable = 'dot.exe'; | ||
} | ||
} | ||
|
||
/** | ||
* @param \drupol\phptree\Node\NodeInterface $node | ||
* | ||
* @throws \Exception | ||
* | ||
* @return string | ||
*/ | ||
public function export(NodeInterface $node): string | ||
{ | ||
$path = $this->getTemporaryFile(); | ||
|
||
$this->writeToFile($path, parent::export($node)); | ||
|
||
\system($this->getConvertCommand($path)); | ||
|
||
return \sprintf('%s.%s', $path, $this->getFormat()); | ||
} | ||
|
||
/** | ||
* Get the executable to use. | ||
* | ||
* @return string | ||
*/ | ||
public function getExecutable(): string | ||
{ | ||
return $this->executable; | ||
} | ||
|
||
/** | ||
* @return string | ||
*/ | ||
public function getFormat(): string | ||
{ | ||
return $this->format; | ||
} | ||
|
||
/** | ||
* Change the executable to use. | ||
* | ||
* @param string $executable | ||
* | ||
* @return \drupol\phptree\Exporter\GvConvert | ||
*/ | ||
public function setExecutable(string $executable): GvConvert | ||
{ | ||
$this->executable = $executable; | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* @param string $format | ||
* | ||
* @return \drupol\phptree\Exporter\GvConvert | ||
*/ | ||
public function setFormat(string $format): GvConvert | ||
{ | ||
$this->format = $format; | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* @param string $path | ||
* | ||
* @return string | ||
*/ | ||
private function getConvertCommand(string $path): string | ||
{ | ||
return \sprintf( | ||
'%s -T%s %s -o %s.%s', | ||
$this->getExecutable(), | ||
$this->getFormat(), | ||
$path, | ||
$path, | ||
$this->getFormat() | ||
); | ||
} | ||
|
||
/** | ||
* @throws \Exception | ||
* | ||
* @return string | ||
*/ | ||
private function getTemporaryFile(): string | ||
{ | ||
$path = \tempnam(\sys_get_temp_dir(), 'graphviz'); | ||
|
||
if (false === $path) { | ||
throw new \Exception('Unable to get temporary file name for graphviz script'); | ||
} | ||
|
||
return $path; | ||
} | ||
|
||
/** | ||
* @param string $path | ||
* @param string $content | ||
* | ||
* @throws \Exception | ||
* | ||
* @return bool | ||
*/ | ||
private function writeToFile(string $path, string $content): bool | ||
{ | ||
$ret = \file_put_contents($path, $content, LOCK_EX); | ||
|
||
if (false === $ret) { | ||
throw new \Exception('Unable to write graphviz script to temporary file'); | ||
} | ||
|
||
return true; | ||
} | ||
} |