Drupal file information, filling the URL information for Services
When working with Drupal as a backend for mobile applications, and serving the information via RESTful services, it is important to limit the number of needed requests from the site to the minimum.
Unfortunately, sometimes Drupal makes things harder.
In this case, the site content included image files. The main idea is to download the content of the site, save it in a local sqlite database, and provide it to the mobile user from it. This way the user can keep using the application in offline, when he has no connectivity.
Regarding to image files, the idea is to download them as well in the background, and show them in the application when they are available.
When working with Drupal 6, this was easy - when we used an imagefield CCK, we got the URL of the image and just download it. In Drupal 7, with the image and the file field, we got into a problem: instead of a full path, all we get when we load a node is a URI with a schema - "public://" in our case.
The reasons for this is clear, but when retrieving the data from another place (mobile app, 3rd party, etc.), those kind of schemas means nothing. While Drupal provides the needed function to retrieve the full path, without calling it the data is useless.
One solution could have been to add a new services REST method that will just call file_create_url($path) and send it back, but this would have require another call per file, which was a heavy overhead.
Another solution could have been just using the existing Services file resource, so instead of downloading the file directly, we would have used the file id (fid) and retrieve the file and its extended data. The main reason for not doing it is the existing client side code we already have that knows nicely to download files and images in the background. Rewriting it due to Drupal changes would have been a mess as well.
The solution, like always, comes from Drupal itself.
First of all, when looking into files in Drupal, we found out file is an entity. This is great, since this means a file field in one entity actually calls another entity, and it is kind of "magic reference".
We thought about using the hooks around entity_load, or the hook_field_load, but in the end we found what we needed - hook_file_load.
Bottom line - after adding some configuration form in the right spot, we created a 30 lines module that do exactly what we needed, and voila - we have the full_url value for each file we need.
Some coding, documentation, and the new "Full URL file information" module is released.
P.S. - you need to clear cache in order to make the module to kick in...
Hope this will be useful for others as well.
Regards,
Shushu
Ralates to: Drupal Planet