diff --git a/spec/Fixtures/invalid_template/plastic.svg b/spec/Fixtures/invalid_template/plastic.svg
new file mode 100644
index 0000000..94b2a65
--- /dev/null
+++ b/spec/Fixtures/invalid_template/plastic.svg
@@ -0,0 +1,13 @@
+
diff --git a/spec/Fixtures/xml_template/plastic.svg b/spec/Fixtures/xml_template/plastic.svg
new file mode 100644
index 0000000..0ec2225
--- /dev/null
+++ b/spec/Fixtures/xml_template/plastic.svg
@@ -0,0 +1,26 @@
+
+
+
+ PHP: Behind the Parser
+
+
+ Ms. Coder
+ Onlivia Actora
+
+
+ Mr. Coder
+ El ActÓr
+
+
+
+ So, this language. It's like, a programming language. Or is it a
+ scripting language? All is revealed in this thrilling horror spoof
+ of a documentary.
+
+
+ PHP solves all my web problems
+
+ 7
+ 5
+
+
diff --git a/spec/PUGX/Poser/Render/SvgRenderSpec.php b/spec/PUGX/Poser/Render/SvgRenderSpec.php
index 34e54f9..50dc13c 100644
--- a/spec/PUGX/Poser/Render/SvgRenderSpec.php
+++ b/spec/PUGX/Poser/Render/SvgRenderSpec.php
@@ -21,6 +21,22 @@ function it_should_render_a_svg()
$this->render($badge)->shouldBeAValidSVGImage();
}
+ function it_should_not_render_an_invalid_svg($calculator)
+ {
+ $templatesDir = __DIR__ . '/../../../Fixtures/invalid_template';
+ $this->beConstructedWith($calculator, $templatesDir);
+ $badge = Badge::fromURI('version-stable-97CA00.svg');
+ $this->shouldThrow(new \RuntimeException('Generated string is not a valid XML'))->duringRender($badge);
+ }
+
+ function it_should_not_render_non_svg_xml($calculator)
+ {
+ $templatesDir = __DIR__ . '/../../../Fixtures/xml_template';
+ $this->beConstructedWith($calculator, $templatesDir);
+ $badge = Badge::fromURI('version-stable-97CA00.svg');
+ $this->shouldThrow(new \RuntimeException('Generated xml is not a SVG'))->duringRender($badge);
+ }
+
public function getMatchers()
{
return array(
diff --git a/src/Render/LocalSvgRenderer.php b/src/Render/LocalSvgRenderer.php
index bb0b039..5d37ec3 100644
--- a/src/Render/LocalSvgRenderer.php
+++ b/src/Render/LocalSvgRenderer.php
@@ -15,6 +15,7 @@
use PUGX\Poser\Calculator\GDTextSizeCalculator;
use PUGX\Poser\Calculator\TextSizeCalculatorInterface;
use PUGX\Poser\Image;
+use SimpleXMLElement;
/**
* Local SVG renderer.
@@ -31,16 +32,26 @@ abstract class LocalSvgRenderer implements RenderInterface
*/
private $textSizeCalculator;
+ /**
+ * @var string
+ */
+ private $templatesDirectory;
+
/**
* @param TextSizeCalculatorInterface $textSizeCalculator
+ * @param null|string $templatesDirectory
*/
- public function __construct(TextSizeCalculatorInterface $textSizeCalculator = null)
+ public function __construct(TextSizeCalculatorInterface $textSizeCalculator = null, $templatesDirectory = null)
{
$this->textSizeCalculator = $textSizeCalculator;
-
if (null === $this->textSizeCalculator) {
$this->textSizeCalculator = new GDTextSizeCalculator();
}
+
+ $this->templatesDirectory = $templatesDirectory;
+ if (null === $this->templatesDirectory) {
+ $this->templatesDirectory = __DIR__ . '/../Resources/templates';;
+ }
}
/**
@@ -50,7 +61,7 @@ public function __construct(TextSizeCalculatorInterface $textSizeCalculator = nu
*/
public function render(Badge $badge)
{
- $template = $this->getTemplate($this->getTemplateName());
+ $template = $this->getTemplate($this->getTemplateName());
$parameters = $this->buildParameters($badge);
return $this->renderSvg($template, $parameters, $badge->getFormat());
@@ -68,8 +79,7 @@ abstract protected function getTemplateName();
*/
private function getTemplate($format)
{
- $templatesDirectory = __DIR__ . '/../Resources/templates';
- $filepath = sprintf('%s/%s.svg', $templatesDirectory, $format);
+ $filepath = sprintf('%s/%s.svg', $this->templatesDirectory, $format);
if (!file_exists($filepath)) {
throw new \InvalidArgumentException(sprintf('No template for format %s', $format));
@@ -90,7 +100,7 @@ private function stringWidth($text)
/**
* @param string $render
- * @param array $parameters
+ * @param array $parameters
* @param string $format
*
* @return Image
@@ -101,11 +111,13 @@ private function renderSvg($render, $parameters, $format)
$render = str_replace(sprintf('{{ %s }}', $key), $variable, $render);
}
- // validate svg
- libxml_use_internal_errors(true);
- $xml = simplexml_load_string($render);
- if (false === $xml) {
- throw new \RuntimeException('Generated string is not a valid SVG');
+ try {
+ $xml = new SimpleXMLElement($render);
+ } catch (\Exception $e) {
+ throw new \RuntimeException('Generated string is not a valid XML');
+ }
+ if ('svg' !== $xml->getName()) {
+ throw new \RuntimeException('Generated xml is not a SVG');
}
return Image::createFromString($render, $format);
@@ -120,15 +132,15 @@ private function buildParameters(Badge $badge)
{
$parameters = array();
- $parameters['vendorWidth'] = $this->stringWidth($badge->getSubject());
- $parameters['valueWidth'] = $this->stringWidth($badge->getStatus());
- $parameters['totalWidth'] = $parameters['valueWidth'] + $parameters['vendorWidth'];
- $parameters['vendorColor'] = static::VENDOR_COLOR;
- $parameters['valueColor'] = $badge->getHexColor();
- $parameters['vendor'] = $badge->getSubject();
- $parameters['value'] = $badge->getStatus();
+ $parameters['vendorWidth'] = $this->stringWidth($badge->getSubject());
+ $parameters['valueWidth'] = $this->stringWidth($badge->getStatus());
+ $parameters['totalWidth'] = $parameters['valueWidth'] + $parameters['vendorWidth'];
+ $parameters['vendorColor'] = static::VENDOR_COLOR;
+ $parameters['valueColor'] = $badge->getHexColor();
+ $parameters['vendor'] = $badge->getSubject();
+ $parameters['value'] = $badge->getStatus();
$parameters['vendorStartPosition'] = round($parameters['vendorWidth'] / 2, 1) + 1;
- $parameters['valueStartPosition'] = $parameters['vendorWidth'] + round($parameters['valueWidth'] / 2, 1) - 1;
+ $parameters['valueStartPosition'] = $parameters['vendorWidth'] + round($parameters['valueWidth'] / 2, 1) - 1;
return $parameters;
}