35 &$query_options, &$join_conds, FormOptions $opts
37 global $wgTranslateRcFilterDefault;
39 if ( $pageName !==
'Recentchanges' || self::isStructuredFilterUiEnabled() ) {
43 $request = RequestContext::getMain()->getRequest();
44 $translations = $request->getVal(
'translations', $wgTranslateRcFilterDefault );
45 $opts->add(
'translations', $wgTranslateRcFilterDefault );
46 $opts->setValue(
'translations', $translations );
48 $dbr = wfGetDB( DB_REPLICA );
50 $namespaces = self::getTranslateNamespaces();
52 if ( $translations ===
'only' ) {
53 $conds[] =
'rc_namespace IN (' . $dbr->makeList( $namespaces ) .
')';
54 $conds[] =
'rc_title like \'%%/%%\'';
55 } elseif ( $translations ===
'filter' ) {
56 $conds[] =
'rc_namespace NOT IN (' . $dbr->makeList( $namespaces ) .
')';
57 } elseif ( $translations ===
'site' ) {
58 $conds[] =
'rc_namespace IN (' . $dbr->makeList( $namespaces ) .
')';
59 $conds[] =
'rc_title not like \'%%/%%\'';
87 if ( self::isStructuredFilterUiEnabled() ) {
91 $opts->consumeValue(
'translations' );
92 $default = $opts->getValue(
'translations' );
95 wfMessage(
'translate-rc-translation-filter' )->text(),
96 'mw-translation-filter'
98 $select =
new XmlSelect(
'translations',
'mw-translation-filter', $default );
100 wfMessage(
'translate-rc-translation-filter-no' )->text(),
103 $select->addOption( wfMessage(
'translate-rc-translation-filter-only' )->text(),
'only' );
105 wfMessage(
'translate-rc-translation-filter-filter' )->text(),
108 $select->addOption( wfMessage(
'translate-rc-translation-filter-site' )->text(),
'site' );
110 $items[
'translations'] = [ $label, $select->getHTML() ];
136 ChangesListSpecialPage $special
138 global $wgTranslateRcFilterDefault;
139 $defaultFilter = $wgTranslateRcFilterDefault !==
'noaction' ?
140 $wgTranslateRcFilterDefault :
141 ChangesListStringOptionsFilterGroup::NONE;
143 $translationsGroup =
new ChangesListStringOptionsFilterGroup(
145 'name' =>
'translations',
146 'title' =>
'translate-rcfilters-translations',
148 'default' => $defaultFilter,
149 'isFullCoverage' =>
true,
153 'label' =>
'translate-rcfilters-translations-only-label',
154 'description' =>
'translate-rcfilters-translations-only-desc',
155 'cssClassSuffix' =>
'only',
156 'isRowApplicableCallable' =>
function ( $ctx, $rc ) {
157 $namespaces = self::getTranslateNamespaces();
159 return in_array( $rc->getAttribute(
'rc_namespace' ), $namespaces ) &&
160 strpos( $rc->getAttribute(
'rc_title' ),
'/' ) !==
false;
165 'label' =>
'translate-rcfilters-translations-site-label',
166 'description' =>
'translate-rcfilters-translations-site-desc',
167 'cssClassSuffix' =>
'site',
168 'isRowApplicableCallable' =>
function ( $ctx, $rc ) {
169 $namespaces = self::getTranslateNamespaces();
171 return in_array( $rc->getAttribute(
'rc_namespace' ), $namespaces ) &&
172 strpos( $rc->getAttribute(
'rc_title' ),
'/' ) ===
false;
177 'label' =>
'translate-rcfilters-translations-filter-label',
178 'description' =>
'translate-rcfilters-translations-filter-desc',
179 'cssClassSuffix' =>
'filter',
180 'isRowApplicableCallable' =>
function ( $ctx, $rc ) {
181 $namespaces = self::getTranslateNamespaces();
183 return !in_array( $rc->getAttribute(
'rc_namespace' ), $namespaces );
187 'name' =>
'filter-translation-pages',
188 'label' =>
'translate-rcfilters-translations-filter-translation-pages-label',
189 'description' =>
'translate-rcfilters-translations-filter-translation-pages-desc',
190 'cssClassSuffix' =>
'filter-translation-pages',
191 'isRowApplicableCallable' =>
static function ( $ctx, $rc ) {
192 $tags = explode(
', ', $rc->getAttribute(
'ts_tags' ) ??
'' );
193 return !in_array(
'translate-filter-translation-pages', $tags );
198 'queryCallable' =>
function ( $specialClassName, $ctx, $dbr, &$tables,
199 &$fields, &$conds, &$query_options, &$join_conds, $selectedValues
201 $fields = array_merge( $fields, [
'rc_title',
'rc_namespace' ] );
204 $filterRenderedIndex = array_search(
'filter-translation-pages', $selectedValues );
205 if ( $filterRenderedIndex !==
false ) {
206 unset( $selectedValues[$filterRenderedIndex] );
207 $selectedValues = array_values( $selectedValues );
209 $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore();
211 $renderedPage = $changeTagDefStore->getId(
'translate-translation-pages' );
212 $tables[
'translatetags'] = ChangeTags::getDisplayTableName();
213 $join_conds[
'translatetags'] = [
215 [
'translatetags.ct_rc_id=rc_id',
'translatetags.ct_tag_id' => $renderedPage ]
217 $conds[
'translatetags.ct_tag_id'] =
null;
218 }
catch ( NameTableAccessException $exception ) {
223 $namespaces = self::getTranslateNamespaces();
224 $inNamespaceCond =
'rc_namespace IN (' .
225 $dbr->makeList( $namespaces ) .
')';
226 $notInNamespaceCond =
'rc_namespace NOT IN (' .
227 $dbr->makeList( $namespaces ) .
')';
229 $onlyCond = $dbr->makeList( [
232 $dbr->buildLike( $dbr->anyString(),
'/', $dbr->anyString() )
234 $siteCond = $dbr->makeList( [
237 $dbr->buildLike( $dbr->anyString(),
'/', $dbr->anyString() )
240 if ( count( $selectedValues ) === 3 ) {
245 if ( $selectedValues === [
'filter',
'only' ] ) {
246 $conds[] = $dbr->makeList( [
253 if ( $selectedValues === [
'filter',
'site' ] ) {
254 $conds[] = $dbr->makeList( [
261 if ( $selectedValues === [
'only',
'site' ] ) {
262 $conds[] = $inNamespaceCond;
266 if ( $selectedValues === [
'filter' ] ) {
267 $conds[] = $notInNamespaceCond;
271 if ( $selectedValues === [
'only' ] ) {
272 $conds[] = $onlyCond;
276 if ( $selectedValues === [
'site' ] ) {
277 $conds[] = $siteCond;
283 $special->registerFilterGroup( $translationsGroup );