Selaa lähdekoodia

Implement MongoGridFSFile

Olivier Lechevalier 10 vuotta sitten
vanhempi
commit
88a7e015e2

+ 73 - 8
lib/Mongo/MongoGridFSFile.php

@@ -13,10 +13,11 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-class MongoGridFSFile {
+class MongoGridFSFile
+{
     /**
      * @link http://php.net/manual/en/class.mongogridfsfile.php#mongogridfsfile.props.file
-     * @var $file
+     * @var array
      */
     public $file;
 
@@ -32,21 +33,34 @@ class MongoGridFSFile {
      * @param array $file A file from the database
      * @return MongoGridFSFile Returns a new MongoGridFSFile
      */
-    public function __construct($gridfs, array $file) {}
+    public function __construct(MongoGridFS $gridfs, array $file)
+    {
+        $this->gridfs = $gridfs;
+        $this->file = $file;
+    }
 
     /**
      * Returns this file's filename
      * @link http://php.net/manual/en/mongogridfsfile.getfilename.php
      * @return string Returns the filename
      */
-    public function getFilename() {}
+    public function getFilename()
+    {
+        if (isset($this->file['filename'])) {
+            return $this->file['filename'];
+        }
+        return null;
+    }
 
     /**
      * Returns this file's size
      * @link http://php.net/manual/en/mongogridfsfile.getsize.php
      * @return int Returns this file's size
      */
-    public function getSize() {}
+    public function getSize()
+    {
+        return $this->file['length'];
+    }
 
     /**
      * Writes this file to the filesystem
@@ -54,14 +68,35 @@ class MongoGridFSFile {
      * @param string $filename The location to which to write the file (path+filename+extension). If none is given, the stored filename will be used.
      * @return int Returns the number of bytes written
      */
-    public function write($filename = null) {}
+    public function write($filename = null)
+    {
+        if ($filename === null) {
+            $filename = $this->getFilename();
+        }
+        if (empty($filename)) {
+            $filename = 'file';
+        }
+
+        $handle = fopen($filename, 'w');
+        $written = $this->writeFromRessource($handle);
+        fclose($handle);
+        return $written;
+    }
 
     /**
      * This will load the file into memory. If the file is bigger than your memory, this will cause problems!
      * @link http://php.net/manual/en/mongogridfsfile.getbytes.php
      * @return string Returns a string of the bytes in the file
      */
-    public function getBytes() {}
+    public function getBytes()
+    {
+        $result = '';
+        $chunks = $this->getChunks();
+        foreach ($chunks as $chunk) {
+            $result .= $chunk['data']->bin;
+        }
+        return $result;
+    }
 
     /**
      * This method returns a stream resource that can be used to read the stored file with all file functions in PHP.
@@ -71,5 +106,35 @@ class MongoGridFSFile {
      * @link http://php.net/manual/en/mongogridfsfile.getresource.php
      * @return resource Returns a resource that can be used to read the file with
      */
-    public function getResource() {}
+    public function getResource()
+    {
+        $handle = tmpfile();
+        $this->writeFromRessource($handle);
+        fseek($handle, 0);
+        return $handle;
+    }
+
+    private function writeFromRessource($handle)
+    {
+
+        if (! $handle) {
+            trigger_error(E_ERROR, 'can not open the destination file');
+        }
+        $written = 0;
+        $chunks = $this->getChunks();
+        foreach ($chunks as $chunk) {
+            $written += fwrite($handle, $chunk['data']->bin);
+        }
+        return $written;
+    }
+
+    private function getChunks()
+    {
+        return $chunks = $this->gridfs->chunks->find(
+            ['files_id' => new \MongoDB\BSON\ObjectID((string) $this->file['_id'])],
+            ['data' => 1],
+            ['n' => 1]
+        );
+    }
+
 }

+ 0 - 13
tests/Alcaeus/MongoDbAdapter/MongoCollectionTest.php

@@ -351,19 +351,6 @@ class MongoCollectionTest extends TestCase
         $this->assertSame(0, $newCollection->count());
     }
 
-    public function testRemoveMultiple()
-    {
-        $collection = $this->getCollection();
-
-
-        $collection->insert(['foo' => 'bar']);
-        $collection->insert(['foo' => 'bar']);
-        $collection->remove([], ['justOne' => false]);
-
-        $newCollection = $this->getCheckDatabase()->selectCollection('test');
-        $this->assertSame(0, $newCollection->count());
-    }
-
     public function testSaveUpdate()
     {
         $id = '54203e08d51d4a1f868b456e';

+ 123 - 0
tests/Alcaeus/MongoDbAdapter/MongoGridFSFileTest.php

@@ -0,0 +1,123 @@
+<?php
+
+namespace Alcaeus\MongoDbAdapter\Tests;
+
+class MongoGridFSFileTest extends TestCase
+{
+    public function testFileProperty()
+    {
+        $file = $this->getFile();
+        $this->assertArrayHasKey('_id', $file->file);
+        $this->assertArraySubset(
+            [
+                'length' => 666,
+                'filename' => 'file',
+                'md5' => 'md5',
+            ],
+            $file->file
+        );
+    }
+
+    public function testGetFilename()
+    {
+        $file = $this->getFile();
+        $this->assertSame('file', $file->getFilename());
+    }
+
+    public function testGetSize()
+    {
+        $file = $this->getFile();
+        $this->assertSame(666, $file->getSize());
+    }
+
+    public function testWrite()
+    {
+        $id = $this->prepareFile();
+        $filename = '/tmp/test-mongo-grid-fs-file';
+        @unlink($filename);
+        $file = $this->getFile(['_id' => $id, 'length' => 4, 'filename' => $filename]);
+
+        $file->write();
+
+        $this->assertTrue(file_exists($filename));
+        $this->assertSame('e2fc714c4727ee9395f324cd2e7f331f', md5_file($filename));
+        unlink($filename);
+    }
+
+    public function testWriteSpecifyFilename()
+    {
+        $id = $this->prepareFile();
+        $filename = '/tmp/test-mongo-grid-fs-file';
+        @unlink($filename);
+        $file = $this->getFile(['_id' => $id, 'length' => 4]);
+
+        $file->write($filename);
+
+        $this->assertTrue(file_exists($filename));
+        $this->assertSame('e2fc714c4727ee9395f324cd2e7f331f', md5_file($filename));
+        unlink($filename);
+    }
+
+    public function testGetBytes()
+    {
+        $id = $this->prepareFile();
+        $file = $this->getFile(['_id' => $id, 'length' => 4]);
+
+        $result = $file->getBytes();
+
+        $this->assertSame('abcd', $result);
+    }
+
+    public function testGetResource()
+    {
+        $id = $this->prepareFile();
+        $file = $this->getFile(['_id' => $id, 'length' => 4]);
+
+        $result = $file->getResource();
+
+        $this->assertTrue(is_resource($result));
+        $this->assertSame('abcd', stream_get_contents($result));
+    }
+
+    /**
+     * @var \MongoGridFSFile
+     */
+    protected function getFile($extra = [])
+    {
+        $file = [
+            '_id' => new \MongoID(),
+            'length' => 666,
+            'filename' => 'file',
+            'md5' => 'md5',
+        ];
+        $file = array_merge($file, $extra);
+        return new \MongoGridFSFile($this->getGridFS(), $file);
+    }
+
+    /**
+     * @var \MongoID
+     */
+    protected function prepareFile($data = 'abcd', $extra = [])
+    {
+        $collection = $this->getGridFS();
+
+        // to make sure we have multiple chunks
+        $extra += ['chunkSize' => 2];
+
+        return $collection->storeBytes($data, $extra);
+    }
+
+    /**
+     * @param string $name
+     * @param \MongoDB|null $database
+     * @return \MongoGridFS
+     */
+    protected function getGridFS($name = 'testfs', \MongoDB $database = null)
+    {
+        if ($database === null) {
+            $database = $this->getDatabase();
+        }
+
+        return new \MongoGridFS($database, $name);
+    }
+}