Compare commits

...

1 Commits
4.1.1 ... 3.0

Author SHA1 Message Date
9a2ade1857 fixes to support composer / packagist 2024-08-08 23:32:26 -04:00
68 changed files with 369 additions and 8612 deletions

5
.gitignore vendored
View File

@ -54,14 +54,11 @@ Temporary Items
# TheTempusProject Specific
.htaccess
composer.lock
app/config/*
!app/config/constants.php
app/install.json
app/config.default.json
uploads/images/*
.env
logs/*
.vscode/
mail.log
vendor/canary/logs/*
docker/.env

View File

@ -17,6 +17,7 @@ use TheTempusProject\Houdini\Classes\Pagination;
use TheTempusProject\TheTempusProject as App;
use TheTempusProject\Models\User;
use TheTempusProject\Models\Sessions;
use TheTempusProject\Bedrock\Functions\Token;
class Controller extends BedrockController {
public static $user;
@ -33,6 +34,7 @@ class Controller extends BedrockController {
}
new Template;
Template::setTemplate( 'default' );
Components::set( 'TOKEN', Token::generate() );
}
public function __destruct() {

View File

@ -1,10 +1,16 @@
{
"name": "thetempusproject/thetempusproject",
"description": "The aim of this project is to provide a simple and stable platform for rapidly prototyping new web applications.",
"type": "project",
"description": "The aim of this project is to provide a simple and stable platform for rapidly prototyping new web applications.",
"keywords":
[
"thetempusproject",
"framework"
],
"license": "MIT",
"homepage": "https://TheTempusProject.com",
"authors": [
"authors":
[
{
"name": "Joey Kimsey",
"email": "Joey@thetempusproject.com",
@ -12,19 +18,39 @@
"role": "Lead Developer"
}
],
"minimum-stability": "dev",
"require": {
"require":
{
"fortawesome/font-awesome": "4.7",
"thetempusproject/bedrock": "1.0",
"thetempusproject/canary": "1.0",
"thetempusproject/houdini": "1.0",
"thetempusproject/bedrock": "dev-main",
"thetempusproject/canary": "dev-main",
"thetempusproject/houdini": "dev-main",
"twbs/bootstrap": "3.3.7"
},
"autoload": {
"psr-4": {
"autoload":
{
"classmap":
[
"app/classes",
"app/functions",
"app/models"
],
"files":
[
"app/config/constants.php"
],
"psr-4":
{
"TheTempusProject\\Bedrock\\": "vendor/thetempusproject/bedrock",
"TheTempusProject\\Canary\\": "vendor/thetempusproject/canary",
"TheTempusProject\\Houdini\\": "vendor/thetempusproject/houdini"
}
}
}
},
"config":
{
"optimize-autoloader": true,
"preferred-install": "dist",
"sort-packages": true
},
"minimum-stability": "dev",
"prefer-stable": true
}

309
composer.lock generated Normal file
View File

@ -0,0 +1,309 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "8990675691531125da9ae6a4bef16a63",
"packages": [
{
"name": "fortawesome/font-awesome",
"version": "v4.7.0",
"source": {
"type": "git",
"url": "https://github.com/FortAwesome/Font-Awesome.git",
"reference": "a8386aae19e200ddb0f6845b5feeee5eb7013687"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/FortAwesome/Font-Awesome/zipball/a8386aae19e200ddb0f6845b5feeee5eb7013687",
"reference": "a8386aae19e200ddb0f6845b5feeee5eb7013687",
"shasum": ""
},
"require-dev": {
"jekyll": "1.0.2",
"lessc": "1.4.2"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.6.x-dev"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"OFL-1.1",
"MIT"
],
"authors": [
{
"name": "Dave Gandy",
"email": "dave@fontawesome.io",
"homepage": "http://twitter.com/davegandy",
"role": "Developer"
}
],
"description": "The iconic font and CSS framework",
"homepage": "http://fontawesome.io/",
"keywords": [
"FontAwesome",
"awesome",
"bootstrap",
"font",
"icon"
],
"support": {
"issues": "https://github.com/FortAwesome/Font-Awesome/issues",
"source": "https://github.com/FortAwesome/Font-Awesome/tree/v4.7.0"
},
"time": "2016-10-24T15:52:54+00:00"
},
{
"name": "thetempusproject/bedrock",
"version": "dev-main",
"source": {
"type": "git",
"url": "https://git.thetempusproject.com/the-tempus-project/bedrock",
"reference": "c75fc2105955ffb3af56f68ca156f81e51f89488"
},
"require": {
"php": ">=8.1.0",
"thetempusproject/canary": ">=1.0",
"thetempusproject/hermes": ">=1.0",
"thetempusproject/houdini": ">=1.0"
},
"default-branch": true,
"type": "library",
"autoload": {
"files": [
"config/constants.php",
"bin/bedrock.php"
],
"classmap": [
"classes",
"functions"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Joey Kimsey",
"email": "Joey@thetempusproject.com",
"homepage": "https://JoeyKimsey.com",
"role": "Lead Developer"
}
],
"description": "Bedrock is intended as the core functionality used by The Tempus Project: a rapid prototyping framework. This library utilizes the MVC architecture in addition to a custom templating engine designed to make building web applications simple.",
"homepage": "https://git.thetempusproject.com/the-tempus-project/bedrock",
"keywords": [
"framework",
"mvc"
],
"time": "2024-08-08T05:18:58+00:00"
},
{
"name": "thetempusproject/canary",
"version": "dev-main",
"source": {
"type": "git",
"url": "https://git.thetempusproject.com/the-tempus-project/canary",
"reference": "be5589533f8c1d0b1c28bac8829333f0077c698d"
},
"require": {
"php": ">=8.1.0"
},
"default-branch": true,
"type": "library",
"autoload": {
"files": [
"config/constants.php",
"bin/canary.php"
],
"classmap": [
"classes"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Joey Kimsey",
"email": "Joey@thetempusproject.com",
"homepage": "https://JoeyKimsey.com",
"role": "Lead Developer"
}
],
"description": "Functionality for tracking, logging, and sending log messages to chrome for debugging.",
"homepage": "https://git.thetempusproject.com/the-tempus-project/canary",
"keywords": [
"debugging",
"php",
"thetempusproject",
"tools"
],
"time": "2024-08-08T05:18:19+00:00"
},
{
"name": "thetempusproject/hermes",
"version": "dev-main",
"source": {
"type": "git",
"url": "https://git.thetempusproject.com/the-tempus-project/hermes",
"reference": "e38f8debefb7097b15cb479184dc869e3e3111c0"
},
"require": {
"php": ">=8.1.0"
},
"default-branch": true,
"type": "library",
"autoload": {
"files": [
"config/constants.php"
],
"classmap": [
"classes",
"functions"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Joey Kimsey",
"email": "Joey@thetempusproject.com",
"homepage": "https://JoeyKimsey.com",
"role": "Lead Developer"
}
],
"description": "Php functions that aid in routing and redirecting; requests and responses.",
"homepage": "https://git.thetempusproject.com/the-tempus-project/hermes",
"keywords": [
"php",
"routing",
"thetempusproject",
"tools"
],
"time": "2024-08-08T05:24:32+00:00"
},
{
"name": "thetempusproject/houdini",
"version": "dev-main",
"source": {
"type": "git",
"url": "https://git.thetempusproject.com/the-tempus-project/houdini",
"reference": "b2d044da64ca1869432dc12b9c98fdb60379ffd9"
},
"require": {
"php": ">=8.1.0",
"thetempusproject/canary": ">=1.0",
"thetempusproject/hermes": ">=1.0"
},
"default-branch": true,
"type": "library",
"autoload": {
"files": [
"config/constants.php"
],
"classmap": [
"classes"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Joey Kimsey",
"email": "Joey@thetempusproject.com",
"homepage": "https://JoeyKimsey.com",
"role": "Lead Developer"
}
],
"description": "Php functions that aid in creating, managing, and displaying frontend components.",
"homepage": "https://git.thetempusproject.com/the-tempus-project/houdini",
"keywords": [
"frontend",
"php",
"thetempusproject",
"tools"
],
"time": "2024-08-08T05:17:27+00:00"
},
{
"name": "twbs/bootstrap",
"version": "v3.3.7",
"source": {
"type": "git",
"url": "https://github.com/twbs/bootstrap.git",
"reference": "0b9c4a4007c44201dce9a6cc1a38407005c26c86"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/twbs/bootstrap/zipball/0b9c4a4007c44201dce9a6cc1a38407005c26c86",
"reference": "0b9c4a4007c44201dce9a6cc1a38407005c26c86",
"shasum": ""
},
"replace": {
"twitter/bootstrap": "self.version"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.3.x-dev"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jacob Thornton",
"email": "jacobthornton@gmail.com"
},
{
"name": "Mark Otto",
"email": "markdotto@gmail.com"
}
],
"description": "The most popular front-end framework for developing responsive, mobile first projects on the web.",
"homepage": "http://getbootstrap.com",
"keywords": [
"JS",
"css",
"framework",
"front-end",
"less",
"mobile-first",
"responsive",
"web"
],
"support": {
"issues": "https://github.com/twbs/bootstrap/issues",
"source": "https://github.com/twbs/bootstrap/tree/master"
},
"time": "2016-07-25T15:51:55+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "dev",
"stability-flags": {
"thetempusproject/bedrock": 20,
"thetempusproject/canary": 20,
"thetempusproject/houdini": 20
},
"prefer-stable": true,
"prefer-lowest": false,
"platform": [],
"platform-dev": [],
"plugin-api-version": "2.3.0"
}

View File

@ -9,20 +9,28 @@ server {
sendfile off;
client_max_body_size 100m;
location /images/ {
if (!-e $request_filename){
rewrite ^/images/(.*)$ /index.php?error=image404&url=$1 last;
}
location /js/ {
access_log off;
log_not_found off;
try_files $uri /index.php?error=js404&file=$uri;
}
location /css/ {
access_log off;
log_not_found off;
try_files $uri /index.php?error=css404&file=$uri;
}
location /images/ {
try_files $uri /index.php?error=image404&url=$uri;
}
location /uploads/ {
if (!-e $request_filename){
rewrite ^/uploads/(.*)$ /index.php?error=upload404&url=$1 last;
}
access_log off;
log_not_found off;
try_files $uri /index.php?error=upload404&url=$uri;
}
location /errors/ {
try_files $uri /index.php?error=$uri;
}
location ~* \.(?:js|css|png|jpg|gif|ico)$ {
@ -60,7 +68,6 @@ server {
}
location / {
rewrite ^/errors/(.*)$ /index.php?error=$1 last;
rewrite ^(.+)$ /index.php?url=$1 last;
rewrite ^/(.+)$ /index.php?url=$1&$args last;
}
}

2
vendor/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*
!.gitignore

View File

@ -1,47 +0,0 @@
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msm
*.msp
# Windows shortcuts
*.lnk
# =========================
# Operating System Files
# =========================
# OSX
# =========================
.DS_Store
.AppleDouble
.LSOverride
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk

View File

@ -1,46 +0,0 @@
# 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/

View File

@ -1,87 +0,0 @@
# Contribution Guidelines for Bedrock
Contributing to Bedrock 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 (with the exception of config which should be stored under config/)
- Controllers must have a constructor and destructor using the constructor and destructor methods found in resources/
- Views must be named using lowerCamelCase
## 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/Core
* @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 Bedrock. 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/Bedrock/compare)
4. Please submit all pull requests to the dev branch or they will be ignored.

View File

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2023 Joey Kimsey
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,31 +0,0 @@
# Tempus Project Core
###### Developer(s): Joey Kimsey
Bedrock is the core functionality used by [The Tempus Project](https://github.com/TheTempusProject/TheTempusProject) a rapid prototyping framework. This Library can be utilized outside of the TempusProject, but the functionality has not been tested well as a stand alone library.
This library utilizes the MVC architecture in addition to a custom templating engine designed to make building web applications fast and simple.
**Notice: This Library is provided as is, please use at your own risk.**
## Installation and Use
The easiest way to use Bedrock in your application is to install and initialize it via composer.
```
"require": {
"TheTempusProject/Bedrock": "*",
},
"autoload": {
"psr-4": {
"Bedrock\": "vendor/TheTempusProject/Bedrock"
}
}
```
If you prefer to handle auto-loading via other means, you can simply clone this repository wherever you need it. Please note, you will need to install and load the [TempusDebugger](https://github.com/thetempusproject/TempusDebugger) library in order to utilize the debug to console options.
### WIP:
- [ ] Expansion of PDO to allow different database types
- [ ] template stuff should really only be called from template/controllers
- [ ] Update installer to account for updates.
- [ ] Implement uniformity in terms of error reporting, exceptions, logging.

View File

@ -1,52 +0,0 @@
<?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/Core
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Bedrock;
use TheTempusProject\Hermes\Classes\Autoloader;
if ( ! defined('BEDROCK_ROOT_DIRECTORY' ) ) {
define('BEDROCK_ROOT_DIRECTORY', dirname(__DIR__) . DIRECTORY_SEPARATOR);
}
if ( ! defined('BEDROCK_CONFIG_DIRECTORY' ) ) {
define('BEDROCK_CONFIG_DIRECTORY', BEDROCK_ROOT_DIRECTORY . 'config' . DIRECTORY_SEPARATOR);
}
if ( ! defined('BEDROCK_CONSTANTS_LOADED' ) ) {
require_once BEDROCK_CONFIG_DIRECTORY . 'constants.php';
}
if ( ! class_exists( 'TheTempusProject\Bedrock\Classes\Autoloader' ) ) {
if ( file_exists( BEDROCK_CLASSES_DIRECTORY . 'autoloader.php' ) ) {
require_once BEDROCK_CLASSES_DIRECTORY . 'autoloader.php';
}
}
if ( ! class_exists( 'TheTempusProject\Bedrock\App' ) ) {
if ( file_exists( BEDROCK_ROOT_DIRECTORY . 'app.php' ) ) {
require_once BEDROCK_ROOT_DIRECTORY . 'app.php';
}
}
$autoloader = new Autoloader;
$autoloader->setRootFolder( BEDROCK_ROOT_DIRECTORY );
$autoloader->addNamespace(
'TheTempusProject\Bedrock',
'bin'
);
$autoloader->addNamespace(
'TheTempusProject\Bedrock\Classes',
'classes'
);
$autoloader->addNamespace(
'TheTempusProject\Bedrock\Functions',
'functions'
);
$autoloader->register();
define( 'BEDROCK_AUTOLOADED', true );

View File

@ -1,263 +0,0 @@
<?php
/**
* app.php
*
* This file parses any given url and separates it into controller,
* method, and data. This allows the application to direct the user
* to the desired location and provide the controller any additional
* information it may require to run.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/Core
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Bedrock;
use TheTempusProject\Canary\Canary as Debug;
use TheTempusProject\Hermes\Functions\Route as Routes;
use TheTempusProject\Bedrock\Functions\Input;
use TheTempusProject\Bedrock\Functions\Check;
use TheTempusProject\Bedrock\Functions\Token;
use TheTempusProject\Bedrock\Functions\Sanitize;
use TheTempusProject\Bedrock\Classes\Config;
use TheTempusProject\Hermes\Classes\Autoloader;
use TheTempusProject\Houdini\Classes\Template;
use TheTempusProject\Houdini\Classes\Components;
class Bedrock {
public static $controllerName = '';
public static $methodName = '';
public static $activeConfig = [];
protected $controllerObject = null;
protected $controllerClass = '';
protected $params = [];
/**
* The constructor handles the entire process of parsing the url,
* finding the controller/method, and calling the appropriate
* class/function for the application.
*
* @param string $url - A custom URL to be parsed to determine
* controller/method. (GET) url is used by
* default if none is provided
*/
public function __construct( $url = '' ) {
Debug::group( 'Bedrock Application' );
ob_start();
self::$activeConfig = new Config( CONFIG_JSON );
set_error_handler( [ 'TheTempusProject\\Canary\\Canary', 'handle_error' ] );
set_exception_handler( [ 'TheTempusProject\\Canary\\Canary', 'handle_exception' ] );
self::$controllerName = DEFAULT_CONTROLLER_CLASS;
self::$methodName = DEFAULT_CONTROLLER_METHOD;
$this->setUrl( $url );
}
public function setUrl( $url ) {
if ( empty( $url ) ) {
Debug::log( 'Using GET url.' );
$url = Input::get( 'url' );
}
$trimmedUrl = trim( $url, '/' );
$url = str_ireplace( '.php', '', $trimmedUrl );
$urlArray = explode( '/', Sanitize::url( $url ) );
$this->setVarsFromUrlArray( $urlArray );
}
public function load() {
$this->loadController();
$this->loadPage();
}
public static function getUrl() {
return Routes::getAddress() . Input::get( 'url' );
}
protected function loadPage() {
if ( !method_exists( $this->controllerClass, self::$methodName ) ) {
return false;
}
Components::set( 'META_IMAGE', Routes::getAddress() . Config::getValue( 'main/logoLarge' ) );
Components::set( 'CURRENT_URL', self::getCurrentUrl() );
Components::set( 'SITENAME', Config::getValue( 'main/name' ) );
Components::set( 'AUTHOR', '<meta name="author" content="' . Config::getValue( 'main/name' ) . '">' );
call_user_func_array( [ $this->controllerObject, self::$methodName ], $this->params );
Components::set( 'TITLE', Template::parse( $this->controllerObject::$title ) );
Components::set( 'PAGE_DESCRIPTION', Template::parse( $this->controllerObject::$pageDescription ) );
Template::render();
Debug::closeAllGroups();
// self::$session->updatePage( self::getUrl() ); // where did this method go?
}
protected function loadController() {
if ( empty( $this->controllerClass ) ) {
$this->controllerClass = (string) APP_SPACE . '\\Controllers\\' . self::$controllerName;
}
$this->controllerObject = new $this->controllerClass;
}
protected function setController( $name, $namespace ) {
$controllerClass = $namespace . ucfirst( $name );
if ( Autoloader::testLoad( $controllerClass ) ) {
$this->controllerClass = $controllerClass;
self::$controllerName = $name;
}
}
protected function setPage( $name ) {
$name = strtolower( $name );
if ( !method_exists( $this->controllerClass, $name ) ) {
Debug::info( 'setPage - Method not found: ' . $name );
return false;
}
self::$methodName = $name;
}
protected function setVarsFromUrlArray( $urlArray ) {
if ( !empty( $urlArray[0] ) ) {
$urlPart = array_shift( $urlArray );
if ( $urlPart == 'admin' ) {
$namespace = APP_SPACE . '\\Controllers\\Admin\\';
if ( empty( $urlArray[0] ) ) {
// if there is no second param, assume they want the home controller
$urlPart = 'home';
} else {
$urlPart = array_shift( $urlArray ); // to drop the admin
}
if ( $urlPart == 'index' ) {
// if its admin/index, again, assume the home controller
$urlPart = 'home';
}
} elseif ( $urlPart == 'api' ) {
$namespace = APP_SPACE . '\\Controllers\\Api\\';
if ( empty( $urlArray[0] ) ) {
// if there is no second param, assume they want the home controller
$urlPart = 'home';
} else {
$urlPart = array_shift( $urlArray ); // to drop the admin
}
if ( $urlPart == 'index' ) {
// if its admin/index, again, assume the home controller
$urlPart = 'home';
}
} else {
$namespace = APP_SPACE . '\\Controllers\\';
}
$this->setController( $urlPart, $namespace );
}
if ( !empty( $urlArray[0] ) ) {
$urlPart = array_shift( $urlArray );
$this->setPage( $urlPart );
}
if ( !empty( $urlArray ) ) {
$this->params = array_values( $urlArray );
}
}
public static function getCurrentUrl() {
return Sanitize::url( Input::get( 'url' ) );
}
protected function printDebug() {
echo '<div style="margin: 0 auto; padding-bottom: 25px; background: #eee; width: 1000px;">';
echo '<h1 style="text-align: center;">PHP Info</h1>';
echo '<table style="margin: 0 auto; padding-bottom: 25px; background: #eee; width: 950px;">';
echo '<tr><td>PHP version: </td><td><code>' . phpversion() . '</code><br></td></tr>';
echo '<tr><td>PDO Loaded version: </td><td><code>' . extension_loaded( 'pdo' ) . '</code><br></td></tr>';
echo '<tr><td>PHP extensions: </td><td><pre>';
foreach ( get_loaded_extensions() as $i => $ext ) {
echo $ext . ' => ' . phpversion( $ext ) . '<br/>';
}
echo '</pre><br></td></tr>';
echo '</table>';
echo '<h1 style="text-align: center;">Tempus Core Info</h1>';
echo '<table style="margin: 0 auto; padding-bottom: 25px; background: #eee; width: 950px;">';
// Just in case
echo '<tr><td>_SERVER: </td><td><pre>';
echo var_export( $_SERVER, true );
echo '</pre><br></td></tr>';
// Checks
echo '<tr><td style="text-align: center; padding-top: 25px; padding-bottom: 10px;" colspan="2"><h2>Checks</h2></td></tr>';
echo '<tr><td>Uploads work?: </td><td><code>' . var_export( Check::uploads(), true ) . '</code><br></td></tr>';
echo '<tr><td>PHP: </td><td><code>' . var_export( Check::php(), true ) . '</code><br></td></tr>';
echo '<tr><td>Mail works?: </td><td><code>' . var_export( Check::mail(), true ) . '</code><br></td></tr>';
echo '<tr><td>Is safe mode?: </td><td><code>' . var_export( Check::safe(), true ) . '</code><br></td></tr>';
echo '<tr><td>Sessions work?: </td><td><code>' . var_export( Check::sessions(), true ) . '</code><br></td></tr>';
echo '<tr><td>Cookies work?: </td><td><code>' . var_export( Check::cookies(), true ) . '</code><br></td></tr>';
echo '<tr><td>is Apache?: </td><td><code>' . var_export( Check::isApache(), true ) . '</code><br></td></tr>';
echo '<tr><td>is Nginx?: </td><td><code>' . var_export( Check::isNginx(), true ) . '</code><br></td></tr>';
echo '<tr><td>Is token enabled?: </td><td><code>' . var_export( Token::isTokenEnabled(), true ) . '</code><br></td></tr>';
// Routes
echo '<tr><td style="text-align: center; padding-top: 25px; padding-bottom: 10px;" colspan="2"><h2>Routes</h2></td></tr>';
echo '<tr><td>Root: </td><td><code>' . var_export( Routes::getRoot(), true ) . '</code><br></td></tr>';
echo '<tr><td>Address: </td><td><code>' . var_export( Routes::getAddress(), true ) . '</code><br></td></tr>';
echo '<tr><td>Protocol: </td><td><code>' . var_export( Routes::getProtocol(), true ) . '</code><br></td></tr>';
echo '<tr><td>App URL: </td><td><code>' . var_export( self::getUrl(), true ) . '</code><br></td></tr>';
// Debugging
echo '<tr><td style="text-align: center; padding-top: 25px; padding-bottom: 10px;" colspan="2"><h2>Debugging</h2></td></tr>';
echo '<tr><td>Console Debugging Enabled: </td><td><code>' . var_export( Debug::status( 'console' ), true ) . '</code><br></td></tr>';
echo '<tr><td>Debug Trace Enabled: </td><td><code>' . var_export( Debug::status( 'trace' ), true ) . '</code><br></td></tr>';
echo '<tr><td>Debugging Enabled: </td><td><code>' . var_export( Debug::status( 'debug' ), true ) . '</code><br></td></tr>';
echo '<tr><td>Rendering Enabled: </td><td><code>' . var_export( Debug::status( 'render' ), true ) . '</code><br></td></tr>';
// Main
echo '<tr><td style="text-align: center; padding-top: 25px; padding-bottom: 10px;" colspan="2"><h2>Main App Variables</h2></td></tr>';
echo '<tr><td>Template Location: </td><td><code>' . var_export( Template::getLocation(), true ) . '</code><br></td></tr>';
echo '<tr><td>Configuration: </td><td><pre>' . var_export( Config::$config, true ) . '</pre></td></tr>';
echo '<tr><td>Check Errors: </td><td><pre>' . var_export( Check::systemErrors(), true ) . '</pre></td></tr>';
echo '<tr><td>GET: </td><td><pre>' . var_export( $_GET, true ) . '</pre></td></tr>';
// Constants
echo '<tr><td style="text-align: center; padding-top: 25px; padding-bottom: 10px;" colspan="2"><h2>Constants</h2></td></tr>';
// Debugging
echo '<tr><td style="text-align: center;"><b>Debugging:</b></td><td></td></tr>';
echo '<tr><td>HERMES_REDIRECTS_ENABLED: </td><td><code>' . var_export( HERMES_REDIRECTS_ENABLED, true ) . '</code><br></td></tr>';
echo '<tr><td>CANARY_TRACE_ENABLED: </td><td><code>' . var_export( CANARY_TRACE_ENABLED, true ) . '</code><br></td></tr>';
echo '<tr><td>CANARY_ENABLED: </td><td><code>' . var_export( CANARY_ENABLED, true ) . '</code><br></td></tr>';
echo '<tr><td>CANARY_DEBUG_TO_CONSOLE: </td><td><code>' . var_export( CANARY_DEBUG_TO_CONSOLE, true ) . '</code><br></td></tr>';
echo '<tr><td>CANARY_DEBUG_TO_FILE: </td><td><code>' . var_export( CANARY_DEBUG_TO_FILE, true ) . '</code><br></td></tr>';
// Tempus Debugger
echo '<tr><td style="text-align: center;"><b>Tempus Debugger:</b></td><td></td></tr>';
echo '<tr><td>CANARY_SECURE_HASH: </td><td><code>' . var_export( CANARY_SECURE_HASH, true ) . '</code><br></td></tr>';
echo '<tr><td>CANARY_SHOW_LINES: </td><td><code>' . var_export( CANARY_SHOW_LINES, true ) . '</code><br></td></tr>';
// Tokens
echo '<tr><td style="text-align: center;"><b>Tokens:</b></td><td></td></tr>';
echo '<tr><td>DEFAULT_TOKEN_NAME: </td><td><code>' . var_export( DEFAULT_TOKEN_NAME, true ) . '</code><br></td></tr>';
echo '<tr><td>TOKEN_ENABLED: </td><td><code>' . var_export( TOKEN_ENABLED, true ) . '</code><br></td></tr>';
// Cookies
echo '<tr><td style="text-align: center;"><b>Cookies:</b></td><td></td></tr>';
echo '<tr><td>DEFAULT_COOKIE_EXPIRATION: </td><td><code>' . var_export( DEFAULT_COOKIE_EXPIRATION, true ) . '</code><br></td></tr>';
echo '<tr><td>DEFAULT_COOKIE_PREFIX: </td><td><code>' . var_export( DEFAULT_COOKIE_PREFIX, true ) . '</code><br></td></tr>';
// Directories
echo '<tr><td style="text-align: center;"><b>Directories:</b></td><td></td></tr>';
echo '<tr><td>APP_ROOT_DIRECTORY: </td><td><code>' . var_export( APP_ROOT_DIRECTORY, true ) . '</code><br></td></tr>';
echo '<tr><td>BIN_DIRECTORY: </td><td><code>' . var_export( BIN_DIRECTORY, true ) . '</code><br></td></tr>';
echo '<tr><td>UPLOAD_DIRECTORY: </td><td><code>' . var_export( UPLOAD_DIRECTORY, true ) . '</code><br></td></tr>';
echo '<tr><td>IMAGE_UPLOAD_DIRECTORY: </td><td><code>' . var_export( IMAGE_UPLOAD_DIRECTORY, true ) . '</code><br></td></tr>';
echo '<tr><td>CLASSES_DIRECTORY: </td><td><code>' . var_export( CLASSES_DIRECTORY, true ) . '</code><br></td></tr>';
echo '<tr><td>CONFIG_DIRECTORY: </td><td><code>' . var_export( CONFIG_DIRECTORY, true ) . '</code><br></td></tr>';
echo '<tr><td>FUNCTIONS_DIRECTORY: </td><td><code>' . var_export( FUNCTIONS_DIRECTORY, true ) . '</code><br></td></tr>';
echo '<tr><td>TEMPLATE_DIRECTORY: </td><td><code>' . var_export( TEMPLATE_DIRECTORY, true ) . '</code><br></td></tr>';
echo '<tr><td>VIEW_DIRECTORY: </td><td><code>' . var_export( VIEW_DIRECTORY, true ) . '</code><br></td></tr>';
echo '<tr><td>ERRORS_DIRECTORY: </td><td><code>' . var_export( ERRORS_DIRECTORY, true ) . '</code><br></td></tr>';
echo '<tr><td>RESOURCES_DIRECTORY: </td><td><code>' . var_export( RESOURCES_DIRECTORY, true ) . '</code><br></td></tr>';
echo '<tr><td>BEDROCK_ROOT_DIRECTORY: </td><td><code>' . var_export( BEDROCK_ROOT_DIRECTORY, true ) . '</code><br></td></tr>';
echo '<tr><td>BEDROCK_BIN_DIRECTORY: </td><td><code>' . var_export( BEDROCK_BIN_DIRECTORY, true ) . '</code><br></td></tr>';
echo '<tr><td>BEDROCK_CLASSES_DIRECTORY: </td><td><code>' . var_export( BEDROCK_CLASSES_DIRECTORY, true ) . '</code><br></td></tr>';
echo '<tr><td>BEDROCK_CONFIG_DIRECTORY: </td><td><code>' . var_export( BEDROCK_CONFIG_DIRECTORY, true ) . '</code><br></td></tr>';
echo '<tr><td>BEDROCK_FUNCTIONS_DIRECTORY: </td><td><code>' . var_export( BEDROCK_FUNCTIONS_DIRECTORY, true ) . '</code><br></td></tr>';
echo '<tr><td>BEDROCK_RESOURCES_DIRECTORY: </td><td><code>' . var_export( BEDROCK_RESOURCES_DIRECTORY, true ) . '</code><br></td></tr>';
echo '<tr><td>BEDROCK_VIEW_DIRECTORY: </td><td><code>' . var_export( BEDROCK_VIEW_DIRECTORY, true ) . '</code><br></td></tr>';
echo '<tr><td>BEDROCK_ERRORS_DIRECTORY: </td><td><code>' . var_export( BEDROCK_ERRORS_DIRECTORY, true ) . '</code><br></td></tr>';
// other
echo '<tr><td style="text-align: center;"><b>Other:</b></td><td></td></tr>';
echo '<tr><td>MINIMUM_PHP_VERSION: </td><td><code>' . var_export( MINIMUM_PHP_VERSION, true ) . '</code><br></td></tr>';
echo '<tr><td>DATA_TITLE_PREG: </td><td><code>' . var_export( DATA_TITLE_PREG, true ) . '</code><br></td></tr>';
echo '<tr><td>PATH_PREG_REQS: </td><td><code>' . var_export( PATH_PREG_REQS, true ) . '</code><br></td></tr>';
echo '<tr><td>SIMPLE_NAME_PREG: </td><td><code>' . var_export( SIMPLE_NAME_PREG, true ) . '</code><br></td></tr>';
echo '<tr><td>ALLOWED_IMAGE_UPLOAD_EXTENTIONS: </td><td><code>' . var_export( ALLOWED_IMAGE_UPLOAD_EXTENTIONS, true ) . '</code><br></td></tr>';
echo '<tr><td>MAX_RESULTS_PER_PAGE: </td><td><code>' . var_export( MAX_RESULTS_PER_PAGE, true ) . '</code><br></td></tr>';
echo '<tr><td>DEFAULT_RESULTS_PER_PAGE: </td><td><code>' . var_export( DEFAULT_RESULTS_PER_PAGE, true ) . '</code><br></td></tr>';
echo '<tr><td>DEFAULT_SESSION_PREFIX: </td><td><code>' . var_export( DEFAULT_SESSION_PREFIX, true ) . '</code><br></td></tr>';
echo '<tr><td>DEFAULT_CONTROLLER_CLASS: </td><td><code>' . var_export( DEFAULT_CONTROLLER_CLASS, true ) . '</code><br></td></tr>';
echo '</table></div>';
}
}

