summaryrefslogtreecommitdiffstats
path: root/plugins/FeedsFileFetcher.inc
blob: a263b9e3f6a9715c9a5c020c333968276aa26c15 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
<?php
// $Id$

/**
 * @file
 * Home of the FeedsFileFetcher and related classes.
 */

/**
 * Definition of the import batch object created on the fetching stage by
 * FeedsFileFetcher.
 */
class FeedsFileBatch extends FeedsImportBatch {
  /**
   * Constructor.
   */
  public function __construct($file_path, $feed_nid = 0) {
    $this->file_path = $file_path;
    parent::__construct('', $feed_nid);
  }

  /**
   * Implements FeedsImportBatch::getRaw();
   */
  public function getRaw() {
    return file_get_contents(realpath($this->file_path));
  }

  /**
   * Implements FeedsImportBatch::getFilePath().
   */
  public function getFilePath() {
    if (!file_exists($this->file_path)) {
      throw new Exception(t('File @filepath is not accessible.', array('@filepath' => $this->file_path)));
    }
    return $this->file_path;
  }
}

/**
 * Fetches data via HTTP.
 */
class FeedsFileFetcher extends FeedsFetcher {

  /**
   * Implements FeedsFetcher::fetch().
   */
  public function fetch(FeedsSource $source) {
    $source_config = $source->getConfigFor($this);
    return new FeedsFileBatch($source_config['source'], $source->feed_nid);
  }

  /**
   * Source form.
   */
  public function sourceForm($source_config) {
    $form = $info = array();
    if (!empty($source_config['source']) && file_exists($source_config['source'])) {
      $info = array(
        'path' => $source_config['source'],
        'size' => filesize(realpath($source_config['source'])),
      );
      if (module_exists('mimedetect')) {
        $info['mime'] = mimedetect_mime(realpath($source_config['source']));
      }
    }
    $form['source'] = array(
      '#type' => empty($this->config['direct']) ? 'value' : 'textfield',
      '#title' => t('File'),
      '#description' => t('Specify a file in the site\'s file system path or upload a file below.'),
      '#default_value' => empty($source_config['source']) ? '' : $source_config['source'],
    );
    $form['upload'] = array(
      '#type' => 'file',
      '#title' => empty($this->config['direct']) ? t('File') : NULL,
      '#description' => empty($source_config['source']) ? t('Select the file to be imported from your local system.') : t('Select a different file to be imported from your local system.'),
      '#theme' => 'feeds_upload',
      '#file_info' => $info,
      '#size' => 10,
    );
    return $form;
  }

  /**
   * Override parent::sourceFormValidate().
   */
  public function sourceFormValidate(&$values) {
    $feed_dir = 'public://feeds';
    file_prepare_directory($feed_dir, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS);

    // If there is a file uploaded, save it, otherwise validate input on
    // file.
    if ($file = file_save_upload('feeds', array('file_validate_extensions' => array(0 => $this->config['allowed_extensions'])), $feed_dir)) {
      $values['source'] = $file->uri;
    }
    elseif (empty($values['source'])) {
      form_set_error('feeds][source', t('Upload a file first.'));
    }
    // If a file has not been uploaded and $values['source'] is not empty, make
    // sure that this file is within Drupal's files directory as otherwise
    // potentially any file that the web server has access could be exposed.
    elseif (strpos($values['source'], 'public://') !== 0) {
      form_set_error('feeds][source', t('File needs to reside within the site\'s file directory, its path needs to start with public://.'));
    }
  }

  /**
   * Override parent::configDefaults().
   */
  public function configDefaults() {
    return array(
      'allowed_extensions' => 'txt csv xml',
      'direct' => FALSE,
    );
  }

  /**
   * Override parent::configForm().
   */
  public function configForm(&$form_state) {
    $form = array();
    $form['allowed_extensions'] = array(
      '#type' =>'textfield',
      '#title' => t('Allowed file extensions'),
      '#description' => t('Allowed file extensions for upload.'),
      '#default_value' => $this->config['allowed_extensions'],
    );
    $form['direct'] = array(
      '#type' =>'checkbox',
      '#title' => t('Supply path to file directly'),
      '#description' => t('For experts. If checked users can specify a path to a file when importing rather than uploading a file. This is useful when files to be imported are already present on server.'),
      '#default_value' => $this->config['direct'],
    );
    return $form;
  }
}