Completed
Push — master ( 04a4d1...1bb4b5 )
by Tom
01:56
created

Builder   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 99
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 12

Importance

Changes 5
Bugs 1 Features 0
Metric Value
wmc 24
c 5
b 1
f 0
lcom 1
cbo 12
dl 0
loc 99
rs 10

12 Methods

Rating   Name   Duplication   Size   Complexity  
A setTime() 0 3 1
A loadModule() 0 3 1
A doPostProcessing() 0 4 1
A __construct() 0 8 3
A addPath() 0 3 1
A setLocale() 0 4 1
A output() 0 22 3
A loadTemplate() 0 5 3
A loadTemplateFromFile() 0 4 3
A setCache() 0 3 1
A isValidDoc() 0 3 4
A __destruct() 0 4 2
1
<?php
2
/* @description     Transformation Style Sheets - Revolutionising PHP templating    *
3
 * @author          Tom Butler [email protected]                                             *
4
 * @copyright       2017 Tom Butler <[email protected]> | https://r.je/                      *
5
 * @license         http://www.opensource.org/licenses/bsd-license.php  BSD License *
6
 * @version         1.2                                                             */
7
namespace Transphporm;
8
/** Builds a Transphorm instance from the 3 constituent parts. XML template string, TSS string and data */
9
class Builder {
10
	private $template;
11
	private $tss;
12
	private $cache;
13
	private $time;
14
	private $modules = [];
15
	private $config;
16
	private $filePath;
17
	private $defaultModules = [
18
		'\\Transphporm\\Module\\Basics',
19
		'\\Transphporm\\Module\\Pseudo',
20
		'\\Transphporm\\Module\\Format',
21
		'\\Transphporm\\Module\\Functions'
22
	];
23
24
	public function __construct($template, $tss = '', $modules = null) {
25
		$this->template = $template;
26
		$this->tss = $tss;
27
		$this->cache = new Cache(new \ArrayObject());
28
		$this->filePath = new FilePath();
29
		$modules = is_array($modules) ? $modules : $this->defaultModules;
30
		foreach ($modules as $module) $this->loadModule(new $module);
31
	}
32
33
	//Allow setting the time used by Transphporm for caching. This is for testing purposes
34
	//Would be better if PHP allowed setting the script clock, but this is the simplest way of overriding it
35
	public function setTime($time) {
36
		$this->time = $time;
37
	}
38
39
	public function loadModule(Module $module) {
40
		$this->modules[get_class($module)] = $module;
41
	}
42
43
	public function setLocale($locale) {
44
                $format = new \Transphporm\Module\Format($locale);
45
                $this->modules[get_class($format)] = $format;
46
        }
47
48
	public function addPath($dir) {
49
		$this->filePath->addPath($dir);
50
	}
51
52
	public function output($data = null, $document = false) {
53
		$headers = [];
54
55
		$elementData = new \Transphporm\Hook\ElementData(new \SplObjectStorage(), $data);
56
		$functionSet = new FunctionSet($elementData);
57
58
		$cachedOutput = $this->loadTemplate();
59
		//To be a valid XML document it must have a root element, automatically wrap it in <template> to ensure it does
60
		$template = new Template($this->isValidDoc($cachedOutput['body']) ? str_ireplace('<!doctype', '<!DOCTYPE', $cachedOutput['body']) : '<template>' . $cachedOutput['body'] . '</template>' );
61
		$tssCache = new SheetLoader($this->cache,  $this->filePath, $this->tss, $template->getPrefix(), $this->time);
62
		$valueParser = new Parser\Value($functionSet);
63
		$this->config = new Config($functionSet, $valueParser, $elementData, new Hook\Formatter(), new Parser\CssToXpath($functionSet, $template->getPrefix(), md5($this->tss)), $this->filePath, $headers);
64
65
		foreach ($this->modules as $module) $module->load($this->config);
66
67
		$tssCache->processRules($template, $this->config);
68
69
		$result = ['body' => $template->output($document), 'headers' => array_merge($cachedOutput['headers'], $headers)];
70
		$this->cache->write($this->template, $result);
71
		$result['body'] = $this->doPostProcessing($template)->output($document);
72
		return (object) $result;
73
	}
74
75
76
	//Add a postprocessing hook. This cleans up anything transphporm has added to the markup which needs to be removed
77
	private function doPostProcessing($template) {
78
		$template->addHook('//*[@transphporm]', new Hook\PostProcess());
79
		return $template;
80
	}
81
82
83
	//Load a template, firstly check if it's a file or a valid string
84
	private function loadTemplate() {
85
        $result = ['body' => $this->template, 'headers' => []];
86
		if (strpos($this->template, "\n") === false && is_file($this->template)) $result = $this->loadTemplateFromFile($this->template);
87
		return $result;
88
	}
89
90
    private function loadTemplateFromFile($file) {
0 ignored issues
show
Unused Code introduced by
The parameter $file is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
91
        $xml = $this->cache->load($this->template, filemtime($this->template));
92
        return $xml ? $xml : ['body' => file_get_contents($this->template) ?: "", 'headers' => []];
93
    }
94
95
	public function setCache(\ArrayAccess $cache) {
96
		$this->cache = new Cache($cache);
97
	}
98
99
	private function isValidDoc($xml) {
100
		return (strpos($xml, '<!') === 0 && strpos($xml, '<!--') !== 0) || strpos($xml, '<?') === 0 || strpos($xml, '<html') === 0;
101
	}
102
103
	public function __destruct() {
104
		//Required hack as DomXPath can only register static functions clear the statically stored instance to avoid memory leaks
105
		if (isset($this->config)) $this->config->getCssToXpath()->cleanup();
106
	}
107
}
108