Skip to content
Snippets Groups Projects
Commit f22a0f7f authored by Chris Leppanen's avatar Chris Leppanen
Browse files

Issue #661606 by MegaChriz, twistor, Cottser, scottrigby, manojbisht_drupal,...

Issue #661606 by MegaChriz, twistor, Cottser, scottrigby, manojbisht_drupal, Mohammed J. Razem, agileadam, emilyf, tmsimont, bradjones1, hairqles, ldavisrobeson, selim13, a.ross, chromix, g089h515r806 | lunk_rat: Added Support unique targets in mappers.
parent a6abe508
No related branches found
No related tags found
No related merge requests found
......@@ -271,10 +271,10 @@ function my_source_get_source(FeedsSource $source, FeedsParserResult $result, $k
* Remove with caution.
* @param $entity_type
* The entity type of the target, for instance a 'node' entity.
* @param $bundle_name
* @param $bundle
* The bundle name for which to alter targets.
*/
function hook_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_name) {
function hook_feeds_processor_targets_alter(&$targets, $entity_type, $bundle) {
if ($entity_type == 'node') {
$targets['my_node_field'] = array(
'name' => t('My custom node field'),
......@@ -292,6 +292,17 @@ function hook_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_nam
'callback' => 'my_module_set_target2',
'real_target' => 'my_node_field_two', // Specify real target field on node.
);
$targets['my_node_field3'] = array(
'name' => t('My third custom node field'),
'description' => t('Description of what my third custom node field does.'),
'callback' => 'my_module_set_target3',
// Set optional_unique to TRUE and specify unique_callbacks to allow the
// target to be unique. Existing entities can be updated based on unique
// targets.
'optional_unique' => TRUE,
'unique_callbacks' => array('my_module_mapper_unique'),
);
}
}
......@@ -368,6 +379,42 @@ function my_module_form_callback($mapping, $target, $form, $form_state) {
);
}
/**
* Example of the unique_callbacks specified in
* hook_feeds_processor_targets_alter().
*
* @param FeedsSource $source
* The Feed source.
* @param string $entity_type
* Entity type for the entity to be processed.
* @param string $bundle
* Bundle name for the entity to be processed.
* @param string $target
* A string identifying the unique target on the entity.
* @param array $values
* The unique values to be checked.
*
* @return int
* The existing entity id, or 0 if not found.
*
* @see hook_feeds_processor_targets_alter()
* @see FeedsProcessor::existingEntityId()
*/
function my_module_mapper_unique(FeedsSource $source, $entity_type, $bundle, $target, array $values) {
list($field_name, $column) = explode(':', $target . ':value');
// Example for if the target is a field.
$query = new EntityFieldQuery();
$result = $query
->entityCondition('entity_type', $entity_type)
->entityCondition('bundle', $bundle)
->fieldCondition($field_name, $column, $values)
->execute();
if (!empty($result[$entity_type])) {
return key($result[$entity_type]);
}
}
/**
* @}
*/
......@@ -38,6 +38,7 @@ files[] = tests/feeds_mapper_field.test
files[] = tests/feeds_mapper_file.test
files[] = tests/feeds_mapper_path.test
files[] = tests/feeds_mapper_profile.test
files[] = tests/feeds_mapper_unique.test
files[] = tests/feeds_mapper.test
files[] = tests/feeds_mapper_config.test
files[] = tests/feeds_fetcher_file.test
......
......@@ -738,10 +738,10 @@ abstract class FeedsProcessor extends FeedsPlugin {
*
* @param FeedsSource $source
* The source information about this import.
* @param $result
* @param FeedsParserResult $result
* A FeedsParserResult object.
*
* @return
* @return int
* The serial id of an entity if found, 0 otherwise.
*/
protected function existingEntityId(FeedsSource $source, FeedsParserResult $result) {
......@@ -751,23 +751,40 @@ abstract class FeedsProcessor extends FeedsPlugin {
->condition('entity_type', $this->entityType())
->condition('id', $source->id);
// Iterate through all unique targets and test whether they do already
// exist in the database.
$targets = &drupal_static('FeedsProcessor::existingEntityId', array());
if (!isset($targets[$this->id])) {
$targets[$this->id] = $this->getMappingTargets();
}
$entity_id = 0;
// Iterate through all unique targets and test whether they already exist in
// the database.
foreach ($this->uniqueTargets($source, $result) as $target => $value) {
switch ($target) {
case 'url':
$entity_id = $query->condition('url', $value)->execute()->fetchField();
break;
case 'guid':
$entity_id = $query->condition('guid', $value)->execute()->fetchField();
break;
if ($target === 'guid' || $target === 'url') {
$entity_id = $query->condition($target, $value)->execute()->fetchField();
}
if (isset($entity_id)) {
// Return with the content id found.
if (!$entity_id && !empty($targets[$this->id][$target]['unique_callbacks'])) {
if (!is_array($value)) {
$value = array($value);
}
foreach ($targets[$this->id][$target]['unique_callbacks'] as $callback) {
if (is_callable($callback) && $entity_id = call_user_func_array($callback, array($source, $this->entityType(), $this->bundle(), $target, $value))) {
// Stop at the first unique ID returned by a callback.
break;
}
}
}
// Return with the content id found.
if ($entity_id) {
return $entity_id;
}
}
return 0;
return $entity_id;
}
......
<?php
/**
* @file
* Contains FeedsMapperUniqueTestCase.
*/
/**
* Class for testing Feeds unique callbacks.
*/
class FeedsMapperUniqueTestCase extends FeedsMapperTestCase {
public static function getInfo() {
return array(
'name' => 'Unique target callbacks',
'description' => 'Test unique target callbacks in mappers.',
'group' => 'Feeds',
);
}
/**
* Test mapping target "unique_callbacks".
*/
public function test() {
// Create content type.
$typename = $this->createContentType(array(), array('alpha' => 'text'));
// Create two nodes. Put unique value into field field_alpha.
$node1 = $this->drupalCreateNode(array(
'type' => $typename,
'field_alpha' => array(
LANGUAGE_NONE => array(
0 => array(
'value' => 'Ut wisi',
),
),
),
));
$node2 = $this->drupalCreateNode(array(
'type' => $typename,
'field_alpha' => array(
LANGUAGE_NONE => array(
0 => array(
'value' => 'Lorem',
),
),
),
));
// Create and configure importer.
$this->createImporterConfiguration('Syndication', 'syndication');
$this->setPlugin('syndication', 'FeedsFileFetcher');
$this->setPlugin('syndication', 'FeedsCSVParser');
$this->setSettings('syndication', 'FeedsNodeProcessor', array('bundle' => $typename, 'update_existing' => 2));
$this->addMappings('syndication', array(
0 => array(
'source' => 'title',
'target' => 'title',
),
1 => array(
'source' => 'alpha',
'target' => 'test_unique_target',
'unique' => TRUE,
),
));
// Import CSV file.
$this->importFile('syndication', $this->absolutePath() . '/tests/feeds/content.csv');
$this->assertText('Updated 2 nodes');
// Ensure the updated nodes have the expected title now.
$node1 = node_load($node1->nid, NULL, TRUE);
$this->assertEqual('Ut wisi enim ad minim veniam', $node1->title, 'Node 1 has the expected title.');
$node2 = node_load($node2->nid, NULL, TRUE);
$this->assertEqual('Lorem ipsum', $node2->title, 'Node 2 has the expected title.');
}
}
......@@ -104,7 +104,7 @@ function feeds_tests_files_remote() {
/**
* Implements hook_feeds_processor_targets_alter().
*/
function feeds_tests_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_name) {
function feeds_tests_feeds_processor_targets_alter(&$targets, $entity_type, $bundle) {
$targets['test_target'] = array(
'name' => t('Test Target'),
'description' => t('This is a test target.'),
......@@ -112,6 +112,14 @@ function feeds_tests_feeds_processor_targets_alter(&$targets, $entity_type, $bun
'summary_callback' => 'feeds_tests_mapper_summary',
'form_callback' => 'feeds_tests_mapper_form',
);
$targets['test_unique_target'] = array(
'name' => t('Test unique target'),
'description' => t('This is a unique test target.'),
'callback' => 'feeds_tests_mapper_set_target',
'optional_unique' => TRUE,
'unique_callbacks' => array('feeds_tests_mapper_unique'),
);
}
/**
......@@ -205,3 +213,21 @@ function feeds_tests_mapper_form($mapping, $target, $form, $form_state) {
),
);
}
/**
* Callback for unique_callbacks for test_target mapper.
*
* @see feeds_tests_feeds_processor_targets_alter()
*/
function feeds_tests_mapper_unique(FeedsSource $source, $entity_type, $bundle, $target, array $values) {
$query = new EntityFieldQuery();
$result = $query
->entityCondition('entity_type', $entity_type)
->entityCondition('bundle', $bundle)
->fieldCondition('field_alpha', 'value', $values)
->execute();
if (!empty($result[$entity_type])) {
return key($result[$entity_type]);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment