Initial commit

This commit is contained in:
Joey Kimsey
2024-08-04 21:15:59 -04:00
parent c9d1fb983f
commit 0d469501ee
695 changed files with 70184 additions and 71 deletions

53
vendor/houdini/classes/components.php vendored Normal file
View File

@ -0,0 +1,53 @@
<?php
/**
* classes/components.php
*
* This class is for managing template components.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/Houdini
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Houdini\Classes;
class Components {
public static $components = [];
public static function parse( $data ) {
foreach ( self::$components as $key => $replace ) {
$find = "~{($key)}~i";
$data = preg_replace( $find, $replace, $data );
}
return $data;
}
/**
* Adds a $key->$value combination to the $components array.
*
* @param {string} [$key]
* @param {wild} [$value]
* @return {bool}
*/
public static function set( $name, $value = '' ) {
if ( null == $value ) {
$value = '';
}
self::$components[ $name ] = $value;
return true;
}
public static function unset( $name ) {
if ( isset( self::$components[ $name ] ) ) {
unset( self::$components[ $name ] );
}
return true;
}
public static function append( $name, $value ) {
if ( ! isset( self::$components[ $name ] ) ) {
return self::set( $name, $value );
}
$curr = self::$components[ $name ];
self::$components[ $name ] = $curr . $value;
return true;
}
}

219
vendor/houdini/classes/email.php vendored Normal file
View File

@ -0,0 +1,219 @@
<?php
/**
* classes/email.php
*
* This is our class for constructing and sending various kinds of emails.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/Core
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Houdini\Classes;
use TheTempusProject\Houdini\Classes\Views;
use TheTempusProject\Bedrock\Classes\Config;
use TheTempusProject\Canary\Canary as Debug;
use TheTempusProject\Hermes\Functions\Route as Routes;
class Email {
private static $header = null;
private static $subject = null;
private static $title = null;
private static $message = null;
private static $unsub = false;
private static $useTemplate = false;
private static $footer = null;
private static $debug = false;
/**
* Sends pre-constructed email templates. Useful for modifying the
* entire theme or layout of the system generated emails.
*
* @param string $email - The email you are sending to.
* @param string $type - The template you wish to send.
* @param string|array $params - Any special parameters that may be required from your individual email template.
*
* @return bool
*/
public static function send( $email, $type, $params = null, $flags = null ) {
if ( !empty( $flags ) ) {
if ( is_array( $flags ) ) {
foreach ( $flags as $key => $value ) {
switch ( $key ) {
case 'template':
if ( $value == true ) {
self::$useTemplate = true;
}
break;
case 'unsubscribe':
if ( $value == true ) {
self::$unsub = true;
}
break;
case 'debug':
if ( $value == true ) {
self::$debug = false;
}
break;
}
}
}
}
self::build();
switch ( $type ) {
case 'debug':
self::$subject = 'Please Confirm your email at {SITENAME}';
self::$title = 'Almost Done';
self::$message = 'Please click or copy-paste this link to confirm your registration: <a href="{BASE}register/confirm/{PARAMS}">Confirm Your Email</a>';
break;
case 'confirmation':
self::$subject = 'Please Confirm your email at {SITENAME}';
self::$title = 'Almost Done';
self::$message = 'Please click or copy-paste this link to confirm your registration: <a href="{BASE}register/confirm/{PARAMS}">Confirm Your Email</a>';
break;
case 'install':
self::$subject = 'Notification from {SITENAME}';
self::$title = 'Installation Success';
self::$message = 'This is just a simple email to notify you that you have successfully installed The Tempus Project framework!';
break;
case 'passwordChange':
self::$subject = 'Security Notice from {SITENAME}';
self::$title = 'Password Successfully Changed';
self::$message = 'Recently your password on {SITENAME} was changed. If you are the one who changed the password, please ignore this email.';
break;
case 'emailChangeNotice':
self::$subject = 'Account Update from {SITENAME}';
self::$title = 'Email Updated';
self::$message = 'This is a simple notification to let you know your email has been changed at {SITENAME}.';
break;
case 'emailChange':
self::$subject = 'Account Update from {SITENAME}';
self::$title = 'Confirm your E-mail';
self::$message = 'Please click or copy-paste this link to confirm your new Email: <a href="{BASE}register/confirm/{PARAMS}">Confirm Your Email</a>';
break;
case 'emailNotify':
self::$subject = 'Account Update from {SITENAME}';
self::$title = 'Email Updated';
self::$message = 'You recently changed your email address on {SITENAME}.';
break;
case 'forgotPassword':
self::$subject = 'Reset Instructions for {SITENAME}';
self::$title = 'Reset your Password';
self::$message = 'You recently requested information to change your password at {SITENAME}.<br>Your password reset code is: {PARAMS}<br> Please click or copy-paste this link to reset your password: <a href="{BASE}register/reset/{PARAMS}">Password Reset</a>';
break;
case 'forgotUsername':
self::$subject = 'Account Update from {SITENAME}';
self::$title = 'Account Details';
self::$message = 'Your username for {SITENAME} is {PARAMS}.';
break;
case 'subscribe':
self::$subject = 'Thanks for Subscribing';
self::$title = 'Thanks for Subscribing!';
self::$message = 'Thank you for subscribing to updates from {SITENAME}. If you no longer wish to receive these emails, you can un-subscribe using the link below.';
self::$unsub = true;
break;
case 'unsubInstructions':
self::$subject = 'Unsubscribe Instructions';
self::$title = 'We are sad to see you go';
self::$message = 'If you would like to be un-subscribed from future emails from {SITENAME} simply click the link below.<br><br><a href="{BASE}home/unsubscribe/{EMAIL}/{PARAMS}">Click here to unsubscribe</a>';
self::$unsub = true;
break;
case 'unsubscribe':
self::$subject = 'Unsubscribed';
self::$title = 'We are sad to see you go';
self::$message = 'This is just a notification that you have successfully been unsubscribed from future emails from {SITENAME}.';
break;
case 'contact':
self::$subject = $params['subject'];
self::$title = $params['title'];
self::$message = $params['message'];
break;
default:
return false;
break;
}
if ( self::$useTemplate ) {
$data = new \stdClass();
if ( self::$unsub ) {
$data->UNSUB = Views::simpleView( 'email.unsubscribe' );
} else {
$data->UNSUB = '';
}
// $data->LOGO = Config::getValue('main/logo');
$data->SITENAME = Config::getValue( 'main/name' );
$data->EMAIL = $email;
if ( !is_array( $params ) ) {
$data->PARAMS = $params;
} else {
foreach ( $params as $key => $value ) {
$data->$key = $value;
}
}
$data->MAIL_FOOT = Views::simpleView( 'email.foot' );
$data->MAIL_TITLE = self::$title;
$data->MAIL_BODY = Template::parse( self::$message, $data );
$subject = Template::parse( self::$subject, $data );
$body = Views::simpleView( 'email.template', $data );
} else {
$subject = self::$subject;
$body = '<h1>' . self::$title . '</h1>' . self::$message;
}
if ( !is_object( $email ) ) {
$email = (object) [
(object) [ 'email' => $email ],
];
}
$error = false;
foreach ( $email as $data ) {
if ( !mail( $data->email, $subject, $body, self::$header ) ) {
Debug::error( 'Failed to send email. emailSubject: ' . $subject . ' emailRecipientEmail: ' . $data->email );
Debug::error( var_export( error_get_last(), true ) );
$error = true;
}
}
if ( $error ) {
return false;
}
Debug::info( "Email sent: $type." );
return true;
}
/**
* Constructor for the header.
*/
public static function build() {
if ( empty( self::$header ) ) {
self::$header = 'From: ' . Config::getValue( 'main/name' ) . ' <' . EMAIL_FROM_EMAIL . ">\r\n";
self::$header .= "MIME-Version: 1.0\r\n";
self::$header .= "Content-Type: text/html; charset=ISO-8859-1\r\n";
$url = parse_url( Routes::getAddress(), PHP_URL_HOST );
$parts = explode( '.', $url );
$count = count( $parts );
if ( $count > 2 ) {
$host = $parts[$count - 2] . '.' . $parts[$count - 1];
} else {
$host = $url;
}
if ( self::$debug ) {
self::$header .= 'CC: ' . DEBUG_EMAIL . "\r\n";
}
}
}
}

