Last active
October 8, 2018 23:50
-
-
Save earth3300/11d5f7f7e421363aef7c702412adc1c4 to your computer and use it in GitHub Desktop.
Converts JSON Color Data to HTML
This file contains hidden or 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 JSON Index. | |
| * | |
| * Allows a JSON data text file to be viewed in a directory through a | |
| * single index file. | |
| * | |
| * @package EC01 JSON Index | |
| * @since 1.0.0 | |
| * @author Clarence Bos <cbos@tnoep.ca> | |
| * @copyright Copyright (c) 2018, Clarence Bos | |
| * @license https://www.gnu.org/licenses/gpl-3.0.en.html GPL-3.0+ | |
| * @link http://wp.cbos.ca/plugins/ec01-json-index | |
| * | |
| * @wordpress-plugin | |
| * Plugin Name: EC01 JSON Index | |
| * Plugin URI: http://wp.cbos.ca/plugins/ec01-json-index/ | |
| * Description: Allows a JSON data text file to be viewed in a directory through a single index file. | |
| * Version: 1.0.0 | |
| * Author: Clarence Bos | |
| * Author URI: http://ec01.earth3300.info/ | |
| * Text Domain: ec01-json-index | |
| * License: GPL-3.0+ | |
| * License URI: https://www.gnu.org/licenses/gpl-3.0.en.html | |
| */ | |
| /** | |
| * Allows a json file to be viewed in a directory. | |
| * | |
| * See the bottom of this file for a more complete description | |
| * and the switch for determining the context in which this file | |
| * is found. | |
| */ | |
| class JSONIndex | |
| { | |
| /** @var array Default options. */ | |
| protected $opts = [ | |
| 'max' => 300, | |
| 'type' => 'json', | |
| 'msg' => [ 'na' => '', ], | |
| ]; | |
| /** | |
| * Gets the JSON file as HTML. | |
| * | |
| * @param array $args | |
| * | |
| * @return string | |
| */ | |
| public function get( $args = null ) | |
| { | |
| /** If no arguments are set, assume current directory */ | |
| if ( $args = $this->setDirectorySwitch( $args ) ) | |
| { | |
| $max = $this->getMaxFiles( $args ); | |
| /** Add the "type" to the class string (i.e. json). */ | |
| $args['class'] = $this->opts['type']; | |
| $str = '<article>' . PHP_EOL; | |
| $args['type'] = $this->opts['type']; | |
| if ( $match = $this->getMatchPattern( $args['type'], $args ) ) | |
| { | |
| $str .= $this->iterateFiles( $match, $max, $args ); | |
| } | |
| $str .= '</article>' . PHP_EOL; | |
| if ( isset( $args['doctype'] ) && $args['doctype'] ) | |
| { | |
| $str = $this->getPageHtml( $str, $args ); | |
| } | |
| return $str; | |
| } | |
| else | |
| { | |
| return "Error."; | |
| } | |
| } | |
| /** | |
| * Iterate over files. | |
| * | |
| * Looks for json only. | |
| * | |
| * @param string $match | |
| * @param array $args | |
| * | |
| * @return string | |
| */ | |
| private function iterateFiles( $match, $max, $args ) | |
| { | |
| $str = ''; | |
| $cnt = 0; | |
| foreach ( glob( $match ) as $file ) | |
| { | |
| $cnt++; | |
| if ( $cnt > $max ) | |
| { | |
| break; | |
| } | |
| $args['file'] = $file; | |
| /** Remove the root of the file path to use it a file source. */ | |
| $args['src'] = $this->getSrcFromFile( $args['file'] ); | |
| $args['name'] = $this->getNamefromFileName( $args['src'] ); | |
| if ( file_exists( $args['file'] ) ) | |
| { | |
| $file = file_get_contents( $args['file'] ); | |
| $json = json_decode( $file ); | |
| } | |
| $str .= $this->getHTMLfromJSON( $json ); | |
| } | |
| return $str; | |
| } | |
| /** | |
| * Get the source from the file, checking for a preceding slash. | |
| * | |
| * @param string $str | |
| * @return string | |
| */ | |
| private function getSrcFromFile( $str ) | |
| { | |
| $src = str_replace( $this->getSitePath(), '', $str ); | |
| /** May be server inconsistency, therefore remove and add again. */ | |
| $src = ltrim( $src, '/' ); | |
| return '/' . $src; | |
| } | |
| /** | |
| * Get the SITE_PATH | |
| * | |
| * Get the SITE_PATH from the constant, from ABSPATH (if loading within WordPress | |
| * as a plugin), else from the $_SERVER['DOCUMENT_ROOT'] | |
| * | |
| * Both of these have been tested online to have a preceding forward slash. | |
| * Therefore do not add one later. | |
| * | |
| * @return bool | |
| */ | |
| private function getSitePath() | |
| { | |
| if ( defined( 'SITE_PATH' ) ) | |
| { | |
| return SITE_PATH; | |
| } | |
| /** Available if loading within WordPress as a plugin. */ | |
| elseif( defined( 'ABSPATH' ) ) | |
| { | |
| return ABSPATH; | |
| } | |
| else | |
| { | |
| return $_SERVER['DOCUMENT_ROOT']; | |
| } | |
| } | |
| /** | |
| * Get the maximum number of images to process. | |
| * | |
| * @param array $args | |
| * @return int | |
| */ | |
| private function getMaxFiles( $args ) | |
| { | |
| if ( isset( $args['max'] ) ) | |
| { | |
| $max = $args['max']; | |
| } | |
| else | |
| { | |
| $max = $this->opts['max']; | |
| } | |
| return $max; | |
| } | |
| /** | |
| * Build the match string. | |
| * | |
| * This is iterated through for each type added to $types, above. A basic | |
| * check for a reasonable string length (currently 10) is in place. Can | |
| * develop this further, if needed. | |
| * | |
| * @param string $type 'jpg', 'png' | |
| * @param array $args | |
| * | |
| * @return string|false | |
| */ | |
| private function getMatchPattern( $type, $args ) | |
| { | |
| $path = $this->getBasePath( $args ); | |
| $prefix = "/*"; | |
| $match = $path . $prefix . $type; | |
| /** Very basic check. Can improve, if needed. */ | |
| if ( strlen( $match ) > 10 ) | |
| { | |
| return $match; | |
| } | |
| else { | |
| return false; | |
| } | |
| } | |
| /** | |
| * Get the Base Path to the Media Directory. | |
| * | |
| * This does not need to include the `/media` directory. | |
| * | |
| * @param array $args | |
| * @return string | |
| */ | |
| private function getBasePath( $args ) | |
| { | |
| if ( isset( $args['self'] ) ) | |
| { | |
| $path = __DIR__; | |
| } | |
| elseif ( defined( 'SITE_CDN_PATH' ) ) | |
| { | |
| $path = SITE_CDN_PATH; | |
| } | |
| return $path; | |
| } | |
| /** | |
| * Get the Media Directory | |
| * | |
| * @param array $args | |
| * | |
| * @return string | |
| * | |
| * @example $args['dir'] = '/architecture/shelter/micro-cabin/' | |
| */ | |
| private function getMediaDir( $args ) | |
| { | |
| if ( isset( $args['dir'] ) ) | |
| { | |
| $media = $args['dir']; | |
| } | |
| else | |
| { | |
| $media = '/media'; | |
| } | |
| return $media; | |
| } | |
| /** | |
| * Get the File HTML. | |
| * | |
| * Types: json | |
| * | |
| * @param array $args | |
| * | |
| * @return string | |
| */ | |
| private function getFileHtml( $args ) | |
| { | |
| $str = '<div class="json">' . PHP_EOL; | |
| $str .= sprintf( '<a href="%s">%s', $args['src'], PHP_EOL ); | |
| $str .= '<img'; | |
| $str .= sprintf( ' class="%s"', $this->getImageClass( $args ) ); | |
| $str .= sprintf( ' src="%s"', $args['src'] ); | |
| $str .= sprintf( ' alt="%s"', $this->getImageAlt( $args ) ); | |
| $str .= sprintf( ' width="%s"', $dim['width'] ); | |
| $str .= sprintf( ' height="%s"', $dim['height'] ); | |
| $str .= ' />' . PHP_EOL; | |
| $str .= '</a>' . PHP_EOL; | |
| $str .= '<p class="text-center">'; | |
| if ( $name = $this->getMediaName( $args['name'] ) ) | |
| { | |
| $str .= sprintf( '<span class="name">%s</span>', $name ); | |
| } | |
| if ( ! empty ( $dim['width'] && ! empty( $dim['height'] ) ) ) | |
| { | |
| $str .= sprintf( ' <span class="dimensions">%sX%s</span>', $dim['width'], $dim['height'] ); | |
| } | |
| if ( $size = $this->getMediaSize( $args ) ) | |
| { | |
| $str .= sprintf( ' <span class="size">%s</span>', $size ); | |
| } | |
| $str .= '</p>' . PHP_EOL; | |
| $str .= '</div>' . PHP_EOL; | |
| return $str; | |
| } | |
| /** | |
| * Wrap the string in page HTML `<!DOCTYPE html>`, etc. | |
| * | |
| * @param string $str | |
| * @return string | |
| */ | |
| public function getPageHtml( $html, $args ) | |
| { | |
| $str = '<!DOCTYPE html>' . PHP_EOL; | |
| $str .= sprintf( '<html class="dynamic %s" lang="en-CA">', $args['type'], 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 .= '<title>JSON Index</title>' . PHP_EOL; | |
| $str .= '<meta name="robots" content="noindex,nofollow" />' . PHP_EOL; | |
| $str .= '<link rel=stylesheet href="/0/theme/css/style.css">' . PHP_EOL; | |
| $str .= '</head>' . PHP_EOL; | |
| $str .= '<body>' . PHP_EOL; | |
| $str .= '<main>' . PHP_EOL; | |
| $str .= $html; | |
| $str .= '</main>' . PHP_EOL; | |
| $str .= '<footer>' . PHP_EOL; | |
| $str .= '<div class="text-center"><small>'; | |
| $str .= 'Note: This page has been <a href="https://github.com/earth3300/ec01-json-index.git">automatically generated</a>. No header, footer, menus or sidebars are available.'; | |
| $str .= '</small></div>' . PHP_EOL; | |
| $str .= '</footer>' . PHP_EOL; | |
| $str .= '</html>' . PHP_EOL; | |
| return $str; | |
| } | |
| /** | |
| * Get the File Name from the String. | |
| * | |
| * Return the direct string values of each. Do no extra processing here. | |
| * | |
| * $regex = '/\/([a-z0-9\-]{3,150})\./' | |
| * | |
| * Part 1: Looks for letters, numbers and dashes from 3 to 150 characters. | |
| * Part 2: Followed by a dash, then dimesions from 2 to 4 x 2 to 5 characters. | |
| * Part 3: Ending. Followed by a dot \. (which will come before the extension). | |
| * | |
| * Not only does it divide the string given it into two parts, but it | |
| * also does a basic quality check on the image name structure. If the image | |
| * name does not meet the criteria given, it won't be captured. | |
| * | |
| * @param string $str | |
| * | |
| * @return array $arr['name'] | |
| * | |
| * @example $arr['name'] = 'image-name' | |
| */ | |
| private function getImageNameDimArr( $str ) | |
| { | |
| /** | |
| * Since we won't have a valid image name with fewer than 13 characaters | |
| * we won't bother processing anything with less than that length. | |
| */ | |
| if ( strlen( $str ) > 12 ) | |
| { | |
| /** If this isn't matched, check for a name only */ | |
| $regex = '//\/([a-z0-9\-]{3,150})\./'; | |
| preg_match( $regex, $str, $match ); | |
| if ( empty( $match ) ) | |
| { | |
| $regex = '/\/([a-z,0-9\-]{5,150})\./'; | |
| preg_match( $regex, $str, $match ); | |
| } | |
| if ( ! empty( $match[1] ) ) | |
| { | |
| $arr['name'] = $match[1]; | |
| } | |
| else | |
| { | |
| $arr['name'] = null; | |
| } | |
| return $arr; | |
| } | |
| else { | |
| return false; | |
| } | |
| } | |
| /** | |
| * Get the Name from the File Name | |
| * | |
| * @param array $args | |
| * | |
| * @return string | |
| */ | |
| private function getNamefromFileName( $str ) | |
| { | |
| if ( strlen( $str ) > 2 ) | |
| { | |
| $name = str_replace( '-', ' ', $str ); | |
| $name = strtoupper( $name ); | |
| } | |
| else | |
| { | |
| $name = $this->opts['msg']['na']; | |
| } | |
| return $name; | |
| } | |
| /** | |
| * Set the Directory Switch (Process Containing or Given Directory). | |
| * | |
| * If $args['self'] or $args['dir'] are not set, it assumes we are in the | |
| * directory for which images are to be processed. Therefore $args['self'] | |
| * is set to true and $args['dir'] is set to null. We also have to set the | |
| * $args['doctype'] to true to know whether or not to wrap the output in | |
| * the correct doctype and the containing html and body elements. | |
| * | |
| * @param array $args | |
| * | |
| * @return array | |
| */ | |
| private function setDirectorySwitch( $args ) | |
| { | |
| /** If $args['dir'] is not set, set it to false. */ | |
| $args['dir'] = isset( $args['dir'] ) ? $args['dir'] : false; | |
| /** if $args['dir'] == false, set $args['self'] to true. */ | |
| if ( ! $args['dir'] ) | |
| { | |
| $args['self'] = true; | |
| $args['doctype'] = true; | |
| return $args; | |
| } | |
| else | |
| { | |
| return $args; | |
| } | |
| } | |
| /** | |
| * JSON Color Data to HTML | |
| * | |
| * @param object $data JSON decoded file | |
| * | |
| * @return string | |
| * | |
| * @example echo jsonToTable([json-decoded-values]); | |
| * | |
| * @example echo jsonToTable(json_decode('{"name":"Bob","age":23,"skills":["php","javascript"]}')); | |
| */ | |
| private function getHTMLfromJSON($arr) | |
| { | |
| $str = '<div class="json" style="font-size: 80%;">' . PHP_EOL; | |
| $max = $this->opts['max']; | |
| $cnt = 0; | |
| $str .= '<div class="line">' . PHP_EOL; | |
| foreach ($arr as $key => $color) | |
| { | |
| $cnt++; | |
| if( $cnt > $max ) { | |
| break; | |
| } | |
| if( 0 ) { | |
| echo "<pre>"; | |
| var_dump( $color->hsl ); | |
| echo "</pre>"; | |
| } | |
| $str .= '<div class="unit size1of4" style="border-radius: 3px;">' . PHP_EOL; | |
| $str .= '<div class="border" style="padding: 3px;">' . PHP_EOL; | |
| $str .= '<div class="inner text-center" style="min-height: 46px; padding:6px; ' . PHP_EOL; | |
| $str .= sprintf( 'background: %s;', $color->hexString ); | |
| $str .= sprintf( 'color: %s">', $this->getTextColor( $color->hsl ) ); | |
| $str .= sprintf('%s<br />%s', $color->name, PHP_EOL); | |
| $str .= sprintf('%s%s<br />', $color->hexString, PHP_EOL); | |
| $str .= sprintf('%s%s', $this->getHSLValue( $color->hsl ), PHP_EOL); | |
| $str .= '</div>' . PHP_EOL; | |
| $str .= '</div>' . PHP_EOL; | |
| $str .= '</div>' . PHP_EOL; | |
| } | |
| $str .= '</div>' . PHP_EOL; | |
| return $str; | |
| } | |
| /** | |
| * Get the color of the text | |
| */ | |
| private function getTextColor( $hsl ) | |
| { | |
| $value = $hsl->h + $hsl->s + $hsl->l; | |
| if ( $value >= 250 ) { | |
| $color = '#fff'; | |
| } | |
| else { | |
| $color = '#000'; | |
| } | |
| return $color; | |
| } | |
| /** | |
| * Get the HSL value as a String | |
| */ | |
| private function getHSLValue( $hsl ) | |
| { | |
| $hsl = sprintf( '(%s, %s, %s)', number_format( $hsl->h, 0 ), $hsl->s, $hsl->l ); | |
| return $hsl; | |
| } | |
| } | |
| /** | |
| * Callback from the json-index shortcode. | |
| * | |
| * Performs a check, then instantiates the JSONIndex class | |
| * and returns the results as HTML. | |
| * | |
| * @param array $args['dir'] | |
| * @return string HTML, wrapped in the article element. | |
| */ | |
| function json_index( $args ) | |
| { | |
| if ( is_array( $args ) ) | |
| { | |
| $media_index = new JSONIndex(); | |
| return $media_index -> get( $args ); | |
| } | |
| else | |
| { | |
| return '<!-- Missing the directory to process. [json-index dir=""]-->'; | |
| } | |
| } | |
| /** | |
| * Check context (WordPress Plugin File or Directory Index File). | |
| * | |
| * The following checks to see whether or not this file (index.php) is being loaded | |
| * as part of the WordPress package, or not. If it is, we expect a WordPress | |
| * function to be available (in this case, `add_shortcode`). We then ensure there | |
| * is no direct access and add the shortcode hook, `media-index`. If we are not in | |
| * WordPress, then this file acts as an "indexing" type of file by listing all | |
| * of the allowed media types (currently jpg, png, mp3 and mp4) and making them | |
| * viewable to the end user by wrapping them in HTML and making use of a css | |
| * file that is expected to be found at `/0/media/theme/css/style.css`. This | |
| * idea was developed out of work to find a more robust method to develop out a | |
| * site, including that for a community. It makes use of the package found at: | |
| * {@link https://github.com/earth3300/ec01/wiki/}, with the entire codeset | |
| * available there through the same link. | |
| */ | |
| if( function_exists( 'add_shortcode' ) ) | |
| { | |
| // No direct access. | |
| defined('ABSPATH') || exit('No direct access.'); | |
| //shortcode [json-index dir=""] | |
| add_shortcode( 'json-index', 'json_index' ); | |
| } | |
| else | |
| { | |
| /** | |
| * Outside of WordPress. Instantiate directly, assuming current directory. | |
| * | |
| * @return string | |
| */ | |
| $json_index = new JSONIndex(); | |
| echo $json_index -> get(); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment