Completed
Push — master ( a8174f...1052a1 )
by Josh
13:43
created

Repository::get()   B

Complexity

Conditions 7
Paths 19

Size

Total Lines 63
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 30
CRAP Score 7

Importance

Changes 0
Metric Value
dl 0
loc 63
ccs 30
cts 30
cp 1
rs 7.2689
c 0
b 0
f 0
cc 7
eloc 31
nc 19
nop 2
crap 7

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
* @package   s9e\TextFormatter
5
* @copyright Copyright (c) 2010-2018 The s9e Authors
6
* @license   http://www.opensource.org/licenses/mit-license.php The MIT License
7
*/
8
namespace s9e\TextFormatter\Plugins\BBCodes\Configurator;
9
10
use DOMDocument;
11
use DOMElement;
12
use DOMXPath;
13
use InvalidArgumentException;
14
use RuntimeException;
15
16
class Repository
17
{
18
	/**
19
	* @var BBCodeMonkey Instance of BBCodeMonkey used to parse definitions
20
	*/
21
	protected $bbcodeMonkey;
22
23
	/**
24
	* @var DOMDocument Repository document
25
	*/
26
	protected $dom;
27
28
	/**
29
	* Constructor
30
	*
31
	* @param  mixed        $value        Either a DOMDocument or the path to a repository's XML file
32
	* @param  BBCodeMonkey $bbcodeMonkey Instance of BBCodeMonkey used to parse definitions
33
	*/
34 14
	public function __construct($value, BBCodeMonkey $bbcodeMonkey)
35
	{
36 14
		$this->bbcodeMonkey = $bbcodeMonkey;
37 14
		$this->dom          = ($value instanceof DOMDocument) ? $value : $this->loadRepository($value);
38 12
	}
39
40
	/**
41
	* Get a BBCode and its associated tag from this repository
42
	*
43
	* @param  string $name Name of the entry in the repository
44
	* @param  array  $vars Replacement variables
45
	* @return array        Array with three elements: "bbcode", "name" and "tag"
46
	*/
47 10
	public function get($name, array $vars = [])
48
	{
49 10
		$name  = BBCode::normalizeName($name);
50 10
		$xpath = new DOMXPath($this->dom);
51 10
		$node  = $xpath->query('//bbcode[@name="' . $name . '"]')->item(0);
52
53 10
		if (!($node instanceof DOMElement))
54
		{
55 1
			throw new RuntimeException("Could not find '" . $name . "' in repository");
56
		}
57
58
		// Clone the node so we don't end up modifying the node in the repository
59 9
		$clonedNode = $node->cloneNode(true);
60
61
		// Replace all the <var> descendants if applicable
62 9
		foreach ($xpath->query('.//var', $clonedNode) as $varNode)
63
		{
64 5
			$varName = $varNode->getAttribute('name');
65
66 5
			if (isset($vars[$varName]))
67
			{
68 4
				$varNode->parentNode->replaceChild(
69 4
					$this->dom->createTextNode($vars[$varName]),
70 5
					$varNode
71
				);
72
			}
73
		}
74
75
		// Now we can parse the BBCode usage and prepare the template.
76
		// Grab the content of the <usage> element then use BBCodeMonkey to parse it
77 9
		$usage      = $xpath->evaluate('string(usage)', $clonedNode);
78 9
		$template   = $xpath->evaluate('string(template)', $clonedNode);
79 9
		$config     = $this->bbcodeMonkey->create($usage, $template);
80 9
		$bbcode     = $config['bbcode'];
81 9
		$bbcodeName = $config['bbcodeName'];
82 9
		$tag        = $config['tag'];
83
84
		// Set the optional tag name
85 9
		if ($node->hasAttribute('tagName'))
86
		{
87 1
			$bbcode->tagName = $node->getAttribute('tagName');
88
		}
89
90
		// Set the rules
91 9
		foreach ($xpath->query('rules/*', $node) as $ruleNode)
92
		{
93 2
			$methodName = $ruleNode->nodeName;
94 2
			$args       = [];
95
96 2
			if ($ruleNode->textContent)
97
			{
98 1
				$args[] = $ruleNode->textContent;
99
			}
100
101 2
			call_user_func_array([$tag->rules, $methodName], $args);
102
		}
103
104
		return [
105 9
			'bbcode'     => $bbcode,
106 9
			'bbcodeName' => $bbcodeName,
107 9
			'tag'        => $tag
108
		];
109
	}
110
111
	/**
112
	* Create an exception for a bad repository file path
113
	*
114
	* @param  mixed $filepath
115
	* @return InvalidArgumentException
116
	*/
117 2
	protected function createRepositoryException($filepath)
118
	{
119 2
		return new InvalidArgumentException(var_export($filepath, true) . ' is not a valid BBCode repository file');
120
	}
121
122
	/**
123
	* Load a repository file into a DOMDocument
124
	*
125
	* @param  string $filepath
126
	* @return DOMDocument
127
	*/
128 5
	protected function loadRepository($filepath)
129
	{
130 5
		if (!file_exists($filepath))
131
		{
132 1
			throw $this->createRepositoryException($filepath);
133
		}
134
135 4
		$dom = new DOMDocument;
136 4
		$dom->preserveWhiteSpace = false;
137 4
		if (!$dom->loadXML(file_get_contents($filepath), LIBXML_NOERROR))
138
		{
139 1
			throw $this->createRepositoryException($filepath);
140
		}
141
142 3
		return $dom;
143
	}
144
}