139
vendor/houdini/classes/filters.php vendored Normal file
View File

@ -0,0 +1,139 @@
<?php
/**
* core/template/filters.php
*
* This class is for managing template filters.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/Core
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Houdini\Classes;
use TheTempusProject\Canary\Canary as Debug;
class Filters {
public static $filters = [
'comments' => [
'name' => 'comments',
'match' => '#/\*.*?\*/#s',
'replace' => '',
'enabled' => true,
],
'commentsTwo' => [
'name' => 'commentsTwo',
'match' => '#(?<!:)//.*#',
'replace' => '',
'enabled' => true,
],
'formComponents' => [
'name' => 'formComponents',
'match' => '#{CHECKED:(.*?)=(.*?)}#s',
'replace' => '',
'enabled' => true,
],
];
/**
* Iterates through the filters list on $data. Leaving only the internal
* contents of enabled filters and removing all traces of disabled filters.
*
* @param {string} [$data]
* @return {string}
*/
public static function apply( $data, $force = false ) {
if ( empty( self::$filters ) ) {
return $data;
}
foreach ( self::$filters as $pattern ) {
if ( $pattern['enabled'] || false !== $force ) {
$data = trim( preg_replace( $pattern['match'], $pattern['replace'], $data ) );
}
}
return $data;
}
public static function applyOne( $name, $data, $force = false ) {
if ( empty( self::$filters ) || empty( self::$filters[$name] ) ) {
return $data;
}
if ( self::$filters[$name]['enabled'] || false !== $force ) {
$data = trim(
preg_replace(
self::$filters[$name]['match'],
self::$filters[$name]['replace'],
$data
)
);
}
return $data;
}
/**
* Adds a filter.
*
* @param {string} [$filterName]
* @param {string} [$match]
* @param {string} [$replace]
* @param {bool} [$enabled] - Whether the filter should be enabled or disabled.
*/
public static function add( $filterName, $match, $replace, $enabled = false ) {
if ( isset( self::$filters[$filterName] ) ) {
Debug::error( "Filter already exists: $filterName" );
return;
}
self::$filters[$filterName] = [
'name' => $filterName,
'match' => $match,
'replace' => $replace,
'enabled' => $enabled,
];
return;
}
/**
* Removes a filter.
*
* @param {string} [$filterName]
* @return {bool}
*/
public function remove( $filterName ) {
if ( !isset( self::$filters[$filterName] ) ) {
Debug::error( "Filter does not exist: $filterName" );
return false;
}
unset( self::$filters[$filterName] );
return true;
}
/**
* Enable a filter.
*
* @param {string} [$filterName]
* @return {bool}
*/
public function enable( $filterName ) {
if ( !isset( self::$filters[$filterName] ) ) {
Debug::error( "Filter does not exist: $filterName" );
return false;
}
self::$filters[$filterName]['enabled'] = true;
return true;
}
/**
* Disables a filter.
*
* @param {string} [$filterName]
* @return {bool}
*/
public function disable( $filterName ) {
if ( !isset( self::$filters[$filterName] ) ) {
Debug::error( "Filter does not exist: $filterName" );
return false;
}
self::$filters[$filterName]['enabled'] = false;
return true;
}
}

193
vendor/houdini/classes/forms.php vendored Normal file
View File

