Projet

Général

Profil

Paste
Télécharger (6,07 ko) Statistiques
| Branche: | Révision:

root / htmltest / sites / all / modules / feeds / plugins / FeedsFetcher.inc @ a5572547

1
<?php
2

    
3
/**
4
 * @file
5
 * Contains the FeedsFetcher and related classes.
6
 */
7

    
8
/**
9
 * Base class for all fetcher results.
10
 */
11
class FeedsFetcherResult extends FeedsResult {
12
  protected $raw;
13
  protected $file_path;
14

    
15
  /**
16
   * Constructor.
17
   */
18
  public function __construct($raw) {
19
    $this->raw = $raw;
20
  }
21

    
22
  /**
23
   * @return
24
   *   The raw content from the source as a string.
25
   *
26
   * @throws Exception
27
   *   Extending classes MAY throw an exception if a problem occurred.
28
   */
29
  public function getRaw() {
30
    return $this->sanitizeRaw($this->raw);
31
  }
32

    
33
  /**
34
   * Get a path to a temporary file containing the resource provided by the
35
   * fetcher.
36
   *
37
   * File will be deleted after DRUPAL_MAXIMUM_TEMP_FILE_AGE.
38
   *
39
   * @return
40
   *   A path to a file containing the raw content as a source.
41
   *
42
   * @throws Exception
43
   *   If an unexpected problem occurred.
44
   */
45
  public function getFilePath() {
46
    if (!isset($this->file_path)) {
47
      $destination = 'public://feeds';
48
      if (!file_prepare_directory($destination, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS)) {
49
        throw new Exception(t('Feeds directory either cannot be created or is not writable.'));
50
      }
51
      $this->file_path = FALSE;
52
      if ($file = file_save_data($this->getRaw(), $destination . '/' . get_class($this) . REQUEST_TIME)) {
53
        $file->status = 0;
54
        file_save($file);
55
        $this->file_path = $file->uri;
56
      }
57
      else {
58
        throw new Exception(t('Cannot write content to %dest', array('%dest' => $destination)));
59
      }
60
    }
61
    return $this->sanitizeFile($this->file_path);
62
  }
63

    
64
  /**
65
   * Sanitize the raw content string. Currently supported sanitizations:
66
   *
67
   * - Remove BOM header from UTF-8 files.
68
   *
69
   * @param string $raw
70
   *   The raw content string to be sanitized.
71
   * @return
72
   *   The sanitized content as a string.
73
   */
74
  public function sanitizeRaw($raw) {
75
    if (substr($raw, 0, 3) == pack('CCC', 0xef, 0xbb, 0xbf)) {
76
      $raw = substr($raw, 3);
77
    }
78
    return $raw;
79
  }
80

    
81
  /**
82
   * Sanitize the file in place. Currently supported sanitizations:
83
   *
84
   * - Remove BOM header from UTF-8 files.
85
   *
86
   * @param string $filepath
87
   *   The file path of the file to be sanitized.
88
   * @return
89
   *   The file path of the sanitized file.
90
   */
91
  public function sanitizeFile($filepath) {
92
    $handle = fopen($filepath, 'r');
93
    $line = fgets($handle);
94
    fclose($handle);
95
    // If BOM header is present, read entire contents of file and overwrite
96
    // the file with corrected contents.
97
    if (substr($line, 0, 3) == pack('CCC', 0xef, 0xbb, 0xbf)) {
98
      $contents = file_get_contents($filepath);
99
      $contents = substr($contents, 3);
100
      $status = file_put_contents($filepath, $contents);
101
      if ($status === FALSE) {
102
        throw new Exception(t('File @filepath is not writeable.', array('@filepath' => $filepath)));
103
      }
104
    }
105
    return $filepath;
106
  }
107
}
108

    
109
/**
110
 * Abstract class, defines shared functionality between fetchers.
111
 *
112
 * Implements FeedsSourceInfoInterface to expose source forms to Feeds.
113
 */
114
abstract class FeedsFetcher extends FeedsPlugin {
115

    
116
  /**
117
   * Implements FeedsPlugin::pluginType().
118
   */
119
  public function pluginType() {
120
    return 'fetcher';
121
  }
122

    
123
  /**
124
   * Fetch content from a source and return it.
125
   *
126
   * Every class that extends FeedsFetcher must implement this method.
127
   *
128
   * @param $source
129
   *   Source value as entered by user through sourceForm().
130
   *
131
   * @return
132
   *   A FeedsFetcherResult object.
133
   */
134
  public abstract function fetch(FeedsSource $source);
135

    
136
  /**
137
   * Clear all caches for results for given source.
138
   *
139
   * @param FeedsSource $source
140
   *   Source information for this expiry. Implementers can choose to only clear
141
   *   caches pertaining to this source.
142
   */
143
  public function clear(FeedsSource $source) {}
144

    
145
  /**
146
   * Request handler invoked if callback URL is requested. Locked down by
147
   * default. For a example usage see FeedsHTTPFetcher.
148
   *
149
   * Note: this method may exit the script.
150
   *
151
   * @return
152
   *   A string to be returned to the client.
153
   */
154
  public function request($feed_nid = 0) {
155
    drupal_access_denied();
156
  }
157

    
158
  /**
159
   * Construct a path for a concrete fetcher/source combination. The result of
160
   * this method matches up with the general path definition in
161
   * FeedsFetcher::menuItem(). For example usage look at FeedsHTTPFetcher.
162
   *
163
   * @return
164
   *   Path for this fetcher/source combination.
165
   */
166
  public function path($feed_nid = 0) {
167
    $id = urlencode($this->id);
168
    if ($feed_nid && is_numeric($feed_nid)) {
169
      return "feeds/importer/$id/$feed_nid";
170
    }
171
    return "feeds/importer/$id";
172
  }
173

    
174
  /**
175
   * Menu item definition for fetchers of this class. Note how the path
176
   * component in the item definition matches the return value of
177
   * FeedsFetcher::path();
178
   *
179
   * Requests to this menu item will be routed to FeedsFetcher::request().
180
   *
181
   * @return
182
   *   An array where the key is the Drupal menu item path and the value is
183
   *   a valid Drupal menu item definition.
184
   */
185
  public function menuItem() {
186
    return array(
187
      'feeds/importer/%feeds_importer' => array(
188
        'page callback' => 'feeds_fetcher_callback',
189
        'page arguments' => array(2, 3),
190
        'access callback' => TRUE,
191
        'file' => 'feeds.pages.inc',
192
        'type' => MENU_CALLBACK,
193
        ),
194
      );
195
  }
196

    
197
  /**
198
   * Subscribe to a source. Only implement if fetcher requires subscription.
199
   *
200
   * @param FeedsSource $source
201
   *   Source information for this subscription.
202
   */
203
  public function subscribe(FeedsSource $source) {}
204

    
205
  /**
206
   * Unsubscribe from a source. Only implement if fetcher requires subscription.
207
   *
208
   * @param FeedsSource $source
209
   *   Source information for unsubscribing.
210
   */
211
  public function unsubscribe(FeedsSource $source) {}
212

    
213
  /**
214
   * Override import period settings. This can be used to force a certain import
215
   * interval.
216
   *
217
   * @param $source
218
   *   A FeedsSource object.
219
   *
220
   * @return
221
   *   A time span in seconds if periodic import should be overridden for given
222
   *   $source, NULL otherwise.
223
   */
224
  public function importPeriod(FeedsSource $source) {}
225
}