3 * Class for blocks composed from multiple blocks.
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
23 namespace MediaWiki\Block
;
29 * Multiple Block class.
31 * Multiple blocks exist to enforce restrictions from more than one block, if several
32 * blocks apply to a user/IP. Multiple blocks are created temporarily on enforcement.
36 class CompositeBlock
extends AbstractBlock
{
37 /** @var AbstractBlock[] */
38 private $originalBlocks;
41 * Create a new block with specified parameters on a user, IP or IP range.
43 * @param array $options Parameters of the block, with options supported by
44 * `AbstractBlock::__construct`, and also:
45 * - originalBlocks: (Block[]) Blocks that this block is composed from
47 public function __construct( array $options = [] ) {
48 parent
::__construct( $options );
51 'originalBlocks' => [],
54 $options +
= $defaults;
56 $this->originalBlocks
= $options[ 'originalBlocks' ];
58 $this->setHideName( $this->propHasValue( 'mHideName', true ) );
59 $this->isSitewide( $this->propHasValue( 'isSitewide', true ) );
60 $this->isEmailBlocked( $this->propHasValue( 'mBlockEmail', true ) );
61 $this->isCreateAccountBlocked( $this->propHasValue( 'blockCreateAccount', true ) );
62 $this->isUsertalkEditAllowed( !$this->propHasValue( 'allowUsertalk', false ) );
66 * Determine whether any original blocks have a particular property set to a
71 * @return bool At least one block has the property set to the value
73 private function propHasValue( $prop, $value ) {
74 foreach ( $this->originalBlocks
as $block ) {
75 if ( $block->$prop == $value ) {
83 * Determine whether any original blocks have a particular method returning a
86 * @param string $method
88 * @param mixed ...$params
89 * @return bool At least one block has the method returning the value
91 private function methodReturnsValue( $method, $value, ...$params ) {
92 foreach ( $this->originalBlocks
as $block ) {
93 if ( $block->$method( ...$params ) == $value ) {
101 * Get the original blocks from which this block is composed
104 * @return AbstractBlock[]
106 public function getOriginalBlocks() {
107 return $this->originalBlocks
;
113 public function getExpiry() {
115 foreach ( $this->originalBlocks
as $block ) {
116 $expiry = $block->getExpiry();
117 if ( $maxExpiry === null ||
$expiry === '' ||
$expiry > $maxExpiry ) {
118 $maxExpiry = $expiry;
125 * Get the IDs for the original blocks, ignoring any that are null
129 protected function getIds() {
131 foreach ( $this->originalBlocks
as $block ) {
132 $id = $block->getId();
133 if ( $id !== null ) {
143 public function getPermissionsError( IContextSource
$context ) {
144 $params = $this->getBlockErrorParams( $context );
146 $ids = implode( ', ', array_map( function ( $id ) {
148 }, $this->getIds() ) );
150 $idsMsg = $context->msg( 'blockedtext-composite-no-ids' )->plain();
152 $idsMsg = $context->msg( 'blockedtext-composite-ids', [ $ids ] )->plain();
155 // TODO: Clean up error messages params so we don't have to do this (T227174)
156 $params[ 4 ] = $idsMsg;
158 $msg = 'blockedtext-composite';
160 array_unshift( $params, $msg );
168 * Determines whether the CompositeBlock applies to a right by checking
169 * whether the original blocks apply to that right. Each block can report
170 * true (applies), false (does not apply) or null (unsure). Then:
171 * - If any original blocks apply, this block applies
172 * - If no original blocks apply but any are unsure, this block is unsure
173 * - If all blocks do not apply, this block does not apply
175 public function appliesToRight( $right ) {
178 foreach ( $this->originalBlocks
as $block ) {
179 $appliesToRight = $block->appliesToRight( $right );
181 if ( $appliesToRight ) {
183 } elseif ( $appliesToRight === null ) {
188 return $isUnsure ?
null : false;
194 public function appliesToUsertalk( Title
$usertalk = null ) {
195 return $this->methodReturnsValue( __FUNCTION__
, true, $usertalk );
201 public function appliesToTitle( Title
$title ) {
202 return $this->methodReturnsValue( __FUNCTION__
, true, $title );
208 public function appliesToNamespace( $ns ) {
209 return $this->methodReturnsValue( __FUNCTION__
, true, $ns );
215 public function appliesToPage( $pageId ) {
216 return $this->methodReturnsValue( __FUNCTION__
, true, $pageId );
222 public function appliesToPasswordReset() {
223 return $this->methodReturnsValue( __FUNCTION__
, true );