1

my function below works error free when viewing the frontend of the website. But causes a fatal error when i login to the admin area. The errors say that it can no longer find the folder.

//req all the php files in current & sub dirs.
function req_php_files($filepath) {
    $Directory = new RecursiveDirectoryIterator($filepath);
    $Iterator = new RecursiveIteratorIterator($Directory);
    $Regex = new RegexIterator($Iterator, '/^.+\.php$/i', RecursiveRegexIterator::GET_MATCH);

    $php_files = array();

    foreach ($Regex as $file) {
        array_push($php_files, $file[0]);
    }
    foreach ($php_files as $req_file) {
        require_once $req_file;
    }
}
req_php_files('wp-content/themes/vac3/acf');

PHP Fatal error: Uncaught exception 'UnexpectedValueException' with message 'RecursiveDirectoryIterator::__construct(wp-content/themes/vac3/acf): failed to open dir: No such file or directory' in /Applications/MAMP/htdocs/vac3/wp-content/themes/vac3/functions.php:177

Why does this function work on the front end of the site but I'm not when I log into admin?

1

I think the problem is with your relative path. When you visit the /wp-admin/, it will try to locate the wp-content/themes/vac3/acf within and it doesn't find it there. Try instead the full path with help of __DIR__ or get_template_directory() – more details in this blog post. What if you later remove the acf/ subdirectory? You might want to check it's existence with is_dir(). Also you might want to use the FilesystemIterator (the parent class) constants and use FilesystemIterator::SKIP_DOTS to skip . and .. pointers and FilesystemIterator::FOLLOW_SYMLINKS (PHP v5.3.1+) to … follow symlinks. You might also want to use FilesystemIterator::CURRENT_AS_PATHNAME to avoid returning objects when you just need the path to files.

If you don't need this on the backend you could hook it to the front-end or use the ! is_admin() check within your hook. You should also take care of only loading this where needed. I also wonder if this should be a plugin? Then there are alternatives like autoloading.

The normal thing to do is to wrap everything up in a callback attached to some filter or hook. Example:

// Use the proper filter – below just as example
add_filter( 'wp_loaded', function() {

    // Only serve for public requests
    if ( is_admin() )
        return;

    $Iterator = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator( get_template_directory().'/acf' )
    );
    $Regex = new RegexIterator(
        $Iterator, 
        '/^.+\.php$/i', 
        RecursiveRegexIterator::GET_MATCH
    );

    foreach ( $Regex as $file )
        require_once $file[0];
} );

Even better would be if you just use the FilesystemIterator in case you only have a single folder to require files from – non recursively:

add_action( 'wp_loaded', function() {

    if ( is_admin() )
        return;

    $files = new \FilesystemIterator( 
        get_template_directory().'/acf', 
        \FilesystemIterator::SKIP_DOTS
        | FilesystemIterator::FOLLOW_SYMLINKS
        | FilesystemIterator::CURRENT_AS_PATHNAME
    );

    foreach ( $files as $file )
    {
        /** @noinspection PhpIncludeInspection */
        ! $files->isDir() and include $files->getRealPath();
    }
} );
  • Thanks @kaiser for extending the tiny answer ;-) Good working examples and shows how the predefined constants can be helpful. I wonder if we need is_dir() check on the get_template_directory().'/acf' path before feeding it into RecursiveDirectoryIterator or FilesystemIterator. ? I played with this recently and if I recall correctly this was need for non-existent directories, but that might be wrongly recalled ;-) – birgire Apr 6 '16 at 15:02
  • np :) – Ad directories ) The 2nd part is mostly explanatory and not meant to work. Why would one FOLLOW_SYMLINKS, but ! $files->is_dir()? Doesn't make any sense and should only explain possibilities (mostly because recursive dir question). And yes, ignoring directories is indeed needed. Btw, you can check against $files->getType() as well and should get file/link/dir in return according to the docs. Of course, you can also set up the it to return SplFileInfo with FilesystemIterator::CURRENT_AS_FILEINFO to make things real fun. – kaiser Apr 6 '16 at 15:15
  • 1
    it looks like you have written a great answer in the comments as well ;-) yes that SplFileInfo approach sound exiting, ... thanks for all that info, will check out your link, just on my way to the kindergarten now ;-) @kaiser – birgire Apr 6 '16 at 15:43
  • 1
    np, maybe you can ask a new question when you are researching further and show what you find as follow up. And btw, I thought you are a bit older. Pretty impressive knowledge … for a 5-year old! :D – kaiser Apr 6 '16 at 15:45
  • 1
    hahaha lol - let's see what happens ;-) Some days I feel like my WordPress progress + understanding is that of a 5 year old, but then again I think most 5-year old kids nowadays have much better english knowledge than I will ever have ;-) @kaiser – birgire Apr 6 '16 at 20:11

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.