View File

@ -1,367 +0,0 @@
<?php
/**
* classes/config.php
*
* This class handles all the hard-coded configurations.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/Core
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Bedrock\Classes;
use TheTempusProject\Canary\Canary as Debug;
use TheTempusProject\Bedrock\Functions\Check;
use TheTempusProject\Bedrock\Functions\Input;
class Config {
public static $config = false;
private static $location = false;
private static $initialized = false;
/**
* Default constructor which will attempt to load the config from the location specified.
*
* @param {string} [$location]
* @return {null|object}
*/
public function __construct( $location = '' ) {
if ( self::$initialized !== false ) {
Debug::log( 'Config already initialized.' );
return $this;
}
if ( empty( $location ) ) {
$location = CONFIG_JSON;
}
self::$initialized = $this->load( $location );
if ( self::$initialized !== false ) {
Debug::log( 'Config initialization succeeded.' );
return $this;
}
Debug::warn( 'Config initialization failed.' );
}
/**
* Attempts to retrieve then set the configuration from a file.
* @note This function will reset the config every time it is used.
*
* @param {string} $location
* @return {bool}
*/
public function load( $location ) {
self::$config = $this->getConfigFile( $location );
self::$location = $location;
if ( self::$config === false || empty( self::$config ) ) {
Debug::warn( 'Config load failed.' );
return false;
}
Debug::log( 'Config load succeeded.' );
return true;
}
/**
* Opens and decodes the config json from the location provided.
*
* @param {string} [$location]
* @return {bool|array}
*/
public function getConfigFile( $location ) {
if ( file_exists( $location ) ) {
Debug::debug( "Config json found: $location" );
return json_decode( file_get_contents( $location ), true );
} else {
Debug::warn( "Config json not found: $location" );
return false;
}
}
/**
* Add a new config option for the specified category.
*
* NOTE: Use a default option when using this function to
* aid in fail safe execution.
*
* @param {string} [$category] - The primary category to add the option to.
* @param {string} [$node] - The name of the new option.
* @param {wild} [$value] - The desired value for the new option.
* @param {bool} [$createMissing] - Whether or not to create missing options.
* @param {bool} [$save] - Whether or not to save the config.
* @param {bool} [$saveDefault] - Whether or not to save the default config.
* @return {bool}
*/
public function update( $category, $node, $value, $createMissing = false, $save = false, $saveDefault = false ) {
// @todo: createMissing is unused here
if ( self::$config === false ) {
Debug::warn( 'Config not loaded.' );
return false;
}
if ( !Check::simpleName( $category ) ) {
Debug::warn( "Category name invalid: $categoryName" );
return false;
}
if ( !isset( self::$config[$category] ) ) {
Debug::warn( "No such category: $category" );
return false;
}
if ( !Check::simpleName( $node ) ) {
Debug::warn( "Node name invalid: $categoryName" );
return false;
}
if ( !isset( self::$config[$category][$node] ) ) {
Debug::warn( 'Config not found.' );
return false;
}
if ( $value === 'true' ) {
$value = true;
}
if ( $value === 'false' ) {
$value = false;
}
self::$config[$category][$node]['value'] = $value;
if ( $save ) {
$this->save( $saveDefault );
}
return true;
}
public function updateFromForm( $save = false, $saveDefault = false ) {
if ( self::$config === false ) {
Debug::warn( 'Config not loaded.' );
return;
}
foreach ( self::$config as $category => $fields ) {
if ( empty( self::$config[ $category ] ) ) {
Debug::warn( "Config category not found: $category" );
continue;
}
foreach ( self::$config[ $category ] as $field => $node ) {
$name = $category . '/' . $field;
if ( empty( $node ) ) {
continue;
}
if ( !empty( $node['protected'] ) ) {
continue;
}
$fieldname = str_ireplace( '/', '-', $name );
if ( Input::exists( $fieldname ) ) {
$this->update( $category, $field, Input::post( $fieldname ) );
}
}
}
if ( $save ) {
return $this->save( $saveDefault );
}
return true;
}
/**
* Saves the current config.
*
* @param {bool} [$default] - Whether or not to save a default copy.
* @return {bool}
*/
public function save( $default = false ) {
if ( self::$config === false ) {
Debug::warn( 'Config not loaded.' );
return false;
}
if ( self::$location === false ) {
Debug::warn( 'Config location not set.' );
return false;
}
if ( $default ) {
$locationArray = explode( '.', self::$location );
$locationArray[] = 'bak';
$backupLoction = implode( '.', $locationArray );
if ( !file_put_contents( $backupLoction, json_encode( self::$config ) ) ) {
return false;
}
}
if ( file_put_contents( self::$location, json_encode( self::$config ) ) ) {
return true;
}
return false;
}
/**
* Adds a new category to the $config array.
*
* @param {string} [$categoryName]
* @return {bool}
*/
public function addCategory( $categoryName ) {
if ( self::$config === false ) {
self::$config = [];
}
if ( !Check::simpleName( $categoryName ) ) {
Debug::warn( "Category name invalid: $categoryName" );
return false;
}
if ( isset( self::$config[$categoryName] ) ) {
Debug::warn( "Category already exists: $categoryName" );
return false;
}
self::$config[$categoryName] = [];
return true;
}
/**
* Removes an existing category from the $config array.
*
* @param {string} [$categoryName]
* @param {string} [$save]
* @return {bool}
*/
public function removeCategory( $categoryName, $save = false, $saveDefault = true ) {
if ( self::$config === false ) {
Debug::warn( 'Config not loaded.' );
return;
}
if ( !isset( self::$config[$categoryName] ) ) {
Debug::warn( "Config does not have category: $categoryName" );
return true;
}
unset( self::$config[$categoryName] );
if ( $save ) {
$this->save( $saveDefault );
}
return true;
}
/**
* Add a new config node for the specified category.
*
* @param {string} [$category] - The primary category to add the option to.
* @param {string} [$node] - The name of the new option.
* @param {wild} [$value] - The desired value for the new option.
* @return {bool}
*/
public function add( $category, $node, $details, $updateExisting = false ) {
if ( self::$config === false ) {
Debug::warn( 'Config not loaded.' );
return false;
}
if ( !Check::simpleName( $category ) ) {
Debug::warn( "Category name invalid: $category" );
return false;
}
if ( !isset( self::$config[$category] ) ) {
Debug::warn( "No such category: $category" );
return false;
}
if ( !Check::simpleName( $node ) ) {
Debug::warn( "Category Node name invalid: $node" );
return false;
}
if ( isset( self::$config[$category][$node] ) ) {
if ( $updateExisting ) {
$details = array_replace(self::$config[$category][$node], $details );
} else {
Debug::warn( "Config already exists: $node" );
return false;
}
}
if ( !isset( $details['value'] ) ) {
$details['value'] = $details['default'];
}
self::$config[$category][$node] = $details;
return true;
}
public function generate( $location, $mods = [] ) {
self::$location = $location;
if ( !empty( $mods ) ) {
foreach ( $mods as $category => $node ) {
$this->addCategory( $category );
foreach ( $node as $name => $details ) {
$this->add( $category, $name, $details, true );
}
}
}
if ( $this->save( true ) ) {
Debug::info( 'config file generated successfully.' );
return true;
}
return false;
}
/**
* Retrieves the config option for $name.
*
* @param {string} [$name] - Must be in <category>/<option> format.
* @return {WILD}
*/
public static function get( $name ) {
$data = explode( '/', $name );
if ( count( $data ) != 2 ) {
Debug::warn( "Config not properly formatted: $name" );
return;
}
if ( self::$config === false ) {
Debug::warn( 'Config not loaded.' );
return;
}
$category = $data[0];
$field = $data[1];
if ( !isset( self::$config[$category][$field] ) ) {
Debug::warn( "Config not found: $name" );
return;
}
$node = self::$config[$category][$field];
if ( !isset( $node['type'] ) ) {
$node['type'] = 'text';
}
if ( !isset( $node['pretty'] ) ) {
$node['pretty'] = $node;
}
if ( !isset( $node['default'] ) ) {
$node['default'] = '';
}
if ( !isset( $node['value'] ) ) {
$node['value'] = $node['default'];
}
if ( !isset( $node['protected'] ) ) {
$node['protected'] = false;
}
return $node;
}
/**
* Retrieves the config option for $name and if the result is bool, converts it to a string.
*
* @param {string} [$name] - Must be in <category>/<option> format.
* @return {WILD}
*/
public static function getString( $name ) {
$result = self::getValue( $name );
if ( is_bool( $result ) ) {
$result = ( $result ? 'true' : 'false' );
}
return $result;
}
public static function getValue( $name ) {
$node = self::get( $name );
if ( empty( $node ) ) {
return;
}
if ( !isset( $node['value'] ) ) {
Debug::warn( 'Node Value not set.' );
return;
}
return $node['value'];
}
public static function getDefault( $name ) {
$node = self::get( $name );
if ( empty( $node ) ) {
return;
}
if ( !isset( $node['default'] ) ) {
Debug::warn( 'Node default not set.' );
return;
}
return $node['default'];
}
}

View File

