3 * Represents a filter group (used on ChangesListSpecialPage and descendants)
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * http://www.gnu.org/copyleft/gpl.html
22 * @author Matthew Flaschen
25 use Wikimedia\Rdbms\IDatabase
;
28 * Represents a filter group with multiple string options. They are passed to the server as
29 * a single form parameter separated by a delimiter. The parameter name is the
30 * group name. E.g. groupname=opt1;opt2 .
32 * If all options are selected they are replaced by the term "all".
34 * There is also a single DB query modification for the whole group.
39 class ChangesListStringOptionsFilterGroup
extends ChangesListFilterGroup
{
41 * Type marker, used by JavaScript
43 const TYPE
= 'string_options';
48 const SEPARATOR
= ';';
51 * Signifies that all options in the group are selected.
56 * Signifies that no options in the group are selected, meaning the group has no effect.
58 * For full-coverage groups, this is the same as ALL if all filters are allowed.
59 * For others, it is not.
64 * Group name; used as form parameter.
70 * Defaul parameter value
72 * @var string $defaultValue
74 protected $defaultValue;
77 * Callable used to do the actual query modification; see constructor
79 * @var callable $queryCallable
81 protected $queryCallable;
84 * Create a new filter group with the specified configuration
86 * @param array $groupDefinition Configuration of group
87 * * $groupDefinition['name'] string Group name
88 * * $groupDefinition['title'] string i18n key for title (optional, can be omitted
89 * * only if none of the filters in the group display in the structured UI)
90 * * $groupDefinition['priority'] int Priority integer. Higher means higher in the
92 * * $groupDefinition['filters'] array Numeric array of filter definitions, each of which
93 * * is an associative array to be passed to the filter constructor. However,
94 * * 'priority' is optional for the filters. Any filter that has priority unset
95 * * will be put to the bottom, in the order given.
96 * * $groupDefinition['default'] string Default for group.
97 * * $groupDefinition['isFullCoverage'] bool Whether the group is full coverage;
98 * * if true, this means that checking every item in the group means no
99 * * changes list entries are filtered out.
100 * * $groupDefinition['queryCallable'] callable Callable accepting parameters:
101 * * string $specialPageClassName Class name of current special page
102 * * IContextSource $context Context, for e.g. user
103 * * IDatabase $dbr Database, for addQuotes, makeList, and similar
104 * * array &$tables Array of tables; see IDatabase::select $table
105 * * array &$fields Array of fields; see IDatabase::select $vars
106 * * array &$conds Array of conditions; see IDatabase::select $conds
107 * * array &$query_options Array of query options; see IDatabase::select $options
108 * * array &$join_conds Array of join conditions; see IDatabase::select $join_conds
109 * * array $selectedValues The allowed and requested values, lower-cased and sorted
110 * * $groupDefinition['whatsThisHeader'] string i18n key for header of "What's
111 * * This" popup (optional).
112 * * $groupDefinition['whatsThisBody'] string i18n key for body of "What's This"
113 * * popup (optional).
114 * * $groupDefinition['whatsThisUrl'] string URL for main link of "What's This"
115 * * popup (optional).
116 * * $groupDefinition['whatsThisLinkText'] string i18n key of text for main link of
117 * * "What's This" popup (optional).
119 public function __construct( array $groupDefinition ) {
120 if ( !isset( $groupDefinition['isFullCoverage'] ) ) {
121 throw new MWException( 'You must specify isFullCoverage' );
124 $groupDefinition['type'] = self
::TYPE
;
126 parent
::__construct( $groupDefinition );
128 $this->queryCallable
= $groupDefinition['queryCallable'];
130 if ( isset( $groupDefinition['default'] ) ) {
131 $this->setDefault( $groupDefinition['default'] );
133 throw new MWException( 'You must specify a default' );
140 public function isPerGroupRequestParameter() {
145 * Sets default of filter group.
147 * @param string $defaultValue
149 public function setDefault( $defaultValue ) {
150 $this->defaultValue
= $defaultValue;
154 * Gets default of filter group
156 * @return string $defaultValue
158 public function getDefault() {
159 return $this->defaultValue
;
165 protected function createFilter( array $filterDefinition ) {
166 return new ChangesListStringOptionsFilter( $filterDefinition );
170 * Registers a filter in this group
172 * @param ChangesListStringOptionsFilter $filter ChangesListStringOptionsFilter
174 public function registerFilter( ChangesListStringOptionsFilter
$filter ) {
175 $this->filters
[$filter->getName()] = $filter;
179 * Modifies the query to include the filter group.
181 * The modification is only done if the filter group is in effect. This means that
182 * one or more valid and allowed filters were selected.
184 * @param IDatabase $dbr Database, for addQuotes, makeList, and similar
185 * @param ChangesListSpecialPage $specialPage Current special page
186 * @param array &$tables Array of tables; see IDatabase::select $table
187 * @param array &$fields Array of fields; see IDatabase::select $vars
188 * @param array &$conds Array of conditions; see IDatabase::select $conds
189 * @param array &$query_options Array of query options; see IDatabase::select $options
190 * @param array &$join_conds Array of join conditions; see IDatabase::select $join_conds
191 * @param string $value URL parameter value
193 public function modifyQuery( IDatabase
$dbr, ChangesListSpecialPage
$specialPage,
194 &$tables, &$fields, &$conds, &$query_options, &$join_conds, $value ) {
196 $allowedFilterNames = [];
197 foreach ( $this->filters
as $filter ) {
198 $allowedFilterNames[] = $filter->getName();
201 if ( $value === self
::ALL
) {
202 $selectedValues = $allowedFilterNames;
204 $selectedValues = explode( self
::SEPARATOR
, strtolower( $value ) );
206 // remove values that are not recognized or not currently allowed
207 $selectedValues = array_intersect(
213 // If there are now no values, because all are disallowed or invalid (also,
214 // the user may not have selected any), this is a no-op.
216 // If everything is unchecked, the group always has no effect, regardless
218 if ( count( $selectedValues ) === 0 ) {
222 sort( $selectedValues );
224 call_user_func_array(
225 $this->queryCallable
,
227 get_class( $specialPage ),
228 $specialPage->getContext(),
243 public function getJsData() {
244 $output = parent
::getJsData();
246 $output['separator'] = self
::SEPARATOR
;
247 $output['default'] = $this->getDefault();