Merge "Selenium: replace UserLoginPage with BlankPage where possible"
[lhc/web/wiklou.git] / includes / historyblob / HistoryBlobStub.php
1 <?php
2 /**
3 * Efficient concatenated text storage.
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 use MediaWiki\MediaWikiServices;
24
25 /**
26 * Pointer object for an item within a CGZ blob stored in the text table.
27 */
28 class HistoryBlobStub {
29 /**
30 * @var array One-step cache variable to hold base blobs; operations that
31 * pull multiple revisions may often pull multiple times from the same
32 * blob. By keeping the last-used one open, we avoid redundant
33 * unserialization and decompression overhead.
34 */
35 protected static $blobCache = [];
36
37 /** @var int */
38 public $mOldId;
39
40 /** @var string */
41 public $mHash;
42
43 /** @var string */
44 public $mRef;
45
46 /**
47 * @param string $hash The content hash of the text
48 * @param int $oldid The old_id for the CGZ object
49 */
50 function __construct( $hash = '', $oldid = 0 ) {
51 $this->mHash = $hash;
52 }
53
54 /**
55 * Sets the location (old_id) of the main object to which this object
56 * points
57 * @param int $id
58 */
59 function setLocation( $id ) {
60 $this->mOldId = $id;
61 }
62
63 /**
64 * Sets the location (old_id) of the referring object
65 * @param string $id
66 */
67 function setReferrer( $id ) {
68 $this->mRef = $id;
69 }
70
71 /**
72 * Gets the location of the referring object
73 * @return string
74 */
75 function getReferrer() {
76 return $this->mRef;
77 }
78
79 /**
80 * @return string|false
81 */
82 function getText() {
83 if ( isset( self::$blobCache[$this->mOldId] ) ) {
84 $obj = self::$blobCache[$this->mOldId];
85 } else {
86 $dbr = wfGetDB( DB_REPLICA );
87 $row = $dbr->selectRow(
88 'text',
89 [ 'old_flags', 'old_text' ],
90 [ 'old_id' => $this->mOldId ]
91 );
92
93 if ( !$row ) {
94 return false;
95 }
96
97 $flags = explode( ',', $row->old_flags );
98 if ( in_array( 'external', $flags ) ) {
99 $url = $row->old_text;
100 $parts = explode( '://', $url, 2 );
101 if ( !isset( $parts[1] ) || $parts[1] == '' ) {
102 return false;
103 }
104 $row->old_text = MediaWikiServices::getInstance()
105 ->getExternalStoreAccess()
106 ->fetchFromURL( $url );
107 }
108
109 if ( !in_array( 'object', $flags ) ) {
110 return false;
111 }
112
113 if ( in_array( 'gzip', $flags ) ) {
114 // This shouldn't happen, but a bug in the compress script
115 // may at times gzip-compress a HistoryBlob object row.
116 $obj = unserialize( gzinflate( $row->old_text ) );
117 } else {
118 $obj = unserialize( $row->old_text );
119 }
120
121 if ( !is_object( $obj ) ) {
122 // Correct for old double-serialization bug.
123 $obj = unserialize( $obj );
124 }
125
126 // Save this item for reference; if pulling many
127 // items in a row we'll likely use it again.
128 $obj->uncompress();
129 self::$blobCache = [ $this->mOldId => $obj ];
130 }
131
132 return $obj->getItem( $this->mHash );
133 }
134
135 /**
136 * Get the content hash
137 *
138 * @return string
139 */
140 function getHash() {
141 return $this->mHash;
142 }
143 }
144
145 // phpcs:ignore Generic.CodeAnalysis.UnconditionalIfStatement.Found
146 if ( false ) {
147 // Blobs generated by MediaWiki < 1.5 on PHP 4 were serialized with the
148 // class name coerced to lowercase. We can improve efficiency by adding
149 // autoload entries for the lowercase variants of these classes (T166759).
150 // The code below is never executed, but it is picked up by the AutoloadGenerator
151 // parser, which scans for class_alias() calls.
152 class_alias( HistoryBlobStub::class, 'historyblobstub' );
153 }