diff --git a/scald_feeds.module b/scald_feeds.module index 13f1780..c90ce7d 100644 --- a/scald_feeds.module +++ b/scald_feeds.module @@ -21,7 +21,6 @@ function scald_feeds_feeds_processor_targets_alter(&$targets, $entity_type, $bun ); } } - } /** @@ -40,16 +39,22 @@ function scald_feeds_set_target($source, $entity, $target, $value) { if (!is_array($value)) { $value = array($value); } + foreach ($value as $k => $v) { - if (!($v instanceof FeedsEnclosure)) { - if (is_string($v)) { - $value[$k] = new FeedsEnclosure($v, file_get_mimetype($v)); - } - else { - unset($value[$k]); + if(!empty($value[$k])) { + if (!($v instanceof FeedsEnclosure)) { + if (is_string($v)) { + $value[$k] = new FeedsEnclosure($v, file_get_mimetype($v)); + } + else { + unset($value[$k]); + } } + } else { + unset($value[$k]); } } + if (empty($value)) { return; } @@ -65,90 +70,276 @@ function scald_feeds_set_target($source, $entity, $target, $value) { $data[$entity_type] = $entity; } - $destination = 'public://'; // Populate entity. - $i = 0; + $i = isset($entity->{$target}[LANGUAGE_NONE])?count($entity->{$target}[LANGUAGE_NONE]):0; $field = isset($entity->$target) ? $entity->$target : array(); + foreach ($value as $v) { - try { - $file = $v->getFile($destination); + // First check if we are given a scald ID + $existing_sid = FALSE; + if(is_numeric($v->getValue())) { + $atom = scald_atom_load($v->getValue()); + if($atom) { + $existing_sid = $atom->sid; + } } - catch (Exception $e) { - watchdog_exception('Feeds', $e, nl2br(check_plain($e))); + + // Check if using a GUID for an existing scald atom previously imported by feeds + if($existing_sid == FALSE) { + $existing_sid = scald_feeds_lookup_atom_by_guid($v->getValue()); } - if ($file) { - $file = (array) $file; - $sid = _scald_feeds_save_atom($file, $file['filename']); - $field['und'][$i] = array( - 'sid' => $sid, + + // Search for a previously imported matching scald atom and use that if found. + if($existing_sid == FALSE) { + $type = _scald_feeds_get_provider_by_mime_type($v->getMimeType()); + $existing_sid = scald_feeds_fetch_matching_atom($v->getValue(), $type); + } + + if($existing_sid) { + $field[LANGUAGE_NONE][$i] = array( + 'sid' => $existing_sid, ); if ($info['cardinality'] == 1) { break; } $i++; } + else { + $sid = _scald_feeds_save_atom($v->getValue(), $type, urldecode(basename($v->getValue()))); + + $field[LANGUAGE_NONE][$i] = array( + 'sid' => $sid, + ); + if ($info['cardinality'] == 1) { + break; + } + $i++; + } } + $entity->{$target} = $field; } +function _scald_feeds_copy_fields($form, &$atom) { + $basic_fields = array( + 'field_scald_description', + 'field_scald_headline', + 'field_licence_std_cc', + 'field_rights', + 'field_scald_location', + 'field_scald_creator' + ); + + foreach($basic_fields as $field) { + if(isset($form[$field])){ + $atom->{$field} = $form[$field]; + } + } + + if(isset($form['field_scald_geo_location'][LANGUAGE_NONE][0]['geom']['#default_value']['lat']) && isset($form['field_scald_geo_location'][LANGUAGE_NONE][0]['geom']['#default_value']['lon'])) { + $atom->{'field_scald_geo_location'}[LANGUAGE_NONE][0]['input_format'] = 'lat/lon'; + $atom->{'field_scald_geo_location'}[LANGUAGE_NONE][0]['geom']['lat'] = $form['field_scald_geo_location'][LANGUAGE_NONE][0]['geom']['#default_value']['lat']; + $atom->{'field_scald_geo_location'}[LANGUAGE_NONE][0]['geom']['lon'] = $form['field_scald_geo_location'][LANGUAGE_NONE][0]['geom']['#default_value']['lon']; + } + + if (isset($form['field_scald_created'][LANGUAGE_NONE][0]['#default_value'])) { + $value1 = str_replace('T', ' ', $form['field_scald_created'][LANGUAGE_NONE][0]['#default_value']['value']); + $value2 = str_replace('T', ' ', $form['field_scald_created'][LANGUAGE_NONE][0]['#default_value']['value2']); + $atom->field_scald_created[LANGUAGE_NONE] = array(array('value' => $value1, 'value2' => $value2)); + } + + if(isset($form['scald_tags'])) { + foreach($form['scald_tags'][LANGUAGE_NONE] as $index => $tag) { + $scald_tags = taxonomy_get_term_by_name($tag, 'scald_tags'); + + if(!isset($atom->scald_tags[LANGUAGE_NONE])) { + $atom->scald_tags[LANGUAGE_NONE] = array(); + } + + if(empty($scald_tags)) { + $scald_tag_vocab = taxonomy_vocabulary_machine_name_load('scald_tags'); + + if($scald_tag_vocab != FALSE) { + $new_scald_tag = new stdClass(); + $new_scald_tag->name = $tag; + $new_scald_tag->vid = $scald_tag_vocab->vid; + taxonomy_term_save($new_scald_tag); + $atom->scald_tags[LANGUAGE_NONE][] = json_decode(json_encode($new_scald_tag), true); + } + } else { + foreach($scald_tags as $tag) { + $atom->scald_tags[LANGUAGE_NONE][] = json_decode(json_encode($tag), true); + } + } + } + } +} + /** * Saves a Scald Atom programmatically from a file. */ -function _scald_feeds_save_atom($file, $title = NULL) { - if (is_numeric($file)) { - $file = (array) file_load($file); +function _scald_feeds_save_atom($file, $type, $title = NULL) { + $atoms = array(new ScaldAtom($type, 'scald_' . $type)); + + // Skip atom type the user isn't allowed to create. + if (!scald_action_permitted($atoms[0], 'create')) { + return FALSE; + } + + if(valid_url($file, TRUE)) { + $data = drupal_http_request($file); + $temp_file = file_unmanaged_save_data($data->data); + } else { + $temp_file = file_unmanaged_copy($file); } - elseif (!is_object($file) && !is_array($file)) { + + if($temp_file === FALSE) { return FALSE; } - $file_array = (array) $file; - if (!isset($file_array['filename'])) { - $file = file_load($file_array['fid']); - $file_array = (array) $file; + $providers = scald_atom_providers(); + $sources = $providers[$type]; + $source = key($sources); + + $form_state = array( + 'values' => array( + 'file' => array( array ('name' => $title, 'tmppath' => $temp_file)) + ), + 'scald' => array( 'type' => $type, 'source' => isset($source) ? $source : NULL, 'atoms' => array($atoms[0])), + 'ajax' => 0 + ); + $form = array('atom0' => array('#entity' => $atoms[0], '#parents' => array('atom0'))); + $form['#entity_type'] = 'scald_atom'; + $form_id = 'scald_atom_add_form_options'; + + $add_form_function = 'scald_' . $type . '_scald_add_form'; + if(function_exists($add_form_function)) { + $add_form_function($form, $form_state); + } else { + return FALSE; } - $type = _scald_feeds_get_provider_by_file($file_array); - $atom = new ScaldAtom($type, 'scald_' . $type); - $atom->base_id = $file_array['fid']; - $atom->title = !empty($title) ? $title : $file_array['filename']; - $file_array['display'] = TRUE; - $target = ''; - switch ($type) { - case 'file': - $target = 'scald_file'; - break; - case 'image': - case 'video': - $target = 'scald_thumbnail'; - break; + $fill_form_function = 'scald_' . $type . '_scald_add_form_fill'; + if(function_exists($fill_form_function)) { + $fill_form_function($atoms, $form, $form_state); + } else { + return FALSE; } - $atom->{$target} = array( - LANGUAGE_NONE => array( - 0 => $file_array, - ), - ); - return scald_atom_save($atom); + drupal_alter('form', $form, $form_state, $form_id); + + // The atom should really be built using entity_form_submit_build_entity... + _scald_feeds_copy_fields($form['atom0'], $atoms[0]); + + $atoms[0]->scald_file[LANGUAGE_NONE][0]['display'] = TRUE; + + return scald_atom_save($atoms[0]); } + /** * Suggests a Scald provider for the given file. * - * Chooses from file, image and video. + * Chooses from file, audio, image and video. */ -function _scald_feeds_get_provider_by_file($file) { +function _scald_feeds_get_provider_by_mime_type($mime_type) { $type = 'file'; - $fi = new finfo(FILEINFO_MIME); - $mime = $fi->buffer(file_get_contents($file['uri'])); - - if (strpos($mime, 'image/') === 0) { + if (strpos($mime_type, 'audio/') === 0) { + $type = 'audio'; + } + if (strpos($mime_type, 'image/') === 0) { $type = 'image'; } - elseif (strpos($mime, 'video/') === 0) { + elseif (strpos($mime_type, 'video/') === 0) { $type = 'video'; } return $type; } + +/** + * Looks up an atom by GUID, assumes SQL storage backend. + * + * @param string $guid + * The Feeds GUID to compare against. + * + * @return int|FALSE + * The atom id, or FALSE if one was not found. + */ +function scald_feeds_lookup_atom_by_guid($guid) { + return db_select('feeds_item') + ->fields('feeds_item', array('entity_id')) + ->condition('entity_type', 'scald_atom') + ->condition('guid', $guid) + ->execute() + ->fetchField(); +} + + +/** + * Looks for an existing imported atom that is equivalent to a newly created atom using the new file. + * This is to avoid creating duplicate atoms on repeated feed imports. + * + * @param string $filename + * The full path & filename of the file to compare + * + * @return int|FALSE + * The atom id, or FALSE if one was not found. + */ +function scald_feeds_fetch_matching_atom($filename, $type) { + global $user; + + $scald_query = array( 'title' => basename($filename), + 'type' => $type, + 'publisher' => $user->uid); + $sids = scald_search($scald_query, FALSE); + + if(!$sids) { + return FALSE; + } + + foreach ($sids as $sid) { + $atom = scald_atom_load($sid); + + switch ($type) { + case 'file': + scald_file_scald_fetch($atom, 'atom'); + break; + case 'image': + scald_image_scald_fetch($atom, 'atom'); + break; + case 'audio': + scald_audio_scald_fetch($atom, 'atom'); + break; + case 'video': + scald_video_scald_fetch($atom, 'atom'); + break; + } + + // For external files, save file to a temporary directory to compare on. + $external_file = 0; + if (strtolower(substr($filename, 0, 4) == 'http')) { + $external_file = 1; + $file_contents = file_get_contents($filename); + $filename = drupal_tempnam('temporary://', 'file'); + file_put_contents($filename, $file_contents); + } + + $new_file_filesize = filesize($filename); + $new_file_md5 = md5_file($filename); + + if ($external_file) { + unlink($filename); + } + + if (filesize($atom->file_source) == $new_file_filesize && + md5_file($atom->file_source) == $new_file_md5 && + $atom->changed == $atom->created) { + + return $sid; + } + } + + return FALSE; +}