Created
September 29, 2020 06:45
-
-
Save johnalarcon/8fd8626027d34748b066d1b532c50341 to your computer and use it in GitHub Desktop.
Extract full plugin details from README.md in a typical ClassicPress plugin.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace CodePotent\Readme2Complete; | |
// Usage | |
$readme_file = 'https://gist.githubusercontent.com/johnalarcon/c19d3111dc73578a3fe224084e2194ec/raw/9a9facfc849e915851fd99cbb6495ded9904340a/README.md'; | |
$readme_lines = file($readme_file); | |
$readme_array = parse_readme($readme_lines); | |
// Result | |
echo '<h3>Extract Details from README.md</h3>'; | |
echo '<p><strong>Source</strong>: <a href="'.$readme_file.'">'.$readme_file.'</a></p>'; | |
echo '<p><strong>Result</strong>:</p>'; | |
echo '<pre>'; | |
print_r($readme_array); | |
echo '</pre>'; | |
/** | |
* Get headers whitelist | |
* | |
* This function returns an array used for finding and whitelisting the many | |
* fields that might be found in a plugin's header. | |
* | |
*/ | |
function get_header_whitelist() { | |
return [ | |
'name:', | |
'description:', | |
'version:', | |
'text domain:', | |
'domain path:', | |
'requires php:', | |
'requires:', | |
'tested:', | |
'author:', | |
'author uri:', | |
'plugin uri:', | |
'download link:', | |
'theme uri:', | |
'donate link:', | |
'license:', | |
'license uri:', | |
'tags:', | |
]; | |
} | |
/** | |
* Get sections whitelist | |
* | |
* This function returns an array used for finding and whitelisting a select | |
* number of the sections that may be present in a plugin's README.md file. | |
* | |
*/ | |
function get_section_whitelist() { | |
return [ | |
'description' => 'description', | |
'faq' => 'frequently asked questions', | |
'installation' => 'installation', | |
'screenshots' => 'screenshots', | |
'reviews' => 'reviews', | |
'other_notes' => 'other notes', | |
'changelog' => 'changelog', | |
'upgrade_notice' => 'upgrade notice', | |
]; | |
} | |
/** | |
* Get header data. | |
* | |
* This function extracts many values from the header section of a README.md | |
* file as it would be wri | |
* the most common values from the header section of values that are often present in | |
* found in a plugin. | |
* in a CLassicPress plugin | |
* header section. The data is coming in as an array of lines. | |
* | |
* @param array $lines Scalar array of lines read from file. | |
* | |
* @return array The data from the endpoint's header section. | |
* | |
*/ | |
function get_header(&$lines) { | |
// Initialize return variable. | |
$header = []; | |
// Line, please?! | |
foreach ($lines as $k=>$line) { | |
// Trim up the right side. | |
$line = rtrim($line); | |
// Assign trimmed value back to orginal array. | |
$lines[$k] = $line; | |
// Grab the plugin name: === Plugin Name === | |
if (strpos(strtolower($line), '===') === 0) { | |
// Remove === and spaces; then unset from original array. | |
$header['name'] = trim(str_replace('===', '', $line)); | |
unset($lines[$k]); | |
} | |
// Other values to check for in the header; lowercase; with colon. | |
$header_properties = get_header_whitelist(); | |
// Iterate over $header_properties to check if they are in $line. | |
foreach ($header_properties as $str) { | |
// If $line is relevant, capture as k/v pair; unset from original array. | |
$key = str_replace(' ', '_', substr($str, 0, strlen($str)-1)); | |
$value = trim(substr($line, strlen($str))); | |
if (strpos(strtolower($line), $str) === 0) { | |
$header[$key] = $value; | |
unset($lines[$k]); | |
} | |
} | |
} // foreach $lines | |
// Return the now-arrayed, header properties. | |
return $header; | |
} | |
/** | |
* Get data for whitelisted sections | |
* | |
* | |
* | |
* @param array $lines | |
* @return array[][] | |
*/ | |
function get_sections(&$lines) { | |
// Particular sections of interest. | |
$natural_sections = get_section_whitelist(); | |
// Throw my thing down, flip it, and reverse it. ~ Missy Elliot | |
$inverse_sections = array_flip($natural_sections); | |
// Initialization. | |
$sections = []; | |
// Flag. | |
$started = false; | |
// Iterate over lines. | |
foreach ($lines as $line) { | |
// Check flag; skip everything until a section is reached. | |
if (!$started && strpos($line, '==') !== 0) { | |
continue; | |
} | |
// Capture headings. | |
if (strpos($line, '==') === 0) { | |
// Ok, we're started...raise the flag! | |
$started = true; | |
// Capture the heading. | |
$heading = trim(str_replace('==', '', strtolower($line))); | |
// Capture only the whitelisted headings. | |
if (!empty($inverse_sections[$heading])) { | |
$sections[$inverse_sections[$heading]] = []; // Nope, remove it. | |
} else { | |
$sections[$heading][] = $heading; // Yep, whitelisted. | |
} | |
// The line was a heading; no need to go further; continue. | |
continue; | |
} | |
/** | |
* If here, the line is part of the last-found $heading array and should | |
* be stored as $sections[$heading][] | |
*/ | |
if (!empty($inverse_sections[$heading])) { | |
$sections[$inverse_sections[$heading]][] = $line; | |
} else { | |
$sections[$heading][] = $line; | |
} | |
} | |
// Remove any unexpected sections. | |
foreach (array_keys($sections) as $heading) { | |
if (empty($natural_sections[$heading])) { | |
unset($sections[$heading]); | |
} | |
} | |
// Return the sections data. | |
return $sections; | |
} | |
/** | |
* Parse file into data array. | |
* | |
* @param array $lines Scalar array of lines from a README.md file. | |
* | |
* @return array[][] Array representing sections and lines in the file. | |
* | |
*/ | |
function parse_readme($lines) { | |
// Initialize the return variable. | |
$data = []; | |
// Extract header data; alters $lines; passed by reference. | |
$header = get_header($lines); | |
// Extract sectional data; alters $lines; passed by reference. | |
$sections = get_sections($lines); | |
// NOT IN README. Unique identifier; ie, my-plugin-dir/my-plugin-file.php | |
$data['identifier'] = ''; | |
// NOT IN README. Plugin directory name. | |
$data['slug'] = dirname($data['identifier']); | |
// Display name for the plugin. | |
$data['name'] = !empty($header['name']) ? $header['name'] : ''; | |
// Plugin short description. | |
$data['description'] = !empty($sections['description']) ? $sections['description'] : ''; | |
// Plugin version; ie, 1.2.3 | |
$data['version'] = !empty($header['version']) ? $header['version'] : ''; | |
// Text domain; ie, my-plugin-name | |
$data['text_domain'] = !empty($header['text_domain']) ? $header['text_domain'] : ''; | |
// Text domain path; ie, /languages | |
$data['domain_path'] = !empty($header['domain_path']) ? $header['domain_path'] : ''; | |
// Minimum PHP requirement; ie, 5.6, or 7, or 7.2, etc | |
$data['requires_php'] = !empty($header['requires_php']) ? $header['requires_php'] : ''; | |
// Minimum ClassicPress requirement; ie, 1.1.1 | |
$data['requires'] = !empty($header['requires']) ? $header['requires'] : ''; | |
// Maximum ClassicPress compatibility; ie, 1.1.1 | |
$data['tested'] = !empty($header['tested']) ? $header['tested'] : ''; | |
// Author URL string. | |
$data['author'] = ''; | |
if (!empty($header['author_uri']) && !empty($header['author'])) { | |
$data['author'] = '<a href="'.$header['author_uri'].'">'.$header['author'].'</a>'; | |
} | |
// Author URL. | |
$data['author_uri'] = !empty($header['author_uri']) ? $header['author_uri'] : ''; | |
// Plugin home page URI. | |
$data['plugin_uri'] = !empty($header['plugin_uri']) ? $header['plugin_uri'] : ''; | |
// Direct link to download file. | |
$data['download_link'] = !empty($header['download_link']) ? $header['download_link'] : ''; | |
// Donation link; ie, https://pay.me/?now-would-be-nice | |
$data['donate_link'] = !empty($header['donate_link']) ? $header['donate_link'] : ''; | |
// License; ie, GPL v2 | |
$data['license'] = !empty($header['license']) ? $header['license'] : ''; | |
// License URL; ie, https://somesite.com/licence.html | |
$data['license_uri'] = !empty($header['license_uri']) ? $header['license_uri'] : ''; | |
// NOT IN README. Last update; ie, 2019-12-16 15:02:08 | |
$data['last_updated'] = ''; | |
// NOT IN README. Release date; ie, 2019-12-16 15:02:08 | |
$data['added'] = ''; | |
// Since the sections array is bigger, put it at the end. | |
$data['sections'] = $sections; | |
// And that's a wrap! | |
return $data; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment