Skip to content
Snippets Groups Projects
FeedsSource.inc 36.9 KiB
Newer Older
    // Alert implementers of FeedsSourceInterface to the fact that we're
    // deleting.
    foreach ($this->importer->plugin_types as $type) {
      $this->importer->$type->sourceDelete($this);
    }
    db_delete('feeds_source')
      ->condition('id', $this->id)
      ->condition('feed_nid', $this->feed_nid)
      ->execute();
    // Remove from schedule.
    $job = array(
      'type' => $this->id,
      'id' => $this->feed_nid,
    );
    JobScheduler::get('feeds_source_import')->remove($job);
    JobScheduler::get('feeds_source_expire')->remove($job);
  /**
   * Checks whether or not the source configuration is valid.
   *
   * @return bool
   *   True if it is valid.
   *   False otherwise.
   */
  public function hasValidConfiguration() {
    // If there is no feed nid given, there must be no content type specified.
    $standalone = empty($this->feed_nid) && empty($this->importer->config['content_type']);

    // If there is a feed nid given, there must be a content type specified.
    $attached = !empty($this->feed_nid) && !empty($this->importer->config['content_type']);

    if ($standalone || $attached) {
      return TRUE;
    }
    return FALSE;
  }

  /**
   * Overrides FeedsConfigurable::doesExist().
   *
   * Checks the following:
   * - If the importer is persistent (= defined in code or DB).
   * - If the source is persistent (= defined in DB).
   */
  public function doesExist() {
    return $this->importer->doesExist() && parent::doesExist();
  }

   * Only return source if configuration is persistent and valid.
   * @see FeedsConfigurable::existing()
    // Ensure that the source configuration is valid.
    if (!$this->hasValidConfiguration()) {
      throw new FeedsNotExistingException(t('Source configuration not valid.'));
    }

    // Ensure that the importer is persistent (= defined in code or DB).
    $this->importer->existing();

    // Ensure that the source is persistent (= defined in DB).
    return parent::existing();
   * Returns the configuration for a specific client class.
   *
   * @param FeedsSourceInterface $client
   *   An object that is an implementer of FeedsSourceInterface.
   *
   *   An array stored for $client.
   */
  public function getConfigFor(FeedsSourceInterface $client) {
    $class = get_class($client);
    return isset($this->config[$class]) ? $this->config[$class] : $client->sourceDefaults();
  /**
   * Sets the configuration for a specific client class.
   *
   * @param FeedsSourceInterface $client
   *   An object that is an implementer of FeedsSourceInterface.
  public function setConfigFor(FeedsSourceInterface $client, array $config) {
   *   The default feed configuration, keyed per Feeds plugin.
   */
  public function configDefaults() {
    // Collect information from plugins.
    $defaults = array();
    foreach ($this->importer->plugin_types as $type) {
      if ($this->importer->$type->hasSourceConfig()) {
        $defaults[get_class($this->importer->$type)] = $this->importer->$type->sourceDefaults();
      }
    }
    return $defaults;
  }

  /**
   * Override parent::configForm().
   */
  public function configForm(&$form_state) {
    // Collect information from plugins.
    $form = array();
    foreach ($this->importer->plugin_types as $type) {
      if ($this->importer->$type->hasSourceConfig()) {
        $class = get_class($this->importer->$type);
Alex Barth's avatar
Alex Barth committed
        $config = isset($this->config[$class]) ? $this->config[$class] : array();
        $form[$class] = $this->importer->$type->sourceForm($config);
        $form[$class]['#tree'] = TRUE;
      }
    }
    return $form;
  }

  /**
   * Override parent::configFormValidate().
   */
  public function configFormValidate(&$values) {
    foreach ($this->importer->plugin_types as $type) {
      $class = get_class($this->importer->$type);
      if (isset($values[$class]) && $this->importer->$type->hasSourceConfig()) {
        $this->importer->$type->sourceFormValidate($values[$class]);
      }
    }
  }
Alex Barth's avatar
Alex Barth committed
  /**
   * Writes to feeds log.
   */
  public function log($type, $message, $variables = array(), $severity = WATCHDOG_NOTICE) {
    feeds_log($this->id, $this->feed_nid, $type, $message, $variables, $severity);
  }

   * Background job helper. Starts a background job using the Drupal queue.
   *   Method to execute on importer; one of 'import' or 'clear'.
   *
   * @see FeedsSource::startImport()
   * @see FeedsSource::startClear()
   */
  protected function startBackgroundJob($method) {
    $job = array(
      'type' => $this->id,
      'id' => $this->feed_nid,
    );
    $queue = DrupalQueue::get('feeds_source_' . $method);
    $queue->createItem($job);

    switch ($method) {
      case 'import':
        $state = $this->state(FEEDS_PARSE);
        break;

      case 'clear':
        $state = $this->state(FEEDS_PROCESS_CLEAR);
        break;

      case 'expire':
        $state = $this->state(FEEDS_PROCESS_EXPIRE);
        break;
    }

    if (isset($state)) {
      $state->progress = 0;
      $this->save();
    }
  }

  /**
   * Batch API helper. Starts a Batch API job.
   *
   * @param string $title
   *   Title to show to user when executing batch.
   * @param string $method
   *   Method to execute on importer; one of 'import' or 'clear'.
   *
   * @see FeedsSource::startImport()
   * @see FeedsSource::startClear()
   * @see feeds_batch()
   */
  protected function startBatchAPIJob($title, $method) {
    $batch = array(
      'title' => $title,
      'operations' => array(
        array('feeds_batch', array($method, $this->id, $this->feed_nid)),
      ),
      'progress_message' => '',
    );
    batch_set($batch);
  }

  /**
   * Acquires a lock for this source.
   *
   * @throws FeedsLockException
   *   If a lock for the requested job could not be acquired.
   */
  protected function acquireLock() {
    if (!lock_acquire("feeds_source_{$this->id}_{$this->feed_nid}", 60.0)) {
      throw new FeedsLockException(t('Cannot acquire lock for source @id / @feed_nid.', array('@id' => $this->id, '@feed_nid' => $this->feed_nid)));
    }
  }

  /**
   * Releases a lock for this source.
   */
  protected function releaseLock() {
    lock_release("feeds_source_{$this->id}_{$this->feed_nid}");
   * Switches account to the feed owner or user 1.
   *
   * To the feed owner is switched if the importer is attached to a content
   * type. When using the standalone form, there is no feed owner, so then a
   * switch to user 1 happens instead.
   */
  protected function switchAccount() {
    // Use author of feed node.
    if ($this->feed_nid) {
      $node = node_load($this->feed_nid);
      if (!empty($node->uid)) {
        $account = user_load($node->uid);
      }
    }

    // If the owner of the feed node is anonymous or if the importer is not
    // attached to a content type, pick user 1 instead.
    if (empty($account)) {
      $account = user_load(1);
    }

    $this->accountSwitcher->switchTo($account);
  }

  /**
   * Switches back to the original user.
   */
  protected function switchBack() {
    $this->accountSwitcher->switchBack();
  /**
   * Implements FeedsConfigurable::dependencies().
   */
  public function dependencies() {
    $dependencies = parent::dependencies();
    return array_merge($dependencies, $this->importer()->dependencies());
  }