MediaWiki
REL1_24
|
00001 <?php 00046 class ExternalStore { 00054 public static function getStoreObject( $proto, array $params = array() ) { 00055 global $wgExternalStores; 00056 00057 if ( !$wgExternalStores || !in_array( $proto, $wgExternalStores ) ) { 00058 return false; // protocol not enabled 00059 } 00060 00061 $class = 'ExternalStore' . ucfirst( $proto ); 00062 00063 // Any custom modules should be added to $wgAutoLoadClasses for on-demand loading 00064 return class_exists( $class ) ? new $class( $params ) : false; 00065 } 00066 00075 public static function fetchFromURL( $url, array $params = array() ) { 00076 $parts = explode( '://', $url, 2 ); 00077 if ( count( $parts ) != 2 ) { 00078 return false; // invalid URL 00079 } 00080 00081 list( $proto, $path ) = $parts; 00082 if ( $path == '' ) { // bad URL 00083 return false; 00084 } 00085 00086 $store = self::getStoreObject( $proto, $params ); 00087 if ( $store === false ) { 00088 return false; 00089 } 00090 00091 return $store->fetchFromURL( $url ); 00092 } 00093 00101 public static function batchFetchFromURLs( array $urls ) { 00102 $batches = array(); 00103 foreach ( $urls as $url ) { 00104 $scheme = parse_url( $url, PHP_URL_SCHEME ); 00105 if ( $scheme ) { 00106 $batches[$scheme][] = $url; 00107 } 00108 } 00109 $retval = array(); 00110 foreach ( $batches as $proto => $batchedUrls ) { 00111 $store = self::getStoreObject( $proto ); 00112 if ( $store === false ) { 00113 continue; 00114 } 00115 $retval += $store->batchFetchFromURLs( $batchedUrls ); 00116 } 00117 // invalid, not found, db dead, etc. 00118 $missing = array_diff( $urls, array_keys( $retval ) ); 00119 if ( $missing ) { 00120 foreach ( $missing as $url ) { 00121 $retval[$url] = false; 00122 } 00123 } 00124 00125 return $retval; 00126 } 00127 00139 public static function insert( $url, $data, array $params = array() ) { 00140 $parts = explode( '://', $url, 2 ); 00141 if ( count( $parts ) != 2 ) { 00142 return false; // invalid URL 00143 } 00144 00145 list( $proto, $path ) = $parts; 00146 if ( $path == '' ) { // bad URL 00147 return false; 00148 } 00149 00150 $store = self::getStoreObject( $proto, $params ); 00151 if ( $store === false ) { 00152 return false; 00153 } else { 00154 return $store->store( $path, $data ); 00155 } 00156 } 00157 00169 public static function insertToDefault( $data, array $params = array() ) { 00170 global $wgDefaultExternalStore; 00171 00172 return self::insertWithFallback( (array)$wgDefaultExternalStore, $data, $params ); 00173 } 00174 00187 public static function insertWithFallback( array $tryStores, $data, array $params = array() ) { 00188 $error = false; 00189 while ( count( $tryStores ) > 0 ) { 00190 $index = mt_rand( 0, count( $tryStores ) - 1 ); 00191 $storeUrl = $tryStores[$index]; 00192 wfDebug( __METHOD__ . ": trying $storeUrl\n" ); 00193 list( $proto, $path ) = explode( '://', $storeUrl, 2 ); 00194 $store = self::getStoreObject( $proto, $params ); 00195 if ( $store === false ) { 00196 throw new MWException( "Invalid external storage protocol - $storeUrl" ); 00197 } 00198 try { 00199 $url = $store->store( $path, $data ); // Try to save the object 00200 } catch ( MWException $error ) { 00201 $url = false; 00202 } 00203 if ( strlen( $url ) ) { 00204 return $url; // Done! 00205 } else { 00206 unset( $tryStores[$index] ); // Don't try this one again! 00207 $tryStores = array_values( $tryStores ); // Must have consecutive keys 00208 wfDebugLog( 'ExternalStorage', 00209 "Unable to store text to external storage $storeUrl" ); 00210 } 00211 } 00212 // All stores failed 00213 if ( $error ) { 00214 throw $error; // rethrow the last error 00215 } else { 00216 throw new MWException( "Unable to store text to external storage" ); 00217 } 00218 } 00219 00226 public static function insertToForeignDefault( $data, $wiki ) { 00227 return self::insertToDefault( $data, array( 'wiki' => $wiki ) ); 00228 } 00229 }