public function exists_blob(BlobFile $objFile)
 {
     $listBlobOptions = new ListBlobsOptions();
     $listBlobOptions->setPrefix('save_image/' . $objFile->file_name);
     $listBlobResults = $this->blobRestProxy->listBlobs($this->containerName, $listBlobOptions);
     $arrBlobs = $listBlobResults->getBlobs();
     if (is_array($arrBlobs) && count($arrBlobs) > 0) {
         return true;
     }
     return false;
 }
Exemple #2
0
 /**
  * Emulates changing of directory name.
  *
  * @param string $path
  * @param string $newPath
  *
  * @return bool
  */
 public function renameDirectory($path, $newPath)
 {
     $sourcePath = $this->applyPathPrefix(rtrim($path, '/') . '/');
     $options = new ListBlobsOptions();
     $options->setPrefix($sourcePath);
     /** @var \WindowsAzure\Blob\Models\ListBlobsResult $listResults */
     $listResults = $this->client->listBlobs($this->container, $options);
     foreach ($listResults->getBlobs() as $blob) {
         /** @var \WindowsAzure\Blob\Models\Blob $blob */
         $this->client->copyBlob($this->container, $this->replacePath($blob->getName(), $path, $newPath), $this->container, $blob->getName());
         $this->client->deleteBlob($this->container, $blob->getName());
     }
     return true;
 }
Exemple #3
0
 /**
  * {@inheritDoc}
  */
 public function exists($key)
 {
     $this->init();
     $listBlobsOptions = new ListBlobsOptions();
     $listBlobsOptions->setPrefix($key);
     try {
         $blobsList = $this->blobProxy->listBlobs($this->containerName, $listBlobsOptions);
         foreach ($blobsList->getBlobs() as $blob) {
             if ($key === $blob->getName()) {
                 return true;
             }
         }
     } catch (ServiceException $e) {
         $this->failIfContainerNotFound($e, 'check if key exists');
         $errorCode = $this->getErrorCodeFromServiceException($e);
         throw new \RuntimeException(sprintf('Failed to check if key "%s" exists in container "%s": %s (%s).', $key, $this->containerName, $e->getErrorText(), $errorCode), $e->getCode());
     }
     return false;
 }
 /**
  * @covers WindowsAzure\Blob\Models\ListBlobsOptions::getIncludeUncommittedBlobs
  */
 public function testGetIncludeUncommittedBlobs()
 {
     // Setup
     $options = new ListBlobsOptions();
     $expected = true;
     $options->setIncludeUncommittedBlobs($expected);
     // Test
     $actual = $options->getIncludeUncommittedBlobs();
     // Assert
     $this->assertEquals($expected, $actual);
 }
