Initial commit
This commit is contained in:
53
vendor/houdini/classes/components.php
vendored
Normal file
53
vendor/houdini/classes/components.php
vendored
Normal 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
219
vendor/houdini/classes/email.php
vendored
Normal 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
139
vendor/houdini/classes/filters.php
vendored
Normal 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
193
vendor/houdini/classes/forms.php
vendored
Normal 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
143
vendor/houdini/classes/issues.php
vendored
Normal 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( '#\{#', '{', $data );
|
||||
$data = preg_replace( '#\}#', '}', $data );
|
||||
$data = preg_replace( '#\$#', '$', $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
38
vendor/houdini/classes/loader.php
vendored
Normal 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
211
vendor/houdini/classes/navigation.php
vendored
Normal 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
224
vendor/houdini/classes/pagination.php
vendored
Normal 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
359
vendor/houdini/classes/template.php
vendored
Normal 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
112
vendor/houdini/classes/views.php
vendored
Normal 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] );
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user