1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
<?php
/**
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
* @file
*/
namespace MediaWiki\EditPage\Constraint;
use MediaWiki\Logger\LoggerFactory;
use Psr\Log\LoggerInterface;
use Wikimedia\Assert\Assert;
/**
* Back end to process the edit constraints
*
* Constraints reflect possible errors that need to be checked
*
* @since 1.36
* @internal
* @author DannyS712
*/
class EditConstraintRunner {
private LoggerInterface $logger;
/**
* @var IEditConstraint[]
*
* Constraints to check.
*/
private $constraints = [];
/**
* @var IEditConstraint|false
*
* The constraint that failed, so that its status can be fetched, or false if none failed.
*/
private $failedConstraint = false;
/**
* Create a new runner
*/
public function __construct() {
// TODO allow passing an array here as the starting constraints?
// TODO consider injecting this?
$this->logger = LoggerFactory::getInstance( 'EditConstraintRunner' );
}
/**
* Add a constraint to check
*
* Not all constraints are applicable to the action api or other methods of submitting
* an edit
*
* For constraints that have dependencies, use the EditConstraintFactory.
*
* @param IEditConstraint $constraint
*/
public function addConstraint( IEditConstraint $constraint ) {
$this->constraints[] = $constraint;
}
/**
* Run constraint checks
*
* Returns true if all constraints pass, false otherwise.
* Check getLegacyStatus for the reason
*
* @return bool
*/
public function checkConstraints(): bool {
foreach ( $this->constraints as $constraint ) {
$result = $constraint->checkConstraint();
if ( $result !== IEditConstraint::CONSTRAINT_PASSED ) {
// Use `info` instead of `debug` for the one constraint that failed
$this->logger->info(
'Checked {name}, got result: {result}',
[
'name' => $this->getConstraintName( $constraint ),
'result' => $result
]
);
$this->failedConstraint = $constraint;
return false;
}
// Pass, log at `debug` level
$this->logger->debug(
'Checked {name}, got result: {result}',
[
'name' => $this->getConstraintName( $constraint ),
'result' => $result
]
);
}
return true;
}
/**
* @param IEditConstraint $constraint
* @return string
*/
private function getConstraintName( IEditConstraint $constraint ): string {
// Used for debug logging
$fullClassName = explode( '\\', get_class( $constraint ) );
$constraintName = end( $fullClassName );
if ( $constraint instanceof PageSizeConstraint ) {
// TODO "When you need to do this instanceof, it's a code smell"
// Convert IEditConstraint to abstract class with a getName method
// once the initial migration to edit constraints is complete
// PageSizeConstraint is used twice, make sure they can be told apart
$constraintName .= ' ' . $constraint->getType();
}
return $constraintName;
}
/**
* Get the constraint that failed
*
* @return IEditConstraint
*/
public function getFailedConstraint(): IEditConstraint {
Assert::precondition(
$this->failedConstraint !== false,
'getFailedConstraint called with no failed constraint'
);
return $this->failedConstraint;
}
}
|