pageId = $pageId; } /** * Get a specific LintError by id * * @param int $id linter_id * @return bool|LintError */ public function getFromId( $id ) { $row = wfGetDB( DB_REPLICA )->selectRow( 'linter', [ 'linter_cat', 'linter_params' ], [ 'linter_id' => $id, 'linter_page' => $this->pageId ], __METHOD__ ); if ( $row ) { $row->linter_id = $id; return $this->makeLintError( $row ); } else { return false; } } /** * Turn a database row into a LintError object * * @param \stdClass $row * @return LintError */ public static function makeLintError( $row ) { $categoryMgr = CategoryManager::getInstance(); return new LintError( $categoryMgr->getCategoryName( $row->linter_cat ), $row->linter_params, (int)$row->linter_id ); } /** * Get all the lint errors for a page * * @return LintError[] */ public function getForPage() { $rows = wfGetDB( DB_REPLICA )->select( 'linter', [ 'linter_id', 'linter_cat', 'linter_params' ], [ 'linter_page' => $this->pageId ], __METHOD__ ); $result = []; foreach ( $rows as $row ) { $error = $this->makeLintError( $row ); $result[$error->id()] = $error; } return $result; } /** * Convert a LintError object into an array for * inserting/querying in the database * * @param LintError $error * @return array */ private function serializeError( LintError $error ) { $categoryMgr = CategoryManager::getInstance(); return [ 'linter_page' => $this->pageId, 'linter_cat' => $categoryMgr->getAndMaybeCreateCategoryId( $error->category ), 'linter_params' => FormatJson::encode( $error->params, false, FormatJson::ALL_OK ), ]; } /** * Save the specified lint errors in the * database * * @param LintError[] $errors * @return array [ 'deleted' => int|bool, 'added' => int ] */ public function setForPage( $errors ) { $previous = $this->getForPage(); $dbw = wfGetDB( DB_MASTER ); if ( !$previous && !$errors ) { return [ 'deleted' => 0, 'added' => 0 ]; } elseif ( !$previous && $errors ) { $toInsert = $errors; $toDelete = []; } elseif ( $previous && !$errors ) { $dbw->delete( 'linter', [ 'linter_page' => $this->pageId ], __METHOD__ ); return [ 'deleted' => true, 'added' => 0 ]; } else { $toInsert = []; $toDelete = $previous; // Diff previous and errors foreach ( $errors as $error ) { $uniqueId = $error->id(); if ( isset( $previous[$uniqueId] ) ) { unset( $toDelete[$uniqueId] ); } else { $toInsert[] = $error; } } } if ( $toDelete ) { $ids = []; foreach ( $toDelete as $lintError ) { if ( $lintError->lintId ) { $ids[] = $lintError->lintId; } } $dbw->delete( 'linter', [ 'linter_id' => $ids ], __METHOD__ ); } if ( $toInsert ) { $dbw->insert( 'linter', array_map( [ $this, 'serializeError' ], $toInsert ), __METHOD__ ); } return [ 'deleted' => count( $toDelete ), 'added' => count( $toInsert ), ]; } }