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