Projet

Général

Profil

Paste
Télécharger (10,2 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / feeds / mappers / file.inc @ b5aa1857

1 85ad3d82 Assos Assos
<?php
2
3
/**
4
 * @file
5
 * On behalf implementation of Feeds mapping API for file.module and
6
 * image.module.
7
 */
8
9 7295e063 Assos Assos
/**
10
 * Flag for dealing with existing files: Replace the existing file if it is
11
 * different. Do nothing if the new file is exactly the same as the existing
12
 * file.
13
 */
14
define('FEEDS_FILE_EXISTS_REPLACE_DIFFERENT', 3);
15
16
/**
17
 * Flag for dealing with existing files: If the new file is different, rename
18
 * it by appending a number until the name is unique. Do nothing if the new file
19
 * is exactly the same as the existing file.
20
 */
21
define('FEEDS_FILE_EXISTS_RENAME_DIFFERENT', 4);
22
23
/**
24
 * Flag for dealing with existing files: Do nothing if a file with the same name
25
 * already exists.
26
 */
27
define('FEEDS_FILE_EXISTS_SKIP', 5);
28
29 85ad3d82 Assos Assos
/**
30 41cc1b08 Assos Assos
 * Implements hook_feeds_processor_targets().
31 85ad3d82 Assos Assos
 */
32 41cc1b08 Assos Assos
function file_feeds_processor_targets($entity_type, $bundle_name) {
33
  $targets = array();
34
35 85ad3d82 Assos Assos
  foreach (field_info_instances($entity_type, $bundle_name) as $name => $instance) {
36
    $info = field_info_field($name);
37
38
    if (in_array($info['type'], array('file', 'image'))) {
39 41cc1b08 Assos Assos
      $targets[$name . ':uri'] = array(
40
        'name' => t('@label: URI', array('@label' => $instance['label'])),
41 85ad3d82 Assos Assos
        'callback' => 'file_feeds_set_target',
42 41cc1b08 Assos Assos
        'description' => t('The URI of the @label field.', array('@label' => $instance['label'])),
43
        'real_target' => $name,
44 7295e063 Assos Assos
        'summary_callbacks' => array('file_feeds_summary_callback'),
45
        'form_callbacks' => array('file_feeds_form_callback'),
46 85ad3d82 Assos Assos
      );
47 41cc1b08 Assos Assos
48 a192dc0b Assos Assos
      // Keep the old target name for backwards compatibility, but hide it from
49
      // the UI.
50
      $targets[$name] = $targets[$name . ':uri'];
51
      $targets[$name]['deprecated'] = TRUE;
52
53 41cc1b08 Assos Assos
      if ($info['type'] == 'image') {
54
        $targets[$name . ':alt'] = array(
55
          'name' => t('@label: Alt', array('@label' => $instance['label'])),
56
          'callback' => 'file_feeds_set_target',
57
          'description' => t('The alt tag of the @label field.', array('@label' => $instance['label'])),
58
          'real_target' => $name,
59
        );
60
        $targets[$name . ':title'] = array(
61
          'name' => t('@label: Title', array('@label' => $instance['label'])),
62
          'callback' => 'file_feeds_set_target',
63
          'description' => t('The title of the @label field.', array('@label' => $instance['label'])),
64
          'real_target' => $name,
65
        );
66
      }
67
      elseif ($info['type'] === 'file') {
68
        $targets[$name . ':description'] = array(
69
          'name' => t('@label: Description', array('@label' => $instance['label'])),
70
          'callback' => 'file_feeds_set_target',
71
          'description' => t('The description of the @label field.', array('@label' => $instance['label'])),
72
          'real_target' => $name,
73
        );
74
      }
75 85ad3d82 Assos Assos
    }
76
  }
77 41cc1b08 Assos Assos
78
  return $targets;
79 85ad3d82 Assos Assos
}
80
81
/**
82 41cc1b08 Assos Assos
 * Callback for mapping file fields.
83 85ad3d82 Assos Assos
 */
84 a192dc0b Assos Assos
function file_feeds_set_target(FeedsSource $source, $entity, $target, array $values, array $mapping) {
85
  $language = $mapping['language'];
86 7295e063 Assos Assos
  $mapping += array('file_exists' => FILE_EXISTS_RENAME);
87 a192dc0b Assos Assos
88 41cc1b08 Assos Assos
  // Add default of uri for backwards compatibility.
89
  list($field_name, $sub_field) = explode(':', $target . ':uri');
90
  $info = field_info_field($field_name);
91 85ad3d82 Assos Assos
92 41cc1b08 Assos Assos
  if ($sub_field == 'uri') {
93
94
    foreach ($values as $k => $v) {
95
      if (!($v instanceof FeedsEnclosure)) {
96 7295e063 Assos Assos
        if (!empty($v) && is_string($v)) {
97 41cc1b08 Assos Assos
          $values[$k] = new FeedsEnclosure($v, file_get_mimetype($v));
98
        }
99
        else {
100
          // Set the value for FALSE rather than remove it to keep our deltas
101
          // correct.
102
          $values[$k] = FALSE;
103
        }
104 85ad3d82 Assos Assos
      }
105
    }
106
107 a192dc0b Assos Assos
    if ($entity instanceof Entity) {
108
      $entity_type = $entity->entityType();
109
      $bundle = $entity->bundle();
110
    }
111
    else {
112
      $entity_type = $source->importer->processor->entityType();
113
      $bundle = $source->importer->processor->bundle();
114
    }
115 41cc1b08 Assos Assos
    $instance_info = field_info_instance($entity_type, $field_name, $bundle);
116
117
    // Determine file destination.
118
    // @todo This needs review and debugging.
119
    $data = array();
120
    if (!empty($entity->uid)) {
121
      $data[$entity_type] = $entity;
122
    }
123
124
    $destination = file_field_widget_uri($info, $instance_info, $data);
125 85ad3d82 Assos Assos
  }
126
127
  // Populate entity.
128 a192dc0b Assos Assos
  $field = isset($entity->$field_name) ? $entity->$field_name : array($language => array());
129 41cc1b08 Assos Assos
  $delta = 0;
130
  foreach ($values as $v) {
131
    if ($info['cardinality'] == $delta) {
132
      break;
133 85ad3d82 Assos Assos
    }
134 41cc1b08 Assos Assos
135 a192dc0b Assos Assos
    if (!isset($field[$language][$delta])) {
136
      $field[$language][$delta] = array();
137 85ad3d82 Assos Assos
    }
138 41cc1b08 Assos Assos
139
    switch ($sub_field) {
140
      case 'alt':
141
      case 'title':
142
      case 'description':
143 a192dc0b Assos Assos
        $field[$language][$delta][$sub_field] = $v;
144 41cc1b08 Assos Assos
        break;
145
146
      case 'uri':
147 7295e063 Assos Assos
        $skip = FALSE;
148 41cc1b08 Assos Assos
        if ($v) {
149 7295e063 Assos Assos
          if ($mapping['file_exists'] == FEEDS_FILE_EXISTS_SKIP) {
150
            if (file_exists($destination . '/' . basename($v->getValue()))) {
151
              $skip = TRUE;
152
            }
153
            else {
154
              // We already know the file doesn't exist so we don't have to
155
              // worry about anything being renamed, but we do need a valid
156
              // replace value for file_save().
157
              $mapping['file_exists'] = FILE_EXISTS_RENAME;
158
            }
159
          }
160
          if ($mapping['file_exists'] == FEEDS_FILE_EXISTS_REPLACE_DIFFERENT) {
161
            if (file_exists($destination . '/' . basename($v->getValue())) && file_feeds_file_compare($v->getValue(), $destination . '/' . basename($v->getValue()))) {
162
              $skip = TRUE;
163
            }
164
            else {
165
              // Either the file doesn't exist or it does and it's different.
166
              $mapping['file_exists'] = FILE_EXISTS_REPLACE;
167
            }
168
          }
169
          if ($mapping['file_exists'] == FEEDS_FILE_EXISTS_RENAME_DIFFERENT) {
170
            if (file_exists($destination . '/' . basename($v->getValue())) && file_feeds_file_compare($v->getValue(), $destination . '/' . basename($v->getValue()))) {
171
              $skip = TRUE;
172
            }
173
            else {
174
              // Either the file doesn't exist or it does and it's different.
175
              $mapping['file_exists'] = FILE_EXISTS_RENAME;
176
            }
177
          }
178
          if ($skip) {
179
            // Create a new dummy feeds enclosure where the value is the file
180
            // already in the file system (it will be skipped by getFile()).
181
            $mapping['file_exists'] = FEEDS_FILE_EXISTS_SKIP;
182
            $existing_path = $destination . '/' . basename($v->getValue());
183
            $v = new FeedsEnclosure($existing_path, file_get_mimetype($existing_path));
184
          }
185 41cc1b08 Assos Assos
          try {
186
            $v->setAllowedExtensions($instance_info['settings']['file_extensions']);
187 7295e063 Assos Assos
            $field[$language][$delta] += (array) $v->getFile($destination, $mapping['file_exists']);
188 41cc1b08 Assos Assos
            // @todo: Figure out how to properly populate this field.
189 a192dc0b Assos Assos
            $field[$language][$delta]['display'] = 1;
190 41cc1b08 Assos Assos
          }
191
          catch (Exception $e) {
192
            watchdog('feeds', check_plain($e->getMessage()));
193 7295e063 Assos Assos
            continue;
194 41cc1b08 Assos Assos
          }
195
        }
196 85ad3d82 Assos Assos
        break;
197
    }
198 41cc1b08 Assos Assos
199
    $delta++;
200 85ad3d82 Assos Assos
  }
201 41cc1b08 Assos Assos
202
  $entity->$field_name = $field;
203 85ad3d82 Assos Assos
}
204 7295e063 Assos Assos
205
/**
206
 * Mapping configuration summary callback for file targets.
207
 */
208
function file_feeds_summary_callback($mapping, $target, $form, $form_state) {
209
  $mapping += array('file_exists' => FILE_EXISTS_RENAME);
210
  switch ($mapping['file_exists']) {
211
    case FILE_EXISTS_REPLACE:
212
      return t('Replace existing files');
213
214
    case FILE_EXISTS_RENAME:
215
      return t('Rename if file exists');
216
217
    case FEEDS_FILE_EXISTS_REPLACE_DIFFERENT:
218
      return t('Replace only if file exists, but is different');
219
220
    case FEEDS_FILE_EXISTS_RENAME_DIFFERENT:
221
      return t('Rename only if file exists, but is different');
222
223
    case FEEDS_FILE_EXISTS_SKIP:
224
      return t('Skip if file exists');
225
  }
226
}
227
228
/**
229
 * Mapping configuration form callback for file targets.
230
 */
231
function file_feeds_form_callback($mapping, $target, $form, $form_state) {
232
  $description = array(
233
    '#theme' => 'item_list',
234
    '#items' => array(
235
      t('Rename: files whose name is already in use are renamed.'),
236
      t('Replace: files on the site with the same name are replaced.'),
237
      t('Replace only if different: files on the site with the same name are replaced only if the file to import is different, in other cases the file will not be imported. Works only if the file to import is locally accessible.'),
238
      t('Rename only if different: files on the site with the same name are renamed only if the file to import is different, in other cases the file will not be imported. Works only if the file to import is locally accessible.'),
239
      t('Skip existing: files whose name is already in use are not imported.'),
240
    ),
241
  );
242
243
  return array(
244
    'file_exists' => array(
245
      '#type' => 'select',
246
      '#title' => t('Replacement method'),
247
      '#default_value' => !empty($mapping['file_exists']) ? $mapping['file_exists'] : FILE_EXISTS_RENAME,
248
      '#options' => array(
249
        FILE_EXISTS_RENAME => t('Rename'),
250
        FILE_EXISTS_REPLACE => t('Replace'),
251
        FEEDS_FILE_EXISTS_REPLACE_DIFFERENT => t('Replace only if different'),
252
        FEEDS_FILE_EXISTS_RENAME_DIFFERENT => t('Rename only if different'),
253
        FEEDS_FILE_EXISTS_SKIP => t('Skip existing'),
254
      ),
255
      '#description' => t('New files are always copied. Files that have a name that is already in use on the site are handled based on this setting.') . drupal_render($description) . t('Note that this setting has no effect when using the File (Field) Paths module.'),
256
    ),
257
  );
258
}
259
260
/**
261
 * Compares two files to determine if they are the same.
262
 *
263
 * @param string $file1
264
 *   The path to the first file to compare.
265
 *
266
 * @param string $file2
267
 *   The path to the second file to compare.
268
 *
269
 * @return bool
270
 *   TRUE if the files are the same.
271
 *   FALSE otherwise.
272
 */
273
function file_feeds_file_compare($file1, $file2) {
274
  // If the file size is different then assume they are different files.
275
  // However, remote files may return FALSE from filesize() so only compare
276
  // file sizes if both values are not empty.
277
  $filesize1 = filesize($file1);
278
  $filesize2 = filesize($file2);
279
  if ($filesize1 !== FALSE && $filesize2 !== FALSE && $filesize1 !== $filesize2) {
280
    return FALSE;
281
  }
282
283
  // File sizes are the same so check md5 hash of files.
284
  if (md5_file($file1) != md5_file($file2)) {
285
    return FALSE;
286
  }
287
288
  return TRUE;
289
}