function feeds_xls_create_csv_of_data in Feeds XLS 7
Create a CSV file with data in which can later be converted to a proper XLS file.
1 string reference to 'feeds_xls_create_csv_of_data'
- feeds_xls_download_populated_template in ./
feeds_xls.template.inc - Callback function to provide the populated template.
File
- ./
feeds_xls.template.inc, line 99
Code
function feeds_xls_create_csv_of_data($feeds_importer, &$context) {
if (!isset($context['sandbox']['progress'])) {
// Calculate the total number of rows to add to this file.
// Use the processor class to guess what entity type we're importing (this
// relies on other coders following a similar convention to the feeds
// module).
$processor_class = get_class($feeds_importer->processor);
$entity_guess = strtolower(substr($processor_class, 5, strpos($processor_class, 'Processor') - 5));
$bundle = '';
$context['sandbox']['entity'] = '';
$context['sandbox']['entity_ids'] = array();
$context['sandbox']['row'] = 0;
switch ($entity_guess) {
case 'node':
$query = db_select('node', 'e')
->fields('e', array(
'nid',
))
->condition('type', $feeds_importer->processor->config['bundle']);
$entity_key = 'nid';
$context['sandbox']['entity'] = 'node';
break;
case 'term':
// The bundle for a term is actually the vid.
$vocabulary = taxonomy_vocabulary_machine_name_load($feeds_importer->processor->config['vocabulary']);
$query = db_select('taxonomy_term_data', 'e')
->fields('e', array(
'tid',
))
->condition('vid', $vocabulary->vid);
$entity_key = 'tid';
$entity_guess = 'taxonomy_term';
$context['sandbox']['entity'] = 'taxonomy_term';
break;
case 'file':
$query = db_select('file_managed', 'e')
->fields('e', array(
'fid',
))
->condition('type', $feeds_importer->processor->config['bundle']);
$entity_key = 'fid';
$context['sandbox']['entity'] = 'file';
break;
case 'user':
$query = db_select('users', 'e')
->fields('e')
->condition('uid', 1, '>');
$entity_key = 'uid';
$context['sandbox']['entity'] = 'user';
break;
}
drupal_alter('feeds_xls_template_query', $query, $context['sandbox']['entity'], $entity_key);
$results = $query
->execute();
$context['sandbox']['progress'] = 0;
foreach ($results as $row) {
$context['sandbox']['entity_ids'][] = $row->{$entity_key};
}
$context['sandbox']['max'] = count($context['sandbox']['entity_ids']);
// Create the template before adding any rows to it.
$context['sandbox']['csv_path'] = drupal_tempnam('temporary://', $feeds_importer->id);
// We need a few variables and stuff when finished, so we shove them in the
// results array.
$context['results']['csv_path'] = $context['sandbox']['csv_path'];
// FIXME - repetition!
if ($context['sandbox']['max'] > 65534) {
// One less than XLS max due to the
// header row
$context['results']['writer'] = 'Excel2007';
}
else {
$context['results']['writer'] = 'Excel5';
}
$context['results']['importer'] = $feeds_importer->id;
file_put_contents($context['results']['csv_path'], "\n");
$context['finished'] = FALSE;
$context['progress'] = 0;
}
// Load the csv file
$csvf = fopen($context['sandbox']['csv_path'], 'a');
// Load the entites
$loop = 0;
$ids_to_load = array();
while ($loop < 500 && ($id = array_pop($context['sandbox']['entity_ids'])) != FALSE) {
$ids_to_load[] = $id;
$loop++;
}
$entities = entity_load($context['sandbox']['entity'], $ids_to_load);
// Loop through each of the entities
foreach ($entities as $entity_id => $entity) {
// If we are unable to edit this entity, we go no further.
if (!user_access('feeds xls allow download of all entities') && !(entity_access('update', $context['sandbox']['entity'], $entity) || entity_access('edit', $context['sandbox']['entity'], $entity))) {
continue;
}
// Create a row array for each entity.
$row_values = array();
foreach ($feeds_importer->processor->config['mappings'] as $key => $mapping) {
$row_values[$key] = '';
if (strpos($mapping['target'], ':')) {
// We currently know of two mappings (node:title and node:nid) that use
// this format. We'll try to work out which this one is.
$target = $mapping['target'];
$target = explode(':', $target);
// The country field is a little awkward, so we strip off the first
// two parts.
// FIXME - This WILL break with the entity language module and some
// mappings, so we need to look for the specific field type.
if (count($target) == 4) {
array_shift($target);
array_shift($target);
}
// First we check to see if we have a value, and proceed if we do.
if (isset($entity->{$target[0]}) && is_array($entity->{$target[0]}) && count($entity->{$target[0]})) {
$cell_values = array();
// The date field users field:start/field:end, while the node_ref
// field uses field:nid/field:title. We guess which we're using.
foreach ($entity->{$target[0]} as $language => $values) {
if ($language == LANGUAGE_NONE && count($cell_values)) {
continue;
}
// FIXME - Why is this loop not foreach($values as ...)?
foreach ($entity->{$target[0]}[$language] as $value) {
switch ($target[1]) {
case 'et':
if ($target[2] == $language || $language == LANGUAGE_NONE) {
_feeds_xls_create_csv_of_data_helper(FALSE, $mapping, $value, $cell_values);
}
break;
case 'iso2':
$cell_values[] = $value['iso2'];
break;
case 'guid':
$field = field_info_field($target[0]);
if (is_array($entity->{$target[0]}) && count($entity->{$target[0]})) {
$cell_values = array();
foreach ($entity->{$target[0]} as $language => $values) {
foreach ($entity->{$target[0]}[$language] as $value) {
foreach ($value as $subkey => $item) {
// Change to the allowed values array().
if ($field && !empty($field['settings']['allowed_values'][$item])) {
$item = $field['settings']['allowed_values'][$item];
}
switch ($subkey) {
case 'tid':
// Note, we could do this with a single query, but
// that would place a requirement on the UUID
// module/column,
// so doing it this way keeps it a little simpler.
$guid = db_select('feeds_item', 'f')
->condition('entity_type', 'taxonomy_term')
->condition('entity_id', $item)
->fields('f', array(
'guid',
))
->execute()
->fetchField();
if (!$guid) {
$term = taxonomy_term_load($item);
$guid = empty($term->uuid) ? '' : $term->uuid;
}
$cell_values[] = $guid;
break;
case 'nid':
$guid = db_select('feeds_item', 'f')
->condition('entity_type', 'node')
->condition('entity_id', $item)
->fields('f', array(
'guid',
))
->execute()
->fetchField();
if (!$guid) {
$node = node_load($item);
$guid = empty($node->uuid) ? '' : $node->uuid;
}
$cell_values[] = $guid;
break;
}
}
}
}
}
break;
case 'tid':
$cell_values[] = $value['tid'];
break;
case 'nid':
$cell_values[] = $value['nid'];
break;
case 'uid':
$cell_values[] = $value['uid'];
break;
case 'start':
if (substr($value['value'], -8) == '00:00:00') {
$value['value'] = trim(substr($value['value'], 0, -8));
}
$cell_values[] = $value['value'];
break;
case 'end':
if (substr($value['value'], -8) == '00:00:00') {
$value['value'] = trim(substr($value['value'], 0, -8));
}
$cell_values[] = $value['value2'];
break;
case 'MediaFeedsLibraryProvider':
$cell_values[] = $value['filename'];
break;
default:
// We most likely have a field collection field. Lets try to
// load the field and check the type.
$field = field_info_field($target[0]);
if ($field['type'] == 'field_collection') {
// We restart the loop just so that we can get the IDs to
// all load at once
$ids = array();
foreach ($entity->{$target[0]}[$language] as $value) {
$ids[] = $value['value'];
}
foreach (entity_load('field_collection_item', $ids) as $fc_entity) {
foreach (array_keys($fc_entity->{$target[1]}) as $language) {
foreach (array_keys($fc_entity->{$target[1]}[$language]) as $delta) {
$cell_values[] = $fc_entity->{$target[1]}[$language][$delta]['value'];
}
}
}
break 3;
}
elseif ($field['type'] == 'link_field') {
$cell_values[] = $value[$target[1]];
break 3;
}
}
}
}
$row_values[$key] = _feeds_xls_get_value(implode('|', $cell_values));
}
}
else {
switch ($mapping['target']) {
case 'group_audience':
$gids = array();
foreach ($entity->{$mapping['target']} as $language => $values) {
foreach ($entity->{$mapping['target']}[$language] as $value) {
$gids[] = $value['gid'];
}
}
$row_values[$key] = implode('|', $gids);
break;
case 'guid':
// Look for this entity in the feeds_item table. If not there, we
// generate an entry for it.
$guid = FALSE;
if (isset($entity->uuid)) {
$guid = $entity->uuid;
}
$feeds_item = feeds_xls_get_or_generate_feeds_item_entry($context['sandbox']['entity'], $entity_id, $feeds_importer->id, $guid);
$row_values[$key] = _feeds_xls_get_value($feeds_item['guid']);
break;
case 'parentguid':
// For some unknown reason, we don't have the parent of this entity,
// so we need to query the taxonomy_term_hierarchy table.
$row = db_select('taxonomy_term_hierarchy', 't')
->fields('t')
->condition('tid', $entity_id)
->execute()
->fetch();
if ($row && $row->parent) {
$parent_term = taxonomy_term_load($row->parent);
if ($parent_term) {
$guid = FALSE;
if (isset($parent_term->uuid)) {
$guid = $parent_term->uuid;
}
$feeds_item = feeds_xls_get_or_generate_feeds_item_entry($context['sandbox']['entity'], $parent_term->tid, $feeds_importer->id, $guid);
$row_values[$key] = _feeds_xls_get_value($feeds_item['guid']);
}
}
break;
case 'parent':
// We don't do anything for parent, as we use parentguid instead.
case 'pass':
// We don't do anything for password
break;
case 'name':
case 'mail':
// Check if we are a stub user - we don't want to continue
if (!empty($entity->stub_user)) {
break;
}
default:
if (isset($entity->{$mapping['target']})) {
$field = field_info_field($mapping['target']);
// We can't do anything with file fields (we allow import, but not
// updating).
if (in_array($field['type'], array(
'file',
))) {
continue;
}
if (is_array($entity->{$mapping['target']}) && count($entity->{$mapping['target']})) {
$cell_values = array();
foreach ($entity->{$mapping['target']} as $language => $values) {
$implosion = '|';
foreach ($entity->{$mapping['target']}[$language] as $value) {
_feeds_xls_create_csv_of_data_helper($field, $mapping, $value, $cell_values);
}
}
$row_values[$key] = _feeds_xls_get_value(implode($implosion, $cell_values));
}
elseif (is_string($entity->{$mapping['target']})) {
$row_values[$key] = _feeds_xls_get_value($entity->{$mapping['target']});
}
}
}
}
}
// Increase the row number
$context['sandbox']['row']++;
// Write out the fields
fputcsv($csvf, $row_values);
}
fclose($csvf);
// Set the progress
$context['progress'] = $context['sandbox']['row'] / $context['sandbox']['max'];
$context['finished'] = $context['progress'];
$context['message'] = t('Added @current entities out of @total to the file.', array(
'@current' => $context['sandbox']['row'],
'@total' => $context['sandbox']['max'],
));
if (!count($context['sandbox']['entity_ids'])) {
$context['finished'] = TRUE;
// Set a message warning the user that the download will take a little while
// to create.
$context['message'] = t('Please wait while your file is converted. This can take a few minutes.');
}
}