@ -1,56 +0,0 @@
<?php
/**
* core/controller.php
*
* The controller handles our main template and provides the
* model and view functions which are the backbone of the tempus
* project. Used to hold and keep track of many of the variables
* that support the applications execution.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/Core
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Bedrock\Classes;
use TheTempusProject\Canary\Canary as Debug;
use TheTempusProject\Bedrock\Functions\Session;
use TheTempusProject\Houdini\Classes\Issues;
class Controller {
public static $title = null;
public static $pageDescription = null;
public static $template = null;
/**
* Check for issues stored in sessions and add them to current issues.
*/
public static function checkSessions() {
$success = Session::checkFlash( 'success' );
$notice = Session::checkFlash( 'notice' );
$error = Session::checkFlash( 'error' );
$info = Session::checkFlash( 'info' );
if ( !empty( $success ) ) {
Issues::add( 'success', $success );
}
if ( !empty( $notice ) ) {
Issues::add( 'notice', $notice );
}
if ( !empty( $error ) ) {
Issues::add( 'error', $error );
}
if ( !empty( $info ) ) {
Issues::add( 'info', $info );
}
}
public function __construct() {
Debug::log( 'Controller Constructing: ' . get_class( $this ) );
self::checkSessions();
}
public function __destruct() {
Debug::log( 'Controller Destructing: ' . get_class( $this ) );
}
}

View File

@ -1,78 +0,0 @@
<?php
/**
* classes/custom_exception.php
*
* This class is used exclusively when throwing predefined exceptions.
* It will intercept framework thrown exceptions and deal with them however
* you choose; in most cases by logging them and taking appropriate responses
* such as redirecting to error pages.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/Core
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Bedrock\Classes;
use Exception;
use TheTempusProject\Hermes\Functions\Redirect;
use TheTempusProject\Canary\Canary as Debug;
class CustomException extends Exception {
private $originFunction = null;
private $exceptionName = null;
private $originClass = null;
private $data = null;
/**
* This function allows the application to deal with errors
* in a dynamic way by letting you customize the response
*
* @param string $type - The type of the exception being called/thrown.
* @param string $data - Any additional data being passed with the exception.
*
* @example - throw new CustomException('model'); - Calls the model-missing exception
*/
public function __construct( $type, $data = null ) {
$this->originFunction = debug_backtrace()[1]['function'];
$this->originClass = debug_backtrace()[1]['class'];
$this->exceptionName = $type;
$this->data = $data;
switch ( $type ) {
case 'model':
Debug::error( 'Model not found: ' . $data );
break;
case 'dbConnection':
Debug::error( 'Error Connecting to the database: ' . $data );
break;
case 'DB':
Debug::error( 'Unspecified database error: ' . $data );
break;
case 'view':
Debug::error( 'View not found: ' . $data );
break;
case 'controller':
Debug::error( 'Controller not found: ' . $data );
Redirect::to( 404 );
break;
case 'defaultController':
Debug::error( 'DEFAULT Controller not found: ' . $data );
Redirect::to( 404 );
break;
case 'method':
Debug::error( 'Method not found: ' . $data );
Redirect::to( 404 );
break;
case 'simpleView':
Debug::error( 'View not found: ' . $data );
break;
case 'defaultMethod':
Debug::error( 'DEFAULT Method not found: ' . $data );
Redirect::to( 404 );
break;
default:
Debug::error( 'Default exception: ' . $data );
break;
}
}
}

View File

@ -1,745 +0,0 @@
<?php
/**
* classes/database.php
*
* Defines all interactions with the database.
*
* @todo - Add more than just MySQL
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/Core
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Bedrock\Classes;
use PDO;
use PDOException;
use TheTempusProject\Houdini\Classes\Pagination;
use TheTempusProject\Canary\Canary as Debug;
class Database {
public static $instance = null;
private $pdo = null;
private $query = null;
private $error = false;
private $results = null;
private $count = 0;
private $maxQuery = 0;
private $totalResults = 0;
private $errorMessage = null;
private $tableBuff = null;
private $fieldBuff = null;
private $queryStatus = false;
/**
* Checks the DB connection with the provided information.
*
* @param string $host - Database Host.
* @param string $db - Database Name.
* @param string $user - Database Username.
* @param string $pass - Database Password.
*
* @return bool
*/
public static function check( $host = null, $db = null, $user = null, $pass = null ) {
if ( empty( $host ) || empty( $db ) || empty( $user ) || empty( $pass ) ) {
Debug::error( 'check::db: one or more parameters are missing.' );
return false;
}
try {
Debug::log( 'Attempting to connect to DB with supplied credentials.' );
$test = new PDO( 'mysql:host=' . $host . ';dbname=' . $db, $user, $pass );
} catch ( PDOException $Exception ) {
Debug::error( 'Cannot connect to DB with provided credentials: ' . $Exception->getMessage() );
return false;
}
return true;
}
/**
* Checks the current database in the configuration file for version verification.
*
* @return boolean
*
* @todo - Update this function to be more effective.
*/
public static function mysql() {
self::connect();
$dbVersion = self::$db->version();
preg_match( '@[0-9]+\.[0-9]+\.[0-9]+@', $dbVersion, $version );
if ( version_compare( $version[0], '10.0.0', '>' ) ) {
return true;
}
self::addError( "MySQL Version is too low! Current version is $version[0]. Version 10.0.0 or higher is required." );
return false;
}
/**
* Automatically open the DB connection with settings from our global config.
*/
private function __construct( $host = null, $name = null, $user = null, $pass = null ) {
Debug::debug( 'Class initialized: ' . get_class( $this ) );
if ( isset( $host ) && isset( $name ) && isset( $user ) && isset( $pass ) ) {
try {
Debug::log( 'Attempting to connect to DB with supplied credentials.' );
$this->pdo = new PDO( 'mysql:host=' . $host . ';dbname=' . $name, $user, $pass );
} catch ( PDOException $Exception ) {
$this->error = true;
$this->errorMessage = $Exception->getMessage();
}
}
if ( !$this->enabled() ) {
$this->error = true;
$this->errorMessage = 'Database disabled in config.';
}
if ( $this->error === false ) {
try {
Debug::debug( 'Attempting to connect to DB with config credentials.' );
$this->pdo = new PDO( 'mysql:host=' . Config::getValue( 'database/dbHost' ) . ';dbname=' . Config::getValue( 'database/dbName' ), Config::getValue( 'database/dbUsername' ), Config::getValue( 'database/dbPassword' ) );
} catch ( PDOException $Exception ) {
$this->error = true;
$this->errorMessage = $Exception->getMessage();
}
}
if ( $this->error !== false ) {
new CustomException( 'dbConnection', $this->errorMessage );
return;
}
$this->maxQuery = Config::getValue( 'database/dbMaxQuery' );
// @TODO add a toggle for this
$this->pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
Debug::debug( 'DB connection successful' );
return;
}
/**
* Checks whether the DB is enabled via the config file.
*
* @return bool - whether the db module is enabled or not.
*/
public function enabled( $type = '' ) {
if ( Config::getValue( 'database/dbEnabled' ) === true ) {
return true;
}
return false;
}
public function lastId() {
return $this->pdo->lastInsertId();
}
/**
* Checks to see if there is already a DB instance open, and if not; create one.
*
* @return function - Returns the PDO DB connection.
*/
public static function getInstance( $host = null, $name = null, $user = null, $pass = null, $new = false ) {
// used to force a new connection
if ( !empty( $host ) && !empty( $name ) && !empty( $user ) && !empty( $pass ) ) {
self::$instance = new self( $host, $name, $user, $pass );
}
if ( empty( self::$instance ) || $new ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Returns the DB version.
*
* @return bool|string
*/
public function version() {
if ( !$this->enabled() ) {
$this->error = true;
$this->errorMessage = 'Database disabled';
return false;
}
$sql = 'select version()';
if ( $this->query = $this->pdo->prepare( $sql ) ) {
try {
$this->query->execute();
} catch ( PDOException $Exception ) {
$this->error = true;
$this->errorMessage = $Exception->getMessage();
Debug::error( 'DB Version Error' );
Debug::error( $this->errorMessage );
return false;
}
return $this->query->fetchColumn();
}
return false;
}
/**
* Checks the database to see if the specified table exists.
*
* @param string $name - The name of the table to check for.
*
* @return boolean
*/
protected function tableExists( $name ) {
$name = Config::getValue( 'database/dbPrefix' ) . $name;
$this->raw( "SHOW TABLES LIKE '$name'" );
if ( $this->error ) {
Debug::error( var_export( $this->errorMessage, true ) );
return false;
}
if ( $this->count === 0 ) {
return false;
}
return true;
}
/**
* Checks first that the table exists, then checks if the specified
* column exists in the table.
*
* @param string $table - The table to search.
* @param string $column - The column to look for.
*
* @return boolean
*
* @todo - Is it necessary to check the current $fields list too?
*/
protected function columnExists( $table, $column ) {
if ( !$this->tableExists( $table ) ) {
return false;
}
$table = Config::getValue( 'database/dbPrefix' ) . $table;
$this->raw( "SHOW COLUMNS FROM `$table` LIKE '$column'" );
if ( !$this->error && $this->count === 0 ) {
return false;
}
return true;
}
/**
* Execute a raw DB query.
*
* @param string $data the query to execute
*
* @return bool
*/
public function raw( $data ) {
$this->queryReset();
if ( !$this->enabled() ) {
$this->error = true;
$this->errorMessage = 'Database disabled';
return false;
}
$this->query = $this->pdo->prepare( $data );
try {
$this->query->execute();
} catch ( PDOException $Exception ) {
$this->error = true;
$this->errorMessage = $Exception->getMessage();
Debug::warn( 'DB Raw Query Error' );
Debug::warn( $this->errorMessage );
return false;
}
// @todo i think this will cause an error some circumstances
$this->count = $this->query->rowCount();
return true;
}
/**
* The actual Query function. This function takes our setup queries
* and send them to the database. it then properly sets our instance
* variables with the proper info from the DB, as secondary constructor
* for almost all objects in this class.
*
* @param string $sql - The SQL to execute.
* @param array $params - Any bound parameters for the query.
*
* @return object
*/
public function query( $sql, $params = [], $noFetch = false ) {
$this->queryReset();
if ( $this->pdo == false ) {
Debug::warn( 'DB::query - no database connection established' );
$this->error = true;
$this->errorMessage = 'DB::query - no database connection established';
return $this;
}
$this->query = $this->pdo->prepare( $sql );
if ( !empty( $params ) ) {
$x = 0;
foreach ( $params as $param ) {
$x++;
if ( is_array( $param ) ) {
dv( $param );
}
$this->query->bindValue( $x, $param );
}
}
try {
$this->query->execute();
} catch ( PDOException $Exception ) {
$this->error = true;
$this->errorMessage = $Exception->getMessage();
Debug::error( 'DB Query Error' );
Debug::error( $this->errorMessage );
return $this;
}
if ( $noFetch === true ) {
$this->results = null;
$this->count = 1;
} else {
$this->results = $this->query->fetchAll( PDO::FETCH_OBJ );
$this->count = $this->query->rowCount();
}
return $this;
}
/**
* This function resets the values used for creating or modifying tables.
* Essentially a cleaner function.
*/
public function queryReset( $includeBuffers = false ) {
$this->results = null;
$this->count = 0;
$this->error = false;
$this->errorMessage = null;
$this->query = null;
if ( $includeBuffers ) {
$this->tableBuff = null;
$this->fieldBuff = null;
$this->queryStatus = false;
}
}
/**
* The action function builds all of our SQL.
*
* @todo : Clean this up.
*
* @param string $action - The type of action being carried out.
* @param string $tableName - The table name being used.
* @param array $where - The parameters for the action
* @param string $by - The key to sort by.
* @param string $direction - The direction to sort the results.
* @param array $limit - The result limit of the query.
*
* @return bool
*/
public function action( $action, $tableName, $where, $by = null, $direction = 'DESC', $reqLimit = null ) {
$this->totalResults = 0; // since this is how we paginate, it can't be reset when we exceed the max
if ( !$this->enabled() ) {
$this->error = true;
$this->errorMessage = 'Database disabled';
return $this;
}
$whereCount = count( $where );
if ( $whereCount < 3 ) {
Debug::error( 'DB::action - Not enough arguments supplied for "where" clause' );
$this->error = true;
$this->errorMessage = 'DB::action - Not enough arguments supplied for "where" clause';
return $this;
}
if ( $action == 'DELETE' ) {
$noFetch = true;
}
$tableName = Config::getValue( 'database/dbPrefix' ) . $tableName;
$sql = "{$action} FROM `{$tableName}` WHERE ";
$validOperators = ['=', '!=', '>', '<', '>=', '<=', 'LIKE', 'IS'];
$validDelimiters = ['AND', 'OR'];
$values = [];
while ( $whereCount > 2 ) {
$whereCount = $whereCount - 3;
$field = array_shift( $where );
$operator = array_shift( $where );
array_push( $values, array_shift( $where ) );
if ( !in_array( $operator, $validOperators ) ) {
Debug::error( 'DB::action - Invalid operator.' );
$this->error = true;
$this->errorMessage = 'DB::action - Invalid operator.';
return $this;
}
$sql .= "{$field} {$operator} ?";
if ( $whereCount > 0 ) {
$delimiter = array_shift( $where );
if ( !in_array( $delimiter, $validDelimiters ) ) {
Debug::error( 'DB::action - Invalid delimiter.' );
$this->error = true;
$this->errorMessage = 'DB::action - Invalid delimiter.';
return $this;
}
$sql .= " {$delimiter} ";
$whereCount--;
}
}
if ( isset( $by ) ) {
$sql .= " ORDER BY {$by} {$direction}";
}
$sqlPreLimit = $sql;
if ( !empty( $reqLimit ) ) {
$lim = implode(',',$reqLimit);
$sql .= " LIMIT {$lim}";
}
if ( isset( $values ) ) {
if ( !empty( $noFetch ) ) {
$error = $this->query( $sql, $values, true )->error();
} else {
$error = $this->query( $sql, $values )->error();
}
} else {
$error = $this->query( $sql )->error();
}
if ( $error ) {
Debug::warn( 'DB Action Error: ' );
Debug::warn( $this->errorMessage );
return $this;
}
$this->totalResults = $this->count;
if ( $this->count <= $this->maxQuery ) {
return $this;
}
Debug::warn( 'Query exceeded maximum results. Maximum allowed is ' . $this->maxQuery );
if ( !empty( $limit ) ) {
$newLimit = ( $reqLimit[0] + Pagination::perPage() );
$limit = " LIMIT {$reqLimit[0]},{$newLimit}";
} else {
$limit = ' LIMIT 0,' .Pagination::perPage();
}
$sql = $sqlPreLimit . $limit;
if ( isset( $values ) ) {
$error = $this->query( $sql, $values )->error();
} else {
$error = $this->query( $sql )->error();
}
if ( $error ) {
Debug::warn( 'DB Action Error: ' );
Debug::warn( $this->errorMessage );
}
return $this;
}
/**
* Function to insert into the DB.
*
* @param string $table - The table you wish to insert into.
* @param array $fields - The array of fields you wish to insert.
*
* @return bool
*/
public function insert( $table, $fields = [] ) {
$keys = array_keys( $fields );
$valuesSQL = null;
$x = 0;
$keysSQL = implode( '`, `', $keys );
foreach ( $fields as $value ) {
$x++;
$valuesSQL .= '?';
if ( $x < count( $fields ) ) {
$valuesSQL .= ', ';
}
}
$table = Config::getValue( 'database/dbPrefix' ) . $table;
$sql = "INSERT INTO `{$table}` (`" . $keysSQL . "`) VALUES ({$valuesSQL})";
if ( !$this->query( $sql, $fields, true )->error() ) {
return true;
}
return false;
}
/**
* Function to duplicate a database entry.
*
* @param string $table - The table you wish to duplicate the entry in.
* @param int $id - The ID of the entry you wish to duplicate.
*
* @return bool
*/
public function duplicateEntry($table, $id) {
// Get the original entry
$originalEntry = $this->action('SELECT', $table, ['ID', '=', $id])->results();
// Exclude the ID field
unset($originalEntry->ID);
// Insert the duplicated entry
if ($this->insert($table, (array) $originalEntry)) {
return true;
}
return false;
}
/**
* Function to update the database.
*
* @param string $table - The table you wish to update in.
* @param int $id - The ID of the entry you wish to update.
* @param array $fields - the various fields you wish to update
*
* @return bool
*/
public function update( $table, $id, $fields = [] ) {
$updateSQL = null;
$x = 0;
foreach ( $fields as $name => $value ) {
$x++;
$updateSQL .= "{$name} = ?";
if ( $x < count( $fields ) ) {
$updateSQL .= ', ';
}
}
$table = Config::getValue( 'database/dbPrefix' ) . $table;
$sql = "UPDATE {$table} SET {$updateSQL} WHERE ID = {$id}";
if ( !$this->query( $sql, $fields, true )->error() ) {
return true;
}
return false;
}
/**
* Deletes a series of, or a single instance(s) in the database.
*
* @param string $table - The table you are deleting from.
* @param string $where - The criteria for deletion.
*
* @return function
*/
public function delete( $table, $where ) {
return $this->action( 'DELETE', $table, $where );
}
/**
* Starts the object to create a new table if none already exists.
*
* NOTE: All tables created with this function will automatically
* have an 11 digit integer called ID added as a primary key.
*
* @param string $name - The name of the table you wish to create.
*
* @return boolean
*
* @todo - add a check for the name.
*/
public function newTable( $name, $addID = true ) {
if ( $this->tableExists( $name ) ) {
$this->tableBuff = null;
Debug::error( "Table already exists: $name" );
return false;
}
$this->queryReset( true );
$this->tableBuff = $name;
if ( $addID === true ) {
$this->addField( 'ID', 'int', 11, false );
}
return true;
}
/**
* Builds and executes a database query to to create a table
* using the current object's table name and fields.
*
* NOTE: By default: All tables have an auto incrementing primary key named 'ID'.
*
* @todo - Come back and add more versatility here.
*/
public function createTable() {
if ( empty( $this->tableBuff ) ) {
Debug::info( 'No Table set.' );
return false;
}
$table = Config::getValue( 'database/dbPrefix' ) . $this->tableBuff;
if ( $this->tableExists( $this->tableBuff ) ) {
Debug::error( "Table already exists: $table" );
return false;
}
$queryBuff = "CREATE TABLE `$table` (";
$x = 0;
$y = count( $this->fieldBuff );
while ( $x < $y ) {
$queryBuff .= $this->fieldBuff[$x];
$x++;
$queryBuff .= ( $x < $y ) ? ',' : '';
}
$queryBuff .= ') ENGINE=InnoDB DEFAULT CHARSET=latin1; ALTER TABLE `' . $table . '` ADD PRIMARY KEY (`ID`); ';
$queryBuff .= 'ALTER TABLE `' . $table . "` MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Primary index value';";
$this->queryStatus = ( $this->raw( $queryBuff ) ? true : false );
return $this->queryStatus;
}
public function removeTable( $name ) {
if ( !$this->tableExists( $name ) ) {
Debug::error( "No table exists: $name" );
return false;
}
$table = Config::getValue( 'database/dbPrefix' ) . $name;
$this->queryStatus = ( $this->raw( 'DROP TABLE `' . $table . '`' ) ? true : false );
return $this->queryStatus;
}
/**
* This function allows you to add a new field to be
* added to a previously specified table.
*
* @param string $name - The name of the field to add
* @param string $type - The type of field.
* @param integer $length - The maximum length value for the field.
* @param boolean $null - Whether or not the field can be null
* @param string $default - The default value to use for new entries if any.
* @param string $comment - DB comment for this field.
*
* @return boolean
*
* @todo - add more error reporting and checks
* use switch/cases?
*/
public function addField( $name, $type, $length, $null = true, $default = null, $comment = '' ) {
if ( empty( $this->tableBuff ) ) {
Debug::info( 'No Table set.' );
return false;
}
if ( $this->columnExists( $this->tableBuff, $name ) ) {
Debug::error( "Column already exists: $this->tableBuff > $name" );
return false;
}
if ( $null === true ) {
$sDefault = ' DEFAULT NULL';
} else {
$sDefault = ' NOT NULL';
if ( !empty( $default ) ) {
$sDefault .= " DEFAULT '$default'";
}
}
if ( !empty( $length ) ) {
if ( is_int( $length ) ) {
$sType = $type . '(' . $length . ')';
} elseif ( is_string( $length ) && ctype_digit( $length ) ) {
$sType = $type . '(' . $length . ')';
} else {
$sType = $type;
}
} else {
$sType = $type;
}
if ( !empty( $comment ) ) {
$sComment = " COMMENT '$comment'";
} else {
$sComment = '';
}
$this->fieldBuff[] = ' `' . $name . '` ' . $sType . $sDefault . $sComment;
return true;
}
public function search( $table, $column, $param ) {
return $this->action( 'SELECT *', $table, [$column, 'LIKE', '%' . $param . '%'] );
}
/**
* Selects data from the database.
*
* @param string $table - The table we wish to select from.
* @param string $where - The criteria we wish to select.
* @param string $by - The key we wish to order by.
* @param string $direction - The direction we wish to order the results.
*
* @return function
*/
public function get( $table, $where, $by = 'ID', $direction = 'DESC', $limit = null ) {
if ( $where === '*' ) {
$where = ['ID', '>=', '0'];
}
return $this->action( 'SELECT *', $table, $where, $by, $direction, $limit );
}
/**
* Selects data from the database and automatically builds the pagination filter for the results array.
*
* @param string $table - The table we wish to select from.
* @param string $where - The criteria we wish to select.
* @param string $by - The key we wish to order by.
* @param string $direction - The direction we wish to order the results.
*
* @return function
*/
public function getPaginated( $table, $where, $by = 'ID', $direction = 'DESC', $limit = null ) {
if ( $where === '*' ) {
$where = ['ID', '>=', '0'];
}
$db = $this->action( 'SELECT ID', $table, $where, $by, $direction );
Pagination::updatePaginationTotal( $this->totalResults );
if ( ! is_array( $limit ) ) {
$limit = [ Pagination::getMin(), Pagination::getMax() ];
}
Pagination::paginate();
return $this->action( 'SELECT *', $table, $where, $by, $direction, $limit );
}
/**
* Function for returning the entire $results array.
*
* @return array - Returns the current query's results.
*/
public function results() {
return $this->results;
}
/**
* Function for returning the first result in the results array.
*
* @return array - Returns the current first member of the results array.
*/
public function first() {
if ( !empty( $this->results[0] ) ) {
return $this->results[0];
}
return false;
}
/**
* Function for returning current results' row count.
*
* @return int - Returns the current instance's SQL result count.
*/
public function count() {
return $this->count;
}
/**
* Returns if there are errors with the current query or not.
*
* @return bool
*/
public function error() {
return $this->error;
}
/**
* Returns if there are errors with the current query or not.
*
* @return bool
*/
public function errorMessage() {
//$this->query->errorInfo();
return $this->errorMessage;
}
/**
* Returns the boolean status of the most recently executed query.
*
* @return boolean
*/
public function getStatus() {
return $this->queryStatus;
}
}

View File

@ -1,193 +0,0 @@
<?php
/**
* core/database_model.php
*
* The class provides some basic functionality for models that interact
* with the database.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/Core
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Bedrock\Classes;
use TheTempusProject\Canary\Canary as Debug;
use TheTempusProject\Bedrock\Functions\Check;
use TheTempusProject\Bedrock\Bedrock;
class DatabaseModel extends Model {
public $databaseMatrix;
public $tableName;
public function __construct() {
parent::__construct();
}
public function enabled() {
if ( empty( $this->enabled ) ) {
$this->enabled = self::$db->enabled();
}
return $this->enabled;
}
public function filter( $data, $params = [] ) {
return $data;
}
/**
* This method will remove all the installed model components.
*
* @return bool - If the uninstall was completed without error
*/
public function uninstall() {
parent::uninstall();
$this->uninstallTable();
return true;
}
public function rowMatrixToArray( $row_matrix ) {
$row_array = [];
$row_array['row_name'] = array_shift( $row_matrix );
$row_array['row_type'] = array_shift( $row_matrix );
$row_array['length'] = array_shift( $row_matrix );
if ( !empty( $row_matrix ) ) {
$row_array['is_null'] = array_shift( $row_matrix );
} else {
$row_array['is_null'] = true;
}
if ( !empty( $row_matrix ) ) {
$row_array['default_value'] = array_shift( $row_matrix );
} else {
$row_array['default_value'] = null;
}
if ( !empty( $row_matrix ) ) {
$row_array['comment'] = array_shift( $row_matrix );
} else {
$row_array['comment'] = '';
}
return $row_array;
}
/**
* Install db tables needed for the model.
*
* @return {bool}
*/
public function installTable() {
// should have some sort of DELTA functionality and safeguards
if ( empty( $this->tableName ) || empty( $this->databaseMatrix )) {
Debug::log( 'databaseMatrix is empty' );
return true;
}
if ( false === self::$db->newTable( $this->tableName ) ) {
return false;
}
Debug::log( 'adding a new table named: ' . $this->tableName );
foreach ( $this->databaseMatrix as $key => $row_matrix ) {
$row = $this->rowMatrixToArray( $row_matrix );
self::$db->addField(
$row['row_name'],
$row['row_type'],
$row['length'],
$row['is_null'],
$row['default_value'],
$row['comment'],
);
}
self::$db->createTable();
return self::$db->getStatus();
}
public function uninstallTable() {
if ( empty( $this->tableName ) ) {
return;
}
return self::$db->removeTable( $this->tableName );
}
/**
* Retrieves a row by its ID and filters it.
*
* @param {int} [$id]
* @return {object} - The filtered db entry.
*/
public function findById( $id ) {
if ( !Check::id( $id ) ) {
Debug::warn( "$this->tableName fingByID: illegal ID: $id" );
return false;
}
$data = self::$db->get( $this->tableName, ['ID', '=', $id] );
if ( !$data->count() ) {
Debug::info( 'No ' . $this->tableName . ' data found.' );
return false;
}
return $this->filter( $data->first() );
}
/**
* Function to delete the specified entry.
*
* @param int|array $ID the log ID or array of ID's to be deleted
* @return bool
*/
public function delete( $idArray ) {
if ( !is_array( $idArray ) ) {
$idArray = [ $idArray ];
}
foreach ( $idArray as $id ) {
if ( !Check::id( $id ) ) {
Debug::info( "invalid ID: $id." );
$error = true;
continue;
}
if ( self::$db->delete( $this->tableName, [ 'ID', '=', $id ] )->error() ) {
Debug::info( "Error Deleting id: $id" );
$error = true;
continue;
}
Debug::info( $this->tableName . " deleted: $id" );
}
if ( !empty( $error ) ) {
return false;
}
return true;
}
/**
* Function to clear entries of a defined type.
*
* @todo this is probably dumb
* @param string $data - The log type to be cleared
* @return bool
*/
public function empty() {
self::$db->delete( $this->tableName, ['ID', '>=', '0'] );
Debug::info( $this->tableName . ' Cleared' );
return true;
}
/**
* retrieves a list of paginated (limited) results.
*
* @param array $filter - A filter to be applied to the list.
* @return bool|object - Depending on success.
*/
public function listPaginated( $filter = null ) {
$data = self::$db->getPaginated( $this->tableName, '*' );
if ( !$data->count() ) {
Debug::info( $this->tableName . ' - No entries found' );
return false;
}
return $this->filter( $data->results() );
}
public function list( $filter = null ) {
$data = self::$db->get( $this->tableName, '*' );
if ( !$data->count() ) {
Debug::info( $this->tableName . ' - No entries found' );
return false;
}
return $this->filter( $data->results() );
}
}

