X-Git-Url: http://git.cyclocoop.org/?a=blobdiff_plain;f=includes%2FExternalStore.php;h=ddb40c32dccfd0aee34216f4739bcf765e019d04;hb=45f9da8ad700d5ee278f3db84e555b41ca26a138;hp=71c4aaac229dbafcb0cc0396286970a43df9abad;hpb=679b0e69b89f988a04252d27fe12fae51a4c42ee;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/ExternalStore.php b/includes/ExternalStore.php index 71c4aaac22..ddb40c32dc 100644 --- a/includes/ExternalStore.php +++ b/includes/ExternalStore.php @@ -1,70 +1,143 @@ mParams = $params; + } + + /** + * Fetch data from given URL + * + * @param $url String: The URL of the text to get + * @param $params Array: associative array of parameters for the ExternalStore object. + * @return The text stored or false on error + */ + static function fetchFromURL( $url, $params = array() ) { global $wgExternalStores; - if (!$wgExternalStores) + if( !$wgExternalStores ) + return false; + + $parts = explode( '://', $url, 2 ); + + if ( count( $parts ) != 2 ) { return false; + } + + list( $proto, $path ) = $parts; - @list($proto,$path)=explode('://',$url,2); - /* Bad URL */ - if ($path=="") + if ( $path == '' ) { // Bad URL return false; + } - $store =& ExternalStore::getStoreObject( $proto ); + $store = self::getStoreObject( $proto, $params ); if ( $store === false ) return false; - return $store->fetchFromURL($url); + return $store->fetchFromURL( $url ); } /** - * Get an external store object of the given type + * Get an external store object of the given type, with the given parameters + * + * @param $proto String: type of external storage, should be a value in $wgExternalStores + * @param $params Array: associative array of parameters for the ExternalStore object. + * @return ExternalStore subclass or false on error */ - function &getStoreObject( $proto ) { + static function getStoreObject( $proto, $params = array() ) { global $wgExternalStores; - if (!$wgExternalStores) + if( !$wgExternalStores ) return false; /* Protocol not enabled */ - if (!in_array( $proto, $wgExternalStores )) + if( !in_array( $proto, $wgExternalStores ) ) return false; - $class='ExternalStore'.ucfirst($proto); - /* Preloaded modules might exist, especially ones serving multiple protocols */ - if (!class_exists($class)) { - if (!include_once($class.'.php')) - return false; + $class = 'ExternalStore' . ucfirst( $proto ); + /* Any custom modules should be added to $wgAutoLoadClasses for on-demand loading */ + if( !class_exists( $class ) ) { + return false; } - $store=new $class(); - return $store; + + return new $class($params); } /** * Store a data item to an external store, identified by a partial URL - * The protocol part is used to identify the class, the rest is passed to the - * class itself as a parameter. - * Returns the URL of the stored data item, or false on error + * The protocol part is used to identify the class, the rest is passed to the + * class itself as a parameter. + * @return The URL of the stored data item, or false on error */ - function insert( $url, $data ) { + static function insert( $url, $data, $params = array() ) { list( $proto, $params ) = explode( '://', $url, 2 ); - $store =& ExternalStore::getStoreObject( $proto ); + $store = self::getStoreObject( $proto, $params ); if ( $store === false ) { return false; } else { return $store->store( $params, $data ); } } + + /** + * Like insert() above, but does more of the work for us. + * This function does not need a url param, it builds it by + * itself. It also fails-over to the next possible clusters. + * + * @param $data String + * @param $storageParams Array: associative array of parameters for the ExternalStore object. + * @return The URL of the stored data item, or false on error + */ + public static function insertToDefault( $data, $storageParams = array() ) { + global $wgDefaultExternalStore; + $tryStores = (array)$wgDefaultExternalStore; + $error = false; + while ( count( $tryStores ) > 0 ) { + $index = mt_rand(0, count( $tryStores ) - 1); + $storeUrl = $tryStores[$index]; + wfDebug( __METHOD__.": trying $storeUrl\n" ); + list( $proto, $params ) = explode( '://', $storeUrl, 2 ); + $store = self::getStoreObject( $proto, $storageParams ); + if ( $store === false ) { + throw new MWException( "Invalid external storage protocol - $storeUrl" ); + } + try { + $url = $store->store( $params, $data ); // Try to save the object + } catch ( DBConnectionError $error ) { + $url = false; + } catch( DBQueryError $error ) { + $url = false; + } + if ( $url ) { + return $url; // Done! + } else { + unset( $tryStores[$index] ); // Don't try this one again! + $tryStores = array_values( $tryStores ); // Must have consecutive keys + wfDebugLog( 'ExternalStorage', "Unable to store text to external storage $storeUrl" ); + } + } + // All stores failed + if ( $error ) { + // Rethrow the last connection error + throw $error; + } else { + throw new MWException( "Unable to store text to external storage" ); + } + } + + /** Like insertToDefault, but inserts on another wiki */ + public static function insertToForeignDefault( $data, $wiki ) { + return self::insertToDefault( $data, array( 'wiki' => $wiki ) ); + } } -?>