Completed
Push — master ( af40d0...a4cfbb )
by Alexander
02:34
created

RefsPlugin::findRevisionsByRef()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 31
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 31
ccs 15
cts 15
cp 1
rs 8.5806
c 0
b 0
f 0
cc 4
eloc 13
nc 4
nop 3
crap 4
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\Plugin;
12
13
14
class RefsPlugin extends AbstractDatabaseCollectorPlugin
15
{
16
17
	/**
18
	 * Returns plugin name.
19
	 *
20
	 * @return string
21
	 */
22 5
	public function getName()
23
	{
24 5
		return 'refs';
25
	}
26
27
	/**
28
	 * Defines parsing statistic types.
29
	 *
30
	 * @return array
31
	 */
32 12
	public function defineStatisticTypes()
33
	{
34 12
		return array();
35
	}
36
37
	/**
38
	 * Processes data.
39
	 *
40
	 * @param integer $from_revision From revision.
41
	 * @param integer $to_revision   To revision.
42
	 *
43
	 * @return void
44
	 */
45 1
	public function doProcess($from_revision, $to_revision)
46
	{
47
		// Do nothing, because "paths" plugin determines refs as well.
48 1
		$this->setLastRevision($to_revision);
49 1
		$this->advanceProgressBar();
50 1
	}
51
52
	/**
53
	 * Find revisions by collected data.
54
	 *
55
	 * @param array       $criteria     Criteria.
56
	 * @param string|null $project_path Project path.
57
	 *
58
	 * @return array
59
	 */
60 6
	public function find(array $criteria, $project_path)
61
	{
62 6
		if ( !$criteria ) {
1 ignored issue
show
Bug Best Practice introduced by
The expression $criteria of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
63 1
			return array();
64
		}
65
66 5
		$project_id = $this->getProject($project_path);
67
68 4
		if ( reset($criteria) === 'all_refs' ) {
69 1
			return $this->getProjectRefs($project_id);
70
		}
71 3
		elseif ( reset($criteria) === 'all' ) {
72 1
			return $this->revisionLog->find('paths', $project_path);
73
		}
74
75 2
		$ref_revisions = $this->findRevisionsByRef($project_id, $project_path, $criteria);
76
77 2
		sort($ref_revisions, SORT_NUMERIC);
78
79 2
		return $ref_revisions;
80
	}
81
82
	/**
83
	 * Returns names of all refs in a project.
84
	 *
85
	 * @param integer $project_id Project ID.
86
	 *
87
	 * @return array
88
	 */
89 1
	protected function getProjectRefs($project_id)
90
	{
91
		$sql = 'SELECT DISTINCT Name
92
				FROM ProjectRefs
93 1
				WHERE ProjectId = :project_id';
94
95 1
		return $this->database->fetchCol($sql, array('project_id' => $project_id));
96
	}
97
98
	/**
99
	 * Finds revisions by ref.
100
	 *
101
	 * @param integer $project_id   Project ID.
102
	 * @param string  $project_path Project path.
103
	 * @param array   $refs         Refs.
104
	 *
105
	 * @return array
106
	 */
107 2
	protected function findRevisionsByRef($project_id, $project_path, array $refs)
108
	{
109 2
		$ref_revisions = array();
110 2
		$ref_count = count($refs);
111
112 2
		foreach ( $refs as $ref ) {
113
			// 1. get all revisions by that path, which includes revisions from merged refs.
114 2
			$tmp_revisions = $this->revisionLog->find('paths', $project_path . $ref . '/');
115
116
			// 2. get revisions, that surely belong to needed ref.
117
			$sql = 'SELECT DISTINCT cr.Revision
118
					FROM ProjectRefs pr
119
					JOIN CommitRefs cr ON cr.RefId = pr.Id
120 2
					WHERE pr.ProjectId = :project_id AND pr.Name = :name';
121 2
			$all_ref_revisions = $this->database->fetchCol($sql, array('project_id' => $project_id, 'name' => $ref));
122
123
			// 3. filter out found revisions, that belongs to needed ref.
124 2
			$tmp_revisions = array_intersect($tmp_revisions, $all_ref_revisions);
125
126 2
			if ( $ref_count === 1 ) {
127 1
				return $tmp_revisions;
128
			}
129
130
			// Add revisions from refs.
131 1
			foreach ( $tmp_revisions as $revision ) {
132 1
				$ref_revisions[$revision] = true;
133 1
			}
134 1
		}
135
136 1
		return array_keys($ref_revisions);
137
	}
138
139
	/**
140
	 * Returns information about revisions.
141
	 *
142
	 * @param array $revisions Revisions.
143
	 *
144
	 * @return array
145
	 */
146 1
	public function getRevisionsData(array $revisions)
147
	{
148 1
		$results = array();
149
150
		$sql = 'SELECT cr.Revision, pr.Name
151
				FROM CommitRefs cr
152
				JOIN ProjectRefs pr ON pr.Id = cr.RefId
153 1
				WHERE cr.Revision IN (:revisions)';
154 1
		$revisions_data = $this->database->fetchAll($sql, array('revisions' => $revisions));
155
156 1
		foreach ( $revisions_data as $revision_data ) {
157 1
			$revision = $revision_data['Revision'];
158 1
			$ref = $revision_data['Name'];
159
160 1
			if ( !isset($results[$revision]) ) {
161 1
				$results[$revision] = array();
162 1
			}
163
164 1
			$results[$revision][] = $ref;
165 1
		}
166
167 1
		return $this->addMissingResults($revisions, $results);
168
	}
169
170
}
171