Microsoft_WindowsAzure_Storage
[ class tree: Microsoft_WindowsAzure_Storage ] [ index: Microsoft_WindowsAzure_Storage ] [ all elements ]

Source for file Stream.php

Documentation is available at Stream.php

  1. <?php
  2. /**
  3.  * Copyright (c) 2009 - 2011, RealDolmen
  4.  * All rights reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions are met:
  8.  *     * Redistributions of source code must retain the above copyright
  9.  *       notice, this list of conditions and the following disclaimer.
  10.  *     * Redistributions in binary form must reproduce the above copyright
  11.  *       notice, this list of conditions and the following disclaimer in the
  12.  *       documentation and/or other materials provided with the distribution.
  13.  *     * Neither the name of RealDolmen nor the
  14.  *       names of its contributors may be used to endorse or promote products
  15.  *       derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
  18.  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  19.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  20.  * DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
  21.  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  22.  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  23.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  24.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  26.  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  *
  28.  * @category   Microsoft
  29.  * @package    Microsoft_WindowsAzure_Storage
  30.  * @subpackage Blob
  31.  * @copyright  Copyright (c) 2009 - 2011, RealDolmen (http://www.realdolmen.com)
  32.  * @license    http://todo     name_todo
  33.  * @version    $Id: Blob.php 24511 2009-07-28 09:17:56Z unknown $
  34.  */
  35.  
  36. /**
  37.  * @see Microsoft_AutoLoader
  38.  */
  39. require_once dirname(__FILE__'/../../../AutoLoader.php';
  40.  
  41.  
  42. /**
  43.  * @category   Microsoft
  44.  * @package    Microsoft_WindowsAzure_Storage
  45.  * @subpackage Blob
  46.  * @copyright  Copyright (c) 2009 - 2011, RealDolmen (http://www.realdolmen.com)
  47.  * @license    http://phpazure.codeplex.com/license
  48.  */
  49. {
  50.     /**
  51.      * Current file name
  52.      * 
  53.      * @var string 
  54.      */
  55.     protected $_fileName = null;
  56.     
  57.     /**
  58.      * Temporary file name
  59.      * 
  60.      * @var string 
  61.      */
  62.     protected $_temporaryFileName = null;
  63.     
  64.     /**
  65.      * Temporary file handle
  66.      * 
  67.      * @var resource 
  68.      */
  69.     protected $_temporaryFileHandle = null;
  70.     
  71.     /**
  72.      * Blob storage client
  73.      * 
  74.      * @var Microsoft_WindowsAzure_Storage_Blob 
  75.      */
  76.     protected $_storageClient = null;
  77.     
  78.     /**
  79.      * Write mode?
  80.      * 
  81.      * @var boolean 
  82.      */
  83.     protected $_writeMode = false;
  84.     
  85.     /**
  86.      * List of blobs
  87.      * 
  88.      * @var array 
  89.      */
  90.     protected $_blobs = null;
  91.     
  92.     /**
  93.      * Retrieve storage client for this stream type
  94.      * 
  95.      * @param string $path 
  96.      * @return Microsoft_WindowsAzure_Storage_Blob 
  97.      */
  98.     protected function _getStorageClient($path '')
  99.     {
  100.         if (is_null($this->_storageClient)) {
  101.             $url explode(':'$path);
  102.             if (!$url{
  103.                 throw new Microsoft_WindowsAzure_Exception('Could not parse path "' $path '".');
  104.             }
  105.  
  106.             $this->_storageClient = Microsoft_WindowsAzure_Storage_Blob::getWrapperClient($url[0]);
  107.             if (!$this->_storageClient{
  108.                 throw new Microsoft_WindowsAzure_Exception('No storage client registered for stream type "' $url[0'://".');
  109.             }
  110.         }
  111.         
  112.         return $this->_storageClient;
  113.     }
  114.     
  115.     /**
  116.      * Extract container name
  117.      *
  118.      * @param string $path 
  119.      * @return string 
  120.      */
  121.     protected function _getContainerName($path)
  122.     {
  123.         $url parse_url($path);
  124.         if ($url['host']{
  125.             return $url['host'];
  126.         }
  127.  
  128.         return '';
  129.     }
  130.     
  131.     /**
  132.      * Extract file name
  133.      *
  134.      * @param string $path 
  135.      * @return string 
  136.      */
  137.     protected function _getFileName($path)
  138.     {
  139.         $url parse_url($path);
  140.         if ($url['host']{
  141.             $fileName = isset($url['path']$url['path'$url['host'];
  142.             if (strpos($fileName'/'=== 0{
  143.                 $fileName substr($fileName1);
  144.             }
  145.             return $fileName;
  146.         }
  147.  
  148.         return '';
  149.     }
  150.        
  151.     /**
  152.      * Open the stream
  153.      *
  154.      * @param  string  $path 
  155.      * @param  string  $mode 
  156.      * @param  integer $options 
  157.      * @param  string  $opened_path 
  158.      * @return boolean 
  159.      */
  160.     public function stream_open($path$mode$options&$opened_path)
  161.     {
  162.         $this->_fileName = $path;
  163.         $this->_temporaryFileName = tempnam(sys_get_temp_dir()'azure');
  164.         
  165.         // Check the file can be opened
  166.         $fh @fopen($this->_temporaryFileName$mode);
  167.         if ($fh === false{
  168.             return false;
  169.         }
  170.         fclose($fh);
  171.         
  172.         // Write mode?
  173.         if (strpbrk($mode'wax+')) {
  174.             $this->_writeMode = true;
  175.         else {
  176.             $this->_writeMode = false;
  177.         }
  178.         
  179.         // If read/append, fetch the file
  180.         if (!$this->_writeMode || strpbrk($mode'ra+')) {
  181.             $this->_getStorageClient($this->_fileName)->getBlob(
  182.                 $this->_getContainerName($this->_fileName),
  183.                 $this->_getFileName($this->_fileName),
  184.                 $this->_temporaryFileName
  185.             );
  186.         }
  187.         
  188.         // Open temporary file handle
  189.         $this->_temporaryFileHandle = fopen($this->_temporaryFileName$mode);
  190.         
  191.         // Ok!
  192.         return true;
  193.     }
  194.  
  195.     /**
  196.      * Close the stream
  197.      *
  198.      * @return void 
  199.      */
  200.     public function stream_close()
  201.     {
  202.         @fclose($this->_temporaryFileHandle);
  203.         
  204.         // Upload the file?
  205.         if ($this->_writeMode{
  206.             // Make sure the container exists
  207.             $containerExists $this->_getStorageClient($this->_fileName)->containerExists(
  208.                 $this->_getContainerName($this->_fileName)
  209.             );
  210.             if (!$containerExists{
  211.                 $this->_getStorageClient($this->_fileName)->createContainer(
  212.                     $this->_getContainerName($this->_fileName)
  213.                 );
  214.             }
  215.             
  216.             // Upload the file
  217.             try {
  218.                 $this->_getStorageClient($this->_fileName)->putBlob(
  219.                     $this->_getContainerName($this->_fileName),
  220.                     $this->_getFileName($this->_fileName),
  221.                     $this->_temporaryFileName
  222.                 );
  223.             catch (Microsoft_WindowsAzure_Exception $ex{
  224.                 @unlink($this->_temporaryFileName);
  225.                 unset($this->_storageClient);
  226.                 
  227.                 throw $ex;
  228.             }
  229.         }
  230.         
  231.         @unlink($this->_temporaryFileName);
  232.         unset($this->_storageClient);
  233.     }
  234.  
  235.     /**
  236.      * Read from the stream
  237.      *
  238.      * @param  integer $count 
  239.      * @return string 
  240.      */
  241.     public function stream_read($count)
  242.     {
  243.         if (!$this->_temporaryFileHandle{
  244.             return false;
  245.         }
  246.  
  247.         return fread($this->_temporaryFileHandle$count);
  248.     }
  249.  
  250.     /**
  251.      * Write to the stream
  252.      *
  253.      * @param  string $data 
  254.      * @return integer 
  255.      */
  256.     public function stream_write($data)
  257.     {
  258.         if (!$this->_temporaryFileHandle{
  259.             return 0;
  260.         }
  261.         
  262.         $len strlen($data);
  263.         fwrite($this->_temporaryFileHandle$data$len);
  264.         return $len;
  265.     }
  266.  
  267.     /**
  268.      * End of the stream?
  269.      *
  270.      * @return boolean 
  271.      */
  272.     public function stream_eof()
  273.     {
  274.         if (!$this->_temporaryFileHandle{
  275.             return true;
  276.         }
  277.  
  278.         return feof($this->_temporaryFileHandle);
  279.     }
  280.  
  281.     /**
  282.      * What is the current read/write position of the stream?
  283.      *
  284.      * @return integer 
  285.      */
  286.     public function stream_tell()
  287.     {
  288.         return ftell($this->_temporaryFileHandle);
  289.     }
  290.  
  291.     /**
  292.      * Update the read/write position of the stream
  293.      *
  294.      * @param  integer $offset 
  295.      * @param  integer $whence 
  296.      * @return boolean 
  297.      */
  298.     public function stream_seek($offset$whence)
  299.     {
  300.         if (!$this->_temporaryFileHandle{
  301.             return false;
  302.         }
  303.         
  304.         return (fseek($this->_temporaryFileHandle$offset$whence=== 0);
  305.     }
  306.  
  307.     /**
  308.      * Flush current cached stream data to storage
  309.      *
  310.      * @return boolean 
  311.      */
  312.     public function stream_flush()
  313.     {
  314.         $result fflush($this->_temporaryFileHandle);
  315.         
  316.          // Upload the file?
  317.         if ($this->_writeMode{
  318.             // Make sure the container exists
  319.             $containerExists $this->_getStorageClient($this->_fileName)->containerExists(
  320.                 $this->_getContainerName($this->_fileName)
  321.             );
  322.             if (!$containerExists{
  323.                 $this->_getStorageClient($this->_fileName)->createContainer(
  324.                     $this->_getContainerName($this->_fileName)
  325.                 );
  326.             }
  327.             
  328.             // Upload the file
  329.             try {
  330.                 $this->_getStorageClient($this->_fileName)->putBlob(
  331.                     $this->_getContainerName($this->_fileName),
  332.                     $this->_getFileName($this->_fileName),
  333.                     $this->_temporaryFileName
  334.                 );
  335.             catch (Microsoft_WindowsAzure_Exception $ex{
  336.                 @unlink($this->_temporaryFileName);
  337.                 unset($this->_storageClient);
  338.                 
  339.                 throw $ex;
  340.             }
  341.         }
  342.         
  343.         return $result;
  344.     }
  345.  
  346.     /**
  347.      * Returns data array of stream variables
  348.      *
  349.      * @return array 
  350.      */
  351.     public function stream_stat()
  352.     {
  353.         if (!$this->_temporaryFileHandle{
  354.             return false;
  355.         }
  356.  
  357.         return $this->url_stat($this->_fileName0);
  358.     }
  359.  
  360.     /**
  361.      * Attempt to delete the item
  362.      *
  363.      * @param  string $path 
  364.      * @return boolean 
  365.      */
  366.     public function unlink($path)
  367.     {
  368.         $this->_getStorageClient($path)->deleteBlob(
  369.             $this->_getContainerName($path),
  370.             $this->_getFileName($path)
  371.         );
  372.  
  373.         // Clear the stat cache for this path.
  374.         clearstatcache(true$path);
  375.         return true;
  376.     }
  377.  
  378.     /**
  379.      * Attempt to rename the item
  380.      *
  381.      * @param  string  $path_from 
  382.      * @param  string  $path_to 
  383.      * @return boolean False
  384.      */
  385.     public function rename($path_from$path_to)
  386.     {
  387.         if ($this->_getContainerName($path_from!= $this->_getContainerName($path_to)) {
  388.             throw new Microsoft_WindowsAzure_Exception('Container name can not be changed.');
  389.         }
  390.         
  391.         if ($this->_getFileName($path_from== $this->_getContainerName($path_to)) {
  392.             return true;
  393.         }
  394.             
  395.         $this->_getStorageClient($path_from)->copyBlob(
  396.             $this->_getContainerName($path_from),
  397.             $this->_getFileName($path_from),
  398.             $this->_getContainerName($path_to),
  399.             $this->_getFileName($path_to)
  400.         );
  401.         $this->_getStorageClient($path_from)->deleteBlob(
  402.             $this->_getContainerName($path_from),
  403.             $this->_getFileName($path_from)
  404.         );
  405.  
  406.         // Clear the stat cache for the affected paths.
  407.         clearstatcache(true$path_from);
  408.         clearstatcache(true$path_to);
  409.         return true;
  410.     }
  411.     
  412.     /**
  413.      * Return array of URL variables
  414.      *
  415.      * @param  string $path 
  416.      * @param  integer $flags 
  417.      * @return array 
  418.      */
  419.     public function url_stat($path$flags)
  420.     {
  421.         $stat array();
  422.         $stat['dev'0;
  423.         $stat['ino'0;
  424.         $stat['mode'0;
  425.         $stat['nlink'0;
  426.         $stat['uid'0;
  427.         $stat['gid'0;
  428.         $stat['rdev'0;
  429.         $stat['size'0;
  430.         $stat['atime'0;
  431.         $stat['mtime'0;
  432.         $stat['ctime'0;
  433.         $stat['blksize'0;
  434.         $stat['blocks'0;
  435.  
  436.         $info null;
  437.         try {
  438.             $info $this->_getStorageClient($path)->getBlobInstance(
  439.                         $this->_getContainerName($path),
  440.                         $this->_getFileName($path)
  441.                     );
  442.             $stat['size']  $info->Size;
  443.  
  444.             // Set the modification time and last modified to the Last-Modified header.
  445.             $lastmodified strtotime($info->LastModified);
  446.             $stat['mtime'$lastmodified;
  447.             $stat['ctime'$lastmodified;
  448.  
  449.             // Entry is a regular file.
  450.             $stat['mode'0100000;
  451.  
  452.             return array_values($stat$stat;
  453.         catch (Microsoft_WindowsAzure_Exception $ex{
  454.             // Unexisting file...
  455.             return false;
  456.         }
  457.     }
  458.  
  459.     /**
  460.      * Create a new directory
  461.      *
  462.      * @param  string  $path 
  463.      * @param  integer $mode 
  464.      * @param  integer $options 
  465.      * @return boolean 
  466.      */
  467.     public function mkdir($path$mode$options)
  468.     {
  469.         if ($this->_getContainerName($path== $this->_getFileName($path)) {
  470.             // Create container
  471.             try {
  472.                 $this->_getStorageClient($path)->createContainer(
  473.                     $this->_getContainerName($path)
  474.                 );
  475.                 return true;
  476.             catch (Microsoft_WindowsAzure_Exception $ex{
  477.                 return false;
  478.             }
  479.         else {
  480.             throw new Microsoft_WindowsAzure_Exception('mkdir() with multiple levels is not supported on Windows Azure Blob Storage.');
  481.         }
  482.     }
  483.  
  484.     /**
  485.      * Remove a directory
  486.      *
  487.      * @param  string  $path 
  488.      * @param  integer $options 
  489.      * @return boolean 
  490.      */
  491.     public function rmdir($path$options)
  492.     {
  493.         if ($this->_getContainerName($path== $this->_getFileName($path)) {
  494.             // Clear the stat cache so that affected paths are refreshed.
  495.             clearstatcache();
  496.  
  497.             // Delete container
  498.             try {
  499.                 $this->_getStorageClient($path)->deleteContainer(
  500.                     $this->_getContainerName($path)
  501.                 );
  502.                 return true;
  503.             catch (Microsoft_WindowsAzure_Exception $ex{
  504.                 return false;
  505.             }
  506.         else {
  507.             throw new Microsoft_WindowsAzure_Exception('rmdir() with multiple levels is not supported on Windows Azure Blob Storage.');
  508.         }
  509.     }
  510.  
  511.     /**
  512.      * Attempt to open a directory
  513.      *
  514.      * @param  string $path 
  515.      * @param  integer $options 
  516.      * @return boolean 
  517.      */
  518.     public function dir_opendir($path$options)
  519.     {
  520.         $this->_blobs = $this->_getStorageClient($path)->listBlobs(
  521.             $this->_getContainerName($path)
  522.         );
  523.         return is_array($this->_blobs);
  524.     }
  525.  
  526.     /**
  527.      * Return the next filename in the directory
  528.      *
  529.      * @return string 
  530.      */
  531.     public function dir_readdir()
  532.     {
  533.         $object current($this->_blobs);
  534.         if ($object !== false{
  535.             next($this->_blobs);
  536.             return $object->Name;
  537.         }
  538.         return false;
  539.     }
  540.  
  541.     /**
  542.      * Reset the directory pointer
  543.      *
  544.      * @return boolean True
  545.      */
  546.     public function dir_rewinddir()
  547.     {
  548.         reset($this->_blobs);
  549.         return true;
  550.     }
  551.  
  552.     /**
  553.      * Close a directory
  554.      *
  555.      * @return boolean True
  556.      */
  557.     public function dir_closedir()
  558.     {
  559.         $this->_blobs = null;
  560.         return true;
  561.     }
  562. }

Documentation generated on Wed, 18 May 2011 12:06:55 +0200 by phpDocumentor 1.4.3