View File

@ -1,124 +0,0 @@
<?php
/**
* core/model.php
*
* The class provides some basic functionality for models.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/Core
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Bedrock\Classes;
use TheTempusProject\Canary\Canary as Debug;
use TheTempusProject\Bedrock\Classes\Config;
use TheTempusProject\Bedrock\Classes\Database;
class Model {
public static $db;
public $configName;
public $configMatrix = [];
public $resourceMatrix = [];
public $modelVersion;
public $enabled = false;
/**
* The model constructor.
*/
public function __construct() {
Debug::debug( 'Model Constructed: ' . get_class( $this ) );
self::$db = Database::getInstance();
$this->load();
}
/**
* This method will remove all the installed model components.
*
* @return bool - If the uninstall was completed without error
*/
public function uninstall() {
$this->uninstallResources();
$this->uninstallConfigs();
return true;
}
/**
* Install resources needed for the model.
*
* @return {bool}
*/
public function installResources() {
// should have some sort of DELTA functionality and safeguards
$ids = [];
if ( empty($this->resourceMatrix) ) {
return true;
}
foreach ( $this->resourceMatrix as $entry ) {
foreach ( $entry as $key => $value ) {
if ( '{time}' == $value ) {
$entry[$key] = time();
}
}
self::$db->insert( $this->tableName, $entry );
$id = self::$db->lastId();
if ( $id ) {
$ids[] = $id;
}
}
return $ids;
}
public function uninstallResources() {
// this one needs some work
// should probably save the created resource ID's or something and remove them.
// presumably this isn't a big issue because i would imagine the table is removed
// there may be future instances where you can create resources for other tables
return true;
}
/**
* Install configs needed for the model.
*
* @return {bool}
*/
public function installConfigs() {
$config = new Config( CONFIG_JSON );
// should have some sort of DELTA functionality and safeguards
$config->addCategory( $this->configName );
foreach ( $this->configMatrix as $name => $details ) {
$config->add( $this->configName, $name, $details );
}
return $config->save();
}
public function uninstallConfigs() {
if ( empty( $this->configName ) ) {
return true;
}
$config = new Config( CONFIG_JSON );
return $config->removeCategory( $this->configName, true, true );
}
/**
* Tells the installer which types of integrations your model needs to install.
*
* @return bool - if the model was loaded without error
*/
public function load() {
return true;
}
public function getModelVersion() {
return $this->modelVersion;
}
/**
* Checks if the model is enabled.
*
* @return bool - if the model is enabled or not
*/
public function enabled() {
return $this->enabled;
}
}

View File

@ -1,28 +0,0 @@
{
"name": "thetempusproject/bedrock",
"type": "library",
"description": "Tempus project core is intended as the core code used by The Tempus Project: a rapid prototyping framework. This library utilizes the MVC architecture in addition to a custom templating engine designed to make building web applications simple.",
"license": "MIT",
"minimum-stability": "dev",
"keywords": ["templating","mvc","framework"],
"homepage": "https://TheTempusProject.com/Core",
"authors": [
{
"name": "Joey Kimsey",
"email": "Joey@thetempusproject.com",
"homepage": "https://TheTempusProject.com",
"role": "Lead Developer"
}
],
"require": {
"php": ">=5.4.0",
"thetempusproject/tempusdebugger": "3.0"
},
"autoload": {
"classmap": [
"classes",
"core",
"functions"
]
}
}

View File

@ -1,105 +0,0 @@
{
"main": {
"logo": {
"type": "file",
"pretty": "Site Logo (Used mostly in emails)",
"default": "images/logo.png",
"value": "images/logo.png"
},
"name": {
"type": "text",
"pretty": "Site Name",
"default": "TTP Example",
"value": "TTP Example"
},
"template": {
"type": "text",
"pretty": "Default Site Template",
"default": "default",
"value": "default"
},
"tokenEnabled": {
"type": "radio",
"pretty": "Enable CSRF Token for all forms.",
"default": true,
"value": true
}
},
"uploads": {
"files": {
"type": "radio",
"pretty": "Enable File Uploads",
"default": true,
"value": true
},
"images": {
"type": "radio",
"pretty": "Enable Image Uploads",
"default": true,
"value": true
},
"maxFileSize": {
"type": "text",
"pretty": "Maximum File Size",
"default": 5000000,
"value": 5000000
},
"maxImageSize": {
"type": "text",
"pretty": "Maximum Image Size",
"default": 500000,
"value": 500000
}
},
"database": {
"dbEnabled": {
"type": "radio",
"pretty": "Database Enabled",
"default": true,
"protected": true,
"value": true
},
"dbHost": {
"type": "text",
"pretty": "Database Host (IE: http://localhost:3306)",
"default": "127.0.0.1",
"protected": true,
"value": "127.0.0.1"
},
"dbMaxQuery": {
"type": "text",
"pretty": "Maximum results per query",
"default": 100,
"protected": true,
"value": 100
},
"dbName": {
"type": "text",
"pretty": "Database Name",
"default": "ttp-example",
"protected": true,
"value": "ttp-example"
},
"dbPassword": {
"type": "text",
"pretty": "Database Password",
"default": "",
"protected": true,
"value": ""
},
"dbPrefix": {
"type": "text",
"pretty": "Database table Prefix",
"default": "TTP_",
"protected": true,
"value": "TTP_"
},
"dbUsername": {
"type": "text",
"pretty": "Database Username",
"default": "root",
"protected": true,
"value": "root"
}
}
}

View File

@ -1,205 +0,0 @@
<?php
// Check
if (!defined('MINIMUM_PHP_VERSION')) {
define('MINIMUM_PHP_VERSION', 8.2);
}
if (!defined('DATA_TITLE_PREG')) {
define('DATA_TITLE_PREG', '#^[a-z 0-9\-\_ ]+$#mi');
}
if (!defined('REDIRECT_PREG_REQS')) {
define('REDIRECT_PREG_REQS', '#^[a-zA-Z0-9\-\_\./]+$#mi');
}
if (!defined('PATH_PREG_REQS')) {
define('PATH_PREG_REQS', '#^[^/?*:;\\{}]+$#mi');
}
if (!defined('SIMPLE_NAME_PREG')) {
define('SIMPLE_NAME_PREG', '#^[a-zA-Z0-9\-\_]+$#mi');
}
if (!defined('ALLOWED_IMAGE_UPLOAD_EXTENTIONS')) {
define('ALLOWED_IMAGE_UPLOAD_EXTENTIONS', [".jpg",".jpeg",".gif",".png"]);
}
if (!defined('MINIMUM_PASSWORD_LENGTH')) {
define('MINIMUM_PASSWORD_LENGTH', 8);
}
if (!defined('MAXIMUM_PASSWORD_LENGTH')) {
define('MAXIMUM_PASSWORD_LENGTH', 24);
}
if (!defined('ADDITIONAL_PASSWORD_REGEX')) {
// define('ADDITIONAL_PASSWORD_REGEX', '#^[a-z 0-9\-\_ ]+$#mi');
define('ADDITIONAL_PASSWORD_REGEX', '#^[a-z0-9\~\_\+\=\.\,\<\>\(\)\#\?\!\@\$\%\^\&\*\-\ ]+$#mi');
}
if (!defined('SESSION_NAME_REGEX')) {
define('SESSION_NAME_REGEX', '#^[a-zA-Z0-9\_\-]+$#mi');
}
// Cookies
if (!defined('DEFAULT_COOKIE_EXPIRATION')) {
define('DEFAULT_COOKIE_EXPIRATION', 604800);
}
if (!defined('DEFAULT_COOKIE_PREFIX')) {
define('DEFAULT_COOKIE_PREFIX', 'TTP_BEDROCK_');
}
// Database
if (!defined('MAX_RESULTS_PER_PAGE')) {
define('MAX_RESULTS_PER_PAGE', 50);
}
if (!defined('DEFAULT_RESULTS_PER_PAGE')) {
define('DEFAULT_RESULTS_PER_PAGE', 10);
}
// Debug
// Log Levels
if ( ! defined('CANARY_DEBUG_LEVEL_ERROR' ) ) {
define( 'CANARY_DEBUG_LEVEL_ERROR', 'error' );
}
if ( ! defined('CANARY_DEBUG_LEVEL_WARN' ) ) {
define( 'CANARY_DEBUG_LEVEL_WARN', 'warn' );
}
if ( ! defined('CANARY_DEBUG_LEVEL_INFO' ) ) {
define( 'CANARY_DEBUG_LEVEL_INFO', 'info' );
}
if ( ! defined('CANARY_DEBUG_LEVEL_LOG' ) ) {
define( 'CANARY_DEBUG_LEVEL_LOG', 'log' );
}
if ( ! defined('CANARY_DEBUG_LEVEL_DEBUG' ) ) {
define( 'CANARY_DEBUG_LEVEL_DEBUG', 'debug' );
}
if (!defined('CANARY_ENABLED')) {
define('CANARY_ENABLED', false);
}
if (!defined('DEBUG_EMAIL')) {
define('DEBUG_EMAIL', 'webmaster@' . $_SERVER['HTTP_HOST']);
}
if (!defined('HERMES_REDIRECTS_ENABLED')) {
define('HERMES_REDIRECTS_ENABLED', true);
}
if (!defined('RENDERING_ENABLED')) {
define('RENDERING_ENABLED', true);
}
if (!defined('CANARY_TRACE_ENABLED')) {
define('CANARY_TRACE_ENABLED', false);
}
if (!defined('CANARY_DEBUG_TO_CONSOLE')) {
define('CANARY_DEBUG_TO_CONSOLE', false);
}
if (!defined('CANARY_DEBUG_TO_FILE')) {
define('CANARY_DEBUG_TO_FILE', false);
}
if (!defined('CANARY_DEBUG_TO_FILE_LEVEL')) {
define('CANARY_DEBUG_TO_FILE_LEVEL', CANARY_DEBUG_LEVEL_ERROR);
}
// Directories
if (!defined('BEDROCK_ROOT_DIRECTORY')) {
define('BEDROCK_ROOT_DIRECTORY', dirname(__DIR__) . DIRECTORY_SEPARATOR);
}
if (!defined('BEDROCK_CONFIG_DIRECTORY')) {
define('BEDROCK_CONFIG_DIRECTORY', BEDROCK_ROOT_DIRECTORY . 'config' . DIRECTORY_SEPARATOR);
}
if (!defined('BEDROCK_BIN_DIRECTORY')) {
define('BEDROCK_BIN_DIRECTORY', BEDROCK_ROOT_DIRECTORY . 'bin' . DIRECTORY_SEPARATOR);
}
if (!defined('BEDROCK_RESOURCES_DIRECTORY')) {
define('BEDROCK_RESOURCES_DIRECTORY', BEDROCK_ROOT_DIRECTORY . 'resources' . DIRECTORY_SEPARATOR);
}
if (!defined('BEDROCK_VIEW_DIRECTORY')) {
define('BEDROCK_VIEW_DIRECTORY', BEDROCK_ROOT_DIRECTORY . 'views' . DIRECTORY_SEPARATOR);
}
if (!defined('BEDROCK_ERRORS_DIRECTORY')) {
define('BEDROCK_ERRORS_DIRECTORY', BEDROCK_VIEW_DIRECTORY . 'errors' . DIRECTORY_SEPARATOR);
}
if (!defined('BEDROCK_CLASSES_DIRECTORY')) {
define('BEDROCK_CLASSES_DIRECTORY', BEDROCK_ROOT_DIRECTORY . 'classes' . DIRECTORY_SEPARATOR);
}
if (!defined('BEDROCK_FUNCTIONS_DIRECTORY')) {
define('BEDROCK_FUNCTIONS_DIRECTORY', BEDROCK_ROOT_DIRECTORY . 'functions' . DIRECTORY_SEPARATOR);
}
if (!defined('BEDROCK_CONFIG_JSON')) {
define('BEDROCK_CONFIG_JSON', BEDROCK_CONFIG_DIRECTORY . 'config.json');
}
// Shared Directories
if (!defined('APP_ROOT_DIRECTORY')) {
define('APP_ROOT_DIRECTORY', BEDROCK_ROOT_DIRECTORY);
}
if (!defined('CONFIG_DIRECTORY')) {
define('CONFIG_DIRECTORY', BEDROCK_CONFIG_DIRECTORY);
}
if (!defined('BIN_DIRECTORY')) {
define('BIN_DIRECTORY', BEDROCK_BIN_DIRECTORY);
}
if (!defined('VIEW_DIRECTORY')) {
define('VIEW_DIRECTORY', BEDROCK_VIEW_DIRECTORY);
}
if (!defined('ERRORS_DIRECTORY')) {
define('ERRORS_DIRECTORY', BEDROCK_ERRORS_DIRECTORY);
}
if (!defined('CLASSES_DIRECTORY')) {
define('CLASSES_DIRECTORY', BEDROCK_CLASSES_DIRECTORY);
}
if (!defined('FUNCTIONS_DIRECTORY')) {
define('FUNCTIONS_DIRECTORY', BEDROCK_FUNCTIONS_DIRECTORY);
}
if (!defined('RESOURCES_DIRECTORY')) {
define('RESOURCES_DIRECTORY', BEDROCK_RESOURCES_DIRECTORY);
}
if (!defined('TEMPLATE_DIRECTORY')) {
define('TEMPLATE_DIRECTORY', BEDROCK_ROOT_DIRECTORY . 'templates' . DIRECTORY_SEPARATOR);
}
if (!defined('UPLOAD_DIRECTORY')) {
define('UPLOAD_DIRECTORY', BEDROCK_ROOT_DIRECTORY . 'uploads' . DIRECTORY_SEPARATOR);
}
if (!defined('IMAGE_UPLOAD_DIRECTORY')) {
define('IMAGE_UPLOAD_DIRECTORY', BEDROCK_ROOT_DIRECTORY . 'images' . DIRECTORY_SEPARATOR);
}
// Files
if (!defined('COMPOSER_JSON_LOCATION')) {
define('COMPOSER_JSON_LOCATION', APP_ROOT_DIRECTORY . 'composer.json');
}
if (!defined('COMPOSER_LOCK_LOCATION')) {
define('COMPOSER_LOCK_LOCATION', APP_ROOT_DIRECTORY . 'composer.lock');
}
if (!defined('CONFIG_JSON')) {
define('CONFIG_JSON', CONFIG_DIRECTORY . 'config.json');
}
// Other
if (!defined('DEFAULT_CONTROLLER_CLASS')) {
define('DEFAULT_CONTROLLER_CLASS', 'Home');
}
if (!defined('DEFAULT_CONTROLLER_METHOD')) {
define('DEFAULT_CONTROLLER_METHOD', 'index');
}
if (!defined('EMAIL_FROM_EMAIL')) {
define('EMAIL_FROM_EMAIL', 'noreply@' . $_SERVER['HTTP_HOST']);
}
if (!defined('DEFAULT_TIMEZONE')) {
define('DEFAULT_TIMEZONE', "America/New_York");
}
if (!defined('DEFAULT_DATE_FORMAT')) {
define('DEFAULT_DATE_FORMAT', "F j, Y");
}
if (!defined('DEFAULT_TIME_FORMAT')) {
define('DEFAULT_TIME_FORMAT', "g:i:s A");
}
// Random
if (!defined('KB')) {
define('KB', 1024);
}
if (!defined('MB')) {
define('MB', 1048576);
}
if (!defined('GB')) {
define('GB', 1073741824);
}
if (!defined('TB')) {
define('TB', 1099511627776);
}
// Sessions
if (!defined('DEFAULT_SESSION_PREFIX')) {
define('DEFAULT_SESSION_PREFIX', 'TTP_BEDROCK_');
}
// Token
if (!defined('DEFAULT_TOKEN_NAME')) {
define('DEFAULT_TOKEN_NAME', 'TTP_BEDROCK_SESSION_TOKEN');
}
if (!defined('TOKEN_ENABLED')) {
define('TOKEN_ENABLED', true);
}
# Tell the app all constants have been loaded.
define( 'BEDROCK_CONSTANTS_LOADED', true );

