Newer
Older
Alex Barth
committed
<?php
/**
* @file
* Contains the FeedsFetcher and related classes.
*/
/**
* Base class for all fetcher results.
*/
class FeedsFetcherResult extends FeedsResult {
protected $raw;
protected $file_path;
/**
* Constructor.
*/
public function __construct($raw) {
$this->raw = $raw;
}
/**
* @return
* The raw content from the source as a string.
*
* @throws Exception
* Extending classes MAY throw an exception if a problem occurred.
*/
public function getRaw() {
return $this->sanitizeRaw($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
* A path to a file containing the raw content as a source.
*
* @throws Exception
* If an unexpected problem occurred.
*/
public function getFilePath() {
if (!isset($this->file_path)) {
$destination = 'public://feeds';
if (!file_prepare_directory($destination, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS)) {
throw new Exception(t('Feeds directory either cannot be created or is not writable.'));
}
$this->file_path = FALSE;
if ($file = file_save_data($this->getRaw(), $destination . '/' . get_class($this) . REQUEST_TIME)) {
$file->status = 0;
file_save($file);
$this->file_path = $file->uri;
}
else {
throw new Exception(t('Cannot write content to %dest', array('%dest' => $destination)));
}
}
return $this->sanitizeFile($this->file_path);
}
/**
* Sanitize the raw content string. Currently supported sanitizations:
*
* - Remove BOM header from UTF-8 files.
*
* @param string $raw
* The raw content string to be sanitized.
* @return
* 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 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
* The file path of the sanitized file.
*/
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)) {
$contents = file_get_contents($filepath);
$contents = substr($contents, 3);
$status = file_put_contents($filepath, $contents);
if ($status === FALSE) {
throw new Exception(t('File @filepath is not writeable.', array('@filepath' => $filepath)));
}
Alex Barth
committed
/**
* Abstract class, defines shared functionality between fetchers.
*
* Implements FeedsSourceInfoInterface to expose source forms to Feeds.
*/
abstract class FeedsFetcher extends FeedsPlugin {
Chris Leppanen
committed
/**
* Implements FeedsPlugin::pluginType().
*/
Chris Leppanen
committed
return 'fetcher';
}
Alex Barth
committed
/**
* Fetch content from a source and return it.
*
* Every class that extends FeedsFetcher must implement this method.
Alex Barth
committed
*
* @param $source
* Source value as entered by user through sourceForm().
*
* @return
* A FeedsFetcherResult object.
Alex Barth
committed
*/
public abstract function fetch(FeedsSource $source);
/**
* Clear all caches for results for given source.
*
* @param FeedsSource $source
* Source information for this expiry. Implementers can choose to only clear
* caches pertaining to this source.
*/
public function clear(FeedsSource $source) {}
/**
* Request handler invoked if callback URL is requested. Locked down by
* default. For a example usage see FeedsHTTPFetcher.
*
* Note: this method may exit the script.
*
* @return
* A string to be returned to the client.
*/
public function request($feed_nid = 0) {
drupal_access_denied();
}
/**
* Construct a path for a concrete fetcher/source combination. The result of
* this method matches up with the general path definition in
* FeedsFetcher::menuItem(). For example usage look at FeedsHTTPFetcher.
*
* @return
* Path for this fetcher/source combination.
*/
public function path($feed_nid = 0) {
$id = urlencode($this->id);
if ($feed_nid && is_numeric($feed_nid)) {
return "feeds/importer/$id/$feed_nid";
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
}
/**
* Menu item definition for fetchers of this class. Note how the path
* component in the item definition matches the return value of
* FeedsFetcher::path();
*
* Requests to this menu item will be routed to FeedsFetcher::request().
*
* @return
* An array where the key is the Drupal menu item path and the value is
* a valid Drupal menu item definition.
*/
public function menuItem() {
return array(
'feeds/importer/%feeds_importer' => array(
'page callback' => 'feeds_fetcher_callback',
'page arguments' => array(2, 3),
'access callback' => TRUE,
'file' => 'feeds.pages.inc',
'type' => MENU_CALLBACK,
),
);
}
/**
* Subscribe to a source. Only implement if fetcher requires subscription.
*
* @param FeedsSource $source
* Source information for this subscription.
*/
public function subscribe(FeedsSource $source) {}
/**
* Unsubscribe from a source. Only implement if fetcher requires subscription.
*
* @param FeedsSource $source
* Source information for unsubscribing.
*/
public function unsubscribe(FeedsSource $source) {}
Alex Barth
committed
/**
* Override import period settings. This can be used to force a certain import
* interval.
*
* @param $source
* A FeedsSource object.
*
* @return
* A time span in seconds if periodic import should be overridden for given
* $source, NULL otherwise.
*/
public function importPeriod(FeedsSource $source) {}
drothstein
committed
/**
* Invoked after an import is finished.
*
* @param $source
* A FeedsSource object.
*/
public function afterImport(FeedsSource $source) {}