In many cases the uploaded files will be images. An automatic thumbnail generation would make sense.

from IRC:
"recrit: commerce_file field can use any file formatters that a file field can - ie image styles of thumbnail, etc..."
[...]
"recrit: commerce_file_field_formatter_info_alter() is where add the commerce_file type to the base file formatters"
[...]
"recrit: i believe image module calls hook_file_download() of the original image on its creation of the derivative (and possibly its hook_field_access)"
[...]
"recrit: then commerce_file_field_access would also need modifying"

CommentFileSizeAuthor
#7 commerce_file_preview-1225760-7.patch2.35 KBdiscipolo

Comments

discipolo’s picture

the first part is easy: adding

$info['image']['field types'][] = COMMERCE_FILE_FIELD_TYPE;
to commerce_file_field_formatter_info_alter(&$info)

yet i cannot find my way around commerce_file_field_access, but i figure it definetly also requires some change to commerce_file_file_download above:

// DENY if no license for the file AND the file is referenced in a commerce_file field

where it should allow a styles preview formatter after checking if it was set. the imagemodule indeed calls file_download() on line 291

// Check the permissions of the original to grant access to this image.
$headers = module_invoke_all('file_download', $original_uri);

i suspect this is where commerce_file hooks in and denies access to the original. which is why the uri in the parameters of commerce_file_file_download is the url to the full image instead of its derivative.

whats the best way to allow access if its a derivative?

discipolo’s picture

1. we do not want to grant access to the originals.
2. we do not want to write our own private file styles to avoid image_file_download.
3. an option would be to use hook_module_implements_alter() to unset image_file_download. (and allow image derivatives through, then if it's not a derivate, call back to image_file_download() yourself and let it do the rest.) [->thanks to catch]

recrit’s picture

i've looked into this to see if there was a way to still use the image formatter but every option that I tried i kept running into access restrictions.
Image module calls hook_file_download() for the original image ONLY on initial creation of the derivative image.
image_style_deliver():
$headers = module_invoke_all('file_download', $image_uri);

Since its only calling for the headers and there is no download of the original file, it would be nice if image module told us that.
Possible solution:
$headers = module_invoke_all('file_download', $image_uri, 'image style creation');
For image module, $request_type could be "image derivative creation" but other modules could set their own as needed.
This would provide a way to handle access restrictions based on why the hook is being called which in commerce_file's case, allow access so that a thumbnail could be built of a protected file.

edit:
I posted a core feature request for this. #1226778: Image style generation file access

discipolo’s picture

no idea why this didnt work before, but i simply had t replace

    // DENY if no license for the file AND the file is referenced in a commerce_file field
    return -1;

with

  // Private file access for image style derivatives.
   if (arg(2) == 'styles') {
	  return;
	  }
	  else{
	  
    // DENY if no license for the file AND the file is referenced in a commerce_file field
    return -1;}
  }

that and adding

$info['image']['field types'][] = COMMERCE_FILE_FIELD_TYPE;
to commerce_file_field_formatter_info_alter(&$info)
will allow download of image derivatives without granting access to the originals just as expected, no idea what i did wrong or whether i am imagining things...

recrit’s picture

@discipolo: detecting with arg(2) == 'styles' would only be true for the Drupal private file system which uses the path "system/files/styles". But it is a solution if the file scheme is private, could add $scheme == 'private'

discipolo’s picture

for the field_access we could add something like

        $bundle_name = $entity->type;
        $field_name = $field['field_name'];
        $finfo = field_info_instance($entity_type, $field_name, $bundle_name);
		if ($finfo['display']['default']['type'] == 'image'){
			return;
	}

around where it says:

// if not on a license, only allow admins of the module or field
edit: actually higher than that due to if (!empty($account->uid))
still have to deal with views though and this only checks the default formatter

discipolo’s picture

StatusFileSize
new2.35 KB

proof of concept
not taken care of views yet. and i totally forgot scheme:private

recrit’s picture

Thanks for the patch. However, its too specific to your use case to be implemented.
To make this more generic, I'm going to add a hook that is called from commerce_file_file_download() in the case of a derivative file being requested for actual download. I still need a way for field_access to allow then... possibly a hook for field_access on a non-license.

mefisto75’s picture

Don't know if my issue is related. What I want is users prior to purchasing images would be able to preview them either in lower resolution or scaled down.
Is that possible? Sorry if hijacking original request.

discipolo’s picture

thats pretty much what this is about

discipolo’s picture

trying to keep up with relevant commits...
Relevant commits

Commerce File: December 19, 2011 14:57
Commit 06d9629 on 7.x-1.x
adding views integration for commerce_file fields to provide the file relationship

Commerce File: December 19, 2011 16:06
Commit a0cecfd on 7.x-1.x
by recrit
adding new display formatter for the commerce_file fields that checks the license view access, if allowed then a link is shown else plain text - this replaces the orginal implementation that altered the existing file formatters

Commerce File: December 19, 2011 20:30
Commit 8dff0ed on 7.x-1.x
by recrit
code refactor to add a 'can_download' function and comment out any denial triggering code until it has been re-worked

Commerce File: January 17, 2012 13:15
Commit 254cdb9 on 7.x-1.x
by recrit
removed field_access to allow showing protected files on the product for non-admins if they have access - this adds too much overhead to a page view and files should only be access edon the uusers files page

how does this proceed?

1. do we have to wait for the core issue Image style generation file access?
2. is Revamp triggering access denied in any way related to the hook mentioned in #8 ?
3. is using a seperate preview file in a normal filefield the only viable soultion? (music download workaround) and if so can this already be done with e.g. rules?
4. is there any other addon module we could build to take care of this? maybe what is needed is some sort of attached entity views solution as a seperate module? (along the lines of http://drupal.org/node/1266132#comment-5672306 )
5. is there anything i missed related to preview of commerce files?

recrit’s picture

Status: Active » Closed (duplicate)

please refer to #1266132: Add to Cart OR Show files formatter for how to create new formatters for Commerce File latest dev (7.x-1.0-beta3+58-dev)

discipolo’s picture

nice!