Skip to content

Instantly share code, notes, and snippets.

@earth3300
Last active September 18, 2019 04:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save earth3300/78d5e020899782efd6f160553de08ef3 to your computer and use it in GitHub Desktop.
Save earth3300/78d5e020899782efd6f160553de08ef3 to your computer and use it in GitHub Desktop.
Prints CSS files from a set of data arrays.
<?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( ['<','>'], ['&lt','&gt'], $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