View File

@ -1,541 +0,0 @@
<?php
/**
* functions/check.php
*
* This class is used to test various inputs.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/Core
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Bedrock\Functions;
use TheTempusProject\Bedrock\Classes\Config;
use TheTempusProject\Canary\Canary as Debug;
class Check {
private static $formValidator = null;
private static $errorLog = [];
private static $errorLogFull = [];
private static $errorLogUser = [];
/**
* This function only logs an error for the user-error-log.
* Primarily used for providing generalized form feedback
*
* @param {string} [$error] - The error information to be added to the list.
*/
public static function addUserError( $error, $data = false ) {
if ( false !== $data ) {
$error .= ' Data: ' . var_export( $data, true );
}
self::$errorLogUser[] = $error;
}
/**
* Function to properly document and handle any errors we encounter in the check.
*
* @param {string} [$error] - The error information to be added to the list, and used in debug info.
* @param string|array $data - Any additional variables or information.
*/
public static function addError( $error, $data = null ) {
/**
* If an array is provided for $error, it is split into
* 2 separate errors for the logging.
*/
if ( is_array( $error ) ) {
$userError = $error[1];
$error = $error[0];
}
Debug::info( "Check error: $error" );
if ( !empty( $data ) ) {
Debug::info( 'Additional error information:' );
Debug::v( $data );
}
self::$errorLog[] = ['errorInfo' => $error, 'errorData' => $data];
if ( isset( $userError ) ) {
self::$errorLogUser[] = $userError;
}
}
/**
* Function for returning the system error array.
*
* @param $full - Flag for returning the full error log.
* @return array - Returns an Array of all the failed checks up until this point.
*/
public static function systemErrors( $full = false ) {
if ( $full ) {
return self::$errorLogFull;
}
return self::$errorLog;
}
/**
* Function for returning the user error array.
*
* @return array - Returns an Array of all the recorded user errors.
*/
public static function userErrors() {
return self::$errorLogUser;
}
/**
* Function for resetting the current error logs and adding the old log
* to the complete error log.
*/
public static function errorReset() {
self::$errorLogFull = array_merge( self::$errorLogFull, self::$errorLog );
self::$errorLog = [];
self::$errorLogUser = [];
}
/**
* Checks an uploaded image for proper size, formatting, and lack of errors in the upload.
*
* @param string $data - The name of the upload field.
* @return {bool}
*/
public static function imageUpload( $imageName ) {
if ( !Config::getValue( 'uploads/images' ) ) {
self::addError( 'Image uploads are disabled.' );
return false;
}
if ( !isset( $_FILES[$imageName] ) ) {
self::addError( 'File not found.', $imageName );
return false;
}
if ( $_FILES[$imageName]['error'] != 0 ) {
self::addError( 'File error:' . $_FILES[$imageName]['error'] );
return false;
}
if ( $_FILES[$imageName]['size'] > Config::getValue( 'uploads/maxImageSize' ) ) {
self::addError( 'Image is too large.' );
return false;
}
$fileType = strrchr( $_FILES[$imageName]['name'], '.' );
if ( !( in_array( $fileType, ALLOWED_IMAGE_UPLOAD_EXTENTIONS ) ) ) {
self::addError( 'Invalid image type', $fileType );
return false;
}
return true;
}
/**
* Checks a string for a boolean string value.
*
* @param string $data - The data being checked.
* @return {bool}
*/
public static function tf( $data ) {
if ( true === $data || '1' === $data || 1 === $data || strtolower( $data ) === 'true' ) {
return true;
}
if ( false === $data || '0' === $data || 0 === $data || strtolower( $data ) === 'false' ) {
return true;
}
self::addError( 'Invalid true-false: ', $data );
return false;
}
/**
* Checks for alpha-numeric type.
*
* @param string $data - The data being checked.
* @return {bool}
*/
public static function alnum( $data ) {
if ( ctype_alpha( $data ) ) {
return true;
}
self::addError( 'Invalid alpha-numeric.', $data );
return false;
}
/**
* Checks an input for spaces.
*
* @param string $data - The data being checked.
* @return {bool}
*/
public static function nospace( $data ) {
if ( !stripos( $data, ' ' ) ) {
return true;
}
self::addError( 'Invalid no-space input.', $data );
return false;
}
/**
* Checks the data to see if it is a digit.
*
* @param mixed $data - Data being checked.
* @return {bool}
*/
public static function id( $data ) {
if ( is_numeric( $data ) ) {
return true;
}
self::addError( 'Invalid ID.', $data );
return false;
}
/**
* Checks the data to see if it is a valid data string. It can
* only contain letters, numbers, space, underscore, and dashes.
*
* @param mixed $data - Data being checked.
* @return {bool}
*/
public static function dataTitle( $data ) {
if ( preg_match( DATA_TITLE_PREG, $data ) ) {
return true;
}
self::addError( 'Invalid data title.', $data );
return false;
}
/**
* Checks the data to see if there are any illegal characters
* in the filename.
*
* @param {string} [$data]
* @return {bool}
*/
public static function path( $data = null ) {
if ( preg_match( REDIRECT_PREG_REQS, $data ) ) {
return true;
}
self::addError( 'Invalid path.', $data );
return false;
}
/**
* Checks the form token.
*
* @param {string|null} - String to check for the token. (Post Token assumed)
* @return {bool}
*/
public static function token( $data = null ) {
if ( false === Token::isTokenEnabled() ) {
return true;
}
if ( empty( $data ) ) {
$data = Input::post( 'token' );
}
$result = Token::check( $data );
if ( $result === false ) {
self::addUserError( 'Invalid Token.', $data );
}
return $result;
}
/**
* Checks for proper url formatting.
*
* @param {string} [$data] The input being checked
* @return {bool}
*/
public static function url( $data ) {
$url = filter_var( $data, FILTER_SANITIZE_URL );
if ( filter_var( $url, FILTER_VALIDATE_URL ) === false ) {
self::addError( 'Invalid Url' );
return false;
}
return true;
}
/**
* Checks email formatting.
*
* @param {string} [$data] - The string being tested.
* @return {bool}
*/
public static function email( $data ) {
$sanitizedEmail = filter_var( $data, FILTER_SANITIZE_EMAIL );
if ( !filter_var( $sanitizedEmail, FILTER_VALIDATE_EMAIL ) ) {
self::addError( 'Email is not properly formatted.' );
return false;
}
return true;
}
/**
* Checks password formatting.
*
* @param {string} [$password] - The string being tested.
* @param {string} [$secondaryPassword] - The string it is being compared to.
* @return {bool}
*/
public static function password( $password, $secondaryPassword = null ) {
if ( strlen( $password ) < MINIMUM_PASSWORD_LENGTH ) {
self::addError([
'Password is too short.',
'Password must be longer than ' . MINIMUM_PASSWORD_LENGTH . ' characters.',
]);
return false;
}
if ( strlen( $password ) > MAXIMUM_PASSWORD_LENGTH ) {
self::addError([
'Password is too long.',
'Password must not be longer than ' . MAXIMUM_PASSWORD_LENGTH . ' characters.',
]);
return false;
}
if ( defined( 'ADDITIONAL_PASSWORD_REGEX' ) ) {
if ( !preg_match( ADDITIONAL_PASSWORD_REGEX, $password ) ) {
self::addError([
'Password does not pass requirements.',
]);
return false;
}
}
if ( isset( $secondaryPassword ) && $password !== $secondaryPassword ) {
self::addError( 'Passwords do not match.' );
return false;
}
return true;
}
/**
* Checks name formatting.
*
* Requirements:
* - 2 - 20 characters long
* - must only contain letters: [A-Z] , [a-z]
*
* @param {string} [$data] - The string being tested.
* @return {bool}
*/
public static function name( $data ) {
if ( strlen( $data ) > 20 ) {
self::addError( 'Name is too long.', $data );
return false;
}
if ( strlen( $data ) < 2 ) {
self::addError( 'Name is too short.', $data );
return false;
}
if ( !ctype_alpha( str_replace( ' ', '', $data ) ) ) {
self::addError( 'Name is not properly formatted.', $data );
return false;
}
return true;
}
/**
* Checks for alpha-numeric type.
*
* @param {string} [$data] - The data being checked.
* @return {bool}
*/
public static function uploads() {
if ( ini_get( 'file_uploads' ) == 1 ) {
return true;
}
self::addError( 'Uploads are disabled.' );
return false;
}
/**
* Checks the PHP version.
*
* @return {bool}
*/
public static function php() {
$phpVersion = phpversion();
if ( version_compare( $phpVersion, MINIMUM_PHP_VERSION, '>=' ) ) {
return true;
}
self::addError( 'PHP version is too old.', $phpVersion );
return false;
}
/**
* Checks PHP's mail function.
*
* @return {bool}
*/
public static function mail() {
if ( function_exists( 'mail' ) ) {
return true;
}
self::addError( 'PHP Mail function is not enabled.' );
return false;
}
/**
* Checks if PHP's Safe mode is enabled.
*
* @return {bool}
*/
public static function safe() {
if ( !ini_get( 'safe_mode' ) ) {
return true;
}
self::addError( 'PHP Safe Mode is enabled.' );
return false;
}
/**
* Checks if PHP's Safe mode is enabled.
* @todo - come back and make this more variable
* pdo_firebird
* pdo_informix
* pdo_mssql
* pdo_oci
* pdo_oci8
* pdo_odbc
* pdo_pgsql
* @return {bool}
*/
public static function phpExtensions() {
if ( !extension_loaded( 'pdo' ) ) {
self::addError( 'PHP PDO is not enabled.' );
return false;
}
if ( extension_loaded( 'pdo_mysql' ) ) {
return true;
} elseif ( extension_loaded( 'pdo_sqlite' ) ) {
return true;
}
self::addError( 'No usable PDO extension is loaded.' );
return false;
}
/**
* Checks to make sure sessions are working properly.
*
* @return {bool}
*/
public static function sessions() {
$_SESSION['sessionTest'] = 1;
if ( !empty( $_SESSION['sessionTest'] ) ) {
unset( $_SESSION['sessionTest'] );
return true;
}
self::addError( 'There is an error with saving sessions.' );
return false;
}
/**
* Checks to see if cookies are enabled.
*
* @return {bool}
*/
public static function cookies() {
Cookie::put( 'test', 'test' );
if ( count( $_COOKIE ) > 0 ) {
Cookie::delete( 'test' );
return true;
}
self::addError( 'Cookies are not enabled.' );
return false;
}
/**
* Checks to see if $data contains only numbers, letters, underscores, and dashes
*
* @return {bool}
*/
public static function simpleName( $data ) {
if ( empty( $data ) ) {
self::addError( 'Empty simple name.', $data );
return false;
}
if ( preg_match( SIMPLE_NAME_PREG, $data ) ) {
return true;
}
self::addError( 'Invalid simple name.', $data );
return false;
}
/**
* Checks to see if the server is running an Nginx configuration.
*
* @return {bool}
*/
public static function isApache() {
if ( isset( $_SERVER['SERVER_SOFTWARE'] ) ) {
if ( false !== stripos( $_SERVER['SERVER_SOFTWARE'], 'Apache' ) ) {
return true;
}
}
return false;
}
/**
* Checks to see if the Apache server has the appropriate modules enabled.
*
* @return {bool}
*/
public static function apacheMods() {
if ( !self::isApache() ) {
self::addError( 'Server is not Apache.' );
return false;
}
$error_log = count( self::$errorLog );
$mods = apache_get_modules();
if ( !in_array( 'mod_rewrite', $mods ) ) {
self::addError( 'The Apache "rewrite" module is disabled.', $data );
}
if ( !in_array( 'mod_buffer', $mods ) ) {
self::addError( 'The Apache "buffer" module is disabled.', $data );
}
if ( !in_array( 'mod_headers', $mods ) ) {
self::addError( 'The Apache "header" module is disabled.', $data );
}
if ( !in_array( 'mod_alias', $mods ) ) {
self::addError( 'The Apache "alias" module is disabled.', $data );
}
if ( !in_array( 'mod_dir', $mods ) ) {
self::addError( 'The Apache "dir" module is disabled.', $data );
}
if ( !in_array( 'mod_expires', $mods ) ) {
self::addError( 'The Apache "expires" module is disabled.', $data );
}
if ( count( self::$errorLog ) > $error_log ) {
return false;
}
return true;
}
/**
* Checks to see if the server is running an Apache configuration.
*
* @return {bool}
*/
public static function isNginx() {
if ( isset( $_SERVER['SERVER_SOFTWARE'] ) ) {
if ( false !== stripos( $_SERVER['SERVER_SOFTWARE'], 'Nginx' ) ) {
return true;
}
}
return false;
}
/**
* Checks the data to see if it is a valid data string. It can
* only contain letters, numbers, space, underscore, and dashes.
*
* @param mixed $data - Data being checked.
* @return {bool}
*/
public static function sessionName( $data ) {
if ( preg_match( SESSION_NAME_REGEX, $data ) ) {
return true;
}
self::addError( 'Invalid session title.', $data );
return false;
}
}

View File

@ -1,51 +0,0 @@
<?php
/**
* functions/code.php
*
* This class is used for creation of custom codes used by the application.
*
* @todo Better code generation.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/Core
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Bedrock\Functions;
use TheTempusProject\Canary\Canary as Debug;
class Code {
/**
* Generates a new confirmation code.
*
* @return string
*/
public static function genConfirmation() {
$code = md5( uniqid() );
Debug::log( "Code Generated: Confirmation: $code" );
return $code;
}
/**
* Generates a new install hash.
*
* @return string
*/
public static function genInstall() {
$code = md5( uniqid() );
Debug::log( "Code Generated: Token: $code" );
return $code;
}
/**
* Generates a new token code.
*
* @return string
*/
public static function genToken() {
$code = md5( uniqid() );
Debug::log( "Code Generated: Token: $code" );
return $code;
}
}

View File

@ -1,95 +0,0 @@
<?php
/**
* functions/cookie.php
*
* This class is used for manipulation of cookies.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/Core
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Bedrock\Functions;
use TheTempusProject\Canary\Canary as Debug;
class Cookie {
/**
* Checks whether $data is a valid saved cookie or not.
*
* @param {string} [$data] - Name of the cookie to check for.
* @return {bool}
*/
public static function exists( $data ) {
if ( !Check::dataTitle( $data ) ) {
return false;
}
$cookieName = DEFAULT_COOKIE_PREFIX . $data;
if ( isset( $_COOKIE[$cookieName] ) ) {
Debug::log( "Cookie found: $data" );
return true;
}
Debug::info( "Cookie not found: $data" );
return false;
}
/**
* Returns a specific cookie if it exists.
*
* @param {string} [$data] - Cookie to retrieve data from.
* @return {bool|string} - String from the requested cookie, or false if the cookie does not exist.
*/
public static function get( $data ) {
if ( !Check::dataTitle( $data ) ) {
return false;
}
if ( self::exists( $data ) ) {
$cookieName = DEFAULT_COOKIE_PREFIX . $data;
return $_COOKIE[$cookieName];
}
return false;
}
/**
* Create cookie function.
*
* @param {string} [$name] - Cookie name.
* @param {string} [$value] - Cookie value.
* @param {int} [$expiry] - How long (in seconds) until the cookie should expire.
* @return {bool}
*/
public static function put( $name, $value, $expire = null ) {
if ( ! Check::dataTitle( $name ) ) {
return false;
}
if ( ! $expire ) {
$expire = time() + DEFAULT_COOKIE_EXPIRATION;
}
if ( ! Check::ID( $expire ) ) {
return false;
}
$cookieName = DEFAULT_COOKIE_PREFIX . $name;
$test = setcookie( $cookieName, $value, $expire, '/' );
if ( ! $test ) {
Debug::error( "Cookie not created: '$name', until: $expire" );
return false;
}
Debug::debug( "Cookie Created: $name till $expire" );
return true;
}
/**
* Delete cookie function.
*
* @param {string} [$name] - Name of cookie to be deleted.
*/
public static function delete( $name ) {
if ( !Check::dataTitle( $name ) ) {
return false;
}
$cookieName = DEFAULT_COOKIE_PREFIX . $name;
setcookie( $cookieName, '', ( time() - 1 ), '/' );
Debug::log( "Cookie deleted: $name" );
return true;
}
}

View File

