3

Looking to create a system whereby users can upload print quality images, have them resized for web, but allow admin users to download the contents of a particular node and download the highres images and field texts as a zip archive... what would be a good starting point for this? A particular module? Build a custom module?

3
+50

I put together a proof of concept module real quick, which exports files based on assumptions about field_type (image, file and media).

To test it out, put the following code in a custom module, then go to /export-entity/node/nid to export a node.

<?php

/**
 * Implements hook_menu().
 */
function export_entity_menu() {
  $items['export-entity/%/%entity_object'] = array(
    'page callback' => 'export_entity_page_callback',
    'page arguments' => array(2, 1),
    'load arguments' => array(1),
    'access arguments' => array('access administration pages'),
  );

  return $items;
}

/**
 * Export entity page callback.
 *
 * @param object $entity
 * @param string $entity_type
 *
 * @throws EntityMalformedException
 * @throws EntityMetadataWrapperException
 * @throws Exception
 */
function export_entity_page_callback($entity, $entity_type) {

  $wrapper = entity_metadata_wrapper($entity_type, $entity);
  list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);

  $file_fields = field_read_fields(array(
    'entity_type' => $entity_type,
    'bundle' => $bundle,
    'type' => array('image', 'file', 'media'),
  ));

  $field_files = array();
  foreach ($file_fields as $field_name => $field_config) {
    $files = $wrapper->{$field_name}->value();
    if ((int) $field_config['cardinality'] === 1) {
      $files = array($files);
    }
    foreach ($files as $file) {
      $field_files[$file['fid']][] = $field_name;
    }
  }

  $export_filename = drupal_tempnam(file_directory_temp(), 'entityexport_');

  $zip = new ZipArchive();
  if (!($zip->open($export_filename, ZipArchive::CREATE))) {
    throw new Exception(t('Unable to create zip archive'));
  }

  $entity_data = entity_var_json_export($wrapper->raw());
  $zip->addFromString(sprintf('%s_%d.json', $entity_type, $id), entity_var_json_export($entity_data));

  // Load and attach all files/file entities
  $files = file_load_multiple(array_keys($field_files));
  foreach ($files as $file) {
    $folder = reset($field_files[$file->fid]);
    $file_path = drupal_realpath($file->uri);
    $zip->addFile($file_path, $folder . '/' . $file->filename);
    $zip->addFromString($folder . '/' . $file->filename . '_entity.json', entity_var_json_export($file));
  }
  $zip->close();

  // Copy archive to public storage and redirect to its URL.
  $public_uri = file_default_scheme() . '://entity-export/' . $entity_type;
  file_prepare_directory($public_uri, FILE_CREATE_DIRECTORY);
  $public_uri .= '/' . basename($export_filename) . '.zip';

  $public_path = file_unmanaged_move($export_filename, $public_uri);
  $public_url = file_create_url($public_path);

  drupal_goto($public_url);
}

Note that this should be done using a batch callback and/or a cron-job, especially if you expect to get alot of data - which may cause the script to time out and/or run out of memory (although it really shouldn't).

1
  • Thank you very much for taking the time to put this example together. It is a great starting point. – digitgopher Oct 29 '15 at 20:02
0

pclzip might be a good place to start. It's only in dev for 7, but you could always take a look at the back end and see what they're doing, then use that to write a custom module off of it if it doesn't suit your needs.

1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.