2

I know drupal_realpath is depreciated but as far as I can tell I cannot avoid using it.

I have a little module that will unzip a file and search the contents of the unzipped file and create content with the images it finds. In order to search the unzipped directory tree I need to rely on standard php methods will not work with paths like 'public://..." so I need to use drupal_realpath to massage my paths into something drupal can handle.

When I actually create the image file I do not want to use the drupal realpath because this would obviously be problematic if I migrated to a different server.

Is there a way I can turn the realpath which will look something like this:

/Applications/MAMP/htdocs/drupal/sites/default/files/my_file.png

back into something like:

public://my_file.png

If not is there some way I can search a directory structure without using drupal_realpath?

EDIT: So it seems that my problem may really only be with certain PHP lirbaries for example simpleXML.

$shape_xml = 'public://Arcade Projects/ender2012/AgentCubes/Open Arcade/Moonsweeper/version8/Moonsweeper/agents/Tutorial/shapes/Tutorial/shape.xml';

watchdog("file exists normal",file_exists($shape_xml));
watchdog("file exists real path",file_exists(drupal_realpath($shape_xml)));

In the above example, both watchdogs print 1, so it seems that file_exists works fine with the drupal path or the realpath.

But, if I call simplexml_load_file with the drupal_realpath like this:

$xml = simplexml_load_file(drupal_realpath($shape_xml));

everything works fine.

But If I call it like this:

$xml = simplexml_load_file($shape_xml);

I get the following error:

Notice: Trying to get property of non-object in harvest_icons() (line 775 of /Applications/MAMP/htdocs/drupal/sites/all/modules/custom/unzip/unzip.module).
  • It seems your problem is not converting from /Applications/MAMP/htdocs/drupal/sites/default/files/my_file.png to public://my_file.png, but vice versa. /Applications/MAMP/htdocs/drupal/sites/default/files/my_file.png is understood from all the functions handling files, while public://my_file.png is understood from a restricted number of functions. – kiamlaluno Jun 18 '12 at 22:22
  • @kiamlaluno: correct, I can get "/Applications/MAMP/htdocs/drupal/sites/default/files/my_file.png" from drupal_realpath but I have no way to get back to "public://my_file.png", sorry if this was not clear in my question. – Mike2012 Jun 18 '12 at 22:28
3

It's not pretty but this will reverse engineer such a path quite reliably:

$old_path = '/Applications/MAMP/htdocs/drupal/sites/default/files/my_file.png';

$doc_root = $_SERVER['DOCUMENT_ROOT'] . '/';

$public_file_path = variable_get('file_public_path', 'sites/default/files') . '/';

$replace = array($doc_root, $public_file_path);

$new_path = 'public://' . str_replace($replace, '', $old_path);
|improve this answer|||||
  • Okay thanks a lot Clive I'll try out your code. That is pretty wicked and seeing code like that makes me think I am doing this all wrong? Is there any other way that wouldn't use the drupal_realpath? Or am I just doing something far outside of the normal drupal use case? – Mike2012 Jun 18 '12 at 22:47
  • It's tricky to say without seeing the whole code; am I understanding it right that you need to create a file, and that you're finding the need to use an absolute path to do so? If so, what function are you using to create the file? As @Berdir says, stream wrappers are a PHP feature and all file manipulation functions that I can think of should work fine with them – Clive Jun 18 '12 at 22:52
  • 1
    @Mike2012 This is the code to convert an absolute local path to a path starting with public://. The problem I see is that normally there isn't any need to make such conversion, as Drupal is able to handle absolute local paths. – kiamlaluno Jun 18 '12 at 22:57
  • Yep, what @kiamlaluno said. The above code will work, but it's nasty and I can't think of a reason why you'd need to use it – Clive Jun 18 '12 at 23:01
  • @clive I'm not actually creating a file. My module works with a .zip file that has been unzipped and contains nested directories. Inside some of these directories there are .xml file and .png files. I need to create content types that contain fields that will be populated by the xml and png files and I also will need to pull the title of the node I am creating out of the xml file and I am using simpleXMl to parse out attributes from the xml file. – Mike2012 Jun 18 '12 at 23:06
2

Stream wrappers are a PHP feature. You can use a path like public:// with normal PHP functions like fopen().

|improve this answer|||||
  • Thanks you for your response, it seems that what you said is true for normal PHP functions like fopen and file_exists, but what can be done in other cases like the one mentioned in my edit? – Mike2012 Jun 18 '12 at 22:19
  • 1
    @Mike2012 Since you know the path is a stream wrapper path you can just grab the code out of drupal_realpath() and use that: if ($wrapper = file_stream_wrapper_get_instance_by_uri($uri)) { return $wrapper->realpath(); } – Clive Jun 18 '12 at 22:26
  • @Clive sorry I'm a bit confused by this. How would the code from drupal_realpath help convert it back into the "public://" formatted path? – Mike2012 Jun 18 '12 at 22:39
  • @Mike2012 Think I'm just getting confused too, I've had a stab at an answer let me know how it works out – Clive Jun 18 '12 at 22:43
1

Here's my code

$purl= drupal_realpath('public://');
$filepath = file_build_uri(str_replace($purl, '', drupal_realpath($image_relative_path . '/' . $file['filename'])));

where $image_relative_path is something like sites/default/files/mydirectory

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.