Skip to content

Commit

Permalink
Add a new exporter GvConvert to export a Graphviz script into another…
Browse files Browse the repository at this point in the history
… format.
  • Loading branch information
drupol committed Jul 2, 2019
1 parent 5ba5f85 commit aaa6af7
Show file tree
Hide file tree
Showing 3 changed files with 206 additions and 0 deletions.
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"php": ">=7.1"
},
"require-dev": {
"drupol/launcher": "^1.0",
"drupol/php-conventions": "^1",
"drupol/phpspec-annotation": "^1",
"graphp/graphviz": "^0.2",
Expand Down
59 changes: 59 additions & 0 deletions spec/drupol/phptree/Exporter/GvConvertSpec.php
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');
}
}
146 changes: 146 additions & 0 deletions src/Exporter/GvConvert.php
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;
}
}

0 comments on commit aaa6af7

Please sign in to comment.