JasonDavis JasonDavis - 3 months ago 21
PHP Question

PHP RegEx to read header comment data from file and add multiple matches to an array

I am building my own plugin system for adding new "Project Media Types" to my WordPress Projects Portfolio Plugin.

I am using the

WP_List_Table
WP Class to create a list of Project Media Type Plugins and allow manaing them by installling, activating, disabling, and deleting each of them.

enter image description here

My code scans a directory using PHP to detect valid Project Media Type Plugins

Each file it finds in this preset folder it then reads the header comment data of the file just like real WordPress plugins do to get information about the plugin.

Below is my function which scans the directory and reads the header comment data from each matching file into PHP variables when a match is detected...

public function get_project_media_types_in_file_system ($from_folder = PLUGINS_FOLDER)
{

if ($handle = opendir($from_folder)) {

while ($file = readdir($handle)) {
echo $file.'rrrrrrr<hr>';
if (is_file($from_folder . $file)) {

if (strpos($from_folder . $file, '.php')) {
$fp = fopen($from_folder . $file, 'r');
// Pull only the first 8kiB of the file in.
$plugin_data = fread($fp, 8192);
fclose($fp);
preg_match('|Project Media Type Name:(.*)$|mi', $plugin_data, $project_media_type_name);
preg_match('|Version:(.*)|i', $plugin_data, $version);
preg_match('|Description:(.*)$|mi', $plugin_data, $description);
preg_match('|Admin Selector Image:(.*)$|mi', $plugin_data, $admin_selector_image);
preg_match('|Screenshot Image 1:(.*)$|mi', $plugin_data, $screenshot_image_1);
preg_match('|Screenshot Image 2:(.*)$|mi', $plugin_data, $screenshot_image_2);
preg_match('|Author:(.*)$|mi', $plugin_data, $author_name);
preg_match('|Author Email:(.*)$|mi', $plugin_data, $author_email);
preg_match('|Author URI:(.*)$|mi', $plugin_data, $author_uri);

foreach (array(
'project_media_type_name' ,
'version' ,
'description',
'admin_selector_image',
'screenshot_image_1',
'screenshot_image_2',
'author_name',
'author_email',
'author_uri'
) as $field) {
if (! empty(${$field})){
${$field} = trim(${$field}[1]);
}else{
${$field} = '';
}
}

$project_media_type_plugin_data = array(
'file_name' => $file,
'project_media_type_name' => $project_media_type_name,
'class_name' => $project_media_type_name,
'title' => $project_media_type_name,
'description' => $description,
'version' => $version,
'admin_selector_image' => $admin_selector_image,
'screenshot_image_1' => $screenshot_image_1,
'screenshot_image_2' => $screenshot_image_2,
'author_name' => $author_name,
'author_email' => $author_email,
'author_uri' => $author_uri,
'installed' => 'no',
'active' => 0

);
$this->project_media_type_plugin_headers[] = $project_media_type_plugin_data;
}
} else{
if ((is_dir($from_folder . $file)) && (substr($file,0,1) != '.')) {
$this->get_project_media_types_in_file_system($from_folder . $file . '/');
}
}

}
closedir($handle);
}
return $this->project_media_type_plugin_headers;
}





The line with this code:

preg_match('|Screenshot Image 1:(.*)$|mi', $plugin_data, $screenshot_image_1);


is followed by another similar line with the number 1 changed to number 2.

My goal now is to modify this code to make it look for
Screenshot Image
instead of
Screenshot Image 1
or
Screenshot Image 2


I want to be able to have any number of lines with
Screenshot Image
and have it add each matching line to an array so that a plugin can have as many images as they like.




Currently this is the format of a plugin header:

<?php
/**
* Project Media Type Name: coverflow slider Test Plugin
* Version: 2.0.0
* Description: coverflow slider Test Plugin description
* Admin Selector Image: https://www.apollowebstudio.com/screenshots/2016/ApplicationFrameHost_2016-07-28_14-39-46.png
* Screenshot Image 1: https://www.apollowebstudio.com/screenshots/2016/Books-Animation.gif
* Screenshot Image 2: https://www.apollowebstudio.com/screenshots/2016/2013-05-20_23-11-40.png
* Author: Jason Davis
* Author Email: jason.davis.fl@gmail.com
* Author URI: https://www.apollowebstudio.com
*/


With the new version it wouyld be able to look like this below and each image would be added to an array instead of a variable with a single string:

<?php
/**
* Project Media Type Name: coverflow slider Test Plugin
* Version: 2.0.0
* Description: coverflow slider Test Plugin description
* Admin Selector Image: https://www.apollowebstudio.com/screenshots/2016/ApplicationFrameHost_2016-07-28_14-39-46.png
* Screenshot Image: https://www.apollowebstudio.com/screenshots/2016/Books-Animation.gif
* Screenshot Image: https://www.apollowebstudio.com/screenshots/2016/2013-05-20_23-11-40.png
* Screenshot Image: https://www.apollowebstudio.com/screenshots/2016/Books-Animation3.gif
* Screenshot Image: https://www.apollowebstudio.com/screenshots/2016/Books-Animation4.gif
* Author: Jason Davis
* Author Email: jason.davis.fl@gmail.com
* Author URI: https://www.apollowebstudio.com
*/





Any help appreciated

Answer

You can solve that with an easy regex like this:

preg_match('|Screenshot Image \d+:(.*)$|mi', $plugin_data, $screenshot_image_1);

Bear in mind that $screenshot_image_1 will be overridden if you use it multiple times.

Maybe you should change it to preg_match_all instead for this case which will store in an array all the matches.

preg_match_all('|Screenshot Image \d+:(.*)$|mi', $plugin_data, $screenshot_image_matches);

Regex demo

IDE One demo