Jump to content

Uploading/saving a file into a file fieldtype on Windows


flydev
 Share

Recommended Posts

Today I ran into an issue while using FieldtypeSecureFile on a Windows 2008 R2 server with an Apache web server, PHP 7.2.1 and ProcessWire 3.0.89 (I am posting here as I think its not an issue with the module itself).

 

Issue description:

I have a script which save a file into a file field (SecureFile) outside the web directory as mentioned in the module readme. The problem is that the directory - the one which has the name of the page ID - isn't created automatically and thus the file can't be copied.  If I create the dir manually, the file is copied successfully.

 

Lets say I have a page ID 723153 which contain a SecureFile field which is configured to save files under this path: C:\DATA

When you add a file then save the page, the following directory/path should be created :  C:\DATA\723153\sekretfile.csv

Instead, I get a warning :

Quote

PHP warning : copy(C:\DATA\723153/sekretfile.csv): failed to open stream: No such file or directory in ...\wire\core\Pagefile.php:157

 

Quote

Storage Location Enter a path outside the web root where the files are stored. You need to create the directory manually. Also make sure that the user running the web server has write permission.

Apache is running under an user which have the right permissions to write to the storage dir. As I said, if I create the "intermediate" directory manually, the file is copied.

 

Note:  everything is working fine on MAMP.

-

I just tested now to upload the file directly trough the backend, the file isn't saved and there are no error or warning.

issue.thumb.gif.1864e305c6b72ac23596c03d8380ccb9.gif

 

I am out of idea, and you ?
 

Edited by flydev
pw version and line
Link to comment
Share on other sites

I just edited the core file Pagefile.php and added on line 157 (pw version 3.0.89) this code :

//if(!copy($filename, $destination)) throw new WireException("Unable to copy: $filename => $destination");
$fileTools = new WireFileTools();
if(!$fileTools->copy($filename, $destination)) throw new WireException("Unable to copy: $filename => $destination");

And... it works...

Should I report something on Github ?

  • Like 4
Link to comment
Share on other sites

Hm, I don't think this is specific to Windows environment since php copy() doesn't create the folder structure. I think pagefile expect that folder is already there. While your mods fix the issue I'm surprised that this isn't spotted by someone before (note: I haven't tried FieldTypeSecureFile).

Link to comment
Share on other sites

14 minutes ago, matjazp said:

I don't think this is specific to Windows environment since php copy() doesn't create the folder structure.

I do not think so either.

The thing is that I don't have any issue on Linux or Mac.

 

Lets ping @Wanze :lol:

Link to comment
Share on other sites

It has do with slashes/backslashes. Wanze is using realpath() function which on windows returns path with backslashes, while WireFileTools->mkdir() assume forward slashes and thus fails to create folder. The solution is simple, something like this in FieldtypeSecureFile.module after line 83:

if(DIRECTORY_SEPARATOR != '/') $storageLocation = str_replace(DIRECTORY_SEPARATOR, '/', $storageLocation);

or

if(DIRECTORY_SEPARATOR != '/') $path = str_replace(DIRECTORY_SEPARATOR, '/', $path);

in WireFileTools.php in mkDir() method. 

I don't know who is "responsible" to deal with that: developer or ProcessWire, so I'm not sure if this is something Ryan should know.

Also, mkDir() method does not create directory structure on windows, even if you specify true for the `$recursive` argument.

  • Like 1
Link to comment
Share on other sites

1 hour ago, matjazp said:

Also, mkDir() method does not create directory structure on windows, even if you specify true for the `$recursive` argument.

It does work here (tested on PHP 7.1, 7.0 and 5.3) both with native mkDir and WireFileTools.

  • Like 1
Link to comment
Share on other sites

I would doublecheck accessrights on C: under windows. If you have a drive with another letter in front, try to use this. Also, it isn't necessary to use backslashes on windows as long as you are inside PHPs functions. (Backslashes are only necessary on the windows commandline, via exec() or system()).

Also I would try a directory downsite the DOCUMENT_ROOT, maybe under /site/assets/files/0. Just to compare if it does work there or not.

Maybe not much of help, but I'm a bit out of ideas.

EDIT: Apache / PHP security setings like opendir / openbasedir restrictions or something?

Edited by horst
  • Like 1
Link to comment
Share on other sites

30 minutes ago, BitPoet said:

It does work here (tested on PHP 7.1, 7.0 and 5.3) both with native mkDir and WireFileTools.

Can you elaborate how you tested? Maybe I'm doing something wrong, staring at the monitor for the whole day ...

Link to comment
Share on other sites

I just ran simple one-liners:

REM Native mkdir
REM ============
REM Default PHP 7.1:
php -r "namespace ProcessWire; include('index.php'); $path = $config->paths->assets . 'test1/1/2/3'; mkdir($path, 0, true);"
REM 7.0:
"C:\Program Files (x86)\PHP\v7.0\php.exe" -r "namespace ProcessWire; include('index.php'); $path = $config->paths->assets . 'test2/1/2/3'; mkdir($path, 0, true);"
REM 5.3:
"C:\Program Files (x86)\PHP\v5.3\php.exe" -r "namespace ProcessWire; include('index.php'); $path = $config->paths->assets . 'test3/1/2/3'; mkdir($path, 0, true);"

REM WireFileTools
REM =============
REM Default PHP 7.1:
php -r "namespace ProcessWire; include('index.php'); $path = $config->paths->assets . 'test4/1/2/3'; $ft = new WireFileTools(); $ft->mkdir($path, true);"
REM 7.0:
"C:\Program Files (x86)\PHP\v7.0\php.exe" -r "namespace ProcessWire; include('index.php'); $path = $config->paths->assets . 'test5/1/2/3'; $ft = new WireFileTools(); $ft->mkdir($path, true);"
REM 5.3:
"C:\Program Files (x86)\PHP\v5.3\php.exe" -r "namespace ProcessWire; include('index.php'); $path = $config->paths->assets . 'test6/1/2/3'; $ft = new WireFileTools(); $ft->mkdir($path, true);"

 

Link to comment
Share on other sites

Thanks for the idea, I tested with and without UAC, same thing happen. And I can confirm that permission are OK as the files are copied by the script only if the dir already exist.

Directories and files in regular site/assets are created/written successfully.

 

This drive me crazzy and I can't live with a modified core file ?

  • Like 1
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...