LAPS Posted June 13, 2018 Share Posted June 13, 2018 I've set the template protected-pages so that only certain, non-guest user roles have access to view pages. I've also set $config->pagefileSecure = true in the config.php file so to prevents http access to file assets of access protected pages. In the protected-pages template file I use the following sample code (note use of check_access=0): $protected_pages = $pages->find("template=protected-pages, check_access=0, title~=somewords"); foreach($protected_pages as $protected_page) { echo $protected_page->title . "<br>"; echo "<img src='$protected_page->image->url' alt='$protected_page->image->description' />"; } The above code shows to guests the page title (as expected) but not the image. I would like to allow guests to access not only page titles but also image files of protected pages, and just for this occasion. Is it possible (maybe just switching pagefileSecure settings on/off at runtime)? If so, how can I make that? 1 Link to comment Share on other sites More sharing options...
Tom. Posted June 13, 2018 Share Posted June 13, 2018 Hi LAPS, Sorry if I'm not following here, but have you tried: $protected_pages = $pages->find("template=protected-pages, title~=somewords"); foreach($protected_pages as $protected_page) { echo $protected_page->title . "<br>"; echo "<img src='{$protected_page->image->url}' alt='{$protected_page->image->description}' />"; } Instead? Link to comment Share on other sites More sharing options...
LAPS Posted June 13, 2018 Author Share Posted June 13, 2018 @Tom. it works the same by using and not using '{' and '}' in the img tag. As you guessed, the problem still remains. Thanks anyway. Link to comment Share on other sites More sharing options...
Tom. Posted June 13, 2018 Share Posted June 13, 2018 Hi @LAPS Can you copy some of the HTML that is being output to the users? Mainly what the img tag is outputting Link to comment Share on other sites More sharing options...
LAPS Posted June 13, 2018 Author Share Posted June 13, 2018 @Tom. certainly! Here it is when rendering one image: somewords<br> <img src="/site/assets/files/1258/image.jpg" alt="img description"> The problem is that the image is not accessible probably because it is protected by PW even if I use check_access=0. Note: I edited the original post adding the check_access=0 in the selector for finding protected pages. Link to comment Share on other sites More sharing options...
dragan Posted June 13, 2018 Share Posted June 13, 2018 I've never used pagefileSecure, but you could try temporarily to add permission with $permissions->add("name") or similar. 1 Link to comment Share on other sites More sharing options...
LAPS Posted June 13, 2018 Author Share Posted June 13, 2018 4 minutes ago, dragan said: I've never used pagefileSecure, but you could try temporarily to add permission with $permissions->add("name") or similar. How can I make that (even though I think it's not the best solution since the check_access=0 should work also for accessing files ?)? Link to comment Share on other sites More sharing options...
BitPoet Posted June 13, 2018 Share Posted June 13, 2018 1 hour ago, LAPS said: How can I make that (even though I think it's not the best solution since the check_access=0 should work also for accessing files ?)? That's likely not going to be trivial. Adding check_access=0 in a selector to display the link is quite another thing as serving the secure file to a guest user. When you have pageFileSecure enabled, the following happens: PW prefixes the file directory site/assets/files/[PAGEID] with $config->pagefileSecurePathPrefix ("-" by default so it will be site/assets/files/-[PAGEID]) When the browsers tries to show the image (i.e. open the URL /path/to/pw/site/assets/files/1258/image.jpg in a separate request), the file isn't found by .htaccess .htaccess hands off the request to index.php index.php calls PageRender::execute with the request URL PageRender::execute checks if the request is to a file, then checks if the page it belongs to is published and viewable by the current user Since $user->hasPermission('page-view', $page) returns false (the guest user doesn't have view permissions) that fails (otherwise, PW would prefix the path now and output the file) PW outputs the 404 page Since the method where the check is are done is not hookable (and some necessary properties and methods are protected, i.e. not reachable from a hook) you'd probably have to hook before ProcessPageView::execute and duplicate a lot of code from ProcessPageView or hook after User::hasPagePermission and at least duplicate ProcessPageView::checkRequestFile in both cases, match the file URL to $page->image to prevent handing out a access to other file/image fields on the page Another approach (if the images aren't too big and the protected pages aren't too many) would be to include the real image data as data URIs: <?php foreach($protected_pages as $protected_page) { echo $protected_page->title . "<br>"; $fn = $protected_page->image->filename; $imgdata = "data:" . mime_content_type($fn) . ";base64," . base64_encode(file_get_contents($fn)); echo "<img src='$imgdata' alt='{$protected_page->image->description}' />"; } If the images are small enough but you have many pages, using PW's pagination might be an option too. 7 1 Link to comment Share on other sites More sharing options...
Noel Boss Posted June 13, 2018 Share Posted June 13, 2018 38 minutes ago, BitPoet said: Another approach (if the images aren't too big and the protected pages aren't too many) would be to include the real image data as data URIs: <?php foreach($protected_pages as $protected_page) { echo $protected_page->title . "<br>"; $fn = $protected_page->image->filename; $imgdata = "data:" . mime_content_type($fn) . ";base64," . base64_encode(file_get_contents($fn)); echo "<img src='$imgdata' alt='{$protected_page->image->description}' />"; } If the images are small enough but you have many pages, using PW's pagination might be an option too. Very nice solution – i had the same issue with user profile pictures … this could work… On one of my pages I have a similar setup, I provide protected files using the page and the filename and then manually serving it using the render hook… Would need to look into the code… Something like > pathtothepage/?f=filename.jpg – because you know the page, you can access the file with PageFilesManager ($page->filesManager) and then send it using http://processwire.com/api/ref/wire-http/send-file/ 2 Link to comment Share on other sites More sharing options...
BitPoet Posted June 13, 2018 Share Posted June 13, 2018 2 minutes ago, Noel Boss said: On one of my pages I have a similar setup, I provide protected files using the page and the filename and then manually serving it using the render hook… Would need to look into the code… Something like > pathtothepage/?f=filename.jpg Actually, you wouldn't even have to pass the filename. If you assemble the image URL like this, you could just as well use a unique parameter that tells your hook to output the image contained in whatever field you want and can stop worrying about exposing the wrong file. Like {$page->url}?showprofileimage=1. Link to comment Share on other sites More sharing options...
LAPS Posted June 13, 2018 Author Share Posted June 13, 2018 Thanks for the replies. @BitPoet your code works. It'd be correct if the check_access=0 handles/supports access to files too. What do you think about? Could it be an inbuilt PW feature? @ryan Link to comment Share on other sites More sharing options...
Noel Boss Posted June 14, 2018 Share Posted June 14, 2018 14 hours ago, BitPoet said: Actually, you wouldn't even have to pass the filename. If you assemble the image URL like this, you could just as well use a unique parameter that tells your hook to output the image contained in whatever field you want and can stop worrying about exposing the wrong file. Like {$page->url}?showprofileimage=1. I have multiple files on said page and inside repeaters, so this does not work… Link to comment Share on other sites More sharing options...
LAPS Posted December 29, 2018 Author Share Posted December 29, 2018 On 6/13/2018 at 5:22 PM, dragan said: I've never used pagefileSecure, but you could try temporarily to add permission with $permissions->add("name") or similar. On 6/13/2018 at 5:23 PM, LAPS said: How can I make that (even though I think it's not the best solution since the check_access=0 should work also for accessing files ?)? Any news on the @dragan approach? I also created a dedicated topic. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now