AnsweredAssumed Answered

fms12_cwp_PHP Documentation for getContainerDataURL using HTML embed Tag does not work

Question asked by tduell_1 on Jul 18, 2012
Latest reply on Aug 23, 2012 by james_quiggins

Summary

fms12_cwp_PHP Documentation for getContainerDataURL using HTML embed Tag does not work

Product

FileMaker Server

Version

12.0

Operating system version

OS X and Windows

Description of the issue

The documentation provided by the fms12_cwp_PHP guide for how to utilize the new getContainerDataURL method for files such as PDF's, mp3's, etc. on page 17 (English version) simply does not work.

$fm=new FileMaker($database, $hostspec, $user, $password);
$findCommand = $fm->newFindCommand($layout);
$findCommand->addFindCriterion('type', 'pdf');
$result = $findCommand->execute();
$records = $result->getRecords();
foreach ($records as $record) {
echo $record->getField('container').'
';
// For movies and PDF files, use the HTML embed tag
echo '
getContainerDataURL($record->getField('container')) .'">';
break;
}

Mostly what I want to get out of this bug report is for FileMaker to provided fully tested documentation, examples, and sample files that work as intended to showcase the new method. I consider this to be a major new feature to the API and the examples should have been updated to use the new code, not provide snippets of code that were assumed to work, which end up with a lot of troubleshooting on the developer's end.

Steps to reproduce the problem

1. You have to URL encode the path to the container field. Therefore, the code should look something like:

echo '
getContainerDataURL(urlencode($record->getField('container'))) .'">';

2. The embed tag does not work to display the content for images or files on Firefox 14.0, Safari 5.1.5, or Chrome 20.0. If you point the embed src URL to a valid path to a file stored in the root of your web site it works. However, the getContainerDataURL method is actually returning an XML call to the database as the URL. So I don't believe the embed src likes the path returned by the API. For example, this is what the getContainerDataURL returns:

http://127.0.0.1/fmi/xml/cnt/Container_Fields_in_FMP12_en.pdf?-db=PHPExternalContainers&-lay=Demo&-recid=21&-field=ExternalContainer(1)

Whereas, if you use a path like this, it's fine:

http://127.0.0.1/Container/MyDocument.pdf

Of course you can't provide a path to the file stored on the server because FileMaker Server is storing the files outside the root. So Even if you know the actual path to the file you can't use it. I would be interested to know exactly how the WPE is providing a file outside the root to the web server.

Expected result

1. The getContainerDataURL method definitely works for externally stored images - jpg, gif, png.

2. The getContainerDataURL method definitely DOES NOT work for externally stored files - pdf, mp3, .mov, etc.

3. The example documentation makes it appear as if you no longer need the containerBridge.php file. You still need this file for it to send the correct header based on the file type! I also noticed that the sample code in the API Tutorial is changed very slightly, but uses all the old code. The "new" tutorial files do not use the getContainerDataURL method and the containerBridge.php file has some major omissions to get the getContainerDataURL method to work. User's should still be utilizing the FMS 11 containerBridge.php file if they want the getContainerDataURL method to work correctly.

Actual result

1. If you use the embed tag with this method you get either the broken image icon on your web page or the missing plugin icon for files.

Workaround

1. There is a work around. However, it's not perfect either. You can use the iframe tag instead of the embed tag. It works fine on Safari and Chrome. I have not gotten around to testing it on IE yet. Firefox on the other hand is a major problem. It requires Acrobat Reader 10 to be installed as well as the PDF Viewer add on (plugin) to be installed. Good luck getting your external web users to have all of that installed! It took me 2 days to figure out why Firefox refused to use iframe. I will have a sample solution posted in the FileMaker section of our web site at formulationspro.com shortly. In the mean time You can try using the following sample code:

I have a database called PHPExternalContainers with the field ExternalContainer that obviously stores the images and files externally. It uses the containerBridge.php file return the content from the container field — the same as FMS 11 PHP API and earlier.

phpcontainer.php

<?php
// Connect to the database
require_once ('FileMaker.php');
$fm = new FileMaker();
$fm->setProperty('database', 'PHPExternalContainers');
$fm->setProperty('username', 'Admin');
$fm->setProperty('password', '1234');

// Find the record
$request = $fm->newFindAllCommand('Demo');
$result = $request->execute();
$record = $result->getFirstRecord();

// Display the container as an images.
echo 'Externally Stored File
Path: ' . $fm->getContainerDataURL($record->getField('ExternalContainer')) . '
';
echo 'getContainerDataURL(urlencode($record->getField('ExternalContainer'))) . '">';

// Display the container as a file using iframe.
echo '';
?>


You still need the containerBridge.php file to process the header correctly for the image or file.

containerBridge.php

<?php
// Connect to the database
require_once ('FileMaker.php');
$fm = new FileMaker();
$fm->setProperty('database', 'PHPExternalContainers');
$fm->setProperty('username', 'Admin');
$fm->setProperty('password', '1234');


//This is a bridge script that calls FileMaker::getContainerData with the provided url.   
if (isset($_GET['path'])){
     $url = $_GET['path'];
     $url = substr($url, 0, strpos($url, "?"));
     $url = substr($url, strrpos($url, ".") + 1);
     if($url == "jpg"){
          header('Content-type: image/jpeg');
     }
     else if($url == "gif"){
          header('Content-type: image/gif');
     }
     else if($url == "png"){
          header('Content-type: image/png');
     }     
     else if($url == "pdf"){
          header('Content-type: application/pdf');
     }     
     else{
          header('Content-type: application/octet-stream');
     }
     echo $fm->getContainerData($_GET['path']);
}

?>

Outcomes