How can I make this function dynamic based on directory traversal of an explicitly referenced, known folder?
The script below is designed to take each folder defined as "WIDGET" and iterate over its files, loading their contents into the database as a widget object.
It works fine, however, as you can see below, for every folder inside of the widget folder that I want to execute this routine against, I have to create a separate branch of nearly identical code, seeding the DEFINE statement with the hard-coded path to the folder that contains the widget contents for that widget object. For example, the foldername (WIDGET) and the $sidebar_id for that widget object (which are the same).
Since I'm naming my folders inside the "widgets" directory, the same as my registered "widgets" in the database, I'd like to convert this routine into a dynamic one that loops over the directories inside the "widgets" folder and for each folder it finds, executes the code starting with the DEFINE statement.
How would I convert this to a single routine that executes for any folder inside of "widgets" folder?
//Install Wigets
$sidebars_widgets = get_option('sidebars_widgets');
$widget_id = count($opts)+1;
$widget_ops = get_option('widget_text');
//1st Widget Area
//make this directory pointer dynamic based on which folder under widgets we are currently working on
DEFINE ('WIDGET', ABSPATH.'/wp-content/plugins/myplugin/widgets/home-header-area/');
$directory_widgets = new DirectoryIterator(WIDGET);
foreach ($directory_widgets as $files_widgets) {
if ($files_widgets->isFile()) {
$file_name_widget = $files_widgets->getFilename();
$widget_text = file_get_contents(WIDGET. $file_name_widget);
$sidebar_id = 'home-header-widget'; //make this dynamic based on the current foldername in the loop
$sidebars_widgets[$sidebar_id] = array("text-".$widget_id);
$widget_ops[$widget_id] = array('title' => $files_widgets->getBasename('.txt'),'text' => $widget_text,);
update_option('widget_text', $widget_ops);
update_option('sidebars_widgets', $sidebars_widgets);
}
}
//2nd Widget Area
//make this directory pointer dynamic based on which folder under widgets we are currently working on
DEFINE ('WIDGET', ABSPATH.'/wp-content/plugins/myplugin/widgets/inside-header-area/');
$directory_widgets = new DirectoryIterator(WIDGET);
foreach ($directory_widgets as $files_widgets) {
if ($files_widgets->isFile()) {
$file_name_widget = $files_widgets->getFilename();
$widge开发者_JS百科t_text = file_get_contents(WIDGETS. $file_name_widget);
$sidebar_id = 'inside-header-widget'; //make this dynamic based on the current foldername in the loop
$sidebars_widgets[$sidebar_id] = array("text-".$widget_id);
$widget_ops[$widget_id] = array('title' => $files_widgets->getBasename('.txt'),'text' => $widget_text,);
update_option('widget_text', $widget_ops);
update_option('sidebars_widgets', $sidebars_widgets);
}
}
Updated Code with Charles answer:
$base = dirname(__FILE__).'/widgets/';
$rdi = new RecursiveDirectoryIterator($base);
foreach(new RecursiveIteratorIterator($rdi) as $files_widgets)
{
if ($files_widgets->isFile())
{
$file_name_widget = $files_widgets->getFilename();
$widget_text = file_get_contents($base . [current directory?] .$file_name_widget);
//NOT SURE IF THIS IS IT OR NOT. I NEED THE CURRENT PARENT DIRECTORY'S NAME
$sidebar_id = $files_widgets->getBasename(); //make this dynamic based on the current foldername in the loop
$sidebars_widgets[$sidebar_id] = array("text-".$widget_id);
$widget_ops[$widget_id] = array('title' => $files_widgets->getBasename('.txt'),'text' => $widget_text,);
update_option('widget_text', $widget_ops);
update_option('sidebars_widgets', $sidebars_widgets);
}
}
How would I convert this to a single routine that executes for any folder inside of "widgets" folder?
Well, you're already using DirectoryIterator
, so it's probably safe for you to consider RecursiveDirectoryIterator
. It can be used to iterate over every filesystem object in a given parent directory and all of the subdirectories it contains.
$base = '/path/to/whatever';
$rdi = new RecursiveDirectoryIterator($base);
foreach(new RecursiveIteratorIterator($rdi) as $files_widgets) {
// Your same foreach contents go here.
}
Just stop using the constant in favor of a variable. I used $base
in the example.
if I'm only expecting the $base folder to have one generation of child folders (no further nesting of folders), do I still need the RecursiveDirectoryIterator?
Do you need it? No, but you can still make use of it. For example, if you only ever want to deal with the first level, then you can set the depth of the recursion at the iterator level:
$rdi = new RecursiveDirectoryIterator($base);
$rii = new RecursiveIteratorIterator($rdi);
$rii->setMaxDepth(1); // Or 2? I dunno, actually.
foreach($rii as $files_widgets) {
// Your same foreach contents go here.
}
How do I obtain a reference to the current folder name while in the loop iterating over its files?
In the loop, $files_widgets
is a SplFileInfo, so you should be able to get the directory in which the file lives by inspecting getPathname()
or getRealPath()
depending on what you need.
精彩评论