I don't think I have a very good handle on feeds as it seems I am going about this the wrong way. Basically I am writing a custom processor to create blank entities retrieved via xml that will have their values completed by the user at a later time. I am successfully creating the entities and blank fields without an issue. I am curious how to pull the parser results in order to name the embedded fields properly (basically create a loop to create each one, using a mapped value from the xml to define their machine names).

A simplified example of what I am trying to do. Note that this excludes the non-relevant functions (at least I think they are non-relevant to solve this).

<?php
// Save Entity
public function entitySave($entity) {
 
$t = get_t();
 
 
$fields_array = array(
    array(
     
'field' => array(
       
'field_name' => $entity->field_name// This should be mapped for each imported entity
       
'label' => $t($entity->title),  // Should be mapped as well
       
'cardinality' => -1,
       
'type' => 'field_collection',
      ),
     
'instance' => array(
       
'field_name' => $entity->field_name// This should be mapped for each imported entity
       
'entity_type' => 'commerce_order',
       
'bundle' => 'commerce_order',
       
'label' => $t($entity->field_name),  // Mapped
       
'description' => '',
       
'widget' => array('type' => 'field_collection_embed'),
       
'required' => 1,
      ),
    ),
array(
     
'field' => array(
       
'field_name' => 'field_test'// Field inside entity with blank value
       
'type' => 'text',
       
'cardinality' => 1,
       
'label' => 'Test Field',
       
'settings' => array(),
      ),
     
'instance' => array(
       
'field_name' => 'field_test',
       
'entity_type' => 'field_collection_item',
       
'bundle' => $entity->field_name// Once again must be pulled from the file through the xml mapping
       
'label' => 'Test Field',
       
'cardinality' => 1,
       
'description' => '',
       
'widget' => array(
         
'type' => 'text_textarea',
         
'weight' => 0,
         
'settings' => array('size' => 50),
        ),
       
'display' => array(
         
'default' => array(
           
'label' => 'above',
           
'settings' => array(),
           
'weight' => 1,
          ),
         
'teaser' => array(
           
'label' => 'above',
           
'settings' => array(),
           
'type' => 'hidden',
          ),
        ),
       
'required' => FALSE,
      )
    ),
  );
 
 
// Loop through fields array and create field and instance
 
foreach ($fields_array as $field) {
   
// Check if field already exists
   
if (!field_info_field($field['field']['field_name'])) {
     
field_create_field($field['field']);
    }

   

// Check if instance exists
   
if (!field_info_instance($field['instance']['entity_type'], $field['instance']['field_name'], $field['instance']['bundle'])) {
     
field_create_instance($field['instance']);
    }
  }  
}

// Mapping Variables
 
public function getMappingTargets() {

   

$targets = parent::getMappingTargets();
   
$targets += array(
     
'field_id' => array(
       
'name' => t('Field ID'),
       
'description' => t('This ID is unique identifier for each field.'),
       
'optional_unique' => TRUE,
      ),
     
'field_name' => array(
       
'name' => t('Field Name'),
       
'description' => t('The Name of the Field.'),
      ),
    );
    return
$targets;
  }
}
?>

As you can see my biggest problem is I can't for the life of me figure out how to get the imported values from the mappings of the xml parser to use in the processor. Any direction is greatly appreciated.

Comments

JMOmandown’s picture

After researching for the past couple days I am more confused and unable to find an answer. It seems my questions is very unique, which is surprising, since pulling values in this way allows for an extreme extension in the feeds module's use cases. Any direction on if pulling values out of the parser stream programmatically would be wonderful, is this even possible?

lyricnz’s picture

I don't understand your requirement, but the simplest way to access all the results from the parser would be to override FeedsProcessor::process(FeedsSource $source, FeedsParserResult $parser_result) and look into $parser_result, before calling parent::process()

JMOmandown’s picture

Thanks for the direction, I am going to see if I can come up with a solution using this approach. The requirements are a bit outside the original scope of the feeds module, but it does a great job extending to this use type. Basically we want feeds to ignore the values and only check to see if there is a value in the parsed file. If there is, then I want to pass that information to the processor where it will create a few entities: 1) A field collection for the overall file being imported, 2) A field inside the field collection for each "group" that contains a value, skipping those that do not have a value, and 3) pragmatically set up conditional fields relationships for the various fields created (obviously outside the scope of this issue).

For example, lets assume we have an xml file like the following:

<Object1>
    <Hours>1600</Hours>
    <Date></Date>
</Object1>
<Object2>
    <Hours></Hours>
    <Date>11/10/2012</Date>
</Object2>

Using the above file, I would basically use the parser to see that there is a value listed in Hours for Object1 and in Date for Object2. This information would be passed to the processor where would would create a field collection for Object1 and a field collection for Object2. Object1 would contain a field named hours and Object2 would have a field named Date.

Basically I am trying to use feeds to sync databases for the entities themselves instead of the values.

JMOmandown’s picture

@lyricnz

I am still struggling with this... think I could get a simplified example of using information from the parser in this manner?