You are here

function attachment_links_retrieve in Attachment Links 7

Same name and namespace in other branches
  1. 6 attachment_links.module \attachment_links_retrieve()

Menu callback to fetch the reqested file for the given node.

1 string reference to 'attachment_links_retrieve'
attachment_links_menu in ./attachment_links.module
Implements hook_menu().

File

./attachment_links.module, line 249

Code

function attachment_links_retrieve($node, $type) {

  // Make sure that attachment links are enabled for a field on this node type.
  $file_field_name = variable_get('attachment_links_selection_' . $node->type, 0);
  if (!$file_field_name) {
    return MENU_NOT_FOUND;
  }

  // Grab the files from the current node for the selected field.
  $files = field_get_items('node', $node, $file_field_name);

  // If we have files, continue, else return 404.
  if (!empty($files)) {
    switch ($type) {
      case 'authoritative':

        // Return the first element of the array, which is the 'highest' one.
        $file = reset($files);
        $uri = $file['uri'];
        break;
      case 'newest':

        // Get the newest item by timestamp. In the case of multiple timestamps
        // being equal, the 'highest' one will be selected. The handy part is
        // that the array returned by field_get_items is already in weight order,
        // with key 0 being the lightest.
        $max_timestamp = 0;
        foreach ($files as $key => $file) {
          if ($file['timestamp'] > $max_timestamp) {
            $max_timestamp = $file['timestamp'];
            $max_key = $key;
          }
        }
        $uri = $files[$max_key]['uri'];
        break;
    }

    // We check for public, and redirect to the file path in that case. In the
    // case of private, we start serving the file in the current request instead
    // of redirecting, this saves resources and is useful when we have an alias
    // for the file path.
    $scheme = file_uri_scheme($uri);
    if ($scheme == 'public') {
      $file_url = file_create_url($uri);
      drupal_goto($file_url);
    }
    else {
      if ($scheme == 'private') {

        // Serve the file from private files.
        if ($wrapper = file_stream_wrapper_get_instance_by_uri($uri)) {

          // Unfortunately we have to do this str_replace nonsense because the
          // function that we want to call (getTarget) is protected in the stream
          // wrapper.
          $file_url = $wrapper
            ->getExternalUrl();
          $file_url = str_replace(url('system/files/', array(
            'absolute' => TRUE,
          )), '', $file_url);

          // The file_url will have URL entities encoded, but file_download()
          // expects a real filename. Decode first (i.e. turn "%20" into " ")
          $file_url = urldecode($file_url);
          $args = explode('/', $file_url);
          array_unshift($args, 'private');

          // Need to send the filename since we aren't redirecting to a file
          // but sending the stream directly. file_download() will handle sending
          // the MIME type and other necessaryt headers.
          header('Content-Disposition: attachment; filename="' . end($args) . '"');

          // This calls the menu callback for private files directly, ensuring that
          // all access permissions are taken care of.
          call_user_func_array('file_download', $args);
        }
      }
      else {
        return MENU_NOT_FOUND;
      }
    }
  }
  else {
    return MENU_NOT_FOUND;
  }
}