contrib modules security updates

This commit is contained in:
Bachir Soussi Chiadmi
2016-10-13 12:10:40 +02:00
parent ffd758abc9
commit 747127f643
732 changed files with 67976 additions and 23207 deletions

View File

@@ -15,6 +15,10 @@ class FeedsNotExistingException extends Exception {
* Base class for configurable classes. Captures configuration handling, form
* handling and distinguishes between in-memory configuration and persistent
* configuration.
*
* Due to the magic method __get(), protected properties from this class and
* from classes that extend this class will be publicly readable (but not
* writeable).
*/
abstract class FeedsConfigurable {
@@ -44,17 +48,20 @@ abstract class FeedsConfigurable {
protected $disabled;
/**
* Instantiate a FeedsConfigurable object.
* Instantiates a FeedsConfigurable object.
*
* Don't use directly, use feeds_importer() or feeds_plugin()
* instead.
* Don't use directly, use feeds_importer() or feeds_plugin() instead.
*
* @see feeds_importer()
* @see feeds_plugin()
*/
public static function instance($class, $id) {
// This is useful at least as long as we're developing.
if (empty($id)) {
throw new Exception(t('Empty configuration identifier.'));
if (!strlen($id)) {
throw new InvalidArgumentException(t('Empty configuration identifier.'));
}
static $instances = array();
$instances = &drupal_static(__METHOD__, array());
if (!isset($instances[$class][$id])) {
$instances[$class][$id] = new $class($id);
}
@@ -136,8 +143,13 @@ abstract class FeedsConfigurable {
}
/**
* Override magic method __get(). Make sure that $this->config goes through
* getConfig().
* Overrides magic method __get().
*
* - Makes sure that external reads of FeedsConfigurable::config go through
* ::getConfig();
* - Makes private and protected properties from this class and protected
* properties from child classes publicly readable.
* - Prevents warnings when accessing non-existent properties.
*/
public function __get($name) {
if ($name == 'config') {
@@ -169,6 +181,17 @@ abstract class FeedsConfigurable {
return array();
}
/**
* Returns whether or not the configurable has a config form.
*
* @return bool
* True if the configurable has a config form, and false if not.
*/
public function hasConfigForm() {
$form_state = array();
return (bool) $this->configForm($form_state);
}
/**
* Return configuration form for this object. The keys of the configuration
* form must match the keys of the array returned by configDefaults().
@@ -202,6 +225,16 @@ abstract class FeedsConfigurable {
drupal_set_message(t('Your changes have been saved.'));
feeds_cache_clear(FALSE);
}
/**
* Returns an array of required modules.
*
* @return array
* The modules that this configurable requires.
*/
public function dependencies() {
return array();
}
}
/**
@@ -265,6 +298,8 @@ function feeds_form_submit($form, &$form_state) {
/**
* Helper for Feeds validate and submit callbacks.
*
* @todo This is all terrible. Remove.
*/
function _feeds_form_helper($form, &$form_state, $action) {
$method = $form['#feeds_form_method'] . $action;
@@ -277,12 +312,13 @@ function _feeds_form_helper($form, &$form_state, $action) {
// This will re-initialize all of the plugins anyway, causing some tricky
// saving issues in certain cases.
// See http://drupal.org/node/1672880.
if ($class == variable_get('feeds_importer_class', 'FeedsImporter')) {
$form['#configurable'] = feeds_importer($id);
}
else {
$form['#configurable'] = feeds_plugin($class, $id);
$importer = feeds_importer($id);
$plugin_key = $importer->config[$form['#configurable']->pluginType()]['plugin_key'];
$form['#configurable'] = feeds_plugin($plugin_key, $id);
}
if (method_exists($form['#configurable'], $method)) {

View File

@@ -54,49 +54,6 @@ class FeedsImporter extends FeedsConfigurable {
}
}
/**
* Remove items older than $time.
*
* @param $time
* All items older than REQUEST_TIME - $time will be deleted. If not
* given, internal processor settings will be used.
*
* @return
* FEEDS_BATCH_COMPLETE if the expiry process finished. A decimal between
* 0.0 and 0.9 periodic if expiry is still in progress.
*
* @throws
* Throws Exception if an error occurs when expiring items.
*/
public function expire($time = NULL) {
return $this->processor->expire($time);
}
/**
* Schedule all periodic tasks for this importer.
*/
public function schedule() {
$this->scheduleExpire();
}
/**
* Schedule expiry of items.
*/
public function scheduleExpire() {
$job = array(
'type' => $this->id,
'period' => 0,
'periodic' => TRUE,
);
if (FEEDS_EXPIRE_NEVER != $this->processor->expiryTime()) {
$job['period'] = 3600;
JobScheduler::get('feeds_importer_expire')->set($job);
}
else {
JobScheduler::get('feeds_importer_expire')->remove($job);
}
}
/**
* Report how many items *should* be created on one page load by this
* importer.
@@ -155,23 +112,17 @@ class FeedsImporter extends FeedsConfigurable {
}
/**
* Delete configuration. Removes configuration information
* from database, does not delete configuration itself.
* Deletes configuration.
*
* Removes configuration information from database, does not delete
* configuration itself.
*/
public function delete() {
db_delete('feeds_importer')
->condition('id', $this->id)
->execute();
$job = array(
'type' => $this->id,
'id' => 0,
);
if ($this->export_type & EXPORT_IN_CODE) {
feeds_reschedule($this->id);
}
else {
JobScheduler::get('feeds_importer_expire')->remove($job);
}
feeds_reschedule($this->id);
}
/**
@@ -320,6 +271,17 @@ class FeedsImporter extends FeedsConfigurable {
}
parent::configFormSubmit($values);
}
/**
* Implements FeedsConfigurable::dependencies().
*/
public function dependencies() {
$dependencies = parent::dependencies();
foreach ($this->plugin_types as $plugin_type) {
$dependencies = array_merge($dependencies, $this->$plugin_type->dependencies());
}
return $dependencies;
}
}
/**

View File

@@ -6,7 +6,7 @@
*/
/**
* Distinguish exceptions occuring when handling locks.
* Distinguish exceptions occurring when handling locks.
*/
class FeedsLockException extends Exception {}
@@ -18,6 +18,7 @@ define('FEEDS_FETCH', 'fetch');
define('FEEDS_PARSE', 'parse');
define('FEEDS_PROCESS', 'process');
define('FEEDS_PROCESS_CLEAR', 'process_clear');
define('FEEDS_PROCESS_EXPIRE', 'process_expire');
/**
* Declares an interface for a class that defines default values and form
@@ -86,9 +87,16 @@ class FeedsState {
public $created;
public $updated;
public $deleted;
public $unpublished;
public $blocked;
public $skipped;
public $failed;
/**
* IDs of entities to be removed.
*/
public $removeList;
/**
* Constructor, initialize variables.
*/
@@ -98,6 +106,8 @@ class FeedsState {
$this->created =
$this->updated =
$this->deleted =
$this->unpublished =
$this->blocked =
$this->skipped =
$this->failed = 0;
}
@@ -124,7 +134,7 @@ class FeedsState {
$this->progress = FEEDS_BATCH_COMPLETE;
}
elseif ($total) {
$this->progress = $progress / $total;
$this->progress = (float) $progress / $total;
if ($this->progress == FEEDS_BATCH_COMPLETE && $total != $progress) {
$this->progress = 0.99;
}
@@ -178,13 +188,18 @@ class FeedsSource extends FeedsConfigurable {
// Timestamp when this source was imported the last time.
protected $imported;
// Holds an exception object in case an exception occurs during importing.
protected $exception;
/**
* Instantiate a unique object per class/id/feed_nid. Don't use
* directly, use feeds_source() instead.
*/
public static function instance($importer_id, $feed_nid) {
$class = variable_get('feeds_source_class', 'FeedsSource');
static $instances = array();
$instances = &drupal_static(__METHOD__, array());
if (!isset($instances[$class][$importer_id][$feed_nid])) {
$instances[$class][$importer_id][$feed_nid] = new $class($importer_id, $feed_nid);
}
@@ -273,6 +288,7 @@ class FeedsSource extends FeedsConfigurable {
*/
public function schedule() {
$this->scheduleImport();
$this->scheduleExpire();
}
/**
@@ -285,19 +301,44 @@ class FeedsSource extends FeedsConfigurable {
if (is_numeric($fetcher_period)) {
$period = $fetcher_period;
}
$period = $this->progressImporting() === FEEDS_BATCH_COMPLETE ? $period : 0;
$job = array(
'type' => $this->id,
'id' => $this->feed_nid,
// Schedule as soon as possible if a batch is active.
'period' => $period,
'periodic' => TRUE,
);
if ($period != FEEDS_SCHEDULE_NEVER) {
if ($period == FEEDS_SCHEDULE_NEVER && $this->progressImporting() === FEEDS_BATCH_COMPLETE) {
JobScheduler::get('feeds_source_import')->remove($job);
}
elseif ($this->progressImporting() === FEEDS_BATCH_COMPLETE) {
JobScheduler::get('feeds_source_import')->set($job);
}
else {
JobScheduler::get('feeds_source_import')->remove($job);
// Feed is not fully imported yet, so we put this job back in the queue
// immediately for further processing.
$queue = DrupalQueue::get('feeds_source_import');
$queue->createItem($job);
}
}
/**
* Schedule background expire tasks.
*/
public function scheduleExpire() {
// Schedule as soon as possible if a batch is active.
$period = $this->progressExpiring() === FEEDS_BATCH_COMPLETE ? 3600 : 0;
$job = array(
'type' => $this->id,
'id' => $this->feed_nid,
'period' => $period,
'periodic' => TRUE,
);
if ($this->importer->processor->expiryTime() == FEEDS_EXPIRE_NEVER) {
JobScheduler::get('feeds_source_expire')->remove($job);
}
else {
JobScheduler::get('feeds_source_expire')->set($job);
}
}
@@ -339,6 +380,7 @@ class FeedsSource extends FeedsConfigurable {
try {
// If fetcher result is empty, we are starting a new import, log.
if (empty($this->fetcher_result)) {
module_invoke_all('feeds_before_import', $this);
$this->state[FEEDS_START] = time();
}
@@ -355,27 +397,91 @@ class FeedsSource extends FeedsConfigurable {
// Process.
$this->importer->processor->process($this, $parser_result);
// Import finished without exceptions, so unset any potentially previously
// recorded exceptions.
unset($this->exception);
}
catch (Exception $e) {
// Do nothing.
// $e is stored and re-thrown once we've had a chance to log our progress.
// Set the exception so that other modules can check if an exception
// occurred in hook_feeds_after_import().
$this->exception = $e;
}
$this->releaseLock();
// Clean up.
$result = $this->progressImporting();
if ($result == FEEDS_BATCH_COMPLETE || isset($e)) {
$this->imported = time();
$this->log('import', 'Imported in !s s', array('!s' => $this->imported - $this->state[FEEDS_START]), WATCHDOG_INFO);
$this->log('import', 'Imported in @s seconds.', array('@s' => $this->imported - $this->state[FEEDS_START]), WATCHDOG_INFO);
module_invoke_all('feeds_after_import', $this);
unset($this->fetcher_result, $this->state);
}
$this->save();
$this->releaseLock();
if (isset($e)) {
throw $e;
}
return $result;
}
/**
* Imports a fetcher result all at once in memory.
*
* @param FeedsFetcherResult $fetcher_result
* The fetcher result to process.
*
* @throws Exception
* Thrown if an error occurs when importing.
*/
public function pushImport(FeedsFetcherResult $fetcher_result) {
// Since locks only work during a request, check if an import is active.
if (!empty($this->fetcher_result) || !empty($this->state)) {
throw new RuntimeException('The feed is currently importing.');
}
$this->acquireLock();
$start = time();
try {
module_invoke_all('feeds_before_import', $this);
// Parse.
do {
$parser_result = $this->importer->parser->parse($this, $fetcher_result);
module_invoke_all('feeds_after_parse', $this, $parser_result);
// Process.
$this->importer->processor->process($this, $parser_result);
} while ($this->progressParsing() !== FEEDS_BATCH_COMPLETE);
}
catch (Exception $e) {
// $e is stored and re-thrown once we've had a chance to log our progress.
// Set the exception so that other modules can check if an exception
// occurred in hook_feeds_after_import().
$this->exception = $e;
}
module_invoke_all('feeds_after_import', $this);
$this->imported = time();
$this->log('import', 'Imported in @s seconds.', array('@s' => $this->imported - $start), WATCHDOG_INFO);
unset($this->fetcher_result, $this->state);
$this->save();
$this->releaseLock();
if (isset($e)) {
throw $e;
}
}
/**
* Remove all items from a feed.
*
@@ -398,7 +504,7 @@ class FeedsSource extends FeedsConfigurable {
$this->importer->processor->clear($this);
}
catch (Exception $e) {
// Do nothing.
// $e is stored and re-thrown once we've had a chance to log our progress.
}
$this->releaseLock();
@@ -415,6 +521,26 @@ class FeedsSource extends FeedsConfigurable {
return $result;
}
/**
* Removes all expired items from a feed.
*/
public function expire() {
$this->acquireLock();
try {
$result = $this->importer->processor->expire($this);
}
catch (Exception $e) {
// Will throw after the lock is released.
}
$this->releaseLock();
if (isset($e)) {
throw $e;
}
return $result;
}
/**
* Report progress as float between 0 and 1. 1 = FEEDS_BATCH_COMPLETE.
*/
@@ -449,6 +575,13 @@ class FeedsSource extends FeedsConfigurable {
return $this->state(FEEDS_PROCESS_CLEAR)->progress;
}
/**
* Report progress on expiry.
*/
public function progressExpiring() {
return $this->state(FEEDS_PROCESS_EXPIRE)->progress;
}
/**
* Return a state object for a given stage. Lazy instantiates new states.
*
@@ -526,6 +659,9 @@ class FeedsSource extends FeedsConfigurable {
if (!empty($record->state)) {
$this->state = unserialize($record->state);
}
if (!is_array($this->state)) {
$this->state = array();
}
if (!empty($record->fetcher_result)) {
$this->fetcher_result = unserialize($record->fetcher_result);
}
@@ -552,6 +688,7 @@ class FeedsSource extends FeedsConfigurable {
'id' => $this->feed_nid,
);
JobScheduler::get('feeds_source_import')->remove($job);
JobScheduler::get('feeds_source_expire')->remove($job);
}
/**
@@ -722,4 +859,13 @@ class FeedsSource extends FeedsConfigurable {
protected function releaseLock() {
lock_release("feeds_source_{$this->id}_{$this->feed_nid}");
}
/**
* Implements FeedsConfigurable::dependencies().
*/
public function dependencies() {
$dependencies = parent::dependencies();
return array_merge($dependencies, $this->importer()->dependencies());
}
}