Last active
September 26, 2019 15:31
-
-
Save earth3300/da93a7f84378d61ff6e92cb53e06fb3d to your computer and use it in GitHub Desktop.
Generates a set of valid CSS files from a set of data files.
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 | |
/** | |
* EC01 CSS From Data Printer | |
* | |
* Generates a set of valid CSS files from a set of data files. | |
* These data files have been generated from a set of CSS files | |
* that were created according to media type (i.e. media-all, | |
* media-screen, media-mixed, etc.). Thus they are arranged | |
* differently than the standarized set of CSS files. | |
* | |
* @package Earth3300\EC01 | |
* @since 1.0.0 | |
* @author Clarence J. Bos <cbos@tnoep.ca> | |
* @copyright Copyright (c) 2019, Clarence J. Bos | |
* @license https://www.gnu.org/licenses/gpl-3.0.en.html GPL v3.0 | |
* @link https://gist.github.com/earth3300/da93a7f84378d61ff6e92cb53e06fb3d | |
* | |
* File: printer.css-from-dat.php | |
* Created: 2019-09-16 | |
* Updated: 2019-09-25 | |
* Time: 14:52 EDT | |
* ID: ENG-ON-001 | |
*/ | |
namespace Earth3300\EC01; | |
if( ! defined( 'NDA' ) ) | |
{ | |
define('NDA',true); | |
} | |
/** | |
* Prints a CSS file. | |
*/ | |
class CssPrinter | |
{ | |
/** @var array Default options. */ | |
protected $opts = [ | |
'dev0' => 0, | |
'dev1' => 0, | |
'dev2' => 0, | |
'dev3' => 0, | |
'this' => [ | |
'file' => 'printer.css-from-dat.php', | |
'title' => 'EC01 CSS From Data Printer', | |
'date' => [ | |
'created' => '2019-09-07', | |
], | |
], | |
'dir' => [ | |
'config' => '/0/t/css', | |
'input' => '/0/t/css/dat', | |
'output' => '/0/t/css/dat/src', | |
], | |
'file' => [ | |
'config' => '/css.data.php', | |
'output' => '/style.dat.css', | |
'overwrite' => 1, | |
], | |
'files' => [ | |
'include' => 'all', | |
'exclude' => 'none', | |
], | |
'max' => [ | |
'len' => 3000000, // Bytes | |
], | |
'write' => [ | |
'root' => 0, | |
], | |
'message' => [ | |
'na' => 'Not available.', | |
'write' => [ | |
'denied' => 'Write permission denied.' , | |
'success' => 'Write operation succeeded.', | |
'failure' => 'Write operation failed.', | |
], | |
], | |
]; | |
/** | |
* Init | |
*/ | |
public function init() | |
{ | |
if( $this->security() ) | |
{ | |
$this->authorize(); | |
} | |
} | |
/** | |
* Security | |
*/ | |
private function security() | |
{ | |
if ( '127.0.0.1' == $_SERVER['REMOTE_ADDR'] | |
&& file_exists( __DIR__ . '/.security' ) ) | |
{ | |
return true; | |
} | |
else | |
{ | |
return false; | |
} | |
} | |
/** | |
* Authorize | |
*/ | |
private function authorize() | |
{ | |
if( isset( $_GET['unlock'] ) ) | |
{ | |
echo $this->run(); | |
} | |
else | |
{ | |
echo '<pre>Unauthorized.</pre>' . PHP_EOL; | |
} | |
} | |
/** | |
* Run | |
* | |
* @return string | |
*/ | |
private function run() | |
{ | |
if( isset( $_GET['run'] ) ) | |
{ | |
$file = []; | |
$file = $this->getPageDesc( $file ); | |
$file = $this->getPaths( $file ); | |
$file = $this->getFiles( $file ); | |
if( isset( $file['files'] ) ) | |
{ | |
$file = $this->initFile( $file ); | |
foreach( $file['files'] as $cnt => $item ) | |
{ | |
$item = $this->preProcess( $file, $item ); | |
$item = $this->process( $file, $item ); | |
$file = $this->postProcess( $file, $item ); | |
} | |
// Do this at the end. | |
$file = $this->getPageInfo( $file ); | |
} | |
else | |
{ | |
pre_dump( "Not set: file['files'] " ); | |
pre_dump( $file['files'] ); | |
} | |
$html = $this->getPageHTML( $file ); | |
return $html; | |
} | |
else | |
{ | |
echo '<pre>You wish to run the script?</pre>' . PHP_EOL; | |
} | |
} | |
/** | |
* Get the Description (Purpose) for This File | |
* | |
* @param array $file | |
* | |
* @return array | |
*/ | |
private function getPageDesc( $file ) | |
{ | |
$file['text']['desc'] = ''; | |
$file['text']['desc'] = '<div class="description">'; | |
$file['text']['desc'] .= '<p>Converts CSS saved as a data file to valid CSS.</p>'; | |
$file['text']['desc'] .= '</div>' . PHP_EOL; | |
$file['text']['desc'] .= '<div class="clear"></div>' . PHP_EOL; | |
$file['text']['desc'] .= PHP_EOL; | |
return $file; | |
} | |
/** | |
* Get Info | |
* | |
* Get page level info. | |
* | |
* @param array $file | |
* | |
* @return array | |
*/ | |
private function getPageInfo( $file ) | |
{ | |
$file['text']['info'] = null; | |
$str = ''; | |
if( is_array( $file ) ) | |
{ | |
// Input path | |
$str .= isset( $file['path']['input'] ) ? | |
sprintf( '<br>Input Path: %s<br>%s', | |
$file['path']['input'], PHP_EOL ) : ''; | |
// Count of the files. | |
$str .= isset( $file['cnt'] ) ? | |
sprintf( '<br>Files: %s<br>%s', | |
$file['cnt'], PHP_EOL ) : ''; | |
// Output path | |
$str .= isset( $file['path']['output'] ) ? | |
sprintf( '<br>Output Path: %s<br><br>%s', | |
$file['path']['output'], PHP_EOL ) : ''; | |
} | |
$file['text']['info'] = $str; | |
return $file; | |
} | |
/** | |
* Get the Paths | |
* | |
* @param array $file | |
* | |
* @return array | |
*/ | |
private function getPaths( $file ) | |
{ | |
$path = []; | |
$path['root'] = rtrim( $_SERVER['DOCUMENT_ROOT'], '/' ); | |
$path['path']['config'] = $path['root']; | |
$path['path']['input'] = $path['root']; | |
$path['path']['config'] .= $this->opts['dir']['config']; | |
$path['path']['input'] .= $this->opts['dir']['input']; | |
$path['path']['output'] = $path['root']; | |
$path['path']['output'] .= $this->opts['dir']['output']; | |
$path['file']['config'] = $path['path']['config']; | |
$path['file']['config'] .= $this->opts['file']['config']; | |
return $path; | |
} | |
/** | |
* Pre Process (In the loop) | |
* | |
* @param array $file | |
* @param array $item | |
* | |
* @return array | |
*/ | |
private function preProcess( $file, $item ) | |
{ | |
$item = $this->getFileInfo( $file, $item ); | |
$item = $this->getFileOut( $file, $item ); | |
return $item; | |
} | |
/** | |
* Process | |
* | |
* @param array $file | |
* | |
* @return array | |
*/ | |
private function process( $file, $item ) | |
{ | |
if( is_array( $item ) ) | |
{ | |
$item['error'] = ''; | |
$item['text']['css'] = ''; | |
$item = $this->getFile( $file, $item ); | |
$item = $this->prcFile( $file, $item ); | |
$item = $this->clnFile( $file, $item ); | |
$item = $this->genFile( $file, $item ); | |
} | |
else | |
{ | |
pre_dump( '291: item is not an array' ); | |
} | |
return $item; | |
} | |
/** | |
* Post Process | |
* | |
* @param array $file | |
* @param array $item | |
* | |
* @return array | |
*/ | |
private function postProcess( $file, $item ) | |
{ | |
$file = $this->printFile( $file, $item ); | |
return $file; | |
} | |
/** | |
* Initialize Array | |
* | |
* This occurs in the loop, just as it has started. | |
* | |
* @param array $file | |
* | |
* @return array | |
*/ | |
private function initFile( $file ) | |
{ | |
// Initialize file level variables here. | |
$file['text']['resp'] = null; | |
return $file; | |
} | |
/** | |
* Get the Files | |
* | |
* Get the files using "glob()", and process each file | |
* retrieved to obtain the full file name (with extension) | |
* and the "base" name (without the extension). (*.php). | |
* | |
* @param array $file | |
* | |
* @return array | |
*/ | |
private function getFiles( $file ) | |
{ | |
$files['files'] = null; | |
if( is_dir( $file['path']['input'] ) ) | |
{ | |
$match = $file['path']['input'] . '/*.php'; | |
$items = glob( $match ); | |
// Loop through the files | |
foreach( $items as $cnt => $str ) | |
{ | |
// load the file. | |
if( file_exists( $str ) ) | |
{ | |
require_once( $str ); | |
$file['files'][$cnt]['file']['input'] = $str; | |
} | |
} | |
} | |
else | |
{ | |
pre_dump( "Not a directory: file['path']['input'] " ); | |
} | |
return $file; | |
} | |
/** | |
* Get File Info | |
* | |
* File Level Info | |
* | |
* path, full name (.ext), and base name (no ext). | |
* $files['files'][$cnt] = $this->getFilesInfo( $file, $item ); | |
* | |
* @param $file | |
* @param $items | |
* | |
* @return $item | |
*/ | |
private function getFileInfo( $file, $item ) | |
{ | |
if( isset( $item['file']['input'] ) ) | |
{ | |
$path = pathinfo( $item['file']['input'] ); | |
// name with ext. | |
$item['file']['name'] = $path["basename"]; | |
// name without ext. | |
$item['file']['base'] = $path["filename"]; | |
return $item; | |
} | |
else | |
{ | |
pre_dump( "384: Not set: item['file']['input'] " ); | |
} | |
} | |
/** | |
* Get the Output File Name | |
* | |
* @param array $file | |
* @param array $item | |
* | |
* @return array | |
*/ | |
private function getFileOut( $file, $item ) | |
{ | |
if( isset( $file['path']['output'] ) ) | |
{ | |
$item['file']['output'] = $file['path']['output']; | |
$item['file']['output'] .= '/' . str_replace( | |
'.php', '.css', $item['file']['name'] ); | |
} | |
return $item; | |
} | |
/** | |
* Get File | |
* | |
* In this context, loads the file. | |
* | |
* @param array $file | |
* @param array $item | |
* | |
* @return array | |
*/ | |
private function getFile( $file, $item ) | |
{ | |
if( isset( $item['file']['input'] ) ) | |
{ | |
if( file_exists( $item['file']['input'] ) ) | |
{ | |
require_once( $item['file']['input'] ); | |
} | |
} | |
return $item; | |
} | |
/** | |
* Process File Based on Given List | |
* | |
* @param $file | |
* @param $item | |
* | |
* @return $item | |
*/ | |
private function prcFile( $file, $item ) | |
{ | |
// We can use the file name as a hint as to what function to call. | |
$input = $item['file']['input']; | |
// Have to hard code the function here, because. | |
if( strpos( $input, 'header' ) !== false ) | |
{ | |
$item['data'] = get_00_header_data(); | |
} | |
elseif( strpos( $input, 'bootstrap' ) !== false ) | |
{ | |
$item['data'] = get_01_bootstrap_data(); | |
} | |
elseif( strpos( $input, 'structural' ) !== false ) | |
{ | |
$item['data'] = get_01_structural_data(); | |
} | |
elseif( strpos( $input, 'media-all' ) !== false ) | |
{ | |
$item['data'] = get_02_media_all_data(); | |
} | |
elseif( strpos( $input, 'media-screen' ) !== false ) | |
{ | |
$item['data'] = get_04_media_screen_data(); | |
} | |
elseif( strpos( $input, 'media-all-sprite' ) !== false ) | |
{ | |
$item['data'] = get_03_media_all_sprite_data(); | |
} | |
elseif( strpos( $input, 'media-screen-flex' ) !== false ) | |
{ | |
$item['data'] = get_05_media_screen_flex_data(); | |
} | |
elseif( strpos( $input, 'media-mixed-color' ) !== false ) | |
{ | |
$item['data'] = get_06_media_mixed_color_data(); | |
} | |
elseif( strpos( $input, 'media-screen-menu' ) !== false ) | |
{ | |
$item['data'] = get_06_media_screen_menu_data(); | |
} | |
elseif( strpos( $input, 'media-mixed-sheet' ) !== false ) | |
{ | |
$item['data'] = get_07_media_mixed_sheet_data(); | |
} | |
elseif( strpos( $input, 'media-mixed-adjust' ) !== false ) | |
{ | |
$item['data'] = get_08_media_mixed_adjust_data(); | |
} | |
elseif( strpos( $input, 'media-print' ) !== false ) | |
{ | |
$item['data'] = get_09_media_print_data(); | |
} | |
else | |
{ | |
// Do nothing. | |
} | |
return $item; | |
} | |
/** | |
* Generates the File | |
* | |
* @param array $file | |
* @param array $item | |
* | |
* @return array | |
*/ | |
private function genFile( $file, $item ) | |
{ | |
if( isset( $item['file']['output'] ) ) | |
{ | |
$item['str'] = ''; | |
$item['text']['css'] = ''; | |
$item = $this->getFileHeader( $file, $item ); | |
$item = $this->genCSS( $file, $item ); | |
$item = $this->getFileSize( $file, $item ); | |
$item = $this->getFileFooter( $file, $item ); | |
//Concatenate | |
$item['str'] = $item['text']['head']; | |
$item['str'] .= $item['text']['css']; | |
$item['str'] .= $item['text']['foot']; | |
return $item; | |
} | |
else | |
{ | |
pre_dump( "Not set: item['file']['output'] " ); | |
} | |
} | |
/** | |
* Clean up the File | |
* | |
* Stray brackets and inconsistent formatting. | |
* | |
* @param string $str | |
* | |
* @return string | |
*/ | |
private function clnFile( $file, $item ) | |
{ | |
if( is_string( $item['text']['css'] ) ) | |
{ | |
// Look's good. | |
} | |
else | |
{ | |
pre_dump( "Not set: item['text']['css'] (514)" ); | |
} | |
return $item; | |
} | |
/** | |
* Generate CSS | |
* | |
* Generates valid CSS as a string and returns in an array. | |
* | |
* @param array $file | |
* | |
* @return array | |
*/ | |
private function genCSS( $file, $item ) | |
{ | |
$str = ''; | |
$lev[0] = false; | |
$lev[1] = false; | |
$lev[2] = false; | |
$lev[3] = false; | |
$media[0] = false; | |
pre_dump( $item['data'], 1 ); | |
if( isset( $item['data'] ) ) | |
{ | |
$lev[0] = true; | |
//=============== LEVEL 0 =============== | |
foreach( $item['data'] as $key0 => $val0 ) | |
{ | |
if( strpos( $key0, 'media' ) !== false ) | |
{ | |
$media[0] = true; | |
} | |
$str .= sprintf( ' %s {%s', $key0, PHP_EOL ); | |
if( is_string( $val0 ) ) | |
{ | |
$str .= sprintf( ' %s: %s;%s', $key0, $val0, PHP_EOL ); | |
} | |
else | |
{ | |
$lev[1] = true; | |
//=============== LEVEL 1 =============== | |
foreach( $val0 as $key1 => $val1 ) | |
{ | |
$str .= sprintf( ' %s {%s', $key1, PHP_EOL ); | |
if( is_string( $val1 ) ) | |
{ | |
$str .= sprintf( ' %s: %s;%s', $key1, $val1, PHP_EOL ); | |
} | |
else | |
{ | |
$lev[2] = true; | |
//=============== LEVEL 2 =============== | |
foreach( $val1 as $key2 => $val2 ) | |
{ | |
if( is_string( $val2 ) ) | |
{ | |
$str .= sprintf( ' %s: %s;%s', $key2, $val2, PHP_EOL ); | |
} | |
else | |
{ | |
$lev[3] = true; | |
//=============== LEVEL 3 =============== | |
foreach( $val2 as $key3 => $val3 ) | |
{ | |
$str .= sprintf( ' %s {%s', $key3, PHP_EOL ); | |
if( is_string( $val3 ) ) | |
{ | |
$str .= sprintf( ' %s: %s;%s', $key3, $val3, PHP_EOL ); | |
} | |
} // Loop 3 | |
if( 1 ) | |
{ | |
$str .= ' }' . PHP_EOL . '/* Level 3 */' . PHP_EOL; | |
} | |
} // else | |
} // Loop 2 | |
if( 1 ) | |
{ | |
$str .= ' }' . PHP_EOL . '/* Level 2 */' . PHP_EOL; | |
} | |
} // else | |
} // Loop 1 | |
if( 1 ) | |
{ | |
$str .= ' }' . PHP_EOL . '/* Level 1 */' . PHP_EOL; | |
} | |
} // else | |
} // Loop 0 | |
if( 1 ) | |
{ | |
if( $media[0] ) | |
{ | |
// Extra when no leading level 0. | |
//$str .= ' }' . PHP_EOL . '/* Level 0 */' . PHP_EOL; | |
} | |
} | |
} // End isset data | |
if( 1 ) | |
{ | |
$str .= '/* END DATA */' . PHP_EOL; | |
} | |
$item['text']['css'] = $str; | |
return $item; | |
} | |
/** | |
* Get File Size | |
* | |
* @param array $file | |
* | |
* @return array | |
*/ | |
private function getFileSize( $file, $item ) | |
{ | |
$item['size'] = null; | |
if( isset( $item['text']['css'] ) ) | |
{ | |
$item['text']['size'] = strlen( $item['text']['css'] ) . 'B' . PHP_EOL; | |
} | |
return $item; | |
} | |
/** | |
* Is (In) String (Helper Function) | |
* | |
* @param string $a Haystack | |
* @param string $b Needle | |
* | |
* @return bool | |
*/ | |
function iss( $a, $b ) | |
{ | |
if( is_string( $a ) && is_string( $b ) | |
&& strpos( $a, $b ) !== false ) | |
{ | |
return true; | |
} | |
else | |
{ | |
return false; | |
} | |
} | |
/** | |
* Print the File | |
* | |
* @param array $file | |
* | |
* @return array | |
*/ | |
private function printFile( $file, $item ) | |
{ | |
$str = ''; | |
if ( isset( $_GET['print'] ) ) | |
{ | |
if ( isset( $_POST['safety'] ) ) | |
{ | |
if( isset( $item['file']['output'] ) && isset( $item['str'] ) ) | |
{ | |
if( ! file_exists( $item['file']['output'] ) | |
|| $this->opts['file']['overwrite'] ) | |
{ | |
$resp = file_put_contents( $item['file']['output'], $item['str'] ); | |
$str = sprintf( | |
'File: %s (%s B)<br>%s', $item['file']['output'], $resp, PHP_EOL ); | |
} | |
else | |
{ | |
$str = sprintf( | |
'File: %s (exists)<br>%s', $item['file']['output'], PHP_EOL ); | |
} | |
} | |
} | |
} | |
$file['text']['resp'] .= $str; | |
return $file; | |
} | |
/** | |
* File Header | |
* | |
* @return string | |
*/ | |
private function getFileHeader( $file, $item ) | |
{ | |
// Initialize | |
$str = ''; | |
$str .= '/*' . PHP_EOL; | |
$str .= sprintf( 'File: %s%s', $item['file']['name'], PHP_EOL ); | |
$str .= sprintf( 'Generated by: %s%s', $this->opts['this']['file'], PHP_EOL ); | |
$str .= PHP_EOL; | |
$str .= $this->getTimeStamp(); | |
$str .= $this->getIDStamp(); | |
$str .= '*/' . PHP_EOL; | |
$str .= PHP_EOL; | |
$item['text']['head'] = $str; | |
return $item; | |
} | |
/** | |
* Time Stamp (Including Created Date) | |
* | |
* @return string | |
*/ | |
private function getTimeStamp() | |
{ | |
$str = ''; | |
$str .= sprintf( 'Created: %s%s', | |
$this->opts['this']['date']['created'], PHP_EOL ); | |
$str .= sprintf( 'Updated: %s%s', date( 'Y-m-d' ), PHP_EOL ); | |
$str .= sprintf( 'Time: %s%s', date( 'H:i:s T' ), PHP_EOL ); | |
return $str; | |
} | |
/** | |
* ID Stamp | |
* | |
* @return string | |
*/ | |
private function getIDStamp() | |
{ | |
$str = ''; | |
$str .= 'ID: ENG-ON-001' . PHP_EOL; | |
return $str; | |
} | |
/** | |
* File Footer | |
* | |
* For use at the end of the file as needed. | |
*/ | |
private function getFileFooter( $file, $item ) | |
{ | |
// Initialize | |
$str = ''; | |
$str .= '/*'; | |
$str .= ' End of File ('; | |
$str .= $item['size'] . ' B).'; | |
$str .= ' */' . PHP_EOL; | |
$str .= PHP_EOL; | |
// Add this string to the end... | |
$item['text']['foot'] = $str; | |
return $item; | |
} | |
/** | |
* Get Form | |
* | |
* @return string | |
*/ | |
private function getForm() | |
{ | |
if( isset( $_GET['ctrls'] ) ) | |
{ | |
// Initialize | |
$str = ''; | |
$str .= '<form action="" method="post">' . PHP_EOL; | |
$str .= '<div>' . PHP_EOL; | |
$str .= '<input type="checkbox" name="safety" id="safety" required> ' . PHP_EOL; | |
$str .= '<input type="submit" class="btn btn-primary" value="Run">' . PHP_EOL; | |
$str .= '</div>' . PHP_EOL; | |
$str .= '</form>' . PHP_EOL; | |
return $str; | |
} | |
else | |
{ | |
return false; | |
} | |
} | |
/** | |
* Wrap the HTML in Page HTML `<!DOCTYPE html>`, etc. | |
* | |
* Use basic settings. Assume no SEO necessary. Bootstrap CSS only. | |
* | |
* @param string $html | |
* | |
* @return string|bool | |
*/ | |
private function getPageHTML( $file ) | |
{ | |
$str = '<!DOCTYPE html>' . PHP_EOL; | |
$str .= '<html lang="en-CA" class="theme-dark">' . PHP_EOL; | |
$str .= '<head>' . PHP_EOL; | |
$str .= '<meta charset="UTF-8">' . PHP_EOL; | |
$str .= '<meta name="viewport" content="width=device-width, initial-scale=1"/>' . PHP_EOL; | |
$str .= sprintf( '<title>%s</title>%s', | |
$this->opts['this']['title'], PHP_EOL ); | |
$str .= '<meta name="robots" content="noindex,nofollow" />' . PHP_EOL; | |
$str .= '<link rel=stylesheet href="/style.min.css">' . PHP_EOL; | |
$str .= '</head>' . PHP_EOL; | |
$str .= '<body>' . PHP_EOL; | |
$str .= '<main>' . PHP_EOL; | |
$str .= sprintf( '<h1>%s</h1>%s', $this->opts['this']['title'], PHP_EOL ); | |
$str .= isset( $file['text']['desc'] ) ? $file['text']['desc'] : ''; | |
$str .= $this->getForm(); | |
$str .= isset( $file['text']['info'] ) ? $file['text']['info'] : ''; | |
$str .= isset( $file['text']['resp'] ) ? $file['text']['resp'] : ''; | |
if( isset( $_GET['display'] ) ) | |
{ | |
if( isset( $file['str'] ) ) | |
{ | |
$str .= '<pre>' . PHP_EOL; | |
$str .= $file['str']; | |
$str .= '</pre>' . PHP_EOL; | |
} | |
} | |
$str .= '</main>' . PHP_EOL; | |
$str .= '</html>' . PHP_EOL; | |
return $str; | |
} | |
} // End Class | |
if ( ! function_exists( 'pre_dump' ) ) { | |
/** Dumps a formatted string or array. */ | |
function pre_dump( $arr, $continue = 1 ) { | |
if ( isset( $_GET['debug'] ) ) { | |
if (is_string( $arr ) ) { | |
$arr = str_replace( ['<','>'], ['<','>'], $arr ); | |
} | |
echo "<pre>" . PHP_EOL; | |
var_dump( $arr ); | |
if ( isset( $_GET['exit'] ) || ! $continue ) { | |
exit( '<br/>' . 'Done.' ); | |
} | |
echo "</pre>" . PHP_EOL; | |
} | |
} | |
} | |
function ec01_css_printer() | |
{ | |
$printer = new CssPrinter(); | |
return $printer->init(); | |
} | |
ec01_css_printer(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment