Merge "Add "help" links for Special:BrokenRedirects, Special:DoubleRedirects, and...
[lhc/web/wiklou.git] / includes / block / CompositeBlock.php
1 <?php
2 /**
3 * Class for blocks composed from multiple blocks.
4 *
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.
9 *
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.
14 *
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
19 *
20 * @file
21 */
22
23 namespace MediaWiki\Block;
24
25 use IContextSource;
26 use Title;
27
28 /**
29 * Multiple Block class.
30 *
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.
33 *
34 * @since 1.34
35 */
36 class CompositeBlock extends AbstractBlock {
37 /** @var AbstractBlock[] */
38 private $originalBlocks;
39
40 /**
41 * Create a new block with specified parameters on a user, IP or IP range.
42 *
43 * @param array $options Parameters of the block:
44 * originalBlocks Block[] Blocks that this block is composed from
45 */
46 public function __construct( array $options = [] ) {
47 parent::__construct( $options );
48
49 $defaults = [
50 'originalBlocks' => [],
51 ];
52
53 $options += $defaults;
54
55 $this->originalBlocks = $options[ 'originalBlocks' ];
56
57 $this->setHideName( $this->propHasValue( 'mHideName', true ) );
58 $this->isSitewide( $this->propHasValue( 'isSitewide', true ) );
59 $this->isEmailBlocked( $this->propHasValue( 'mBlockEmail', true ) );
60 $this->isCreateAccountBlocked( $this->propHasValue( 'blockCreateAccount', true ) );
61 $this->isUsertalkEditAllowed( !$this->propHasValue( 'allowUsertalk', false ) );
62 }
63
64 /**
65 * Determine whether any original blocks have a particular property set to a
66 * particular value.
67 *
68 * @param string $prop
69 * @param mixed $value
70 * @return bool At least one block has the property set to the value
71 */
72 private function propHasValue( $prop, $value ) {
73 foreach ( $this->originalBlocks as $block ) {
74 if ( $block->$prop == $value ) {
75 return true;
76 }
77 }
78 return false;
79 }
80
81 /**
82 * Determine whether any original blocks have a particular method returning a
83 * particular value.
84 *
85 * @param string $method
86 * @param mixed $value
87 * @param mixed ...$params
88 * @return bool At least one block has the method returning the value
89 */
90 private function methodReturnsValue( $method, $value, ...$params ) {
91 foreach ( $this->originalBlocks as $block ) {
92 if ( $block->$method( ...$params ) == $value ) {
93 return true;
94 }
95 }
96 return false;
97 }
98
99 /**
100 * Get the original blocks from which this block is composed
101 *
102 * @since 1.34
103 * @return AbstractBlock[]
104 */
105 public function getOriginalBlocks() {
106 return $this->originalBlocks;
107 }
108
109 /**
110 * @inheritDoc
111 */
112 public function getExpiry() {
113 $maxExpiry = null;
114 foreach ( $this->originalBlocks as $block ) {
115 $expiry = $block->getExpiry();
116 if ( $maxExpiry === null || $expiry === '' || $expiry > $maxExpiry ) {
117 $maxExpiry = $expiry;
118 }
119 }
120 return $maxExpiry;
121 }
122
123 /**
124 * @inheritDoc
125 */
126 public function getPermissionsError( IContextSource $context ) {
127 $params = $this->getBlockErrorParams( $context );
128
129 $msg = 'blockedtext-composite';
130
131 array_unshift( $params, $msg );
132
133 return $params;
134 }
135
136 /**
137 * @inheritDoc
138 */
139 public function appliesToRight( $right ) {
140 return $this->methodReturnsValue( __FUNCTION__, true, $right );
141 }
142
143 /**
144 * @inheritDoc
145 */
146 public function appliesToUsertalk( Title $usertalk = null ) {
147 return $this->methodReturnsValue( __FUNCTION__, true, $usertalk );
148 }
149
150 /**
151 * @inheritDoc
152 */
153 public function appliesToTitle( Title $title ) {
154 return $this->methodReturnsValue( __FUNCTION__, true, $title );
155 }
156
157 /**
158 * @inheritDoc
159 */
160 public function appliesToNamespace( $ns ) {
161 return $this->methodReturnsValue( __FUNCTION__, true, $ns );
162 }
163
164 /**
165 * @inheritDoc
166 */
167 public function appliesToPage( $pageId ) {
168 return $this->methodReturnsValue( __FUNCTION__, true, $pageId );
169 }
170
171 /**
172 * @inheritDoc
173 */
174 public function appliesToPasswordReset() {
175 return $this->methodReturnsValue( __FUNCTION__, true );
176 }
177
178 }