9 Replies Latest reply on Feb 1, 2014 4:40 AM by TimDietrich

    CWP PHP Beginner Question: File Upload Methodologies

    steve_ssh

      Hello Everyone,

       

       

      Background to this post:

       

      I am beginning my studies of CWP with the FM PHP API, and right now I am at the level of a rank amatuer.

       

      So far the resources that I am learning from are:

       

      - The Formulations Pro book by Todd Duell

      - The FMS12 CWP with PHP Guide by FMI

      - Posts on this forum

       

      The version of FMS that I am learning with is FMS 12; I'm using the development license key, and running my dev environment on an older version of OSX (10.6.8), as a single machine deployment.

       

       

       

      Background to the question:

       

      I note that in the CWP PHP API guide there is the following statement:

       

      "When you publish a database using the Web Publishing Engine, the following limitations apply to container field objects: Web users cannot modify or add to the contents of container fields. Web users cannot use container fields to upload objects to the database."

       

       

       

      Question:

       

      Supposing I were to desire to allow users of a CWP/PHP web app to upload files to be stored in a container field in some FM table:

       

      The options that I see are as follows:

       

      1) Have the PHP script receive the uploaded file, scan it for appropriate size and content, and then relocate the file to a directory where FMS would have permissions to grab the file locally using the file:// protocol and the Insert From Url script step.

       

      2) Have the PHP script receive the uploaded file, scan it for appropriate size and content, and then store the file somewhere where the webserver could serve the file to FMS, and FMS would access the file using http:// or https:// protocol and the Insert From Url script step. (I'm not fond of this option, as it opens a security concern of making sure that only FMS will be served the file, but I'm thinking that perhaps someone has done this in the case of a deployment where the webserver is on a separate machine, and the FMS server is locked down, i.e. no access via something like scp.)

       

      3) Change my mind, and not store the content within a container field, and instead utilize something like SuperContainer.

       

       

       

      Am I thinking about this sensibly and accurately, or are there other parts of the picture that I am not seeing?


       

      Note that this is not for a practical application as much as it is for me to learn the lay of the land and find out what the common practices are in this territory which is new to me. As such, I don't have any theoretical values to toss out for how much data would need to be stored. Mostly I would like to check in with the CWP pros on the forum and find out if I am thinking along the lines of standard practice, or if I am completely not getting it, and if the latter, what topics I should be looking into regarding this particular topic.

       

      Any comments from those willing to share their experience would be much appreciated.

       

      Many thanks and best regards,

       

      -steve

       

      p.s. By and large, the world of CWP and PHP looks like it will be an enjoyable environment to work within. Thanks for helping me get off to a good start!

        • 1. Re: CWP PHP Beginner Question: File Upload Methodologies
          user21485

          Steve,

          I guess it depends on file types you are expecting to be uploaded and what use is to be made of the files within Filemaker. In FM12 I used PHP to upload image files and create thumbs, and store them in a separate folder at the same time I populated two text fields one with the file URL and the other with the thumb URL. Then I used  web viewer in my layouts to display the thumb images.

           

          Que

          • 2. Re: CWP PHP Beginner Question: File Upload Methodologies
            beverly

            I also prefer the 'relative path' and URL for display of images (web viewer) method, but that may also depend the images/files are intended for web viewing/downloading (on website) rather than storage in container field.  You can protect a directory from outside entry, if security is a concern. And use PHP to get the image/file, rather than just display the direct url to it - you can add a check on session (login) to see if the image/file is available for a particular user.

             

            Otherwise if it needs to be IN a container field, SuperContainer works well!

            • 3. Re: CWP PHP Beginner Question: File Upload Methodologies
              tduell

              If you check "Lesson 12: Upload File" in FileMaker API for PHP A Proactical Guide for Creating Database Drive Web Sites with FileMaker Pro 12 and FileMaker Server 12, this is the best practices to upload a file to the database. I cannot stress enough that for web enabled solutions you should not be storing the contentent in a container field. FMS will take an enourmous performance hit to display that content on the web. Store your files externally and use a text field with the path to the file. As mentioned in the previous responses, you can use a web viewer for local FileMaker Pro users if you need them to have access to the file. Otherwsise if you really, really, want to spend the time and the money to put the file in a container field you can use Super Container or Troi File Plugin to move the file. You can do that with the script running on the server — "Lession 17 Run a Script" will get you the basics for how to run a script on the server from your PHP web page after you've completed the upload.

              • 4. Re: CWP PHP Beginner Question: File Upload Methodologies
                mbraendle

                Quentins solution is the one I had also implemented in one of my solutions.

                 

                Another option is to use the JDBC/ODBC interface - have never tried this -, which allows to write container fields using an SQL INSERT statement. See FileMaker ODBC and JDBC Guide, and the following slides (especially slide 16) on JDBC to get an idea:

                 

                http://de.slideshare.net/fmkonferenz/fmk2012-filemaker-und-java-und-es-offnen-sich-neue-welten-von-bernhard-schulz

                 

                 

                Similar statements also exist in PHP for an ODBC connection:

                 

                http://www.php.net/manual/en/book.uodbc.php

                • 5. Re: CWP PHP Beginner Question: File Upload Methodologies
                  steve_ssh

                  Thank you to everyone for the replies to this post.

                   

                  Quentin, Beverly, Martin, and Todd:

                   

                  I value advice from each of you very much.  Thanks for taking the time to share some of your experience.

                   

                  It seems as though consensus is that uploading to a container field is not the common practice, and moreover is best to be avoided if the intention is to serve such data back to users via CWP.  This is good to know, and I will take it to heart.

                   

                  @Beverly and Quentin:  Thanks for providing a few of the details concerning how you might go about this situation.

                   

                  @Martin - Thanks for suggesting the JDBC option.  I will probably not go that route any time soon, but I will have a look, and I appreciate you opening my eyes to that possibility.

                   

                  @Todd - The step-by-step format of your book (along with the sample code) is a very easy format to learn by.  Thanks!

                   

                   

                  Very best to all,

                   

                  -steve

                  • 6. Re: CWP PHP Beginner Question: File Upload Methodologies
                    TimDietrich

                    Steve --

                     

                    I'm a little late to this thread, but anyway...

                     

                    The process that you originally described (upload a file, evaluate it, move it to a location that you can get to via a URL, and then use and then "Insert From URL" to grab it) is pretty much how FMWebFrame's "FMPutContainer" function works.

                     

                    FMWebFrame also includes functions that make it easy to publish container contents using relatively-decent looking URLs.

                     

                    If you're interested, the demo app lets you upload a file, and then it returns a URL that you can use to view / download it: http://demo.fmwebframe.com/pages/container-upload.php

                     

                    Hope this helps.

                     

                    -- Tim

                    • 7. Re: CWP PHP Beginner Question: File Upload Methodologies
                      steve_ssh

                      Hi Tim,

                       

                      Many sincere thanks for your input.  I have been very interested to check out FmWebFrame, both to see the functionality that it makes available for use in projects that I might undertake, as well as to study the code and see how someone such as yourself implements the functionality.  My delay in checking out the framework thus far has been only so that I could build up enough familiarity with CWP and the PHP API to have enough of a starting background before checking it out.  I expect I'll be digging into it before the end of February, and I look forward to that very much.

                       

                      Thanks both for developing the framework and for making it available to other developers.

                       

                      With appreciation,

                       

                      -steve

                      • 8. Re: CWP PHP Beginner Question: File Upload Methodologies
                        tduell

                        I beleive the crux to the solution from FMPutContainer is very simple. If I combine it with the concept from my book you get this:

                         

                        1. Once you upload the file to your web server upload directory you can either insert the path into a text field or send a script parameter with the path to a script on the server. You'll need to know the following minimum parameters to make this work:

                         

                        a. RecordID of the record where the file or image will be inserted into the database.

                        b. The name and extension of the file that was uploaded - whether it be the original name and extension or the RecordID as I specify in my book.

                         

                        For example 1234.png

                         

                        c. The full URL path to the upload folder, which should be known since you are the web developer!

                         

                        For example http://www.mycompany.com/upload/

                         

                        If it was me, I would send a single script parameter with the RecordID and the extension because I would get both pieces of information I need in one script parameter and it's easy enough to parse apart to get what I need in the FileMaker Script. My book example does create variables for both the file name and the extension. You could repurpose those variables when you send your script parameter as well.

                         

                        2. Once you call the script you will find the record in the table. Then use the Insert From URL function to grab the file from the web server (via the full URL path) and insert it into the container field.

                         

                        Your URL path will need to be a fully qualified path such as http://www.mycompany.com/upload/1234.png. Since each upload script will be specific for each container field you'll know the full path on the web server. Then you can combine the image/file name and it should work. Here's what the server script would look like:

                         

                        Enter Find Mode

                        Set Field (RecordID; Get(ScriptParameter)) (Note, you'll need a field in the database that auto enters the RecordID value so you can find the record)

                        Perform Find

                        (Trap for errors if you want i.e. no records found would stop the script)

                        Insert From URL [Select; No Dialog; ContainerField; "http://www.mycompany.com/upload/1234.png"] (Note, you'll need to concatenate the actual URL path here)

                        Commit Records/Requests [Skip data entry validation, No dialog]

                         

                        This is a nice alternative to using the Troi plugin to try to move the file on the server. It completely avoids any need to deal with security on the server that may block you from moving files or gaining access to web server directories without changing the file permissions, which is a PITA to deal with. The only downfall is the web server does take an extra performance hit. But, when the process is free and avoids a lot of server permissions problems, it's certainly worth it in my mind. Hopefully you don't have a whole bunch of these uploads in your system :-)

                        • 9. Re: CWP PHP Beginner Question: File Upload Methodologies
                          TimDietrich

                          Todd --

                           

                          What makes fmPutContainer different is that it is a function, so it can be used to upload a file to any container field in any table. In other words, it isn't hard-wired to a specific database / layout / field.

                           

                          To use it, you pass it the FileMaker connection object, the name of the container field and name of a layout that it appears on, the record object (for the record that the file is to be saved to), and the uploaded file handle.

                           

                          For example:

                           

                          fmPutContainer (

                             $fmDemo,

                             'Resource - Form',

                             'Resource',

                             $uploaded_record,

                             $_FILES['uploaded_file']

                          );

                           

                          That's really all there is to it - fmPutContainer does the rest.

                           

                          -- Tim