1

I am creating a WordPress plugin which allows a user to apply sorting rules to a particular template (page, archive, single etc). I am populating list of pages using PHP scandir like so:

$files = scandir(get_template_directory());

The problem is that I keep single.php templates in a '/single' subfolder so these templates are not being called by the above function.

How can I use multiple directories within the scandir function (perhaps an array?) or will I need a different solution?

So basically I am trying to:

$files  =   scandir( get_template_directory() AND get_template_directory().'/single' );

My current solution (not very elegant as it requires 2 for each loops):

        function query_caller_is_template_file_get_template_files()
            {
                $template_files_list    =   array();

                $files          =   scandir(get_template_directory());
                $singlefiles    =   scandir(get_template_directory().'/single');

                foreach($files  as  $file)
                    {
                        if(strpos($file, '.php')    === FALSE)
                            continue;

                        $template_files_list[]  =   $file;
                    }

                foreach($singlefiles  as  $singlefile)
                    {
                        if(strpos($file, '.php')    === FALSE)
                            continue;

                        $template_files_list[]  =   $singlefile;
                    }

                return $template_files_list;
            }
  • Are you looking for http://stackoverflow.com/questions/14304935/php-listing-all-directories-and-sub-directories-recursively-in-drop-down-menu ? – Gwendal Feb 05 '16 at 14:03
  • I'm not entirely sure without a little experimenting, have not really used scandir before. –  Feb 05 '16 at 14:08
  • [scandir](http://php.net/manual/en/function.scandir.php) returns you an array, so you could combine those two arrays and iterate through its single elements. Edit: `array_merge` should do the trick. – Matthias W. Feb 05 '16 at 14:23
  • This should do it: `$files = array_merge( glob( get_template_directory() . "/*.php" ), glob( get_template_directory() . "/single/*.php" ) );` – Gerald Schneider Feb 05 '16 at 14:23
  • @GeraldSchneider Nice solution, only problem is this is returning the entire path of the files, I need just the filename –  Feb 05 '16 at 14:27
  • `$files = array_map( "basename", array_merge( ... ) )` – Gerald Schneider Feb 05 '16 at 14:32
  • @GeraldSchneider thank you so much! want to write as an answer and I will accept.. –  Feb 05 '16 at 14:35
  • I don't see any point in posting it as an answer, your question is of topic for this site anyway. This page is for help with programming errors, but you want to improve working code. There is a special site on the SE network for that, called [codereview.se]. – Gerald Schneider Feb 05 '16 at 14:52

1 Answers1

0

First, there's not really anything wrong about what you're doing. You have two directories, so you do the same thing twice. Of course you could make it look a little cleaner and avoid the blatant copy paste:

$files = array_merge(
    scandir(get_template_directory()),
    scandir(get_template_directory().'/single')
);

Now just iterate over the single array.

In your case, getting the file list recursively doesn't make sense, as there may be subdirectories you don't want to check. If you did want to recurse into subdirectories, opendir() and readdir() along with is_dir() would allow you to build a recursive scan function.

You could event tighten up the '.php' filter part a bit with array_filter().

$files = array_filter($files, function($file){
    return strpos($file, '.php');
});

Here I'm assuming that should a file start with .php you're not really interested in it making your list (as strpos() will return the falsy value of 0 in that case). I'm also assuming that you're sure there will be no files that have .php in the middle somewhere.

Like, template.php.bak, because you'll be using version control for something like that.

If however there is the chance of that, you may want to tighten up your check a bit to ensure the .php is at the end of the filename.

Tim Lytle
  • 17,549
  • 10
  • 60
  • 91