class FeedsFetcherResult in Feeds 7.2
Base class for all fetcher results.
Hierarchy
- class \FeedsResult
- class \FeedsFetcherResult
Expanded class hierarchy of FeedsFetcherResult
File
- plugins/
FeedsFetcher.inc, line 11 - Contains the FeedsFetcher and related classes.
View source
class FeedsFetcherResult extends FeedsResult {
/**
* The raw fetched data.
*
* @var string
*/
protected $raw;
/**
* The path to a file where the raw data is stored.
*
* @var string
*/
protected $file_path;
/**
* Constructor.
*/
public function __construct($raw) {
$this->raw = $raw;
}
/**
* Prevent saving the raw result when serializing object.
*/
public function __sleep() {
if (!empty($this->raw)) {
// Save contents of raw to a file for later use.
$this
->saveRawToFile();
}
// Save anything but 'raw'.
unset($this->raw);
return array_keys(get_object_vars($this));
}
/**
* Returns the raw content.
*
* @return string
* The raw content from the source as a string.
*
* @throws Exception
* Extending classes MAY throw an exception if a problem occurred.
*/
public function getRaw() {
if (empty($this->raw)) {
// Return raw contents from file.
return $this
->getFileContents();
}
return $this
->sanitizeRawOptimized($this->raw);
}
/**
* Get a path to a temporary file containing the resource provided by the
* fetcher.
*
* File will be deleted after DRUPAL_MAXIMUM_TEMP_FILE_AGE.
*
* @return string
* A path to a file containing the raw content as a source.
*
* @throws Exception
* If an unexpected problem occurred.
*/
public function getFilePath() {
if (empty($this->file_path)) {
// No file exists yet. Save any raw data that we got.
$this
->saveRawToFile();
}
// Check if given file exists now.
$this
->checkFile();
// Return file path.
return $this
->sanitizeFile($this->file_path);
}
/**
* Returns directory for storing files that are in progress of import.
*
* @return string
* The cache dir to use.
*/
public function getFeedsInProgressDir() {
$dir = variable_get('feeds_in_progress_dir', NULL);
if ($dir) {
return $dir;
}
else {
$schemes = file_get_stream_wrappers(STREAM_WRAPPERS_WRITE_VISIBLE);
$scheme = isset($schemes['private']) ? 'private' : 'public';
return $scheme . '://feeds/in_progress';
}
}
/**
* Constructs file name for saving the raw data.
*/
public function constructFilePath() {
return $this
->getFeedsInProgressDir() . '/' . get_class($this) . REQUEST_TIME;
}
/**
* Returns if raw data exists.
*
* This checks if either $this->raw is set or if the raw data exists in a
* file. This is better then calling just ::getRaw() as that would return a
* copy of all raw data which may lead to memory issues if the data is very
* large.
*
* @return bool
* True if the raw data exists.
* False otherwise.
*/
public function rawExists() {
return !empty($this->raw) || $this
->fileExists();
}
/**
* Returns if the file to parse exists.
*
* @return bool
* True if the file exists.
* False otherwise.
*/
public function fileExists() {
if (!empty($this->file_path) && is_readable($this->file_path)) {
return TRUE;
}
return FALSE;
}
/**
* Returns the contents of a file, if it exists.
*
* @return string
* The file contents.
*/
public function getFileContents() {
if ($this
->fileExists()) {
$this
->sanitizeFile($this->file_path);
return file_get_contents($this->file_path);
}
}
/**
* Checks that a file exists and is readable.
*
* @throws RuntimeException
* Thrown if the file isn't readable or writable.
*/
protected function checkFile() {
if (!file_exists($this->file_path)) {
throw new RuntimeException(t('File %filepath does not exist.', array(
'%filepath' => $this->file_path,
)));
}
if (!is_readable($this->file_path)) {
throw new RuntimeException(t('File %filepath is not readable.', array(
'%filepath' => $this->file_path,
)));
}
}
/**
* Saves the raw fetcher result to a file.
*
* @throws RuntimeException
* In case the destination wasn't writable.
*/
public function saveRawToFile() {
$file_in_progress_dir = $this
->getFeedsInProgressDir();
if (!file_prepare_directory($file_in_progress_dir, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS)) {
throw new RuntimeException(t('Feeds directory either cannot be created or is not writable.'));
}
$this->file_path = FALSE;
if ($file = file_save_data($this
->getRaw(), $this
->constructFilePath())) {
$file->status = 0;
file_save($file);
$this->file_path = $file->uri;
// Clear raw data to save memory, but also to prevent saving the same raw data
// to a file again in the same request.
$this->raw = NULL;
}
else {
throw new RuntimeException(t('Cannot write content to %dest', array(
'%dest' => $destination,
)));
}
}
/**
* Sanitize the raw content string.
*
* Currently supported sanitizations:
* - Remove BOM header from UTF-8 files.
*
* Consider using ::sanitizeRawOptimized() instead that receives the variable
* by reference and thus saves memory.
*
* @param string $raw
* The raw content string to be sanitized.
*
* @return string
* The sanitized content as a string.
*/
public function sanitizeRaw($raw) {
if (substr($raw, 0, 3) == pack('CCC', 0xef, 0xbb, 0xbf)) {
$raw = substr($raw, 3);
}
return $raw;
}
/**
* Sanitize the raw content string.
*
* Currently supported sanitizations:
* - Remove BOM header from UTF-8 files.
*
* This accepts the raw contents by reference to prevent having the whole raw
* contents in memory again.
*
* @param string $raw
* The raw content string to be sanitized.
*
* @return string
* The sanitized content as a string.
*/
public function sanitizeRawOptimized(&$raw) {
if (substr($raw, 0, 3) == pack('CCC', 0xef, 0xbb, 0xbf)) {
$raw = substr($raw, 3);
}
return $raw;
}
/**
* Sanitize the file in place.
*
* Currently supported sanitizations:
* - Remove BOM header from UTF-8 files.
*
* @param string $filepath
* The file path of the file to be sanitized.
*
* @return string
* The file path of the sanitized file.
*
* @throws RuntimeException
* Thrown if the file is not writeable.
*/
public function sanitizeFile($filepath) {
$handle = fopen($filepath, 'r');
$line = fgets($handle);
fclose($handle);
// If BOM header is present, read entire contents of file and overwrite the
// file with corrected contents.
if (substr($line, 0, 3) !== pack('CCC', 0xef, 0xbb, 0xbf)) {
return $filepath;
}
if (!is_writable($filepath)) {
throw new RuntimeException(t('File %filepath is not writable.', array(
'%filepath' => $filepath,
)));
}
$contents = file_get_contents($filepath);
$contents = substr($contents, 3);
$status = file_put_contents($filepath, $contents);
return $filepath;
}
}
Members
Name![]() |
Modifiers | Type | Description | Overrides |
---|---|---|---|---|
FeedsFetcherResult:: |
protected | property | The path to a file where the raw data is stored. | |
FeedsFetcherResult:: |
protected | property | The raw fetched data. | |
FeedsFetcherResult:: |
protected | function | Checks that a file exists and is readable. | |
FeedsFetcherResult:: |
public | function | Constructs file name for saving the raw data. | |
FeedsFetcherResult:: |
public | function | Returns if the file to parse exists. | |
FeedsFetcherResult:: |
public | function | Returns directory for storing files that are in progress of import. | |
FeedsFetcherResult:: |
public | function | Returns the contents of a file, if it exists. | |
FeedsFetcherResult:: |
public | function | Get a path to a temporary file containing the resource provided by the fetcher. | 1 |
FeedsFetcherResult:: |
public | function | Returns the raw content. | 2 |
FeedsFetcherResult:: |
public | function | Returns if raw data exists. | |
FeedsFetcherResult:: |
public | function | Sanitize the file in place. | |
FeedsFetcherResult:: |
public | function | Sanitize the raw content string. | |
FeedsFetcherResult:: |
public | function | Sanitize the raw content string. | |
FeedsFetcherResult:: |
public | function | Saves the raw fetcher result to a file. | |
FeedsFetcherResult:: |
public | function | Constructor. | 2 |
FeedsFetcherResult:: |
public | function | Prevent saving the raw result when serializing object. |