@ -0,0 +1,193 @@
<?php
/**
* core/template/forms.php
*
* This class is for managing template forms.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/Core
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Houdini\Classes;
use DateTimeZone;
class Forms {
public static $options = [];
/**
* Sets the specified radio button with $x value to checked.
*
* @param {string} [$fieldName] - The name of the radio field.
* @param {string} [$value] - The field value to be selected.
*/
public static function selectRadio( $fieldName, $value ) {
$selected = 'CHECKED:' . $fieldName . '=' . $value;
Components::set( $selected, 'checked="checked"' );
}
/**
* This will add an option to our selected options menu that will
* automatically be selected when the template is rendered.
*
* @param {string} [$value] - The value of the option you want selected.
*/
public static function selectOption( $value ) {
$find = "#\<option (.*?)value=\'" . $value . "\'#s";
$replace = "<option $1value='" . $value . "' selected";
self::$options[$find] = $replace;
}
public static function getFormFieldHtml( $fieldname, $fieldTitle, $type, $defaultValue = '', $options = null ) {
$out = '';
switch ( $type ) {
case 'radio':
case 'bool':
case 'boolean':
$fieldHtml = self::getRadioHtml( $fieldname, [ 'true', 'false' ], $defaultValue );
break;
case 'select':
$fieldHtml = self::getSelectHtml( $fieldname, $options, $defaultValue );
break;
case 'customSelect':
if ( empty( $options ) ) {
$options = '{' . $fieldname . '-options}';
}
$fieldHtml = self::getSelectHtml( $fieldname, $options, $defaultValue );
break;
case 'block':
$fieldHtml = self::getTextBlockHtml( $fieldname, $defaultValue );
break;
case 'text':
case 'url':
$fieldHtml = self::getTextHtml( $fieldname, $defaultValue );
break;
case 'checkbox':
$fieldHtml = self::getCheckboxHtml( $fieldname, $defaultValue );
break;
case 'timezone':
$fieldHtml = self::getTimezoneHtml( $defaultValue );
break;
case 'file':
$fieldHtml = self::getFileHtml( $fieldname );
break;
default:
Debug::error( "unknown field type: $type" );
break;
}
$out .= '<div class="form-group">';
$out .= '<label for="' . $fieldname . '" class="col-lg-3 control-label">' . $fieldTitle . '</label>';
$out .= '<div class="col-lg-3">';
$out .= $fieldHtml;
$out .= '</div>';
// @todo need to remove this or make it more generic (can't depend on bedrock anymore)
if ( 'file' === $type ) {
$out .= '<div class="col-lg-3 avatar-125" align="center">';
$out .= '<img alt="User Avatar" src="' . $defaultValue . '" class="img-circle img-responsive">';
$out .= '</div>';
}
$out .= '</div>';
return $out;
}
public static function getTimezoneHtml( $default ) {
$tzlist = DateTimeZone::listIdentifiers( DateTimeZone::ALL );
$out = '<select name="timezone" id="timezone" class="form-control">';
foreach ( $tzlist as $value ) {
if ( $default == $value ) {
$selected = ' selected';
} else {
$selected = '';
}
$out .= '<option value="' . $value . '"' . $selected . '>' . $value . '</option>';
}
$out .= '</select>';
return $out;
}
public static function getFileHtml( $name ) {
$out = '<input type="file" class="form-control" name="' . $name . '" id="' . $name . '">';
return $out;
}
public static function getCheckboxHtml( $name, $checked = false ) {
if ( false !== $checked ) {
$checked = ' checked';
} else {
$checked = '';
}
return '<input type="checkbox" class="form-control" name="' . $name . '" id="' . $name . '" value="true"' . $checked . '>';
}
public static function getTextHtml( $name, $default = '' ) {
$out = '<input type="text" class="form-control" name="' . $name . '" id="' . $name . '" value="' . $default . '">';
return $out;
}
public static function getTextBlockHtml( $name, $default = '' ) {
// @todo add some sort of mechanism for changing the size, maybe options?
$out = '<textarea class="form-control" name="' . $name . '" maxlength="2000" rows="10" cols="50" id="entry">' . $default . '</textarea>';
return $out;
}
public static function getSelectHtml( $name, $options, $default = null ) {
$out = '<select name="' . $name . '" id="' . $name . '" class="form-control">';
if ( !is_string( $options ) ) {
$out .= self::getOptionsHtml( $options, $default );
} else {
$out .= $options;
}
$out .= '</select>';
return $out;
}
public static function getOptionsHtml( $options = [], $default = null ) {
$out = '';
if ( isset( $options[0] ) ) {
$assocOptions = [];
foreach ( $options as $key => $value ) {
$assocOptions[$value] = $value;
}
$options = $assocOptions;
}
foreach ( $options as $name => $value ) {
if ( $default == $value ) {
$selected = ' selected';
} else {
$selected = '';
}
$out .= '<option value="' . $value . '"' . $selected . '>' . $name . '</option>';
}
return $out;
}
public static function getRadioHtml( $name, $options, $default = null ) {
if ( null === $default ) {
$option_one = '';
$option_two = '';
} elseif ( $options[0] == $default ) {
$option_one = ' checked="checked"';
$option_two = '';
} elseif ( $options[1] == $default ) {
$option_one = '';
$option_two = ' checked="checked"';
} else {
$option_one = '';
$option_two = '';
}
$out = '<fieldset class="form-group">
<div class="form-check">
<label class="form-check-label">
<input type="radio" class="" name="' . $name . '" id="' . $name . '" value="' . $options[0] . '"' . $option_one . '>
Yes
</label>
<label class="form-check-label">
<input type="radio" class="" name="' . $name . '" id="' . $name . '" value="' . $options[1] . '"' . $option_two . '>
No
</label>
</div>
</fieldset>';
return $out;
}
}

143
vendor/houdini/classes/issues.php vendored Normal file
View File

@ -0,0 +1,143 @@
<?php
/**
* core/template/issues.php
*
* This class is for managing template issues.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/Core
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Houdini\Classes;
use TheTempusProject\Houdini\Classes\Template;
class Issues {
private static $hasIssues = false;
private static $success = [];
private static $notice = [];
private static $error = [];
private static $info = [];
/**
* Returns the prepared message html.
*
* @return {string}
*/
public static function add( $type, $messages, $parse = true ) {
if ( ! is_array( $messages ) ) {
$messages = [ $messages => '' ];
}
foreach ( $messages as $parent => $child ) {
$out = self::filters( $parent );
if ( !empty( $child ) ) {
$out .= '<ul>';
if ( ! is_array( $child ) ) {
$child = [ $child ];
}
foreach ( $child as $children ) {
$out .= '<li>' . $children . '</li>';
}
$out .= '</ul>';
}
if ( $parse ) {
$out = Template::parse( $out );
}
self::$type( $out );
}
}
private static function filters( $data ) {
$data = preg_replace( '#\{#', '&#123;', $data );
$data = preg_replace( '#\}#', '&#125;', $data );
$data = preg_replace( '#\$#', '&#36;', $data );
return $data;
}
/**
* Adds a success message to the issues list.
*
* @param {string} [$message]
*/
private static function success( $message ) {
self::$hasIssues = true;
self::$success[] = $message;
}
/**
* Adds a warning message to the issues list.
*
* @param {string} [$message]
*/
private static function notice( $message ) {
self::$hasIssues = true;
self::$notice[] = $message;
}
/**
* Adds an info message to the issues list.
*
* @param {string} [$message]
*/
private static function info( $message ) {
self::$hasIssues = true;
self::$info[] = $message;
}
/**
* Adds an error message to the issues list.
*
* @param {string} [$message]
*/
private static function error( $message ) {
self::$hasIssues = true;
self::$error[] = $message;
}
/**
* This is the function that tells the application if we have
* have any messages to display or not.
*
* @return {bool}
*/
public static function hasIssues() {
return self::$hasIssues;
}
/**
* Returns the success message array.
*
* @return {string}
*/
public static function getSuccessMessages() {
return self::$success;
}
/**
* Returns the warning message array.
*
* @return {string}
*/
public static function getNoticeMessages() {
return self::$notice;
}
/**
* Returns the error message array.
*
* @return {string}
*/
public static function getErrorMessages() {
return self::$error;
}
/**
* Returns the info message array.
*
* @return {string}
*/
public static function getInfoMessages() {
return self::$info;
}
}