@ -1,408 +0,0 @@
<?php
/**
* functions/date.php
*
* This class is used to manage date inputs in a site-wide repeatable way.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/Core
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Bedrock\Functions;
use DateTime;
use DateTimeZone;
class Date {
private static $date = null;
private static $errorLog = [];
private static $errorLogFull = [];
private static $errorLogUser = [];
public static function formatTimestamp( $type, $timestamp ) {
if ( stripos( $type, 'date' ) ) {
$dateFormat = self::getDateFormat();
} elseif ( stripos( $type, 'time' ) ) {
$dateFormat = self::getTimeFormat();
} else {
$dateFormat = self::getDateFormat() . ' ' . self::getTimeFormat();
}
$time = intval( $timestamp );
$dt = new DateTime( self::getTimezone() );
$dt->setTimestamp( $time );
return $dt->format( $dateFormat );
}
public static function applyTimezoneToTimestamp( $timestamp ) {
$timestamp = intval( $timestamp );
$date = new DateTime();
$date->setTimestamp( $timestamp );
$timezone = new DateTimeZone( self::getTimezone() );
$date->setTimezone( $timezone );
$formattedDate = $date->format('Y-m-d H:i:s');
return $formattedDate;
}
public static function applyUtcToDate( $date ) {
$timestamp = intval( strtotime( $date ) );
$startDate = new DateTime( $date, new DateTimeZone( self::getTimezone() ) );
$startDate->setTimezone( new DateTimeZone( 'UTC' ) );
$firstSecond = $startDate->getTimestamp();
return $firstSecond;
}
public static function getReadableDate( $timestamp, $with_timezone = false ) {
if ( $with_timezone ) {
$date = new DateTime();
$date->setTimestamp( $timestamp );
$timezone = new DateTimeZone( self::getTimezone() );
$date->setTimezone( $timezone );
$formattedDate = $date->format('Y-m-d H:i:s');
return $formattedDate;
}
return date( 'Y-m-d H:i:s', $timestamp );
}
public static function convertToTimestampWithTimezone( $dateString, $timeString, $timezoneString ) {
$datetimeString = $dateString . ' ' . $timeString;
$date = new DateTime($datetimeString, new DateTimeZone($timezoneString));
$timestamp = $date->getTimestamp();
return $timestamp;
}
public static function getDateBreakdown( $timestamp, $with_timezone = false ) {
$timestamp = intval( $timestamp );
$init = date('Y-m-d H:i:s', $timestamp);
if ( true === $with_timezone ) {
$readableDate = self::applyTimezoneToTimestamp( $timestamp );
} else {
$readableDate = date('Y-m-d H:i:s', $timestamp);
}
$date = date( 'Y-m-d', strtotime( $readableDate ) );
$time = date( 'H:i', strtotime( $readableDate ) );
return [
'time' => $time,
'date' => $date,
];
}
public static function determineDateInput( $with_timezone = false) {
$currentTimestamp = time();
$currentDateString = date( 'F d, Y', $currentTimestamp );
// Prioritize inputs: Post > Get > defaults
if ( Input::exists('time') ) {
$time = Input::post('time') ? Input::post('time') : Input::get('time');
} else {
$time = '00:00';
}
if ( Input::exists('date') ) {
$date = Input::post('date') ? Input::post('date') : Input::get('date');
} else {
$date = $currentDateString;
}
if ( Input::exists('hour') ) {
$hour = Input::post('hour') ? Input::post('hour') : Input::get('hour');
} else {
$hour = '00';
}
if ( Input::exists('minute') ) {
$minute = Input::post('minute') ? Input::post('minute') : Input::get('minute');
} else {
$minute = '00';
}
if ( Input::exists('day') ) {
$day = Input::post('day') ? Input::post('day') : Input::get('day');
} else {
$day = date( 'd', $currentTimestamp );
}
if ( Input::exists('month') ) {
$month = Input::post('month') ? Input::post('month') : Input::get('month');
} else {
$month = date( 'M', $currentTimestamp );
}
if ( Input::exists('year') ) {
$year = Input::post('year') ? Input::post('year') : Input::get('year');
} else {
$year = date( 'Y', $currentTimestamp );
}
// prioritize a time input over individual hours and minutes
if ( '00:00' == $time ) {
$time = $hour . ':' . $minute;
}
// prioritize a date input over individual day, month, year
if ( $currentDateString == $date ) {
$inputTimestamp = strtotime( $time. ' ' . $month . ' ' . $day . ', ' . $year );
/**
* Its possible to select IE: 31, Feb; in navigation.
* This will back the day down until it finds an acceptable date.
*/
$intDay = intval( $day );
$intMonth = intval( date( 'm', $inputTimestamp ) );
$intYear = intval( $year );
// 29
if ( ! checkdate( $intMonth, $intDay, $intYear ) ) {
$day = $intDay - 1;
}
// 30
if ( ! checkdate( $intMonth, $intDay, $intYear ) ) {
$day = $intDay - 1;
}
// 31
if ( ! checkdate( $intMonth, $intDay, $intYear ) ) {
$day = $intDay - 1;
}
$inputTimestamp = strtotime( $time. ' ' . $month . ' ' . $day . ', ' . $year );
} else {
$inputTimestamp = strtotime( $time . ' ' . $date );
}
$timestamp = self::getReadableDate( $inputTimestamp, $with_timezone );
return $timestamp;
}
/**
* Application getters
*/
public static function getDateFormat() {
$format = DEFAULT_DATE_FORMAT;
if ( !empty( self::$activePrefs ) && !empty( self::$activePrefs['dateFormat'] ) ) {
$format = self::$activePrefs['dateFormat'];
}
return $format;
}
public static function getTimeFormat() {
$format = DEFAULT_TIME_FORMAT;
if ( !empty( self::$activePrefs ) && !empty( self::$activePrefs['timeFormat'] ) ) {
$format = self::$activePrefs['timeFormat'];
}
return $format;
}
public static function getTimezone() {
$format = DEFAULT_TIMEZONE;
if ( !empty( self::$activePrefs ) && !empty( self::$activePrefs['timezone'] ) ) {
$format = self::$activePrefs['timezone'];
}
return $format;
}
/**
* Current getters
*/
public static function getCurrentDay() {
$date = new DateTime();
$date->setTimestamp( time() );
$timezone = new DateTimeZone( self::getTimezone() );
$date->setTimezone( $timezone );
$hourNow = $date->format('d');
return $hourNow;
}
public static function getCurrentMonth() {
$date = new DateTime();
$date->setTimestamp( time() );
$timezone = new DateTimeZone( self::getTimezone() );
$date->setTimezone( $timezone );
$hourNow = $date->format('M');
return $hourNow;
}
public static function getCurrentYear() {
$date = new DateTime();
$date->setTimestamp( time() );
$timezone = new DateTimeZone( self::getTimezone() );
$date->setTimezone( $timezone );
$hourNow = $date->format('Y');
return $hourNow;
}
public static function getCurrentHour() {
$date = new DateTime();
$date->setTimestamp( time() );
$timezone = new DateTimeZone( self::getTimezone() );
$date->setTimezone( $timezone );
$hourNow = $date->format('H');
return $hourNow;
}
/**
* Relative Dates
*/
public static function getDayStartTimestamp( $timestamp = 0, $with_timezone = false ) {
if ( empty( $timestamp ) ) {
$timestamp = self::determineDateInput();
}
$day = date( 'd', $timestamp );
$month = date( 'M', $timestamp );
$year = date( 'Y', $timestamp );
$startTime = '00:00:00';
$firstSecond = date( 'U', strtotime( "$startTime $day $month $year" ) );
if ( $with_timezone ) {
$specificDateString = $year.'-'.$month.'-'.$day;
$startDate = new DateTime( $specificDateString . ' ' . $startTime, new DateTimeZone( self::getTimezone() ) );
$startDate->setTimezone( new DateTimeZone( 'UTC' ) );
$firstSecond = $startDate->getTimestamp();
}
return $firstSecond;
}
public static function getDayEndTimestamp( $timestamp = 0, $with_timezone = false ) {
if ( empty( $timestamp ) ) {
$timestamp = self::determineDateInput();
}
$day = date( 'd', $timestamp );
$month = date( 'M', $timestamp );
$year = date( 'Y', $timestamp );
$endTime = '23:59:59';
$lastSecond = date( 'U', strtotime( "$endTime $day $month $year" ) );
if ( $with_timezone ) {
$specificDateString = $year.'-'.$month.'-'.$day;
$endDate = new DateTime( $specificDateString . ' ' . $endTime, new DateTimeZone( self::getTimezone() ) );
$endDate->setTimezone( new DateTimeZone( 'UTC' ) );
$lastSecond = $endDate->getTimestamp();
}
return $lastSecond;
}
public static function getWeekStartTimestamp( $timestamp = 0, $with_timezone = false ) {
if ( empty( $timestamp ) ) {
$timestamp = self::determineDateInput();
}
// $timestamp = intval( $timestamp );
$startTime = '00:00:00';
// find the first sunday in the week containing the date
if ( date( 'N', $timestamp ) == 7 ) {
$firstDate = $timestamp;
} else {
$firstDate = strtotime('last Sunday', $timestamp);
}
$firstSecond = date( 'Y-M-d '. $startTime, $firstDate );
if ( $with_timezone ) {
$startDate = new DateTime( $firstSecond, new DateTimeZone( self::getTimezone() ) );
$startDate->setTimezone( new DateTimeZone( 'UTC' ) );
$firstSecond = $startDate->getTimestamp();
} else {
$firstSecond = strtotime( $firstSecond );
}
return $firstSecond;
}
public static function getWeekEndTimestamp( $timestamp = 0, $with_timezone = false ) {
if ( empty( $timestamp ) ) {
$timestamp = self::determineDateInput();
}
// $timestamp = intval( $timestamp );
$endTime = '23:59:59';
// find the last saturday in the week containing the date
if ( date( 'N', $timestamp ) == 6 ) {
$lastDate = $timestamp;
} else {
$lastDate = strtotime( 'next Saturday', $timestamp );
}
$lastSecond = date( 'Y-M-d '. $endTime, $lastDate );
if ( $with_timezone ) {
$endDate = new DateTime( $lastSecond, new DateTimeZone( self::getTimezone() ) );
$endDate->setTimezone( new DateTimeZone( 'UTC' ) );
$lastSecond = $endDate->getTimestamp();
} else {
$lastSecond = strtotime( $lastSecond );
}
return $lastSecond;
}
public static function getMonthStartTimestamp( $timestamp = 0, $with_timezone = false ) {
if ( empty( $timestamp ) ) {
$timestamp = self::determineDateInput();
}
$startTime = '00:00:00';
$year = date( 'Y', $timestamp );
$month = date( 'M', $timestamp );
$firstDayUnix = strtotime( "$startTime $month 01 $year" );
// find the first sunday in the week containing the date
if ( date( 'N', $firstDayUnix ) == 7 ) {
$firstDate = $firstDayUnix;
} else {
$firstDate = strtotime('last Sunday', $firstDayUnix);
}
$firstSecond = date( 'Y-M-d '. $startTime, $firstDate );
if ( $with_timezone ) {
$startDate = new DateTime( $firstSecond, new DateTimeZone( self::getTimezone() ) );
$startDate->setTimezone( new DateTimeZone( 'UTC' ) );
$firstSecond = $startDate->getTimestamp();
} else {
$firstSecond = strtotime( $firstSecond );
}
return $firstSecond;
}
public static function getMonthEndTimestamp( $timestamp = 0, $with_timezone = false ) {
if ( empty( $timestamp ) ) {
$timestamp = self::determineDateInput();
}
$endTime = '23:59:59';
$year = date( 'Y', $timestamp );
// Find last day of month
$month = date( 'm', $timestamp );
$lastDay = cal_days_in_month( CAL_GREGORIAN, $month, $year );
$month = date( 'M', $timestamp );
$lastDayUnix = strtotime( "$endTime $month $lastDay $year" );
// find the last saturday in the week containing the date
if ( date( 'N', $lastDayUnix ) == 6 ) {
$lastDate = $lastDayUnix;
} else {
$lastDate = strtotime('next Saturday', $lastDayUnix);
}
$lastSecond = date( 'Y-M-d '. $endTime, $lastDate );
if ( $with_timezone ) {
$endDate = new DateTime( $lastSecond, new DateTimeZone( self::getTimezone() ) );
$endDate->setTimezone( new DateTimeZone( 'UTC' ) );
$lastSecond = $endDate->getTimestamp();
} else {
$lastSecond = strtotime( $lastSecond );
}
return $lastSecond;
}
public static function getYearStartTimestamp( $timestamp = 0, $with_timezone = false ) {
if ( empty( $timestamp ) ) {
$timestamp = self::determineDateInput();
}
$startTime = '00:00:00';
$year = date( 'Y', $timestamp );
$firstDayUnix = strtotime( "$startTime January 01 $year" );
$firstSecond = date( 'Y-M-d '. $startTime, $firstDayUnix );
if ( $with_timezone ) {
$startDate = new DateTime( $firstSecond, new DateTimeZone( self::getTimezone() ) );
$startDate->setTimezone( new DateTimeZone( 'UTC' ) );
$firstSecond = $startDate->getTimestamp();
} else {
$firstSecond = strtotime( $firstSecond );
}
return $firstSecond;
}
public static function getYearEndTimestamp( $timestamp = 0, $with_timezone = false ) {
if ( empty( $timestamp ) ) {
$timestamp = self::determineDateInput();
}
$endTime = '23:59:59';
$year = date( 'Y', $timestamp );
$lastDayUnix = strtotime( "$endTime December 31 $year" );
$lastSecond = date( 'Y-M-d '. $endTime, $lastDayUnix );
if ( $with_timezone ) {
$endDate = new DateTime( $lastSecond, new DateTimeZone( self::getTimezone() ) );
$endDate->setTimezone( new DateTimeZone( 'UTC' ) );
$lastSecond = $endDate->getTimestamp();
} else {
$lastSecond = strtotime( $lastSecond );
}
return $lastSecond;
}
}

View File

@ -1,43 +0,0 @@
<?php
/**
* functions/hash.php
*
* This class is used to salt, hash, and check passwords.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/Core
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Bedrock\Functions;
use TheTempusProject\Canary\Canary as Debug;
class Hash {
/**
* Uses php native hashing scheme to make a password hash.
*
* @param string $password - Validated password input.
* @return string - salted/hashed and ready to use password hash.
*/
public static function make( $password ) {
return password_hash( $password, PASSWORD_DEFAULT );
}
/**
* Uses php native password support to verify the given password.
*
* @param string $password - Password being verified.
* @param string $hash - Saved password hash.
* @return bool
*/
public static function check( $password, $hash ) {
$result = password_verify( $password, $hash );
if ( $result ) {
return true;
}
Debug::info( 'Hash::check: Failed to verify password match.' );
return false;
}
}

View File

@ -1,111 +0,0 @@
<?php
/**
* functions/input.php
*
* This class manages and returns GET, FILE, and POST variables.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/Core
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Bedrock\Functions;
use TheTempusProject\Canary\Canary as Debug;
class Input {
/**
* Checks to see if input exists in the order of POST, GET, FILE.
* A default name value of "submit" is used if none is specified.
*
* @param {string} [$data] - Name of the desired input (default: 'submit')
* @return {bool}
*/
public static function exists( $data = 'submit' ) {
if ( self::post( $data ) ) {
return true;
} elseif ( self::get( $data ) ) {
return true;
} elseif ( self::file( $data ) ) {
return true;
} else {
Debug::info( 'Input::exists: No input Found: '. $data );
return false;
}
}
/**
* Checks for a files existence and that it is not null
* then returns its value or bool false if none is found
*
* @param {string} [$data] - Name of desired $_FILES value.
* @return {bool|string} - Returns false if not found and a string if found.
*/
public static function file( $data ) {
if ( !isset( $_FILES[$data] ) ) {
Debug::debug( "Input - file : $data not found." );
return false;
}
if ( $_FILES[$data]['tmp_name'] == '' ) {
Debug::debug( "Input - file : $data empty." );
return false;
}
return $_FILES[$data];
}
/**
* Checks for a post variable named $data and returns
* its value if true or bool false if none is found.
*
* @param {string} [$data] - Name of desired $_POST value.
* @return {bool|string} - Returns false if not found and a string if found.
*/
public static function post( $data ) {
if ( !isset( $_POST[$data] ) ) {
Debug::debug( "Input - post : $data not found." );
return false;
}
if ( empty( $_POST[$data] ) ) {
Debug::debug( "Input - post : $data empty." );
return false;
}
return $_POST[$data];
}
/**
* Checks for a post variable named $data and returns
* its value if found or null if not found.
*
* @param {string} [$data] - Name of desired $_POST value.
* @return {string}
*/
public static function postNull( $data ) {
if ( !isset( $_POST[$data] ) ) {
Debug::debug( "Input - post : $data not found." );
return;
}
if ( empty( $_POST[$data] ) ) {
Debug::debug( "Input - post : $data empty." );
return;
}
return $_POST[$data];
}
/**
* Checks for a get variable named $data.
*
* @param {string} [$data] - Name of desired $_GET value.
* @return {bool|string} - Returns false if not found and a string if found.
*/
public static function get( $data ) {
if ( !isset( $_GET[$data] ) ) {
Debug::debug( "Input - get : $data not found." );
return false;
}
if ( empty( $_GET[$data] ) ) {
Debug::debug( "Input - get : $data empty." );
return false;
}
return $_GET[$data];
}
}

View File

@ -1,44 +0,0 @@
<?php
/**
* functions/sanitize.php
*
* This class is used to sanitize user input.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/Core
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Bedrock\Functions;
class Sanitize {
/**
* This function strips all html tags except for p/a/br from the given string.
*
* @param {string} [$data] - The string to be parsed
* @return {string} - The sanitized string.
*/
public static function contentShort( $data ) {
return strip_tags( $data, '<p><a><br>' );
}
/**
* This function is to remove $'s and brackets from the rich HTML editor
* which are the only parts that cause parse issues
*
* @param {string} [$data] - The string to be parsed
* @return {string} - The sanitized string.
*/
public static function rich( $data ) {
$data = preg_replace( '#\{#', '&#123;', $data );
$data = preg_replace( '#\}#', '&#125;', $data );
$data = preg_replace( '#\$#', '&#36;', $data );
return $data;
}
public static function url( $data ) {
$trimmed = rtrim( $data, '/' );
$filtered = filter_var( $trimmed, FILTER_SANITIZE_URL );
return $filtered;
}
}

View File

@ -1,130 +0,0 @@
<?php
/**
* functions/session.php
*
* This class is used for management of session data.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/Core
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Bedrock\Functions;
use TheTempusProject\Canary\Canary as Debug;
class Session {
/**
* Checks if a session exists.
*
* @param {string} [$name] - The name of the session being checked for.
* @return {bool}
*/
public static function exists( $name ) {
if ( !Check::sessionName( $name ) ) {
return false;
}
$sessionName = DEFAULT_SESSION_PREFIX . $name;
if ( isset( $_SESSION[$sessionName] ) ) {
return true;
}
Debug::info("Session::exists - Session not found: $sessionName");
return false;
}
/**
* Retrieves the value of a session if it exists
*
* @param {string} [$name] - The name of the session variable you are trying to retrieve.
* @return {string|bool} - Returns the data from the session or false if nothing is found..
*/
public static function get( $name ) {
if ( !Check::sessionName( $name ) ) {
return false;
}
if ( self::exists( $name ) ) {
$sessionName = DEFAULT_SESSION_PREFIX . $name;
return $_SESSION[$sessionName];
}
Debug::info("Session::get - Session not found: $name");
return false;
}
/**
* Creates a session.
*
* @param {string} [$name] - Session name.
* @param {string} [$data] - Session data.
* @return {bool}
*/
public static function put( $name, $data ) {
if ( !Check::sessionName( $name ) ) {
return false;
}
$sessionName = DEFAULT_SESSION_PREFIX . $name;
$_SESSION[$sessionName] = $data;
Debug::info("Session: Created: $sessionName");
return true;
}
/**
* Deletes the specified session.
*
* @param {string} [$name] - The name of the session to be destroyed.
* @return {bool}
*/
public static function delete( $name ) {
if ( !Check::sessionName( $name ) ) {
return false;
}
if ( self::exists( $name ) ) {
$sessionName = DEFAULT_SESSION_PREFIX . $name;
unset( $_SESSION[$sessionName] );
Debug::info("Session::deleted: $sessionName");
return true;
}
Debug::error("Session::delete - Session not found.");
return false;
}
/**
* 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} [$data] - 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.
*/
public static function checkFlash( $name ) {
if ( !Check::sessionName( $name ) ) {
return false;
}
if ( self::exists( $name ) ) {
Debug::info("Session::flash - Exists");
$session = self::get( $name );
self::delete( $name );
return $session;
}
return;
}
public static function flash( $name, $data = null ) {
if ( !Check::sessionName( $name ) ) {
return false;
}
if ( !empty( $data ) ) {
self::put( $name, $data );
Debug::info("Session::flash - Session created.");
return true;
}
if ( self::exists( $name ) ) {
Debug::info("Session::flash - Exists");
$session = self::get( $name );
self::delete( $name );
return $session;
}
Debug::error("Session::flash - null return");
return;
}
}

View File

@ -1,120 +0,0 @@
<?php
/**
* functions/token.php
*
* This class handles form tokens.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/Core
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Bedrock\Functions;
use TheTempusProject\Bedrock\Classes\Config;
use TheTempusProject\Canary\Canary as Debug;
class Token {
private static $tokenName;
private static $tokenSaved;
private static $tokenEnabled = 'not_set';
public static function start() {
if ( !self::isTokenEnabled() ) {
return false;
}
if ( empty( self::$tokenName ) ) {
self::setTokenName();
}
if ( empty( self::$tokenSaved ) ) {
self::$tokenSaved = Session::get( self::$tokenName );
Debug::info( 'Token saved: ' . Session::get( self::$tokenName ) );
} else {
Debug::log( 'Original token was already saved' );
}
return true;
}
public static function setTokenName( $name = '' ) {
if ( !empty( $name ) ) {
if ( !Check::simpleName( $name ) ) {
Debug::warn( "Token name invalid: $name" );
return false;
}
self::$tokenName = $name;
}
if ( !empty( self::$tokenName ) ) {
return true;
}
self::$tokenName = DEFAULT_TOKEN_NAME;
return true;
}
/**
* Determines, saves, then returns whether or not tokens are enabled.
*
* @return bool
*/
public static function isTokenEnabled() {
if ( self::$tokenEnabled !== 'not_set' ) {
return self::$tokenEnabled;
}
$sessionCheck = Check::sessions();
if ( $sessionCheck === false ) {
self::$tokenEnabled = false;
return self::$tokenEnabled;
}
$tokenConfig = Config::getValue( 'main/tokenEnabled' );
if ( !empty( $tokenConfig ) ) {
self::$tokenEnabled = $tokenConfig;
return self::$tokenEnabled;
}
if ( !empty( TOKEN_ENABLED ) ) {
self::$tokenEnabled = TOKEN_ENABLED;
return self::$tokenEnabled;
}
self::$tokenEnabled = false;
return self::$tokenEnabled;
}
/**
* Creates a token and stores it as a session variable.
*
* @return string - Returns the string of the token generated.
*/
public static function generate() {
if ( !self::start() ) {
Debug::warn( 'Token disabled' );
return false;
}
$token = Code::genToken();
Session::put( self::$tokenName, $token );
Debug::info( 'New token generated' );
return $token;
}
/**
* Checks a form token against a session token to confirm no XSS has occurred.
*
* @param string $token - This should be a post variable from the hidden token field.
* @return bool
*/
public static function check( $token ) {
if ( !self::start() ) {
Debug::warn( 'Token disabled' );
return false;
}
if ( $token === self::$tokenSaved ) {
Debug::info( 'Token check passed' );
return true;
}
Debug::error( 'Token check failed' );
Debug::error( 'token: ' . $token );
Debug::error( 'tokenSaved: ' . self::$tokenSaved );
return false;
}
}

