Link to home
Start Free TrialLog in
Avatar of GileadIT
GileadITFlag for United States of America

asked on

PHP - Find all files in a UNC Directory

I am attempting to make a plugin for WordPress for our company Intranet that will automatically scan a directory on our file server and return all files as hyperlinks. Our setup is windows based with IIS with the app pool set to use a domain account which has full access to the directories being accessed.

The code I have so far is as follows (found online - can I provide a link?):
function findfiles($atts = [], $content = null) {

    // normalize attribute keys, lowercase

    $atts = array_change_key_case((array)$atts, CASE_LOWER);

    // override default attributes with user attributes

    $atts = shortcode_atts(['department' => 'nothing', 'title' => 'nothing'], $atts);

    $directory = "//adama/shared/Intranet Documents/" . $atts['department'];
    $output = "<div class=gv-gcs-title>" . $atts['title'] . "</div>";
    $files = glob($directory . "*.*");

    foreach ($files as $file)
        {
        echo "<a target=_blank href='File:///$file'>".basename($file)."</a><br>";
        }
}

Open in new window


The issue I am having is that the statement
$files = glob($directory . "*.*");

Open in new window

returns 0. I'm not sure what I am doing wrong with it or if the issue is a permissions issue. If it were permissions I would expect an "access denied" message but I also know that is not a given.

Any help would be appreciated - Thanks, Joe
Avatar of Jim Riddles
Jim Riddles
Flag of United States of America image

The glob function returns false on error...which could be why it returns 0.

Have you verified that your directory path is correct?  I see that you included a "//" at the beginning of your directory variable, but use "/" between each folder after that.
Do you have a slash after the department?

$directory = "//adama/shared/Intranet Documents/" . $atts['department'];

Open in new window


The string would result in something that looks like this if the department was accounting.

//adama/shared/Intranet Documents/accounting*.*
Avatar of GileadIT

ASKER

Hey Jim & Jeff,
Thanks for replying. Jeff, you are right about the trailing /, I added it but got the same affect. Jim, I would think the code would be incorrect with the path I am using. A unc is \\server\share which I tried first but had terrible issues with \ escaping. Then as luck would have it, I found an article with a guy wanting to do a similar thing but he used forward slashes instead of backslashes so no escaping ;-). I never thought it would have worked but he states that it was working. Who am I to judge, so I am now using it. For all I know I am totally wrong. Here is the article - https://stackoverflow.com/questions/10312502/php-extract-only-the-filename-from-unc-path
This page http://php.net/manual/en/function.glob.php says that 'glob' doesn't work on remote file systems.
Dave,

Does that apply here?  It seems like a UNC path would be available to the server's filesystem.
Dave could very well be right. the UNC path is accessible by the server but the server's file system would not. I'm going to start fiddling with is_dir() and opendir()
This has never worked in all the similar questions over the years.  You say that you are operating under "a domain account" but in my experience you are really operating under the IUSR account when it is from a web page on the web server.  The IUSR account is very restricted and isn't allowed access to other systems.
If that's the case then this is one of the few languages to stop you from doing it. I'm pretty optimistic.
It is not the language, it is the IIS software and user.  Other questions used ASP and ASP.NET and they didn't work either when run as web pages thru the web server.  Now obviously you can write a program (that is Not a web page) that can access the other systems.  IIS blocks it as a security feature.  What you might be able to do is write a helper program that PHP can call that runs under a local or admin user that can access the other systems and leave the info for your PHP code to read.

PS: Apache and probably nGinx also do the same thing.  This is to prevent malicious users from getting accidental access to the other systems.
We use it in asp.net and I've gotten it to work in asp. Like I said, I'm optimistic. There is a way and I will find it.
I think that Dave may be on to something regarding the IIS User.

However, when I run this from the command line it works.

The server "myserver" is a different server on the same network.

<?php

 $directory = "//myserver/myshare/datastage/20170804/*.*";

    $files = glob($directory);

    foreach ($files as $file)
        {
        echo basename($file)."\n";
        }

Open in new window

The question is how did you use it in asp.net and ASP.  As Jeff points out above, PHP on the command line does not have the same restrictions that you see when running thru the web server.
return all files as hyperlinks
I'm wondering what you're expecting when people click on the links.  You can't edit or run most things thru a web browser.  You don't get read/write access thru a browser either.  You won't get this method to work like Sharepoint.
ASKER CERTIFIED SOLUTION
Avatar of GileadIT
GileadIT
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Just a heads up, got the script working using opendir(). After working through this and reading through anything I could find on the Internet, I found that the permissions for the pool identity was not the trick for my development environment.

Our development environment uses anonymous authentication while our production environment uses windows authentication. The production environment will just use the permissions of the user to access the files. In development though, you need to change the anonymous authentication to use a specific domain account with access to the files. Once this was changed the script worked. Below is the working script. It still needs some adjustment to create an actual hyperlink but it does list the files in the directory.

function findfiles($atts = [], $content = null) {

    // normalize attribute keys, lowercase

    $atts = array_change_key_case((array)$atts, CASE_LOWER);

    // override default attributes with user attributes

    $atts = shortcode_atts(['department' => 'nothing', 'title' => 'nothing'], $atts);

    $directory = "//adama/shared/intranet_documents/" . $atts['department'] . '/';
    $output = "<div class=gv-gcs-title>" . $atts['title'] . "</div>";
    

    if (is_dir($directory)) {
        if ($dh = opendir($directory)) {
            while (($file = readdir($dh)) !== false) {
                echo "filename: $file : filetype: " . filetype($directory . $file) . "\n";
            }
            closedir($dh);
        }
    }

}

Open in new window

Trying things a different way