Custom stream wrapper support

Added support for custom stream wrappers, such as "fly" or "s3".
Support is determined per reader.
This commit is contained in:
Adrien Loison committed 2016-03-18 17:09:13 -07:00
1 parent 0c90d102ef
commit d2ac54c578
10 files changed
+333 -5

No files matched your search

@@ -280,6 +280,17 @@ class GlobalFunctionsHelper
return mb_convert_encoding($string, $targetEncoding, $sourceEncoding);
}
/**
* Wrapper around global function stream_get_wrappers()
* @see stream_get_wrappers()
*
* @return array
*/
public function stream_get_wrappers()
{
return stream_get_wrappers();
}
/**
* Wrapper around global function stream_get_line()
* @see stream_get_line()
+75 -3
View File
@@ -19,6 +19,13 @@ abstract class AbstractReader implements ReaderInterface
/** @var \Box\Spout\Common\Helper\GlobalFunctionsHelper Helper to work with global functions */
protected $globalFunctionsHelper;
/**
* Returns whether stream wrappers are supported
*
* @return bool
*/
abstract protected function doesSupportStreamWrapper();
/**
* Opens the file at the given file path to make it ready to be read
*
@@ -62,6 +69,10 @@ abstract class AbstractReader implements ReaderInterface
*/
public function open($filePath)
{
if ($this->isStreamWrapper($filePath) && (!$this->doesSupportStreamWrapper() || !$this->isSupportedStreamWrapper($filePath))) {
throw new IOException("Could not open $filePath for reading! Stream wrapper used is not supported for this type of file.");
}
if (!$this->isPhpStream($filePath)) {
// we skip the checks if the provided file path points to a PHP stream
if (!$this->globalFunctionsHelper->file_exists($filePath)) {
@@ -72,8 +83,7 @@ abstract class AbstractReader implements ReaderInterface
}
try {
// Need to use realpath to fix "Can't open file" on some Windows setup
$fileRealPath = realpath($filePath);
$fileRealPath = $this->getFileRealPath($filePath);
$this->openReader($fileRealPath);
$this->isStreamOpened = true;
} catch (\Exception $exception) {
@@ -81,6 +91,67 @@ abstract class AbstractReader implements ReaderInterface
}
}
/**
* Returns the real path of the given path.
* If the given path is a valid stream wrapper, returns the path unchanged.
*
* @param string $filePath
* @return string
*/
protected function getFileRealPath($filePath)
{
if ($this->isSupportedStreamWrapper($filePath)) {
return $filePath;
}
// Need to use realpath to fix "Can't open file" on some Windows setup
return realpath($filePath);
}
/**
* Returns the scheme of the custom stream wrapper, if the path indicates a stream wrapper is used.
* For example, php://temp => php, s3://path/to/file => s3...
*
* @param string $filePath Path of the file to be read
* @return string|null The stream wrapper scheme or NULL if not a stream wrapper
*/
protected function getStreamWrapperScheme($filePath)
{
$streamScheme = null;
if (preg_match('/^(\w+):\/\//', $filePath, $matches)) {
$streamScheme = $matches[1];
}
return $streamScheme;
}
/**
* Checks if the given path is an unsupported stream wrapper
* (like local path, php://temp, mystream://foo/bar...).
*
* @param string $filePath Path of the file to be read
* @return bool Whether the given path is an unsupported stream wrapper
*/
protected function isStreamWrapper($filePath)
{
return ($this->getStreamWrapperScheme($filePath) !== null);
}
/**
* Checks if the given path is an supported stream wrapper
* (like php://temp, mystream://foo/bar...).
* If the given path is a local path, returns true.
*
* @param string $filePath Path of the file to be read
* @return bool Whether the given path is an supported stream wrapper
*/
protected function isSupportedStreamWrapper($filePath)
{
$streamScheme = $this->getStreamWrapperScheme($filePath);
return ($streamScheme !== null) ?
in_array($streamScheme, $this->globalFunctionsHelper->stream_get_wrappers()) :
true;
}
/**
* Checks if a path is a PHP stream (like php://output, php://memory, ...)
*
@@ -89,7 +160,8 @@ abstract class AbstractReader implements ReaderInterface
*/
protected function isPhpStream($filePath)
{
return (strpos($filePath, 'php://') === 0);
$streamScheme = $this->getStreamWrapperScheme($filePath);
return ($streamScheme === 'php');
}
/**
+12 -2
View File
@@ -30,7 +30,7 @@ class Reader extends AbstractReader
protected $encoding = EncodingHelper::ENCODING_UTF8;
/** @var string Defines the End of line */
protected $endOfLineCharacter = "\n";
protected $endOfLineCharacter = "\n";
/**
* Sets the field delimiter for the CSV.
@@ -82,7 +82,17 @@ class Reader extends AbstractReader
{
$this->endOfLineCharacter = $endOfLineCharacter;
return $this;
}
}
/**
* Returns whether stream wrappers are supported
*
* @return bool
*/
protected function doesSupportStreamWrapper()
{
return true;
}
/**
* Opens the file at the given path to make it ready to be read.
+10
View File
@@ -19,6 +19,16 @@ class Reader extends AbstractReader
/** @var SheetIterator To iterator over the ODS sheets */
protected $sheetIterator;
/**
* Returns whether stream wrappers are supported
*
* @return bool
*/
protected function doesSupportStreamWrapper()
{
return false;
}
/**
* Opens the file at the given file path to make it ready to be read.
*
+10
View File
@@ -37,6 +37,16 @@ class Reader extends AbstractReader
return $this;
}
/**
* Returns whether stream wrappers are supported
*
* @return bool
*/
protected function doesSupportStreamWrapper()
{
return false;
}
/**
* Opens the file at the given file path to make it ready to be read.
* It also parses the sharedStrings.xml file to get all the shared strings available in memory