View File

@ -1,73 +0,0 @@
<?php
/**
* functions/upload.php
*
* This class is used for manipulation of Images used by the application.
*
* @todo Add the config switches.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/Core
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Bedrock\Functions;
use TheTempusProject\Canary\Canary as Debug;
class Upload {
public static $lastUpload = null;
public static $lastUploadLocation = null;
/**
* This function verifies a valid image upload, creates any
* necessary directories, moves, and saves, the image.
*
* @param {string} [$fieldname] - The name of the input field for the upload.
* @param {string} [$folder] - The sub-folder to store the uploaded image.
* @return {bool}
*/
public static function image( $fieldname, $folder ) {
if ( !Check::imageUpload( $fieldname ) ) {
Debug::error( Check::systemErrors() );
return false;
}
// @todo Let's try and avoid 777 if possible
// Try catch here for better error handling
if ( empty( $folder ) ) {
$folder = IMAGE_UPLOAD_DIRECTORY;
}
if ( !file_exists( $folder ) ) {
Debug::Info( 'Creating Directory because it does not exist' );
mkdir( $folder, 0777, true );
}
self::$lastUpload = basename( $_FILES[$fieldname]['name'] );
self::$lastUploadLocation = $folder . self::$lastUpload;
if ( move_uploaded_file( $_FILES[$fieldname]['tmp_name'], self::$lastUploadLocation ) ) {
return true;
} else {
Debug::error( 'failed to move the file.' );
return false;
}
}
/**
* Returns the file location of the most recent
* uploaded image if one exists.
*
* @return {string} - The file location of the most recent uploaded image.
*/
public static function lastLocation() {
return self::$lastUploadLocation;
}
/**
* Returns the name of the most recent
* uploaded image if one exists.
*
* @return {string} - The filename of the most recent uploaded image.
*/
public static function last() {
return self::$lastUpload;
}
}

View File

@ -1,15 +0,0 @@
RewriteEngine On
RewriteBase {APP_WEB_ROOT}
# Intercepts other errors
RewriteRule ^errors/(.*)$ index.php?error=$1 [L,NC,QSA]
# Intercept all traffic not originating locally and not going to images or uploads
RewriteCond %{REMOTE_ADDR} !^127\.0\.0\.1
RewriteCond %{REMOTE_ADDR} !^\:\:1
RewriteRule ^(.+)$ {APP_WEB_ROOT}?url=$1 [QSA,L]
# Catchall for any non existent files or folders
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ {APP_WEB_ROOT}?url=$1 [QSA,L]";

View File

@ -1,12 +0,0 @@
location /web/www/errors {
rewrite ^/web/www/errors/(.*)$ /web/www/index.php?error=$1 break;
}
location /web/www/ {
if ($remote_addr !~ "^127\.0\.0\.1"){
rewrite ^/web/www/(.+)$ /web/www/indexParser.php?local=false&url=$1 break;
}
if (!-e $request_filename){
rewrite ^/web/www/(.+)$ /web/www/indexParser.php?missing=true&url=$1 [QSA,L]";;
}
}

View File

@ -1,46 +0,0 @@
# 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/

View File

@ -1,88 +0,0 @@
# 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.

View File

@ -1,21 +0,0 @@
# TempusDebugger
#### PHP Library for sending debug messages to Chrome
###### Developer(s): Joey Kimsey
TempusDebugger is a php library that will enable real time debugging messages to be sent to the TempusTools chrome extension.
**Notice: This code is in _still_ not production ready. This framework is provided as is, use at your own risk.**
## Installation
To install simply use the composer command:
`php composer.phar require TheTempusProject/TempusDebugger:1.*`
REALLLLLY need to update the contributing document for this one.

View File

@ -1,41 +0,0 @@
<?php
/**
* autoload.php
*
* Uses the Hermes autoloader if it has been defined.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/TempusDebugger
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Canary;
use TheTempusProject\Hermes\Classes\Autoloader;
if ( !defined( 'CANARY_ROOT_DIRECTORY' ) ) {
define( 'CANARY_ROOT_DIRECTORY', dirname( __DIR__ ) . DIRECTORY_SEPARATOR );
}
if ( ! defined('CANARY_CONFIG_DIRECTORY' ) ) {
define('CANARY_CONFIG_DIRECTORY', CANARY_ROOT_DIRECTORY . 'config' . DIRECTORY_SEPARATOR);
}
if ( ! defined('CANARY_CONSTANTS_LOADED' ) ) {
require_once CANARY_CONFIG_DIRECTORY . 'constants.php';
}
if ( class_exists( 'TheTempusProject\Hermes\Classes\Autoloader' ) ) {
$Autoloader = new Autoloader;
$autoloader->setRootFolder( CANARY_ROOT_DIRECTORY );
$autoloader->addNamespace(
'TheTempusProject\Canary\Classes',
'classes'
);
$autoloader->addNamespace(
'TheTempusProject\Canary',
'bin'
);
$Autoloader->register();
define( 'CANARY_AUTOLOADED', true );
}

View File

@ -1,449 +0,0 @@
<?php
/**
* bin/canary.php
*
* The Canary class is responsible for providing a log of relevant debugging information.
* It has functionality to generate a log file as it goes allowing you to print it at any
* given point in the script. It can also interface directly with the browser via the
* Overwatch browser extension.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/Core
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Canary;
use TheTempusProject\Canary\Classes\TempusDebugger;
use TheTempusProject\Canary\Classes\Logger;
use Exception;
class Canary {
private static $lastCall = '';
private static $group = 0;
private static $tempusDebugger;
private static $tempusLogger;
private static $debugLog = '';
/**
* @param {object} [$exception]
*/
public static function handle_exception( $exception ) {
echo '<div style="margin-top: 80px;margin-bottom: 80px;margin-left: 275px;">';
echo '<hr><h3>Exception Handler:</h3>';
echo '<b>Class: </b><code>' . get_class( $exception ) . '</code><br>';
// echo "<b>Message: </b><code>{ $exception->message }" . '</code><br>';
// echo "<b>File: </b><code>{ $exception->getFile() }" . '</code><br>';
// echo "<b>Line: </b><code>{ $exception->getLine() }" . '</code><br>';
echo '<b>Exception:</b><pre>' . print_r( $exception, true ) . '</pre><br><hr>';
echo '</div>';
}
/**
* @param {object} [$exception]
*/
public static function handle_error( $error_code, $error_description, $file = null, $error_line_number = null ) {
$displayErrors = ini_get( 'display_errors' );
$displayErrors = strtolower( $displayErrors );
echo '<div style="margin-top: 80px;margin-bottom: 80px;margin-left: 275px;">';
if ( 0 === $error_code || 0 === error_reporting() || $displayErrors === 'on' ) {
echo '<h1>fail</h1></div>';
return false;
}
// wtf? remove this or find an alternative
// if ( isset( $GLOBALS['error_fatal'] ) ) {
// if ( $GLOBALS['error_fatal'] && $error_code ) {
// die('fatal');
// }
// }
$errstr = htmlspecialchars( $error_description );
switch( $error_code ) {
case E_ERROR:
$errorType = 'E_ERROR';
$errorReadable = 'Fatal Error';
// throw new ErrorException($error_description, 0, $error_code, $file, $err_line);
// $log = LOG_ERR;
break;
case E_WARNING:
$errorType = 'E_WARNING';
$errorReadable = 'Warning';
// throw new WarningException($error_description, 0, $error_code, $file, $err_line);
// $log = LOG_WARNING;
break;
case E_PARSE:
$errorType = 'E_PARSE';
$errorReadable = 'Parse Error';
// throw new ParseException($error_description, 0, $error_code, $file, $err_line);
// $log = LOG_ERR;
break;
case E_NOTICE:
$errorType = 'E_NOTICE';
$errorReadable = 'Notice';
// throw new NoticeException($error_description, 0, $error_code, $file, $err_line);
// $log = LOG_NOTICE;
break;
case E_CORE_ERROR:
$errorType = 'E_CORE_ERROR';
$errorReadable = 'Core Error';
// throw new CoreErrorException($error_description, 0, $error_code, $file, $err_line);
// $log = LOG_ERR;
break;
case E_CORE_WARNING:
$errorType = 'E_CORE_WARNING';
$errorReadable = 'Core Warning';
// throw new CoreWarningException($error_description, 0, $error_code, $file, $err_line);
// $log = LOG_WARNING;
break;
case E_COMPILE_ERROR:
$errorType = 'E_COMPILE_ERROR';
$errorReadable = 'Compile Error';
// throw new CompileErrorException($error_description, 0, $error_code, $file, $err_line);
// $log = LOG_ERR;
break;
case E_COMPILE_WARNING:
$errorType = 'E_COMPILE_WARNING';
$errorReadable = 'Compile Warning';
// throw new CoreWarningException($error_description, 0, $error_code, $file, $err_line);
// $log = LOG_WARNING;
break;
case E_USER_ERROR:
$errorType = 'E_USER_ERROR';
$errorReadable = 'User Error';
// handling an sql error
if ( $error_description == '(SQL)' ) {
echo '<b>SQL Query: </b><code>' . SQLQUERY . '</code><br>';
echo '<b>SQL Line: </b><code>' . SQLERRORLINE . '</code><br>';
echo '<b>SQL File: </b><code>' . SQLERRORFILE . '</code><br>';
}
// throw new UserErrorException($error_description, 0, $error_code, $file, $err_line);
// $log = LOG_ERR;
break;
case E_USER_NOTICE:
$errorType = 'E_USER_NOTICE';
$errorReadable = 'User Notice';
// $log = LOG_NOTICE;
break;
case E_STRICT:
$errorType = 'E_STRICT';
$errorReadable = 'Strict';
// $log = LOG_NOTICE;
break;
case E_RECOVERABLE_ERROR:
$errorType = 'E_RECOVERABLE_ERROR';
$errorReadable = 'Recoverable Error';
// $log = LOG_WARNING;
break;
case E_USER_WARNING:
$errorType = 'E_USER_WARNING';
$errorReadable = 'User Warning';
// $log = LOG_WARNING;
break;
case E_DEPRECATED:
$errorType = 'E_DEPRECATED';
$errorReadable = 'Deprecated';
// $log = LOG_NOTICE;
// no break
case E_USER_DEPRECATED:
$errorType = 'E_USER_DEPRECATED';
$errorReadable = 'User Deprecated';
// $log = LOG_NOTICE;
break;
default:
$errorType = 'UNKNOWN';
$errorReadable = 'Unknown Error';
break;
}
echo '<h3>' . $errorReadable . ':</h3>';
echo "<b>Error Description: </b><code>{$error_description}" . '</code><br>';
echo "<b>File: </b><code>{$file}" . '</code><br>';
echo "<b>Line Number: </b><code>{$error_line_number}" . '</code><br>';
echo "<b>Error Case: </b><code>{$errorType}" . '</code><br>';
echo "<b>Error Code: </b><code>{$error_code}" . '</code><br>';
echo "<b>Error Description (fancy): </b><code>{$errstr}" . '</code><br>';
echo '<b>PHP Version: </b><code>' . PHP_VERSION . '</code><br>';
echo '<b>PHP OS: </b><code>' . PHP_OS . '</code><br>';
// $data = [
// // 'level' => $log,
// 'code' => $error_line_number,
// // 'error' => $error,
// 'description' => $error_description,
// 'file' => $file,
// 'line' => $error_line_number,
// 'path' => $file,
// 'message' => $error . ' (' . $error_line_number . '): ' . $error_description . ' in [' . $file . ', line ' . $error_line_number . ']'
// ];
echo '</div>';
}
/**
* Acts as a constructor.
*/
private static function startDebug() {
if ( self::status( 'file' ) ) {
self::$tempusLogger = new Logger;
}
if ( self::status( 'console' ) ) {
ob_start();
self::$tempusDebugger = TempusDebugger::getInstance( true );
self::$tempusDebugger->setOption( 'includeLineNumbers', CANARY_SHOW_LINES );
// self::$tempusDebugger->setHash( CANARY_SECURE_HASH );
}
}
/**
* Returns the current Debug Status.
*
* @return bool
*/
public static function status( $flag = null ) {
switch ( $flag ) {
case 'console':
return CANARY_DEBUG_TO_CONSOLE;
case 'file':
return CANARY_DEBUG_TO_FILE;
case 'trace':
return CANARY_TRACE_ENABLED;
case 'render':
return RENDERING_ENABLED;
case 'debug':
default:
return CANARY_ENABLED;
}
}
/**
* This is the interface that writes to our log file/console depending on input type.
*
* @param string $type - Debugging type.
* @param string $data - Debugging data.
*
* @todo make a case statement
*/
private static function put( $type, $data = null, $params = null ) {
if ( ! CANARY_ENABLED ) {
return;
}
if ( strlen( self::$debugLog ) > 50000 ) {
self::$tempusDebugger->log( 'Error log too large, possible loop.' );
return;
}
if ( is_object( $data ) ) {
$data = 'cannot save objects';
}
if ( !is_string( $data ) ) {
$data = var_export( $data, true );
}
if ( !empty( self::$lastCall ) ) {
$highlight = '';
$trimmed_class = trim(self::$lastCall, '\\');
$trimmed_class = trim($trimmed_class, '"');
$trimmed_class = trim($trimmed_class, "'");
$exploded_classname = explode( '\\\\', $trimmed_class );
$exploded_classname[1] = '<b>'.$exploded_classname[1].'</b>';
$bolded_line = implode( ' \\ ', $exploded_classname );
$shortened_name = str_ireplace( 'TheTempusProject', 'TTP', $bolded_line );
if ( in_array( $type, ['error','info','warn'])) {
$highlight = 'debug-log-' . $type;
}
$full_line = "<span class='debug-log {$highlight}'>&lt;{$shortened_name}&gt;:{$data}</span><br>";
self::$debugLog .= $full_line;
self::$lastCall = '';
}
if ( self::status( 'file' ) ) {
if ( ! self::$tempusLogger ) {
self::startDebug();
}
switch ( $type ) {
case 'error':
case 'warn':
case 'info':
case 'log':
case 'debug':
self::$tempusLogger->addLog( $type, $data );
break;
default:
break;
}
}
if ( ! self::status( 'console' ) ) {
return;
}
if ( ! self::$tempusDebugger ) {
self::startDebug();
}
switch ( $type ) {
case 'variable':
self::$tempusDebugger->info( $data, $params );
break;
case 'groupEnd':
self::$tempusDebugger->groupEnd();
break;
case 'trace':
self::$tempusDebugger->trace( $data );
break;
case 'group':
if ( $params ) {
self::$tempusDebugger->group( $data, $params );
} else {
self::$tempusDebugger->group( $data );
}
break;
case 'info':
self::$tempusDebugger->$type( 'color: #1452ff', '%c' . $data );
break;
default:
self::$tempusDebugger->$type( $data );
break;
}
}
/**
* Ends a group.
*/
public static function gend() {
if ( self::$group > 0 ) {
self::$group--;
self::put( 'groupEnd' );
}
}
/**
* Creates a group divider into the console output.
*
* @param string $data name of the group
* @param wild $collapsed if anything is present the group will be collapsed by default
*/
public static function closeAllGroups() {
list($childClass, $caller) = debug_backtrace(false, 2);
self::$lastCall = var_export($caller['class'],true);
if ( self::$group > 0 ) {
while ( self::$group > 0 ) {
self::$group--;
self::put( 'groupEnd' );
}
// self::put('log', 'closed all groups.');
}
}
/**
* Creates a group divider into the console output.
*
* @param string $data name of the group
* @param wild $collapsed if anything is present the group will be collapsed by default
*/
public static function group( $data, $collapsed = null ) {
list($childClass, $caller) = debug_backtrace(false, 2);
self::$lastCall = var_export($caller['class'],true);
if ( !empty( $collapsed ) ) {
$params = ['Collapsed' => true];
self::put( 'group', $data, $params );
} else {
self::put( 'group', $data );
}
self::$group++;
}
/**
* Allows you to print the contents of any variable into the console.
*
* @param WILD $var - The variable you wish to read.
* @param string $data - Optional name for the variable output.
*/
public static function v( $var, $data = null ) {
list($childClass, $caller) = debug_backtrace(false, 2);
self::$lastCall = var_export($caller['class'],true);
if ( !isset( $data ) ) {
$data = 'Default Variable label';
}
self::put( 'variable', $var, $data );
}
/**
* Socket function for a basic debugging log.
*
* @param string $data - The debug data.
*/
public static function log( $data, $params = null ) {
list($childClass, $caller) = debug_backtrace(false, 2);
self::$lastCall = var_export($caller['class'],true);
self::put( 'log', $data );
if ( !empty( $params ) ) {
self::gend();
}
}
/**
* Provides a stack trace from the current calling spot.
*
* @param string $data the name of the trace
*/
public static function trace( $data = 'Default Trace' ) {
list( $childClass, $caller ) = debug_backtrace(false, 2);
self::$lastCall = var_export( $caller['class'], true );
self::group( 'Debug Trace', 1 );
self::put( 'trace' );
self::gend();
}
/**
* Socket function for debugging info.
*
* @param string $data - The debug data.
*/
public static function info( $data, $params = null ) {
list($childClass, $caller) = debug_backtrace(false, 2);
self::$lastCall = var_export($caller['class'],true);
self::put( 'info', $data );
if ( !empty( $params ) ) {
self::gend();
}
}
/**
* Socket function for a debugging warning.
*
* @param string $data - The debug data.
*/
public static function warn( $data, $params = null ) {
list($childClass, $caller) = debug_backtrace(false, 2);
self::$lastCall = var_export($caller['class'],true);
self::put( 'warn', $data );
if ( !empty( $params ) ) {
self::gend();
}
}
public static function debug( $data, $params = null ) {
list($childClass, $caller) = debug_backtrace(false, 2);
self::$lastCall = var_export($caller['class'],true);
self::put( 'debug', $data );
if ( !empty( $params ) ) {
self::gend();
}
}
/**
* Socket function for a debugging error.
*
* @param string $data - The debug data.
*/
public static function error( $data, $params = null ) {
list($childClass, $caller) = debug_backtrace(false, 2);
self::$lastCall = var_export($caller['class'],true);
self::put( 'error', $data );
if ( CANARY_TRACE_ENABLED ) {
self::trace();
}
if ( !empty( $params ) ) {
self::gend();
}
}
/**
* This returns the contents of the debug log.
*/
public static function dump() {
return self::$debugLog;
}
}

View File

