55 protected function initialize( $mode = self::LOAD_ONLY ) {
56 if ( $this->mName ===
null && $this->mID ===
null ) {
57 throw new MWException( __METHOD__ .
' has both names and IDs null' );
58 }
elseif ( $this->mID ===
null ) {
59 $where = [
'cat_title' => $this->mName ];
60 }
elseif ( $this->mName ===
null ) {
61 $where = [
'cat_id' => $this->mID ];
68 $row =
$dbr->selectRow(
70 [
'cat_id',
'cat_title',
'cat_pages',
'cat_subcats',
'cat_files' ],
76 # Okay, there were no contents. Nothing to initialize.
77 if ( $this->mTitle ) {
78 # If there is a title object but no record in the category table,
79 # treat this as an empty category.
81 $this->mName = $this->mTitle->getDBkey();
86 # If the title exists, call refreshCounts to add a row for it.
87 if ( $mode === self::LAZY_INIT_ROW && $this->mTitle->exists() ) {
88 DeferredUpdates::addCallableUpdate( [ $this,
'refreshCounts' ] );
97 $this->mID = $row->cat_id;
98 $this->mName = $row->cat_title;
99 $this->mPages = $row->cat_pages;
100 $this->mSubcats = $row->cat_subcats;
101 $this->mFiles = $row->cat_files;
103 # (T15683) If the count is negative, then 1) it's obviously wrong
104 # and should not be kept, and 2) we *probably* don't have to scan many
105 # rows to obtain the correct figure, so let's risk a one-time recount.
106 if ( $this->mPages < 0 || $this->mSubcats < 0 || $this->mFiles < 0 ) {
107 $this->mPages =
max( $this->mPages, 0 );
108 $this->mSubcats =
max( $this->mSubcats, 0 );
109 $this->mFiles =
max( $this->mFiles, 0 );
111 if ( $mode === self::LAZY_INIT_ROW ) {
112 DeferredUpdates::addCallableUpdate( [ $this,
'refreshCounts' ] );
128 $title = Title::makeTitleSafe(
NS_CATEGORY, $name );
135 $cat->mName = $title->getDBkey();
150 $cat->mName = $title->getDBkey();
163 $cat->mID =
intval( $id );
183 # NOTE: the row often results from a LEFT JOIN on categorylinks. This may result in
184 # all the cat_xxx fields being null, if the category page exists, but nothing
185 # was ever added to the category. This case should be treated link an empty
186 # category, if possible.
188 if ( $row->cat_title ===
null ) {
189 if ( $title ===
null ) {
190 # the name is probably somewhere in the row, for example as page_title,
191 # but we can't know that here...
194 # if we have a title object, fetch the category name from there
195 $cat->mName = $title->getDBkey();
203 $cat->mName = $row->cat_title;
204 $cat->mID = $row->cat_id;
205 $cat->mSubcats = $row->cat_subcats;
206 $cat->mPages = $row->cat_pages;
207 $cat->mFiles = $row->cat_files;
217 return $this->
getX(
'mName' );
224 return $this->
getX(
'mID' );
231 return $this->
getX(
'mPages' );
238 return $this->
getX(
'mSubcats' );
245 return $this->
getX(
'mFiles' );
252 if ( $this->mTitle ) {
253 return $this->mTitle;
256 if ( !$this->
initialize( self::LAZY_INIT_ROW ) ) {
260 $this->mTitle = Title::makeTitleSafe(
NS_CATEGORY, $this->mName );
261 return $this->mTitle;
274 $conds = [
'cl_to' => $this->
getName(),
'cl_from = page_id' ];
275 $options = [
'ORDER BY' =>
'cl_sortkey' ];
281 if ( $offset !==
'' ) {
282 $conds[] =
'cl_sortkey > ' .
$dbr->addQuotes( $offset );
287 [
'page',
'categorylinks' ],
288 [
'page_id',
'page_namespace',
'page_title',
'page_len',
289 'page_is_redirect',
'page_latest' ],
304 private function getX( $key ) {
305 if ( $this->{$key} ===
null && !$this->
initialize( self::LAZY_INIT_ROW ) ) {
308 return $this->{$key};
321 # If we have just a category name, find out whether there is an
322 # existing row. Or if we have just an ID, get the name, because
323 # that's what categorylinks uses.
324 if ( !$this->
initialize( self::LOAD_ONLY ) ) {
329 # Avoid excess contention on the same category (T162121)
330 $name = __METHOD__ .
':' .
md5( $this->mName );
331 $scopedLock = $dbw->getScopedLockAndFlush( $name, __METHOD__, 0 );
332 if ( !$scopedLock ) {
336 $dbw->startAtomic( __METHOD__ );
340 $dbw->lockForUpdate(
'category', [
'cat_title' => $this->mName ], __METHOD__ );
344 $dbw->selectRowCount(
345 [
'categorylinks',
'page' ],
347 [
'cl_to' => $this->mName,
'page_id = cl_from' ],
349 [
'LOCK IN SHARE MODE' ]
352 $catCond = $dbw->conditional( [
'page_namespace' =>
NS_CATEGORY ], 1,
'NULL' );
353 $fileCond = $dbw->conditional( [
'page_namespace' =>
NS_FILE ], 1,
'NULL' );
354 $result = $dbw->selectRow(
355 [
'categorylinks',
'page' ],
357 'pages' =>
'COUNT(*)',
358 'subcats' =>
"COUNT($catCond)",
359 'files' =>
"COUNT($fileCond)"
361 [
'cl_to' => $this->mName,
'page_id = cl_from' ],
365 $shouldExist = $result->pages > 0 || $this->
getTitle()->exists();
368 if ( $shouldExist ) {
369 # The category row already exists, so do a plain UPDATE instead
370 # of INSERT...ON DUPLICATE KEY UPDATE to avoid creating a gap
371 # in the cat_id sequence. The row may or may not be "affected".
375 'cat_pages' => $result->pages,
376 'cat_subcats' => $result->subcats,
377 'cat_files' => $result->files
379 [
'cat_title' => $this->mName ],
383 # The category is empty and has no description page, delete it
386 [
'cat_title' => $this->mName ],
391 }
elseif ( $shouldExist ) {
392 # The category row doesn't exist but should, so create it. Use
393 # upsert in case of races.
397 'cat_title' => $this->mName,
398 'cat_pages' => $result->pages,
399 'cat_subcats' => $result->subcats,
400 'cat_files' => $result->files
404 'cat_pages' => $result->pages,
405 'cat_subcats' => $result->subcats,
406 'cat_files' => $result->files
414 $dbw->endAtomic( __METHOD__ );
416 # Now we should update our local counts.
417 $this->mPages = $result->pages;
418 $this->mSubcats = $result->subcats;
419 $this->mFiles = $result->files;
438 $hasLink = $dbw->selectField(
441 [
'cl_to' => $this->
getName() ],
450 $hasBadRow = $dbw->selectField(
453 [
'cat_title' => $this->
getName(),
'cat_pages <= 0' ],
and that you know you can do these things To protect your we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights These restrictions translate to certain responsibilities for you if you distribute copies of the or if you modify it For if you distribute copies of such a whether gratis or for a you must give the recipients all the rights that you have You must make sure that receive or can get the source code And you must show them these terms so they know their rights We protect your rights with two and(2) offer you this license which gives you legal permission to copy
wfReadOnly()
Check whether the wiki is in read-only mode.
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
Category objects are immutable, strictly speaking.
static newFromID( $id)
Factory function.
static newFromName( $name)
Factory function.
refreshCountsIfEmpty()
Call refreshCounts() if there are no entries in the categorylinks table or if the category table has ...
$mName
Name of the category, normalized to DB-key form.
static newFromTitle( $title)
Factory function.
initialize( $mode=self::LOAD_ONLY)
Set up all member variables using a database query.
$mPages
Counts of membership (cat_pages, cat_subcats, cat_files)
getMembers( $limit=false, $offset='')
Fetch a TitleArray of up to $limit category members, beginning after the category sort key $offset.
refreshCounts()
Refresh the counts for this category.
getX( $key)
Generic accessor.
Title $mTitle
Category page title.
static newFromRow( $row, $title=null)
Factory function, for constructing a Category object from a result set.
static newFromResult( $res)
Represents a title within MediaWiki.
namespace being checked & $result
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped & $options
namespace and then decline to actually register it file or subcat img or subcat $title