Projet

Général

Profil

Paste
Télécharger (28,3 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / feeds / feeds.drush.inc @ 651307cd

1
<?php
2

    
3
/**
4
 * @file
5
 * Drush commands for Feeds module.
6
 */
7

    
8
/**
9
 * The default maximum number of feeds to list or import.
10
 *
11
 * @var int
12
 */
13
define('DRUSH_FEEDS_DEFAULT_LIMIT', 2147483647);
14

    
15
/**
16
 * Implements hook_drush_command().
17
 */
18
function feeds_drush_command() {
19
  $items = array();
20

    
21
  $items['feeds-list-importers'] = array(
22
    'description' => 'Get a list of all Feeds importers in the system.',
23
    'aliases' => array('feeds'),
24
  );
25

    
26
  $items['feeds-list-feeds'] = array(
27
    'description' => 'List all feed sources.',
28
    'arguments' => array(
29
      'importer' => 'The name of the Feeds importer whose instances will be listed. Optional.',
30
    ),
31
    'examples' => array(
32
      'drush feeds-list-feeds' => 'List all instances of all feeds.',
33
      'drush feeds-list-feeds rss_feed' => 'List all feed sources of the rss_feed importer.',
34
      'drush feeds-list-feeds --limit=3' => 'Only list the first three feed sources.',
35
    ),
36
    'options' => array(
37
      'limit' => 'Limit the number of feeds to show in the list. Optional.',
38
    ),
39
    'aliases' => array('feeds-lf'),
40
  );
41

    
42
  $items['feeds-import'] = array(
43
    'description' => 'Imports a feed.',
44
    'arguments' => array(
45
      'importer' => 'The name of the Feeds importer that will be refreshed. Mandatory.',
46
    ),
47
    'options' => array(
48
      'nid' => '(optional) The nid of the Feeds importer that will be imported.',
49
      'file' => '(optional) The file to import. Bypasses the configured fetcher and does *not* update the source configuration.',
50
      'url' => '(optional) The URL to import. Bypasses the configured fetcher and does *not* update the source configuration.',
51
      'stdin' => '(optional) Read the file to import from stdin. Bypasses the configured fetcher and does *not* update the source configuration.',
52
    ),
53
    'examples' => array(
54
      'drush feeds-import my_importer' => "Import items with the importer 'my_importer'.",
55
      'drush feeds-import my_importer --nid=2' => "Import items with the importer 'my_importer' for feed node 2.",
56
    ),
57
    'aliases' => array('feeds-im'),
58
  );
59

    
60
  $items['feeds-import-all'] = array(
61
    'description' => 'Import all instances of feeds of the given type.',
62
    'arguments' => array(
63
      'importer' => 'The name of the Feeds importer that will be refreshed. Omitting the importer will cause all instances of all feeds to be imported.',
64
    ),
65
    'examples' => array(
66
      'drush feeds-import-all' => 'Import all instances of all feeds.',
67
      'drush feeds-import-all my_importer' => "Import all instances of the importer 'my_importer'.",
68
      'drush feeds-import-all my_importer --limit=10' => "Import 10 instances of the feed 'my_importer'.",
69
    ),
70
    'options' => array(
71
      'limit' => 'Limit the number of feeds to import. Optional.',
72
    ),
73
    'aliases' => array('feeds-ia', 'feeds-im-all'),
74
  );
75

    
76
  $items['feeds-clear'] = array(
77
    'description' => 'Delete all items from a feed.',
78
    'arguments' => array(
79
      'importer' => 'The name of the Feeds importer that will be cleared. Mandatory.',
80
    ),
81
    'options' => array(
82
      'nid' => 'The ID of the Feed node that will be cleared. Required if the importer is attached to a content type.',
83
    ),
84
    'examples' => array(
85
      'drush feeds-clear my_importer' => "Deletes all items imported with the importer 'my_importer'. The importer must use the standalone import form.",
86
      'drush feeds-clear my_importer --nid=2' => "Deletes all items imported with the importer 'my_importer' for the feed node with ID 2. The importer must be attached to a content type.",
87
    ),
88
  );
89

    
90
  $items['feeds-enable'] = array(
91
    'description' => 'Enables one or more Feeds importers.',
92
    'arguments' => array(
93
      'importers' => 'A space delimited list of Feeds importers. Mandatory.',
94
    ),
95
    'examples' => array(
96
      'drush feeds-enable importer_1 importer_2' => "Enable Feeds importers 'importer_1' and 'importer_2'.",
97
    ),
98
    'aliases' => array('feeds-en'),
99
  );
100

    
101
  $items['feeds-disable'] = array(
102
    'description' => 'Disable one or more Feeds importers.',
103
    'arguments' => array(
104
      'importers' => 'A space delimited list of Feeds importers. Mandatory.',
105
    ),
106
    'examples' => array(
107
      'drush feeds-disable importer_1 importer_2' => "Disable Feeds importers 'importer_1' and 'importer_2'.",
108
    ),
109
    'aliases' => array('feeds-dis'),
110
  );
111

    
112
  $items['feeds-delete'] = array(
113
    'description' => 'Deletes one or more Feeds importers.',
114
    'arguments' => array(
115
      'importers' => 'A space delimited list of Feeds importers. Mandatory.',
116
    ),
117
    'examples' => array(
118
      'drush feeds-delete importer_1 importer_2' => "Delete Feeds importers 'importer_1' and 'importer_2'.",
119
    ),
120
  );
121

    
122
  $items['feeds-revert'] = array(
123
    'description' => 'Reverts one or more Feeds importers.',
124
    'arguments' => array(
125
      'importers' => 'A space delimited list of Feeds importers. Mandatory.',
126
    ),
127
    'examples' => array(
128
      'drush feeds-revert importer_1 importer_2' => "Revert Feeds importers 'importer_1' and 'importer_2'.",
129
    ),
130
  );
131

    
132
  return $items;
133
}
134

    
135
/**
136
 * Implements hook_drush_help().
137
 */
138
function feeds_drush_help($section) {
139
  switch ($section) {
140
    case 'drush:feeds-list-importers':
141
      return dt('Show a list of available Feeds importers with information about them.');
142
    case 'drush:feeds-list-feeds':
143
      return dt("List all feed sources. You can limit the number of feed sources to display by setting the option '--limit'.");
144
    case 'drush:feeds-import':
145
      $help = dt("Import items from a feed. Follow the command with the importer name to import items with. If the importer is attached to a content type, specify also the feed node with the option '--nid'.");
146
      $help .= "\n" . dt("Note that the options '--file', '--stdin' and '--url' temporary bypass the configured fetcher and do *not* update the source configuration. For example, if a file was uploaded for the feed source, that file will remain there even when you specify a different file using the '--file' option. Same story applies for when importing from a url. If you omit these options, the last stored source will be used.");
147
      return $help;
148
    case 'drush:feeds-import-all':
149
      return dt('Import items from all feeds. Optionally specify the importer name to import all feeds for.');
150
    case 'drush:feeds-clear':
151
      return dt("Delete all items from a feed. Follow the command with the importer name to delete items from. If the importer is attached to a content type, specify also the feed node with the option '--nid'.");
152
    case 'drush:feeds-enable':
153
      return dt('Enable the specified Feeds importers. Follow the command with a space delimited list of importer names.');
154
    case 'drush:feeds-disable':
155
      return dt('Disable the specified Feeds importers. Follow the command with a space delimited list of importer names.');
156
    case 'drush:feeds-delete':
157
      return dt('Delete the specified Feeds importers. Follow the command with a space delimited list of importer names.');
158
    case 'drush:feeds-revert':
159
      return dt('Revert the specified Feeds importers. Follow the command with a space delimited list of importer names.');
160
  }
161
}
162

    
163
/**
164
 * Prints a list of all Feeds importers.
165
 */
166
function drush_feeds_list_importers() {
167
  if (!$importers = feeds_importer_load_all(TRUE)) {
168
    drush_print(dt('No importers available.'));
169
    return;
170
  }
171

    
172
  $rows = array();
173

    
174
  $rows[] = array(
175
    dt('Name'),
176
    dt('Description'),
177
    dt('Attached to'),
178
    dt('Status'),
179
    dt('State'),
180
  );
181

    
182
  foreach ($importers as $importer) {
183
    if ($importer->export_type == EXPORT_IN_CODE) {
184
      $state = dt('Default');
185
    }
186
    elseif ($importer->export_type == EXPORT_IN_DATABASE) {
187
      $state = dt('Normal');
188
    }
189
    elseif ($importer->export_type == (EXPORT_IN_CODE | EXPORT_IN_DATABASE)) {
190
      $state = dt('Overridden');
191
    }
192

    
193
    $rows[] = array(
194
      $importer->config['name'] . ' (' . $importer->id . ')',
195
      $importer->config['description'],
196
      $importer->config['content_type'] ? dt(node_type_get_name($importer->config['content_type'])) : dt('none'),
197
      $importer->disabled ? dt('Disabled') : dt('Enabled'),
198
      $state,
199
    );
200
  }
201

    
202
  drush_print_table($rows, TRUE);
203
}
204

    
205
/**
206
 * Lists all feeds.
207
 *
208
 * @param string $importer_id
209
 *   (optional) The importer id.
210
 */
211
function drush_feeds_list_feeds($importer_id = NULL) {
212
  if (!$limit = drush_get_option('limit')) {
213
    $limit = DRUSH_FEEDS_DEFAULT_LIMIT;
214
  }
215

    
216
  $header = array(
217
    'importer_id' => dt('Importer ID'),
218
    'feed_nid' => dt('Feed NID'),
219
    'feed_title' => dt('Feed title'),
220
    'imported' => dt('Last imported'),
221
    'source' => dt('Feed source'),
222
    'process_in_background' => dt('Process in background'),
223
  );
224

    
225
  $rows = array();
226
  $nids = array();
227

    
228
  foreach (_drush_feeds_get_all($importer_id, $limit) as $feed) {
229
    $feed_config = feeds_source($feed->id, $feed->feed_nid)->importer->getConfig();
230

    
231
    $rows[] = array(
232
      'importer_id' => $feed->id,
233
      'feed_nid' => $feed->feed_nid,
234
      'feed_title' => '',
235
      'imported' => $feed->imported ? date('Y-m-d H:i:s', $feed->imported) : dt('Never'),
236
      'source' => is_scalar($feed->source) ? $feed->source : gettype($feed->source),
237
      'process_in_background' => !empty($feed_config['process_in_background']) ? dt('Yes') : dt('No'),
238
    );
239

    
240
    // Collect node ID's to find titles for.
241
    if ($feed->feed_nid) {
242
      $nids[] = $feed->feed_nid;
243
    }
244
  }
245

    
246
  // Find titles for feed nodes.
247
  if (count($nids)) {
248
    $nodes = db_select('node')
249
      ->fields('node', array('nid', 'title'))
250
      ->condition('nid', $nids)
251
      ->execute()
252
      ->fetchAllKeyed();
253

    
254
    foreach ($rows as &$row) {
255
      $nid = $row['feed_nid'];
256
      if ($nid && isset($nodes[$nid])) {
257
        $row['feed_title'] = $nodes[$nid];
258
      }
259
    }
260
  }
261

    
262
  // Check if there were any results.
263
  if (count($rows) == 0) {
264
    if (empty($importer_id)) {
265
      drush_print(dt('There are no feed sources.'));
266
    }
267
    else {
268
      drush_print(dt("No feed sources exists for importer '@importer_id'.", array(
269
        '@importer_id' => $importer_id,
270
      )));
271
    }
272
    return FALSE;
273
  }
274

    
275
  // Create table.
276
  $table = array_merge(array($header), $rows);
277

    
278
  drush_print_table($table, TRUE);
279
}
280

    
281
/**
282
 * Imports a given importer/source.
283
 *
284
 * @param string $importer_id
285
 *   (optional) The importer id to filter on.
286
 */
287
function drush_feeds_import($importer_id = NULL) {
288
  if (!strlen($importer_id)) {
289
    drush_set_error(dt("Please specify the importer to import items with. If the importer is attached to a content type, specify also the feed node with the option '--nid'."));
290
    return FALSE;
291
  }
292

    
293
  if (!$feed_nid = drush_get_option('nid')) {
294
    $feed_nid = 0;
295
  }
296

    
297
  try {
298
    $source = feeds_source($importer_id, $feed_nid)->existing();
299
  }
300
  catch (FeedsNotExistingException $e) {
301
    $importer = feeds_importer_load($importer_id);
302
    if (!$importer) {
303
      drush_set_error(dt("The importer '@importer' does not exist or is not enabled.", array(
304
        '@importer' => $importer_id,
305
      )));
306
      return FALSE;
307
    }
308

    
309
    if ($feed_nid == 0) {
310
      // Check if the importer is a standalone importer.
311
      if ($importer->config['content_type']) {
312
        drush_set_error(dt("The importer '@importer' is attached to a content type. Please specify the feed node to import items for with the option '--nid'. To show a list of available feed nodes for this importer, use 'drush feeds-list-feeds @importer'.", array(
313
          '@importer' => $importer_id,
314
        )));
315
        return FALSE;
316
      }
317
      elseif (drush_get_option('file') || drush_get_option('url') || drush_get_option('stdin')) {
318
        // Create a new source.
319
        $source = feeds_source($importer_id);
320
        $source->save();
321
      }
322
    }
323
    elseif (!$importer->config['content_type']) {
324
      $message = dt("The importer '@importer' is not attached to a content type. Do you want to import items for this importer?", array(
325
        '@importer' => $importer_id,
326
      ));
327

    
328
      if (!drush_confirm($message)) {
329
        return drush_log(dt('Aborting.'), 'ok');
330
      }
331
      else {
332
        drush_set_option('nid', 0);
333
        // Avoid asking for confirmation twice.
334
        drush_set_option('feeds_import_skip_confirm', 1);
335
        return drush_feeds_import($importer_id);
336
      }
337
    }
338

    
339
    if (empty($source)) {
340
      // Only abort at this point when no source object exists. It can exist
341
      // when the importer is not attached to a content type and a file, url or
342
      // stdin is supplied.
343
      if ($feed_nid == 0) {
344
        drush_set_error(dt("No source exists yet for the importer '@importer'. There is nothing to import. You can import from a file or url using the options '--file' or '--url' or go to /import/@importer to configure the source to import. See 'drush help feeds-import' for more information.", array(
345
          '@importer' => $importer_id,
346
        )));
347
        return FALSE;
348
      }
349
      else {
350
        drush_set_error(dt("There is no feed node with ID @nid for importer '@importer'. To show a list of available feed nodes for this importer, use 'drush feeds-list-feeds @importer'.", array(
351
          '@importer' => $importer_id,
352
          '@nid' => $feed_nid,
353
        )));
354
        return FALSE;
355
      }
356
    }
357
  }
358

    
359
  // Propose confirmation message.
360
  $messages = array();
361
  $vars = array(
362
    '@importer' => $importer_id,
363
    '@feed_nid' => $feed_nid,
364
  );
365
  if ($feed_nid) {
366
    $messages[] = dt("Items will be imported with the importer '@importer' for the feed node @feed_nid.", $vars);
367
  }
368
  else {
369
    $messages[] = dt("Items will be imported with the importer '@importer'.", $vars);
370
  }
371

    
372
  $result = NULL;
373
  if ($filename = drush_get_option('file')) {
374
    $filepath = _drush_feeds_find_file($filename);
375
    if (!is_file($filepath)) {
376
      drush_set_error(dt("The file '@file' does not exist.", array('@file' => $filename)));
377
      return FALSE;
378
    }
379
    else {
380
      $filepath = realpath($filepath);
381
    }
382
    $result = new FeedsFileFetcherResult($filepath);
383

    
384
    $messages[] = dt("The items will be imported from the file '@file'.", array(
385
      '@file' => $filepath,
386
    ));
387
  }
388
  elseif ($url = drush_get_option('url')) {
389
    $result = new FeedsHTTPFetcherResult($url);
390

    
391
    $messages[] = dt("The items will be imported from the url '@url'.", array(
392
      '@url' => $url,
393
    ));
394
  }
395
  elseif (drush_get_option('stdin')) {
396
    $result = new FeedsFetcherResult(file_get_contents('php://stdin'));
397

    
398
    $messages[] = dt('The items will be imported from stdin.');
399
  }
400

    
401
  // Only ask for confirmation if it wasn't already asked before. See above.
402
  if (!drush_get_option('feeds_import_skip_confirm')) {
403
    $messages[] = dt('Do you really want to continue?');
404
    $message = implode(' ', $messages);
405
    if (!drush_confirm($message)) {
406
      return drush_log(dt('Aborting.'), 'ok');
407
    }
408
  }
409

    
410
  // Start the import!
411
  if ($result) {
412
    try {
413
      $source->pushImport($result);
414
    }
415
    catch (Exception $e) {
416
      drush_set_error($e->getMessage());
417
      return FALSE;
418
    }
419
  }
420
  else {
421
    _drush_feeds_create_import_batch($importer_id, $feed_nid);
422
    drush_backend_batch_process();
423
    return;
424
  }
425
}
426

    
427
/**
428
 * Imports all feeds.
429
 *
430
 * @param string $importer_id
431
 *   (optional) The importer id to filter on.
432
 */
433
function drush_feeds_import_all($importer_id = NULL) {
434
  if (!$limit = drush_get_option('limit')) {
435
    $limit = DRUSH_FEEDS_DEFAULT_LIMIT;
436
  }
437

    
438
  // Set flag for whether or not executing the batch. When all importers are not
439
  // not confirmed there are no batches set and in that case there are no
440
  // batches to process.
441
  $execute_batch = FALSE;
442

    
443
  foreach (_drush_feeds_get_all($importer_id, $limit) as $feed) {
444
    if (!isset($feed->source) || !strlen($feed->source)) {
445
      continue;
446
    }
447

    
448
    try {
449
      $source = feeds_source($feed->id, $feed->feed_nid)->existing();
450
    }
451
    catch (FeedsNotExistingException $e) {
452
      continue;
453
    }
454

    
455
    // Compose messages.
456
    $vars = array(
457
      '@importer_id' => $source->id,
458
      '@feed_nid' => $source->feed_nid,
459
    );
460
    if ($source->feed_nid) {
461
      $feed_node = node_load($source->feed_nid);
462
      if ($feed_node) {
463
        $vars['@title'] = $feed_node->title;
464
      }
465
      else {
466
        drush_set_error(dt('The feed node @feed_nid (@importer_id) does not exist.', $vars));
467
        continue;
468
      }
469
      $confirm_message = dt("Do you want to import items with the importer '@importer_id' for the feed '@title'?", $vars);
470
      $skip_message = dt("Skipping importer '@importer_id' for feed '@title'.", $vars);
471
    }
472
    else {
473
      $confirm_message = dt("Do you want to import items with the importer '@importer_id'?", $vars);
474
      $skip_message = dt("Skipping importer '@importer_id'.", $vars);
475
    }
476

    
477
    if (drush_confirm($confirm_message)) {
478
      _drush_feeds_create_import_batch($feed->id, $feed->feed_nid);
479
      $execute_batch = TRUE;
480
    }
481
    else {
482
      drush_log($skip_message, 'ok');
483
    }
484
  }
485

    
486
  if ($execute_batch) {
487
    drush_backend_batch_process();
488
  }
489
}
490

    
491
/**
492
 * Creates a batch job for an import.
493
 *
494
 * @param string $importer_id
495
 *   The importer id.
496
 * @param int $feed_nid
497
 *   The feed node id.
498
 */
499
function _drush_feeds_create_import_batch($importer_id, $feed_nid) {
500
  $feed_node = FALSE;
501
  if ($feed_nid) {
502
    if (!$feed_node = node_load($feed_nid)) {
503
      drush_set_error(dt('The feed node @feed_nid (@importer_id) does not exist.', array('@importer_id' => $importer_id, '@feed_nid' => $feed_nid)));
504
      return FALSE;
505
    }
506
  }
507

    
508
  $title = $feed_node ? $feed_node->title . ' (' . $importer_id . ')' : $importer_id;
509

    
510
  drush_log(dt('Importing: @title', array('@title' => $title)), 'ok');
511

    
512
  $batch = array(
513
    'title' => '',
514
    'operations' => array(
515
      array('feeds_batch', array('import', $importer_id, $feed_nid)),
516
    ),
517
    'progress_message' => '',
518
  );
519

    
520
  batch_set($batch);
521
}
522

    
523
/**
524
 * Clears a Feeds importer.
525
 *
526
 * @param string $importer_id
527
 *   The importer id to clean.
528
 */
529
function drush_feeds_clear($importer_id = NULL) {
530
  if (!strlen($importer_id)) {
531
    drush_set_error(dt("Please specify the importer to delete all imported items from. If the importer is attached to a content type, specify also the feed node with the option '--nid'."));
532
    return FALSE;
533
  }
534

    
535
  if (!$feed_nid = drush_get_option('nid')) {
536
    $feed_nid = 0;
537
  }
538

    
539
  try {
540
    feeds_source($importer_id, $feed_nid)->existing();
541
  }
542
  catch (FeedsNotExistingException $e) {
543
    $importer = feeds_importer_load($importer_id);
544
    if (!$importer) {
545
      drush_set_error(dt("The importer '@importer' does not exist or is not enabled.", array(
546
        '@importer' => $importer_id,
547
      )));
548
      return FALSE;
549
    }
550

    
551
    if ($feed_nid == 0) {
552
      // Check if the importer is a standalone importer.
553
      if ($importer->config['content_type']) {
554
        drush_set_error(dt("The importer '@importer' is attached to a content type. Please specify the feed node to delete items from with the option '--nid'. To show a list of available feed nodes for this importer, use 'drush feeds-list-feeds @importer'.", array(
555
          '@importer' => $importer_id,
556
        )));
557
        return FALSE;
558
      }
559
    }
560
    elseif (!$importer->config['content_type']) {
561
      $message = dt("The importer '@importer' is not attached to a content type. Do you want to clear all items for this importer?", array(
562
        '@importer' => $importer_id,
563
      ));
564

    
565
      if (!drush_confirm($message)) {
566
        return drush_log(dt('Aborting.'), 'ok');
567
      }
568
      else {
569
        drush_set_option('nid', 0);
570
        // Avoid asking for confirmation twice.
571
        drush_set_option('feeds_clear_skip_confirm', 1);
572
        return drush_feeds_clear($importer_id);
573
      }
574
    }
575

    
576
    drush_set_error(dt("There is no feed node with ID @nid for importer '@importer'. To show a list of available feed nodes for this importer, use 'drush feeds-list-feeds @importer'.", array(
577
      '@importer' => $importer_id,
578
      '@nid' => $feed_nid,
579
    )));
580
    return FALSE;
581
  }
582

    
583
  // Only ask for confirmation if it wasn't already asked before. See above.
584
  if (!drush_get_option('feeds_clear_skip_confirm')) {
585
    if ($feed_nid) {
586
      $message = dt("All items imported with the importer '@importer' for the feed node @feed_nid will be deleted. Do you really want to continue?", array(
587
        '@importer' => $importer_id,
588
        '@feed_nid' => $feed_nid,
589
      ));
590
    }
591
    else {
592
      $message = dt("All items imported with the importer '@importer' will be deleted. Do you really want to continue?", array(
593
        '@importer' => $importer_id,
594
      ));
595
    }
596
    if (!drush_confirm($message)) {
597
      return drush_log(dt('Aborting.'), 'ok');
598
    }
599
  }
600

    
601
  $batch = array(
602
    'title' => dt('Clearing !importer', array('!importer' => $importer_id)),
603
    'operations' => array(
604
      array('feeds_batch', array('clear', $importer_id, $feed_nid)),
605
    ),
606
  );
607

    
608
  batch_set($batch);
609
  drush_backend_batch_process();
610
}
611

    
612
/**
613
 * Enables a set of Feeds importers.
614
 */
615
function drush_feeds_enable() {
616
  $all = array_keys(feeds_importer_load_all(TRUE));
617
  $enabled = array_keys(feeds_importer_load_all());
618
  $missing = array_diff(func_get_args(), $all);
619
  $to_enable = array_diff(func_get_args(), $enabled, $missing);
620
  $already_enabled = array_intersect(func_get_args(), $enabled);
621

    
622
  if ($missing) {
623
    drush_print(dt('The following importers are missing: !importers', array('!importers' => implode(', ', $missing))));
624
  }
625

    
626
  if ($already_enabled) {
627
    drush_print(dt('The following importers are already enabled: !importers', array('!importers' => implode(', ', $already_enabled))));
628
  }
629

    
630
  if ($to_enable) {
631
    drush_print(dt('The following importers will be enabled: !importers', array('!importers' => implode(', ', $to_enable))));
632
  }
633
  elseif (count(func_get_args()) == 0) {
634
    return drush_set_error(dt('Please specify a space delimited list of importers to enable.'));
635
  }
636
  else {
637
    return drush_print(dt('There are no importers to enable.'));
638
  }
639

    
640
  if (!drush_confirm(dt('Do you really want to continue?'))) {
641
    return drush_log(dt('Aborting.'), 'ok');
642
  }
643

    
644
  $disabled = variable_get('default_feeds_importer', array());
645

    
646
  foreach ($to_enable as $importer_id) {
647
    unset($disabled[$importer_id]);
648
    drush_log(dt("The importer '!importer' has been enabled.", array('!importer' => $importer_id)), 'ok');
649
  }
650

    
651
  variable_set('default_feeds_importer', $disabled);
652
  feeds_cache_clear();
653
}
654

    
655
/**
656
 * Disables a set of Feeds importers.
657
 */
658
function drush_feeds_disable() {
659
  $all = array_keys(feeds_importer_load_all(TRUE));
660
  $enabled = array_keys(feeds_importer_load_all());
661
  $to_disable = array_intersect(func_get_args(), $enabled);
662
  $missing = array_diff(func_get_args(), $all);
663
  $already_disabled = array_diff(func_get_args(), $enabled, $missing);
664

    
665
  if ($missing) {
666
    drush_print(dt('The following importers are missing: !importers', array('!importers' => implode(', ', $missing))));
667
  }
668

    
669
  if ($already_disabled) {
670
    drush_print(dt('The following importers are already disabled: !importers', array('!importers' => implode(', ', $already_disabled))));
671
  }
672

    
673
  if ($to_disable) {
674
    drush_print(dt('The following importers will be disabled: !importers', array('!importers' => implode(', ', $to_disable))));
675
  }
676
  elseif (count(func_get_args()) == 0) {
677
    return drush_set_error(dt('Please specify a space delimited list of importers to disable.'));
678
  }
679
  else {
680
    return drush_print(dt('There are no importers to disable.'));
681
  }
682

    
683
  if (!drush_confirm(dt('Do you really want to continue?'))) {
684
    return drush_log(dt('Aborting.'), 'ok');
685
  }
686

    
687
  $disabled = variable_get('default_feeds_importer', array());
688
  foreach ($to_disable as $importer_id) {
689
    $disabled[$importer_id] = TRUE;
690
    drush_log(dt("The importer '!importer' has been disabled.", array('!importer' => $importer_id)), 'ok');
691
  }
692

    
693
  variable_set('default_feeds_importer', $disabled);
694
  feeds_cache_clear();
695
}
696

    
697
/**
698
 * Deletes a set of Feeds importers.
699
 */
700
function drush_feeds_delete() {
701
  $all = feeds_importer_load_all(TRUE);
702
  $to_delete = array_intersect_key($all, array_flip(func_get_args()));
703
  $missing = array_diff(func_get_args(), array_keys($all));
704
  $cant_delete = array();
705

    
706
  // Filter out default importers that are not overridden.
707
  foreach ($to_delete as $delta => $importer) {
708
    if ($importer->export_type === EXPORT_IN_CODE) {
709
      unset($to_delete[$delta]);
710
      $cant_delete[$importer->id] = $importer->id;
711
    }
712
  }
713

    
714
  if ($missing) {
715
    drush_print(dt('The following importers are missing: !importers', array('!importers' => implode(', ', $missing))));
716
  }
717

    
718
  if ($cant_delete) {
719
    drush_print(dt('The following importers cannot be deleted because they only exist in code: !importers', array('!importers' => implode(', ', array_keys($cant_delete)))));
720
  }
721

    
722
  if ($to_delete) {
723
    drush_print(dt('The following importers will be deleted: !importers', array('!importers' => implode(', ', array_keys($to_delete)))));
724
  }
725
  elseif (count(func_get_args()) == 0) {
726
    return drush_set_error(dt('Please specify a space delimited list of importers to delete.'));
727
  }
728
  else {
729
    return drush_print(dt('There are no importers to delete.'));
730
  }
731

    
732
  if (!drush_confirm(dt('Do you really want to continue?'))) {
733
    return drush_log(dt('Aborting.'), 'ok');
734
  }
735

    
736
  foreach ($to_delete as $importer) {
737
    $importer->delete();
738
    drush_log(dt("The importer '!importer' was deleted successfully.", array('!importer' => $importer->id)), 'ok');
739
  }
740

    
741
  feeds_cache_clear();
742
}
743

    
744
/**
745
 * Reverts a set of feeds.
746
 */
747
function drush_feeds_revert() {
748
  $all = feeds_importer_load_all(TRUE);
749
  $missing = array_diff(func_get_args(), array_keys($all));
750
  $to_revert = array_intersect_key($all, array_flip(func_get_args()));
751
  $cant_revert = array();
752
  $cant_revert_db = array();
753

    
754
  // Filter out non-overridden importers.
755
  foreach ($to_revert as $delta => $importer) {
756
    if ($importer->export_type !== (EXPORT_IN_CODE | EXPORT_IN_DATABASE)) {
757
      unset($to_revert[$delta]);
758
      if ($importer->export_type == EXPORT_IN_DATABASE) {
759
        $cant_revert_db[$importer->id] = $importer->id;
760
      }
761
      else {
762
        $cant_revert[$importer->id] = $importer->id;
763
      }
764
    }
765
  }
766

    
767
  if ($missing) {
768
    drush_print(dt('The following importers are missing: !importers', array('!importers' => implode(', ', $missing))));
769
  }
770

    
771
  if ($cant_revert) {
772
    drush_print(dt('The following importers cannot be reverted because they are not overridden: !importers', array('!importers' => implode(', ', array_keys($cant_revert)))));
773
  }
774
  if ($cant_revert_db) {
775
    drush_print(dt('The following importers cannot be reverted because they only exist in the database: !importers', array('!importers' => implode(', ', array_keys($cant_revert_db)))));
776
  }
777

    
778
  if ($to_revert) {
779
    drush_print(dt('The following importers will be reverted: !importers', array('!importers' => implode(', ', array_keys($to_revert)))));
780
  }
781
  elseif (count(func_get_args()) == 0) {
782
    return drush_set_error(dt('Please specify a space delimited list of importers to revert.'));
783
  }
784
  else {
785
    return drush_print(dt('There are no importers to revert.'));
786
  }
787

    
788
  if (!drush_confirm(dt('Do you really want to continue?'))) {
789
    return drush_log(dt('Aborting.'), 'ok');
790
  }
791

    
792
  foreach ($to_revert as $importer) {
793
    $importer->delete();
794
    drush_log(dt("The importer '!importer' was reverted successfully.", array('!importer' => $importer->id)), 'ok');
795
  }
796

    
797
  feeds_cache_clear();
798
}
799

    
800
/**
801
 * Returns all feed instances filtered by an optional importer.
802
 *
803
 * @param string $importer_id
804
 *   (optional) The importer id.
805
 * @param int $limit
806
 *   (optional) The number of feeds to return.
807
 *
808
 * @return DatabaseStatementInterface
809
 *   A list of feeds objects.
810
 */
811
function _drush_feeds_get_all($importer_id = NULL, $limit = DRUSH_FEEDS_DEFAULT_LIMIT) {
812
  if (isset($importer_id)) {
813
    return db_query_range("SELECT * FROM {feeds_source} WHERE id = :importer ORDER BY imported ASC", 0, $limit, array(':importer' => $importer_id));
814
  }
815

    
816
  return db_query_range("SELECT * FROM {feeds_source} ORDER BY imported ASC", 0, $limit);
817
}
818

    
819
/**
820
 * Tries to find the specified file at several locations.
821
 *
822
 * @param string $filename
823
 *   The file to look for.
824
 *
825
 * @return string
826
 *   If found, the file that was found.
827
 *   NULL otherwise.
828
 */
829
function _drush_feeds_find_file($filename) {
830
  // If the full path to the file is specified, the file will be found right away.
831
  if (is_file($filename)) {
832
    // Found!
833
    return $filename;
834
  }
835

    
836
  // Look for the file within the current active directory.
837
  $search = drush_cwd() . '/' . $filename;
838
  if (is_file($search)) {
839
    // Found!
840
    return $search;
841
  }
842

    
843
  // Look for the file within the directory Drupal is installed in.
844
  // bootstrap_drupal_root() sets the active directory to the Drupal root.
845
  $search = getcwd() . '/' . $filename;
846
  if (is_file($search)) {
847
    // Found!
848
    return $search;
849
  }
850
}