@ -1,213 +0,0 @@
<?php
/**
* tempus_tools.php
*
* This is an interface for the Tempus Debugger to interact with TempusTools
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/TempusDebugger
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Canary\Classes;
if ( !class_exists( 'TempusDebugger', false ) ) {
require_once 'tempus_debugger.php';
}
/**
* Sends the given data to the TempusTools Chrome Extension.
* The data can be displayed in devtools.
*
* @param mixed $Object
* @return true
* @throws Exception
*/
function tt() {
$instance = TempusDebugger::getInstance( true );
$args = func_get_args();
return call_user_func_array( [ $instance, 'tt' ], $args );
}
class TempusTools {
/**
* Set an Insight console to direct all logging calls to
*
* @param object $console The console object to log to
* @return void
*/
public static function setLogToInsightConsole( $console ) {
TempusDebugger::getInstance( true )->setLogToInsightConsole( $console );
}
/**
* Enable and disable logging to TempusTools
*
* @param boolean $enabled TRUE to enable, FALSE to disable
* @return void
*/
public static function setEnabled( $enabled ) {
TempusDebugger::getInstance( true )->setEnabled( $enabled );
}
/**
* Check if logging is enabled
*
* @return boolean TRUE if enabled
*/
public static function getEnabled() {
return TempusDebugger::getInstance( true )->getEnabled();
}
/**
* Specify a filter to be used when encoding an object
*
* Filters are used to exclude object members.
*
* @param string $class The class name of the object
* @param array $filter An array or members to exclude
* @return void
*/
public static function setObjectFilter( $class, $filter ) {
TempusDebugger::getInstance( true )->setObjectFilter( $class, $filter );
}
/**
* Set some options for the library
*
* @param array $options The options to be set
* @return void
*/
public static function setOptions( $options ) {
TempusDebugger::getInstance( true )->setOptions( $options );
}
/**
* Get options for the library
*
* @return array The options
*/
public static function getOptions() {
return TempusDebugger::getInstance( true )->getOptions();
}
/**
* Log object to console
*
* @param mixed $object
* @return true
* @throws Exception
*/
public static function send() {
$args = func_get_args();
return call_user_func_array( [ TempusDebugger::getInstance( true ), 'tt' ], $args );
}
/**
* Start a group for following messages
*
* Options:
* Collapsed: [true|false]
* Color: [#RRGGBB|ColorName]
*
* @param string $name
* @param array $options OPTIONAL Instructions on how to log the group
* @return true
*/
public static function group( $name, $options = null ) {
return TempusDebugger::getInstance( true )->group( $name, $options );
}
/**
* Ends a group you have started before
*
* @return true
* @throws Exception
*/
public static function groupEnd() {
return self::send( null, null, TempusDebugger::GROUP_END );
}
/**
* Log object with label to the console
*
* @param mixes $object
* @param string $label
* @return true
* @throws Exception
*/
public static function log( $object, $label = null ) {
return self::send( $object, $label, TempusDebugger::LOG );
}
/**
* Log object with label to the console
*
* @param mixes $object
* @param string $label
* @return true
* @throws Exception
*/
public static function info( $object, $label = null ) {
return self::send( $object, $label, TempusDebugger::INFO );
}
/**
* Log object with label to the console
*
* @param mixes $object
* @param string $label
* @return true
* @throws Exception
*/
public static function warn( $object, $label = null ) {
return self::send( $object, $label, TempusDebugger::WARN );
}
/**
* Log object with label to the console
*
* @param mixes $object
* @param string $label
* @return true
* @throws Exception
*/
public static function error( $object, $label = null ) {
return self::send( $object, $label, TempusDebugger::ERROR );
}
/**
* Dumps key and variable to console
*
* @param string $key
* @param mixed $variable
* @return true
* @throws Exception
*/
public static function dump( $key, $variable ) {
return self::send( $variable, $key, TempusDebugger::DUMP );
}
/**
* Log a trace in the console
*
* @param string $label
* @return true
* @throws Exception
*/
public static function trace( $label ) {
return self::send( $label, TempusDebugger::TRACE );
}
/**
* Log a table in the console
*
* @param string $label
* @param string $table
* @return true
* @throws Exception
*/
public static function table( $label, $table ) {
return self::send( $table, $label, TempusDebugger::TABLE );
}
}

View File

@ -1,108 +0,0 @@
<?php
/**
* logger.php
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
*/
namespace TheTempusProject\Canary\Classes;
use TheTempusProject\Bedrock\Functions\Date;
class Logger {
public $file;
public $logDirectory;
public $logFilePath;
public function __construct() {
$this->setupLogFile();
$this->file = fopen( $this->logFilePath, 'a' );
fwrite( $this->file, '===================------++++++++++------===================' . PHP_EOL );
}
public function setupLogFile() {
$this->logDirectory = rtrim( CANARY_DEBUG_DIRECTORY, DIRECTORY_SEPARATOR );
if ( ! is_dir( $this->logDirectory ) ) {
mkdir( $this->logDirectory, 0777, true );
}
$currentFile = date('m-d-Y') . '.log';
$this->logFilePath = $this->logDirectory . DIRECTORY_SEPARATOR . $currentFile;
if ( ! file_exists( $this->logFilePath ) ) {
touch( $this->logFilePath );
chmod( $this->logFilePath, 0777 );
}
}
public function __destruct() {
fwrite( $this->file, '============================================================' . PHP_EOL );
fclose( $this->file );
}
public function addLog( $type = 'log', $log ) {
switch ( CANARY_DEBUG_TO_FILE_LEVEL ) {
case CANARY_DEBUG_LEVEL_ERROR:
$acceptableLoggingLevels = [
CANARY_DEBUG_LEVEL_ERROR,
];
if (! in_array( $type, $acceptableLoggingLevels )) {
return;
}
break;
case CANARY_DEBUG_LEVEL_WARN:
$acceptableLoggingLevels = [
CANARY_DEBUG_LEVEL_ERROR,
CANARY_DEBUG_LEVEL_WARN,
];
if (! in_array( $type, $acceptableLoggingLevels )) {
return;
}
break;
case CANARY_DEBUG_LEVEL_INFO:
$acceptableLoggingLevels = [
CANARY_DEBUG_LEVEL_ERROR,
CANARY_DEBUG_LEVEL_WARN,
CANARY_DEBUG_LEVEL_INFO,
];
if (! in_array( $type, $acceptableLoggingLevels )) {
return;
}
break;
case CANARY_DEBUG_LEVEL_LOG:
$acceptableLoggingLevels = [
CANARY_DEBUG_LEVEL_ERROR,
CANARY_DEBUG_LEVEL_WARN,
CANARY_DEBUG_LEVEL_INFO,
CANARY_DEBUG_LEVEL_LOG,
];
if (! in_array( $type, $acceptableLoggingLevels )) {
return;
}
break;
case CANARY_DEBUG_LEVEL_DEBUG:
$acceptableLoggingLevels = [
CANARY_DEBUG_LEVEL_ERROR,
CANARY_DEBUG_LEVEL_WARN,
CANARY_DEBUG_LEVEL_INFO,
CANARY_DEBUG_LEVEL_LOG,
CANARY_DEBUG_LEVEL_DEBUG,
];
if (! in_array( $type, $acceptableLoggingLevels )) {
return;
}
break;
default:
return;
}
$formattedMessage = $this->timestamp() . $this->typestamp( $type ) . $log . PHP_EOL;
fwrite( $this->file, $formattedMessage );
}
private function timestamp() {
$dateString = Date::getReadableDate( time() );
return '['.$dateString.'] - ';
}
private function typestamp( $type ) {
$dateString = Date::getReadableDate( time() );
return '[' . strtoupper( $type ) . '] - ';
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,27 +0,0 @@
{
"name": "thetempusproject/tempusdebugger",
"type": "library",
"description": "Framework for sending php messages to chrome for in-browser debugging.",
"license": "MIT",
"minimum-stability": "dev",
"keywords": ["php","tools","debugging","thetempusproject"],
"homepage": "https://github.com/TheTempusProject/TempusDebugger",
"authors": [
{
"name": "Joey Kimsey",
"email": "Joey@thetempusproject.com",
"homepage": "https://TheTempusProject.com",
"role": "Lead Developer"
}
],
"require": {
"php": ">=5.4.0"
},
"autoload": {
"classmap": [
"TempusDebugger.php",
"TempusTools.php"
]
}
}

View File

@ -1,53 +0,0 @@
<?php
if ( ! defined('CANARY_ENABLED' ) ) {
define( 'CANARY_ENABLED', false );
}
// Directories
if ( ! defined( 'CANARY_ROOT_DIRECTORY' ) ) {
define( 'CANARY_ROOT_DIRECTORY', dirname( __DIR__ ) . DIRECTORY_SEPARATOR );
}
if ( ! defined( 'CANARY_CONFIG_DIRECTORY' ) ) {
define( 'CANARY_CONFIG_DIRECTORY', CANARY_ROOT_DIRECTORY . 'config' . DIRECTORY_SEPARATOR );
}
// Log Levels
if ( ! defined('CANARY_DEBUG_LEVEL_ERROR' ) ) {
define( 'CANARY_DEBUG_LEVEL_ERROR', 'error' );
}
if ( ! defined('CANARY_DEBUG_LEVEL_WARN' ) ) {
define( 'CANARY_DEBUG_LEVEL_WARN', 'warn' );
}
if ( ! defined('CANARY_DEBUG_LEVEL_INFO' ) ) {
define( 'CANARY_DEBUG_LEVEL_INFO', 'info' );
}
if ( ! defined('CANARY_DEBUG_LEVEL_LOG' ) ) {
define( 'CANARY_DEBUG_LEVEL_LOG', 'log' );
}
if ( ! defined('CANARY_DEBUG_LEVEL_DEBUG' ) ) {
define( 'CANARY_DEBUG_LEVEL_DEBUG', 'debug' );
}
// File Logging
if ( ! defined('CANARY_DEBUG_TO_FILE' ) ) {
define( 'CANARY_DEBUG_TO_FILE', false );
}
if ( ! defined( 'CANARY_DEBUG_DIRECTORY' ) ) {
define( 'CANARY_DEBUG_DIRECTORY', CANARY_ROOT_DIRECTORY . 'logs' . DIRECTORY_SEPARATOR );
}
if ( ! defined( 'CANARY_DEBUG_TO_FILE_LEVEL' ) ) {
define( 'CANARY_DEBUG_TO_FILE_LEVEL', CANARY_DEBUG_LEVEL_ERROR );
}
if ( ! defined( 'CANARY_SECURE_HASH' ) ) {
define( 'CANARY_SECURE_HASH', '' );
}
if ( ! defined( 'CANARY_SHOW_LINES' ) ) {
define( 'CANARY_SHOW_LINES', false );
}
if ( ! defined('CANARY_DEBUG_TO_CONSOLE' ) ) {
define( 'CANARY_DEBUG_TO_CONSOLE', false );
}
# Tell the app all constants have been loaded.
define( 'CANARY_CONSTANTS_LOADED', true );

View File

@ -1,2 +0,0 @@
# Hermes
Hermes is a small package to handle routing and autoloading designed in conjunction with [The Tempus Project](https://thetempusproject.com).

View File

@ -1,44 +0,0 @@
<?php
/**
* autoload.php
*
* Uses the Hermes autoloader if it has been defined.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/TempusDebugger
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Canary;
use TheTempusProject\Hermes\Classes\Autoloader;
if ( !defined( 'HERMES_ROOT_DIRECTORY' ) ) {
define( 'HERMES_ROOT_DIRECTORY', dirname( __DIR__ ) . DIRECTORY_SEPARATOR );
}
if ( ! defined('HERMES_CONFIG_DIRECTORY' ) ) {
define('HERMES_CONFIG_DIRECTORY', HERMES_ROOT_DIRECTORY . 'config' . DIRECTORY_SEPARATOR);
}
if ( ! defined('HERMES_CONSTANTS_LOADED' ) ) {
require_once HERMES_CONFIG_DIRECTORY . 'constants.php';
}
if ( ! class_exists( 'TheTempusProject\Hermes\Classes\Autoloader' ) ) {
require_once HERMES_CLASSES_DIRECTORY . 'autoloader.php';
}
$autoloader = new Autoloader;
$autoloader->setRootFolder( HERMES_ROOT_DIRECTORY );
$autoloader->addNamespace(
'TheTempusProject\Hermes\Classes',
'classes'
);
$autoloader->addNamespace(
'TheTempusProject\Hermes\Functions',
'functions'
);
$autoloader->register();
define( 'HERMES_AUTOLOADED', true );

View File

@ -1,168 +0,0 @@
<?php
/**
* classes/autoloader.php
*
* This should provide a simple way to add autoloading.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/Core
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Hermes\Classes;
class Autoloader {
protected static $namespaces = [];
protected $rootFolder = '';
/**
* Automatically requires all the files within a given directory.
*
* @param {string} [$directory]
* @param {bool} [$includeRoot]
*/
public function includeFolder( $directory = '', $includeRoot = true ) {
$base_dir = str_replace( '\\', DIRECTORY_SEPARATOR, $directory );
$base_dir = str_replace( '/', DIRECTORY_SEPARATOR, $base_dir );
$base_dir = rtrim( $base_dir, DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR;
// should require all the files in the specific folder
if ( $includeRoot ) {
$base_dir = $this->rootFolder . $base_dir;
}
if ( !is_dir( $base_dir ) ) {
return false;
}
$files = scandir( $base_dir );
array_shift( $files );
array_shift( $files );
foreach ( $files as $key => $value ) {
if ( stripos( $value, '.php' ) ) {
include_once $base_dir . $value;
}
}
return true;
}
/**
* Adds a namespace and corresponding directory to the autoload list.
*
* @param {string} [$namespace]
* @param {string} [$directory]
* @param {bool} [$includeRoot]
*/
public function addNamespace( $namespace, $directory = '', $includeRoot = true ) {
// normalize namespace prefix
$prefix = trim( $namespace, '\\' ) . '\\';
// normalize directory
$base_dir = str_replace( '\\', DIRECTORY_SEPARATOR, $directory );
$base_dir = str_replace( '/', DIRECTORY_SEPARATOR, $base_dir );
$base_dir = rtrim( $base_dir, DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR;
if ( $base_dir === DIRECTORY_SEPARATOR ) {
$base_dir = '';
}
if ( empty( self::$namespaces[ $prefix ] ) ) {
self::$namespaces[ $prefix ] = [];
}
// retain the base directory for the namespace prefix
if ( $includeRoot ) {
$base_dir = $this->rootFolder . $base_dir;
}
array_push( self::$namespaces[ $prefix ], $base_dir );
}
/**
* This is the main method for the autoloader. It will cycle through
* possible locations and load the first available file.
*
* @param {string} [$class]
*/
public function loadClass( $class ) {
$class = trim( $class, '\\' );
$namespace_array = explode( '\\', $class );
$class_name = array_pop( $namespace_array );
$namespace = implode( '\\', $namespace_array ) . '\\';
if ( empty( self::$namespaces[ $namespace ] ) ) {
return false;
}
$file = convertClassNameToFileName( $class_name );
$possible_locations = [];
foreach ( self::$namespaces[ $namespace ] as $key => $folder ) {
if ( file_exists( $folder . $file ) ) {
$possible_locations[] = $folder . $file;
}
}
// foreach ( $possible_locations as $location ) {
// // report the locations
// }
if ( !empty( $possible_locations ) ) {
require_once $possible_locations[0];
}
}
public static function testLoad( $class ) {
$class = trim( $class, '\\' );
$namespace_array = explode( '\\', $class );
$class_name = array_pop( $namespace_array );
$namespace = implode( '\\', $namespace_array ) . '\\';
if ( class_exists( $class ) ) {
return true;
}
if ( empty( self::$namespaces[ $namespace ] ) ) {
return false;
}
$file = convertClassNameToFileName( $class_name );
$possible_locations = [];
foreach ( self::$namespaces[ $namespace ] as $key => $folder ) {
if ( file_exists( $folder . $file ) ) {
$possible_locations[] = $folder . $file;
}
}
if ( !empty( $possible_locations ) ) {
return true;
}
return false;
}
/**
* Sets the root folder for file paths.
*
* @param {string} [$folder]
*/
public function setRootFolder( $folder ) {
$this->rootFolder = rtrim( $folder, DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR;
}
/**
* Registers a new autoloader that should serve the currently defined namespaces.
*/
public function register() {
spl_autoload_register( [ $this, 'loadClass' ] );
}
/**
* Retrieves the currently defined namespaces.
*/
public function getNamespaces() {
return self::$namespaces;
}
/**
* Retrieves the currently defined root folder.
*/
public function getRootFolder() {
return $this->rootFolder;
}
}

View File

@ -1,17 +0,0 @@
<?php
// Directories
if ( !defined( 'HERMES_ROOT_DIRECTORY' ) ) {
define( 'HERMES_ROOT_DIRECTORY', dirname( __DIR__ ) . DIRECTORY_SEPARATOR );
}
if ( ! defined('HERMES_CONFIG_DIRECTORY' ) ) {
define('HERMES_CONFIG_DIRECTORY', HERMES_ROOT_DIRECTORY . 'config' . DIRECTORY_SEPARATOR);
}
if (!defined('HERMES_CLASSES_DIRECTORY')) {
define('HERMES_CLASSES_DIRECTORY', HERMES_ROOT_DIRECTORY . 'classes' . DIRECTORY_SEPARATOR);
}
if (!defined('HERMES_REDIRECTS_ENABLED')) {
define('HERMES_REDIRECTS_ENABLED', true);
}
# Tell the app all constants have been loaded.
define( 'HERMES_CONSTANTS_LOADED', true );

View File

@ -1,64 +0,0 @@
<?php
/**
* functions/redirect.php
*
* This class is used for header modification and page redirection.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/Core
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Hermes\Functions;
class Redirect {
/**
* The main redirect function. This will automatically call the
* error controller if the value passed to it is numerical. It will
* automatically populate the url based on the config and add the
* $data string at the end
*
* @param string|int $data - The desired redirect location (string for location and integer for error page).
*/
public static function to( $data ) {
if ( ! HERMES_REDIRECTS_ENABLED ) {
return;
}
if ( is_numeric( $data ) ) {
header( 'Location: ' . Route::getAddress() . 'Errors/' . $data );
}
$url = Route::getAddress() . $data;
if ( filter_var( $url, FILTER_VALIDATE_URL ) != false ) {
header( 'Location: ' . $url );
}
}
public static function home() {
if ( ! HERMES_REDIRECTS_ENABLED ) {
return;
}
header( 'Location: ' . Route::getAddress() );
}
public static function external( $data ) {
if ( ! HERMES_REDIRECTS_ENABLED ) {
return;
}
$url = filter_var( $data, FILTER_SANITIZE_URL );
if ( filter_var( $url, FILTER_VALIDATE_URL ) != false ) {
header( 'Location: ' . $data );
}
}
/**
* Refreshes the current page.
*
* @return null
*/
public static function reload() {
if ( ! HERMES_REDIRECTS_ENABLED ) {
exit();
}
header( 'Refresh:0' );
}
}

View File

@ -1,104 +0,0 @@
<?php
/**
* functions/routes.php
*
* This class is used to return file and directory locations.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com/Core
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Hermes\Functions;
class Route {
public static function testRouting() {
// $url = Routes::getAddress( true ) . DEFAULT_CONTROLLER_CLASS . '/' . DEFAULT_CONTROLLER_METHOD;
// echo '<pre>' . var_export( $url, true ) . '</pre>';
// $host = gethostbyname( $url );
// echo '<pre>' . var_export( $url, true ) . '</pre>';
// $host = dns_get_record( $url );
// echo '<pre>' . var_export( $url, true ) . '</pre>';
// $headers = @get_headers( $url );
// echo '<pre>' . var_export( $headers, true ) . '</pre>';
// $file = true;
// echo '<pre>' . var_export( $file, true ) . '</pre>';
// exit;
return true;
$headers = get_headers( $url );
if ( empty( $headers ) ) {
return false;
}
$response_code = substr( $headers[0], 9, 3 );
if ( $response_code != '200' ) {
return false;
}
return true;
}
/**
* Determines if the server is using a secure transfer protocol or not.
*
* @return string - The string representation of the server's transfer protocol
*/
public static function getProtocol() {
if ( !empty( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] !== 'off' ) {
return 'https';
}
if ( $_SERVER['SERVER_PORT'] == 443 ) {
return 'https';
}
return 'http';
}
public static function getHost( $internal = false ) {
$host = $_SERVER['HTTP_HOST'];
if ( true === $internal ) {
// if ( 'docker' === getenv( 'APP_ENV' ) ) {
// if ( Check::isNginx() ) {
// $host = 'webone';
// } elseif ( Check::isApache() ) {
// $host = 'webtwo';
// } else {
// $host = '127.0.0.1';
// }
// }
}
return $host;
}
/**
* Finds the root directory of the application.
*
* @return string - The applications root directory.
*/
public static function getRoot() {
$fullArray = explode( '/', $_SERVER['PHP_SELF'] );
array_pop( $fullArray ); // removes the current file name (index.php)
$route = implode( '/', $fullArray ) . '/';
return $route;
}
/**
* finds the physical location of the application
*
* @return string - The root file location for the application.
*/
public static function getAddress( $internal = false ) {
return self::getProtocol() . '://' . self::getHost( $internal ) . self::getRoot();
}
public static function getRequestUrl( $includeParams = true ) {
return self::getProtocol() . '://' . self::getHost() . self::getUri( $includeParams );
}
public static function getUri( $includeParams = true ) {
if ( true === $includeParams ) {
$out = $_SERVER['REQUEST_URI'];
} else {
$explodedSelect = explode( '?', $_SERVER['REQUEST_URI'] );
$out = $explodedSelect[0];
}
return $out;
}
}

View File

@ -1,46 +0,0 @@
# 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/

View File

@ -1,88 +0,0 @@
# 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.

View File

@ -1,18 +0,0 @@
# 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

View File

@ -1,34 +0,0 @@
<?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 );

View File

@ -1,53 +0,0 @@
<?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;
}
}

View File

@ -1,219 +0,0 @@
<?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";
}
}
}
}

View File

@ -1,139 +0,0 @@
<?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;
}
}

View File

@ -1,193 +0,0 @@
<?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;
}
}

View File

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

View File

@ -1,38 +0,0 @@
<?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;
}
}

View File

@ -1,211 +0,0 @@
<?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;
}
}

View File

@ -1,224 +0,0 @@
<?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' );
}
}
}

View File

@ -1,359 +0,0 @@
<?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;
}
}

View File

@ -1,112 +0,0 @@
<?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] );
}
}
}

View File

@ -1,26 +0,0 @@
{
"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"
]
}
}

View File

@ -1,10 +0,0 @@
<?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 );

View File

@ -1,7 +0,0 @@
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>');