http://www.mediawiki.org/wiki/Special:Code/MediaWiki/100164
Revision: 100164
Author: blobaugh
Date: 2011-10-18 21:36:50 +0000 (Tue, 18 Oct 2011)
Log Message:
-----------
Updated the architecture for the FileBackend to support multiple data stores
registered at the same time through and external interface
Modified Paths:
--------------
branches/FileBackend/phase3/includes/filerepo/FileBackend.php
Added Paths:
-----------
branches/FileBackend/phase3/includes/filerepo/AbstractFileStore.php
branches/FileBackend/phase3/includes/filerepo/dataStores/
branches/FileBackend/phase3/includes/filerepo/dataStores/LocalFileSystemDataStore.php
branches/FileBackend/phase3/includes/filerepo/dataStores/MemcachedDataStore.php
Added: branches/FileBackend/phase3/includes/filerepo/AbstractFileStore.php
===================================================================
--- branches/FileBackend/phase3/includes/filerepo/AbstractFileStore.php
(rev 0)
+++ branches/FileBackend/phase3/includes/filerepo/AbstractFileStore.php
2011-10-18 21:36:50 UTC (rev 100164)
@@ -0,0 +1,42 @@
+<?php
+
+/**
+ * A particular data store may not support every operation. If it does not
support
+ * an operation that should return -1. It should not throw an exception as
+ * the operation in question may be naively called from a loop that does not
+ * check for support
+ */
+abstract class AbstractFileStore {
+
+ abstract store( $params ) {
+ return -1;
+ }
+
+ abstract relocate( $params ) {
+ return -1;
+ }
+
+ abstract copy( $params ) {
+ return -1;
+ }
+
+ abstract delete( $params ) {
+ return -1;
+ }
+
+ abstract move( $params ) {
+ return -1;
+ }
+
+ abstract concatinate( $params ) {
+ return -1;
+ }
+
+ abstract fileExists( $params ) {
+ return -1;
+ }
+
+ abstract getLocalCopy( $params ) {
+ return -1;
+ }
+} // end class
\ No newline at end of file
Property changes on:
branches/FileBackend/phase3/includes/filerepo/AbstractFileStore.php
___________________________________________________________________
Added: svn:eol-style
+ native
Modified: branches/FileBackend/phase3/includes/filerepo/FileBackend.php
===================================================================
--- branches/FileBackend/phase3/includes/filerepo/FileBackend.php
2011-10-18 21:21:12 UTC (rev 100163)
+++ branches/FileBackend/phase3/includes/filerepo/FileBackend.php
2011-10-18 21:36:50 UTC (rev 100164)
@@ -1,123 +1,232 @@
<?php
+/**
+ * Handles all operations on real files. The FileBacked is designed to be an
+ * abstraction layer that allows developers to create a new class that extends
+ * this class to use any arbitrary data store for media uploads. To manipulate
+ * files contained within the current MediaWiki installation the dev/extension
+ * writer need only to interact with the doOps() method in this class
+ *
+ * PLEASE PLEASE leave feedback on improving this file abstraction layer
+ *
+ * @todo Implement streamFile
+ * @todo Implement enumFiles
+ * @todo Design and implement smart file chunking uploads
+ * @todo Fill in $this->validOperations via reflection into AbstractDataStore
+ * @todo implement a method to ensure there is a primary store that
registerDataStore can use
+ * @todo Alter registerDataStore with the above to set incoming data store as
primary if one does not exist
+ * @todo Alter registerDataStore to alter the current primary to false if
isPrimaryStore is set to true on incoming
+ * @todo Register data store in global and existing in
includes/filerepo/dataStores inside of constructor
+ */
abstract class FileBackend {
+ /*
+ * This could potentially be populated via reflection. Look at the methods
+ * available in the AbstratDataStore object
+ */
+ protected $validOperations = array('store'/* add a new file to data store
*/,
+ 'relocate' /* used to relocate all
files in store */,
+ 'copy',
+ 'delete',
+ 'move',
+ 'concatinate',
+ 'fileExists',
+ 'getFileProps',
+ 'getLocalCopy'
+ /* 'streamFile' not yet implemented ,
*/
+ /* 'enumFiles' not yet implemented*/
+ );
+ private $registeredDataStores = array();
+
+ /**
+ * Constructor, currently does nothing
+ */
public function __construct();
+
+ /**
+ * This is the main entry point into the file system back end. Callers will
+ * supply a list of operations to be performed (almost like a script) as an
+ * array. This class will then handle handing the operations off to the
+ * correct file store module
+ *
+ * For more information about a specific operation see the abstract method
+ * definitions comment block
+ *
+ * Using $ops
+ * $ops is an array of arrays. The first array holds a list of operations.
+ * The inner array contains the parameters, E.G:
+ * <code>
+ * $ops = array(
+ * array('operation' => 'store',
+ * 'src' => '/tmp/uploads/picture.png',
+ * 'dest' => 'zone/uploadedFilename.png'
+ * )
+ * );
+ * </code>
+ * @param Array $ops - Array of arrays containing N operations to execute
IN ORDER
+ * @return Status
+ */
public function doOps($ops) {
if(!is_array($ops)) {
throw new MWException(__METHOD__ . " not provided with an
operations array");
}
+ $statusObject = ''; // some sort of status object that can hold other
status objects
+
foreach($ops AS $op) {
-
- switch ($op['operations']) {
+ switch ($op['operation']) {
case 'move':
- $this->move($params);
+ $statusObject->append($this->commonCaller('move', $op));
break;
case 'delete':
- $this->delete($params);
+ $statusObject->append($this->commonCaller('delete', $op));
break;
case 'copy':
- $result = $this->copy();
+ $statusObject->append($this->copy());
+ break;
+ case 'getFileProps':
+ $tmpFile = $this->getLocalCopy();
+ $statusObject->append($this->getFileProps($tmpFile));
default:
- throw new MWException("$op unknown in " . __METHOD__);
+ $statusObject->append('Unknown data store operation ' .
$op['operation']);
}
}
+
+ return 'STATUS OBJECT';
}
-
/**
- * Store a file to a given destination.
*
- * @param $srcPath String: source path or virtual URL
- * @param $dstZone String: destination zone
- * @param $dstRel String: destination relative path
- * @param $flags Integer: bitwise combination of the following flags:
- * self::DELETE_SOURCE Delete the source file after upload
- * self::OVERWRITE Overwrite an existing destination file
instead of failing
- * self::OVERWRITE_SAME Overwrite the file if the destination
exists and has the
- * same contents as the source
- * @return FileRepoStatus
+ * @param <type> $dataStoreObject
+ * @param <type> $isPrimaryStore
*/
- abstract function store( $srcPath, $dstZone, $dstRel, $flags = 0 );
+ public function registerDataStoreModule($dataStoreObject, $isPrimaryStore
= false) {
+ if(is_subclassof($dataStoreObject, 'AbstractDataStore')) {
+ $this->registeredDataStores[] = array($dataSourceObject,
$isPrimaryStore);
+ }
+ }
- /**
- * Verify that a file exists in the file store
- *
- * @param String $file
- * @param Integer $flags
- * @return Boolean
- */
- abstract function fileExists( $file, $flags = 0 );
-
/**
- * Move a file to the deletion archive.
- * If no valid deletion archive exists, this may either delete the file
- * or throw an exception, depending on the preference of the repository
- * @param $srcRel Mixed: relative path for the file to be deleted
- * @param $archiveRel Mixed: relative path for the archive location.
- * Relative to a private archive directory.
- * @return FileRepoStatus object
- */
- abstract function delete( $srcRel, $archiveRel );
-
- /**
- * Moves a file from one place to another in the file store
+ * Ensure that there are data stores registered. If not then register the
+ * local file system as the default data store
*
- * @param String $srcRel - Path to source file
- * @param String $destRel - Path to new destination
- * @return Boolean
+ * @todo Create local data store object and set as default if no store
exists
*/
- abstract function move( $srcRel, $destRel );
+ private function ensureRegisteredDataStore() {
+ if(empty($this->registeredDataStores)) {
+ // $this->registerDataStoreModule(new LocalFileSystemDataStore())
+ }
+ }
- abstract function copy ( $src, $dest );
-
-
-
-
-
-
/**
- * Retreive a copy of a file from the file store and place it in the local
- * $wgTmpDirectory. A new TempLocalFile object should be created and
returned
- * that contains the local path to the file
- *
- * Please overload this class inside your storage module
- *
- * @return TempLocalFile
+ * The commonCaller() method is used for operations that contain the same
+ * code as many other options. It should be used as often as possible to
+ * reduce code duplication
+ * @param String $operation
+ * @param Array $params
+ * @return Status object of some sort
*/
- abstract function getLocalCopy( $file );
-
- /**
- * Return an associative array containing the file properties
- *
- * @param String $file
- * @return Array
- */
- public function getFileProps( $file ) {
- $file = $this->getLocalCopy( $file );
- return File::getPropsFromPath( $file->getPath() );
+ private function commonCaller($operation, $params) {
+ $statusObject = ''; // new Status object of some sort
+ foreach($this->registeredDataStores AS $store) {
+ $statusObject->append($store->$operation($params));
+ }
+ return $statusObject;
}
- /**
- * Returns an associative array containing a listing of the names of the
- * thumbnail files associated with the provided image file
- *
- * Please overload this class inside your storage module
- *
- * @param String $file - Name of file to retreive thumbnail listing for
- * @retrun Array
- */
- abstract function getThumbnailList( $file );
+// /**
+// * Store a file to a given destination.
+// *
+// * @param $srcPath String: source path or virtual URL
+// * @param $dstZone String: destination zone
+// * @param $dstRel String: destination relative path
+// * @param $flags Integer: bitwise combination of the following flags:
+// * self::DELETE_SOURCE Delete the source file after upload
+// * self::OVERWRITE Overwrite an existing destination file
instead of failing
+// * self::OVERWRITE_SAME Overwrite the file if the destination
exists and has the
+// * same contents as the source
+// * @return FileRepoStatus
+// */
+// abstract function store( $srcPath, $dstZone, $dstRel, $flags = 0 );
+//
+// /**
+// * Verify that a file exists in the file store
+// *
+// * @param String $file
+// * @param Integer $flags
+// * @return Boolean
+// */
+// abstract function fileExists( $file, $flags = 0 );
+//
+// /**
+// * Move a file to the deletion archive.
+// * If no valid deletion archive exists, this may either delete the file
+// * or throw an exception, depending on the preference of the repository
+// * @param $srcRel Mixed: relative path for the file to be deleted
+// * @param $archiveRel Mixed: relative path for the archive location.
+// * Relative to a private archive directory.
+// * @return FileRepoStatus object
+// */
+// abstract function delete( $srcRel, $archiveRel );
+//
+// /**
+// * Moves a file from one place to another in the file store
+// *
+// * @param String $srcRel - Path to source file
+// * @param String $destRel - Path to new destination
+// * @return Boolean
+// */
+// abstract function move( $srcRel, $destRel );
+//
+// abstract function copy ( $src, $dest );
+//
+//
+//
+//
+//
+//
+// /**
+// * Retreive a copy of a file from the file store and place it in the
local
+// * $wgTmpDirectory. A new TempLocalFile object should be created and
returned
+// * that contains the local path to the file
+// *
+// * Please overload this class inside your storage module
+// *
+// * @return TempLocalFile
+// */
+// abstract function getLocalCopy( $file );
+//
+// /**
+// * Return an associative array containing the file properties
+// *
+// * @param String $file
+// * @return Array
+// */
+// public function getFileProps( $file ) {
+// $file = $this->getLocalCopy( $file );
+// return File::getPropsFromPath( $file->getPath() );
+// }
+//
+// /**
+// * Returns an associative array containing a listing of the names of the
+// * thumbnail files associated with the provided image file
+// *
+// * Please overload this class inside your storage module
+// *
+// * @param String $file - Name of file to retreive thumbnail listing for
+// * @retrun Array
+// */
+// abstract function getThumbnailList( $file );
+//
+//
+//
+// public function addChunk() { throw new MWException( __METHOD__ . ' not
yet implemented.' ); }
+// public function concatenateChunks() { throw new MWException( __METHOD__
. ' not yet implemented.' ); }
-
- public function addChunk() { throw new MWException( __METHOD__ . ' not yet
implemented.' ); }
- public function concatenateChunks() { throw new MWException( __METHOD__ .
' not yet implemented.' ); }
-
} // end class
\ No newline at end of file
Added:
branches/FileBackend/phase3/includes/filerepo/dataStores/LocalFileSystemDataStore.php
===================================================================
---
branches/FileBackend/phase3/includes/filerepo/dataStores/LocalFileSystemDataStore.php
(rev 0)
+++
branches/FileBackend/phase3/includes/filerepo/dataStores/LocalFileSystemDataStore.php
2011-10-18 21:36:50 UTC (rev 100164)
@@ -0,0 +1,6 @@
+<?php
+
+/**
+
+ * @todo Create a module for the FileBackend that extends AbstractFileStore to
implement the logic for using the local file system as a data store
+ */
\ No newline at end of file
Property changes on:
branches/FileBackend/phase3/includes/filerepo/dataStores/LocalFileSystemDataStore.php
___________________________________________________________________
Added: svn:eol-style
+ native
Added:
branches/FileBackend/phase3/includes/filerepo/dataStores/MemcachedDataStore.php
===================================================================
---
branches/FileBackend/phase3/includes/filerepo/dataStores/MemcachedDataStore.php
(rev 0)
+++
branches/FileBackend/phase3/includes/filerepo/dataStores/MemcachedDataStore.php
2011-10-18 21:36:50 UTC (rev 100164)
@@ -0,0 +1,8 @@
+<?php
+
+/**
+ * Ehh? This could be an interesting one to implement. Could be set as the
+ * primary data store for registered data stores in FileBackend. That would
+ * cause it to be read first before hitting the real data store. It would also
+ * instantly populate the cache with newly stored files
+ */
\ No newline at end of file
Property changes on:
branches/FileBackend/phase3/includes/filerepo/dataStores/MemcachedDataStore.php
___________________________________________________________________
Added: svn:eol-style
+ native
_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs