Initial commit
This commit is contained in:
46
vendor/houdini/CODE_OF_CONDUCT.md
vendored
Normal file
46
vendor/houdini/CODE_OF_CONDUCT.md
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at webmaster@thetempusproject.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
88
vendor/houdini/CONTRIBUTING.md
vendored
Normal file
88
vendor/houdini/CONTRIBUTING.md
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
# Contribution Guidelines for TempusDebugger
|
||||
Contributing to TempusDebugger is completely voluntary and should follow all of the guidelines listed here in order to ensure the highest probability of acceptance. It is highly recommended to use a php linter to automate more of this process. The project is maintained on github and all contributions need to be submitted via pull request to their specific repository under the `dev` branch. In order to contribute, simply follow the instructions for [creating a pull request](#creating-a-pull-request) below.
|
||||
|
||||
## Pull Request Requirements
|
||||
- All revisions must follow TTP naming conventions (see [Naming Conventions](#naming-conventions) Section)
|
||||
- Include a clear and concise explanation of the features or changes included in your revision listed by file.
|
||||
- All code must follow [PSR 2](http://www.php-fig.org/psr/psr-2/) standards
|
||||
- prefer the use of [] for arrays over array()
|
||||
- All functions must be documented with the exception of controller methods (see [Documentation](#documentation) Section)
|
||||
- Controller methods may be doc-blocked when necessary for clarity (see [Documentation](#documentation) Section)
|
||||
- All new Classes must include a class level doc-block (see [Documentation](#documentation) Section)
|
||||
- Any new dependencies will have a longer validation process and should be accompanied by the required information (see [Dependencies](#dependencies) Section)
|
||||
|
||||
## Naming Conventions
|
||||
- File names are to be lower case
|
||||
- All class names must be upper case
|
||||
- Any data being stored as a file must be saved in the `app/` directory, preferably the `app/config/` directory.
|
||||
- Controllers must have a constructor and destructor incorporating the constructor and destructor in the Resources Controller
|
||||
- (This will be an interface requirement soon)
|
||||
- Views must be named using underscores for separation and must be prefixed with view_
|
||||
|
||||
## Dependencies
|
||||
Whenever a dependency is updated or added, pull requests must include a section that answers the following questions.
|
||||
- Why is this dependency required
|
||||
- Could this be reasonably accomplished within the app by implementing new features in a later version? explain.
|
||||
- What is the latest stable version that can be used
|
||||
- What features are absolutely necessary for your feature or modification to work
|
||||
|
||||
## Documentation
|
||||
### Classes
|
||||
|
||||
New classes must be prefaced with a doc-block following this style:
|
||||
```
|
||||
/**
|
||||
* controllers/admin.php
|
||||
*
|
||||
* This is the admin controller.
|
||||
*
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com/TempusDebugger
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
```
|
||||
|
||||
From top to bottom:
|
||||
- Filename on the second line
|
||||
- A description for the file
|
||||
- The TTP version this file was built for
|
||||
`@version 1.0`
|
||||
- The Authors name or alias and email
|
||||
`@author first last <email@link.com>`
|
||||
- A copy of the MIT license
|
||||
`@license https://opensource.org/licenses/MIT [MIT LICENSE]`
|
||||
- May include a link for more information
|
||||
`@link http://link.com`
|
||||
|
||||
### Functions
|
||||
Functions must be prefaced with a doc-block following this style:
|
||||
```
|
||||
/**
|
||||
* Intended as a self-destruct session. If the specified session does not
|
||||
* exist, it is created. If the specified session does exist, it will be
|
||||
* destroyed and returned.
|
||||
*
|
||||
* @param string $name - Session name to be created or checked
|
||||
* @param string $string - The string to be used if session needs to be
|
||||
* created. (optional)
|
||||
*
|
||||
* @return bool|string - Returns bool if creating, and a string if the
|
||||
* check is successful.
|
||||
*/
|
||||
```
|
||||
|
||||
From top to bottom:
|
||||
- There must be a description of the functions intended usage on the second line
|
||||
- All parameters should be documented like this
|
||||
`@param [type] $name - description`
|
||||
- Any function with a return statement must also be documented as such
|
||||
`@return [type] - description`
|
||||
|
||||
## Creating a Pull Request
|
||||
This is a simple explanation of how to create a pull request for changes to TempusDebugger. You can find a detailed walk-through on how to [create a pull request](https://help.github.com/articles/creating-a-pull-request/) on github.
|
||||
|
||||
1. First ensure you have followed all the contributing guidelines
|
||||
2. Squash your merge into a single revision. This will make it easier to view the changes as a whole.
|
||||
3. You can submit a pull request [here](https://github.com/TheTempusProject/TempusDebugger/compare)
|
||||
4. Please submit all pull requests to the dev branch or they will be ignored.
|
18
vendor/houdini/README.md
vendored
Normal file
18
vendor/houdini/README.md
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
# Houdini
|
||||
Houdini is a php templating engine designed in conjunction with [The Tempus Project](https://thetempusproject.com). Honestly, I do not know how to explain it other than to show you.
|
||||
|
||||
## Installation
|
||||
You can install houdini either using composer or its included autoload functionality
|
||||
|
||||
## Usage
|
||||
|
||||
### Components
|
||||
### Filters
|
||||
### Forms
|
||||
### Issues
|
||||
### Navigation
|
||||
### Pagination
|
||||
### Views
|
||||
|
||||
## Settings
|
||||
|
34
vendor/houdini/bin/autoload.php
vendored
Normal file
34
vendor/houdini/bin/autoload.php
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/**
|
||||
* bin/autoload.php
|
||||
*
|
||||
* Handles the initial setup like autoloading, basic functions, constants, etc.
|
||||
*
|
||||
* @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;
|
||||
|
||||
use TheTempusProject\Hermes\Classes\Autoloader;
|
||||
|
||||
if ( ! defined('HOUDINI_ROOT_DIRECTORY' ) ) {
|
||||
define('HOUDINI_ROOT_DIRECTORY', dirname(__DIR__) . DIRECTORY_SEPARATOR);
|
||||
}
|
||||
if ( ! defined('HOUDINI_CONFIG_DIRECTORY' ) ) {
|
||||
define('HOUDINI_CONFIG_DIRECTORY', BEDROCK_ROOT_DIRECTORY . 'config' . DIRECTORY_SEPARATOR);
|
||||
}
|
||||
if ( ! defined('HOUDINI_CONSTANTS_LOADED' ) ) {
|
||||
require_once HOUDINI_CONFIG_DIRECTORY . 'constants.php';
|
||||
}
|
||||
|
||||
$autoloader = new Autoloader;
|
||||
$autoloader->setRootFolder( HOUDINI_ROOT_DIRECTORY );
|
||||
$autoloader->addNamespace(
|
||||
'TheTempusProject\Houdini\Classes',
|
||||
'classes'
|
||||
);
|
||||
$autoloader->register();
|
||||
|
||||
define( 'HOUDINI_AUTOLOADED', true );
|
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] );
|
||||
}
|
||||
}
|
||||
}
|
26
vendor/houdini/composer.json
vendored
Normal file
26
vendor/houdini/composer.json
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "thetempusproject/houdini",
|
||||
"type": "library",
|
||||
"description": "Php functions that aid in creating, managing, and displaying frontend components.",
|
||||
"license": "MIT",
|
||||
"minimum-stability": "dev",
|
||||
"keywords": ["php","tools","frontend","thetempusproject"],
|
||||
"homepage": "https://github.com/TheTempusProject/Houdini",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Joey Kimsey",
|
||||
"email": "Joey@thetempusproject.com",
|
||||
"homepage": "https://TheTempusProject.com",
|
||||
"role": "Lead Developer"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=8.1.0"
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"classes"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
10
vendor/houdini/config/constants.php
vendored
Normal file
10
vendor/houdini/config/constants.php
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
// Directories
|
||||
if ( !defined( 'HOUDINI_ROOT_DIRECTORY' ) ) {
|
||||
define( 'HOUDINI_ROOT_DIRECTORY', dirname( __DIR__ ) . DIRECTORY_SEPARATOR );
|
||||
}
|
||||
if ( ! defined('HOUDINI_CONFIG_DIRECTORY' ) ) {
|
||||
define('HOUDINI_CONFIG_DIRECTORY', HOUDINI_ROOT_DIRECTORY . 'config' . DIRECTORY_SEPARATOR);
|
||||
}
|
||||
// # Tell the app all constants have been loaded.
|
||||
define( 'HOUDINI_CONSTANTS_LOADED', true );
|
7
vendor/houdini/notes.md
vendored
Normal file
7
vendor/houdini/notes.md
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
|
||||
From default Template:
|
||||
$this->cssIncludes[] = Template::parse('<link rel="stylesheet" href="{BOOTSTRAP_CDN}css/bootstrap-theme.min.css" crossorigin="anonymous">');
|
||||
$this->jsIncludes[] = Template::parse('<script language="JavaScript" crossorigin="anonymous" type="text/javascript" src="https://code.jquery.com/jquery-2.2.4.min.js"></script>');
|
||||
|
||||
|
Reference in New Issue
Block a user