Exemple #5
0
 /**
  * Lists all of the blobs in the given container.
  * 
  * @param string                  $container The container name.
  * @param Models\ListBlobsOptions $options   The optional parameters.
  * 
  * @return Models\ListBlobsResult
  * 
  * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd135734.aspx
  */
 public function listBlobs($container, $options = null)
 {
     Validate::isString($container, 'container');
     $method = Resources::HTTP_GET;
     $headers = array();
     $postParams = array();
     $queryParams = array();
     $path = $container;
     $statusCode = Resources::STATUS_OK;
     if (is_null($options)) {
         $options = new ListBlobsOptions();
     }
     $this->addOptionalQueryParam($queryParams, Resources::QP_TIMEOUT, $options->getTimeout());
     $this->addOptionalQueryParam($queryParams, Resources::QP_REST_TYPE, 'container');
     $this->addOptionalQueryParam($queryParams, Resources::QP_COMP, 'list');
     $this->addOptionalQueryParam($queryParams, Resources::QP_PREFIX, str_replace('\\', '/', $options->getPrefix()));
     $this->addOptionalQueryParam($queryParams, Resources::QP_MARKER, $options->getMarker());
     $this->addOptionalQueryParam($queryParams, Resources::QP_DELIMITER, $options->getDelimiter());
     $this->addOptionalQueryParam($queryParams, Resources::QP_MAX_RESULTS, $options->getMaxResults());
     $includeMetadata = $options->getIncludeMetadata();
     $includeSnapshots = $options->getIncludeSnapshots();
     $includeUncommittedBlobs = $options->getIncludeUncommittedBlobs();
     $includeValue = $this->groupQueryValues(array($includeMetadata ? 'metadata' : null, $includeSnapshots ? 'snapshots' : null, $includeUncommittedBlobs ? 'uncommittedblobs' : null));
     $this->addOptionalQueryParam($queryParams, Resources::QP_INCLUDE, $includeValue);
     $response = $this->send($method, $headers, $queryParams, $postParams, $path, $statusCode);
     $parsed = $this->dataSerializer->unserialize($response->getBody());
     return ListBlobsResult::create($parsed);
 }
 public static function getInterestingListBlobsOptions()
 {
     $ret = array();
     $options = new ListBlobsOptions();
     array_push($ret, $options);
     $options = new ListBlobsOptions();
     $options->setMaxResults(2);
     array_push($ret, $options);
     $options = new ListBlobsOptions();
     $options->setTimeout(10);
     array_push($ret, $options);
     $options = new ListBlobsOptions();
     $options->setTimeout(-10);
     array_push($ret, $options);
     $options = new ListBlobsOptions();
     $options->setPrefix(self::$nonExistBlobPrefix);
     array_push($ret, $options);
     $options = new ListBlobsOptions();
     $options->setPrefix(self::$testUniqueId);
     array_push($ret, $options);
     $options = new ListBlobsOptions();
     // Cannot set Marker to arbitrary values. Must only use if the previous request returns a NextMarker.
     //            $options->setMarker('abc');
     // So, add logic in listBlobsWorker to loop and setMarker if there is a NextMarker.
     $options->setMaxResults(2);
     $options->setPrefix(self::$testUniqueId);
     $options->setTimeout(10);
     array_push($ret, $options);
     $options = new ListBlobsOptions();
     $options->setMaxResults(3);
     $options->setPrefix(self::$testUniqueId);
     $options->setTimeout(10);
     array_push($ret, $options);
     $options = new ListBlobsOptions();
     $options->setMaxResults(4);
     $options->setPrefix(self::$testUniqueId);
     $options->setTimeout(10);
     array_push($ret, $options);
     return $ret;
 }
 /**
  * @covers WindowsAzure\Blob\BlobRestProxy::createBlobSnapshot
  * @covers WindowsAzure\Blob\BlobRestProxy::createPageBlob
  * @covers WindowsAzure\Blob\BlobRestProxy::deleteBlob
  * @covers WindowsAzure\Blob\BlobRestProxy::getBlob
  * @covers WindowsAzure\Blob\BlobRestProxy::listBlobs
  */
 private function createBlobSnapshotWorker($options, $container)
 {
     $blob = BlobServiceFunctionalTestData::getInterestingBlobName();
     // Make sure there is something to test
     $dataSize = 512;
     $this->restProxy->createPageBlob($container, $blob, $dataSize);
     $snapshot1 = $this->restProxy->createBlobSnapshot($container, $blob);
     if (!is_null($options)) {
         BlobServiceFunctionalTestData::fixEtagAccessCondition($options->getAccessCondition(), $snapshot1->getEtag());
     }
     try {
         $res = is_null($options) ? $this->restProxy->createBlobSnapshot($container, $blob) : $this->restProxy->createBlobSnapshot($container, $blob, $options);
         if (is_null($options)) {
             $options = new CreateBlobSnapshotOptions();
         }
         if (!is_null($options->getTimeout()) && $options->getTimeout() < 1) {
             $this->assertTrue(false, 'Expect negative timeouts in $options to throw');
         }
         if (!BlobServiceFunctionalTestData::passTemporalAccessCondition($options->getAccessCondition())) {
             $this->assertTrue(false, 'Expect failing temporal access condition should throw');
         }
         if (!BlobServiceFunctionalTestData::passTemporalAccessCondition($options->getAccessCondition())) {
             $this->assertTrue(false, 'Expect failing etag access condition to throw');
         }
         $listOptions = new ListBlobsOptions();
         $listOptions->setIncludeSnapshots(true);
         $listOptions->setPrefix($blob);
         $listBlobsResult = $this->restProxy->listBlobs($container == '' ? '$root' : $container, $listOptions);
         $blobs = $listBlobsResult->getBlobs();
         $getBlobOptions = new GetBlobOptions();
         $getBlobOptions->setSnapshot($res->getSnapshot());
         $getBlobResult = $this->restProxy->getBlob($container, $blob, $getBlobOptions);
         $this->verifyCreateBlobSnapshotWorker($res, $options, $blobs, $getBlobResult);
     } catch (ServiceException $e) {
         if (!is_null($options->getTimeout()) && $options->getTimeout() < 1) {
             $this->assertEquals(500, $e->getCode(), 'bad timeout: deleteHttpStatusCode');
         } else {
             if (!BlobServiceFunctionalTestData::passTemporalAccessCondition($options->getAccessCondition())) {
                 $this->assertEquals(412, $e->getCode(), 'bad temporal access condition IF_UNMODIFIED_SINCE: deleteHttpStatusCode');
             } else {
                 if (!BlobServiceFunctionalTestData::passEtagAccessCondition($options->getAccessCondition())) {
                     $this->assertEquals(412, $e->getCode(), 'bad etag access condition: deleteHttpStatusCode');
                 } else {
                 }
             }
         }
     }
     // Clean up.
     $this->restProxy->deleteBlob($container, $blob);
 }
