Completed
Push — master ( 8eb698...a673ca )
by Alexander
02:26
created

PathsRevisionLogPlugin::getLastRevision()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2
Metric Value
dl 0
loc 10
ccs 5
cts 5
cp 1
rs 9.4285
cc 2
eloc 5
nc 2
nop 0
crap 2
1
<?php
2
/**
3
 * This file is part of the SVN-Buddy library.
4
 * For the full copyright and license information, please view
5
 * the LICENSE file that was distributed with this source code.
6
 *
7
 * @copyright Alexander Obuhovich <[email protected]>
8
 * @link      https://github.com/console-helpers/svn-buddy
9
 */
10
11
namespace ConsoleHelpers\SVNBuddy\Repository\RevisionLog;
12
13
14
class PathsRevisionLogPlugin extends AbstractRevisionLogPlugin
15
{
16
	const CACHE_FORMAT_VERSION = 1;
17
18
	/**
19
	 * Paths affected by specific revision.
20
	 *
21
	 * @var array
22
	 */
23
	private $_revisionPaths = array();
24
25
	/**
26
	 * Revisions affecting a specific path.
27
	 *
28
	 * @var array
29
	 */
30
	private $_pathRevisions = array();
31
32
	/**
33
	 * Returns plugin name.
34
	 *
35
	 * @return string
36
	 */
37 4
	public function getName()
38
	{
39 4
		return 'paths';
40
	}
41
42
	/**
43
	 * Parse log entries.
44
	 *
45
	 * @param \SimpleXMLElement $log Log.
46
	 *
47
	 * @return void
48
	 */
49 1
	public function parse(\SimpleXMLElement $log)
50
	{
51 1
		foreach ( $log->logentry as $log_entry ) {
52 1
			$revision = (int)$log_entry['revision'];
53 1
			$this->_revisionPaths[$revision] = array();
54
55 1
			foreach ( $log_entry->paths->path as $path_node ) {
56
				/** @var \SimpleXMLElement $path_node */
57 1
				$path = (string)$path_node;
58
59 1
				if ( !isset($this->_pathRevisions[$path]) ) {
60 1
					$this->_pathRevisions[$path] = array();
61 1
				}
62
63 1
				$this->_pathRevisions[$path][] = $revision;
64
65 1
				$path_data = array('path' => $path);
66
67 1
				foreach ( $path_node->attributes() as $attribute_name => $attribute_value ) {
68 1
					$path_data[$attribute_name] = (string)$attribute_value;
69 1
				}
70
71 1
				$this->_revisionPaths[$revision][] = $path_data;
72 1
			}
73 1
		}
74 1
	}
75
76
	/**
77
	 * Find revisions by collected data.
78
	 *
79
	 * @param array $criteria Criteria.
80
	 *
81
	 * @return array
82
	 */
83 5
	public function find(array $criteria)
84
	{
85 5
		if ( reset($criteria) === '' ) {
86
			// Include revisions from all paths.
87 1
			$path_revisions = $this->_revisionPaths;
88 1
		}
89
		else {
90
			// Include revisions from given sub-path only.
91 4
			$path_revisions = array();
92
93 4
			foreach ( $criteria as $path ) {
94 3
				$path_length = strlen($path);
95
96 3
				foreach ( $this->_pathRevisions as $test_path => $revisions ) {
97
					// FIXME: Fast, but does sub-match in inside a folder and "tags/stable" matches also "tags/stable2".
98 3
					if ( substr($test_path, 0, $path_length) == $path ) {
99 2
						foreach ( $revisions as $revision ) {
100 2
							$path_revisions[$revision] = true;
101 2
						}
102 2
					}
103 3
				}
104 4
			}
105
		}
106
107 5
		$path_revisions = array_keys($path_revisions);
108 5
		sort($path_revisions, SORT_NUMERIC);
109
110 5
		return $path_revisions;
111
	}
112
113
	/**
114
	 * Returns information about revision.
115
	 *
116
	 * @param integer $revision Revision.
117
	 *
118
	 * @return array
119
	 * @throws \InvalidArgumentException When revision is not found.
120
	 */
121 2
	public function getRevisionData($revision)
122
	{
123 2
		if ( !isset($this->_revisionPaths[$revision]) ) {
124 1
			$error_msg = 'Revision "%s" not found by "%s" plugin.';
125 1
			throw new \InvalidArgumentException(sprintf($error_msg, $revision, $this->getName()));
126
		}
127
128 1
		return $this->_revisionPaths[$revision];
129
	}
130
131
	/**
132
	 * Returns information about revisions.
133
	 *
134
	 * @param array $revisions Revisions.
135
	 *
136
	 * @return array
137
	 */
138 2
	public function getRevisionsData(array $revisions)
139
	{
140 2
		$results = array();
141
142 2
		foreach ( $revisions as $revision ) {
143 2
			if ( isset($this->_revisionPaths[$revision]) ) {
144 1
				$results[$revision] = $this->_revisionPaths[$revision];
145 1
			}
146 2
		}
147
148 2
		$this->assertNoMissingRevisions($revisions, $results);
149
150 1
		return $results;
151
	}
152
153
	/**
154
	 * Returns data, collected by plugin.
155
	 *
156
	 * @return array
157
	 */
158 1
	public function getCollectedData()
159
	{
160
		return array(
161 1
			'revision_paths' => $this->_revisionPaths,
162 1
			'path_revisions' => $this->_pathRevisions,
163 1
		);
164
	}
165
166
	/**
167
	 * Initializes plugin using previously collected data.
168
	 *
169
	 * @param array $collected_data Collected data.
170
	 *
171
	 * @return void
172
	 */
173 7
	public function setCollectedData(array $collected_data)
174
	{
175 7
		$this->_revisionPaths = $collected_data['revision_paths'];
176 7
		$this->_pathRevisions = $collected_data['path_revisions'];
177 7
	}
178
179
	/**
180
	 * Returns cache invalidator for this plugin data.
181
	 *
182
	 * @return string
183
	 */
184 2
	public function getCacheInvalidator()
185
	{
186 2
		return self::CACHE_FORMAT_VERSION;
187
	}
188
189
	/**
190
	 * Returns last known revision number.
191
	 *
192
	 * @return integer
193
	 */
194 2
	public function getLastRevision()
195
	{
196 2
		if ( !$this->_revisionPaths ) {
197 1
			return null;
198
		}
199
200 1
		end($this->_revisionPaths);
201
202 1
		return key($this->_revisionPaths);
203
	}
204
205
}
206