1<?php 2 3use MediaWiki\MediaWikiServices; 4use MediaWiki\Revision\RevisionLookup; 5use MediaWiki\Revision\RevisionRecord; 6use MediaWiki\Revision\SlotRecord; 7 8/** 9 * Transitional trait used to share the methods between SearchResult and RevisionSearchResult. 10 * All the content of this trait can be moved to RevisionSearchResult once SearchResult is finally 11 * refactored into an abstract class. 12 * NOTE: This trait MUST NOT be used by something else than SearchResult and RevisionSearchResult. 13 * It will be removed without deprecation period once SearchResult 14 */ 15trait RevisionSearchResultTrait { 16 /** 17 * @var RevisionRecord 18 */ 19 protected $mRevisionRecord = null; 20 21 /** 22 * @var File 23 */ 24 protected $mImage = null; 25 26 /** 27 * @var Title|null 28 */ 29 protected $mTitle; 30 31 /** 32 * @var string 33 */ 34 protected $mText; 35 36 /** 37 * Initialize from a Title and if possible initializes a corresponding 38 * RevisionRecord and File. 39 * 40 * @param Title|null $title 41 */ 42 protected function initFromTitle( $title ) { 43 $this->mTitle = $title; 44 if ( $title !== null ) { 45 $services = MediaWikiServices::getInstance(); 46 $id = false; 47 Hooks::runner()->onSearchResultInitFromTitle( $title, $id ); 48 49 $this->mRevisionRecord = $services->getRevisionLookup()->getRevisionByTitle( 50 $title, 51 $id, 52 RevisionLookup::READ_NORMAL 53 ); 54 if ( $title->getNamespace() === NS_FILE ) { 55 $this->mImage = $services->getRepoGroup()->findFile( $title ); 56 } 57 } 58 } 59 60 /** 61 * Check if this is result points to an invalid title 62 * 63 * @return bool 64 */ 65 public function isBrokenTitle() { 66 return $this->mTitle === null; 67 } 68 69 /** 70 * Check if target page is missing, happens when index is out of date 71 * 72 * @return bool 73 */ 74 public function isMissingRevision() { 75 return !$this->mRevisionRecord && !$this->mImage; 76 } 77 78 /** 79 * @return Title|null 80 */ 81 public function getTitle() { 82 return $this->mTitle; 83 } 84 85 /** 86 * Get the file for this page, if one exists 87 * @return File|null 88 */ 89 public function getFile() { 90 return $this->mImage; 91 } 92 93 /** 94 * Lazy initialization of article text from DB 95 */ 96 protected function initText() { 97 if ( !isset( $this->mText ) ) { 98 if ( $this->mRevisionRecord != null ) { 99 $content = $this->mRevisionRecord->getContent( SlotRecord::MAIN ); 100 $this->mText = $content !== null ? $content->getTextForSearchIndex() : ''; 101 } else { // TODO: can we fetch raw wikitext for commons images? 102 $this->mText = ''; 103 } 104 } 105 } 106 107 /** 108 * @param string[] $terms Terms to highlight (this parameter is deprecated and ignored) 109 * @return string Highlighted text snippet, null (and not '') if not supported 110 */ 111 public function getTextSnippet( $terms = [] ) { 112 return ''; 113 } 114 115 /** 116 * @return string Highlighted title, '' if not supported 117 */ 118 public function getTitleSnippet() { 119 return ''; 120 } 121 122 /** 123 * @return string Highlighted redirect name (redirect to this page), '' if none or not supported 124 */ 125 public function getRedirectSnippet() { 126 return ''; 127 } 128 129 /** 130 * @return Title|null Title object for the redirect to this page, null if none or not supported 131 */ 132 public function getRedirectTitle() { 133 return null; 134 } 135 136 /** 137 * @return string Highlighted relevant section name, null if none or not supported 138 */ 139 public function getSectionSnippet() { 140 return ''; 141 } 142 143 /** 144 * @return Title|null Title object (pagename+fragment) for the section, 145 * null if none or not supported 146 */ 147 public function getSectionTitle() { 148 return null; 149 } 150 151 /** 152 * @return string Highlighted relevant category name or '' if none or not supported 153 */ 154 public function getCategorySnippet() { 155 return ''; 156 } 157 158 /** 159 * @return string Timestamp 160 */ 161 public function getTimestamp() { 162 if ( $this->mRevisionRecord ) { 163 return $this->mRevisionRecord->getTimestamp(); 164 } elseif ( $this->mImage ) { 165 return $this->mImage->getTimestamp(); 166 } 167 return ''; 168 } 169 170 /** 171 * @return int Number of words 172 */ 173 public function getWordCount() { 174 $this->initText(); 175 return str_word_count( $this->mText ); 176 } 177 178 /** 179 * @return int Size in bytes 180 */ 181 public function getByteSize() { 182 $this->initText(); 183 return strlen( $this->mText ); 184 } 185 186 /** 187 * @return string Interwiki prefix of the title (return iw even if title is broken) 188 */ 189 public function getInterwikiPrefix() { 190 return ''; 191 } 192 193 /** 194 * @return string Interwiki namespace of the title (since we likely can't resolve it locally) 195 */ 196 public function getInterwikiNamespaceText() { 197 return ''; 198 } 199 200 /** 201 * Did this match file contents (eg: PDF/DJVU)? 202 * @return bool 203 */ 204 public function isFileMatch() { 205 return false; 206 } 207} 208