Last active
September 18, 2019 04:18
-
-
Save earth3300/78d5e020899782efd6f160553de08ef3 to your computer and use it in GitHub Desktop.
Prints CSS files from a set of data arrays.
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 Printer (from Data) | |
* | |
* Prints CSS files from a set of data arrays. | |
* | |
* @package Earth3300\EC01 | |
* @since 1.0.1 | |
* @author Clarence J. Bos <cbos@tnoep.ca> | |
* @copyright Copyright (c) 2018, Clarence J. Bos | |
* @license https://www.gnu.org/licenses/gpl-3.0.en.html GPL v3.0 | |
* @link https://gist.github.com/earth3300/78d5e020899782efd6f160553de08ef3 | |
* | |
* File: printer.css-dat.php | |
* Created: 2019-09-16 | |
* Updated: 2019-09-17 | |
* Time: 16:35 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 = [ | |
'this' => [ | |
'file' => 'printer.css-dat.php', | |
'title' => 'EC01 CSS Printer', | |
'date' => [ | |
'created' => '2019-09-07', | |
], | |
], | |
'dir' => [ | |
'config' => '/0/t/css', | |
'input' => '/0/t/css/dat', | |
'output' => '/0/t/css/emp', | |
], | |
'file' => [ | |
'config' => '/data.php', | |
'output' => '/style.emp.css', | |
'overwrite' => 1, | |
], | |
'files' => [ | |
'include' => 'all', | |
'exclude' => 'none', | |
/* | |
[ 'name' => '/01-bootstrap.css', 'type' => 'bootstrap', 'use' => 0, ], | |
[ 'name' => '/02-media-all-struct.css', 'type' => 'structural', 'use' => 1, ], | |
[ 'name' => '/03-media-all-sprite.css', 'type' => 'sprite', 'use' => 1, ], | |
[ 'name' => '/04-media-screen.css', 'type' => 'screen', 'use' => 1, ], | |
[ 'name' => '/05-media-screen-header.css', 'type' => 'header', 'use' => 1, ], | |
[ 'name' => '/06-media-screen-menu.css', 'type' => 'menu', 'use' => 1, ], | |
[ 'name' => '/07-media-screen-sheet.css', 'type' => 'sheet', 'use' => 1, ], | |
[ 'name' => '/08-media-screen-style.css', 'type' => 'style', 'use' => 1, ], | |
[ 'name' => '/09-media-screen-flex.css', 'type' => 'flex', 'use' => 1, ], | |
[ 'name' => '/10-media-mixed-color.css', 'type' => 'color', 'use' => 1, ], | |
[ 'name' => '/11-media-mixed-adjust.css', 'type' => 'adjust', 'use' => 1, ], | |
[ 'name' => '/12-media-print.css', 'type' => 'print', 'use' => 1, ], | |
*/ | |
], | |
'max' => [ | |
'len' => 3000000, // Bytes | |
], | |
'write' => [ | |
'root' => 1, | |
], | |
'message' => [ | |
'na' => 'Not available.', | |
'write' => [ | |
'denied' => 'Write permission denied.' , | |
'success' => 'Write operation succeeded.', | |
'failure' => 'Write operation failed.', | |
], | |
], | |
'link' => 'https://github.com/earth3300/ec01-css-printer', | |
]; | |
/** | |
* 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; | |
} | |
} | |
/** | |
* Gets the list of files | |
* | |
* Allow CSS files only. | |
* | |
* @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types | |
* | |
* @param array $args | |
* | |
* @return string | |
*/ | |
private function run() | |
{ | |
if( isset( $_GET['run'] ) ) | |
{ | |
$file = []; | |
$strCSS = ''; | |
$file = $this->getPaths( $file ); | |
$file = $this->getDataFiles( $file ); | |
$file = $this->getMessage( $file ); | |
$html = $this->getPageHTML( $file ); | |
return $html; | |
} | |
else | |
{ | |
echo '<pre>You wish to run the script?</pre>' . PHP_EOL; | |
} | |
} | |
/** | |
* Get the Paths to the Files to Process. | |
* | |
* @return array | |
*/ | |
private function getPaths() | |
{ | |
$path = []; | |
$path['root'] = rtrim( $_SERVER['DOCUMENT_ROOT'], '/' ); | |
$path['path']['input'] = $path['root']; | |
$path['path']['config'] = $path['root']; | |
$path['path']['input'] .= $this->opts['dir']['input']; | |
$path['path']['config'] .= $this->opts['dir']['config']; | |
$path['path']['output'] = $path['root']; | |
$path['path']['output'] .= $this->opts['dir']['output']; | |
$path['file']['output'] = $path['path']['output']; | |
$path['file']['config'] = $path['path']['config']; | |
$path['file']['config'] .= $this->opts['file']['config']; | |
return $path; | |
} | |
/** | |
* Get Data Files | |
* | |
* Will also need some file info. | |
* Available: | |
* PATHINFO_DIRNAME | |
* PATHINFO_BASENAME (file name, with extension). | |
* PATHINFO_EXTENSION | |
* PATHINFO_FILENAME (file name, no extension). | |
* | |
* @param array $file | |
* | |
* @return array | |
*/ | |
private function getDataFiles( $file ) | |
{ | |
if( is_dir( $file['path']['input'] ) ) | |
{ | |
$match = $file['path']['input'] . '/*.php'; | |
$items = glob( $match ); | |
// Loop through the files | |
foreach( $items as $cnt => $item ) | |
{ | |
// load the file. | |
if( file_exists( $item ) && require_once( $item ) ) | |
{ | |
$this->processItem( $item, $file ); | |
} | |
} | |
} | |
return $file; | |
} | |
/** | |
* Process Item Based on HTML Entity Type | |
* | |
* Need the function names | |
*/ | |
private function processItem( $item, $file ) | |
{ | |
if( strpos( $item, 'sectioning' ) !== false ) | |
{ | |
$data = get_sectioning_data(); | |
} | |
elseif( strpos( $item, 'content' ) !== false ) | |
{ | |
$data = get_content_data(); | |
} | |
elseif( strpos( $item, 'structural' ) !== false ) | |
{ | |
$data = get_structural_data(); | |
} | |
elseif( strpos( $item, 'semantics' ) !== false ) | |
{ | |
$data = get_semantics_data(); | |
} | |
elseif( strpos( $item, 'media' ) !== false ) | |
{ | |
$data = get_media_data(); | |
} | |
elseif( strpos( $item, 'embedded' ) !== false ) | |
{ | |
$data = get_embedded_data(); | |
} | |
elseif( strpos( $item, 'script' ) !== false ) | |
{ | |
$data = get_script_data(); | |
} | |
elseif( strpos( $item, 'edits' ) !== false ) | |
{ | |
$data = get_edits_data(); | |
} | |
elseif( strpos( $item, 'table' ) !== false ) | |
{ | |
$data = get_table_data(); | |
} | |
elseif( strpos( $item, 'forms' ) !== false ) | |
{ | |
$data = get_forms_data(); | |
} | |
elseif( strpos( $item, 'interactive' ) !== false ) | |
{ | |
$data = get_interactive_data(); | |
} | |
elseif( strpos( $item, 'components' ) !== false ) | |
{ | |
$data = get_components_data(); | |
} | |
else | |
{ | |
// Do nothing. | |
} | |
$name = pathinfo( $item, PATHINFO_BASENAME ); | |
$file['file']['output'] .= '/' . str_replace( '.php', '.css', $name ); | |
$file = $this->genFile( $name, $file, $data ); | |
} | |
/** | |
* Generates the File | |
* | |
* @param array $file | |
* @param array $data | |
* | |
* @return array | |
*/ | |
private function genFile( $name, $file, $data ) | |
{ | |
if( is_array( $file ) && is_array( $data ) && count( $data ) > 0 ) | |
{ | |
$file['str'] = ''; | |
$file = $this->getFileHeader( $name, $file, $data ); | |
$file = $this->genSpecs( $file, $data ); | |
$file = $this->getFileSize( $file, $data ); | |
$file = $this->getFileFooter( $file, $data ); | |
$file = $this->printFile( $file ); | |
return $file; | |
} | |
else | |
{ | |
echo '<pre>Not an array.</pre>' . PHP_EOL; | |
} | |
} | |
/** | |
* Generate Specifications (Structural) | |
* | |
* @param array $file | |
* | |
* @return array | |
*/ | |
private function genSpecs( $file, $data ) | |
{ | |
$str = ''; | |
$strValue = ''; | |
if( is_array( $data ) && count( $data ) > 0 ) | |
{ | |
foreach( $data as $selector => $properties ) | |
{ | |
// always use a media selector to block out sections. | |
if( 'media' == $selector ) | |
{ | |
$str .= sprintf( '@media %s {%s', $properties, PHP_EOL ); | |
} | |
else | |
{ | |
if( is_array( $properties ) | |
&& count( $properties ) > 0 ) | |
{ | |
$str .= sprintf( ' %s {%s', $selector, PHP_EOL ); | |
foreach( $properties as $key => $value ) | |
{ | |
if( strlen( $value ) > 0 ) | |
{ | |
$str .= sprintf( ' %s: %s;%s', $key, $value, PHP_EOL ); | |
} | |
} | |
$str .= ' }' . PHP_EOL; | |
$str .= PHP_EOL; | |
} | |
} | |
} | |
// Close media selector. | |
$str .= '}' . PHP_EOL; | |
} | |
$file['str'] .= $str; | |
return $file; | |
} | |
/** | |
* Get File Size | |
* | |
* @param array $file | |
* | |
* @return array | |
*/ | |
private function getFileSize( $file ) | |
{ | |
$file['size'] = null; | |
if( isset( $file['str'] ) ) | |
{ | |
$file['size'] = strlen( $file['str'] ); | |
} | |
return $file; | |
} | |
/** | |
* Minify CSS | |
* | |
* @param string | |
* | |
* @return string|bool | |
*/ | |
function minifyCSS( $str ) | |
{ | |
if( is_string( $str ) && strlen( $str ) < $this->opts['max']['len'] ) | |
{ | |
return $this->getMinified( $str, 'https://cssminifier.com/raw' ); | |
} | |
else | |
{ | |
return false; | |
} | |
} | |
/** | |
* Get Minified | |
* | |
* @param string | |
* | |
* @return bool | |
*/ | |
private function getMinified( $str, $url ) | |
{ | |
if( is_string( $str ) ) | |
{ | |
$data = array( 'http' => array ( | |
'method' => 'POST', | |
'header' => 'Content-type: application/x-www-form-urlencoded', | |
'content' => http_build_query( array('input' => $str ) ) ) ); | |
return file_get_contents( $url, false, stream_context_create( $data ) ); | |
} | |
else | |
{ | |
return false; | |
} | |
} | |
/** | |
* Print the File | |
* | |
* @param array $file | |
* | |
* @return array | |
*/ | |
private function printFile( $file ) | |
{ | |
$resp = 'N/A'; | |
//pre_dump( $file['file']['output'] ); | |
//pre_dump( $file['str'], 0 ); | |
if ( | |
isset( $_GET['print'] ) | |
&& isset( $_POST['safety'] ) | |
&& isset( $file['file']['output'] ) | |
&& isset( $file['str'] ) && strlen( $file['str'] ) > 0 ) | |
{ | |
$resp .= sprintf( '<br>%s:<br>%s', $file['file']['output'], PHP_EOL ); | |
$resp .= file_put_contents( $file['file']['output'], $file['str'] ); | |
pre_dump( $resp ); | |
} | |
$file['resp'] = $resp; | |
return $file; | |
} | |
/** | |
* Get Message | |
* | |
* @param array $file | |
* | |
* @return array | |
*/ | |
private function getMessage( $file ) | |
{ | |
$str = ''; | |
$file['msg'] = null; | |
if( is_array( $file ) && count( $file ) > 0 ) | |
{ | |
// Count of the files. | |
$str .= isset( $file['cnt'] ) ? | |
sprintf( '<br>Files: %s<br>%s', $file['cnt'], PHP_EOL ) : ''; | |
// Length of the files. | |
$str .= isset( $file['str'] ) ? | |
sprintf( '<br>Bytes: %s<br>%s', strlen ( $file['str'] ), PHP_EOL ) : ''; | |
// Length of the files. | |
$str .= isset( $file['resp'] ) ? | |
sprintf( '<br>Resp: %s<br>%s', $file['resp'], PHP_EOL ) : ''; | |
} | |
$file['msg'] = $str; | |
return $file; | |
} | |
/** | |
* File Header | |
* | |
* @return string | |
*/ | |
private function getFileHeader( $name, $file, $data ) | |
{ | |
// Initialize | |
$str = ''; | |
$str .= '/**' . PHP_EOL; | |
$str .= sprintf( ' * File: %s%s', $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; | |
$file['str'] = $str; | |
return $file; | |
} | |
/** | |
* 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, $data ) | |
{ | |
// Initialize | |
$str = PHP_EOL; | |
$str .= '/*'; | |
$str .= ' End of File ('; | |
$str .= $file['size'] . ' B). '; | |
$str .= '*/' . PHP_EOL; | |
$str .= PHP_EOL; | |
// Add this string to the end... | |
$file['str'] .= $str; | |
return $file; | |
} | |
/** | |
* 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 style="display:block;">%s</h1>%s', | |
$this->opts['this']['title'], PHP_EOL ); | |
$str .= $this->getForm(); | |
$str .= isset( $file['msg'] ) ? $file['msg'] : ''; | |
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