Newer
Older
Alex Barth
committed
Alex Barth
committed
* Contains all page callbacks, forms and theming functions for Feeds
* administrative pages.
twistor
committed
* Introductory help for admin/structure/feeds/%feeds_importer page
Alex Barth
committed
function feeds_ui_edit_help() {
return t('
<p>
You can create as many Feeds importer configurations as you would like to. Each can have a distinct purpose like letting your users aggregate RSS feeds or importing a CSV file for content migration. Here are a couple of things that are important to understand in order to get started with Feeds:
</p>
<ul>
<li>
Every importer configuration consists of basic settings, a fetcher, a parser and a processor and their settings.
</li>
<li>
The <strong>basic settings</strong> define the general behavior of the importer. <strong>Fetchers</strong> are responsible for loading data, <strong>parsers</strong> for organizing it and <strong>processors</strong> for "doing stuff" with it, usually storing it.
</li>
<li>
In Basic settings, you can <strong>attach an importer configuration to a content type</strong>. This is useful when many imports of a kind should be created, for example in an RSS aggregation scenario. If you don\'t attach a configuration to a content type, you can use it on the !import page.
</li>
<li>
Imports can be <strong>scheduled periodically</strong> - see the periodic import select box in the Basic settings.
Alex Barth
committed
</li>
<li>
Processors can have <strong>mappings</strong> in addition to settings. Mappings allow you to define what elements of a data feed should be mapped to what content fields on a granular level. For instance, you can specify that a feed item\'s author should be mapped to a node\'s body.
Alex Barth
committed
</li>
</ul>
', array('!import' => l(t('Import'), 'import')));
}
/**
* Help text for mapping.
*/
function feeds_ui_mapping_help() {
return t('
<p>
Define which elements of a single item of a feed (= <em>Sources</em>) map to which content pieces in Drupal (= <em>Targets</em>). Make sure that at least one definition has a <em>Unique target</em>. A unique target means that a value for a target can only occur once. E. g. only one item with the URL <em>http://example.com/content/1</em> can exist.
Alex Barth
committed
</p>
');
/**
* Build overview of available configurations.
*/
function feeds_ui_overview_form($form, &$form_status) {
$form = $form['enabled'] = $form['disabled'] = array();
$form['#header'] = array(
t('Name'),
t('Description'),
t('Attached to'),
t('Status'),
t('Operations'),
t('Enabled'),
);
foreach (feeds_importer_load_all(TRUE) as $importer) {
$importer_form['name']['#markup'] = check_plain($importer->config['name']);
$importer_form['description']['#markup'] = check_plain($importer->config['description']);
Alex Barth
committed
if (empty($importer->config['content_type'])) {
Alex Barth
committed
else {
$importer_form['attached']['#markup'] = l(node_type_get_name($importer->config['content_type']), 'node/add/' . str_replace('_', '-', $importer->config['content_type']));
$importer_form['attached']['#markup'] = check_plain(node_type_get_name($importer->config['content_type']));
Alex Barth
committed
}
Alex Barth
committed
if ($importer->export_type == EXPORT_IN_CODE) {
$status = t('Default');
$edit = t('Override');
$delete = '';
}
elseif ($importer->export_type == EXPORT_IN_DATABASE) {
Alex Barth
committed
$status = t('Normal');
$edit = t('Edit');
$delete = t('Delete');
}
elseif ($importer->export_type == (EXPORT_IN_CODE | EXPORT_IN_DATABASE)) {
Alex Barth
committed
$status = t('Overridden');
$edit = t('Edit');
$delete = t('Revert');
}
Alex Barth
committed
);
if (!$importer->disabled) {
$importer_form['operations'] = array(
twistor
committed
l($edit, 'admin/structure/feeds/' . $importer->id) . ' | ' .
l(t('Export'), 'admin/structure/feeds/' . $importer->id . '/export') . ' | ' .
l(t('Clone'), 'admin/structure/feeds/' . $importer->id . '/clone') .
(empty($delete) ? '' : ' | ' . l($delete, 'admin/structure/feeds/' . $importer->id . '/delete')),
}
$importer_form[$importer->id] = array(
'#type' => 'checkbox',
'#default_value' => !$importer->disabled,
'#attributes' => array('class' => array('feeds-ui-trigger-submit')),
);
if ($importer->disabled) {
$form['disabled'][$importer->id] = $importer_form;
}
else {
$form['enabled'][$importer->id] = $importer_form;
}
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
'#attributes' => array('class' => array('feeds-ui-hidden-submit')),
return $form;
}
/**
* Submit handler for feeds_ui_overview_form().
*/
function feeds_ui_overview_form_submit($form, &$form_state) {
$disabled = array();
foreach (feeds_importer_load_all(TRUE) as $importer) {
$disabled[$importer->id] = !$form_state['values'][$importer->id];
}
variable_set('default_feeds_importer', $disabled);
feeds_cache_clear();
}
/**
* Create a new configuration.
Alex Barth
committed
*
* @param $form_state
* Form API form state array.
* @param $from_importer
* FeedsImporter object. If given, form will create a new importer as a copy
* of $from_importer.
function feeds_ui_create_form($form, &$form_state, $from_importer = NULL) {
$form['#attached']['js'][] = drupal_get_path('module', 'feeds_ui') . '/feeds_ui.js';
Alex Barth
committed
$form['#from_importer'] = $from_importer;
$form['name'] = array(
'#type' => 'textfield',
'#title' => t('Name'),
'#description' => t('A natural name for this configuration. Example: RSS Feed. You can always change this name later.'),
'#required' => TRUE,
Alex Barth
committed
'#maxlength' => 128,
'#type' => 'machine_name',
Alex Barth
committed
'#maxlength' => 128,
'#machine_name' => array(
'exists' => 'feeds_ui_importer_machine_name_exists',
),
Alex Barth
committed
$form['description'] = array(
'#type' => 'textfield',
'#title' => t('Description'),
'#description' => t('A description of this configuration.'),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Create'),
);
return $form;
}
/**
* Validation callback for the importer machine name field.
*/
function feeds_ui_importer_machine_name_exists($id) {
if ($id == 'create') {
// Create is a reserved path for the add importer form.
return TRUE;
}
ctools_include('export');
if (ctools_export_load_object('feeds_importer', 'conditions', array('id' => $id))) {
return TRUE;
}
}
Alex Barth
committed
/**
* Validation handler for feeds_build_create_form().
*/
Alex Barth
committed
function feeds_ui_create_form_validate($form, &$form_state) {
Dave Reid
committed
if (!empty($form_state['values']['id'])) {
$importer = feeds_importer($form_state['values']['id']);
$importer->configFormValidate($form_state['values']);
}
Alex Barth
committed
}
/**
* Submit handler for feeds_build_create_form().
*/
Alex Barth
committed
function feeds_ui_create_form_submit($form, &$form_state) {
// Create feed.
$importer = feeds_importer($form_state['values']['id']);
// If from_importer is given, copy its configuration.
if (!empty($form['#from_importer'])) {
$importer->copy($form['#from_importer']);
}
// In any case, we want to set this configuration's title and description.
$importer->addConfig($form_state['values']);
$importer->save();
// Set a message and redirect to settings form.
if (empty($form['#from_importer'])) {
drupal_set_message(t('Your configuration has been created with default settings. If they do not fit your use case you can adjust them here.'));
}
else {
drupal_set_message(t('A clone of the @name configuration has been created.', array('@name' => $form['#from_importer']->config['name'])));
Alex Barth
committed
}
twistor
committed
$form_state['redirect'] = 'admin/structure/feeds/' . $importer->id;
feeds_cache_clear();
Alex Barth
committed
* Delete configuration form.
function feeds_ui_delete_form($form, &$form_state, $importer) {
$form['#importer'] = $importer->id;
if ($importer->export_type & EXPORT_IN_CODE) {
$title = t('Would you really like to revert the importer @importer?', array('@importer' => $importer->config['name']));
$button_label = t('Revert');
}
else {
$title = t('Would you really like to delete the importer @importer?', array('@importer' => $importer->config['name']));
$button_label = t('Delete');
}
return confirm_form(
$form,
$title,
'admin/structure/feeds',
t('This action cannot be undone.'),
$button_label
);
Alex Barth
committed
/**
Alex Barth
committed
* Submit handler for feeds_ui_delete_form().
Alex Barth
committed
*/
Alex Barth
committed
function feeds_ui_delete_form_submit($form, &$form_state) {
$form_state['redirect'] = 'admin/structure/feeds';
Alex Barth
committed
// Remove importer.
feeds_importer($form['#importer'])->delete();
Alex Barth
committed
// Clear cache, deleting a configuration may have an affect on menu tree.
feeds_cache_clear();
Alex Barth
committed
}
Alex Barth
committed
* Export a feed configuration.
function feeds_ui_export_form($form, &$form_state, $importer) {
Alex Barth
committed
$code = feeds_export($importer->id);
$form['export'] = array(
'#title' => t('Export feed configuration'),
'#type' => 'textarea',
'#value' => $code,
'#rows' => substr_count($code, "\n"),
);
return $form;
Alex Barth
committed
/**
* Edit feed configuration.
*/
function feeds_ui_edit_page($importer, $active = 'help', $plugin_key = '') {
// Get plugins and configuration.
Alex Barth
committed
$plugins = FeedsPlugin::all();
Alex Barth
committed
$config = $importer->config;
// Base path for changing the active container.
twistor
committed
$path = 'admin/structure/feeds/' . $importer->id;
Alex Barth
committed
$active_container = array(
'class' => array('active-container'),
Alex Barth
committed
'actions' => array(l(t('Help'), $path)),
);
switch ($active) {
case 'help':
$active_container['title'] = t('Getting started');
$active_container['body'] = '<div class="help feeds-admin-ui">' . feeds_ui_edit_help() . '</div>';
Alex Barth
committed
unset($active_container['actions']);
break;
case 'fetcher':
case 'parser':
case 'processor':
$active_container['title'] = t('Select a !plugin_type', array('!plugin_type' => $active));
$active_container['body'] = drupal_get_form('feeds_ui_plugin_form', $importer, $active);
break;
case 'settings':
drupal_add_js(drupal_get_path('module', 'ctools') . '/js/dependent.js');
Alex Barth
committed
if (empty($plugin_key)) {
$active_container['title'] = t('Basic settings');
$active_container['body'] = feeds_get_form($importer, 'configForm');
Alex Barth
committed
}
Alex Barth
committed
// feeds_plugin() returns a correct result because feed has been
Alex Barth
committed
// instantiated previously.
Alex Barth
committed
elseif (in_array($plugin_key, array_keys($plugins)) && $plugin = feeds_plugin($plugin_key, $importer->id)) {
Alex Barth
committed
$active_container['title'] = t('Settings for !plugin', array('!plugin' => $plugins[$plugin_key]['name']));
$active_container['body'] = feeds_get_form($plugin, 'configForm');
Alex Barth
committed
}
break;
case 'mapping':
$active_container['title'] = t('Mapping for !processor', array('!processor' => $plugins[$config['processor']['plugin_key']]['name']));
$active_container['body'] = drupal_get_form('feeds_ui_mapping_form', $importer);
break;
}
// Build config info.
$config_info = $info = array();
$info['class'] = array('config-set');
Alex Barth
committed
// Basic information.
$items = array();
$items[] = t('Attached to: @type', array('@type' => $importer->config['content_type'] ? node_type_get_name($importer->config['content_type']) : t('[none]')));
Alex Barth
committed
if ($importer->config['import_period'] == FEEDS_SCHEDULE_NEVER) {
Alex Barth
committed
}
elseif ($importer->config['import_period'] == 0) {
$import_period = t('as often as possible');
}
else {
$import_period = t('every !interval', array('!interval' => format_interval($importer->config['import_period'])));
}
$items[] = t('Periodic import: !import_period', array('!import_period' => $import_period));
$items[] = $importer->config['import_on_create'] ? t('Import on submission') : t('Do not import on submission');
Alex Barth
committed
$info['title'] = t('Basic settings');
$info['body'] = array(
array(
'body' => theme('item_list', array('items' => $items)),
'actions' => array(l(t('Settings'), $path . '/settings')),
Alex Barth
committed
),
);
$config_info[] = $info;
// Fetcher.
$fetcher = $plugins[$config['fetcher']['plugin_key']];
$actions = array();
if (feeds_get_form($importer->fetcher, 'configForm')) {
$actions = array(l(t('Settings'), $path . '/settings/' . $config['fetcher']['plugin_key']));
Alex Barth
committed
}
$info['title'] = t('Fetcher');
$info['body'] = array(
array(
'title' => $fetcher['name'],
'body' => $fetcher['description'],
'actions' => $actions,
),
);
$info['actions'] = array(l(t('Change'), $path . '/fetcher'));
Alex Barth
committed
$config_info[] = $info;
// Parser.
$parser = $plugins[$config['parser']['plugin_key']];
$actions = array();
if (feeds_get_form($importer->parser, 'configForm')) {
$actions = array(l(t('Settings'), $path . '/settings/' . $config['parser']['plugin_key']));
Alex Barth
committed
}
$info['title'] = t('Parser');
$info['body'] = array(
array(
'title' => $parser['name'],
'body' => $parser['description'],
'actions' => $actions,
)
);
$info['actions'] = array(l(t('Change'), $path . '/parser'));
Alex Barth
committed
$config_info[] = $info;
// Processor.
$processor = $plugins[$config['processor']['plugin_key']];
$actions = array();
if (feeds_get_form($importer->processor, 'configForm')) {
$actions[] = l(t('Settings'), $path . '/settings/' . $config['processor']['plugin_key']);
Alex Barth
committed
}
$actions[] = l(t('Mapping'), $path . '/mapping');
Alex Barth
committed
$info['title'] = t('Processor');
$info['body'] = array(
array(
'title' => $processor['name'],
'body' => $processor['description'],
'actions' => $actions,
)
);
$info['actions'] = array(l(t('Change'), $path . '/processor'));
Alex Barth
committed
$config_info[] = $info;
return theme('feeds_ui_edit_page', array(
'info' => $config_info,
'active' => $active_container,
));
Alex Barth
committed
}
Alex Barth
committed
* Build a form of plugins to pick from.
*
* @param $form_state
* Form API form state array.
* @param $importer
* FeedsImporter object.
* @param $type
* Plugin type. One of 'fetcher', 'parser', 'processor'.
*
* @return
* A Form API form definition.
function feeds_ui_plugin_form($form, &$form_state, $importer, $type) {
Alex Barth
committed
$plugins = FeedsPlugin::byType($type);
Alex Barth
committed
$form['#importer'] = $importer->id;
Alex Barth
committed
$form['#plugin_type'] = $type;
$importer_key = $importer->config[$type]['plugin_key'];
Alex Barth
committed
foreach ($plugins as $key => $plugin) {
Alex Barth
committed
$form['plugin_key'][$key] = array(
'#type' => 'radio',
'#parents' => array('plugin_key'),
'#title' => check_plain($plugin['name']),
'#description' => filter_xss(isset($plugin['help']) ? $plugin['help'] : $plugin['description']),
Alex Barth
committed
'#return_value' => $key,
'#default_value' => ($key == $importer_key) ? $key : '',
Alex Barth
committed
);
}
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
'#attributes' => array('class' => array('feeds-ui-hidden-submit')),
Alex Barth
committed
* Submit handler for feeds_ui_plugin_form().
Alex Barth
committed
function feeds_ui_plugin_form_submit($form, &$form_state) {
// Set the plugin and save feed.
$importer = feeds_importer($form['#importer']);
$importer->setPlugin($form_state['values']['plugin_key']);
$importer->save();
drupal_set_message(t('Changed @type plugin.', array('@type' => $form['#plugin_type'])));
Alex Barth
committed
* Theme feeds_ui_plugin_form().
function theme_feeds_ui_plugin_form($variables) {
$form = $variables['form'];
drupal_add_js(drupal_get_path('module', 'feeds_ui') . '/feeds_ui.js');
Alex Barth
committed
$output = '';
foreach (element_children($form['plugin_key']) as $key) {
// Assemble container, render form elements.
$container = array(
'title' => $form['plugin_key'][$key]['#title'],
'body' => isset($form['plugin_key'][$key]['#description']) ? $form['plugin_key'][$key]['#description'] : '',
Alex Barth
committed
);
$form['plugin_key'][$key]['#title'] = t('Select');
$form['plugin_key'][$key]['#attributes']['class'] = array('feeds-ui-radio-link');
Alex Barth
committed
unset($form['plugin_key'][$key]['#description']);
$container['actions'] = array(drupal_render($form['plugin_key'][$key]));
$output .= theme('feeds_ui_container', array('container' => $container));
Alex Barth
committed
}
$output .= drupal_render_children($form);
Alex Barth
committed
return $output;
* Edit mapping.
Alex Barth
committed
*
* @todo Completely merge this into config form handling. This is just a
Alex Barth
committed
* shared form of configuration, most of the common functionality can live in
* FeedsProcessor, a flag can tell whether mapping is supported or not.
function feeds_ui_mapping_form($form, &$form_state, $importer) {
drupal_add_js(drupal_get_path('module', 'feeds_ui') . '/feeds_ui.js');
Alex Barth
committed
$form['#importer'] = $importer->id;
$form['#mappings'] = $mappings = $importer->processor->getMappings();
$form['help']['#markup'] = feeds_ui_mapping_help();
niklas
committed
$form['#prefix'] = '<div id="feeds-ui-mapping-form-wrapper">';
$form['#suffix'] = '</div>';
Alex Barth
committed
// Get mapping sources from parsers and targets from processor, format them
// for output.
// Some parsers do not define mapping sources but let them define on the fly.
if ($sources = $importer->parser->getMappingSources()) {
$source_options = _feeds_ui_format_options($sources);
foreach ($sources as $k => $source) {
$legend['sources'][$k]['name']['#markup'] = empty($source['name']) ? $k : $source['name'];
$legend['sources'][$k]['description']['#markup'] = empty($source['description']) ? '' : $source['description'];
Alex Barth
committed
}
$legend['sources']['#markup'] = t('This parser supports free source definitions. Enter the name of the source field in lower case into the Source text field above.');
Alex Barth
committed
$targets = $importer->processor->getMappingTargets();
$target_options = _feeds_ui_format_options($targets);
$legend['targets'] = array();
foreach ($targets as $k => $target) {
$legend['targets'][$k]['name']['#markup'] = empty($target['name']) ? $k : $target['name'];
$legend['targets'][$k]['description']['#markup'] = empty($target['description']) ? '' : $target['description'];
// Legend explaining source and target elements.
$form['legendset'] = array(
'#type' => 'fieldset',
'#title' => t('Legend'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#tree' => TRUE,
);
$form['legendset']['legend'] = $legend;
Alex Barth
committed
niklas
committed
// Add config forms and remove flags to mappings.
$form['config'] = $form['remove_flags'] = $form['mapping_weight'] = array(
Alex Barth
committed
'#tree' => TRUE,
);
if (is_array($mappings)) {
Alex Barth
committed
foreach ($mappings as $i => $mapping) {
niklas
committed
if (isset($targets[$mapping['target']])) {
$form['config'][$i] = feeds_ui_mapping_settings_form($form, $form_state, $i, $mapping, $targets[$mapping['target']]);
Alex Barth
committed
}
niklas
committed
Alex Barth
committed
$form['remove_flags'][$i] = array(
'#type' => 'checkbox',
'#title' => t('Remove'),
'#prefix' => '<div class="feeds-ui-checkbox-link">',
'#suffix' => '</div>',
);
$form['mapping_weight'][$i] = array(
'#type' => 'weight',
'#title' => '',
'#default_value' => $i,
'#attributes' => array(
'class' => array(
'feeds-ui-mapping-weight'
),
),
);
Alex Barth
committed
}
}
Alex Barth
committed
$form['source'] = array(
Alex Barth
committed
'#options' => array('' => t('Select a source')) + $source_options,
Alex Barth
committed
}
else {
$form['source'] = array(
'#type' => 'textfield',
'#size' => 20,
'#default_value' => t('Name of source field'),
'#attributes' => array('class' => array('hide-text-on-focus')),
Alex Barth
committed
$form['target'] = array(
'#type' => 'select',
'#options' => array('' => t('Select a target')) + $target_options,
Alex Barth
committed
);
$form['add'] = array(
'#type' => 'submit',
'#value' => t('Add'),
'#submit' => array('feeds_ui_mapping_form_add_submit'),
niklas
committed
'#validate' => array('feeds_ui_mapping_form_add_validate'),
Alex Barth
committed
);
$form['save'] = array(
'#type' => 'submit',
'#value' => t('Save'),
'#attributes' => array('class' => array('feeds-ui-hidden-submit')),
Alex Barth
committed
);
return $form;
}
niklas
committed
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
/**
* Per mapper configuration form that is a part of feeds_ui_mapping_form().
*/
function feeds_ui_mapping_settings_form($form, $form_state, $i, $mapping, $target) {
$form_state += array(
'mapping_settings_edit' => NULL,
'mapping_settings' => array(),
);
$base_button = array(
'#submit' => array('feeds_ui_mapping_form_multistep_submit'),
'#ajax' => array(
'callback' => 'feeds_ui_mapping_settings_form_callback',
'wrapper' => 'feeds-ui-mapping-form-wrapper',
'effect' => 'fade',
'progress' => 'none',
),
'#i' => $i,
);
if (isset($form_state['mapping_settings'][$i])) {
$mapping = $form_state['mapping_settings'][$i] + $mapping;
}
if ($form_state['mapping_settings_edit'] === $i) {
// Build the form.
if (isset($target['form_callback'])) {
$settings_form = call_user_func($target['form_callback'], $mapping, $target, $form, $form_state);
}
else {
$settings_form = array();
}
// Merge in the optional unique form.
$settings_form += feeds_ui_mapping_settings_optional_unique_form($mapping, $target, $form, $form_state);
return array(
'#type' => 'container',
'settings' => $settings_form,
'save_settings' => $base_button + array(
'#type' => 'submit',
'#name' => 'mapping_settings_update_' . $i,
'#value' => t('Update'),
'#op' => 'update',
),
'cancel_settings' => $base_button + array(
'#type' => 'submit',
'#name' => 'mapping_settings_cancel_' . $i,
'#value' => t('Cancel'),
'#op' => 'cancel',
),
);
}
else {
// Build the summary.
if (isset($target['summary_callback'])) {
$summary = call_user_func($target['summary_callback'], $mapping, $target, $form, $form_state);
}
else {
$summary = '';
}
// Append the optional unique summary.
if ($optional_unique_summary = feeds_ui_mapping_settings_optional_unique_summary($mapping, $target, $form, $form_state)) {
$summary .= ' ' . $optional_unique_summary;
}
if ($summary) {
return array(
'summary' => array(
'#prefix' => '<div>',
'#markup' => $summary,
'#suffix' => '</div>',
),
'edit_settings' => $base_button + array(
'#type' => 'image_button',
'#name' => 'mapping_settings_edit_' . $i,
'#src' => 'misc/configure.png',
'#attributes' => array('alt' => t('Edit')),
'#op' => 'edit',
),
);
}
}
}
/**
* Submit callback for a per mapper configuration form. Switches between edit
* and summary mode.
*/
function feeds_ui_mapping_form_multistep_submit($form, &$form_state) {
$trigger = $form_state['triggering_element'];
switch ($trigger['#op']) {
case 'edit':
$form_state['mapping_settings_edit'] = $trigger['#i'];
break;
case 'update':
$values = $form_state['values']['config'][$trigger['#i']]['settings'];
$form_state['mapping_settings'][$trigger['#i']] = $values;
unset($form_state['mapping_settings_edit']);
break;
case 'cancel':
unset($form_state['mapping_settings_edit']);
break;
}
$form_state['rebuild'] = TRUE;
}
/**
* AJAX callback that returns the whole feeds_ui_mapping_form().
*/
function feeds_ui_mapping_settings_form_callback($form, $form_state) {
return $form;
}
/**
* Validation for source and target selection.
*/
function feeds_ui_mapping_form_add_validate($form, &$form_state) {
if ($form_state['values']['source'] == '') {
form_set_error('source', t('You must select a mapping source.'));
}
if ($form_state['values']['target'] == '') {
form_set_error('target', t('You must select a mapping target.'));
}
}
Alex Barth
committed
* Submit handler for add button on feeds_ui_mapping_form().
Alex Barth
committed
function feeds_ui_mapping_form_add_submit($form, &$form_state) {
$importer = feeds_importer($form['#importer']);
Alex Barth
committed
try {
$mappings = $form['#mappings'];
$mappings[] = array(
'source' => $form_state['values']['source'],
'target' => $form_state['values']['target'],
'unique' => FALSE,
);
$importer->processor->addConfig(array('mappings' => $mappings));
niklas
committed
$importer->save();
Alex Barth
committed
drupal_set_message(t('Mapping has been added.'));
}
catch (Exception $e) {
drupal_set_message($e->getMessage(), 'error');
Alex Barth
committed
* Submit handler for save button on feeds_ui_mapping_form().
Alex Barth
committed
function feeds_ui_mapping_form_submit($form, &$form_state) {
$importer = feeds_importer($form['#importer']);
niklas
committed
$processor = $importer->processor;
$form_state += array(
'mapping_settings' => array(),
'mapping_settings_edit' => NULL,
);
// If an item is in edit mode, prepare it for saving.
if ($form_state['mapping_settings_edit'] !== NULL) {
$values = $form_state['values']['config'][$form_state['mapping_settings_edit']]['settings'];
$form_state['mapping_settings'][$form_state['mapping_settings_edit']] = $values;
}
// We may set some settings to mappings that we remove in the subsequent step,
// that's fine.
$mappings = $form['#mappings'];
niklas
committed
foreach ($form_state['mapping_settings'] as $k => $v) {
$mappings[$k] = array(
'source' => $mappings[$k]['source'],
'target' => $mappings[$k]['target'],
) + $v;
Alex Barth
committed
Tobby Hagler
committed
if (!empty($form_state['values']['remove_flags'])) {
$remove_flags = array_keys(array_filter($form_state['values']['remove_flags']));
foreach ($remove_flags as $k) {
unset($mappings[$k]);
unset($form_state['values']['mapping_weight'][$k]);
Alex Barth
committed
}
// Keep our keys clean.
$mappings = array_values($mappings);
if (!empty($mappings)) {
array_multisort($form_state['values']['mapping_weight'], $mappings);
}
$processor->addConfig(array('mappings' => $mappings));
niklas
committed
$importer->save();
drupal_set_message(t('Your changes have been saved.'));
Alex Barth
committed
* Walk the result of FeedsParser::getMappingSources() or
* FeedsProcessor::getMappingTargets() and format them into
* a Form API options array.
Alex Barth
committed
function _feeds_ui_format_options($options) {
$result = array();
foreach ($options as $k => $v) {
if (is_array($v) && !empty($v['name'])) {
$result[$k] = $v['name'];
}
elseif (is_array($v)) {
$result[$k] = $k;
}
else {
$result[$k] = $v;
}
}
asort($result);
Alex Barth
committed
return $result;
niklas
committed
/**
* Per mapping settings summary callback. Shows whether a mapping is used as
* unique or not.
*/
function feeds_ui_mapping_settings_optional_unique_summary($mapping, $target, $form, $form_state) {
if (!empty($target['optional_unique'])) {
if ($mapping['unique']) {
return t('Used as <strong>unique</strong>.');
niklas
committed
return t('Not used as unique.');
}
}
}
/**
* Per mapping settings form callback. Lets the user choose if a target is as
* unique or not.
*/
function feeds_ui_mapping_settings_optional_unique_form($mapping, $target, $form, $form_state) {
$settings_form = array();
if (!empty($target['optional_unique'])) {
$settings_form['unique'] = array(
'#type' => 'checkbox',
'#title' => t('Unique'),
'#default_value' => !empty($mapping['unique']),
);
}
return $settings_form;
}
/**
* Theme feeds_ui_overview_form().
*/
function theme_feeds_ui_overview_form($variables) {
$form = $variables['form'];
drupal_add_js(drupal_get_path('module', 'feeds_ui') . '/feeds_ui.js');
drupal_add_css(drupal_get_path('module', 'feeds_ui') . '/feeds_ui.css');
// Iterate through all importers and build a table.
foreach (array('enabled', 'disabled') as $type) {
if (isset($form[$type])) {
foreach (element_children($form[$type]) as $id) {
$row = array();
foreach (element_children($form[$type][$id]) as $col) {
$row[$col] = array(
'data' => drupal_render($form[$type][$id][$col]),
);
}
$rows[] = array(
'data' => $row,
Dave Reid
committed
$output = theme('table', array(
'header' => $form['#header'],
'rows' => $rows,
'attributes' => array('class' => array('feeds-admin-importers')),
'empty' => t('No importers available.'),
));
if (!empty($rows)) {
$output .= drupal_render_children($form);
Dave Reid
committed
Alex Barth
committed
* Theme feeds_ui_edit_page().
function theme_feeds_ui_edit_page($variables) {
$config_info = $variables['info'];
$active_container = $variables['active'];
drupal_add_css(drupal_get_path('module', 'feeds_ui') . '/feeds_ui.css');
Alex Barth
committed
// Outer wrapper.
$output = '<div class="feeds-settings clear-block">';
Alex Barth
committed
// Build left bar.
$output .= '<div class="left-bar">';
foreach ($config_info as $info) {
$output .= theme('feeds_ui_container', array('container' => $info));
Alex Barth
committed
}
$output .= '</div>';
// Build configuration space.
$output .= '<div class="configuration">';
$output .= '<div class="configuration-squeeze">';
$output .= theme('feeds_ui_container', array('container' => $active_container));
Alex Barth
committed
$output .= '</div>';
$output .= '</div>';
$output .= '</div>'; // ''<div class="feeds-settings">';
return $output;
Alex Barth
committed
* Render a simple container. A container can have a title, a description and
* one or more actions. Recursive.
*
* @todo Replace with theme_fieldset or a wrapper to theme_fieldset?
Alex Barth
committed
*
* @param $variables
* An array containing an array at 'container'.
* A 'container' array may contain one or more of the following keys:
Alex Barth
committed
* array(
* 'title' => 'the title',
* 'body' => 'the body of the container, may also be an array of more
* containers or a renderable array.',
* 'class' => array('the class of the container.'),
Alex Barth
committed
* 'id' => 'the id of the container',
* );
function theme_feeds_ui_container($variables) {
$container = $variables['container'];
Alex Barth
committed
$class = array_merge(array('feeds-container'), empty($container['class']) ? array('plain') : $container['class']);
$id = empty($container['id']) ? '': ' id="' . $container['id'] . '"';
$output = '<div class="' . implode(' ', $class) . '"' . $id . '>';
Alex Barth
committed
if (isset($container['actions']) && count($container['actions'])) {
$output .= '<ul class="container-actions">';
foreach ($container['actions'] as $action) {
$output .= '<li>' . $action . '</li>';
}
$output .= '</ul>';
Alex Barth
committed
}
if (!empty($container['title'])) {
$output .= '<h4 class="feeds-container-title">';
$output .= $container['title'];
$output .= '</h4>';
}
if (!empty($container['body'])) {
$output .= '<div class="feeds-container-body">';
if (is_array($container['body'])) {
if (isset($container['body']['#type'])) {
$output .= drupal_render($container['body']);
}
else {
foreach ($container['body'] as $c) {
$output .= theme('feeds_ui_container', array('container' => $c));
}
Alex Barth
committed
}
}
else {
$output .= $container['body'];
}
$output .= '</div>';
}
$output .= '</div>';
return $output;
}
/**
* Theme function for feeds_ui_mapping_form().
*/
function theme_feeds_ui_mapping_form($variables) {
$form = $variables['form'];