38
vendor/houdini/classes/loader.php vendored Normal file
View File

@ -0,0 +1,38 @@
<?php
/**
* core/template/navigation.php
*
* This class is for managing template navigation including menus, pagination, and breadcrumbs.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/Core
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Houdini\Classes;
use TheTempusProject\Houdini\Classes\Components;
class Loader {
protected $cssIncludes = [];
protected $jsIncludes = [];
public function buildComponents() {
Components::append( 'TEMPLATE_CSS_INCLUDES', implode( "\n", $this->cssIncludes ) );
Components::append( 'TEMPLATE_JS_INCLUDES', implode( "\n", $this->jsIncludes ) );
}
public function addCss( $text, $parse = true ) {
if ( $parse ) {
$text = Template::parse( $text );
}
$this->cssIncludes[] = $text;
}
public function addJs( $text, $parse = true ) {
if ( $parse ) {
$text = Template::parse( $text );
}
$this->jsIncludes[] = $text;
}
}

211
vendor/houdini/classes/navigation.php vendored Normal file
View File

@ -0,0 +1,211 @@
<?php
/**
* core/template/navigation.php
*
* This class is for managing template navigation including menus, pagination, and breadcrumbs.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/Core
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Houdini\Classes;
use TheTempusProject\Hermes\Functions\Route as Routes;
use TheTempusProject\Canary\Canary as Debug;
class Navigation extends Template {
public static $menus_array = [];
public static $collapse_count = 0;
public static function normalizeLinkArray( $link ) {
$normal_link = [];
if ( !isset( $link['text'] ) ) {
Debug::info( 'You must provide link text when extending the main menu.' );
return false;
}
$normal_link['text'] = Components::parse( $link['text'] );
if ( empty( $link['url'] ) ) {
$normal_link['url'] = '#';
} elseif ( is_array( $link['url'] ) ) {
$normal_link['url'] = $link['url'];
} else {
$normal_link['url'] = Components::parse( $link['url'] );
}
if ( !isset( $link['filter'] ) ) {
$normal_link['filter'] = '';
} else {
$normal_link['filter'] = $link['filter'];
}
return $normal_link;
}
public static function addMenu( $name ) {
if ( !isset( self::$menus_array[ $name ] ) ) {
self::$menus_array[ $name ] = [];
}
}
public static function addLink( $menuName, $link ) {
if ( !isset( self::$menus_array[ $menuName ] ) ) {
Debug::debug( 'menu link mot found, creating new:' . $menuName);
self::addMenu( $menuName );
}
self::$menus_array[ $menuName ][] = self::normalizeLinkArray( $link );
}
public static function getListItem( $link, $class = '' ) {
$link = self::normalizeLinkArray( $link );
if ( empty( $link ) ) {
return '';
}
if ( ! empty( $class ) ) {
$class = ' class="' . $class . '"';
}
// this is a good idea but it breaks active page select because the regex is not equipped to deal with the inclusion of a 'class' field in the list items field
// $list_item_class = ''; # the class for individual list items
$data = '<li'.$class.'><a href="' . $link['url'] . '">' . $link['text'] . '</a></li>';
if ( !empty( $link['filter'] ) ) {
$data = '{' . strtoupper($link['filter']) . '}'.$data.'{/' . strtoupper($link['filter']) . '}';
$data = Filters::apply( $data );
}
return $data;
}
public static function getMenuView( $nav_view, $list_component_name, $menu_name, $should_set_active_page = true ) {
if ( empty( self::$menus_array[$menu_name] ) ) {
Debug::error( 'menu not found: ' . $menu_name );
return '';
}
$list = '';
foreach ( self::$menus_array[$menu_name] as $key => $link ) {
if ( ! empty( $link) && is_array( $link['url'] ) ) {
self::$collapse_count++;
$sub_list = '';
foreach ( $link['url'] as $key => $sub_link ) {
$sub_list .= self::getListItem( $sub_link, 'submenu' );
}
$list .= '<li>
<a href="javascript:;" data-toggle="collapse" data-target="#menu-collapse-' . self::$collapse_count . '">
' . $link['text'] . '<i class="fa fa-fw fa-caret-down"></i>
</a>
<ul id="menu-collapse-' . self::$collapse_count . '" class="collapse">' . $sub_list . '</ul>
</li>';
continue;
}
$list .= self::getListItem( $link );
}
Components::set( $list_component_name, $list );
if ( true === $should_set_active_page ) {
$out = self::activePageSelect( $nav_view );
} else {
$out = Views::simpleView( $nav_view );
}
return $out;
}
public static function setCrumbComponent( $breadcrumb_component, $url ) {
// @todo this should be some sort of other thing or not let url be empty
$esplodade = explode( '/', $url );
$allCrumbs = '';
$previousCrumb = '';
foreach ( $esplodade as $key => $crumb ) {
if ( 'delete' === substr( $crumb, 0, 6 ) ) {
break;
}
if ( !empty( $previousCrumb ) ) {
$allCrumbs .= ' <b>></b> ';
$previousCrumb = trim( $previousCrumb ) . '/' . $crumb;
} else {
$previousCrumb = $crumb;
}
$url = Routes::getAddress() . $previousCrumb;
if ( 'create' === substr( $crumb, 0, 6 ) ||
'view' === substr( $crumb, 0, 4 ) ||
$url === Routes::getRequestUrl() ||
'edit' === substr( $crumb, 0, 4 ) ) {
$allCrumbs .= '<b>' . ucfirst( $crumb ) . '</b>';
break;
}
$allCrumbs .= '<a href="' . $url . '">' . ucfirst( $crumb ) . '</a>';
}
Components::set( $breadcrumb_component, $allCrumbs );
}
/**
* This function parses either given html or the current page content and sets
* the current active page to selected within an html list.
*
* @param string $menu - The name of the view you wish to add. can be any arbitrary value if $view is
* provided.
* @param string $selectString - The string/url you are searching for, default model/controller is used if none is
* provided.
* @param string $view - The html you want parsed, view is generated from menu name if $view is left blank
*
* @return string|bool - returns bool if the menu was added to the page content or
* returns the parsed view if one was provided with the
* function call.
*/
public static function activePageSelect( $menu, $selectString = null, $addToContent = false, $use_included_html = false ) {
$regSelect = null;
if ( false === $use_included_html ) {
$view = Views::simpleView( $menu );
} else {
$view = $menu;
}
if ( $selectString == null ) {
$selectString = ltrim( Routes::getUri(false), '/' );
}
$explodedUrl = explode( '/', $selectString );
$variations = [
Routes::getRequestUrl(),
Routes::getUri(),
Routes::getUri(false),
Routes::getAddress() . $selectString,
Routes::getAddress() . $explodedUrl[0],
$selectString,
$explodedUrl[0],
'/' . $explodedUrl[0],
'/' . $explodedUrl[0] . '/',
$explodedUrl[0] . '/index',
'/' . $explodedUrl[0] . '/index',
'/' . $explodedUrl[0] . '/index/',
];
foreach ( $variations as $url ) {
$regex = "#(.*)<li(?: class=\")?(.*?)(?:\")?>\s*?<a href=\"$url\"(.*)#is";
if ( preg_match( $regex, $view ) ) {
$regSelect = $url;
break;
}
}
if ( !empty( $regSelect ) ) {
$regSelect = preg_quote($regSelect);
$regActive = "$1<li class=\"$2 active\"><a href=\"$regSelect\"$3";
$view = preg_replace( $regex, $regActive, $view );
$parentRegex = "#(.*)class=\"collapse(.*?)<li class=\"submenu active\">\s*<a href=\"$regSelect\"(.*)#is";
if ( preg_match( $parentRegex, $view ) ) {
$expandRegex = "$1 class=\"expand$2<li class=\"submenu active\"><a href=\"$regSelect\"$3";
$view = preg_replace( $parentRegex, $expandRegex, $view );
}
if ( !empty( $addToContent ) ) {
self::$content .= $view;
return true;
}
}
return $view;
}
}

