SimpleSubPageFinder   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 209
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 84.62%

Importance

Changes 0
Metric Value
dl 0
loc 209
ccs 55
cts 65
cp 0.8462
rs 10
c 0
b 0
f 0
wmc 20
lcom 1
cbo 1

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 10 1
A setOption() 0 3 1
A setLimit() 0 7 3
A setSortOrder() 0 7 3
A setIncludeRedirects() 0 7 2
A setOffset() 0 7 3
A countSubPages() 0 19 2
A getSubPagesFor() 0 19 1
A getConditions() 0 17 2
A getOptions() 0 12 2
1
<?php
2
3
namespace SubPageList\Lister;
4
5
use InvalidArgumentException;
6
use SubPageList\Counter\SubPageCounter;
7
use SubPageList\DBConnectionProvider;
8
use Title;
9
use TitleArray;
10
11
/**
12
 * Simple subpage finder and counter that uses a like query
13
 * on the page table to find subpages.
14
 *
15
 * @since 1.2
16
 *
17
 * @licence GNU GPL v2+
18
 * @author Jeroen De Dauw < [email protected] >
19
 */
20
class SimpleSubPageFinder implements SubPageFinder, SubPageCounter {
21
22
	const OPT_INCLUDE_REDIRECTS = 'redirects';
23
	const OPT_LIMIT = 'limit';
24
	const OPT_OFFSET = 'offset';
25
	const OPT_SORT_ORDER = 'sort';
26
	const SORT_ASCENDING = 'asc';
27
	const SORT_DESCENDING = 'desc';
28
29
	/**
30
	 * @var DBConnectionProvider
31
	 */
32
	private $connectionProvider;
33
34
	/**
35
	 * @var array
36
	 */
37
	private $options;
38
39
	/**
40
	 * @since 1.2
41
	 *
42
	 * @param DBConnectionProvider $connectionProvider
43
	 */
44 27
	public function __construct( DBConnectionProvider $connectionProvider ) {
45 27
		$this->connectionProvider = $connectionProvider;
46
47 27
		$this->options = [
48 27
			self::OPT_INCLUDE_REDIRECTS => false,
49 27
			self::OPT_LIMIT => 500,
50 27
			self::OPT_OFFSET => 0,
51 27
			self::OPT_SORT_ORDER => self::SORT_ASCENDING,
52
		];
53 27
	}
54
55
	/**
56
	 * @param string $option
57
	 * @param mixed $value
58
	 */
59 19
	private function setOption( $option, $value ) {
60 19
		$this->options[$option] = $value;
61 19
	}
62
63
	/**
64
	 * @see SubPageFinder::setLimit
65
	 *
66
	 * @since 1.2
67
	 *
68
	 * @param int $limit
69
	 *
70
	 * @throws InvalidArgumentException
71
	 */
72 19
	public function setLimit( $limit ) {
73 19
		if ( !is_int( $limit ) || $limit < 1 ) {
74
			throw new InvalidArgumentException( '$limit needs to be an int bigger than 0' );
75
		}
76
77 19
		$this->setOption( self::OPT_LIMIT, $limit );
78 19
	}
79
80
	/**
81
	 * @param string $sortOrder
82
	 *
83
	 * @throws InvalidArgumentException
84
	 */
85 19
	public function setSortOrder( $sortOrder ) {
86 19
		if ( strtolower($sortOrder) != self::SORT_DESCENDING && strtolower($sortOrder) != self::SORT_ASCENDING ) {
87
			throw new InvalidArgumentException( 'Invalid $sortOrder specified' );
88
		}
89
90 19
		$this->setOption( self::OPT_SORT_ORDER, $sortOrder );
91 19
	}
92
93
	/**
94
	 * @see SubPageFinder::setIncludeRedirects
95
	 *
96
	 * @since 1.4.0
97
	 *
98
	 * @param bool $includeRedirects
99
	 *
100
	 * @throws InvalidArgumentException
101
	 */
102 19
	public function setIncludeRedirects( $includeRedirects ) {
103 19
		if ( !is_bool( $includeRedirects ) ) {
104
			throw new InvalidArgumentException( '$includeRedirects needs to be boolean' );
105
		}
106
107 19
		$this->setOption( self::OPT_INCLUDE_REDIRECTS, $includeRedirects );
108 19
	}
109
110
	/**
111
	 * @see SubPageFinder::setOffset
112
	 *
113
	 * @since 1.2
114
	 *
115
	 * @param int $offset
116
	 *
117
	 * @throws InvalidArgumentException
118
	 */
119
	public function setOffset( $offset ) {
120
		if ( !is_int( $offset ) || $offset < 0 ) {
121
			throw new InvalidArgumentException( '$limit needs to be a positive int' );
122
		}
123
124
		$this->setOption( self::OPT_OFFSET, $offset );
125
	}
126
127
	/**
128
	 * @see SubPageFinder::getSubPagesFor
129
	 *
130
	 * @since 1.2
131
	 *
132
	 * @param Title $title
133
	 *
134
	 * @return Title[]
135
	 */
136 22
	public function getSubPagesFor( Title $title ) {
137
		/**
138
		 * @var \DatabaseBase $dbr
139
		 */
140 22
		$dbr = $this->connectionProvider->getConnection();
141
142 22
		$titleArray = TitleArray::newFromResult(
143 22
			$dbr->select( 'page',
144 22
				[ 'page_id', 'page_namespace', 'page_title', 'page_is_redirect' ],
145 22
				$this->getConditions( $title ),
146 22
				__METHOD__,
147 22
				$this->getOptions()
148
			)
149
		);
150
151 22
		$this->connectionProvider->releaseConnection();
152
153 22
		return iterator_to_array( $titleArray );
154
	}
155
156
	/**
157
	 * @see SubPageCounter::countSubPages
158
	 *
159
	 * @since 1.2
160
	 *
161
	 * @param Title $title
162
	 *
163
	 * @return integer
164
	 */
165 4
	public function countSubPages( Title $title ) {
166
		/**
167
		 * @var \DatabaseBase $dbr
168
		 */
169 4
		$dbr = $this->connectionProvider->getConnection();
170
171 4
		$res = $dbr->selectRow(
172 4
			'page',
173 4
			'COUNT(*) AS rowcount',
174 4
			$this->getConditions( $title ),
175 4
			__METHOD__
176
		);
177
178 4
		if ( is_object( $res ) ) {
179 4
			return (int)$res->rowcount;
180
		}
181
182
		return 0;
183
	}
184
185
	/**
186
	 * @since 1.2
187
	 *
188
	 * @param Title $title
189
	 *
190
	 * @return array
191
	 */
192 26
	private function getConditions( Title $title ) {
193
		/**
194
		 * @var \DatabaseBase $dbr
195
		 */
196 26
		$dbr = $this->connectionProvider->getConnection();
197
198
		$conditions = [
199 26
			'page_namespace' => $title->getNamespace(),
200 26
			'page_title'  . $dbr->buildLike( $title->getDBkey() . '/', $dbr->anyString() )
201
		];
202
203 26
		if ( !$this->options[self::OPT_INCLUDE_REDIRECTS] ) {
204 26
			$conditions['page_is_redirect'] = 0;
205
		}
206
207 26
		return $conditions;
208
	}
209
210
	/**
211
	 * @since 1.2
212
	 *
213
	 * @return array
214
	 */
215 22
	private function getOptions() {
216 22
		$options = [];
217
218 22
		$options['LIMIT'] = (int)$this->options[self::OPT_LIMIT];
219 22
		$options['ORDER BY'] = "page_title {$this->options[self::OPT_SORT_ORDER]}";
220
221 22
		if ( $this->options[self::OPT_OFFSET] > 0 ) {
222
			$options['OFFSET'] = (int)$this->options[self::OPT_OFFSET];
223
		}
224
225 22
		return $options;
226
	}
227
228
}
229