- $error = false;
- while ( count( $tryStores ) > 0 ) {
- $index = mt_rand( 0, count( $tryStores ) - 1 );
- $storeUrl = $tryStores[$index];
- wfDebug( __METHOD__ . ": trying $storeUrl\n" );
- list( $proto, $path ) = explode( '://', $storeUrl, 2 );
- $store = self::getStoreObject( $proto, $params );
- if ( $store === false ) {
- throw new MWException( "Invalid external storage protocol - $storeUrl" );
- }
-
- try {
- if ( $store->isReadOnly( $path ) ) {
- $msg = 'read only';
- } else {
- $url = $store->store( $path, $data );
- if ( $url !== false ) {
- return $url; // a store accepted the write; done!
- }
- $msg = 'operation failed';
- }
- } catch ( Exception $error ) {
- $msg = 'caught exception';
- }
-
- 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 ($msg)" );
- }
- // All stores failed
- if ( $error ) {
- throw $error; // rethrow the last error
- } else {
- throw new MWException( "Unable to store text to external storage" );
- }
- }
-
- /**
- * @return bool Whether all the default insertion stores are marked as read-only
- * @since 1.31
- */
- public static function defaultStoresAreReadOnly() {
- global $wgDefaultExternalStore;
-
- $tryStores = (array)$wgDefaultExternalStore;
- if ( !$tryStores ) {
- return false; // no stores exists which can be "read only"
- }
-
- foreach ( $tryStores as $storeUrl ) {
- list( $proto, $path ) = explode( '://', $storeUrl, 2 );
- $store = self::getStoreObject( $proto, [] );
- if ( !$store->isReadOnly( $path ) ) {
- return false; // at least one store is not read-only
- }
- }
-
- return true; // all stores are read-only