224
vendor/houdini/classes/pagination.php vendored Normal file
View File

@ -0,0 +1,224 @@
<?php
/**
* core/template/pagination.php
*
* This class is for managing template pagination.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/Core
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Houdini\Classes;
use TheTempusProject\Houdini\Classes\Template;
use TheTempusProject\Hermes\Functions\Route as Routes;
use TheTempusProject\Bedrock\Functions\Input;
use TheTempusProject\Bedrock\Classes\Config;
use TheTempusProject\Bedrock\Functions\Check;
use TheTempusProject\Canary\Canary as Debug;
class Pagination extends Template {
//The settings that will not change
public static $paginationSettings = [];
//The instance for each generation
public static $instance = null;
public function __construct() {
if ( empty( self::$paginationSettings['limit'] ) ) {
$this->loadSettings();
}
// check for user settings
if ( empty( self::$paginationSettings['perPage'] ) ) {
self::$paginationSettings['perPage'] = DEFAULT_RESULTS_PER_PAGE;
if ( ( !empty( self::$paginationSettings['userPerPage'] ) ) && ( self::$paginationSettings['userPerPage'] <= self::$paginationSettings['maxPerPage'] ) ) {
self::$paginationSettings['perPage'] = self::$paginationSettings['userPerPage'];
}
}
// The query minimum and maximum based on current page and page limit
if ( self::$paginationSettings['currentPage'] == 1 ) {
self::$paginationSettings['min'] = 0;
} else {
self::$paginationSettings['min'] = ( ( self::$paginationSettings['currentPage'] - 1 ) * self::$paginationSettings['perPage'] );
}
// if ( self::$paginationSettings['currentPage'] == 1 ) {
self::$paginationSettings['max'] = self::$paginationSettings['perPage'];
// } else {
// self::$paginationSettings['max'] = ( self::$paginationSettings['currentPage'] * self::$paginationSettings['perPage'] );
// }
// The query limit based on our settings here
self::$paginationSettings['limit'] = [self::$paginationSettings['min'], self::$paginationSettings['max']];
}
private static function loadSettings() {
Debug::log( 'Loading Pagination Settings.' );
// hard cap built into system for displaying results
self::$paginationSettings['maxPerPage'] = MAX_RESULTS_PER_PAGE;
// hard cap built into system retrieving results
self::$paginationSettings['maxQuery'] = Config::getValue( 'database/dbMaxQuery' );
// Set max query to the lowest of the three settings since this will modify how many results are possible.
if ( self::$paginationSettings['maxQuery'] <= self::$paginationSettings['maxPerPage'] ) {
self::$paginationSettings['maxPerPage'] = self::$paginationSettings['maxQuery'];
}
// Check for results request to set/modify the perPage setting
if ( Input::exists( 'results' ) ) {
if ( Check::ID( Input::get( 'results' ) ) ) {
if ( Input::get( 'results' ) <= self::$paginationSettings['maxPerPage'] ) {
self::$paginationSettings['perPage'] = Input::get( 'results' );
}
}
}
if ( empty( self::$paginationSettings['perPage'] ) ) {
self::$paginationSettings['perPage'] = self::$paginationSettings['maxPerPage'];
}
// Check for pagination in get
if ( Input::exists( 'page' ) ) {
if ( Check::ID( Input::get( 'page' ) ) ) {
self::$paginationSettings['currentPage'] = (int) Input::get( 'page' );
} else {
self::$paginationSettings['currentPage'] = 1;
}
} else {
self::$paginationSettings['currentPage'] = 1;
}
if ( ( self::$paginationSettings['currentPage'] - 3 ) > 1 ) {
self::$paginationSettings['firstPage'] = ( self::$paginationSettings['currentPage'] - 2 );
} else {
self::$paginationSettings['firstPage'] = 1;
}
}
public static function generate() {
// account for empty values here instead of inside the script.
Debug::log( 'Creating new Pagination Instance.' );
self::$instance = new self();
return self::$instance;
}
public static function updatePaginationTotal( $count ) {
if ( empty( self::$paginationSettings ) ) {
self::generate();
}
if ( Check::id( $count ) ) {
Debug::log( 'Pagination: Updating results count' );
self::$paginationSettings['results'] = $count;
self::$paginationSettings['totalPages'] = ceil( ( self::$paginationSettings['results'] / self::$paginationSettings['perPage'] ) );
if ( ( self::$paginationSettings['currentPage'] + 3 ) < self::$paginationSettings['totalPages'] ) {
self::$paginationSettings['lastPage'] = self::$paginationSettings['currentPage'] + 3;
} else {
self::$paginationSettings['lastPage'] = self::$paginationSettings['totalPages'];
}
Debug::info( 'Pagination: results update completed.' );
} else {
Debug::info( 'Pagination: results update failed.' );
}
}
public static function paginate() {
$pageData = [];
if ( self::firstPage() != 1 ) {
$data[1]['ACTIVEPAGE'] = '';
$data[1]['PAGENUMBER'] = 1;
$data[1]['LABEL'] = 'First';
$pageData[1] = (object) $data[1];
}
for ( $x = self::firstPage(); $x < self::lastPage(); $x++ ) {
if ( $x == self::currentPage() ) {
$active = ' class="active"';
} else {
$active = '';
}
$data[$x]['ACTIVEPAGE'] = $active;
$data[$x]['PAGENUMBER'] = $x;
$data[$x]['LABEL'] = $x;
$pageData[$x] = (object) $data[$x];
}
if ( self::lastPage() <= self::totalPages() ) {
$x = self::totalPages();
if ( $x == self::currentPage() ) {
$active = ' class="active"';
} else {
$active = '';
}
$data[$x]['ACTIVEPAGE'] = $active;
$data[$x]['PAGENUMBER'] = $x;
$data[$x]['LABEL'] = 'Last';
$pageData[$x] = (object) $data[$x];
}
$pageData = (object) $pageData;
if ( self::totalPages() <= 1 ) {
Components::set( 'PAGINATION', 'no pagination' );
} else {
Components::set( 'PAGINATION', Views::simpleView( 'nav.pagination', $pageData ) );
}
}
public static function updatePrefs( $pageLimit ) {
if ( Check::id( $pageLimit ) ) {
Debug::log( 'Pagination: Updating user pref' );
self::$paginationSettings['userPerPage'] = $pageLimit;
} else {
Debug::info( 'Pagination: User pref update failed.' );
}
}
/**
* Getters
*/
public static function getMin() {
if ( isset( self::$paginationSettings['min'] ) ) {
return self::$paginationSettings['min'];
} else {
Debug::info( 'Pagination: Min not found' );
return 0;
}
}
public static function getMax() {
if ( isset( self::$paginationSettings['max'] ) ) {
return self::$paginationSettings['max'];
} else {
Debug::info( 'Pagination: Max not found' );
return 0;
}
}
public static function perPage() {
if ( !empty( self::$paginationSettings['perPage'] ) ) {
return self::$paginationSettings['perPage'];
}
}
public static function firstPage() {
if ( !empty( self::$paginationSettings['firstPage'] ) ) {
return self::$paginationSettings['firstPage'];
} else {
Debug::info( 'Pagination: firstPage not found' );
}
}
public static function lastPage() {
if ( !empty( self::$paginationSettings['lastPage'] ) ) {
return self::$paginationSettings['lastPage'];
} else {
Debug::info( 'Pagination: lastPage not found' );
}
}
public static function totalPages() {
if ( !empty( self::$paginationSettings['totalPages'] ) ) {
return self::$paginationSettings['totalPages'];
} else {
Debug::info( 'Pagination: totalPages not found' );
}
}
public static function currentPage() {
if ( !empty( self::$paginationSettings['currentPage'] ) ) {
return self::$paginationSettings['currentPage'];
} else {
Debug::info( 'Pagination: currentPage not found' );
}
}
}