Exemple #8
0
    $doc_code = $_GET["dc_id"];
}
if (!$account_id_is_set && $doc_code == "") {
    error("No code provided.");
}
//$remove_action = isset($_POST["remove_action"])?$_POST["remove_action"]:"1";
//$remove_access_times =  isset($_POST["remove_access_times"])?$_POST["remove_access_times"]:"1";
//$remove_hours =  isset($_POST["remove_hours"])?$_POST["remove_hours"]:"1";
try {
    $blobRestProxy = ServicesBuilder::getInstance()->createBlobService($connectionString);
    //createContainerIfNotExists($blobRestProxy);
    $listContainersOptions = new ListContainersOptions();
    $listContainersOptions->setPrefix($container);
    $arr = [];
    $blob_list = null;
    $op = new ListBlobsOptions();
    //if the user did not pass the document code, list all the files withing the container
    //because that is the list of files for that account
    if ($doc_code == "" && $account_id_is_set) {
        $blob_list = $blobRestProxy->listBlobs($container);
    } else {
        $op->setPrefix("{$doc_code}/");
        // List blobs.
        $blob_list = $blobRestProxy->listBlobs($container, $op);
    }
    $blobs = $blob_list->getBlobs();
    $i = 0;
    foreach ($blobs as $blob) {
        $arr[$i] = ["name" => basename($blob->getName()), "url" => $blob->getUrl(), "bid" => $doc_code];
        $i++;
    }
 /**
  * @covers WindowsAzure\Blob\BlobRestProxy::copyBlob
  * @covers WindowsAzure\Blob\BlobRestProxy::createBlobSnapshot
  * @covers WindowsAzure\Blob\BlobRestProxy::createPageBlob
  * @covers WindowsAzure\Blob\BlobRestProxy::deleteBlob
  * @covers WindowsAzure\Blob\BlobRestProxy::getBlob
  * @covers WindowsAzure\Blob\BlobRestProxy::listBlobs
  * @covers WindowsAzure\Blob\BlobRestProxy::setBlobMetadata
  */
 private function copyBlobWorker($options, $sourceContainer, $destContainer)
 {
     $sourceBlob = BlobServiceFunctionalTestData::getInterestingBlobName($sourceContainer);
     $destBlob = BlobServiceFunctionalTestData::getInterestingBlobName($destContainer);
     // Make sure there is something to test
     $sourceDataSize = 512;
     $this->restProxy->createPageBlob($sourceContainer, $sourceBlob, $sourceDataSize);
     $destDataSize = 2048;
     $destBlobInfo = $this->restProxy->createPageBlob($destContainer, $destBlob, $destDataSize);
     $this->restProxy->createBlobSnapshot($destContainer, $destBlob);
     $metadata = BlobServiceFunctionalTestData::getNiceMetadata();
     $this->restProxy->setBlobMetadata($sourceContainer, $sourceBlob, $metadata);
     $snapshot = $this->restProxy->createBlobSnapshot($sourceContainer, $sourceBlob);
     if (!is_null($options)) {
         BlobServiceFunctionalTestData::fixETagAccessCondition($options->getSourceAccessCondition(), $snapshot->getETag());
         BlobServiceFunctionalTestData::fixETagAccessCondition($options->getAccessCondition(), $destBlobInfo->getETag());
         $options->setSourceSnapshot(is_null($options->getSourceSnapshot()) ? null : $snapshot->getSnapshot());
     }
     try {
         if (is_null($options)) {
             $this->restProxy->copyBlob($destContainer, $destBlob, $sourceContainer, $sourceBlob);
         } else {
             $this->restProxy->copyBlob($destContainer, $destBlob, $sourceContainer, $sourceBlob, $options);
         }
         if (is_null($options)) {
             $options = new CopyBlobOptions();
         }
         if (!is_null($options->getTimeout()) && $options->getTimeout() < 1) {
             $this->assertTrue(false, 'Expect negative timeouts in $options to throw');
         }
         if (!BlobServiceFunctionalTestData::passTemporalAccessCondition($options->getSourceAccessCondition())) {
             $this->assertTrue(false, 'Expect failing source temporal access condition should throw');
         }
         if (!BlobServiceFunctionalTestData::passTemporalAccessCondition($options->getSourceAccessCondition())) {
             $this->assertTrue(false, 'Expect failing source etag access condition to throw');
         }
         if (!BlobServiceFunctionalTestData::passTemporalAccessCondition($options->getAccessCondition())) {
             $this->assertTrue(false, 'Expect failing dest temporal access condition should throw');
         }
         if (!BlobServiceFunctionalTestData::passTemporalAccessCondition($options->getAccessCondition())) {
             $this->assertTrue(false, 'Expect failing dest etag access condition to throw');
         }
         $listOptions = new ListBlobsOptions();
         $listOptions->setIncludeSnapshots(true);
         $listOptions->setPrefix($destBlob);
         $listBlobsResult = $this->restProxy->listBlobs($destContainer == '' ? '$root' : $destContainer, $listOptions);
         $blobs = $listBlobsResult->getBlobs();
         $getBlobResult = $this->restProxy->getBlob($destContainer, $destBlob);
         $this->verifyCopyBlobWorker($options, $blobs, $getBlobResult, $sourceDataSize, $metadata);
     } catch (ServiceException $e) {
         if (is_null($options)) {
             $options = new CopyBlobOptions();
         }
         if (!is_null($options->getTimeout()) && $options->getTimeout() < 1) {
             $this->assertEquals(500, $e->getCode(), 'bad timeout: deleteHttpStatusCode');
         } else {
             if (!BlobServiceFunctionalTestData::passTemporalAccessCondition($options->getSourceAccessCondition())) {
                 $this->assertEquals(412, $e->getCode(), 'bad source temporal access condition IF_UNMODIFIED_SINCE: deleteHttpStatusCode');
             } else {
                 if (!BlobServiceFunctionalTestData::passETagAccessCondition($options->getSourceAccessCondition())) {
                     $this->assertEquals(412, $e->getCode(), 'bad source etag access condition: deleteHttpStatusCode');
                 } else {
                     if (!BlobServiceFunctionalTestData::passTemporalAccessCondition($options->getAccessCondition())) {
                         $this->assertEquals(412, $e->getCode(), 'bad dest temporal access condition IF_UNMODIFIED_SINCE: deleteHttpStatusCode');
                     } else {
                         if (!BlobServiceFunctionalTestData::passETagAccessCondition($options->getAccessCondition())) {
                             $this->assertEquals(412, $e->getCode(), 'bad dest etag access condition: deleteHttpStatusCode');
                         } else {
                             throw $e;
                         }
                     }
                 }
             }
         }
     }
     // Clean up.
     $this->restProxy->deleteBlob($sourceContainer, $sourceBlob);
     $this->restProxy->deleteBlob($destContainer, $destBlob);
 }
 /**
  * List blobs
  *
  * @param  string $container Container name
  * @param  string $prefix    Optional. Filters the results to return only blobs whose name begins with the
  *                           specified prefix.
  * @param  string $delimiter Optional. Delimiter, i.e. '/', for specifying folder hierarchy
  *
  * @return array
  * @throws \Exception
  */
 public function listBlobs($container, $prefix = '', $delimiter = '')
 {
     $this->checkConnection();
     $options = new ListBlobsOptions();
     if (!empty($delimiter)) {
         $options->setDelimiter($delimiter);
     }
     if (!empty($prefix)) {
         $options->setPrefix($prefix);
     }
     /** @var ListBlobsResult $results */
     $results = $this->blobConn->listBlobs($container, $options);
     $blobs = $results->getBlobs();
     $prefixes = $results->getBlobPrefixes();
     $out = [];
     /** @var \WindowsAzure\Blob\Models\Blob $blob */
     foreach ($blobs as $blob) {
         $name = $blob->getName();
         if (0 == strcmp($prefix, $name)) {
             continue;
         }
         $props = $blob->getProperties();
         $out[] = ['name' => $name, 'last_modified' => gmdate(static::TIMESTAMP_FORMAT, $props->getLastModified()->getTimestamp()), 'content_length' => $props->getContentLength(), 'content_type' => $props->getContentType(), 'content_encoding' => $props->getContentEncoding(), 'content_language' => $props->getContentLanguage()];
     }
     foreach ($prefixes as $blob) {
         $out[] = ['name' => $blob->getName(), 'content_type' => null, 'content_length' => 0, 'last_modified' => null];
     }
     return $out;
 }
 /**
  * BlobのPrefix一覧取得
  * @param type $containerName
  * @return type
  * @throws Exception
  */
 public function getBobPrefixes($containerName, $prefix = null, $delimiter = null)
 {
     $options = new ListBlobsOptions();
     $blobPrefixes = array();
     while (true) {
         try {
             if ($prefix) {
                 $options->setPrefix($prefix);
             }
             if ($delimiter) {
                 $options->setDelimiter($delimiter);
             }
             $blobList = $this->blobRestProxy->listBlobs($containerName, $options);
         } catch (Exception $e) {
             throw new Exception($e->getMessage(), $e->getCode());
         }
         foreach ($blobList->getBlobPrefixes() as $blobPrefix) {
             $blobPrefixes[] = $blobPrefix->getName();
         }
         $nextMarker = $blobList->getNextMarker();
         if (!$nextMarker || strlen($nextMarker) == 0) {
             break;
         }
         $options->setMarker($nextMarker);
     }
     return $blobPrefixes;
 }
Exemple #12
0
function get_document_list()
{
    $connectionString = get_option('vso_dps_storage_connection_string');
    try {
        $blobRestProxy = ServicesBuilder::getInstance()->createBlobService($connectionString);
        $options = new ListBlobsOptions();
        $options->setPrefix('en-us/vscom-pilot-20151126-172651/documentation/articles');
        $result = $blobRestProxy->listBlobs("vs-com-support-articles", $options);
        $blobs = $result->getBlobs();
        $stringContent = "<ul>";
        foreach ($blobs as $blob) {
            //echo $blob->getName().": ".$blob->getUrl()."<br />";
            $stringContent .= "<li>" . $blob->getName() . "</li>";
        }
        $stringContent .= "</ul>";
        return $stringContent;
    } catch (ServiceException $e) {
        $code = $e->getCode();
        $error_message = $e->getMessage();
        echo $code . ": " . $error_message . "<br />";
    }
}
 /**
  * @covers WindowsAzure\Blob\BlobRestProxy::createPageBlob
  * @covers WindowsAzure\Blob\BlobRestProxy::deleteBlob
  * @covers WindowsAzure\Blob\BlobRestProxy::listBlobs
  */
 public function testListBlobsWithDelimiterWorks()
 {
     // Arrange
     $blobNames = array('myblob1', 'myblob2', 'dir1-blob1', 'dir1-blob2', 'dir2-dir21-blob3', 'dir2-dir22-blob3');
     foreach ($blobNames as $blob) {
         $this->restProxy->createPageBlob(self::$_test_container_for_listing, $blob, 512);
     }
     // Act
     $opts = new ListBlobsOptions();
     $opts->setDelimiter('-');
     $results = $this->restProxy->listBlobs(self::$_test_container_for_listing, $opts);
     $opts->setPrefix('dir1-');
     $results2 = $this->restProxy->listBlobs(self::$_test_container_for_listing, $opts);
     $opts->setPrefix('dir2-');
     $results3 = $this->restProxy->listBlobs(self::$_test_container_for_listing, $opts);
     $opts->setPrefix('dir2-dir21-');
     $results4 = $this->restProxy->listBlobs(self::$_test_container_for_listing, $opts);
     $opts->setPrefix('dir2-dir22-');
     $results5 = $this->restProxy->listBlobs(self::$_test_container_for_listing, $opts);
     $opts->setPrefix('dir2-dir44-');
     $results6 = $this->restProxy->listBlobs(self::$_test_container_for_listing, $opts);
     foreach ($blobNames as $blob) {
         $this->restProxy->deleteBlob(self::$_test_container_for_listing, $blob);
     }
     // Assert
     $this->assertNotNull($results, '$results');
     $this->assertEquals(2, count($results->getBlobs()), 'count($results->getBlobs())');
     $this->assertEquals(2, count($results->getBlobPrefixes()), 'count($results->getBlobPrefixes())');
     $this->assertEquals(2, count($results2->getBlobs()), 'count($results2->getBlobs())');
     $this->assertEquals(0, count($results2->getBlobPrefixes()), 'count($results2->getBlobPrefixes())');
     $this->assertEquals(0, count($results3->getBlobs()), 'count($results3->getBlobs())');
     $this->assertEquals(2, count($results3->getBlobPrefixes()), 'count($results3->getBlobPrefixes())');
     $this->assertEquals(1, count($results4->getBlobs()), 'count($results4->getBlobs())');
     $this->assertEquals(0, count($results4->getBlobPrefixes()), 'count($results4->getBlobPrefixes())');
     $this->assertEquals(1, count($results5->getBlobs()), 'count($results5->getBlobs())');
     $this->assertEquals(0, count($results5->getBlobPrefixes()), 'count($results5->getBlobPrefixes())');
     $this->assertEquals(0, count($results6->getBlobs()), 'count($results6->getBlobs())');
     $this->assertEquals(0, count($results6->getBlobPrefixes()), 'count($results6->getBlobPrefixes())');
 }
 public function pn_blob_cache_exists($key)
 {
     try {
         $blob_list_options = new ListBlobsOptions();
         $blob_list_options->setPrefix($key);
         $blob_list = $this->blob_service->listBlobs($this->container, $blob_list_options);
         $blobs = $blob_list->getBlobs();
         foreach ($blobs as $blob) {
             if ($blob->getname() == $key) {
                 return TRUE;
             }
         }
     } catch (ServiceException $e) {
         $this->pn_handle_exception($e);
     }
     return FALSE;
 }
 /**  
  * @covers WindowsAzure\Blob\BlobRestProxy::createBlobSnapshot 
  * @covers WindowsAzure\Blob\Models\createBlobSnapshotResult::create 
  */
 public function testCreateBlobSnapshot()
 {
     // Setup
     $containerName = 'createblobsnapshot' . $this->createSuffix();
     $blobName = 'testBlob';
     $blobValue = 'TestBlobValue';
     $this->createContainer($containerName);
     $this->restProxy->createBlockBlob($containerName, $blobName, $blobValue);
     // Test
     $snapshotResult = $this->restProxy->createBlobSnapshot($containerName, $blobName);
     // Assert
     $listOptions = new ListBlobsOptions();
     $listOptions->setIncludeSnapshots(true);
     $blobsResult = $this->restProxy->listBlobs($containerName, $listOptions);
     $blobs = $blobsResult->getBlobs();
     $actualBlob = $blobs[0];
     $this->assertNotNull($snapshotResult->getETag());
     $this->assertNotNull($snapshotResult->getLastModified());
     $this->assertNotNull($snapshotResult->getSnapshot());
     $this->assertEquals($snapshotResult->getSnapshot(), $actualBlob->getSnapshot());
 }
 /**
  * {@inheritdoc}
  */
 public function listContents($directory = '', $recursive = false)
 {
     // Prefix the path
     $directory = $this->applyPathPrefix($directory);
     $options = new ListBlobsOptions();
     $options->setPrefix($directory);
     /** @var ListBlobsResult $listResults */
     $listResults = $this->client->listBlobs($this->container, $options);
     $contents = [];
     foreach ($listResults->getBlobs() as $blob) {
         $contents[] = $this->normalizeBlobProperties($blob->getName(), $blob->getProperties());
     }
     return $contents;
 }
Exemple #17
0
 /**
  * {@inheritdoc}
  */
 public function listContents($directory = '', $recursive = false)
 {
     $directory = $this->applyPathPrefix($directory);
     // Append trailing slash only for directory other than root (which after normalization is an empty string).
     // Listing for / doesn't work properly otherwise.
     if (strlen($directory)) {
         $directory = rtrim($directory, '/') . '/';
     }
     $options = new ListBlobsOptions();
     $options->setPrefix($directory);
     if (!$recursive) {
         $options->setDelimiter('/');
     }
     /** @var ListBlobsResult $listResults */
     $listResults = $this->client->listBlobs($this->container, $options);
     $contents = [];
     foreach ($listResults->getBlobs() as $blob) {
         $contents[] = $this->normalizeBlobProperties($blob->getName(), $blob->getProperties());
     }
     if (!$recursive) {
         $contents = array_merge($contents, array_map([$this, 'normalizeBlobPrefix'], $listResults->getBlobPrefixes()));
     }
     return Util::emulateDirectories($contents);
 }