359
vendor/houdini/classes/template.php vendored Normal file
View File

@ -0,0 +1,359 @@
<?php
/**
* core/template.php
*
* This class is responsible for all visual output for the application.
* This class also contains all the functions for parsing data outputs
* into HTML, including: bbcodes, the data replacement structure, the
* filters, and other variables used to display application content.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/Core
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Houdini\Classes;
use TheTempusProject\Canary\Canary as Debug;
use TheTempusProject\Hermes\Functions\Route as Routes;
use TheTempusProject\Bedrock\Functions\Token;
use TheTempusProject\Bedrock\Functions\Date;
use TheTempusProject\Bedrock\Classes\Config;
use TheTempusProject\Bedrock\Classes\CustomException;
use TheTempusProject\Houdini\Classes\Components;
use TheTempusProject\Houdini\Classes\Forms;
use TheTempusProject\Houdini\Classes\Filters;
use TheTempusProject\Houdini\Classes\Issues;
use TheTempusProject\Houdini\Classes\Pagination;
class Template {
private static $follow = true;
private static $index = true;
private static $headers = [];
private static $additionalLocations = [];
private static $templateLocation = null;
protected static $content = null;
/**
* The constructor automatically sets a few $values and variables
* the template will need.
*/
public function __construct() {
Debug::group( 'Template Constructor', 1 );
Components::set( 'SITENAME', 'Houdini Site' );
Components::set( 'ROOT_URL', Routes::getRoot() );
Components::set( 'ROOT_ADDRESS', Routes::getAddress() );
Components::set( 'TITLE', '' );
Components::set( 'PAGE_DESCRIPTION', '' );
Components::set( 'TOKEN', Token::generate() );
Components::set( 'BASE', Routes::getAddress() );
Debug::gend();
}
private static function loadIssues() {
Filters::add( 'issues', '#{ISSUES}(.*?){/ISSUES}#is', ( Issues::hasIssues() ? '$1' : '' ), true );
$notices = implode( '<br>', Issues::getNoticeMessages() );
if ( !empty( $notices ) ) {
$notices = '<div class="alert alert-warning" role="alert">' . $notices . '</div>';
}
Components::set( 'NOTICE', $notices );
$successes = implode( '<br>', Issues::getSuccessMessages() );
if ( !empty( $successes ) ) {
$successes = '<div class="alert alert-success" role="alert">' . $successes . '</div>';
}
Components::set( 'SUCCESS', $successes );
$errors = implode( '<br>', Issues::getErrorMessages() );
if ( !empty( $errors ) ) {
$errors = '<div class="alert alert-danger" role="alert">' . $errors . '</div>';
}
Components::set( 'ERROR', $errors );
$infos = implode( '<br>', Issues::getInfoMessages() );
if ( !empty( $infos ) ) {
$infos = '<div class="alert alert-info" role="alert">' . $infos . '</div>';
}
Components::set( 'INFO', $infos );
}
public static function addTemplateLocation( $location ) {
self::$additionalLocations[] = $location;
return;
}
public static function getLocation() {
return self::$templateLocation;
}
/**
* This function sets the '<template>.tpl' to be used for the rendering of the
* application. It also calls the template include file via the Template::loadTemplate
* function and stores the keys to the $values array for the template to use later.
*
* @param string $name - The name of the template you are trying to use.
* ('.', and '_' are valid delimiters and the
* '.tpl' or '.inc.php' are not required.)
* @todo - Add a check for proper filename.
*/
public static function setTemplate( $name ) {
Debug::info( "Setting template: $name" );
$name = strtolower( str_replace( '.', '_', $name ) );
$location = TEMPLATE_DIRECTORY . $name . DIRECTORY_SEPARATOR;
$docLocation = $location . $name . '.tpl';
if ( file_exists( $docLocation ) ) {
self::$templateLocation = $docLocation;
return self::loadTemplate( $location, $name );
}
foreach ( self::$additionalLocations as $key => $location ) {
$docLocation = $location . $name . '.tpl';
if ( file_exists( $docLocation ) ) {
self::$templateLocation = $docLocation;
return self::loadTemplate( $location, $name );
}
}
new CustomException( 'template', $docLocation );
}
/**
* Checks for, requires, and instantiates the template include file
* and constructor for the specified template. Uses the class templateName
* if none is provided.
*
* @param string $name - A custom template name to load the include for.
* @return array - Returns the values object from the loader file,
* or an empty array.
* @todo - Add a check for proper filename.
*/
private static function loadTemplate( $path, $name ) {
Debug::group( 'Template Loader', 1 );
$fullPath = $path . $name . '.inc.php';
$className = APP_SPACE . '\\Templates\\' . ucfirst( $name ) . 'Loader';
if ( !file_exists( $fullPath ) ) {
new CustomException( 'templateLoader', $fullPath );
} else {
Debug::log( 'Requiring template loader: ' . $name );
require_once $fullPath;
$loaderNameFull = $className;
Debug::log( 'Calling loader: ' . $className );
new $className;
}
Debug::gend();
}
/**
* Sets the current page as noFollow and rebuilds the robots meta tag.
*
* @param boolean $status - The desired state for noFollow.
*/
public static function noFollow( $status = false ) {
self::$follow = (bool) $status;
self::buildRobot();
}
/**
* Sets the current page as noIndex and rebuilds the robots meta tag.
*
* @param boolean $status - The desired state for noIndex.
*/
public static function noIndex( $status = false ) {
self::$index = (bool) $status;
self::buildRobot();
}
public static function addHeader( $header ) {
self::$headers[] = $header;
}
public static function removeHeader( $header ) {
if ( isset( self::$headers[$header] ) ) {
unset( self::$headers[$header] );
}
}
public static function buildHeaders() {
if ( empty( self::$headers ) ) {
return;
}
foreach ( self::$headers as $key => $header) {
header( $header );
}
}
/**
* Updates the component for ROBOT.
*/
public static function buildRobot() {
if ( !self::$index && !self::$follow ) {
Components::set( 'ROBOT', '<meta name="robots" content="noindex,nofollow">' );
} elseif ( !self::$index ) {
Components::set( 'ROBOT', '<meta name="robots" content="noindex">' );
} elseif ( !self::$follow ) {
Components::set( 'ROBOT', '<meta name="robots" content="nofollow">' );
} else {
Components::set( 'ROBOT', '' );
}
}
/**
* Prints the parsed and fully rendered page using the specified template from
* templateLocation.
* NOTE: This should be the only echo in the system.
*/
public static function render() {
self::loadIssues();
Components::set( 'CONTENT', self::$content );
self::buildRobot();
self::buildHeaders();
if ( empty( self::$templateLocation ) ) {
self::setTemplate( Config::getValue( 'main/template' ) );
}
if ( empty( self::$templateLocation ) ) {
self::setTemplate( Config::getValue( 'main/template' ) );
return;
}
if ( !Debug::status( 'render' ) ) {
return;
}
echo self::parse( file_get_contents( self::$templateLocation ) );
}
/**
* The loop function for the template engine's {loop}{/loop} tag.
*
* @param string $template The string being checked for a loop
* @param array $data the data being looped through
* @return string the filtered and completed LOOP
*/
public static function buildLoop( $template, $data = null ) {
$header = null;
$footer = null;
$final = null;
$loopAlternative = null;
$loop = '#.*{LOOP}(.*?){/LOOP}.*#is';
$loopTemplate = preg_replace( $loop, '$1', $template );
if ( $loopTemplate != $template ) {
//Separate off the header if it exists.
$header = trim( preg_replace( '#^(.*)?{LOOP}.*$#is', '$1', $template ) );
if ( $header === $template ) {
$header = null;
}
//Separate off the footer if it exists.
$footer = trim( preg_replace( '#^.*?{/LOOP}(.*)$#is', '$1', $template ) );
if ( $footer === $template ) {
$footer = null;
}
if ( !empty( $footer ) ) {
//Separate off the alternative to the loop if it exists.
$alt = '#{ALT}(.*?){/ALT}#is';
$loopAlternative = trim( preg_replace( $alt, '$1', $footer ) );
if ( $loopAlternative === $footer ) {
$loopAlternative = null;
} else {
$footer = trim( preg_replace( '#^.*?{/ALT}(.*)$#is', '$1', $footer ) );
}
}
}
if ( !empty( $data ) ) {
//iterate through the data as instances.
foreach ( $data as $instance ) {
$x = 0;
//reset the template for every iteration of $data.
$modifiedTemplate = $loopTemplate;
if ( !is_object( $instance ) ) {
$instance = $data;
$end = 1;
}
//loop the template as many times as we have data for.
foreach ( $instance as $key => $value ) {
if ( !is_object( $value ) ) {
$tagPattern = "~{($key)}~i";
if ( is_array( $value ) || null === $value ) {
$value = '';
}
$modifiedTemplate = preg_replace( $tagPattern, $value, $modifiedTemplate );
}
}
//since this loop may have a header, and/or footer, we have to define the final output of the loop.
$final .= $modifiedTemplate;
if ( $x === 0 ) {
$singlePattern = '#{SINGLE}(.*?){/SINGLE}#is';
//If there is a {SINGLE}{/SINGLE} tag, we will replace it on the first iteration.
$final = preg_replace( $singlePattern, '$1', $final );
//Same practice, but for the entry template.
$loopTemplate = preg_replace( $singlePattern, '', $loopTemplate );
$x++;
}
//Since $data is only for a single data set, we break the loop.
if ( isset( $end ) ) {
unset( $end );
$output = $header . $final . $footer;
break;
}
}
$output = $header . $final . $footer;
} else {
if ( !empty( $loopAlternative ) ) {
$output = $header . $loopAlternative;
} else {
$output = $header . $loopTemplate . $footer;
}
}
return $output;
}
/**
* This is the main function of the template engine.
* this function parses the given view and replaces
* all of the necessary components with their processed
* counterparts.
*
* @param string $template - The html that needs to be parsed.
* @param array|object $data - An associative array or object that will
* be used as components for the provided html.
* @return string - The fully parsed html output.
*/
public static function parse( $template, $data = null, $flags = null ) {
if ( empty( $template ) ) {
return $template;
}
//Check for a {LOOP}{/LOOP} tag.
$template = self::buildLoop( $template, $data );
$template = Components::parse( $template );
if ( strpos( $template, '{OPTION=' ) !== false ) {
foreach ( Forms::$options as $key => $value ) {
$template = preg_replace( $key, $value, $template, 1 );
}
$template = preg_replace( '#\{OPTION\=(.*?)\}#is', '', $template );
}
//Convert any dates into preferred Date/Time format. User preference will be applied her in the future.
// @todo - there must be something to migrate this ability from the top to the bottom when a user has a pref
$dtc = '#{DTC(.*?)}(.*?){/DTC}#is';
$template = preg_replace_callback(
$dtc,
function ( $data ) {
if ( empty( $data[2] ) ) {
return '';
}
return Date::formatTimestamp( $data[1], $data[2] );
},
$template
);
//Run through our full list of generated filters.
$template = Filters::apply( $template );
return $template;
}
}

112
vendor/houdini/classes/views.php vendored Normal file
View File

@ -0,0 +1,112 @@
<?php
/**
* core/template/views.php
*
* This class is for managing template views.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/Core
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Houdini\Classes;
use TheTempusProject\Canary\Canary as Debug;
class Views extends Template {
public static $additionalLocations = [];
/**
* This function adds a standard view to the main {CONTENT}
* section of the page.
*
* @param string $viewName - The name of the view being called.
* @param wild $data - Any data to be used with the view.
*
* @todo add a check to viewName
*/
public static function view( $viewName, $data = null ) {
if ( !empty( $data ) ) {
$out = self::simpleView( $viewName, $data );
} else {
$out = self::simpleView( $viewName );
}
if ( !empty( $out ) ) {
self::$content .= $out;
} else {
// new CustomException( 'view', $viewName );
}
}
public static function raw( $html ) {
$out = self::parse( $html );
self::$content .= $out;
}
/**
* Returns a completely parsed view.
*
* NOTE: Results will contain raw HTML.
*
* @param {string} [$view] - The name of the view you wish to call.
* @param {var} [$data] - Any data to be used by the view.
* @return {string} HTML view.
*/
public static function simpleView( $view, $data = null ) {
Debug::log( "Calling Standard: $view" );
// all views start with lowercase letters
$lowerCase = lcfirst( $view );
// convert ., \, and /, to DIRECTORY_SEPARATOR
$normalized = str_replace( '.', DIRECTORY_SEPARATOR, $lowerCase );
$normalized = str_replace( '\\', DIRECTORY_SEPARATOR, $normalized );
$normalized = str_replace( '/', DIRECTORY_SEPARATOR, $normalized );
// trim any hanging DIRECTORY_SEPARATOR (shouldn't be necessary)
$trimmed = rtrim( $normalized, DIRECTORY_SEPARATOR );
// add the html extension
$viewName = $trimmed . '.html';
// check the main views directory
$path = VIEW_DIRECTORY . $viewName;
Debug::log( "Trying location: $path" );
if ( is_file( $path ) ) {
if ( !empty( $data ) ) {
return self::parse( file_get_contents( $path ), $data );
} else {
return self::parse( file_get_contents( $path ) );
}
}
// if the first part of the view name matches the name of an additionalLocation Index, we check there too
$exploded = explode( DIRECTORY_SEPARATOR, $viewName );
$potentialKey = array_shift( $exploded );
$imploded = implode( DIRECTORY_SEPARATOR, $exploded );
Debug::debug( "Trying potentialKey: $potentialKey" );
Debug::debug( "Trying imploded: $imploded" );
Debug::debug( 'additionalLocations: ' . var_export( self::$additionalLocations, true ) );
if ( !empty( self::$additionalLocations[$potentialKey] ) ) {
$path = self::$additionalLocations[$potentialKey] . $imploded;
Debug::debug( "Trying path: $path" );
}
if ( is_file( $path ) ) {
Debug::log( "WINNER path: $path" );
if ( !empty( $data ) ) {
return self::parse( file_get_contents( $path ), $data );
} else {
return self::parse( file_get_contents( $path ) );
}
}
// @todo - this would be awesome, if i actually caught the exception anywhere :/
// throw new CustomException('simpleView', $path);
return false;
}
public static function addViewLocation( $name, $location ) {
self::$additionalLocations[$name] = $location;
}
public static function removeViewLocation( $name ) {
if ( ! empty( self::$additionalLocations[$name] ) ) {
unset( self::$additionalLocations[$name] );
}
}
}