Compare commits
64 Commits
3.0.2
...
d7d8fc4b5e
Author | SHA1 | Date | |
---|---|---|---|
d7d8fc4b5e | |||
b1b0da0c08 | |||
3eec88c228 | |||
113499254b | |||
3b6d7f3a2c | |||
09f96c369a | |||
afb9624971 | |||
8d3dee2ac2 | |||
355e509e68 | |||
c3f46cf6c3 | |||
4a521afa88 | |||
0fa83b0ae6 | |||
5c7a320c2a | |||
551f6654f6 | |||
80048ad1dd | |||
80b8226218 | |||
cc9e57888f | |||
ec317e6426 | |||
910c9646b8 | |||
44dcb29060 | |||
431b1214fa | |||
9972f6a654 | |||
b658614ce8 | |||
55a725cd9e | |||
a8b972acf5 | |||
fd8d37d67a | |||
c8eed20814 | |||
b6767ae846 | |||
156f19ee97 | |||
0a9a5a433f | |||
b8c75a128a | |||
e4e72905fc | |||
74e9af4539 | |||
46c0376dfc | |||
90ba704a69 | |||
fb92682eed | |||
54e1a6a817 | |||
9eacdcdc37 | |||
4388a4baa8 | |||
ed43b2f2df | |||
e88c8486a1 | |||
16dbc6c4e2 | |||
14f8f134bc | |||
ea30628ef8 | |||
e1d7c7fcc7 | |||
ee5bcd23fa | |||
b6add64d14 | |||
19e34583d1 | |||
7e296b2468 | |||
e9988d4a14 | |||
4ccbd17607 | |||
7eb1ad9f7d | |||
14bc0c1e64 | |||
4d1e8d6753 | |||
468d48cc00 | |||
778a9882b8 | |||
60985c8c09 | |||
e2d32ab0a0 | |||
136e85dd14 | |||
2fc3338d0f | |||
aba39575fa | |||
508c25c111 | |||
6cf4594622 | |||
0aa1b52a6d |
4
.gitignore
vendored
4
.gitignore
vendored
@ -54,11 +54,11 @@ Temporary Items
|
||||
|
||||
# TheTempusProject Specific
|
||||
.htaccess
|
||||
app/config/*
|
||||
!app/config/constants.php
|
||||
uploads/images/*
|
||||
logs/*
|
||||
.vscode/
|
||||
mail.log
|
||||
vendor/canary/logs/*
|
||||
docker/.env
|
||||
.env
|
||||
components/*
|
||||
|
74
.gitlab-ci.yml
Normal file
74
.gitlab-ci.yml
Normal file
@ -0,0 +1,74 @@
|
||||
stages:
|
||||
- prepare
|
||||
- build
|
||||
- test
|
||||
- update
|
||||
- deploy
|
||||
|
||||
variables:
|
||||
TIMEZONE: "America/New_York" # For the system in general
|
||||
DATE_TIMEZONE: ${TIMEZONE} # For PHP
|
||||
|
||||
GIT_DEPTH: 1
|
||||
GITLAB_API_URL: ${CI_API_V4_URL}
|
||||
TARGET_BRANCH: ${CI_COMMIT_REF_NAME} # This is the branch chosen in the `Pipeline Schedule`
|
||||
TARGET_REMOTE: "https://${GITLAB_USERNAME}:${GITLAB_ACCESS_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}.git"
|
||||
|
||||
# These could/should be overridden in an extending job:
|
||||
UPDATE_BRANCH_PREFIX: "update_PHP_deps_" # Used for the update branch name, it will be followed by the datetime
|
||||
GIT_USER: "DependBot" # Used for the update commit
|
||||
GIT_EMAIL: "webmaster@thetempusproject.com" # Used for the update commit
|
||||
GITLAB_USERNAME: "root" # Used for pushing the new branch and opening the MR
|
||||
GITLAB_ACCESS_TOKEN: "glpat-PKEmivGtBfbz4DVPdhzk" # Used for pushing the new branch and opening the MR
|
||||
MERGE_IF_SUCCESSFUL: "true" # Set to true, to merge automatically if the pipeline succeeds
|
||||
SECONDS_BETWEEN_POOLING: 10 # Nbr of seconds between checking if the MR pipeline is successful, so then it will merge
|
||||
JOB_GIT_FLAGS: ""
|
||||
JOB_CURL_FLAGS: ""
|
||||
JOB_COMPOSER_FLAGS: ""
|
||||
|
||||
composer_update:
|
||||
stage: update
|
||||
rules:
|
||||
- if: '$CI_COMMIT_BRANCH == "main"'
|
||||
image: composer:latest
|
||||
interruptible: true # allows to stop the job if a newer pipeline starts, saving resources and allowing new jobs to start because job concurrency is limited
|
||||
script:
|
||||
- git ${JOB_GIT_FLAGS} fetch origin ${TARGET_BRANCH}
|
||||
- git ${JOB_GIT_FLAGS} checkout ${TARGET_BRANCH}
|
||||
- git reset --hard origin/main
|
||||
- git pull --allow-unrelated-histories
|
||||
- export DATE_TIME="$(date '+%Y%m%d%H%M%S')"
|
||||
- export MR_BRANCH="${UPDATE_BRANCH_PREFIX}${DATE_TIME}"
|
||||
- git ${JOB_GIT_FLAGS} checkout -b "${MR_BRANCH}"
|
||||
- composer update ${JOB_COMPOSER_FLAGS}
|
||||
- if [ "$(git diff)" == "" ]; then echo "No updates needed!"; exit 0; fi
|
||||
- export TITLE="Update PHP dependencies [${DATE_TIME}]"
|
||||
- git ${JOB_GIT_FLAGS} commit -a -m "${TITLE}"
|
||||
- git ${JOB_GIT_FLAGS} push "${TARGET_REMOTE}" "${MR_BRANCH}"
|
||||
artifacts:
|
||||
paths:
|
||||
- vendor/
|
||||
cache:
|
||||
key: ${CI_COMMIT_REF_SLUG}
|
||||
paths:
|
||||
- vendor/
|
||||
|
||||
prepare:
|
||||
stage: prepare
|
||||
script:
|
||||
- echo "Preparing environment..."
|
||||
|
||||
build:
|
||||
stage: build
|
||||
script:
|
||||
- echo "Building the project..."
|
||||
|
||||
test:
|
||||
stage: test
|
||||
script:
|
||||
- echo "Running tests..."
|
||||
|
||||
deploy:
|
||||
stage: deploy
|
||||
script:
|
||||
- echo "Deploying the project..."
|
8
LICENSE
8
LICENSE
@ -1,6 +1,10 @@
|
||||
MIT License
|
||||
Copyright (c) 2024-present Joey Kimsey
|
||||
|
||||
Copyright (c) 2024 Joey Kimsey
|
||||
Portions of this software are licensed as follows:
|
||||
|
||||
* All content residing under the "app/" directory of this repository, excluding "app/plugins/"; is licensed under "Creative Commons: CC BY-SA 4.0 license".
|
||||
* All third party components incorporated into The Tempus Project Software including plugins are licensed under the original license provided by the owner of the applicable component.
|
||||
* Content outside of the above mentioned directories or restrictions above is available under the "MIT Expat" license as defined below.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
50
README.md
50
README.md
@ -1,39 +1,41 @@
|
||||
# The Tempus Project
|
||||
|
||||
|
||||
need to make a vs battle for dnd. someone makes a truly broken character, we take the base character and hand it to two people and give them some time to figure out how they would break it
|
||||
|
||||
need to track points once a week
|
||||
|
||||
a huge table tracks points day to day then we add and erase the old data, or move it to historical...
|
||||
|
||||
## Rapid Prototyping Framework
|
||||
|
||||
## Developer(s): Joey Kimsey
|
||||
### Developer(s): Joey Kimsey
|
||||
|
||||
The aim of this project is to provide a simple and stable platform from which to easily add functionality. The goal being the ability to quickly build and test new projects with a lightweight ecosystem to help.
|
||||
|
||||
**Notice: This code is in _still_ not production ready. This framework is provided as is, use at your own risk.**
|
||||
I am working very hard to ensure the system is safe and reliable enough for me to endorse its widespread use. Unfortunately, it still needs a lot of QA and improvements.
|
||||
|
||||
Currently I am in the process of testing all the systems in preparation for the first production ready release. The beta is still on-going. If you would like to participate or stay up to date with the latest, you can find more information at: https://TheTempusProject.com/beta
|
||||
|
||||
## Features
|
||||
|
||||
- A Plugin system that allows plug-and-play functionality
|
||||
- A User management system
|
||||
- groups
|
||||
- permissions
|
||||
- preferences
|
||||
- registration and recovery
|
||||
(All Controlled dynamically via our plugin interface)
|
||||
- Compatibility with both Apache and NGINX
|
||||
- Built with Bootstrap with a focus on mobile compatibility
|
||||
- Incredibly easy to set-up, deploy, and develop
|
||||
A User management system with groups, permissions, preferences, registration, and recovery. (All Controlled dynamically via our plugin interface)
|
||||
A Plugin system that allows plug-and-play functionality for a huge number of features.
|
||||
Compatibility with both Apache and NGINX.
|
||||
Built with Bootstrap with a focus on mobile compatibility.
|
||||
Incredibly easy to set-up, deploy, and develop with.
|
||||
|
||||
## Installation
|
||||
|
||||
Preferred method for installation is using composer. Special attention has been given to use without composer and more information is included below.
|
||||
Preferred method for installation is using composer.
|
||||
|
||||
### Manually
|
||||
|
||||
### Docker
|
||||
|
||||
### Composer
|
||||
|
||||
The simplest method to start a new project is to use composer to create a new project and automatically clone all the necessary files:
|
||||
|
||||
```
|
||||
composer create-project thetempusproject/thetempusproject test-app
|
||||
```
|
||||
|
||||
1. Clone the directory to wherever you want to install the framework.
|
||||
2. Open your terminal to the directory you previously cloned the repository.
|
||||
3. Install using composer:
|
||||
@ -41,12 +43,6 @@ composer create-project thetempusproject/thetempusproject test-app
|
||||
4. Open your browser and navigate to install.php (it will be in the root directory of your installation)
|
||||
5. When prompted, complete the forms and complete the process.
|
||||
|
||||
|
||||
### Manually
|
||||
|
||||
### Docker
|
||||
|
||||
|
||||
#### Apache
|
||||
|
||||
#### NGINX
|
||||
@ -376,3 +372,9 @@ What is my goal here?
|
||||
|
||||
I would like to play Dungeons and Dragons once a week with my friends. In an ideal world, I would DM this game and spend all week building tools for us to use that I then put on a website which sells memberships to other players so they can use the tools too.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
i need to be able to name models in camel case, this shit is getting crazy. Find whatever prevents this and fix it
|
@ -1,8 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* app/classes/admin_controller.php
|
||||
* app/classes/api_controller.php
|
||||
*
|
||||
* This is the base admin controller. Every other admin controller should
|
||||
* This is the base api controller. Every other api controller should
|
||||
* extend this class.
|
||||
*
|
||||
* @version 3.0
|
||||
|
@ -1,18 +1,18 @@
|
||||
<?php
|
||||
/**
|
||||
* classes/config.php
|
||||
* app/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
|
||||
* @link https://TheTempusProject.com
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Classes;
|
||||
|
||||
use TheTempusProject\Houdini\Classes\Forms;
|
||||
use TheTempusProject\Canary\Canary as Debug;
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Bedrock\Functions\Input;
|
||||
use TheTempusProject\Bedrock\Classes\Config as BedrockConfig;
|
||||
|
@ -13,11 +13,12 @@ namespace TheTempusProject\Classes;
|
||||
|
||||
use TheTempusProject\Bedrock\Classes\Controller as BedrockController;
|
||||
use TheTempusProject\Houdini\Classes\Template;
|
||||
use TheTempusProject\Houdini\Classes\Pagination;
|
||||
use TheTempusProject\Bedrock\Classes\Pagination;
|
||||
use TheTempusProject\TheTempusProject as App;
|
||||
use TheTempusProject\Models\User;
|
||||
use TheTempusProject\Models\Sessions;
|
||||
use TheTempusProject\Bedrock\Functions\Token;
|
||||
use TheTempusProject\Houdini\Classes\Components;
|
||||
|
||||
class Controller extends BedrockController {
|
||||
public static $user;
|
||||
|
@ -13,7 +13,7 @@ namespace TheTempusProject\Classes;
|
||||
|
||||
use TheTempusProject\Bedrock\Classes\DatabaseModel as BedrockDatabaseModel;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Canary\Canary as Debug;
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Models\Log;
|
||||
|
||||
class DatabaseModel extends BedrockDatabaseModel {
|
||||
|
@ -14,7 +14,7 @@ namespace TheTempusProject\Classes;
|
||||
use TheTempusProject\Houdini\Classes\Template;
|
||||
use TheTempusProject\Houdini\Classes\Views;
|
||||
use TheTempusProject\Hermes\Functions\Route as Routes;
|
||||
use TheTempusProject\Canary\Canary as Debug;
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
|
||||
class Email {
|
||||
private static $header = null;
|
||||
|
@ -15,12 +15,20 @@
|
||||
namespace TheTempusProject\Classes;
|
||||
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Canary\Canary as Debug;
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Bedrock\Functions\Input;
|
||||
use TheTempusProject\Models\User;
|
||||
use TheTempusProject\Classes\Forms;
|
||||
use TheTempusProject\Bedrock\Classes\Database;
|
||||
|
||||
class Forms extends Check {
|
||||
private static $formHandlers = [];
|
||||
private static $initialized = false;
|
||||
|
||||
public static function check( $formName ) {
|
||||
if ( self::$initialized !== true ) {
|
||||
self::initHandlers();
|
||||
}
|
||||
if ( empty( self::$formHandlers[ $formName ] ) ) {
|
||||
Debug::error( "Form not found: $formName" );
|
||||
return false;
|
||||
@ -74,4 +82,530 @@ class Forms extends Check {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds these functions to the form list.
|
||||
*/
|
||||
public function __construct() {
|
||||
if ( self::$initialized === true ) {
|
||||
return;
|
||||
}
|
||||
self::initHandlers();
|
||||
}
|
||||
|
||||
private static function initHandlers() {
|
||||
self::addHandler( 'passwordResetCode', __CLASS__, 'passwordResetCode' );
|
||||
self::addHandler( 'createRoute', __CLASS__, 'createRoute' );
|
||||
self::addHandler( 'editRoute', __CLASS__, 'editRoute' );
|
||||
self::addHandler( 'register', __CLASS__, 'register' );
|
||||
self::addHandler( 'createUser', __CLASS__, 'createUser' );
|
||||
self::addHandler( 'editUser', __CLASS__, 'editUser' );
|
||||
self::addHandler( 'login', __CLASS__, 'login' );
|
||||
self::addHandler( 'changeEmail', __CLASS__, 'changeEmail' );
|
||||
self::addHandler( 'changePassword', __CLASS__, 'changePassword' );
|
||||
self::addHandler( 'passwordReset', __CLASS__, 'passwordReset' );
|
||||
self::addHandler( 'emailConfirmation', __CLASS__, 'emailConfirmation' );
|
||||
self::addHandler( 'confirmationResend', __CLASS__, 'confirmationResend' );
|
||||
self::addHandler( 'replyMessage', __CLASS__, 'replyMessage' );
|
||||
self::addHandler( 'newMessage', __CLASS__, 'newMessage' );
|
||||
self::addHandler( 'userPrefs', __CLASS__, 'userPrefs' );
|
||||
self::addHandler( 'newGroup', __CLASS__, 'newGroup' );
|
||||
self::addHandler( 'editGroup', __CLASS__, 'editGroup' );
|
||||
self::addHandler( 'install', __CLASS__, 'install' );
|
||||
self::addHandler( 'installStart', __CLASS__, 'install', [ 'start' ] );
|
||||
self::addHandler( 'installAgreement', __CLASS__, 'install', [ 'agreement' ] );
|
||||
self::addHandler( 'installCheck', __CLASS__, 'install', [ 'check' ] );
|
||||
self::addHandler( 'installConfigure', __CLASS__, 'install', [ 'configure' ] );
|
||||
self::addHandler( 'installRouting', __CLASS__, 'install', [ 'routing' ] );
|
||||
self::addHandler( 'installModels', __CLASS__, 'install', [ 'models' ] );
|
||||
self::addHandler( 'installPlugins', __CLASS__, 'install', [ 'plugins' ] );
|
||||
self::addHandler( 'installResources', __CLASS__, 'install', [ 'resources' ] );
|
||||
self::addHandler( 'installAdminUser', __CLASS__, 'install', [ 'adminUser' ] );
|
||||
self::$initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the installer forms.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function install( $page = '' ) {
|
||||
// if ( !self::token() ) {
|
||||
// return false;
|
||||
// }
|
||||
switch ( $page ) {
|
||||
case 'configure':
|
||||
if ( ! Input::exists( 'submit' ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( !Database::check( Input::post( 'dbHost' ), Input::post( 'dbName' ), Input::post( 'dbUsername' ), Input::post( 'dbPassword' ) ) ) {
|
||||
self::addUserError( 'DB connection error.' );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
case 'adminUser':
|
||||
if ( !self::checkUsername( Input::post( 'newUsername' ) ) ) {
|
||||
self::addUserError( 'Invalid username.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::password( Input::post( 'userPassword' ) ) ) {
|
||||
self::addUserError( 'Invalid password.' );
|
||||
return false;
|
||||
}
|
||||
if ( Input::post( 'userPassword' ) !== Input::post( 'userPassword2' ) ) {
|
||||
self::addUserError( 'Passwords do not match.' );
|
||||
return false;
|
||||
}
|
||||
if ( Input::post( 'userEmail' ) !== Input::post( 'userEmail2' ) ) {
|
||||
self::addUserError( 'Emails do not match.' );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
case 'check':
|
||||
if ( !self::uploads() ) {
|
||||
self::addUserError( 'Uploads are disabled.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::php() ) {
|
||||
self::addUserError( 'PHP version is too old.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::phpExtensions() ) {
|
||||
self::addUserError( 'PHP extensions are missing.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::sessions() ) {
|
||||
self::addUserError( 'There is an error with Sessions.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::mail() ) {
|
||||
self::addUserError( 'PHP mail is not enabled.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::safe() ) {
|
||||
self::addUserError( 'Safe mode is enabled.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'submit' ) ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
case 'start':
|
||||
case 'agreement':
|
||||
case 'routing':
|
||||
case 'models':
|
||||
case 'plugins':
|
||||
case 'resources':
|
||||
if ( ! Input::exists( 'submit' ) ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the password re-send form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function passwordResetCode() {
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the route creation form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function createRoute() {
|
||||
if ( !Input::exists( 'redirect_type' ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( 'external' == Input::post( 'redirect_type' ) && !self::url( Input::post( 'forwarded_url' ) ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the route edit form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function editRoute() {
|
||||
if ( !Input::exists( 'redirect_type' ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( 'external' == Input::post( 'redirect_type' ) && !self::url( Input::post( 'forwarded_url' ) ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the user creation form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function createUser() {
|
||||
$user = new User;
|
||||
if ( !$user->checkUsername( Input::post( 'username' ) ) ) {
|
||||
self::addUserError( 'Invalid username.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::password( Input::post( 'password' ) ) ) {
|
||||
self::addUserError( 'Invalid password.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::email( Input::post( 'email' ) ) ) {
|
||||
self::addUserError( 'Invalid Email.' );
|
||||
return false;
|
||||
}
|
||||
if ( !$user->noEmailExists( Input::post( 'email' ) ) ) {
|
||||
self::addUserError( 'A user with that email is already registered.' );
|
||||
return false;
|
||||
}
|
||||
if ( Input::post( 'password' ) !== Input::post( 'password2' ) ) {
|
||||
self::addUserError( 'Passwords do not match.' );
|
||||
return false;
|
||||
}
|
||||
if ( Input::post( 'email' ) !== Input::post( 'email2' ) ) {
|
||||
self::addUserError( 'Emails do not match.' );
|
||||
return false;
|
||||
}
|
||||
if ( !Input::post( 'groupSelect' ) ) {
|
||||
self::addUserError( 'You must select a group for the new user.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the user edit form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function editUser() {
|
||||
$user = new User;
|
||||
if ( !$user->checkUsername( Input::post( 'username' ) ) ) {
|
||||
self::addUserError( 'Invalid username.' );
|
||||
return false;
|
||||
}
|
||||
if ( Input::exists( 'password' ) ) {
|
||||
if ( !self::password( Input::post( 'password' ) ) ) {
|
||||
self::addUserError( 'Invalid password.' );
|
||||
return false;
|
||||
}
|
||||
if ( Input::post( 'password' ) !== Input::post( 'password2' ) ) {
|
||||
self::addUserError( 'Passwords do not match.' );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ( !self::email( Input::post( 'email' ) ) ) {
|
||||
self::addUserError( 'Invalid Email.' );
|
||||
return false;
|
||||
}
|
||||
if ( !Input::post( 'groupSelect' ) ) {
|
||||
self::addUserError( 'You must select a group for the new user.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the user registration form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function register() {
|
||||
$user = new User;
|
||||
if ( !self::checkUsername( Input::post( 'username' ) ) ) {
|
||||
self::addUserError( 'Invalid username.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::password( Input::post( 'password' ) ) ) {
|
||||
self::addUserError( 'Invalid password.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::email( Input::post( 'email' ) ) ) {
|
||||
self::addUserError( 'Invalid Email.' );
|
||||
return false;
|
||||
}
|
||||
if ( !$user->noEmailExists( Input::post( 'email' ) ) ) {
|
||||
self::addUserError( 'A user with that email is already registered.' );
|
||||
return false;
|
||||
}
|
||||
if ( Input::post( 'password' ) !== Input::post( 'password2' ) ) {
|
||||
self::addUserError( 'Passwords do not match.' );
|
||||
return false;
|
||||
}
|
||||
if ( Input::post( 'email' ) !== Input::post( 'email2' ) ) {
|
||||
self::addUserError( 'Emails do not match.' );
|
||||
return false;
|
||||
}
|
||||
if ( Input::post( 'terms' ) != '1' ) {
|
||||
self::addUserError( 'You must agree to the terms of service.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the user login form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function login() {
|
||||
if ( !self::checkUsername( Input::post( 'username' ) ) ) {
|
||||
self::addUserError( 'Invalid username.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::password( Input::post( 'password' ) ) ) {
|
||||
self::addUserError( 'Invalid password.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the email change form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function changeEmail() {
|
||||
if ( !self::email( Input::post( 'email' ) ) ) {
|
||||
self::addUserError( 'Invalid Email.' );
|
||||
return false;
|
||||
}
|
||||
if ( Input::post( 'email' ) !== Input::post( 'email2' ) ) {
|
||||
self::addUserError( 'Emails do not match.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the password change form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function changePassword() {
|
||||
if ( !self::password( Input::post( 'password' ) ) ) {
|
||||
self::addUserError( 'Invalid password.' );
|
||||
return false;
|
||||
}
|
||||
if ( Input::post( 'password' ) !== Input::post( 'password2' ) ) {
|
||||
self::addUserError( 'Passwords do not match.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the password reset form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function passwordReset() {
|
||||
if ( !self::password( Input::post( 'password' ) ) ) {
|
||||
self::addUserError( 'Invalid password.' );
|
||||
return false;
|
||||
}
|
||||
if ( Input::post( 'password' ) !== Input::post( 'password2' ) ) {
|
||||
self::addUserError( 'Passwords do not match.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the email confirmation re-send form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function emailConfirmation() {
|
||||
if ( !Input::exists( 'confirmationCode' ) ) {
|
||||
self::addUserError( 'No confirmation code provided.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the email confirmation re-send form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function confirmationResend() {
|
||||
if ( !Input::exists( 'resendConfirmation' ) ) {
|
||||
self::addUserError( 'Confirmation not provided.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the reply message form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function replyMessage() {
|
||||
if ( !Input::exists( 'message' ) ) {
|
||||
self::addUserError( 'Reply cannot be empty.' );
|
||||
return false;
|
||||
}
|
||||
if ( !Input::exists( 'messageID' ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the new message form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function newMessage() {
|
||||
if ( !Input::exists( 'toUser' ) ) {
|
||||
self::addUserError( 'You must specify a user to send the message to.' );
|
||||
return false;
|
||||
}
|
||||
if ( !Input::exists( 'subject' ) ) {
|
||||
self::addUserError( 'You must have a subject for your message.' );
|
||||
return false;
|
||||
}
|
||||
if ( !Input::exists( 'message' ) ) {
|
||||
self::addUserError( 'No message entered.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the user preferences form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function userPrefs() {
|
||||
// @todo make this a real check
|
||||
if ( !Input::exists( 'timeFormat' ) ) {
|
||||
self::addUserError( 'You must specify timeFormat' );
|
||||
return false;
|
||||
}
|
||||
if ( !Input::exists( 'pageLimit' ) ) {
|
||||
self::addUserError( 'You must specify pageLimit' );
|
||||
return false;
|
||||
}
|
||||
if ( !Input::exists( 'gender' ) ) {
|
||||
self::addUserError( 'You must specify gender' );
|
||||
return false;
|
||||
}
|
||||
if ( !Input::exists( 'dateFormat' ) ) {
|
||||
self::addUserError( 'You must specify dateFormat' );
|
||||
return false;
|
||||
}
|
||||
if ( !Input::exists( 'timezone' ) ) {
|
||||
self::addUserError( 'You must specify timezone' );
|
||||
return false;
|
||||
}
|
||||
if ( !Input::exists( 'updates' ) ) {
|
||||
self::addUserError( 'You must specify updates' );
|
||||
return false;
|
||||
}
|
||||
if ( !Input::exists( 'newsletter' ) ) {
|
||||
self::addUserError( 'You must specify newsletter' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the group creation form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function newGroup() {
|
||||
if ( !Input::exists( 'name' ) ) {
|
||||
self::addUserError( 'You must specify a name' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::dataTitle( Input::exists( 'name' ) ) ) {
|
||||
self::addUserError( 'invalid group name' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the group edit form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function editGroup() {
|
||||
if ( !Input::exists( 'name' ) ) {
|
||||
self::addUserError( 'You must specify a name' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::dataTitle( Input::exists( 'name' ) ) ) {
|
||||
self::addUserError( 'invalid group name' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ namespace TheTempusProject\Classes;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Bedrock\Functions\Code;
|
||||
use TheTempusProject\Bedrock\Functions\Cookie;
|
||||
use TheTempusProject\Canary\Canary as Debug;
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Hermes\Functions\Redirect;
|
||||
use TheTempusProject\Hermes\Functions\Route as Routes;
|
||||
use TheTempusProject\Bedrock\Functions\Session;
|
||||
@ -266,6 +266,7 @@ class Installer {
|
||||
}
|
||||
|
||||
public function getModelInfo( $filename, $folder = '' ) {
|
||||
Debug::debug( 'getModelInfo filename: ' . $filename . ', folder: ' . $folder);
|
||||
$object = self::emptyModule( 'model', $folder, $filename );
|
||||
|
||||
if ( ! class_exists( $object->class ) ) {
|
||||
@ -326,7 +327,7 @@ class Installer {
|
||||
}
|
||||
|
||||
if ( empty( $module_data->class_object ) ) {
|
||||
self::$errors[] = [ 'errorInfo' => 'Class not found: ' . $module_data->class ];
|
||||
self::$errors[] = [ 'errorInfo' => 'installPlugin: class_object not found: ' . $module_data->class ];
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -363,7 +364,7 @@ class Installer {
|
||||
return false;
|
||||
}
|
||||
|
||||
$errors[] = [ 'errorInfo' => $module_data['name'] . " has been installed." ];
|
||||
$errors[] = [ 'errorInfo' => $module_data['name'] . " Plugin has been installed." ];
|
||||
self::$errors = array_merge( self::$errors, $errors );
|
||||
return true;
|
||||
}
|
||||
@ -373,7 +374,7 @@ class Installer {
|
||||
$errors = [];
|
||||
|
||||
if ( empty( $module_data->class_object ) ) {
|
||||
self::$errors[] = [ 'errorInfo' => 'Class not found: ' . $module_data->class ];
|
||||
self::$errors[] = [ 'errorInfo' => 'uninstallPlugin: class_object not found: ' . $module_data->class ];
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -393,7 +394,7 @@ class Installer {
|
||||
}
|
||||
|
||||
$this->removeModule( $module_data->name, true );
|
||||
$errors[] = [ 'errorInfo' => $module_data->name . " has been installed." ];
|
||||
$errors[] = [ 'errorInfo' => $module_data->name . " Plugin has been uninstalled." ];
|
||||
self::$errors = array_merge( self::$errors, $errors );
|
||||
return true;
|
||||
}
|
||||
@ -408,7 +409,7 @@ class Installer {
|
||||
}
|
||||
|
||||
if ( empty( $module_data->class_object ) ) {
|
||||
self::$errors[] = [ 'errorInfo' => 'Class not found: ' . $module_data->class ];
|
||||
self::$errors[] = [ 'errorInfo' => 'installModel class_object not found: ' . $module_data->class ];
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -465,7 +466,7 @@ class Installer {
|
||||
return false;
|
||||
}
|
||||
|
||||
$errors[] = [ 'errorInfo' => $module_data['name'] . " has been installed." ];
|
||||
$errors[] = [ 'errorInfo' => $module_data['name'] . " model has been installed." ];
|
||||
self::$errors = array_merge( self::$errors, $errors );
|
||||
return true;
|
||||
}
|
||||
@ -475,7 +476,7 @@ class Installer {
|
||||
$errors = [];
|
||||
|
||||
if ( empty( $module_data->class_object ) ) {
|
||||
self::$errors[] = [ 'errorInfo' => 'Class not found: ' . $module_data->class ];
|
||||
self::$errors[] = [ 'errorInfo' => 'uninstallModel: class_object not found: ' . $module_data->class ];
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -499,7 +500,7 @@ class Installer {
|
||||
|
||||
// exclude any flags we don't have a matric map for
|
||||
if ( empty( $module_data->class_object->$matrix ) ) {
|
||||
Debug::warn( "$flag_type does not have a proper matrix map and cannot be installed." );
|
||||
Debug::warn( "$flag_type does not have a proper matrix map and cannot be uninstalled." );
|
||||
$module_data->$flag_type = INSTALL_STATUS_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
@ -512,7 +513,7 @@ class Installer {
|
||||
return false;
|
||||
}
|
||||
|
||||
$errors[] = [ 'errorInfo' => $module_data->name . " has been uninstalled." ];
|
||||
$errors[] = [ 'errorInfo' => $module_data->name . " model has been uninstalled." ];
|
||||
self::$errors = array_merge( self::$errors, $errors );
|
||||
return true;
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
*/
|
||||
namespace TheTempusProject\Classes;
|
||||
|
||||
use TheTempusProject\Canary\Canary as Debug;
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Houdini\Classes\Forms;
|
||||
use TheTempusProject\Bedrock\Functions\Input;
|
||||
|
@ -14,7 +14,7 @@ namespace TheTempusProject\Classes;
|
||||
use TheTempusProject\Houdini\Classes\Navigation;
|
||||
use TheTempusProject\Houdini\Classes\Filters;
|
||||
use TheTempusProject\TheTempusProject as App;
|
||||
use TheTempusProject\Canary\Canary as Debug;
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Bedrock\Classes\Database;
|
||||
|
||||
class Plugin {
|
||||
|
@ -13,7 +13,7 @@ namespace TheTempusProject\Classes;
|
||||
|
||||
use TheTempusProject\Houdini\Classes\Issues;
|
||||
use TheTempusProject\Houdini\Classes\Forms;
|
||||
use TheTempusProject\Canary\Canary as Debug;
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Bedrock\Functions\Upload;
|
||||
use TheTempusProject\Bedrock\Functions\Input;
|
||||
|
312
app/config/config.json
Normal file
312
app/config/config.json
Normal file
@ -0,0 +1,312 @@
|
||||
{
|
||||
"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": "TableTop Elite"
|
||||
},
|
||||
"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
|
||||
},
|
||||
"loginLimit":
|
||||
{
|
||||
"type": "text",
|
||||
"pretty": "Maximum Login Attempts per hour",
|
||||
"default": 5,
|
||||
"value": "5"
|
||||
}
|
||||
},
|
||||
"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":
|
||||
{
|
||||
"dbMaxQuery":
|
||||
{
|
||||
"type": "text",
|
||||
"pretty": "Maximum results per query",
|
||||
"default": 100,
|
||||
"protected": true,
|
||||
"value": 100
|
||||
},
|
||||
"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": "194.195.208.99"
|
||||
},
|
||||
"dbName":
|
||||
{
|
||||
"type": "text",
|
||||
"pretty": "Database Name",
|
||||
"default": "ttp-example",
|
||||
"protected": true,
|
||||
"value": "tte-com"
|
||||
},
|
||||
"dbPassword":
|
||||
{
|
||||
"type": "text",
|
||||
"pretty": "Database Password",
|
||||
"default": "",
|
||||
"protected": true,
|
||||
"value": "lsVb#$D74816"
|
||||
},
|
||||
"dbPrefix":
|
||||
{
|
||||
"type": "text",
|
||||
"pretty": "Database table Prefix",
|
||||
"default": "TTP_",
|
||||
"protected": true,
|
||||
"value": "TTP_"
|
||||
},
|
||||
"dbUsername":
|
||||
{
|
||||
"type": "text",
|
||||
"pretty": "Database Username",
|
||||
"default": "root",
|
||||
"protected": true,
|
||||
"value": "joeyk"
|
||||
}
|
||||
},
|
||||
"group":
|
||||
{
|
||||
"defaultGroup":
|
||||
{
|
||||
"type": "customSelect",
|
||||
"pretty": "The Default Group for new registrations.",
|
||||
"default": 5,
|
||||
"value": 5
|
||||
}
|
||||
},
|
||||
"logging":
|
||||
{
|
||||
"admin":
|
||||
{
|
||||
"type": "radio",
|
||||
"pretty": "Enable Admin Action Logging.",
|
||||
"default": true,
|
||||
"value": true
|
||||
},
|
||||
"errors":
|
||||
{
|
||||
"type": "radio",
|
||||
"pretty": "Enable Error Logging",
|
||||
"default": true,
|
||||
"value": true
|
||||
},
|
||||
"logins":
|
||||
{
|
||||
"type": "radio",
|
||||
"pretty": "Enable Login Logging",
|
||||
"default": true,
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"bugreports":
|
||||
{
|
||||
"enabled":
|
||||
{
|
||||
"type": "radio",
|
||||
"pretty": "Enable Bug reporting.",
|
||||
"default": true,
|
||||
"value": true
|
||||
},
|
||||
"sendEmail":
|
||||
{
|
||||
"type": "radio",
|
||||
"pretty": "Email the user after submitting.",
|
||||
"default": true,
|
||||
"value": true
|
||||
},
|
||||
"emailTemplate":
|
||||
{
|
||||
"type": "text",
|
||||
"pretty": "Email Template",
|
||||
"default": "BugReportEmail",
|
||||
"value": "BugReportEmail"
|
||||
}
|
||||
},
|
||||
"bugtracker":
|
||||
{
|
||||
"enabled":
|
||||
{
|
||||
"type": "radio",
|
||||
"pretty": "Enable Bug tracking.",
|
||||
"default": true,
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"calendar":
|
||||
{
|
||||
"enabled":
|
||||
{
|
||||
"type": "radio",
|
||||
"pretty": "Enable Calendar.",
|
||||
"default": true,
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"chat":
|
||||
{
|
||||
"enabled":
|
||||
{
|
||||
"type": "radio",
|
||||
"pretty": "Enable Chat.",
|
||||
"default": true,
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"dice":
|
||||
{
|
||||
"enabled":
|
||||
{
|
||||
"type": "radio",
|
||||
"pretty": "Enable dice usage.",
|
||||
"default": true,
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"dnd":
|
||||
{
|
||||
"enabled":
|
||||
{
|
||||
"type": "radio",
|
||||
"pretty": "Enable D&D plugin.",
|
||||
"default": true,
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"feedback":
|
||||
{
|
||||
"enabled":
|
||||
{
|
||||
"type": "radio",
|
||||
"pretty": "Enable User Feedback.",
|
||||
"default": true,
|
||||
"value": true
|
||||
},
|
||||
"sendEmail":
|
||||
{
|
||||
"type": "radio",
|
||||
"pretty": "Email the user after submitting.",
|
||||
"default": false,
|
||||
"value": false
|
||||
},
|
||||
"emailTemplate":
|
||||
{
|
||||
"type": "text",
|
||||
"pretty": "Email Template",
|
||||
"default": "feedbackEmail",
|
||||
"value": "feedbackEmail"
|
||||
}
|
||||
},
|
||||
"initiativeTracker":
|
||||
{
|
||||
"enabled":
|
||||
{
|
||||
"type": "radio",
|
||||
"pretty": "Enable tracker usage.",
|
||||
"default": true,
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"npcGeneration":
|
||||
{
|
||||
"enabled":
|
||||
{
|
||||
"type": "radio",
|
||||
"pretty": "Enable NPC-Generator usage.",
|
||||
"default": true,
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"rng":
|
||||
{
|
||||
"enabled":
|
||||
{
|
||||
"type": "radio",
|
||||
"pretty": "Enable rng usage.",
|
||||
"default": true,
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"tablefinder":
|
||||
{
|
||||
"enabled":
|
||||
{
|
||||
"type": "radio",
|
||||
"pretty": "Enable the table finder.",
|
||||
"default": true,
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"timers":
|
||||
{
|
||||
"enabled":
|
||||
{
|
||||
"type": "radio",
|
||||
"pretty": "Enable timer usage.",
|
||||
"default": true,
|
||||
"value": true
|
||||
}
|
||||
}
|
||||
}
|
1
app/config/config.json.bak
Normal file
1
app/config/config.json.bak
Normal file
@ -0,0 +1 @@
|
||||
{"main":{"logo":{"value":"images\/logo.png"},"name":{"value":"Table-Top Elite"},"loginLimit":{"type":"text","pretty":"Maximum Login Attempts per hour","default":5,"value":5}},"database":{"dbMaxQuery":{"value":100},"dbEnabled":{"value":true},"dbHost":{"value":"194.195.208.99"},"dbName":{"value":"tte-com"},"dbPassword":{"value":"lsVb#$D74816"},"dbPrefix":{"value":"TTP_"},"dbUsername":{"value":"joeyk"}}}
|
@ -1,135 +1,146 @@
|
||||
<?php
|
||||
if ( ! defined( 'APP_SPACE' ) ) {
|
||||
define( 'APP_SPACE', 'TheTempusProject' );
|
||||
}
|
||||
if ( ! defined( 'APP_ROOT_DIRECTORY' ) ) {
|
||||
define( 'APP_ROOT_DIRECTORY', dirname( __DIR__ ) . DIRECTORY_SEPARATOR ); // need to verify
|
||||
}
|
||||
if ( ! defined( 'CONFIG_DIRECTORY' ) ) {
|
||||
define( 'CONFIG_DIRECTORY', APP_ROOT_DIRECTORY . 'app' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR );
|
||||
}
|
||||
define( 'APP_DIRECTORY', APP_ROOT_DIRECTORY . 'app' . DIRECTORY_SEPARATOR );
|
||||
// Directories
|
||||
define( 'APP_DIRECTORY', APP_ROOT_DIRECTORY . 'app' . DIRECTORY_SEPARATOR );
|
||||
define( 'CSS_DIRECTORY', APP_ROOT_DIRECTORY . 'css' . DIRECTORY_SEPARATOR );
|
||||
define( 'IMAGE_DIRECTORY', APP_ROOT_DIRECTORY . 'images' . DIRECTORY_SEPARATOR );
|
||||
define( 'JAVASCRIPT_DIRECTORY', APP_ROOT_DIRECTORY . 'js' . DIRECTORY_SEPARATOR );
|
||||
define( 'HTACCESS_LOCATION', APP_ROOT_DIRECTORY . '.htaccess' );
|
||||
define( 'PLUGIN_DIRECTORY', APP_DIRECTORY . 'plugins' . DIRECTORY_SEPARATOR );
|
||||
define( 'MODEL_DIRECTORY', APP_DIRECTORY . 'models' . DIRECTORY_SEPARATOR );
|
||||
define( 'CONTROLLER_DIRECTORY', APP_DIRECTORY . 'controllers' . DIRECTORY_SEPARATOR );
|
||||
define( 'ADMIN_CONTROLLER_DIRECTORY', CONTROLLER_DIRECTORY. 'admin' . DIRECTORY_SEPARATOR );
|
||||
define( 'API_CONTROLLER_DIRECTORY', CONTROLLER_DIRECTORY. 'api' . DIRECTORY_SEPARATOR );
|
||||
define( 'CSS_DIRECTORY', APP_ROOT_DIRECTORY . 'css' . DIRECTORY_SEPARATOR );
|
||||
define( 'IMAGE_DIRECTORY', APP_ROOT_DIRECTORY . 'images' . DIRECTORY_SEPARATOR );
|
||||
define( 'JAVASCRIPT_DIRECTORY', APP_ROOT_DIRECTORY . 'js' . DIRECTORY_SEPARATOR );
|
||||
define( 'HTACCESS_LOCATION', APP_ROOT_DIRECTORY . '.htaccess' );
|
||||
if ( ! defined( 'CONFIG_DIRECTORY' ) ) {
|
||||
define( 'CONFIG_DIRECTORY', APP_DIRECTORY . 'config' . DIRECTORY_SEPARATOR );
|
||||
}
|
||||
define( 'PLUGIN_DIRECTORY', APP_DIRECTORY . 'plugins' . DIRECTORY_SEPARATOR );
|
||||
define( 'MODEL_DIRECTORY', APP_DIRECTORY . 'models' . DIRECTORY_SEPARATOR );
|
||||
define( 'CONTROLLER_DIRECTORY', APP_DIRECTORY . 'controllers' . DIRECTORY_SEPARATOR );
|
||||
define( 'ADMIN_CONTROLLER_DIRECTORY', CONTROLLER_DIRECTORY. 'admin' . DIRECTORY_SEPARATOR );
|
||||
define( 'API_CONTROLLER_DIRECTORY', CONTROLLER_DIRECTORY. 'api' . DIRECTORY_SEPARATOR );
|
||||
// Files
|
||||
define( 'PERMISSIONS_JSON', CONFIG_DIRECTORY . 'permissions.json' );
|
||||
define( 'PREFERENCES_JSON', CONFIG_DIRECTORY . 'preferences.json' );
|
||||
define( 'INSTALL_JSON_LOCATION', CONFIG_DIRECTORY . 'install.json' );
|
||||
define( 'INSTALLER_LOCATION', APP_ROOT_DIRECTORY . 'install.php' );
|
||||
define( 'PERMISSIONS_JSON', CONFIG_DIRECTORY . 'permissions.json' );
|
||||
define( 'PREFERENCES_JSON', CONFIG_DIRECTORY . 'preferences.json' );
|
||||
define( 'INSTALL_JSON_LOCATION', CONFIG_DIRECTORY . 'install.json' );
|
||||
define( 'INSTALLER_LOCATION', APP_ROOT_DIRECTORY . 'install.php' );
|
||||
// Other
|
||||
define( 'PLUGINS_ENABLED', true );
|
||||
define( 'INSTALL_STATUS_NOT_REQUIRED', 'Not Required' );
|
||||
define( 'INSTALL_STATUS_NOT_FOUND', 'Not Found' );
|
||||
define( 'INSTALL_STATUS_PARTIALLY_INSTALLED', 'Partially Installed' );
|
||||
define( 'INSTALL_STATUS_NOT_INSTALLED', 'Not Installed' );
|
||||
define( 'INSTALL_STATUS_INSTALLED', 'Installed' );
|
||||
define( 'INSTALL_STATUS_UNINSTALLED', 'Uninstalled' );
|
||||
define( 'INSTALL_STATUS_SUCCESS', 'Success' );
|
||||
define( 'INSTALL_STATUS_SKIPPED', 'Skipped' );
|
||||
define( 'INSTALL_STATUS_FAIL', 'Failed' );
|
||||
define( 'MODEL_INSTALL_FLAGS', [ 'installTable', 'installPermissions', 'installConfigs', 'installResources', 'installPreferences' ] );
|
||||
define( 'PLUGIN_INSTALL_FLAGS', [ 'models_installed', 'permissions_installed', 'configs_installed', 'resources_installed', 'preferences_installed' ] );
|
||||
define( 'PLUGINS_ENABLED', true );
|
||||
define( 'INSTALL_STATUS_NOT_REQUIRED', 'Not Required' );
|
||||
define( 'INSTALL_STATUS_NOT_FOUND', 'Not Found' );
|
||||
define( 'INSTALL_STATUS_PARTIALLY_INSTALLED', 'Partially Installed' );
|
||||
define( 'INSTALL_STATUS_NOT_INSTALLED', 'Not Installed' );
|
||||
define( 'INSTALL_STATUS_INSTALLED', 'Installed' );
|
||||
define( 'INSTALL_STATUS_UNINSTALLED', 'Uninstalled' );
|
||||
define( 'INSTALL_STATUS_SUCCESS', 'Success' );
|
||||
define( 'INSTALL_STATUS_SKIPPED', 'Skipped' );
|
||||
define( 'INSTALL_STATUS_FAIL', 'Failed' );
|
||||
define( 'MODEL_INSTALL_FLAGS', [ 'installTable', 'installPermissions', 'installConfigs', 'installResources', 'installPreferences' ] );
|
||||
define( 'PLUGIN_INSTALL_FLAGS', [ 'models_installed', 'permissions_installed', 'configs_installed', 'resources_installed', 'preferences_installed' ] );
|
||||
# Tempus Debugger
|
||||
define( 'CANARY_SECURE_HASH', 'd73ed7591a30f0ca7d686a0e780f0d05' );
|
||||
# Tempus Project Core
|
||||
// Check
|
||||
define( 'MINIMUM_PHP_VERSION', 8.1);
|
||||
// Cookies
|
||||
define( 'DEFAULT_COOKIE_PREFIX', 'TP_');
|
||||
// Debug
|
||||
// Check
|
||||
define( 'MINIMUM_PHP_VERSION', 8.1);
|
||||
// Cookies
|
||||
define( 'DEFAULT_COOKIE_PREFIX', 'TP_');
|
||||
// Debug
|
||||
|
||||
define( 'CANARY_DEBUG_DIRECTORY', APP_ROOT_DIRECTORY . 'logs' . DIRECTORY_SEPARATOR );
|
||||
define( 'CANARY_DEBUG_LEVEL_ERROR', 'error' );
|
||||
define( 'CANARY_DEBUG_LEVEL_WARN', 'warn' );
|
||||
define( 'CANARY_DEBUG_LEVEL_INFO', 'info' );
|
||||
define( 'CANARY_DEBUG_LEVEL_LOG', 'log' );
|
||||
define( 'CANARY_DEBUG_LEVEL_DEBUG', 'debug' );
|
||||
define( 'CANARY_DEBUG_TO_FILE_LEVEL', CANARY_DEBUG_LEVEL_INFO );
|
||||
define( 'CANARY_ENABLED', true );
|
||||
define( 'DEBUG_EMAIL', 'webmaster@' . $_SERVER['HTTP_HOST'] );
|
||||
define( 'HERMES_REDIRECTS_ENABLED', true );
|
||||
define( 'RENDERING_ENABLED', true );
|
||||
define( 'CANARY_TRACE_ENABLED', false );
|
||||
define( 'CANARY_DEBUG_TO_CONSOLE', false );
|
||||
define( 'CANARY_DEBUG_TO_FILE', true );
|
||||
// Directories
|
||||
define( 'VENDOR_DIRECTORY', APP_ROOT_DIRECTORY . 'vendor' . DIRECTORY_SEPARATOR );
|
||||
if ( is_dir( VENDOR_DIRECTORY . 'thetempusproject' )) {
|
||||
define( 'TP_VENDOR_DIRECTORY', VENDOR_DIRECTORY . 'thetempusproject' . DIRECTORY_SEPARATOR );
|
||||
} elseif ( is_dir( VENDOR_DIRECTORY . 'TheTempusProject' )) {
|
||||
define( 'TP_VENDOR_DIRECTORY', VENDOR_DIRECTORY . 'TheTempusProject' . DIRECTORY_SEPARATOR );
|
||||
} else {
|
||||
define( 'TP_VENDOR_DIRECTORY', VENDOR_DIRECTORY);
|
||||
}
|
||||
# Bedrock
|
||||
if ( is_dir( TP_VENDOR_DIRECTORY . 'tempusprojectcore' )) {
|
||||
define( 'BEDROCK_ROOT_DIRECTORY', TP_VENDOR_DIRECTORY . 'tempusprojectcore' . DIRECTORY_SEPARATOR );
|
||||
} elseif ( is_dir( TP_VENDOR_DIRECTORY . 'TempusProjectCore' )) {
|
||||
define( 'BEDROCK_ROOT_DIRECTORY', TP_VENDOR_DIRECTORY . 'TempusProjectCore' . DIRECTORY_SEPARATOR );
|
||||
} elseif ( is_dir( TP_VENDOR_DIRECTORY . 'bedrock' )) {
|
||||
define( 'BEDROCK_ROOT_DIRECTORY', TP_VENDOR_DIRECTORY . 'bedrock' . DIRECTORY_SEPARATOR );
|
||||
} elseif ( is_dir( TP_VENDOR_DIRECTORY . 'Bedrock' )) {
|
||||
define( 'BEDROCK_ROOT_DIRECTORY', TP_VENDOR_DIRECTORY . 'Bedrock' . DIRECTORY_SEPARATOR );
|
||||
}
|
||||
if ( is_dir( BEDROCK_ROOT_DIRECTORY . 'config' )) {
|
||||
define( 'BEDROCK_CONFIG_DIRECTORY', BEDROCK_ROOT_DIRECTORY . 'config' . DIRECTORY_SEPARATOR );
|
||||
}
|
||||
# Canary
|
||||
if ( is_dir( TP_VENDOR_DIRECTORY . 'tempusdebugger' )) {
|
||||
define( 'CANARY_ROOT_DIRECTORY', TP_VENDOR_DIRECTORY . 'tempusdebugger' . DIRECTORY_SEPARATOR );
|
||||
} elseif ( is_dir( TP_VENDOR_DIRECTORY . 'TempusDebugger' )) {
|
||||
define( 'CANARY_ROOT_DIRECTORY', TP_VENDOR_DIRECTORY . 'TempusDebugger' . DIRECTORY_SEPARATOR );
|
||||
} elseif ( is_dir( TP_VENDOR_DIRECTORY . 'canary' )) {
|
||||
define( 'CANARY_ROOT_DIRECTORY', TP_VENDOR_DIRECTORY . 'canary' . DIRECTORY_SEPARATOR );
|
||||
} elseif ( is_dir( TP_VENDOR_DIRECTORY . 'Canary' )) {
|
||||
define( 'CANARY_ROOT_DIRECTORY', TP_VENDOR_DIRECTORY . 'Canary' . DIRECTORY_SEPARATOR );
|
||||
}
|
||||
if ( is_dir( CANARY_ROOT_DIRECTORY . 'config' )) {
|
||||
define( 'CANARY_CONFIG_DIRECTORY', CANARY_ROOT_DIRECTORY . 'config' . DIRECTORY_SEPARATOR );
|
||||
}
|
||||
# Hermes
|
||||
if ( is_dir( TP_VENDOR_DIRECTORY . 'hermes' )) {
|
||||
define( 'HERMES_ROOT_DIRECTORY', TP_VENDOR_DIRECTORY . 'hermes' . DIRECTORY_SEPARATOR );
|
||||
} elseif ( is_dir( TP_VENDOR_DIRECTORY . 'Hermes' )) {
|
||||
define( 'HERMES_ROOT_DIRECTORY', TP_VENDOR_DIRECTORY . 'Hermes' . DIRECTORY_SEPARATOR );
|
||||
}
|
||||
if ( is_dir( HERMES_ROOT_DIRECTORY . 'config' )) {
|
||||
define( 'HERMES_CONFIG_DIRECTORY', HERMES_ROOT_DIRECTORY . 'config' . DIRECTORY_SEPARATOR );
|
||||
}
|
||||
# Houdini
|
||||
if ( is_dir( TP_VENDOR_DIRECTORY . 'houdini' )) {
|
||||
define( 'HOUDINI_ROOT_DIRECTORY', TP_VENDOR_DIRECTORY . 'houdini' . DIRECTORY_SEPARATOR );
|
||||
} elseif ( is_dir( TP_VENDOR_DIRECTORY . 'Houdini' )) {
|
||||
define( 'HOUDINI_ROOT_DIRECTORY', TP_VENDOR_DIRECTORY . 'Houdini' . DIRECTORY_SEPARATOR );
|
||||
}
|
||||
if ( is_dir( HOUDINI_ROOT_DIRECTORY . 'config' )) {
|
||||
define( 'HOUDINI_CONFIG_DIRECTORY', HOUDINI_ROOT_DIRECTORY . 'config' . DIRECTORY_SEPARATOR );
|
||||
}
|
||||
// Shared Directories
|
||||
define( 'BIN_DIRECTORY', APP_ROOT_DIRECTORY . 'bin' . DIRECTORY_SEPARATOR );
|
||||
define( 'VIEW_DIRECTORY', APP_DIRECTORY . 'views' . DIRECTORY_SEPARATOR );
|
||||
define( 'ERRORS_DIRECTORY', VIEW_DIRECTORY . 'errors' . DIRECTORY_SEPARATOR );
|
||||
define( 'CLASSES_DIRECTORY', APP_DIRECTORY . 'classes' . DIRECTORY_SEPARATOR );
|
||||
define( 'FUNCTIONS_DIRECTORY', APP_DIRECTORY . 'functions' . DIRECTORY_SEPARATOR );
|
||||
define( 'RESOURCES_DIRECTORY', APP_DIRECTORY . 'resources' . DIRECTORY_SEPARATOR );
|
||||
define( 'TEMPLATE_DIRECTORY', APP_DIRECTORY . 'templates' . DIRECTORY_SEPARATOR );
|
||||
define( 'UPLOAD_DIRECTORY', APP_ROOT_DIRECTORY . 'uploads' . DIRECTORY_SEPARATOR );
|
||||
define( 'IMAGE_UPLOAD_DIRECTORY', UPLOAD_DIRECTORY . 'images' . DIRECTORY_SEPARATOR );
|
||||
// Files
|
||||
define( 'COMPOSER_JSON_LOCATION', APP_ROOT_DIRECTORY . 'composer.json' );
|
||||
define( 'COMPOSER_LOCK_LOCATION', APP_ROOT_DIRECTORY . 'composer.lock' );
|
||||
define( 'CONFIG_JSON', CONFIG_DIRECTORY . 'config.json' );
|
||||
// Other
|
||||
define( 'EMAIL_FROM_EMAIL', 'noreply@localohost.com' );
|
||||
// Sessions
|
||||
define( 'DEFAULT_SESSION_PREFIX', 'TP_' );
|
||||
// Token
|
||||
define( 'DEFAULT_TOKEN_NAME', 'TP_SESSION_TOKEN' );
|
||||
define( 'CANARY_ENABLED', true );
|
||||
define( 'DEBUG_EMAIL', 'webmaster@' . $_SERVER['HTTP_HOST'] );
|
||||
define( 'HERMES_REDIRECTS_ENABLED', true );
|
||||
define( 'RENDERING_ENABLED', true );
|
||||
define( 'CANARY_TRACE_ENABLED', false );
|
||||
define( 'CANARY_DEBUG_TO_CONSOLE', false );
|
||||
define( 'CANARY_DEBUG_TO_FILE', true );
|
||||
// Directories
|
||||
if ( ! defined( 'VENDOR_DIRECTORY' ) ) {
|
||||
define( 'VENDOR_DIRECTORY', APP_ROOT_DIRECTORY . 'vendor' . DIRECTORY_SEPARATOR );
|
||||
}
|
||||
if ( is_dir( VENDOR_DIRECTORY . 'thetempusproject' )) {
|
||||
define( 'TP_VENDOR_DIRECTORY', VENDOR_DIRECTORY . 'thetempusproject' . DIRECTORY_SEPARATOR );
|
||||
} elseif ( is_dir( VENDOR_DIRECTORY . 'TheTempusProject' )) {
|
||||
define( 'TP_VENDOR_DIRECTORY', VENDOR_DIRECTORY . 'TheTempusProject' . DIRECTORY_SEPARATOR );
|
||||
} else {
|
||||
define( 'TP_VENDOR_DIRECTORY', VENDOR_DIRECTORY);
|
||||
}
|
||||
# Bedrock
|
||||
if ( is_dir( TP_VENDOR_DIRECTORY . 'tempusprojectcore' )) {
|
||||
define( 'BEDROCK_ROOT_DIRECTORY', TP_VENDOR_DIRECTORY . 'tempusprojectcore' . DIRECTORY_SEPARATOR );
|
||||
} elseif ( is_dir( TP_VENDOR_DIRECTORY . 'TempusProjectCore' )) {
|
||||
define( 'BEDROCK_ROOT_DIRECTORY', TP_VENDOR_DIRECTORY . 'TempusProjectCore' . DIRECTORY_SEPARATOR );
|
||||
} elseif ( is_dir( TP_VENDOR_DIRECTORY . 'bedrock' )) {
|
||||
define( 'BEDROCK_ROOT_DIRECTORY', TP_VENDOR_DIRECTORY . 'bedrock' . DIRECTORY_SEPARATOR );
|
||||
} elseif ( is_dir( TP_VENDOR_DIRECTORY . 'Bedrock' )) {
|
||||
define( 'BEDROCK_ROOT_DIRECTORY', TP_VENDOR_DIRECTORY . 'Bedrock' . DIRECTORY_SEPARATOR );
|
||||
}
|
||||
if ( is_dir( BEDROCK_ROOT_DIRECTORY . 'config' )) {
|
||||
define( 'BEDROCK_CONFIG_DIRECTORY', BEDROCK_ROOT_DIRECTORY . 'config' . DIRECTORY_SEPARATOR );
|
||||
}
|
||||
# Canary
|
||||
if ( is_dir( TP_VENDOR_DIRECTORY . 'tempusdebugger' )) {
|
||||
define( 'CANARY_ROOT_DIRECTORY', TP_VENDOR_DIRECTORY . 'tempusdebugger' . DIRECTORY_SEPARATOR );
|
||||
} elseif ( is_dir( TP_VENDOR_DIRECTORY . 'TempusDebugger' )) {
|
||||
define( 'CANARY_ROOT_DIRECTORY', TP_VENDOR_DIRECTORY . 'TempusDebugger' . DIRECTORY_SEPARATOR );
|
||||
} elseif ( is_dir( TP_VENDOR_DIRECTORY . 'canary' )) {
|
||||
define( 'CANARY_ROOT_DIRECTORY', TP_VENDOR_DIRECTORY . 'canary' . DIRECTORY_SEPARATOR );
|
||||
} elseif ( is_dir( TP_VENDOR_DIRECTORY . 'Canary' )) {
|
||||
define( 'CANARY_ROOT_DIRECTORY', TP_VENDOR_DIRECTORY . 'Canary' . DIRECTORY_SEPARATOR );
|
||||
}
|
||||
if ( is_dir( CANARY_ROOT_DIRECTORY . 'config' )) {
|
||||
define( 'CANARY_CONFIG_DIRECTORY', CANARY_ROOT_DIRECTORY . 'config' . DIRECTORY_SEPARATOR );
|
||||
}
|
||||
# Hermes
|
||||
if ( is_dir( TP_VENDOR_DIRECTORY . 'hermes' )) {
|
||||
define( 'HERMES_ROOT_DIRECTORY', TP_VENDOR_DIRECTORY . 'hermes' . DIRECTORY_SEPARATOR );
|
||||
} elseif ( is_dir( TP_VENDOR_DIRECTORY . 'Hermes' )) {
|
||||
define( 'HERMES_ROOT_DIRECTORY', TP_VENDOR_DIRECTORY . 'Hermes' . DIRECTORY_SEPARATOR );
|
||||
}
|
||||
if ( is_dir( HERMES_ROOT_DIRECTORY . 'config' )) {
|
||||
define( 'HERMES_CONFIG_DIRECTORY', HERMES_ROOT_DIRECTORY . 'config' . DIRECTORY_SEPARATOR );
|
||||
}
|
||||
# Houdini
|
||||
if ( is_dir( TP_VENDOR_DIRECTORY . 'houdini' )) {
|
||||
define( 'HOUDINI_ROOT_DIRECTORY', TP_VENDOR_DIRECTORY . 'houdini' . DIRECTORY_SEPARATOR );
|
||||
} elseif ( is_dir( TP_VENDOR_DIRECTORY . 'Houdini' )) {
|
||||
define( 'HOUDINI_ROOT_DIRECTORY', TP_VENDOR_DIRECTORY . 'Houdini' . DIRECTORY_SEPARATOR );
|
||||
}
|
||||
if ( is_dir( HOUDINI_ROOT_DIRECTORY . 'config' )) {
|
||||
define( 'HOUDINI_CONFIG_DIRECTORY', HOUDINI_ROOT_DIRECTORY . 'config' . DIRECTORY_SEPARATOR );
|
||||
}
|
||||
// Shared Directories
|
||||
define( 'BIN_DIRECTORY', APP_ROOT_DIRECTORY . 'bin' . DIRECTORY_SEPARATOR );
|
||||
define( 'VIEW_DIRECTORY', APP_DIRECTORY . 'views' . DIRECTORY_SEPARATOR );
|
||||
define( 'ERRORS_DIRECTORY', VIEW_DIRECTORY . 'errors' . DIRECTORY_SEPARATOR );
|
||||
define( 'CLASSES_DIRECTORY', APP_DIRECTORY . 'classes' . DIRECTORY_SEPARATOR );
|
||||
define( 'FUNCTIONS_DIRECTORY', APP_DIRECTORY . 'functions' . DIRECTORY_SEPARATOR );
|
||||
define( 'RESOURCES_DIRECTORY', APP_DIRECTORY . 'resources' . DIRECTORY_SEPARATOR );
|
||||
define( 'TEMPLATE_DIRECTORY', APP_DIRECTORY . 'templates' . DIRECTORY_SEPARATOR );
|
||||
define( 'UPLOAD_DIRECTORY', APP_ROOT_DIRECTORY . 'uploads' . DIRECTORY_SEPARATOR );
|
||||
define( 'IMAGE_UPLOAD_DIRECTORY', UPLOAD_DIRECTORY . 'images' . DIRECTORY_SEPARATOR );
|
||||
// Files
|
||||
define( 'COMPOSER_JSON_LOCATION', APP_ROOT_DIRECTORY . 'composer.json' );
|
||||
define( 'COMPOSER_LOCK_LOCATION', APP_ROOT_DIRECTORY . 'composer.lock' );
|
||||
define( 'CONFIG_JSON', CONFIG_DIRECTORY . 'config.json' );
|
||||
// Other
|
||||
define( 'EMAIL_FROM_EMAIL', 'noreply@localohost.com' );
|
||||
// Sessions
|
||||
define( 'DEFAULT_SESSION_PREFIX', 'TP_' );
|
||||
// Token
|
||||
define( 'DEFAULT_TOKEN_NAME', 'TP_SESSION_TOKEN' );
|
||||
|
||||
# Bugsnag
|
||||
define( 'BUGSNAG_API_KEY', '88045bdc058de51139ac1a47dcd5694b' );
|
||||
// define( 'BUGSNAG_API_KEY', 'cb94acd2a46160589b37cbaad0c61047' );
|
||||
|
||||
# Recaptcha
|
||||
|
||||
# Google Analytics
|
||||
|
||||
# Tell the app; all constants have been loaded
|
||||
define( 'TEMPUS_PROJECT_CONSTANTS_LOADED', true );
|
||||
define( 'TEMPUS_PROJECT_CONSTANTS_LOADED', true );
|
||||
|
1
app/config/install.json
Normal file
1
app/config/install.json
Normal file
File diff suppressed because one or more lines are too long
1
app/config/permissions.json
Normal file
1
app/config/permissions.json
Normal file
@ -0,0 +1 @@
|
||||
{"adminAccess":{"pretty":"Access Administrator Areas","default":false},"addRoute":{"pretty":"Add Custom Routes","default":false},"uploadImages":{"pretty":"Upload images (such as avatars)","default":false},"bugReport":{"pretty":"Can Submit Bug Reports","default":false},"bugTrack":{"pretty":"Can Track Bugs","default":false},"useCalendar":{"pretty":"Can use the calendar feature","default":false},"createEvents":{"pretty":"Can add events to calendars","default":false},"chat":{"pretty":"Can use chat","default":false},"modAccess":{"pretty":"Access Moderator Areas","default":false},"dice":{"pretty":"Can use dice","default":true},"canCreateCharacters":{"pretty":"Can use the character creator","default":true},"canCreateClasses":{"pretty":"Can add Classes.","default":true},"canCreateItems":{"pretty":"Can add Items","default":true},"canCreateMonsters":{"pretty":"Can add Monsters","default":true},"canCreateRaces":{"pretty":"Can add Races","default":true},"canCreateSkills":{"pretty":"Can add Skills","default":true},"canCreateSourceBooks":{"pretty":"Can add SourceBooks","default":true},"canCreateSpells":{"pretty":"Can add Spells","default":true},"feedback":{"pretty":"Can Submit Feedback","default":false},"uploadFiles":{"pretty":"Can upload files","default":false},"useInitiativeTracker":{"pretty":"Can use the tracker","default":true},"memberAccess":{"pretty":"Access Member Areas","default":false},"controlMemberships":{"pretty":"User can Access and Control user memberships.","default":false},"sendMessages":{"pretty":"Can send Messages","default":false},"sendNotifications":{"pretty":"Can send notifications","default":false},"suggest":{"pretty":"Can create suggestions","default":false},"redirects":{"pretty":"Can modify redirects","default":false},"useTableFinder":{"pretty":"Can use the table finder","default":true},"timers":{"pretty":"Can use timers","default":true}}
|
1
app/config/permissions.json.bak
Normal file
1
app/config/permissions.json.bak
Normal file
@ -0,0 +1 @@
|
||||
{"adminAccess":{"pretty":"Access Administrator Areas","default":false},"addRoute":{"pretty":"Add Custom Routes","default":false},"uploadImages":{"pretty":"Upload images (such as avatars)","default":false},"bugReport":{"pretty":"Can Submit Bug Reports","default":false},"bugTrack":{"pretty":"Can Track Bugs","default":false},"useCalendar":{"pretty":"Can use the calendar feature","default":false},"createEvents":{"pretty":"Can add events to calendars","default":false},"chat":{"pretty":"Can use chat","default":false},"modAccess":{"pretty":"Access Moderator Areas","default":false},"dice":{"pretty":"Can use dice","default":true},"canCreateCharacters":{"pretty":"Can use the character creator","default":true},"canCreateClasses":{"pretty":"Can add Classes.","default":true},"canCreateItems":{"pretty":"Can add Items","default":true},"canCreateMonsters":{"pretty":"Can add Monsters","default":true},"canCreateRaces":{"pretty":"Can add Races","default":true},"canCreateSkills":{"pretty":"Can add Skills","default":true},"canCreateSourceBooks":{"pretty":"Can add SourceBooks","default":true},"canCreateSpells":{"pretty":"Can add Spells","default":true},"feedback":{"pretty":"Can Submit Feedback","default":false},"uploadFiles":{"pretty":"Can upload files","default":false},"useInitiativeTracker":{"pretty":"Can use the tracker","default":true},"memberAccess":{"pretty":"Access Member Areas","default":false},"controlMemberships":{"pretty":"User can Access and Control user memberships.","default":false},"sendMessages":{"pretty":"Can send Messages","default":false},"sendNotifications":{"pretty":"Can send notifications","default":false},"suggest":{"pretty":"Can create suggestions","default":false},"redirects":{"pretty":"Can modify redirects","default":false},"useTableFinder":{"pretty":"Can use the table finder","default":true},"timers":{"pretty":"Can use timers","default":true}}
|
1
app/config/preferences.json
Normal file
1
app/config/preferences.json
Normal file
@ -0,0 +1 @@
|
||||
{"gender":{"pretty":"Gender","type":"select","default":"unspecified","options":["male","female","other","unspecified"],"avatar":"\/var\/www\/tabletopelite.com\/images\/defaultAvatar.png"},"newsletter":{"pretty":"Receive our Newsletter?","type":"checkbox","default":"true","avatar":"\/var\/www\/tabletopelite.com\/images\/defaultAvatar.png","options":null},"avatar":{"pretty":"Avatar","type":"file","default":"images\/defaultAvatar.png","avatar":"\/var\/www\/tabletopelite.com\/images\/defaultAvatar.png","options":null},"timezone":{"pretty":"Timezone","type":"timezone","default":"America\/New_York","avatar":"\/var\/www\/tabletopelite.com\/images\/defaultAvatar.png","options":null},"dateFormat":{"pretty":"Date Format","type":"select","default":"F j, Y","options":{"1-8-1991":"n-j-Y","8-1-1991":"j-n-Y","01-08-1991":"m-d-Y","08-01-1991":"d-m-Y","January 8, 1991":"F-j-Y","8 January, 1991":"j-F-Y","January 08, 1991":"F-d-Y","08 January, 1991":"d-F-Y","Jan 8, 1991":"M-j-Y","8 Jan 1991":"j-M-Y","Jan 08, 1991":"M-d-Y","08 Jan 1991":"d-M-Y"},"avatar":"\/var\/www\/tabletopelite.com\/images\/defaultAvatar.png"},"timeFormat":{"pretty":"Time Format","type":"select","default":"g:i:s A","options":{"3:33:33 AM":"g:i:s A","03:33:33 AM":"h:i:s A","3:33:33 am":"g:i:s a","03:33:33 am":"h:i:s a","3:33:33 (military)":"G:i:s","03:33:33 (military)":"H:i:s"},"avatar":"\/var\/www\/tabletopelite.com\/images\/defaultAvatar.png"},"pageLimit":{"pretty":"Items Displayed Per Page","type":"select","default":"10","options":["10","15","20","25","50"],"avatar":"\/var\/www\/tabletopelite.com\/images\/defaultAvatar.png"},"calendarPreference":{"pretty":"Default Calendar View","type":"select","default":"byMonth","options":{"Daily":"byDay","Weekly":"byWeek","Monthly":"byMonth","Yearly":"byYear","All Events":"events"},"avatar":"\/var\/www\/tabletopelite.com\/images\/defaultAvatar.png"},"weekStart":{"pretty":"First day of the week for the Calendar","type":"select","default":"sunday","options":{"Sunday":"6","Monday":"7"},"avatar":"\/var\/www\/tabletopelite.com\/images\/defaultAvatar.png"}}
|
1
app/config/preferences.json.bak
Normal file
1
app/config/preferences.json.bak
Normal file
@ -0,0 +1 @@
|
||||
{"gender":{"pretty":"Gender","type":"select","default":"unspecified","options":["male","female","other","unspecified"],"avatar":"\/var\/www\/tabletopelite.com\/images\/defaultAvatar.png"},"newsletter":{"pretty":"Receive our Newsletter?","type":"checkbox","default":"true","avatar":"\/var\/www\/tabletopelite.com\/images\/defaultAvatar.png","options":null},"avatar":{"pretty":"Avatar","type":"file","default":"images\/defaultAvatar.png","avatar":"\/var\/www\/tabletopelite.com\/images\/defaultAvatar.png","options":null},"timezone":{"pretty":"Timezone","type":"timezone","default":"America\/New_York","avatar":"\/var\/www\/tabletopelite.com\/images\/defaultAvatar.png","options":null},"dateFormat":{"pretty":"Date Format","type":"select","default":"F j, Y","options":{"1-8-1991":"n-j-Y","8-1-1991":"j-n-Y","01-08-1991":"m-d-Y","08-01-1991":"d-m-Y","January 8, 1991":"F-j-Y","8 January, 1991":"j-F-Y","January 08, 1991":"F-d-Y","08 January, 1991":"d-F-Y","Jan 8, 1991":"M-j-Y","8 Jan 1991":"j-M-Y","Jan 08, 1991":"M-d-Y","08 Jan 1991":"d-M-Y"},"avatar":"\/var\/www\/tabletopelite.com\/images\/defaultAvatar.png"},"timeFormat":{"pretty":"Time Format","type":"select","default":"g:i:s A","options":{"3:33:33 AM":"g:i:s A","03:33:33 AM":"h:i:s A","3:33:33 am":"g:i:s a","03:33:33 am":"h:i:s a","3:33:33 (military)":"G:i:s","03:33:33 (military)":"H:i:s"},"avatar":"\/var\/www\/tabletopelite.com\/images\/defaultAvatar.png"},"pageLimit":{"pretty":"Items Displayed Per Page","type":"select","default":"10","options":["10","15","20","25","50"],"avatar":"\/var\/www\/tabletopelite.com\/images\/defaultAvatar.png"},"calendarPreference":{"pretty":"Default Calendar View","type":"select","default":"byMonth","options":{"Daily":"byDay","Weekly":"byWeek","Monthly":"byMonth","Yearly":"byYear","All Events":"events"},"avatar":"\/var\/www\/tabletopelite.com\/images\/defaultAvatar.png"},"weekStart":{"pretty":"First day of the week for the Calendar","type":"select","default":"sunday","options":{"Sunday":"6","Monday":"7"},"avatar":"\/var\/www\/tabletopelite.com\/images\/defaultAvatar.png"}}
|
@ -39,7 +39,7 @@ class Admin extends AdminController {
|
||||
}
|
||||
|
||||
public function index() {
|
||||
return Views::view( 'admin.logs.admin_list', self::$log->list( 'admin' ) );
|
||||
return Views::view( 'admin.logs.admin_list', self::$log->listPaginated( 'admin' ) );
|
||||
}
|
||||
|
||||
public function view( $id = null ) {
|
||||
|
@ -59,6 +59,6 @@ class Composer extends AdminController {
|
||||
$out[] = (object) $versionsInstalled[ $name ];
|
||||
}
|
||||
|
||||
Views::view( 'admin.dependencies', $out );
|
||||
Views::view( 'admin.modules.composer.dependencies', $out );
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ class Errors extends AdminController {
|
||||
}
|
||||
|
||||
public function index() {
|
||||
return Views::view( 'admin.logs.error_list', self::$log->list( 'error' ) );
|
||||
return Views::view( 'admin.logs.error_list', self::$log->listPaginated( 'error' ) );
|
||||
}
|
||||
|
||||
public function view( $id = null ) {
|
||||
|
@ -95,7 +95,7 @@ class Groups extends AdminController {
|
||||
}
|
||||
|
||||
public function index( $data = null ) {
|
||||
Views::view( 'admin.groups.list', self::$group->list() );
|
||||
Views::view( 'admin.groups.list', self::$group->listPaginated() );
|
||||
}
|
||||
|
||||
public function listmembers( $data = null ) {
|
||||
|
@ -39,7 +39,7 @@ class Logins extends AdminController {
|
||||
}
|
||||
|
||||
public function index() {
|
||||
return Views::view( 'admin.logs.login_list', self::$log->list( 'login' ) );
|
||||
return Views::view( 'admin.logs.login_list', self::$log->listPaginated( 'login' ) );
|
||||
}
|
||||
|
||||
public function view( $id = null ) {
|
||||
|
@ -26,8 +26,8 @@ class Logs extends AdminController {
|
||||
}
|
||||
|
||||
public function index( $data = null ) {
|
||||
Views::view( 'admin.logs.error_list', self::$log->list( 'error' ) );
|
||||
Views::view( 'admin.logs.admin_list', self::$log->list( 'admin' ) );
|
||||
Views::view( 'admin.logs.login_list', self::$log->list( 'login' ) );
|
||||
Views::view( 'admin.logs.error_list', self::$log->listPaginated( 'error' ) );
|
||||
Views::view( 'admin.logs.admin_list', self::$log->listPaginated( 'admin' ) );
|
||||
Views::view( 'admin.logs.login_list', self::$log->listPaginated( 'login' ) );
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ class Plugins extends AdminController {
|
||||
if ( !Input::exists( 'installHash' ) ) {
|
||||
return Views::view( 'admin.modules.plugins.enable' );
|
||||
}
|
||||
if ( !Plugin::enable( $name ) ) {
|
||||
if ( ! Plugin::enable( $name ) ) {
|
||||
Session::flash( 'error', 'There was an error enabling the plugin.' );
|
||||
} else {
|
||||
Session::flash( 'success', 'Plugin has been enabled.' );
|
||||
|
@ -11,7 +11,7 @@
|
||||
*/
|
||||
namespace TheTempusProject\Controllers\Admin;
|
||||
|
||||
use TheTempusProject\TTPForms;
|
||||
use TheTempusProject\Classes\Forms as TTPForms;
|
||||
use TheTempusProject\Houdini\Classes\Views;
|
||||
use TheTempusProject\Houdini\Classes\Issues;
|
||||
use TheTempusProject\Houdini\Classes\Navigation;
|
||||
@ -88,7 +88,7 @@ class Routes extends AdminController {
|
||||
}
|
||||
|
||||
public function index() {
|
||||
return Views::view( 'admin.routes.list', self::$routes->list() );
|
||||
return Views::view( 'admin.routes.list', self::$routes->listPaginated() );
|
||||
}
|
||||
|
||||
public function view( $id = null ) {
|
||||
|
@ -140,7 +140,7 @@ class Users extends AdminController {
|
||||
}
|
||||
|
||||
public function index() {
|
||||
Views::view( 'admin.users.list', self::$user->userList() );
|
||||
Views::view( 'admin.users.list', self::$user->listPaginated() );
|
||||
}
|
||||
|
||||
public function view( $id = null ) {
|
||||
|
@ -30,7 +30,7 @@ class Users extends ApiController {
|
||||
$response = 'No user found.';
|
||||
} else {
|
||||
$responseType = 'data';
|
||||
$response = $user;
|
||||
$response = $user->ID;
|
||||
}
|
||||
Views::view( 'api.response', ['response' => json_encode( [ $responseType => $response ], true )]);
|
||||
}
|
||||
|
@ -29,6 +29,11 @@ class Home extends Controller {
|
||||
self::$title = '{SITENAME}';
|
||||
self::$pageDescription = 'This is the homepage of your new Tempus Project Installation. Thank you for installing. find more info at https://thetempusproject.com';
|
||||
Views::view( 'index' );
|
||||
|
||||
Template::addHeader( 'Access-Control-Allow-Origin: *');
|
||||
$bugsnag = \Bugsnag\Client::make( BUGSNAG_API_KEY );
|
||||
\Bugsnag\Handler::register($bugsnag);
|
||||
$bugsnag->notifyException(new \RuntimeException("Test error"));
|
||||
}
|
||||
|
||||
public function login() {
|
||||
|
@ -217,7 +217,7 @@ pre {
|
||||
color: #000;
|
||||
background-color: #FFF;
|
||||
}
|
||||
#carousel-example-generic {
|
||||
#carousel-home {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.col-centered {
|
||||
|
@ -1,542 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/functions/forms.php
|
||||
*
|
||||
* This class is used in conjunction with TheTempusProject\Bedrock\Classes\Check
|
||||
* to house complete form verification. You can utilize the error reporting
|
||||
* to easily define exactly what feedback you would like to give.
|
||||
*
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject;
|
||||
|
||||
use TheTempusProject\Bedrock\Functions\Input;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Models\User;
|
||||
use TheTempusProject\Classes\Forms;
|
||||
use TheTempusProject\Bedrock\Classes\Database;
|
||||
|
||||
class TTPForms extends Forms {
|
||||
/**
|
||||
* Adds these functions to the form list.
|
||||
*/
|
||||
public function __construct() {
|
||||
self::addHandler( 'passwordResetCode', __CLASS__, 'passwordResetCode' );
|
||||
self::addHandler( 'createRoute', __CLASS__, 'createRoute' );
|
||||
self::addHandler( 'editRoute', __CLASS__, 'editRoute' );
|
||||
self::addHandler( 'register', __CLASS__, 'register' );
|
||||
self::addHandler( 'createUser', __CLASS__, 'createUser' );
|
||||
self::addHandler( 'editUser', __CLASS__, 'editUser' );
|
||||
self::addHandler( 'login', __CLASS__, 'login' );
|
||||
self::addHandler( 'changeEmail', __CLASS__, 'changeEmail' );
|
||||
self::addHandler( 'changePassword', __CLASS__, 'changePassword' );
|
||||
self::addHandler( 'passwordReset', __CLASS__, 'passwordReset' );
|
||||
self::addHandler( 'emailConfirmation', __CLASS__, 'emailConfirmation' );
|
||||
self::addHandler( 'confirmationResend', __CLASS__, 'confirmationResend' );
|
||||
self::addHandler( 'replyMessage', __CLASS__, 'replyMessage' );
|
||||
self::addHandler( 'newMessage', __CLASS__, 'newMessage' );
|
||||
self::addHandler( 'userPrefs', __CLASS__, 'userPrefs' );
|
||||
self::addHandler( 'newGroup', __CLASS__, 'newGroup' );
|
||||
self::addHandler( 'editGroup', __CLASS__, 'editGroup' );
|
||||
self::addHandler( 'install', __CLASS__, 'install' );
|
||||
self::addHandler( 'installStart', __CLASS__, 'install', [ 'start' ] );
|
||||
self::addHandler( 'installAgreement', __CLASS__, 'install', [ 'agreement' ] );
|
||||
self::addHandler( 'installCheck', __CLASS__, 'install', [ 'check' ] );
|
||||
self::addHandler( 'installConfigure', __CLASS__, 'install', [ 'configure' ] );
|
||||
self::addHandler( 'installRouting', __CLASS__, 'install', [ 'routing' ] );
|
||||
self::addHandler( 'installModels', __CLASS__, 'install', [ 'models' ] );
|
||||
self::addHandler( 'installPlugins', __CLASS__, 'install', [ 'plugins' ] );
|
||||
self::addHandler( 'installResources', __CLASS__, 'install', [ 'resources' ] );
|
||||
self::addHandler( 'installAdminUser', __CLASS__, 'install', [ 'adminUser' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the installer forms.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function install( $page = '' ) {
|
||||
// if ( !self::token() ) {
|
||||
// return false;
|
||||
// }
|
||||
switch ( $page ) {
|
||||
case 'configure':
|
||||
if ( ! Input::exists( 'submit' ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( !Database::check( Input::post( 'dbHost' ), Input::post( 'dbName' ), Input::post( 'dbUsername' ), Input::post( 'dbPassword' ) ) ) {
|
||||
self::addUserError( 'DB connection error.' );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
case 'adminUser':
|
||||
if ( !self::checkUsername( Input::post( 'newUsername' ) ) ) {
|
||||
self::addUserError( 'Invalid username.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::password( Input::post( 'userPassword' ) ) ) {
|
||||
self::addUserError( 'Invalid password.' );
|
||||
return false;
|
||||
}
|
||||
if ( Input::post( 'userPassword' ) !== Input::post( 'userPassword2' ) ) {
|
||||
self::addUserError( 'Passwords do not match.' );
|
||||
return false;
|
||||
}
|
||||
if ( Input::post( 'userEmail' ) !== Input::post( 'userEmail2' ) ) {
|
||||
self::addUserError( 'Emails do not match.' );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
case 'check':
|
||||
if ( !self::uploads() ) {
|
||||
self::addUserError( 'Uploads are disabled.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::php() ) {
|
||||
self::addUserError( 'PHP version is too old.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::phpExtensions() ) {
|
||||
self::addUserError( 'PHP extensions are missing.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::sessions() ) {
|
||||
self::addUserError( 'There is an error with Sessions.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::mail() ) {
|
||||
self::addUserError( 'PHP mail is not enabled.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::safe() ) {
|
||||
self::addUserError( 'Safe mode is enabled.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'submit' ) ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
case 'start':
|
||||
case 'agreement':
|
||||
case 'routing':
|
||||
case 'models':
|
||||
case 'plugins':
|
||||
case 'resources':
|
||||
if ( ! Input::exists( 'submit' ) ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the password re-send form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function passwordResetCode() {
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the route creation form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function createRoute() {
|
||||
if ( !Input::exists( 'redirect_type' ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( 'external' == Input::post( 'redirect_type' ) && !self::url( Input::post( 'forwarded_url' ) ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the route edit form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function editRoute() {
|
||||
if ( !Input::exists( 'redirect_type' ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( 'external' == Input::post( 'redirect_type' ) && !self::url( Input::post( 'forwarded_url' ) ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the user creation form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function createUser() {
|
||||
$user = new User;
|
||||
if ( !$user->checkUsername( Input::post( 'username' ) ) ) {
|
||||
self::addUserError( 'Invalid username.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::password( Input::post( 'password' ) ) ) {
|
||||
self::addUserError( 'Invalid password.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::email( Input::post( 'email' ) ) ) {
|
||||
self::addUserError( 'Invalid Email.' );
|
||||
return false;
|
||||
}
|
||||
if ( !$user->noEmailExists( Input::post( 'email' ) ) ) {
|
||||
self::addUserError( 'A user with that email is already registered.' );
|
||||
return false;
|
||||
}
|
||||
if ( Input::post( 'password' ) !== Input::post( 'password2' ) ) {
|
||||
self::addUserError( 'Passwords do not match.' );
|
||||
return false;
|
||||
}
|
||||
if ( Input::post( 'email' ) !== Input::post( 'email2' ) ) {
|
||||
self::addUserError( 'Emails do not match.' );
|
||||
return false;
|
||||
}
|
||||
if ( !Input::post( 'groupSelect' ) ) {
|
||||
self::addUserError( 'You must select a group for the new user.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the user edit form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function editUser() {
|
||||
$user = new User;
|
||||
if ( !$user->checkUsername( Input::post( 'username' ) ) ) {
|
||||
self::addUserError( 'Invalid username.' );
|
||||
return false;
|
||||
}
|
||||
if ( Input::exists( 'password' ) ) {
|
||||
if ( !self::password( Input::post( 'password' ) ) ) {
|
||||
self::addUserError( 'Invalid password.' );
|
||||
return false;
|
||||
}
|
||||
if ( Input::post( 'password' ) !== Input::post( 'password2' ) ) {
|
||||
self::addUserError( 'Passwords do not match.' );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ( !self::email( Input::post( 'email' ) ) ) {
|
||||
self::addUserError( 'Invalid Email.' );
|
||||
return false;
|
||||
}
|
||||
if ( !Input::post( 'groupSelect' ) ) {
|
||||
self::addUserError( 'You must select a group for the new user.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the user registration form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function register() {
|
||||
$user = new User;
|
||||
if ( !self::checkUsername( Input::post( 'username' ) ) ) {
|
||||
self::addUserError( 'Invalid username.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::password( Input::post( 'password' ) ) ) {
|
||||
self::addUserError( 'Invalid password.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::email( Input::post( 'email' ) ) ) {
|
||||
self::addUserError( 'Invalid Email.' );
|
||||
return false;
|
||||
}
|
||||
if ( !$user->noEmailExists( Input::post( 'email' ) ) ) {
|
||||
self::addUserError( 'A user with that email is already registered.' );
|
||||
return false;
|
||||
}
|
||||
if ( Input::post( 'password' ) !== Input::post( 'password2' ) ) {
|
||||
self::addUserError( 'Passwords do not match.' );
|
||||
return false;
|
||||
}
|
||||
if ( Input::post( 'email' ) !== Input::post( 'email2' ) ) {
|
||||
self::addUserError( 'Emails do not match.' );
|
||||
return false;
|
||||
}
|
||||
if ( Input::post( 'terms' ) != '1' ) {
|
||||
self::addUserError( 'You must agree to the terms of service.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the user login form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function login() {
|
||||
if ( !self::checkUsername( Input::post( 'username' ) ) ) {
|
||||
self::addUserError( 'Invalid username.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::password( Input::post( 'password' ) ) ) {
|
||||
self::addUserError( 'Invalid password.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the email change form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function changeEmail() {
|
||||
if ( !self::email( Input::post( 'email' ) ) ) {
|
||||
self::addUserError( 'Invalid Email.' );
|
||||
return false;
|
||||
}
|
||||
if ( Input::post( 'email' ) !== Input::post( 'email2' ) ) {
|
||||
self::addUserError( 'Emails do not match.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the password change form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function changePassword() {
|
||||
if ( !self::password( Input::post( 'password' ) ) ) {
|
||||
self::addUserError( 'Invalid password.' );
|
||||
return false;
|
||||
}
|
||||
if ( Input::post( 'password' ) !== Input::post( 'password2' ) ) {
|
||||
self::addUserError( 'Passwords do not match.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the password reset form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function passwordReset() {
|
||||
if ( !self::password( Input::post( 'password' ) ) ) {
|
||||
self::addUserError( 'Invalid password.' );
|
||||
return false;
|
||||
}
|
||||
if ( Input::post( 'password' ) !== Input::post( 'password2' ) ) {
|
||||
self::addUserError( 'Passwords do not match.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the email confirmation re-send form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function emailConfirmation() {
|
||||
if ( !Input::exists( 'confirmationCode' ) ) {
|
||||
self::addUserError( 'No confirmation code provided.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the email confirmation re-send form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function confirmationResend() {
|
||||
if ( !Input::exists( 'resendConfirmation' ) ) {
|
||||
self::addUserError( 'Confirmation not provided.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the reply message form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function replyMessage() {
|
||||
if ( !Input::exists( 'message' ) ) {
|
||||
self::addUserError( 'Reply cannot be empty.' );
|
||||
return false;
|
||||
}
|
||||
if ( !Input::exists( 'messageID' ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the new message form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function newMessage() {
|
||||
if ( !Input::exists( 'toUser' ) ) {
|
||||
self::addUserError( 'You must specify a user to send the message to.' );
|
||||
return false;
|
||||
}
|
||||
if ( !Input::exists( 'subject' ) ) {
|
||||
self::addUserError( 'You must have a subject for your message.' );
|
||||
return false;
|
||||
}
|
||||
if ( !Input::exists( 'message' ) ) {
|
||||
self::addUserError( 'No message entered.' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the user preferences form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function userPrefs() {
|
||||
// @todo make this a real check
|
||||
if ( !Input::exists( 'timeFormat' ) ) {
|
||||
self::addUserError( 'You must specify timeFormat' );
|
||||
return false;
|
||||
}
|
||||
if ( !Input::exists( 'pageLimit' ) ) {
|
||||
self::addUserError( 'You must specify pageLimit' );
|
||||
return false;
|
||||
}
|
||||
if ( !Input::exists( 'gender' ) ) {
|
||||
self::addUserError( 'You must specify gender' );
|
||||
return false;
|
||||
}
|
||||
if ( !Input::exists( 'dateFormat' ) ) {
|
||||
self::addUserError( 'You must specify dateFormat' );
|
||||
return false;
|
||||
}
|
||||
if ( !Input::exists( 'timezone' ) ) {
|
||||
self::addUserError( 'You must specify timezone' );
|
||||
return false;
|
||||
}
|
||||
if ( !Input::exists( 'updates' ) ) {
|
||||
self::addUserError( 'You must specify updates' );
|
||||
return false;
|
||||
}
|
||||
if ( !Input::exists( 'newsletter' ) ) {
|
||||
self::addUserError( 'You must specify newsletter' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the group creation form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function newGroup() {
|
||||
if ( !Input::exists( 'name' ) ) {
|
||||
self::addUserError( 'You must specify a name' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::dataTitle( Input::exists( 'name' ) ) ) {
|
||||
self::addUserError( 'invalid group name' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the group edit form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function editGroup() {
|
||||
if ( !Input::exists( 'name' ) ) {
|
||||
self::addUserError( 'You must specify a name' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::dataTitle( Input::exists( 'name' ) ) ) {
|
||||
self::addUserError( 'invalid group name' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::token() ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
new TTPForms;
|
@ -11,101 +11,8 @@
|
||||
/**
|
||||
* Automatically selects/de-selects all check boxes associated with that field
|
||||
**/
|
||||
function checkAll(ele) {
|
||||
var checkboxes = document.getElementsByTagName( 'input' );
|
||||
if (ele.checked) {
|
||||
test = true;
|
||||
} else {
|
||||
test = false;
|
||||
}
|
||||
for ( var i = 0; i < checkboxes.length; i++ ) {
|
||||
if ( checkboxes[i].type == 'checkbox' ) {
|
||||
if ( checkboxes[i].name == ele.value ) {
|
||||
checkboxes[i].checked = test;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function copyAll( ele ) {
|
||||
var eleName = '#' + ele;
|
||||
var text = $( eleName ).text();
|
||||
text = text.replaceAll( "''", "\n" ).trim();
|
||||
text = text.substring( 1, text.length - 1 );
|
||||
navigator.clipboard.writeText( text );
|
||||
console.log( '#' + ele );
|
||||
}
|
||||
|
||||
function insertTag( box, tag ) {
|
||||
var Field = document.getElementById( box );
|
||||
var currentPos = cursorPos( Field );
|
||||
var val = Field.value;
|
||||
var before = val.substring( 0, currentPos );
|
||||
var after = val.substring( currentPos, val.length );
|
||||
Field.value = before + '(' + tag + ')' + after;
|
||||
}
|
||||
import BugsnagPerformance from '//d2wy8f7a9ursnm.cloudfront.net/v1/bugsnag-performance.min.js'
|
||||
|
||||
function cursorPos( el ) {
|
||||
if ( el.selectionStart ) {
|
||||
return el.selectionStart;
|
||||
} else if ( document.selection ) {
|
||||
el.focus();
|
||||
var r = document.selection.createRange();
|
||||
if ( r == null ) {
|
||||
return 0;
|
||||
}
|
||||
var re = el.createTextRange(),
|
||||
rc = re.duplicate();
|
||||
re.moveToBookmark( r.getBookmark() );
|
||||
rc.setEndPoint( 'EndToStart', re );
|
||||
return rc.text.length;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function getRandomInt(min, max) {
|
||||
const minCeiled = Math.ceil(min);
|
||||
const maxFloored = Math.floor(max);
|
||||
return Math.floor(Math.random() * (maxFloored - minCeiled) + minCeiled);
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
$('select').each(function() {
|
||||
var selectedValue = $(this).attr('value');
|
||||
if (selectedValue) {
|
||||
$(this).removeAttr('value');
|
||||
$(this).find('option').each(function() {
|
||||
if ($(this).attr('value') === selectedValue) {
|
||||
$(this).prop('selected', true);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// with the dynamic footer, you need to adjust the content padding to make sure the footer doesn't overlap the content
|
||||
window.onload = function () {
|
||||
function updateFooterPadding() {
|
||||
var footer = document.querySelector('footer');
|
||||
var container = document.querySelector('.container-fluid.top-pad');
|
||||
if ( ! container ) {
|
||||
return;
|
||||
}
|
||||
// footer has no height but its children do!
|
||||
var footerHeight = Array.from(footer.children).reduce((totalHeight, child) => {
|
||||
return totalHeight + child.offsetHeight;
|
||||
}, 0);
|
||||
|
||||
footerHeight += 20; // Add 20px for padding
|
||||
|
||||
// console.error(footerHeight);
|
||||
|
||||
container.style.setProperty('--footer-height', footerHeight + 'px');
|
||||
}
|
||||
|
||||
// Update padding on initial load
|
||||
updateFooterPadding();
|
||||
|
||||
// Update padding on window resize
|
||||
window.addEventListener('resize', updateFooterPadding);
|
||||
};
|
||||
BugsnagPerformance.start({ apiKey: '88045bdc058de51139ac1a47dcd5694b' });
|
||||
|
@ -12,7 +12,7 @@
|
||||
namespace TheTempusProject\Models;
|
||||
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Canary\Canary as Debug;
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Classes\Permissions;
|
||||
use TheTempusProject\Bedrock\Classes\Config;
|
||||
use TheTempusProject\Bedrock\Functions\Input;
|
||||
@ -257,7 +257,7 @@ class Group extends DatabaseModel {
|
||||
if ( $group === false ) {
|
||||
return false;
|
||||
}
|
||||
$members = self::$db->get( 'users', [ 'userGroup', '=', $id ] );
|
||||
$members = self::$db->getPaginated( 'users', [ 'userGroup', '=', $id ] );
|
||||
if ( !$members->count() ) {
|
||||
Debug::info( "list members: Could not find anyone in group: $id" );
|
||||
return false;
|
||||
|
@ -13,10 +13,10 @@ namespace TheTempusProject\Models;
|
||||
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Bedrock\Classes\Config;
|
||||
use TheTempusProject\Bedrock\Classes\CustomException;
|
||||
use TheTempusProject\Canary\Classes\CustomException;
|
||||
use TheTempusProject\TheTempusProject as App;
|
||||
use TheTempusProject\Classes\DatabaseModel;
|
||||
use TheTempusProject\Canary\Canary as Debug;
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
|
||||
class Log extends DatabaseModel {
|
||||
public $tableName = 'logs';
|
||||
|
@ -12,7 +12,7 @@
|
||||
namespace TheTempusProject\Models;
|
||||
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Canary\Canary as Debug;
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Classes\DatabaseModel;
|
||||
|
||||
class Routes extends DatabaseModel {
|
||||
|
@ -16,7 +16,7 @@ namespace TheTempusProject\Models;
|
||||
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Bedrock\Functions\Code;
|
||||
use TheTempusProject\Canary\Canary as Debug;
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Bedrock\Functions\Session;
|
||||
use TheTempusProject\Bedrock\Functions\Cookie;
|
||||
use TheTempusProject\Classes\DatabaseModel;
|
||||
|
@ -16,12 +16,12 @@
|
||||
namespace TheTempusProject\Models;
|
||||
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Canary\Canary as Debug;
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Bedrock\Functions\Hash;
|
||||
use TheTempusProject\Bedrock\Functions\Session;
|
||||
use TheTempusProject\Bedrock\Functions\Code;
|
||||
use TheTempusProject\Bedrock\Classes\Config;
|
||||
use TheTempusProject\Bedrock\Classes\CustomException;
|
||||
use TheTempusProject\Canary\Classes\CustomException;
|
||||
use TheTempusProject\Classes\Email;
|
||||
use TheTempusProject\Classes\DatabaseModel;
|
||||
use TheTempusProject\Classes\Preferences;
|
||||
|
@ -13,7 +13,7 @@
|
||||
namespace TheTempusProject\Controllers;
|
||||
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Canary\Canary as Debug;
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Bedrock\Functions\Input;
|
||||
use TheTempusProject\Houdini\Classes\Components;
|
||||
use TheTempusProject\Houdini\Classes\Issues;
|
||||
|
@ -12,16 +12,19 @@
|
||||
*/
|
||||
namespace TheTempusProject\Models;
|
||||
|
||||
use TheTempusProject\Canary\Canary as Debug;
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Bedrock\Functions\Sanitize;
|
||||
use TheTempusProject\Classes\DatabaseModel;
|
||||
use TheTempusProject\TheTempusProject as App;
|
||||
use TheTempusProject\Bedrock\Classes\CustomException;
|
||||
use TheTempusProject\Canary\Classes\CustomException;
|
||||
use TheTempusProject\Houdini\Classes\Filters;
|
||||
use TheTempusProject\Plugins\Comments as CommentPlugin;
|
||||
use TheTempusProject\Models\Comments;
|
||||
|
||||
class Posts extends DatabaseModel {
|
||||
public $tableName = 'posts';
|
||||
public static $comments = false;
|
||||
|
||||
public $databaseMatrix = [
|
||||
[ 'author', 'int', '11' ],
|
||||
@ -32,19 +35,14 @@ class Posts extends DatabaseModel {
|
||||
[ 'content', 'text', '' ],
|
||||
];
|
||||
|
||||
public $resourceMatrix = [
|
||||
[
|
||||
'title' => 'Welcome',
|
||||
'content' => '<p>This is just a simple message to say thank you for installing The Tempus Project. If you have any questions you can find everything through our website <a href="https://TheTempusProject.com">here</a>.</p>',
|
||||
'author' => 1,
|
||||
'created' => '{time}',
|
||||
'edited' => '{time}',
|
||||
'draft' => 0,
|
||||
],
|
||||
];
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
if ( class_exists( 'TheTempusProject\Plugins\Comments' ) ) {
|
||||
$comments = new CommentPlugin;
|
||||
if ( $comments->checkEnabled() ) {
|
||||
self::$comments = new Comments;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function newPost( $title, $post, $draft ) {
|
||||
@ -161,6 +159,9 @@ class Posts extends DatabaseModel {
|
||||
if ( isset( $params['stripHtml'] ) && $params['stripHtml'] === true ) {
|
||||
$instance->contentSummary = strip_tags( $instance->content );
|
||||
}
|
||||
if ( self::$comments !== false ) {
|
||||
$instance->commentCount = self::$comments->count( 'blog', $instance->ID );
|
||||
}
|
||||
$instance->content = Filters::applyOne( 'mentions.0', $instance->content, true );
|
||||
$instance->content = Filters::applyOne( 'hashtags.0', $instance->content, true );
|
||||
$out[] = $instance;
|
||||
|
@ -38,6 +38,18 @@ class Blog extends Plugin {
|
||||
'url' => '{ROOT_URL}blog/index',
|
||||
],
|
||||
];
|
||||
public $resourceMatrix = [
|
||||
'posts' => [
|
||||
[
|
||||
'title' => 'Welcome',
|
||||
'content' => '<p>This is just a simple message to say thank you for installing The Tempus Project. If you have any questions you can find everything through our website <a href="https://TheTempusProject.com">here</a>.</p>',
|
||||
'author' => 1,
|
||||
'created' => '{time}',
|
||||
'edited' => '{time}',
|
||||
'draft' => 0,
|
||||
],
|
||||
],
|
||||
];
|
||||
public $posts;
|
||||
|
||||
public function __construct( $load = false ) {
|
||||
|
@ -1,402 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/bugreport/controllers/bugreport.php
|
||||
*
|
||||
* This is the bug reports controller.
|
||||
*
|
||||
* @package TP BugReports
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Controllers;
|
||||
|
||||
use TheTempusProject\Hermes\Functions\Redirect;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Bedrock\Functions\Input;
|
||||
use TheTempusProject\Bedrock\Functions\Session;
|
||||
use TheTempusProject\Houdini\Classes\Issues;
|
||||
use TheTempusProject\Houdini\Classes\Views;
|
||||
use TheTempusProject\Classes\Controller;
|
||||
use TheTempusProject\Classes\Forms;
|
||||
use TheTempusProject\Models\Bookmarks as Bookmark;
|
||||
use TheTempusProject\Models\Folders;
|
||||
use TheTempusProject\TheTempusProject as App;
|
||||
use TheTempusProject\Houdini\Classes\Components;
|
||||
use TheTempusProject\Houdini\Classes\Forms as HoudiniForms;
|
||||
use TheTempusProject\Houdini\Classes\Navigation;
|
||||
|
||||
class Bookmarks extends Controller {
|
||||
protected static $bookmarks;
|
||||
protected static $folders;
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
if ( !App::$isLoggedIn ) {
|
||||
Session::flash( 'notice', 'You must be logged in to create or manage bookmarks.' );
|
||||
return Redirect::home();
|
||||
}
|
||||
self::$bookmarks = new Bookmark;
|
||||
self::$folders = new Folders;
|
||||
self::$title = 'Bookmarks - {SITENAME}';
|
||||
self::$pageDescription = 'Add and save url bookmarks here.';
|
||||
|
||||
$folderTabs = Views::simpleView( 'bookmarks.nav.folderTabs' );
|
||||
if ( stripos( Input::get('url'), 'bookmarks/bookmarks' ) !== false ) {
|
||||
$tabsView = Navigation::activePageSelect( $folderTabs, '/bookmarks/folders/', false, true );
|
||||
$userFolderTabs = Views::simpleView('bookmarks.nav.userFolderTabs', self::$folders->simpleObjectByUser(true) );
|
||||
$userFolderTabsView = Navigation::activePageSelect( $userFolderTabs, Input::get( 'url' ), false, true );
|
||||
} else {
|
||||
$tabsView = Navigation::activePageSelect( $folderTabs, Input::get( 'url' ), false, true );
|
||||
$userFolderTabsView = '';
|
||||
}
|
||||
Components::set( 'userFolderTabs', $userFolderTabsView );
|
||||
Views::raw( $tabsView );
|
||||
}
|
||||
|
||||
public function index() {
|
||||
$bookmarks = self::$bookmarks->noFolder();
|
||||
$folders = self::$folders->byUser();
|
||||
|
||||
$panelArray = [];
|
||||
if ( !empty( $folders ) ) {
|
||||
foreach ( $folders as $folder ) {
|
||||
$panel = new \stdClass();
|
||||
$folderObject = new \stdClass();
|
||||
$folderObject->bookmarks = self::$bookmarks->byFolder( $folder->ID );
|
||||
$folderObject->ID = $folder->ID;
|
||||
$folderObject->title = $folder->title;
|
||||
$folderObject->color = $folder->color;
|
||||
$folderObject->bookmarkListRows = Views::simpleView( 'bookmarks.components.bookmarkListRows', $folderObject->bookmarks );
|
||||
$panel->panel = Views::simpleView( 'bookmarks.components.bookmarkListPanel', [$folderObject] );
|
||||
$panelArray[] = $panel;
|
||||
}
|
||||
}
|
||||
Components::set( 'foldersList', Views::simpleView( 'bookmarks.folders.list', $folders ) );
|
||||
Components::set( 'folderPanels', Views::simpleView( 'bookmarks.components.folderPanelList', $panelArray ) );
|
||||
Components::set( 'bookmarksList', Views::simpleView( 'bookmarks.bookmarks.list', $bookmarks ) );
|
||||
return Views::view( 'bookmarks.dash' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Bookmarks
|
||||
*/
|
||||
public function bookmark( $id = 0 ) {
|
||||
$bookmark = self::$bookmarks->findById( $id );
|
||||
if ( $bookmark == false ) {
|
||||
Session::flash( 'error', 'Bookmark not found.' );
|
||||
return Redirect::to( 'bookmarks/index' );
|
||||
}
|
||||
if ( $bookmark->createdBy != App::$activeUser->ID ) {
|
||||
Session::flash( 'error', 'You do not have permission to modify this bookmark.' );
|
||||
return Redirect::to( 'bookmarks/index' );
|
||||
}
|
||||
Navigation::setCrumbComponent( 'BookmarkBreadCrumbs', 'bookmarks/bookmark/' . $id );
|
||||
return Views::view( 'bookmarks.bookmarks.view', $bookmark );
|
||||
}
|
||||
|
||||
public function bookmarks( $id = null ) {
|
||||
$folder = self::$folders->findById( $id );
|
||||
if ( $folder == false ) {
|
||||
Session::flash( 'error', 'Folder not found.' );
|
||||
return Redirect::to( 'bookmarks/index' );
|
||||
}
|
||||
if ( $folder->createdBy != App::$activeUser->ID ) {
|
||||
Session::flash( 'error', 'You do not have permission to view this folder.' );
|
||||
return Redirect::to( 'bookmarks/index' );
|
||||
}
|
||||
Navigation::setCrumbComponent( 'BookmarkBreadCrumbs', 'bookmarks/bookmarks/' . $id );
|
||||
|
||||
|
||||
$bookmarks = self::$bookmarks->noFolder();
|
||||
|
||||
$panelArray = [];
|
||||
$panel = new \stdClass();
|
||||
$folderObject = new \stdClass();
|
||||
$folderObject->bookmarks = self::$bookmarks->byFolder( $folder->ID );
|
||||
$folderObject->ID = $folder->ID;
|
||||
$folderObject->title = $folder->title;
|
||||
$folderObject->color = $folder->color;
|
||||
$folderObject->bookmarkListRows = Views::simpleView( 'bookmarks.components.bookmarkListRows', $folderObject->bookmarks );
|
||||
$panel->panel = Views::simpleView( 'bookmarks.components.bookmarkListPanel', [$folderObject] );
|
||||
$panelArray[] = $panel;
|
||||
|
||||
return Views::view( 'bookmarks.components.folderPanelList', $panelArray );
|
||||
}
|
||||
|
||||
public function createBookmark( $id = null ) {
|
||||
$folderID = Input::get('folder_id') ? Input::get('folder_id') : $id;
|
||||
$folderID = Input::post('folder_id') ? Input::post('folder_id') : $id;
|
||||
$folderSelect = HoudiniForms::getFormFieldHtml( 'folder_id', 'Folder', 'select', $folderID, self::$folders->simpleByUser() );
|
||||
Components::set( 'folderSelect', $folderSelect );
|
||||
|
||||
if ( ! Input::exists() ) {
|
||||
return Views::view( 'bookmarks.bookmarks.create' );
|
||||
}
|
||||
if ( ! Forms::check( 'createBookmark' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error with your form.' => Check::userErrors() ] );
|
||||
return Views::view( 'bookmarks.bookmarks.create' );
|
||||
}
|
||||
|
||||
$result = self::$bookmarks->create(
|
||||
Input::post('title'),
|
||||
Input::post('url'),
|
||||
$folderID,
|
||||
Input::post('description'),
|
||||
Input::post('color'),
|
||||
Input::post('privacy'),
|
||||
);
|
||||
|
||||
if ( ! $result ) {
|
||||
Issues::add( 'error', [ 'There was an error creating your bookmark.' => Check::userErrors() ] );
|
||||
return Views::view( 'bookmarks.bookmarks.create' );
|
||||
}
|
||||
self::$bookmarks->refreshInfo( $result );
|
||||
Session::flash( 'success', 'Your Bookmark has been created.' );
|
||||
Redirect::to( 'bookmarks/bookmarks/'. $folderID );
|
||||
}
|
||||
|
||||
public function editBookmark( $id = null ) {
|
||||
$folderID = Input::exists('folder_id') ? Input::post('folder_id') : '';
|
||||
|
||||
$bookmark = self::$bookmarks->findById( $id );
|
||||
if ( $bookmark == false ) {
|
||||
Issues::add( 'error', 'Bookmark not found.' );
|
||||
return Redirect::to( 'bookmarks/index' );
|
||||
}
|
||||
if ( $bookmark->createdBy != App::$activeUser->ID ) {
|
||||
Issues::add( 'error', 'You do not have permission to modify this bookmark.' );
|
||||
return Redirect::to( 'bookmarks/index' );
|
||||
}
|
||||
if ( empty( $folderID ) ) {
|
||||
$folderID = $bookmark->folderID;
|
||||
}
|
||||
|
||||
$folderSelect = HoudiniForms::getFormFieldHtml( 'folder_id', 'Folder', 'select', $folderID, self::$folders->simpleByUser() );
|
||||
Components::set( 'folderSelect', $folderSelect );
|
||||
Components::set( 'color', $bookmark->color );
|
||||
|
||||
if ( ! Input::exists( 'submit' ) ) {
|
||||
return Views::view( 'bookmarks.bookmarks.edit', $bookmark );
|
||||
}
|
||||
if ( ! Forms::check( 'editBookmark' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error updating your bookmark.' => Check::userErrors() ] );
|
||||
return Views::view( 'bookmarks.bookmarks.edit', $bookmark );
|
||||
}
|
||||
|
||||
$result = self::$bookmarks->update(
|
||||
$id,
|
||||
Input::post('title'),
|
||||
Input::post('url'),
|
||||
$folderID,
|
||||
Input::post('description'),
|
||||
Input::post('color'),
|
||||
Input::post('privacy'),
|
||||
);
|
||||
if ( ! $result ) {
|
||||
Issues::add( 'error', [ 'There was an error updating your bookmark.' => Check::userErrors() ] );
|
||||
return Views::view( 'bookmarks.bookmarks.edit', $bookmark );
|
||||
}
|
||||
Session::flash( 'success', 'Your Bookmark has been updated.' );
|
||||
Redirect::to( 'bookmarks/folders/'. $bookmark->folderID );
|
||||
}
|
||||
|
||||
public function deleteBookmark( $id = null ) {
|
||||
$bookmark = self::$bookmarks->findById( $id );
|
||||
if ( $bookmark == false ) {
|
||||
Issues::add( 'error', 'Bookmark not found.' );
|
||||
return $this->index();
|
||||
}
|
||||
if ( $bookmark->createdBy != App::$activeUser->ID ) {
|
||||
Issues::add( 'error', 'You do not have permission to modify this bookmark.' );
|
||||
return $this->index();
|
||||
}
|
||||
$result = self::$bookmarks->delete( $id );
|
||||
if ( !$result ) {
|
||||
Session::flash( 'error', 'There was an error deleting the bookmark(s)' );
|
||||
} else {
|
||||
Session::flash( 'success', 'Bookmark deleted' );
|
||||
}
|
||||
Redirect::to( 'bookmarks/folders/'. $bookmark->folderID );
|
||||
}
|
||||
|
||||
/**
|
||||
* Folders
|
||||
*/
|
||||
public function folders( $id = null) {
|
||||
$folder = self::$folders->findById( $id );
|
||||
if ( $folder == false ) {
|
||||
$folders = self::$folders->byUser();
|
||||
return Views::view( 'bookmarks.folders.list', $folders );
|
||||
}
|
||||
if ( $folder->createdBy != App::$activeUser->ID ) {
|
||||
Session::flash( 'error', 'You do not have permission to view this folder.' );
|
||||
return Redirect::to( 'bookmarks/index' );
|
||||
}
|
||||
Navigation::setCrumbComponent( 'BookmarkBreadCrumbs', 'bookmarks/folders/' . $id );
|
||||
return Views::view( 'bookmarks.folders.view', $folder );
|
||||
}
|
||||
|
||||
public function createFolder( $id = 0 ) {
|
||||
$folderID = Input::exists('folder_id') ? Input::post('folder_id') : $id;
|
||||
$folders = self::$folders->simpleByUser();
|
||||
if ( ! empty( $folders ) ) {
|
||||
$folderSelect = HoudiniForms::getFormFieldHtml( 'folder_id', 'Folder', 'select', $folderID, $folders );
|
||||
} else {
|
||||
$folderSelect = '';
|
||||
}
|
||||
Components::set( 'folderSelect', $folderSelect );
|
||||
if ( ! Input::exists() ) {
|
||||
return Views::view( 'bookmarks.folders.create' );
|
||||
}
|
||||
if ( ! Forms::check( 'createFolder' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error creating your folder.' => Check::userErrors() ] );
|
||||
return Views::view( 'bookmarks.folders.create' );
|
||||
}
|
||||
$folder = self::$folders->create( Input::post('title'), $folderID, Input::post('description'), Input::post('color'), Input::post('privacy') );
|
||||
if ( ! $folder ) {
|
||||
return Views::view( 'bookmarks.folders.create' );
|
||||
}
|
||||
Session::flash( 'success', 'Your Folder has been created.' );
|
||||
Redirect::to( 'bookmarks/folders' );
|
||||
}
|
||||
|
||||
public function editFolder( $id = null ) {
|
||||
$folder = self::$folders->findById( $id );
|
||||
|
||||
if ( $folder == false ) {
|
||||
Issues::add( 'error', 'Folder not found.' );
|
||||
return $this->index();
|
||||
}
|
||||
|
||||
if ( $folder->createdBy != App::$activeUser->ID ) {
|
||||
Issues::add( 'error', 'You do not have permission to modify this folder.' );
|
||||
return $this->index();
|
||||
}
|
||||
$folderID = ( false === Input::exists('folder_id') ) ? $folder->ID : Input::post('folder_id');
|
||||
|
||||
$folderSelect = HoudiniForms::getFormFieldHtml( 'folder_id', 'Folder', 'select', $folderID, self::$folders->simpleByUser() );
|
||||
Components::set( 'folderSelect', $folderSelect );
|
||||
Components::set( 'color', $folder->color );
|
||||
|
||||
if ( ! Input::exists( 'submit' ) ) {
|
||||
return Views::view( 'bookmarks.folders.edit', $folder );
|
||||
}
|
||||
|
||||
if ( !Forms::check( 'editFolder' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error editing your folder.' => Check::userErrors() ] );
|
||||
return Views::view( 'bookmarks.folders.edit', $folder );
|
||||
}
|
||||
|
||||
$result = self::$folders->update( $id, Input::post('title'), $folderID, Input::post('description'), Input::post('color'), Input::post('privacy') );
|
||||
if ( !$result ) {
|
||||
Issues::add( 'error', [ 'There was an error updating your folder.' => Check::userErrors() ] );
|
||||
return Views::view( 'bookmarks.folders.edit', $folder );
|
||||
}
|
||||
Session::flash( 'success', 'Your Folder has been updated.' );
|
||||
Redirect::to( 'bookmarks/folders/'. $folder->ID );
|
||||
}
|
||||
|
||||
public function deleteFolder( $id = null ) {
|
||||
$folder = self::$folders->findById( $id );
|
||||
if ( $folder == false ) {
|
||||
Issues::add( 'error', 'Folder not found.' );
|
||||
return $this->index();
|
||||
}
|
||||
if ( $folder->createdBy != App::$activeUser->ID ) {
|
||||
Issues::add( 'error', 'You do not have permission to modify this folder.' );
|
||||
return $this->index();
|
||||
}
|
||||
$results = self::$bookmarks->deleteByFolder( $id );
|
||||
$result = self::$folders->delete( $id );
|
||||
if ( !$result ) {
|
||||
Session::flash( 'error', 'There was an error deleting the folder(s)' );
|
||||
} else {
|
||||
Session::flash( 'success', 'Folder deleted' );
|
||||
}
|
||||
Redirect::to( 'bookmarks/folders' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Functionality
|
||||
*/
|
||||
public function hideBookmark( $id = null ) {
|
||||
$bookmark = self::$bookmarks->findById( $id );
|
||||
if ( $bookmark == false ) {
|
||||
Session::flash( 'error', 'Bookmark not found.' );
|
||||
return Redirect::to( 'bookmarks/index' );
|
||||
}
|
||||
if ( $bookmark->createdBy != App::$activeUser->ID ) {
|
||||
Session::flash( 'error', 'You do not have permission to modify this bookmark.' );
|
||||
return Redirect::to( 'bookmarks/index' );
|
||||
}
|
||||
self::$bookmarks->hide( $id );
|
||||
Session::flash( 'success', 'Bookmark hidden.' );
|
||||
return Redirect::to( 'bookmarks/index' );
|
||||
}
|
||||
|
||||
public function archiveBookmark( $id = null ) {
|
||||
$bookmark = self::$bookmarks->findById( $id );
|
||||
if ( $bookmark == false ) {
|
||||
Session::flash( 'error', 'Bookmark not found.' );
|
||||
return Redirect::to( 'bookmarks/index' );
|
||||
}
|
||||
if ( $bookmark->createdBy != App::$activeUser->ID ) {
|
||||
Session::flash( 'error', 'You do not have permission to modify this bookmark.' );
|
||||
return Redirect::to( 'bookmarks/index' );
|
||||
}
|
||||
self::$bookmarks->archive( $id );
|
||||
Session::flash( 'success', 'Bookmark archived.' );
|
||||
return Redirect::to( 'bookmarks/index' );
|
||||
}
|
||||
|
||||
public function showBookmark( $id = null ) {
|
||||
$bookmark = self::$bookmarks->findById( $id );
|
||||
if ( $bookmark == false ) {
|
||||
Session::flash( 'error', 'Bookmark not found.' );
|
||||
return Redirect::to( 'bookmarks/index' );
|
||||
}
|
||||
if ( $bookmark->createdBy != App::$activeUser->ID ) {
|
||||
Session::flash( 'error', 'You do not have permission to modify this bookmark.' );
|
||||
return Redirect::to( 'bookmarks/index' );
|
||||
}
|
||||
self::$bookmarks->show( $id );
|
||||
Session::flash( 'success', 'Bookmark shown.' );
|
||||
return Redirect::to( 'bookmarks/index' );
|
||||
}
|
||||
|
||||
public function unarchiveBookmark( $id = null ) {
|
||||
$bookmark = self::$bookmarks->findById( $id );
|
||||
if ( $bookmark == false ) {
|
||||
Session::flash( 'error', 'Bookmark not found.' );
|
||||
return Redirect::to( 'bookmarks/index' );
|
||||
}
|
||||
if ( $bookmark->createdBy != App::$activeUser->ID ) {
|
||||
Session::flash( 'error', 'You do not have permission to modify this bookmark.' );
|
||||
return Redirect::to( 'bookmarks/index' );
|
||||
}
|
||||
self::$bookmarks->unarchive( $id );
|
||||
Session::flash( 'success', 'Bookmark un-archived.' );
|
||||
return Redirect::to( 'bookmarks/index' );
|
||||
}
|
||||
|
||||
public function refreshBookmark( $id = null ) {
|
||||
$bookmark = self::$bookmarks->findById( $id );
|
||||
if ( $bookmark == false ) {
|
||||
Session::flash( 'error', 'Bookmark not found.' );
|
||||
return Redirect::to( 'bookmarks/index' );
|
||||
}
|
||||
if ( $bookmark->createdBy != App::$activeUser->ID ) {
|
||||
Session::flash( 'error', 'You do not have permission to modify this bookmark.' );
|
||||
return Redirect::to( 'bookmarks/index' );
|
||||
}
|
||||
$info = self::$bookmarks->refreshInfo( $id );
|
||||
if ( false == $info ) {
|
||||
Session::flash( 'error', 'Issue refreshing your bookmark.' );
|
||||
return Redirect::to( 'bookmarks/bookmark/' . $bookmark->ID );
|
||||
}
|
||||
Session::flash( 'success', 'Bookmark data refreshed.' );
|
||||
return Redirect::to( 'bookmarks/bookmark/' . $bookmark->ID );
|
||||
}
|
||||
}
|
@ -1,122 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/bookmarks/forms.php
|
||||
*
|
||||
* This houses all of the form checking functions for this plugin.
|
||||
*
|
||||
* @package TP Bookmarks
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Plugins\Bookmarks;
|
||||
|
||||
use TheTempusProject\Bedrock\Functions\Input;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Classes\Forms;
|
||||
|
||||
class BookmarksForms extends Forms {
|
||||
/**
|
||||
* Adds these functions to the form list.
|
||||
*/
|
||||
public function __construct() {
|
||||
self::addHandler( 'createBookmark', __CLASS__, 'createBookmark' );
|
||||
self::addHandler( 'createFolder', __CLASS__, 'createFolder' );
|
||||
self::addHandler( 'editBookmark', __CLASS__, 'editBookmark' );
|
||||
self::addHandler( 'editFolder', __CLASS__, 'editFolder' );
|
||||
}
|
||||
|
||||
public static function createBookmark() {
|
||||
// if ( ! Input::exists( 'title' ) ) {
|
||||
// Check::addUserError( 'You must include a title.' );
|
||||
// return false;
|
||||
// }
|
||||
if ( ! Input::exists( 'url' ) ) {
|
||||
Check::addUserError( 'You must include a url.' );
|
||||
return false;
|
||||
}
|
||||
// if ( ! Input::exists( 'color' ) ) {
|
||||
// Check::addUserError( 'You must include a color.' );
|
||||
// return false;
|
||||
// }
|
||||
// if ( ! Input::exists( 'privacy' ) ) {
|
||||
// Check::addUserError( 'You must include a privacy.' );
|
||||
// return false;
|
||||
// }
|
||||
// if ( !self::token() ) {
|
||||
// Check::addUserError( 'token - comment out later.' );
|
||||
// return false;
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function createFolder() {
|
||||
if ( ! Input::exists( 'title' ) ) {
|
||||
Check::addUserError( 'You must include a title.' );
|
||||
return false;
|
||||
}
|
||||
// if ( ! Input::exists( 'color' ) ) {
|
||||
// Check::addUserError( 'You must include a color.' );
|
||||
// return false;
|
||||
// }
|
||||
// if ( ! Input::exists( 'privacy' ) ) {
|
||||
// Check::addUserError( 'You must include a privacy.' );
|
||||
// return false;
|
||||
// }
|
||||
// if ( ! self::token() ) {
|
||||
// Check::addUserError( 'token - comment out later.' );
|
||||
// return false;
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function editBookmark() {
|
||||
// if ( ! Input::exists( 'title' ) ) {
|
||||
// Check::addUserError( 'You must include a title.' );
|
||||
// return false;
|
||||
// }
|
||||
if ( ! Input::exists( 'url' ) ) {
|
||||
Check::addUserError( 'You must include a url.' );
|
||||
return false;
|
||||
}
|
||||
// if ( ! Input::exists( 'color' ) ) {
|
||||
// Check::addUserError( 'You must include a color.' );
|
||||
// return false;
|
||||
// }
|
||||
// if ( ! Input::exists( 'privacy' ) ) {
|
||||
// Check::addUserError( 'You must include a privacy.' );
|
||||
// return false;
|
||||
// }
|
||||
// if ( !self::token() ) {
|
||||
// Check::addUserError( 'token - comment out later.' );
|
||||
// return false;
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function editFolder() {
|
||||
if ( ! Input::exists( 'submit' ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'title' ) ) {
|
||||
Check::addUserError( 'You must include a title.' );
|
||||
return false;
|
||||
}
|
||||
// if ( ! Input::exists( 'color' ) ) {
|
||||
// Check::addUserError( 'You must include a color.' );
|
||||
// return false;
|
||||
// }
|
||||
// if ( ! Input::exists( 'privacy' ) ) {
|
||||
// Check::addUserError( 'You must include a privacy.' );
|
||||
// return false;
|
||||
// }
|
||||
// if ( !self::token() ) {
|
||||
// Check::addUserError( 'token - comment out later.' );
|
||||
// return false;
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
new BookmarksForms;
|
@ -1,149 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/bookmarks/models/bookmarkViews.php
|
||||
*
|
||||
* This class is used for the manipulation of the bookmark_views database table.
|
||||
*
|
||||
* @package TP Bookmarks
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Models;
|
||||
|
||||
use TheTempusProject\Bedrock\Classes\Config;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Canary\Canary as Debug;
|
||||
use TheTempusProject\Classes\DatabaseModel;
|
||||
use TheTempusProject\TheTempusProject as App;
|
||||
use TheTempusProject\Houdini\Classes\Filters;
|
||||
use TheTempusProject\Bedrock\Classes\CustomException;
|
||||
|
||||
class BookmarkViews extends DatabaseModel {
|
||||
public $tableName = 'bookmark_views';
|
||||
public $databaseMatrix = [
|
||||
[ 'title', 'varchar', '256' ],
|
||||
[ 'description', 'text', '' ],
|
||||
[ 'privacy', 'varchar', '48' ],
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[ 'createdBy', 'int', '11' ],
|
||||
[ 'createdAt', 'int', '11' ],
|
||||
[ 'updatedAt', 'int', '11' ],
|
||||
];
|
||||
|
||||
/**
|
||||
* The model constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function create( $title, $description = '', $privacy = 'private' ) {
|
||||
if ( ! Check::dataTitle( $title ) ) {
|
||||
Debug::info( 'Views: illegal title.' );
|
||||
return false;
|
||||
}
|
||||
$fields = [
|
||||
'title' => $title,
|
||||
'description' => $description,
|
||||
'privacy' => $privacy,
|
||||
'createdBy' => App::$activeUser->ID,
|
||||
'createdAt' => time(),
|
||||
];
|
||||
if ( ! self::$db->insert( $this->tableName, $fields ) ) {
|
||||
new CustomException( 'viewCreate' );
|
||||
Debug::error( "Views: not created " . var_export($fields,true) );
|
||||
return false;
|
||||
}
|
||||
return self::$db->lastId();
|
||||
}
|
||||
|
||||
public function update( $id, $title, $description = '', $privacy = 'private' ) {
|
||||
if ( !Check::id( $id ) ) {
|
||||
Debug::info( 'Views: illegal ID.' );
|
||||
return false;
|
||||
}
|
||||
if ( !Check::dataTitle( $title ) ) {
|
||||
Debug::info( 'Views: illegal title.' );
|
||||
return false;
|
||||
}
|
||||
$fields = [
|
||||
'title' => $title,
|
||||
'description' => $description,
|
||||
'privacy' => $privacy,
|
||||
];
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'viewUpdate' );
|
||||
Debug::error( "Views: $id not updated: $fields" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function byUser( $limit = null ) {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
if ( empty( $limit ) ) {
|
||||
$views = self::$db->get( $this->tableName, $whereClause );
|
||||
} else {
|
||||
$views = self::$db->get( $this->tableName, $whereClause, 'ID', 'DESC', [0, $limit] );
|
||||
}
|
||||
if ( !$views->count() ) {
|
||||
Debug::info( 'No Views found.' );
|
||||
return false;
|
||||
}
|
||||
return $this->filter( $views->results() );
|
||||
}
|
||||
|
||||
public function getName( $id ) {
|
||||
$views = self::findById( $id );
|
||||
if (false == $views) {
|
||||
return 'unknown';
|
||||
}
|
||||
return $views->title;
|
||||
}
|
||||
|
||||
public function simpleByUser() {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
$views = self::$db->get( $this->tableName, $whereClause );
|
||||
if ( !$views->count() ) {
|
||||
Debug::warn( 'Could not find any Views' );
|
||||
return false;
|
||||
}
|
||||
|
||||
$views = $views->results();
|
||||
$out = [];
|
||||
foreach ( $views as $view ) {
|
||||
$out[ $view->title ] = $view->ID;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function simpleObjectByUser() {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
$views = self::$db->get( $this->tableName, $whereClause );
|
||||
if ( !$views->count() ) {
|
||||
Debug::warn( 'Could not find any Views' );
|
||||
return false;
|
||||
}
|
||||
|
||||
$views = $views->results();
|
||||
$out = [];
|
||||
foreach ( $views as $view ) {
|
||||
$obj = new \stdClass();
|
||||
$obj->title = $view->title;
|
||||
$obj->ID = $view->ID;
|
||||
$out[] = $obj;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
}
|
@ -1,705 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/bookmarks/models/bookmarks.php
|
||||
*
|
||||
* This class is used for the manipulation of the bookmarks database table.
|
||||
*
|
||||
* @package TP Bookmarks
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Models;
|
||||
|
||||
use TheTempusProject\Bedrock\Classes\Config;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Canary\Canary as Debug;
|
||||
use TheTempusProject\Classes\DatabaseModel;
|
||||
use TheTempusProject\TheTempusProject as App;
|
||||
use TheTempusProject\Houdini\Classes\Filters;
|
||||
use TheTempusProject\Bedrock\Classes\CustomException;
|
||||
|
||||
class Bookmarks extends DatabaseModel {
|
||||
public $tableName = 'bookmarks';
|
||||
public $linkTypes = [
|
||||
'Open in New Tab' => 'external',
|
||||
'Open in Same Tab' => 'internal',
|
||||
];
|
||||
|
||||
public $databaseMatrix = [
|
||||
[ 'title', 'varchar', '256' ],
|
||||
[ 'url', 'text', '' ],
|
||||
[ 'color', 'varchar', '48' ],
|
||||
[ 'privacy', 'varchar', '48' ],
|
||||
[ 'folderID', 'int', '11' ],
|
||||
[ 'description', 'text', '' ],
|
||||
[ 'createdBy', 'int', '11' ],
|
||||
[ 'createdAt', 'int', '11' ],
|
||||
[ 'meta', 'text', '' ],
|
||||
[ 'icon', 'text', '' ],
|
||||
[ 'archivedAt', 'int', '11' ],
|
||||
[ 'refreshedAt', 'int', '11' ],
|
||||
[ 'hiddenAt', 'int', '11' ],
|
||||
[ 'order', 'int', '11' ],
|
||||
[ 'linkType', 'varchar', '32' ],
|
||||
];
|
||||
|
||||
/**
|
||||
* The model constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function create( $title, $url, $folderID = 0, $description = '', $color = 'default', $privacy = 'private', $type = 'external' ) {
|
||||
$fields = [
|
||||
'title' => $title,
|
||||
'url' => $url,
|
||||
'description' => $description,
|
||||
'color' => $color,
|
||||
'privacy' => $privacy,
|
||||
'createdBy' => App::$activeUser->ID,
|
||||
'createdAt' => time(),
|
||||
];
|
||||
if ( !empty( $folderID ) ) {
|
||||
$fields['folderID'] = $folderID;
|
||||
} else {
|
||||
$fields['folderID'] = null;
|
||||
}
|
||||
if ( ! self::$db->insert( $this->tableName, $fields ) ) {
|
||||
new CustomException( 'bookmarkCreate' );
|
||||
Debug::error( "Bookmarks: not created " . var_export($fields,true) );
|
||||
return false;
|
||||
}
|
||||
return self::$db->lastId();
|
||||
}
|
||||
|
||||
public function update( $id, $title, $url, $folderID = 0, $description = '', $color = 'default', $privacy = 'private', $type = 'external', $order = 0 ) {
|
||||
if ( !Check::id( $id ) ) {
|
||||
Debug::info( 'Bookmarks: illegal ID.' );
|
||||
return false;
|
||||
}
|
||||
$fields = [
|
||||
'title' => $title,
|
||||
'url' => $url,
|
||||
'description' => $description,
|
||||
'color' => $color,
|
||||
'privacy' => $privacy,
|
||||
// 'linkType' => $type,
|
||||
// 'order' => $order,
|
||||
];
|
||||
if ( !empty( $folderID ) ) {
|
||||
$fields['folderID'] = $folderID;
|
||||
}
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'bookmarkUpdate' );
|
||||
Debug::error( "Bookmarks: $id not updated" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function byUser( $limit = null ) {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
if ( empty( $limit ) ) {
|
||||
$bookmarks = self::$db->get( $this->tableName, $whereClause );
|
||||
} else {
|
||||
$bookmarks = self::$db->get( $this->tableName, $whereClause, 'ID', 'DESC', [0, $limit] );
|
||||
}
|
||||
if ( !$bookmarks->count() ) {
|
||||
Debug::info( 'No Bookmarks found.' );
|
||||
return false;
|
||||
}
|
||||
return $this->filter( $bookmarks->results() );
|
||||
}
|
||||
|
||||
public function byFolder( $id, $limit = null ) {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID, 'AND'];
|
||||
|
||||
$whereClause = array_merge( $whereClause, [ 'folderID', '=', $id ] );
|
||||
if ( empty( $limit ) ) {
|
||||
$bookmarks = self::$db->get( $this->tableName, $whereClause );
|
||||
} else {
|
||||
$bookmarks = self::$db->get( $this->tableName, $whereClause, 'ID', 'DESC', [0, $limit] );
|
||||
}
|
||||
if ( !$bookmarks->count() ) {
|
||||
Debug::info( 'No Bookmarks found.' );
|
||||
return false;
|
||||
}
|
||||
return $this->filter( $bookmarks->results() );
|
||||
}
|
||||
|
||||
public function noFolder( $id = 0, $limit = 10 ) {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID, 'AND'];
|
||||
if ( !empty( $id ) ) {
|
||||
$whereClause = array_merge( $whereClause, ['folderID', '!=', $id] );
|
||||
} else {
|
||||
$whereClause = array_merge( $whereClause, [ 'folderID', 'IS', null] );
|
||||
}
|
||||
if ( empty( $limit ) ) {
|
||||
$bookmarks = self::$db->get( $this->tableName, $whereClause );
|
||||
} else {
|
||||
$bookmarks = self::$db->get( $this->tableName, $whereClause, 'ID', 'DESC', [ 0, $limit ] );
|
||||
}
|
||||
if ( !$bookmarks->count() ) {
|
||||
Debug::info( 'No Bookmarks found.' );
|
||||
return false;
|
||||
}
|
||||
return $this->filter( $bookmarks->results() );
|
||||
}
|
||||
|
||||
public function getName( $id ) {
|
||||
$bookmarks = self::findById( $id );
|
||||
if (false == $bookmarks) {
|
||||
return 'unknown';
|
||||
}
|
||||
return $bookmarks->title;
|
||||
}
|
||||
|
||||
public function getColor( $id ) {
|
||||
$bookmarks = self::findById( $id );
|
||||
if (false == $bookmarks) {
|
||||
return 'default';
|
||||
}
|
||||
return $bookmarks->color;
|
||||
}
|
||||
|
||||
public function simpleByUser() {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
$bookmarks = self::$db->get( $this->tableName, $whereClause );
|
||||
if ( !$bookmarks->count() ) {
|
||||
Debug::warn( 'Could not find any bookmarks' );
|
||||
return false;
|
||||
}
|
||||
|
||||
$bookmarks = $bookmarks->results();
|
||||
$out = [];
|
||||
foreach ( $bookmarks as $bookmarks ) {
|
||||
$out[ $bookmarks->title ] = $bookmarks->ID;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function simpleObjectByUser() {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
$bookmarks = self::$db->get( $this->tableName, $whereClause );
|
||||
if ( !$bookmarks->count() ) {
|
||||
Debug::warn( 'Could not find any bookmarks' );
|
||||
return false;
|
||||
}
|
||||
|
||||
$bookmarks = $bookmarks->results();
|
||||
$out = [];
|
||||
foreach ( $bookmarks as $bookmarks ) {
|
||||
$obj = new \stdClass();
|
||||
$obj->title = $bookmarks->title;
|
||||
$obj->ID = $bookmarks->ID;
|
||||
$out[] = $obj;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function deleteByFolder( $folderID ) {
|
||||
$whereClause = [ 'createdBy', '=', App::$activeUser->ID, 'AND' ];
|
||||
$whereClause = array_merge( $whereClause, [ 'folderID', '=', $folderID ] );
|
||||
$bookmarks = self::$db->get( $this->tableName, $whereClause );
|
||||
if ( ! $bookmarks->count() ) {
|
||||
Debug::info( 'No ' . $this->tableName . ' data found.' );
|
||||
return [];
|
||||
}
|
||||
foreach( $bookmarks->results() as $bookmark ) {
|
||||
$this->delete( $bookmark->ID );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private function resolveShortenedUrl( $url ) {
|
||||
$ch = curl_init($url);
|
||||
|
||||
// Set curl options
|
||||
curl_setopt($ch, CURLOPT_NOBODY, true); // We don't need the body
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // Follow redirects
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // Return the response
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 30); // Set a timeout
|
||||
// curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); // Maybe sketchy?
|
||||
// Maybe sketchy?
|
||||
// curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // Disable SSL host verification
|
||||
// curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Disable SSL peer verification
|
||||
// curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
|
||||
|
||||
// added to support the regex site
|
||||
// curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
|
||||
|
||||
// =
|
||||
// curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST, 'AES256+EECDH:AES256+EDH' );
|
||||
|
||||
|
||||
|
||||
|
||||
// Execute curl
|
||||
$response = curl_exec( $ch );
|
||||
|
||||
// Check if there was an error
|
||||
if ( curl_errno( $ch ) ) {
|
||||
|
||||
|
||||
// Get error details
|
||||
$errorCode = curl_errno($ch);
|
||||
$errorMessage = curl_error($ch);
|
||||
// Log or display the error details
|
||||
dv('cURL Error: ' . $errorMessage . ' (Error Code: ' . $errorCode . ')');
|
||||
|
||||
curl_close($ch);
|
||||
// return $url; // Return the original URL if there was an error
|
||||
|
||||
|
||||
$url = rtrim( $url, '/' );
|
||||
$ch2 = curl_init($url);
|
||||
curl_setopt($ch2, CURLOPT_NOBODY, true); // We don't need the body
|
||||
curl_setopt($ch2, CURLOPT_FOLLOWLOCATION, true); // Follow redirects
|
||||
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true); // Return the response
|
||||
curl_setopt($ch2, CURLOPT_TIMEOUT, 5); // Set a timeout
|
||||
curl_exec($ch2);
|
||||
|
||||
if ( curl_errno( $ch2 ) ) {
|
||||
|
||||
}
|
||||
curl_close( $ch );
|
||||
return $url;
|
||||
}
|
||||
|
||||
// Get the effective URL (the final destination after redirects)
|
||||
$finalUrl = curl_getinfo( $ch, CURLINFO_EFFECTIVE_URL );
|
||||
curl_close( $ch );
|
||||
|
||||
return $finalUrl;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// $headers = get_headers( $url, 1 );
|
||||
$headers = @get_headers($url, 1);
|
||||
if ( $headers === false ) {
|
||||
}
|
||||
if ( isset( $headers['Location'] ) ) {
|
||||
if (is_array($headers['Location'])) {
|
||||
return end($headers['Location']);
|
||||
} else {
|
||||
return $headers['Location'];
|
||||
}
|
||||
} else {
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
|
||||
public function filter( $data, $params = [] ) {
|
||||
foreach ( $data as $instance ) {
|
||||
if ( !is_object( $instance ) ) {
|
||||
$instance = $data;
|
||||
$end = true;
|
||||
}
|
||||
$base_url = $this->getBaseUrl( $instance->url );
|
||||
|
||||
if ( empty( $instance->icon ) ) {
|
||||
$instance->iconHtml = '<i class="glyphicon glyphicon-link"></i>';
|
||||
} else {
|
||||
if (strpos($instance->icon, 'http') !== false) {
|
||||
$instance->iconHtml = '<img src="' . $instance->icon .'" />';
|
||||
} else {
|
||||
$instance->iconHtml = '<img src="' . $base_url . ltrim( $instance->icon, '/' ) .'" />';
|
||||
}
|
||||
}
|
||||
if ( empty( $instance->hiddenAt ) ) {
|
||||
$instance->hideBtn = '
|
||||
<a href="{ROOT_URL}bookmarks/hideBookmark/'.$instance->ID.'" class="btn btn-sm btn-warning" role="button">
|
||||
<i class="glyphicon glyphicon-eye-open"></i>
|
||||
</a>';
|
||||
} else {
|
||||
$instance->hideBtn = '
|
||||
<a href="{ROOT_URL}bookmarks/showBookmark/'.$instance->ID.'" class="btn btn-sm btn-default" role="button">
|
||||
<i class="glyphicon glyphicon-eye-open"></i>
|
||||
</a>';
|
||||
}
|
||||
if ( empty( $instance->archivedAt ) ) {
|
||||
$instance->archiveBtn = '
|
||||
<a href="{ROOT_URL}bookmarks/archiveBookmark/'.$instance->ID.'" class="btn btn-sm btn-info" role="button">
|
||||
<i class="glyphicon glyphicon-briefcase"></i>
|
||||
</a>';
|
||||
} else {
|
||||
$instance->archiveBtn = '
|
||||
<a href="{ROOT_URL}bookmarks/unarchiveBookmark/'.$instance->ID.'" class="btn btn-sm btn-default" role="button">
|
||||
<i class="glyphicon glyphicon-briefcase"></i>
|
||||
</a>';
|
||||
}
|
||||
if ( ! empty( $instance->refreshedAt ) && time() < ( $instance->refreshedAt + ( 60 * 10 ) ) ) {
|
||||
$instance->refreshBtn = '
|
||||
<a href="{ROOT_URL}bookmarks/refreshBookmark/'.$instance->ID.'" class="btn btn-sm btn-danger" role="button">
|
||||
<i class="glyphicon glyphicon-refresh"></i>
|
||||
</a>';
|
||||
} else {
|
||||
$instance->refreshBtn = '
|
||||
<a href="{ROOT_URL}bookmarks/refreshBookmark/'.$instance->ID.'" class="btn btn-sm btn-success" role="button">
|
||||
<i class="glyphicon glyphicon-refresh"></i>
|
||||
</a>';
|
||||
}
|
||||
|
||||
$out[] = $instance;
|
||||
if ( !empty( $end ) ) {
|
||||
$out = $out[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function hide( $id ) {
|
||||
if ( !Check::id( $id ) ) {
|
||||
Debug::info( 'Bookmarks: illegal ID.' );
|
||||
return false;
|
||||
}
|
||||
$fields = [
|
||||
'hiddenAt' => time(),
|
||||
];
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'bookmarkUpdate' );
|
||||
Debug::error( "Bookmarks: $id not updated" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function show( $id ) {
|
||||
if ( !Check::id( $id ) ) {
|
||||
Debug::info( 'Bookmarks: illegal ID.' );
|
||||
return false;
|
||||
}
|
||||
$fields = [
|
||||
'hiddenAt' => 0,
|
||||
];
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'bookmarkUpdate' );
|
||||
Debug::error( "Bookmarks: $id not updated" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function archive( $id ) {
|
||||
if ( !Check::id( $id ) ) {
|
||||
Debug::info( 'Bookmarks: illegal ID.' );
|
||||
return false;
|
||||
}
|
||||
$fields = [
|
||||
'archivedAt' => time(),
|
||||
];
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'bookmarkUpdate' );
|
||||
Debug::error( "Bookmarks: $id not updated" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function unarchive( $id ) {
|
||||
if ( !Check::id( $id ) ) {
|
||||
Debug::info( 'Bookmarks: illegal ID.' );
|
||||
return false;
|
||||
}
|
||||
$fields = [
|
||||
'archivedAt' => 0,
|
||||
];
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'bookmarkUpdate' );
|
||||
Debug::error( "Bookmarks: $id not updated" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function extractMetaTags($htmlContent) {
|
||||
$doc = new \DOMDocument();
|
||||
@$doc->loadHTML($htmlContent);
|
||||
$metaTags = [];
|
||||
foreach ($doc->getElementsByTagName('meta') as $meta) {
|
||||
$name = $meta->getAttribute('name') ?: $meta->getAttribute('property');
|
||||
$content = $meta->getAttribute('content');
|
||||
if ($name && $content) {
|
||||
$metaTags[$name] = $content;
|
||||
}
|
||||
}
|
||||
return $metaTags;
|
||||
}
|
||||
|
||||
public function fetchUrlData($url) {
|
||||
$ch = curl_init();
|
||||
|
||||
// Set cURL options
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_HEADER, true); // Include headers in the output
|
||||
curl_setopt($ch, CURLOPT_NOBODY, false); // Include the body in the output
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // Follow redirects
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 30); // Set a timeout
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // Disable SSL host verification for testing
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Disable SSL peer verification for testing
|
||||
|
||||
// Execute cURL request
|
||||
$response = curl_exec($ch);
|
||||
|
||||
// Check if there was an error
|
||||
if (curl_errno($ch)) {
|
||||
$errorMessage = curl_error($ch);
|
||||
curl_close($ch);
|
||||
throw new \Exception('cURL Error: ' . $errorMessage);
|
||||
}
|
||||
|
||||
// Get HTTP status code
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
|
||||
// Separate headers and body
|
||||
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
|
||||
$headers = substr($response, 0, $headerSize);
|
||||
$body = substr($response, $headerSize);
|
||||
|
||||
curl_close($ch);
|
||||
|
||||
// Parse headers into an associative array
|
||||
$headerLines = explode("\r\n", trim($headers));
|
||||
$headerArray = [];
|
||||
foreach ($headerLines as $line) {
|
||||
$parts = explode(': ', $line, 2);
|
||||
if (count($parts) == 2) {
|
||||
$headerArray[$parts[0]] = $parts[1];
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'http_code' => $httpCode,
|
||||
'headers' => $headerArray,
|
||||
'body' => $body,
|
||||
];
|
||||
}
|
||||
|
||||
private function getMetaTagsAndFavicon( $url ) {
|
||||
try {
|
||||
// $url = 'https://runescape.wiki';
|
||||
$data = $this->fetchUrlData($url);
|
||||
|
||||
// iv($data);
|
||||
|
||||
// Get headers
|
||||
$headers = $data['headers'];
|
||||
iv($headers);
|
||||
|
||||
// Get meta tags
|
||||
$metaTags = $this->extractMetaTags($data['body']);
|
||||
} catch (Exception $e) {
|
||||
dv( 'Error: ' . $e->getMessage());
|
||||
|
||||
}
|
||||
$metaInfo = [
|
||||
'url' => $url,
|
||||
'title' => null,
|
||||
'description' => null,
|
||||
'image' => null,
|
||||
'favicon' => null
|
||||
];
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
$html = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
if ($html === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$meta = @get_meta_tags( $url );
|
||||
|
||||
$dom = new \DOMDocument('1.0', 'utf-8');
|
||||
$dom->strictErrorChecking = false;
|
||||
$dom->loadHTML($html, LIBXML_NOERROR);
|
||||
$xml = simplexml_import_dom($dom);
|
||||
$arr = $xml->xpath('//link[@rel="shortcut icon"]');
|
||||
|
||||
// Get the title of the page
|
||||
$titles = $dom->getElementsByTagName('title');
|
||||
if ($titles->length > 0) {
|
||||
$metaInfo['title'] = $titles->item(0)->nodeValue;
|
||||
}
|
||||
|
||||
// Get the meta tags
|
||||
$metaTags = $dom->getElementsByTagName('meta');
|
||||
$metadata = [];
|
||||
foreach ($metaTags as $meta) {
|
||||
$metadata[] = [
|
||||
'name' => $meta->getAttribute('name'),
|
||||
'property' => $meta->getAttribute('property'),
|
||||
'content' => $meta->getAttribute('content')
|
||||
];
|
||||
if ($meta->getAttribute('name') === 'description') {
|
||||
$metaInfo['description'] = $meta->getAttribute('content');
|
||||
}
|
||||
if ($meta->getAttribute('itemprop') === 'image') {
|
||||
$metaInfo['google_image'] = $meta->getAttribute('content');
|
||||
}
|
||||
if ($meta->getAttribute('property') === 'og:image') {
|
||||
$metaInfo['image'] = $meta->getAttribute('content');
|
||||
}
|
||||
}
|
||||
|
||||
// Get the link tags to find the favicon
|
||||
$linkTags = $dom->getElementsByTagName('link');
|
||||
$metadata['links'] = [];
|
||||
foreach ($linkTags as $link) {
|
||||
$metadata['links'][] = [ $link->getAttribute('rel') => $link->getAttribute('href') ];
|
||||
if ( $link->getAttribute('rel') === 'icon' || $link->getAttribute('rel') === 'shortcut icon') {
|
||||
$metaInfo['favicon'] = $link->getAttribute('href');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$metaInfo['metadata'] = $metadata;
|
||||
|
||||
return $metaInfo;
|
||||
}
|
||||
|
||||
public function retrieveInfo( $url ) {
|
||||
$finalDestination = $this->resolveShortenedUrl( $url );
|
||||
$info = $this->getMetaTagsAndFavicon( $finalDestination );
|
||||
$base_url = $this->getBaseUrl( $finalDestination );
|
||||
|
||||
if ( ! empty( $info['favicon'] ) ) {
|
||||
echo 'favicon exists' . PHP_EOL;
|
||||
if ( stripos( $info['favicon'], 'http' ) !== false) {
|
||||
echo 'favicon is full url' . PHP_EOL;
|
||||
$imageUrl = $info['favicon'];
|
||||
} else {
|
||||
echo 'favicon is not full url' . PHP_EOL;
|
||||
$imageUrl = trim( $base_url, '/' ) . '/' . ltrim( $info['favicon'], '/' );
|
||||
}
|
||||
if ( $this->isValidImageUrl( $imageUrl ) ) {
|
||||
echo 'image is valid' . PHP_EOL;
|
||||
$info['favicon'] = $imageUrl;
|
||||
} else {
|
||||
echo 'image is not valid' . PHP_EOL;
|
||||
$base_info = $this->getMetaTagsAndFavicon( $base_url );
|
||||
if ( ! empty( $base_info['favicon'] ) ) {
|
||||
echo 'parent favicon exists!';
|
||||
if ( stripos( $base_info['favicon'], 'http' ) !== false) {
|
||||
echo 'parent favicon is full url' . PHP_EOL;
|
||||
$imageUrl = $base_info['favicon'];
|
||||
} else {
|
||||
echo 'parent favicon is not full url' . PHP_EOL;
|
||||
$imageUrl = trim( $base_url, '/' ) . '/' . ltrim( $base_info['favicon'], '/' );
|
||||
}
|
||||
if ( $this->isValidImageUrl( $imageUrl ) ) {
|
||||
echo 'parent favicon image is valid' . PHP_EOL;
|
||||
$info['favicon'] = $imageUrl;
|
||||
} else {
|
||||
echo 'parent favicon image is not valid' . PHP_EOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
echo 'favicon does not exist' . PHP_EOL;
|
||||
$base_info = $this->getMetaTagsAndFavicon( $base_url );
|
||||
if ( ! empty( $base_info['favicon'] ) ) {
|
||||
echo 'parent favicon exists!' . PHP_EOL;
|
||||
if ( stripos( $base_info['favicon'], 'http' ) !== false) {
|
||||
echo 'parent favicon is full url' . PHP_EOL;
|
||||
$imageUrl = $base_info['favicon'];
|
||||
} else {
|
||||
echo 'parent favicon is not full url' . PHP_EOL;
|
||||
$imageUrl = trim( $base_url, '/' ) . '/' . ltrim( $base_info['favicon'], '/' );
|
||||
}
|
||||
if ( $this->isValidImageUrl( $imageUrl ) ) {
|
||||
echo 'parent favicon image is valid' . PHP_EOL;
|
||||
$info['favicon'] = $imageUrl;
|
||||
} else {
|
||||
echo 'parent favicon image is not valid' . PHP_EOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
public function refreshInfo( $id ) {
|
||||
if ( !Check::id( $id ) ) {
|
||||
Debug::info( 'Bookmarks: illegal ID.' );
|
||||
return false;
|
||||
}
|
||||
$bookmark = self::findById( $id );
|
||||
if ( $bookmark == false ) {
|
||||
Debug::info( 'Bookmarks not found.' );
|
||||
return false;
|
||||
}
|
||||
if ( $bookmark->createdBy != App::$activeUser->ID ) {
|
||||
Debug::info( 'You do not have permission to modify this bookmark.' );
|
||||
return false;
|
||||
}
|
||||
if ( time() < ( $bookmark->refreshedAt + ( 60 * 10 ) ) ) {
|
||||
Debug::info( 'You may only fetch bookmarks once every 10 minutes.' );
|
||||
return false;
|
||||
}
|
||||
|
||||
$info = $this->retrieveInfo( $bookmark->url );
|
||||
|
||||
$fields = [
|
||||
// 'refreshedAt' => time(),
|
||||
];
|
||||
|
||||
if ( empty( $bookmark->title ) && ! empty( $info['title'] ) ) {
|
||||
$fields['title'] = $info['title'];
|
||||
}
|
||||
if ( empty( $bookmark->description ) && ! empty( $info['description'] ) ) {
|
||||
$fields['description'] = $info['description'];
|
||||
}
|
||||
|
||||
if ( ( empty( $bookmark->icon ) || ! $this->isValidImageUrl( $bookmark->icon ) ) && ! empty( $info['favicon'] ) ) {
|
||||
$fields['icon'] = $info['favicon'];
|
||||
}
|
||||
$fields['meta'] = json_encode( $info['metadata'] );
|
||||
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'bookmarkUpdate' );
|
||||
Debug::error( "Bookmarks: $id not updated" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private function getBaseUrl ($url ) {
|
||||
$parsedUrl = parse_url($url);
|
||||
|
||||
if (isset($parsedUrl['scheme']) && isset($parsedUrl['host'])) {
|
||||
return $parsedUrl['scheme'] . '://' . $parsedUrl['host'] . '/';
|
||||
} else {
|
||||
return null; // URL is not valid or cannot be parsed
|
||||
}
|
||||
}
|
||||
|
||||
function isValidImageUrl($url) {
|
||||
$headers = @get_headers($url);
|
||||
if ($headers && strpos($headers[0], '200') !== false) {
|
||||
|
||||
return true;
|
||||
// Further check to ensure it's an image
|
||||
foreach ($headers as $header) {
|
||||
if (strpos(strtolower($header), 'content-type:') !== false) {
|
||||
if (strpos(strtolower($header), 'image/') !== false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,157 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/bookmarks/models/folders.php
|
||||
*
|
||||
* This class is used for the manipulation of the folders database table.
|
||||
*
|
||||
* @package TP Bookmarks
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Models;
|
||||
|
||||
use TheTempusProject\Bedrock\Classes\Config;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Canary\Canary as Debug;
|
||||
use TheTempusProject\Classes\DatabaseModel;
|
||||
use TheTempusProject\TheTempusProject as App;
|
||||
use TheTempusProject\Houdini\Classes\Filters;
|
||||
use TheTempusProject\Bedrock\Classes\CustomException;
|
||||
|
||||
class Folders extends DatabaseModel {
|
||||
public $tableName = 'folders';
|
||||
public $databaseMatrix = [
|
||||
[ 'title', 'varchar', '256' ],
|
||||
[ 'color', 'varchar', '48' ],
|
||||
[ 'privacy', 'varchar', '48' ],
|
||||
[ 'description', 'text', '' ],
|
||||
[ 'folderID', 'int', '11' ],
|
||||
[ 'createdBy', 'int', '11' ],
|
||||
[ 'createdAt', 'int', '11' ],
|
||||
];
|
||||
|
||||
/**
|
||||
* The model constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function create( $title, $folderID = 0, $description = '', $color = 'default', $privacy = 'private' ) {
|
||||
if ( ! Check::dataTitle( $title ) ) {
|
||||
Debug::info( 'Folders: illegal title.' );
|
||||
return false;
|
||||
}
|
||||
$fields = [
|
||||
'title' => $title,
|
||||
'description' => $description,
|
||||
'color' => $color,
|
||||
'privacy' => $privacy,
|
||||
'createdBy' => App::$activeUser->ID,
|
||||
'createdAt' => time(),
|
||||
];
|
||||
if ( !empty( $folderID ) ) {
|
||||
$fields['folderID'] = $folderID;
|
||||
}
|
||||
if ( ! self::$db->insert( $this->tableName, $fields ) ) {
|
||||
new CustomException( 'folderCreate' );
|
||||
Debug::error( "Folders: not created " . var_export($fields,true) );
|
||||
return false;
|
||||
}
|
||||
return self::$db->lastId();
|
||||
}
|
||||
|
||||
public function update( $id, $title, $folderID = 0, $description = '', $color = 'default', $privacy = 'private' ) {
|
||||
if ( !Check::id( $id ) ) {
|
||||
Debug::info( 'Folders: illegal ID.' );
|
||||
return false;
|
||||
}
|
||||
if ( !Check::dataTitle( $title ) ) {
|
||||
Debug::info( 'Folders: illegal title.' );
|
||||
return false;
|
||||
}
|
||||
$fields = [
|
||||
'title' => $title,
|
||||
'description' => $description,
|
||||
'color' => $color,
|
||||
'privacy' => $privacy,
|
||||
];
|
||||
if ( !empty( $folderID ) ) {
|
||||
$fields['folderID'] = $folderID;
|
||||
}
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'folderUpdate' );
|
||||
Debug::error( "Folders: $id not updated: $fields" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function byUser( $limit = null ) {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
if ( empty( $limit ) ) {
|
||||
$folders = self::$db->get( $this->tableName, $whereClause );
|
||||
} else {
|
||||
$folders = self::$db->get( $this->tableName, $whereClause, 'ID', 'DESC', [0, $limit] );
|
||||
}
|
||||
if ( !$folders->count() ) {
|
||||
Debug::info( 'No Folders found.' );
|
||||
return false;
|
||||
}
|
||||
return $this->filter( $folders->results() );
|
||||
}
|
||||
|
||||
public function getName( $id ) {
|
||||
$folder = self::findById( $id );
|
||||
if (false == $folder) {
|
||||
return 'unknown';
|
||||
}
|
||||
return $folder->title;
|
||||
}
|
||||
|
||||
public function getColor( $id ) {
|
||||
$folder = self::findById( $id );
|
||||
if (false == $folder) {
|
||||
return 'default';
|
||||
}
|
||||
return $folder->color;
|
||||
}
|
||||
|
||||
public function simpleByUser() {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
$folders = self::$db->get( $this->tableName, $whereClause );
|
||||
if ( !$folders->count() ) {
|
||||
Debug::warn( 'Could not find any folders' );
|
||||
return false;
|
||||
}
|
||||
|
||||
$folders = $folders->results();
|
||||
$out = [];
|
||||
$out[ 'No Folder' ] = 0;
|
||||
foreach ( $folders as $folder ) {
|
||||
$out[ $folder->title ] = $folder->ID;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function simpleObjectByUser() {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
$folders = self::$db->get( $this->tableName, $whereClause );
|
||||
if ( !$folders->count() ) {
|
||||
Debug::warn( 'Could not find any folders' );
|
||||
return false;
|
||||
}
|
||||
|
||||
$folders = $folders->results();
|
||||
$out = [];
|
||||
foreach ( $folders as $folder ) {
|
||||
$obj = new \stdClass();
|
||||
$obj->title = $folder->title;
|
||||
$obj->ID = $folder->ID;
|
||||
$out[] = $obj;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/bookmarks/plugin.php
|
||||
*
|
||||
* This houses all of the main plugin info and functionality.
|
||||
*
|
||||
* @package TP Bookmarks
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Plugins;
|
||||
|
||||
use TheTempusProject\Classes\Plugin;
|
||||
use TheTempusProject\Models\Events;
|
||||
use TheTempusProject\Models\Bookmarks as Bookmark;
|
||||
use TheTempusProject\Models\Folders;
|
||||
use TheTempusProject\Houdini\Classes\Components;
|
||||
use TheTempusProject\Houdini\Classes\Template;
|
||||
|
||||
class Bookmarks extends Plugin {
|
||||
public $pluginName = 'TP Bookmarks';
|
||||
public $configName = 'bookmarks';
|
||||
public $pluginAuthor = 'JoeyK';
|
||||
public $pluginWebsite = 'https://TheTempusProject.com';
|
||||
public $modelVersion = '1.0';
|
||||
public $pluginVersion = '3.0';
|
||||
public $pluginDescription = 'A simple plugin which adds a site wide bookmark system.';
|
||||
public $permissionMatrix = [
|
||||
'useBookmarks' => [
|
||||
'pretty' => 'Can use the bookmarks feature',
|
||||
'default' => false,
|
||||
],
|
||||
'createEvents' => [
|
||||
'pretty' => 'Can add events to bookmarks',
|
||||
'default' => false,
|
||||
],
|
||||
];
|
||||
public $main_links = [
|
||||
[
|
||||
'text' => 'Bookmarks',
|
||||
'url' => '{ROOT_URL}bookmarks/index',
|
||||
'filter' => 'loggedin',
|
||||
],
|
||||
];
|
||||
public $configMatrix = [
|
||||
'enabled' => [
|
||||
'type' => 'radio',
|
||||
'pretty' => 'Enable Bookmarks.',
|
||||
'default' => true,
|
||||
],
|
||||
];
|
||||
public $bookmarks;
|
||||
public $folders;
|
||||
|
||||
public function __construct( $load = false ) {
|
||||
$this->bookmarks = new Bookmark;
|
||||
$this->folders = new Folders;
|
||||
parent::__construct( $load );
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
<legend>Create Bookmark</legend>
|
||||
{BookmarkBreadCrumbs}
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<div class="form-group">
|
||||
<label for="title" class="col-lg-3 control-label">Title</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="title" id="title">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="url" class="col-lg-3 control-label">URL:</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="url" id="url">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description" class="col-lg-3 control-label">Description:</label>
|
||||
<div class="col-lg-3">
|
||||
<textarea class="form-control" name="description" maxlength="2000" rows="10" cols="50" id="description"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
{folderSelect}
|
||||
<div class="form-group">
|
||||
<label for="privacy" class="col-lg-3 control-label">Privacy</label>
|
||||
<div class="col-lg-3 select-container" id="colorContainer">
|
||||
<select id="privacy" name="privacy" class="form-control custom-select">
|
||||
<option value="private">Private</option>
|
||||
<option value="public">Public</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="color" class="col-lg-3 control-label">Color</label>
|
||||
<div class="col-lg-3 select-container" id="colorContainer">
|
||||
{colorSelect}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="submit" class="col-lg-3 control-label"></label>
|
||||
<div class="col-lg-3">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block ">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -1,45 +0,0 @@
|
||||
<legend>Edit Bookmark</legend>
|
||||
{BookmarkBreadCrumbs}
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<div class="form-group">
|
||||
<label for="title" class="col-lg-3 control-label">Title</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="title" id="title" value="{title}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="url" class="col-lg-3 control-label">URL:</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="url" id="url" value="{url}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description" class="col-lg-3 control-label">Description:</label>
|
||||
<div class="col-lg-3">
|
||||
<textarea class="form-control" name="description" maxlength="2000" rows="10" cols="50" id="description">{description}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
{folderSelect}
|
||||
<div class="form-group">
|
||||
<label for="privacy" class="col-lg-3 control-label">Privacy</label>
|
||||
<div class="col-lg-3 select-container" id="colorContainer">
|
||||
<select id="privacy" name="privacy" class="form-control custom-select" value="{privacy}">
|
||||
<option value="private">Private</option>
|
||||
<option value="public">Public</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="color" class="col-lg-3 control-label">Color</label>
|
||||
<div class="col-lg-3 select-container" id="colorContainer">
|
||||
{colorSelect}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="submit" class="col-lg-3 control-label"></label>
|
||||
<div class="col-lg-3">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block ">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -1,37 +0,0 @@
|
||||
{BookmarkBreadCrumbs}
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 75%">Bookmark</th>
|
||||
<th style="width: 10%"></th>
|
||||
<th style="width: 5%"></th>
|
||||
<th style="width: 5%"></th>
|
||||
<th style="width: 5%"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{LOOP}
|
||||
<tr>
|
||||
<td style="text-align: center;">
|
||||
<a href="{url}" role="button">
|
||||
{title}
|
||||
</a>
|
||||
</td>
|
||||
<td style="text-align: center;">
|
||||
{privacy}
|
||||
</td>
|
||||
<td><a href="{ROOT_URL}bookmarks/bookmarks/{ID}" class="btn btn-sm btn-primary" role="button"><i class="glyphicon glyphicon-open"></i></a></td>
|
||||
<td><a href="{ROOT_URL}bookmarks/editBookmark/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a></td>
|
||||
<td><a href="{ROOT_URL}bookmarks/deleteBookmark/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a></td>
|
||||
</tr>
|
||||
{/LOOP}
|
||||
{ALT}
|
||||
<tr>
|
||||
<td style="text-align: center;" colspan="6">
|
||||
No results to show.
|
||||
</td>
|
||||
</tr>
|
||||
{/ALT}
|
||||
</tbody>
|
||||
</table>
|
||||
<a href="{ROOT_URL}bookmarks/createBookmark" class="btn btn-sm btn-primary" role="button">Create</a>
|
@ -1,84 +0,0 @@
|
||||
{BookmarkBreadCrumbs}<br />
|
||||
<div class="container col-md-4 col-lg-4">
|
||||
<div class="row">
|
||||
<div class="panel panel-{color}">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">Bookmark</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
<div class="">
|
||||
<table class="table table-user-primary">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="left" width="200"><b>Title</b></td>
|
||||
<td align="right">{title}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left" width="200"><b>URL</b></td>
|
||||
<td align="right">{url}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left" width="200"><b>Type</b></td>
|
||||
<td align="right">{linkType}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left" width="200"><b>Privacy</b></td>
|
||||
<td align="right">{privacy}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left" width="200"><b>Color</b></td>
|
||||
<td align="right">{color}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" colspan="2"><b>Description</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{description}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" colspan="2"><b>Icon</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{iconHtml}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{icon}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" colspan="2"><b>Meta</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{meta}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Created</b></td>
|
||||
<td align="right">{DTC}{createdAt}{/DTC}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Archived</b></td>
|
||||
<td align="right">{DTC}{archivedAt}{/DTC}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Hidden</b></td>
|
||||
<td align="right">{DTC}{hiddenAt}{/DTC}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Last Refreshed</b></td>
|
||||
<td align="right">{DTC}{refreshedAt}{/DTC}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
{refreshBtn}
|
||||
{hideBtn}
|
||||
{archiveBtn}
|
||||
<a href="{ROOT_URL}bookmarks/editBookmark/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a>
|
||||
<a href="{ROOT_URL}bookmarks/deleteBookmark/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,21 +0,0 @@
|
||||
<div class="panel panel-{color}">
|
||||
<div class="panel-heading" data-target="#Collapse{ID}" data-toggle="collapse" aria-expanded="true" aria-controls="#Collapse{ID}">
|
||||
{title}
|
||||
</div>
|
||||
<div id="Collapse{ID}" class="panel-collapse collapse in" style="width:100%; position: relative;" role="tabpanel" aria-expanded="true">
|
||||
<div class="panel-body">
|
||||
<ul class="list-group">
|
||||
{bookmarkListRows}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
<a href="{ROOT_URL}bookmarks/createBookmark/{ID}" class="btn btn-sm btn-success" role="button"><i class="glyphicon glyphicon-plus-sign"></i></a></td>
|
||||
<span class="pull-right">
|
||||
<a href="{ROOT_URL}bookmarks/bookmarks/{ID}" class="btn btn-sm btn-primary" role="button"><i class="glyphicon glyphicon-th-list"></i></a>
|
||||
<a href="{ROOT_URL}bookmarks/folders/{ID}" class="btn btn-sm btn-primary" role="button"><i class="glyphicon glyphicon-info-sign"></i></a></td>
|
||||
<a href="{ROOT_URL}bookmarks/editFolder/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a></td>
|
||||
<a href="{ROOT_URL}bookmarks/deleteFolder/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a></td>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,18 +0,0 @@
|
||||
|
||||
{LOOP}
|
||||
<li class="list-group-item list-group-item-{color}">
|
||||
<a href="{ROOT_URL}bookmarks/bookmarks/{ID}" class="btn btn-sm" role="button">{iconHtml}</a>
|
||||
<a href="{url}" class="list-group"> {title}</a>
|
||||
<span class="pull-right">
|
||||
{hideBtn}
|
||||
{archiveBtn}
|
||||
<a href="{ROOT_URL}bookmarks/editBookmark/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a>
|
||||
<a href="{ROOT_URL}bookmarks/deleteBookmark/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a>
|
||||
</span>
|
||||
</li>
|
||||
{/LOOP}
|
||||
{ALT}
|
||||
<li class="list-group-item">
|
||||
<a href="#" class="list-group">No Bookmarks</a>
|
||||
</li>
|
||||
{/ALT}
|
@ -1,10 +0,0 @@
|
||||
{LOOP}
|
||||
<div class="col-xlg-6 col-lg-6 col-md-6 col-sm-6 col-xs-6">
|
||||
{panel}
|
||||
</div>
|
||||
{/LOOP}
|
||||
{ALT}
|
||||
<div class="col-xlg-6 col-lg-6 col-md-6 col-sm-6 col-xs-6">
|
||||
<p>no folders</p>
|
||||
</div>
|
||||
{/ALT}
|
@ -1,16 +0,0 @@
|
||||
|
||||
{BookmarkBreadCrumbs}
|
||||
<div class="row">
|
||||
<div class="col-xlg-6 col-lg-6 col-md-6 col-sm-6 col-xs-6">
|
||||
<legend>Unsorted Bookmarks</legend>
|
||||
{bookmarksList}
|
||||
</div>
|
||||
<div class="col-xlg-6 col-lg-6 col-md-6 col-sm-6 col-xs-6">
|
||||
<legend>Folders List</legend>
|
||||
{foldersList}
|
||||
</div>
|
||||
</div>
|
||||
<legend>Folders</legend>
|
||||
<div class="row">
|
||||
{folderPanels}
|
||||
</div>
|
@ -1,39 +0,0 @@
|
||||
<legend>Create Folder</legend>
|
||||
{BookmarkBreadCrumbs}
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<div class="form-group">
|
||||
<label for="title" class="col-lg-3 control-label">Title</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="title" id="title">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description" class="col-lg-3 control-label">Description:</label>
|
||||
<div class="col-lg-3">
|
||||
<textarea class="form-control" name="description" maxlength="2000" rows="10" cols="50" id="description"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
{folderSelect}
|
||||
<div class="form-group">
|
||||
<label for="privacy" class="col-lg-3 control-label">Privacy</label>
|
||||
<div class="col-lg-3 select-container" id="colorContainer">
|
||||
<select id="privacy" name="privacy" class="form-control custom-select">
|
||||
<option value="private">Private</option>
|
||||
<option value="public">Public</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="color" class="col-lg-3 control-label">Color</label>
|
||||
<div class="col-lg-3 select-container" id="colorContainer">
|
||||
{colorSelect}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="submit" class="col-lg-3 control-label"></label>
|
||||
<div class="col-lg-3">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block ">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -1,39 +0,0 @@
|
||||
<legend>Edit Folder</legend>
|
||||
{BookmarkBreadCrumbs}
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<div class="form-group">
|
||||
<label for="title" class="col-lg-3 control-label">Title</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="title" id="title" value="{title}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description" class="col-lg-3 control-label">Description:</label>
|
||||
<div class="col-lg-3">
|
||||
<textarea class="form-control" name="description" maxlength="2000" rows="10" cols="50" id="description">{description}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
{folderSelect}
|
||||
<div class="form-group">
|
||||
<label for="privacy" class="col-lg-3 control-label">Privacy</label>
|
||||
<div class="col-lg-3 select-container" id="colorContainer">
|
||||
<select id="privacy" name="privacy" class="form-control custom-select" value="{privacy}">
|
||||
<option value="private">Private</option>
|
||||
<option value="public">Public</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="color" class="col-lg-3 control-label">Color</label>
|
||||
<div class="col-lg-3 select-container" id="colorContainer">
|
||||
{colorSelect}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="submit" class="col-lg-3 control-label"></label>
|
||||
<div class="col-lg-3">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block ">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -1,33 +0,0 @@
|
||||
{BookmarkBreadCrumbs}
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 35%">Title</th>
|
||||
<th style="width: 20%">Privacy</th>
|
||||
<th style="width: 30%">Description</th>
|
||||
<th style="width: 5%"></th>
|
||||
<th style="width: 5%"></th>
|
||||
<th style="width: 5%"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{LOOP}
|
||||
<tr>
|
||||
<td align="center">{title}</td>
|
||||
<td align="center">{privacy}</td>
|
||||
<td>{description}</td>
|
||||
<td><a href="{ROOT_URL}bookmarks/folders/{ID}" class="btn btn-sm btn-primary" role="button"><i class="glyphicon glyphicon-info-sign"></i></a></td>
|
||||
<td><a href="{ROOT_URL}bookmarks/editFolder/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a></td>
|
||||
<td><a href="{ROOT_URL}bookmarks/deleteFolder/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a></td>
|
||||
</tr>
|
||||
{/LOOP}
|
||||
{ALT}
|
||||
<tr>
|
||||
<td align="center" colspan="7">
|
||||
No results to show.
|
||||
</td>
|
||||
</tr>
|
||||
{/ALT}
|
||||
</tbody>
|
||||
</table>
|
||||
<a href="{ROOT_URL}bookmarks/createFolder" class="btn btn-sm btn-primary" role="button">Create</a>
|
@ -1,47 +0,0 @@
|
||||
{BookmarkBreadCrumbs}<br />
|
||||
<div class="container col-md-4 col-lg-4">
|
||||
<div class="row">
|
||||
<div class="panel panel-{color}">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">Bookmark Folder</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
<div class="">
|
||||
<table class="table table-user-primary">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="left" width="200"><b>Title</b></td>
|
||||
<td align="right">{title}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left" width="200"><b>Privacy</b></td>
|
||||
<td align="right">{privacy}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left" width="200"><b>Color</b></td>
|
||||
<td align="right">{color}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" colspan="2"><b>Description</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{description}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Created</b></td>
|
||||
<td align="right">{DTC}{createdAt}{/DTC}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
<a href="{ROOT_URL}bookmarks/bookmarks/{ID}" class="btn btn-sm btn-primary" role="button"><i class="glyphicon glyphicon-th-list"></i></a>
|
||||
<a href="{ROOT_URL}bookmarks/editFolder/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a>
|
||||
<a href="{ROOT_URL}bookmarks/deleteFolder/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,5 +0,0 @@
|
||||
<ul class="nav nav-tabs">
|
||||
<li><a href="{ROOT_URL}bookmarks/index/">Dashboard</a></li>
|
||||
<li><a href="{ROOT_URL}bookmarks/folders/">Folders</a></li>
|
||||
</ul>
|
||||
{userFolderTabs}
|
@ -1,9 +0,0 @@
|
||||
<ul class="nav nav-tabs">
|
||||
<li><a href="{ROOT_URL}bookmarks/folders/">All</a></li>
|
||||
{LOOP}
|
||||
<li><a href="{ROOT_URL}bookmarks/bookmarks/{ID}">{title}</a></li>
|
||||
{/LOOP}
|
||||
{ALT}
|
||||
<li></li>
|
||||
{/ALT}
|
||||
</ul>
|
@ -14,8 +14,8 @@ namespace TheTempusProject\Models;
|
||||
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Bedrock\Classes\Config;
|
||||
use TheTempusProject\Canary\Canary as Debug;
|
||||
use TheTempusProject\Bedrock\Classes\CustomException;
|
||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
||||
use TheTempusProject\Canary\Classes\CustomException;
|
||||
use TheTempusProject\Classes\DatabaseModel;
|
||||
use TheTempusProject\Plugins\Bugreport as Plugin;
|
||||
use TheTempusProject\TheTempusProject as App;
|
||||
|
@ -1,7 +0,0 @@
|
||||
<?php
|
||||
# bugTracker
|
||||
define( 'TRACKER_STATUS_IN_PROGRESS', 'In Progress' );
|
||||
define( 'TRACKER_STATUS_TESTING', 'Needs Testing' );
|
||||
define( 'TRACKER_STATUS_NEW', 'New' );
|
||||
define( 'TRACKER_STATUS_FIXED', 'Fixed' );
|
||||
define( 'TRACKER_STATUS_CLOSED', 'Closed' );
|
@ -1,206 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/bugtracker/controllers/admin/bugtracker.php
|
||||
*
|
||||
* This is the Bug-Tracker admin controller.
|
||||
*
|
||||
* @package TP BugTracker
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Controllers\Admin;
|
||||
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Bedrock\Functions\Upload;
|
||||
use TheTempusProject\Bedrock\Functions\Input;
|
||||
use TheTempusProject\Houdini\Classes\Issues;
|
||||
use TheTempusProject\Houdini\Classes\Views;
|
||||
use TheTempusProject\Houdini\Classes\Navigation;
|
||||
use TheTempusProject\Houdini\Classes\Components;
|
||||
use TheTempusProject\Houdini\Classes\Forms as FormGen;
|
||||
use TheTempusProject\Classes\AdminController;
|
||||
use TheTempusProject\Classes\Forms;
|
||||
use TheTempusProject\Models\Bugtracker as BugtrackerModel;
|
||||
use TheTempusProject\TheTempusProject as App;
|
||||
use TheTempusProject\Models\Comments;
|
||||
|
||||
class Bugtracker extends AdminController {
|
||||
protected static $tracker;
|
||||
protected static $comments;
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
self::$tracker = new BugtrackerModel;
|
||||
self::$title = 'Admin - Bug-Tracker';
|
||||
$view = Navigation::activePageSelect( 'nav.admin', '/admin/bugtracker' );
|
||||
Components::set( 'ADMINNAV', $view );
|
||||
}
|
||||
|
||||
public function index( $data = null ) {
|
||||
Views::view( 'bugtracker.admin.list', self::$tracker->list() );
|
||||
}
|
||||
|
||||
public function create( $data = null ) {
|
||||
$form = '';
|
||||
$form .= FormGen::getFormFieldHtml( 'title', 'Title', 'text', Input::post('title') );
|
||||
$form .= FormGen::getFormFieldHtml( 'description', 'Description', 'block', Input::post('description') );
|
||||
$form .= FormGen::getFormFieldHtml( 'bugImage', 'Screenshot', 'file', '' );
|
||||
$form .= FormGen::getFormFieldHtml( 'url', 'URL (if possible)', 'text', '' );
|
||||
$form .= FormGen::getFormFieldHtml( 'repeat', 'Has this happened more than once', 'radio' );
|
||||
Components::set( 'TRACKER_FORM', $form );
|
||||
if ( !Input::exists( 'submit' ) ) {
|
||||
return Views::view( 'bugtracker.admin.create' );
|
||||
}
|
||||
if ( !Forms::check( 'newBugTracker' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] );
|
||||
return Views::view( 'bugtracker.admin.create' );
|
||||
}
|
||||
$image = '';
|
||||
if ( Input::exists( 'bugImage' ) ) {
|
||||
$folder = IMAGE_UPLOAD_DIRECTORY . App::$activeUser->username . DIRECTORY_SEPARATOR;
|
||||
if ( !Upload::image( 'bugImage', $folder ) ) {
|
||||
Issues::add( 'error', [ 'There was an error with your upload.' => Check::systemErrors() ] );
|
||||
} else {
|
||||
$route = str_replace( APP_ROOT_DIRECTORY, '', $folder );
|
||||
$image = $route . Upload::last();
|
||||
}
|
||||
}
|
||||
$result = self::$tracker->create(
|
||||
App::$activeUser->ID,
|
||||
Input::post( 'url' ),
|
||||
$image,
|
||||
Input::post( 'repeat' ),
|
||||
Input::post( 'description' ),
|
||||
Input::post( 'title' ),
|
||||
);
|
||||
if ( $result ) {
|
||||
Issues::add( 'success', 'Your tracker has been created.' );
|
||||
return $this->index();
|
||||
} else {
|
||||
Issues::add( 'error', [ 'There was an unknown error submitting your data.' => Check::userErrors() ] );
|
||||
return $this->index();
|
||||
}
|
||||
}
|
||||
|
||||
public function edit( $data = null ) {
|
||||
if ( !Input::exists( 'submit' ) ) {
|
||||
$bug = self::$tracker->findById( $data );
|
||||
$statusList = [
|
||||
TRACKER_STATUS_IN_PROGRESS => TRACKER_STATUS_IN_PROGRESS,
|
||||
TRACKER_STATUS_TESTING => TRACKER_STATUS_TESTING,
|
||||
TRACKER_STATUS_NEW => TRACKER_STATUS_NEW,
|
||||
TRACKER_STATUS_FIXED => TRACKER_STATUS_FIXED,
|
||||
TRACKER_STATUS_CLOSED => TRACKER_STATUS_CLOSED,
|
||||
];
|
||||
$form = '';
|
||||
$form .= FormGen::getFormFieldHtml( 'title', 'Title', 'text', $bug->title );
|
||||
$form .= FormGen::getFormFieldHtml( 'description', 'Description', 'block', $bug->description );
|
||||
$form .= FormGen::getFormFieldHtml( 'bugImage', 'Screenshot', 'file', $bug->image );
|
||||
$form .= FormGen::getFormFieldHtml( 'url', 'Page you were on', 'text', $bug->url );
|
||||
$form .= FormGen::getFormFieldHtml( 'repeat', 'Has this happened more than once', 'radio', $bug->repeatable );
|
||||
$form .= FormGen::getFormFieldHtml( 'status', 'Status', 'customSelect', $bug->status, $statusList );
|
||||
Components::set( 'TRACKER_FORM', $form );
|
||||
return Views::view( 'bugtracker.admin.edit', $bug );
|
||||
}
|
||||
if ( !Forms::check( 'editBugTracker' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error with your form.' => Check::userErrors() ] );
|
||||
return $this->index();
|
||||
}
|
||||
$image = '';
|
||||
if ( Input::exists( 'bugImage' ) ) {
|
||||
$folder = IMAGE_UPLOAD_DIRECTORY . App::$activeUser->username . DIRECTORY_SEPARATOR;
|
||||
if ( !Upload::image( 'bugImage', $folder ) ) {
|
||||
Issues::add( 'error', [ 'There was an error with your upload.' => Check::systemErrors() ] );
|
||||
} else {
|
||||
$image = $folder . Upload::last();
|
||||
}
|
||||
}
|
||||
$tracker = self::$tracker->updateTracker(
|
||||
$data,
|
||||
Input::post( 'url' ),
|
||||
$image,
|
||||
Input::post( 'repeat' ),
|
||||
Input::post( 'description' ),
|
||||
Input::post( 'title' ),
|
||||
Input::post( 'status' )
|
||||
);
|
||||
if ( true === $tracker ) {
|
||||
Issues::add( 'success', 'Tracker Updated.' );
|
||||
return $this->index();
|
||||
}
|
||||
Issues::add( 'error', 'There was an error with your request.' );
|
||||
$this->index();
|
||||
}
|
||||
|
||||
public function view( $id = null ) {
|
||||
if ( empty( self::$comments ) ) {
|
||||
self::$comments = new Comments;
|
||||
}
|
||||
$data = self::$tracker->findById( $id );
|
||||
if ( $data === false ) {
|
||||
Issues::add( 'error', 'Tracker not found.' );
|
||||
return $this->index();
|
||||
}
|
||||
if ( Input::exists( 'contentId' ) ) {
|
||||
$this->comments( 'post', Input::post( 'contentId' ) );
|
||||
}
|
||||
if ( empty( self::$comments ) ) {
|
||||
self::$comments = new Comments;
|
||||
}
|
||||
Components::set( 'CONTENT_ID', $id );
|
||||
Components::set( 'COMMENT_TYPE', 'admin/bugtracker' );
|
||||
Components::set( 'count', self::$comments->count( 'tracker', $id ) );
|
||||
Components::set( 'NEWCOMMENT', Views::simpleView( 'comments.create' ) );
|
||||
Components::set( 'COMMENTS', Views::simpleView( 'comments.list', self::$comments->display( 10, 'tracker', $id ) ) );
|
||||
Views::view( 'bugtracker.admin.view', $data );
|
||||
}
|
||||
|
||||
public function delete( $data = null ) {
|
||||
if ( $data == null ) {
|
||||
if ( Input::exists( 'T_' ) ) {
|
||||
$data = Input::post( 'T_' );
|
||||
}
|
||||
}
|
||||
if ( !self::$tracker->delete( $data ) ) {
|
||||
Issues::add( 'error', 'There was an error with your request.' );
|
||||
} else {
|
||||
Issues::add( 'success', 'Tracker has been deleted' );
|
||||
}
|
||||
$this->index();
|
||||
}
|
||||
|
||||
public function comments( $sub = null, $data = null ) {
|
||||
if ( empty( self::$comments ) ) {
|
||||
self::$comments = new Comments;
|
||||
}
|
||||
if ( empty( $sub ) || empty( $data ) ) {
|
||||
Session::flash( 'error', 'Whoops, try again.' );
|
||||
Redirect::to( 'admin/bugtracker' );
|
||||
}
|
||||
switch ( $sub ) {
|
||||
case 'post':
|
||||
$content = self::$tracker->findById( $data );
|
||||
if ( empty( $content ) ) {
|
||||
Session::flash( 'error', 'Unknown Post.' );
|
||||
Redirect::to( 'admin/bugtracker' );
|
||||
}
|
||||
return self::$comments->formPost( 'tracker', $content, 'admin/bugtracker/view/' );
|
||||
case 'edit':
|
||||
$content = self::$comments->findById( $data );
|
||||
if ( empty( $content ) ) {
|
||||
Session::flash( 'error', 'Unknown Comment.' );
|
||||
Redirect::to( 'admin/bugtracker' );
|
||||
}
|
||||
return self::$comments->formEdit( 'tracker', $content, 'admin/bugtracker/view/' );
|
||||
case 'delete':
|
||||
$content = self::$comments->findById( $data );
|
||||
if ( empty( $content ) ) {
|
||||
Session::flash( 'error', 'Unknown Comment.' );
|
||||
Redirect::to( 'admin/bugtracker' );
|
||||
}
|
||||
return self::$comments->formDelete( 'tracker', $content, 'admin/bugtracker/view/' );
|
||||
}
|
||||
}
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/bugtracker/forms.php
|
||||
*
|
||||
* This houses all of the form checking functions for this plugin.
|
||||
*
|
||||
* @package TP BugTracker
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Plugins\Bugreport;
|
||||
|
||||
use TheTempusProject\Bedrock\Functions\Input;
|
||||
use TheTempusProject\Classes\Forms;
|
||||
|
||||
class BugTrackerForms extends Forms {
|
||||
/**
|
||||
* Adds these functions to the form list.
|
||||
*/
|
||||
public function __construct() {
|
||||
self::addHandler( 'newBugTracker', __CLASS__, 'newBugTracker' );
|
||||
self::addHandler( 'editBugTracker', __CLASS__, 'editBugTracker' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the bug tracker create form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function newBugTracker() {
|
||||
if ( !empty(Input::post( 'url' )) && !self::url( Input::post( 'url' ) ) ) {
|
||||
self::addUserError( 'Invalid url: <code>' . Input::post( 'url' ) . '</code>' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::tf( Input::post( 'repeat' ) ) ) {
|
||||
self::addUserError( 'Invalid repeat value: ' . Input::post( 'repeat' ) );
|
||||
return false;
|
||||
}
|
||||
if ( !Input::exists( 'title' ) ) {
|
||||
self::addUserError( 'You must specify title' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::dataTitle( Input::post( 'title' ) ) ) {
|
||||
self::addUserError( 'Invalid title' );
|
||||
return false;
|
||||
}
|
||||
if ( !Input::exists( 'description' ) ) {
|
||||
self::addUserError( 'You must specify a description' );
|
||||
return false;
|
||||
}
|
||||
// if ( !self::token() ) {
|
||||
// return false;
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the bug tracker create form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function editBugTracker() {
|
||||
if ( !empty(Input::post( 'url' )) && !self::url( Input::post( 'url' ) ) ) {
|
||||
self::addUserError( 'Invalid url.' . Input::post( 'url' ) );
|
||||
return false;
|
||||
}
|
||||
if ( !self::tf( Input::post( 'repeat' ) ) ) {
|
||||
self::addUserError( 'Invalid repeat value.' );
|
||||
return false;
|
||||
}
|
||||
if ( !Input::exists( 'title' ) ) {
|
||||
self::addUserError( 'You must specify title' );
|
||||
return false;
|
||||
}
|
||||
if ( !self::dataTitle( Input::post( 'title' ) ) ) {
|
||||
self::addUserError( 'Invalid title' );
|
||||
return false;
|
||||
}
|
||||
if ( !Input::exists( 'description' ) ) {
|
||||
self::addUserError( 'You must specify a description' );
|
||||
return false;
|
||||
}
|
||||
// if ( !self::token() ) {
|
||||
// return false;
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
new BugTrackerForms;
|
@ -1,142 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/bugtracker/models/bugtracker.php
|
||||
*
|
||||
* This class is used for the manipulation of the bugs database table.
|
||||
*
|
||||
* @package TP BugTracker
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Models;
|
||||
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Bedrock\Classes\Config;
|
||||
use TheTempusProject\Canary\Canary as Debug;
|
||||
use TheTempusProject\Bedrock\Classes\CustomException;
|
||||
use TheTempusProject\Classes\DatabaseModel;
|
||||
use TheTempusProject\TheTempusProject as App;
|
||||
use TheTempusProject\Plugins\Bugtracker as Plugin;
|
||||
|
||||
class Bugtracker extends DatabaseModel {
|
||||
public $tableName = 'bugs';
|
||||
public $databaseMatrix = [
|
||||
[ 'userID', 'int', '11' ],
|
||||
[ 'time', 'int', '10' ],
|
||||
[ 'title', 'varchar', '128' ],
|
||||
[ 'status', 'varchar', '64' ],
|
||||
[ 'description', 'text', '' ],
|
||||
[ 'image', 'varchar', '256' ],
|
||||
[ 'repeatable', 'varchar', '5' ],
|
||||
[ 'url', 'varchar', '256' ],
|
||||
];
|
||||
public $plugin;
|
||||
|
||||
/**
|
||||
* The model constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
$this->plugin = new Plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function parses the bug reports description and
|
||||
* separates it into separate keys in the array.
|
||||
*
|
||||
* @param array $data - The data being parsed.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function filter( $data, $params = [] ) {
|
||||
foreach ( $data as $instance ) {
|
||||
if ( !is_object( $instance ) ) {
|
||||
$instance = $data;
|
||||
$end = true;
|
||||
}
|
||||
$instance->submittedBy = self::$user->getUsername( $instance->userID );
|
||||
$instance->repeatText = ( 'false' == $instance->repeatable ? 'no' : 'yes' );
|
||||
$out[] = $instance;
|
||||
if ( !empty( $end ) ) {
|
||||
$out = $out[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a Bug Report form.
|
||||
*
|
||||
* @param int $ID the user ID submitting the form
|
||||
* @param string $url the url
|
||||
* @param string $o_url the original url
|
||||
* @param int $repeat is repeatable?
|
||||
* @param string $description_ description of the event.
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function create( $ID, $url, $image, $repeat, $description, $title ) {
|
||||
if ( !$this->plugin->checkEnabled() ) {
|
||||
Debug::info( 'Bug Tracking is disabled in the config.' );
|
||||
return false;
|
||||
}
|
||||
if ( !Check::dataTitle( $title ) ) {
|
||||
Debug::info( 'bugTracker: illegal title.' );
|
||||
return false;
|
||||
}
|
||||
$fields = [
|
||||
'userID' => App::$activeUser->ID,
|
||||
'time' => time(),
|
||||
'title' => $title,
|
||||
'status' => TRACKER_STATUS_NEW,
|
||||
'description' => $description,
|
||||
'image' => $image,
|
||||
'repeatable' => $repeat,
|
||||
'url' => $url,
|
||||
];
|
||||
if ( !self::$db->insert( $this->tableName, $fields ) ) {
|
||||
new CustomException( $this->tableName );
|
||||
return false;
|
||||
}
|
||||
return self::$db->lastId();
|
||||
}
|
||||
|
||||
public function updateTracker( $ID, $url, $image, $repeat, $description, $title, $status ) {
|
||||
if ( !$this->plugin->checkEnabled() ) {
|
||||
Debug::info( 'Bug Tracking is disabled in the config.' );
|
||||
return false;
|
||||
}
|
||||
if ( empty( self::$log ) ) {
|
||||
self::$log = new Log;
|
||||
}
|
||||
if ( !Check::id( $ID ) ) {
|
||||
Debug::info( 'bugTracker: illegal ID.' );
|
||||
return false;
|
||||
}
|
||||
if ( !Check::dataTitle( $title ) ) {
|
||||
Debug::info( 'bugTracker: illegal title.' );
|
||||
return false;
|
||||
}
|
||||
$fields = [
|
||||
'url' => $url,
|
||||
'description' => $description,
|
||||
'repeatable' => $repeat,
|
||||
'title' => $title,
|
||||
'status' => $status,
|
||||
];
|
||||
if ( !empty( $image ) ) {
|
||||
$fields['image'] = $image;
|
||||
}
|
||||
if ( !self::$db->update( $this->tableName, $ID, $fields ) ) {
|
||||
new CustomException( $this->tableName );
|
||||
Debug::error( "Tracker Post: $ID not updated: $fields" );
|
||||
|
||||
return false;
|
||||
}
|
||||
self::$log->admin( "Updated Tracker Post: $ID" );
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/bugtracker/plugin.php
|
||||
*
|
||||
* This houses all of the main plugin info and functionality.
|
||||
*
|
||||
* @package TP BugTracker
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Plugins;
|
||||
|
||||
use ReflectionClass;
|
||||
use TheTempusProject\Classes\Installer;
|
||||
use TheTempusProject\Houdini\Classes\Navigation;
|
||||
use TheTempusProject\Classes\Plugin;
|
||||
use TheTempusProject\TheTempusProject as App;
|
||||
|
||||
class Bugtracker extends Plugin {
|
||||
public $pluginName = 'TP BugTracker';
|
||||
public $pluginAuthor = 'JoeyK';
|
||||
public $pluginWebsite = 'https://TheTempusProject.com';
|
||||
public $modelVersion = '1.0';
|
||||
public $pluginVersion = '3.0';
|
||||
public $pluginDescription = '';
|
||||
public $configName = 'bugtracker';
|
||||
public $configMatrix = [
|
||||
'enabled' => [
|
||||
'type' => 'radio',
|
||||
'pretty' => 'Enable Bug tracking.',
|
||||
'default' => true,
|
||||
],
|
||||
];
|
||||
public $permissionMatrix = [
|
||||
'bugTrack' => [
|
||||
'pretty' => 'Can Track Bugs',
|
||||
'default' => false,
|
||||
],
|
||||
];
|
||||
public $admin_links = [
|
||||
[
|
||||
'text' => '<i class="fa fa-fw fa-bug"></i> Bug Tracker',
|
||||
'url' => '{ROOT_URL}admin/bugtracker',
|
||||
],
|
||||
];
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
<form action="" method="post" class="form-horizontal" enctype="multipart/form-data">
|
||||
<legend>Create Bug Tracker</legend>
|
||||
{TRACKER_FORM}
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block">Save</button><br>
|
||||
</form>
|
@ -1,30 +0,0 @@
|
||||
<legend>New Bugs</legend>
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 20%"></th>
|
||||
<th style="width: 65%"></th>
|
||||
<th style="width: 5%"></th>
|
||||
<th style="width: 5%"></th>
|
||||
<th style="width: 5%"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{LOOP}
|
||||
<tr>
|
||||
<td>{title}</td>
|
||||
<td>{description}</td>
|
||||
<td><a href="{ROOT_URL}admin/bugtracker/view/{ID}" class="btn btn-sm btn-primary" role="button"><i class="glyphicon glyphicon-open"></i></a></td>
|
||||
<td><a href="{ROOT_URL}admin/bugtracker/edit/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a></td>
|
||||
<td width="30px"><a href="{ROOT_URL}admin/bugtracker/delete/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a></td>
|
||||
</tr>
|
||||
{/LOOP}
|
||||
{ALT}
|
||||
<tr>
|
||||
<td align="center" colspan="5">
|
||||
No results to show.
|
||||
</td>
|
||||
</tr>
|
||||
{/ALT}
|
||||
</tbody>
|
||||
</table>
|
@ -1,6 +0,0 @@
|
||||
<form action="" method="post" class="form-horizontal" enctype="multipart/form-data">
|
||||
<legend>Edit Bug Tracker</legend>
|
||||
{TRACKER_FORM}
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block">Save</button><br>
|
||||
</form>
|
@ -1,45 +0,0 @@
|
||||
<legend>Bug Trackers</legend>
|
||||
{PAGINATION}
|
||||
<form action="{ROOT_URL}admin/bugtracker/delete" method="post">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 30%">Title</th>
|
||||
<th style="width: 40%">Description</th>
|
||||
<th style="width: 10%">Status</th>
|
||||
<th style="width: 5%">Time Submitted</th>
|
||||
<th style="width: 5%"></th>
|
||||
<th style="width: 5%"></th>
|
||||
<th style="width: 5%">
|
||||
<INPUT type="checkbox" onchange="checkAll(this)" name="check.br" value="T_[]"/>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{LOOP}
|
||||
<tr>
|
||||
<td><a href="{ROOT_URL}admin/bugtracker/view/{ID}">{title}</a></td>
|
||||
<td>{description}</td>
|
||||
<td>{status}</td>
|
||||
<td align="center">{DTC}{time}{/DTC}</td>
|
||||
<td><a href="{ROOT_URL}admin/bugtracker/edit/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a></td>
|
||||
<td><a href="{ROOT_URL}admin/bugtracker/delete/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a></td>
|
||||
<td>
|
||||
<input type="checkbox" value="{ID}" name="T_[]">
|
||||
</td>
|
||||
</tr>
|
||||
{/LOOP}
|
||||
{ALT}
|
||||
<tr>
|
||||
<td align="center" colspan="7">
|
||||
No results to show.
|
||||
</td>
|
||||
</tr>
|
||||
{/ALT}
|
||||
</tbody>
|
||||
</table>
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-sm btn-danger">Delete</button>
|
||||
<a href="{ROOT_URL}admin/bugtracker/create" class="btn btn-sm btn-primary" role="button">Create</a>
|
||||
</form>
|
||||
<br />
|
||||
<a href="{ROOT_URL}admin/bugtracker/clear">clear all</a>
|
@ -1,74 +0,0 @@
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-12 col-md-6 col-lg-6 col-xs-offset-0 col-sm-offset-0 col-md-offset-3 col-lg-offset-3 top-pad" >
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">Bug Tracker</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
<div class=" col-md-12 col-lg-12 ">
|
||||
<table class="table table-user-primary">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="center" colspan="2">Title</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{title}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" colspan="2">Description</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{description}</td>
|
||||
</tr>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div align="center">
|
||||
<a href="{ROOT_URL}{image}"><img alt="Screenshot" src="{ROOT_URL}{image}" class="img-responsive"></a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left" width="200">Status</td>
|
||||
<td align="right">{status}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left" width="200">ID</td>
|
||||
<td align="right">{ID}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Time submitted</td>
|
||||
<td align="right">{DTC}{time}{/DTC}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Submitted by</td>
|
||||
<td align="right"><a href="{ROOT_URL}admin/users/view/{userID}">{submittedBy}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>URL:</td>
|
||||
<td align="right">{URL}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Multiple occurrences?</td>
|
||||
<td align="right">{repeatText}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
{ADMIN}
|
||||
<a href="{ROOT_URL}admin/bugtracker/delete/{ID}" class="btn btn-md btn-danger" role="button">Delete</a>
|
||||
<a href="{ROOT_URL}admin/bugtracker/edit/{ID}" class="btn btn-md btn-warning" role="button">Edit</a>
|
||||
<a href="{ROOT_URL}admin/comments/tracker/{ID}" class="btn btn-md btn-primary" role="button">View Comments</a>
|
||||
{/ADMIN}
|
||||
</div>
|
||||
</div>
|
||||
{COMMENTS}
|
||||
{NEWCOMMENT}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,593 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/calendar/controllers/calendar.php
|
||||
*
|
||||
* This is the calendar controller.
|
||||
*
|
||||
* @package TP Calendar
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Controllers;
|
||||
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Bedrock\Functions\Input;
|
||||
use TheTempusProject\Bedrock\Functions\Session;
|
||||
use TheTempusProject\Bedrock\Functions\Date;
|
||||
use TheTempusProject\Classes\Controller;
|
||||
use TheTempusProject\Houdini\Classes\Forms as HoudiniForms;
|
||||
use TheTempusProject\Classes\Forms;
|
||||
use TheTempusProject\Houdini\Classes\Issues;
|
||||
use TheTempusProject\Houdini\Classes\Views;
|
||||
use TheTempusProject\Houdini\Classes\Template;
|
||||
use TheTempusProject\Houdini\Classes\Components;
|
||||
use TheTempusProject\Hermes\Functions\Redirect;
|
||||
use TheTempusProject\TheTempusProject as App;
|
||||
use TheTempusProject\Models\Events;
|
||||
use TheTempusProject\Models\Calendars;
|
||||
use TheTempusProject\Houdini\Classes\Navigation;
|
||||
|
||||
class Calendar extends Controller {
|
||||
protected static $events;
|
||||
protected static $calendars;
|
||||
protected static $defaultView;
|
||||
protected static $defaultCalendar;
|
||||
protected static $selectedDate;
|
||||
|
||||
public function __construct() {
|
||||
if ( !App::$isLoggedIn ) {
|
||||
Session::flash( 'notice', 'You must be logged in to create or manage calendars.' );
|
||||
return Redirect::home();
|
||||
}
|
||||
parent::__construct();
|
||||
self::$title = 'Calendar - {SITENAME}';
|
||||
self::$pageDescription = 'The {SITENAME} calendar is where you can find various features for creating and managing events and schedules.';
|
||||
self::$events = new Events;
|
||||
self::$calendars = new Calendars;
|
||||
|
||||
$prefs = App::$activePrefs;
|
||||
if ( ! empty( $prefs['calendarPreference'] ) ) {
|
||||
$view = $prefs['calendarPreference'];
|
||||
} else {
|
||||
Session::flash( 'info', 'You can select a default view for this page in your user settings in the top right.' );
|
||||
$view = 'byMonth';
|
||||
}
|
||||
self::$defaultView = $view;
|
||||
self::$selectedDate = intval( strtotime( Date::determineDateInput() ) );
|
||||
|
||||
Template::setTemplate( 'calendar' );
|
||||
|
||||
// Date Dropdown
|
||||
$dateDropdownView = Views::simpleView('calendar.nav.dateDropdown', Date::getDateBreakdown( self::$selectedDate ) );
|
||||
Components::set( 'dateDropdown', $dateDropdownView );
|
||||
|
||||
// Calendar Top Tabs
|
||||
$calendarTabs = Views::simpleView('calendar.nav.topTabs');
|
||||
$tabsView = Navigation::activePageSelect( $calendarTabs, Input::get( 'url' ), false, true );
|
||||
// must be done after top-nav gets selected
|
||||
$calendarDropdown = Views::simpleView('calendar.nav.calendarDropdown', self::$calendars->simpleObjectByUser() );
|
||||
$calendarDropdownView = Navigation::activePageSelect( $calendarDropdown, Input::get( 'url' ), false, true ); // add notebookID as second param
|
||||
Components::set( 'calendarDropdown', $calendarDropdownView);
|
||||
// must be done after dropdown gets added
|
||||
Components::set( 'CalendarNav', Template::parse( $calendarTabs ) );
|
||||
}
|
||||
public function index() {
|
||||
if ( method_exists( $this, self::$defaultView ) ) {
|
||||
Redirect::to( 'calendar/'.self::$defaultView.'/' );
|
||||
} else {
|
||||
Redirect::to( 'calendar/byMonth/' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Events
|
||||
*/
|
||||
public function event( $id = null ) {
|
||||
$event = $this->findEventOrFail( $id );
|
||||
Views::view( 'calendar.events.view', $event );
|
||||
}
|
||||
public function createEvent() {
|
||||
// get the url calendar input
|
||||
$newCalendar = Input::get('calendar_id') ? Input::get('calendar_id') : '';// for loading the form
|
||||
$calendarSelect = HoudiniForms::getFormFieldHtml( 'calendar_id', 'Calendar', 'select', $newCalendar, self::$calendars->simpleByUser() );
|
||||
Components::set( 'calendarSelect', $calendarSelect );
|
||||
|
||||
$repeatSelect = HoudiniForms::getFormFieldHtml( 'repeats', 'Frequency', 'select', 'none', self::$events->repeatOptions );
|
||||
Components::set( 'repeatSelect', $repeatSelect );
|
||||
|
||||
$dateSelect = Views::simpleView( 'calendar.dateSelect', $this->getEventBreakdown( self::$selectedDate ) );
|
||||
Components::set( 'dateSelect', $dateSelect );
|
||||
|
||||
if ( ! Input::exists() ) {
|
||||
return Views::view( 'calendar.events.create' );
|
||||
}
|
||||
|
||||
/** Attempt to save the form data somewhat */
|
||||
// get the form calendar input
|
||||
$calendarID = Input::post('calendar_id') ? Input::post('calendar_id') : ''; // for submitting the form
|
||||
$calendarSelect = HoudiniForms::getFormFieldHtml( 'calendar_id', 'Calendar', 'select', $calendarID, self::$calendars->simpleByUser() );
|
||||
Components::set( 'calendarSelect', $calendarSelect );
|
||||
|
||||
$repeatSelect = HoudiniForms::getFormFieldHtml( 'repeats', 'Frequency', 'select', Input::post('repeats'), self::$events->repeatOptions );
|
||||
Components::set( 'repeatSelect', $repeatSelect );
|
||||
|
||||
if ( ! Forms::check( 'createEvent' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error with your form.' => Check::userErrors() ] );
|
||||
return Views::view( 'calendar.events.create' );
|
||||
}
|
||||
|
||||
$event_id = self::$events->create(
|
||||
$calendarID,
|
||||
Input::post('title'),
|
||||
Date::applyUtcToDate( Date::determineDateInput() ),
|
||||
Input::post('description'),
|
||||
Input::post('location'),
|
||||
Input::post('repeats'),
|
||||
Input::post('color'),
|
||||
0,
|
||||
);
|
||||
if ( ! $event_id ) {
|
||||
Issues::add( 'error', [ 'There was an error creating your event.' => Check::userErrors() ] );
|
||||
return Views::view( 'calendar.events.create' );
|
||||
}
|
||||
|
||||
if ( Input::post('repeats') != 'none' ) {
|
||||
$childrens = self::$events->generateChildEvents( $event_id, true, true );
|
||||
}
|
||||
|
||||
Session::flash( 'success', 'Your Event has been created.' );
|
||||
Redirect::to( 'calendar/'.self::$defaultView.'/'. $calendarID );
|
||||
}
|
||||
public function editEvent( $id = null ) {
|
||||
$calendar = Input::exists('calendar_id') ? Input::post('calendar_id') : '';
|
||||
$event = self::$events->findById( $id );
|
||||
$readableDate = date('Y-m-d H:i:s', $event->event_time);
|
||||
|
||||
if ( $event == false ) {
|
||||
Session::flash( 'error', 'Event not found.' );
|
||||
return Redirect::to( 'calendar/'.self::$defaultView.'/' );
|
||||
}
|
||||
if ( $event->createdBy != App::$activeUser->ID ) {
|
||||
Session::flash( 'error', 'You do not have permission to modify this event.' );
|
||||
return Redirect::to( 'calendar/'.self::$defaultView.'/' );
|
||||
}
|
||||
|
||||
$repeatSelect = HoudiniForms::getFormFieldHtml( 'repeats', 'Frequency', 'select', $event->repeats, self::$events->repeatOptions );
|
||||
Components::set( 'repeatSelect', $repeatSelect );
|
||||
|
||||
// there should be a way to do this natively
|
||||
$event_at = Date::getDateBreakdown( $event->event_time, true );
|
||||
|
||||
// $readableDate = date('Y-m-d H:i:s', $readableDate);
|
||||
$dateSelect = Views::simpleView( 'calendar.dateSelect', $event_at );
|
||||
Components::set( 'dateSelect', $dateSelect );
|
||||
Components::set( 'color', $event->color );
|
||||
|
||||
if ( ! Input::exists( 'submit' ) ) {
|
||||
return Views::view( 'calendar.events.edit', $event );
|
||||
}
|
||||
if ( ! Forms::check( 'editEvent' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error updating your event.' => Check::userErrors() ] );
|
||||
return Views::view( 'calendar.events.edit', $event );
|
||||
}
|
||||
$result = self::$events->update(
|
||||
$id,
|
||||
Input::post('title'),
|
||||
Date::applyUtcToDate( Date::determineDateInput() ),
|
||||
Input::post('description'),
|
||||
Input::post('location'),
|
||||
Input::post('repeats'),
|
||||
Input::post('color'),
|
||||
);
|
||||
|
||||
if ( Input::post('repeats') != 'none' && $event->parent_id == 0 ) {
|
||||
$childrens = self::$events->generateChildEvents( $event->ID, true, true );
|
||||
}
|
||||
|
||||
if ( ! $result ) {
|
||||
Issues::add( 'error', [ 'There was an error updating your event.' => Check::userErrors() ] );
|
||||
return Views::view( 'calendar.events.edit', $event->ID );
|
||||
}
|
||||
Session::flash( 'success', 'Your Event has been updated.' );
|
||||
Redirect::to( 'calendar/'.self::$defaultView.'/'. $event->calendar_id );
|
||||
}
|
||||
public function deleteEvent( $id = null ) {
|
||||
$event = self::$events->findById( $id );
|
||||
if ( $event == false ) {
|
||||
Issues::add( 'error', 'Event not found.' );
|
||||
return $this->index();
|
||||
}
|
||||
if ( $event->createdBy != App::$activeUser->ID ) {
|
||||
Issues::add( 'error', 'You do not have permission to modify this event.' );
|
||||
return $this->index();
|
||||
}
|
||||
$result = self::$events->delete( $id );
|
||||
if ( !$result ) {
|
||||
Session::flash( 'error', 'There was an error deleting the event(s)' );
|
||||
} else {
|
||||
Session::flash( 'success', 'Event deleted' );
|
||||
}
|
||||
return $this->index();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calendars
|
||||
*/
|
||||
public function calendar( $id = null ) {
|
||||
$calendar = $this->findCalendarOrFail( $id );
|
||||
Views::view( 'calendar.calendar.view', $calendar );
|
||||
}
|
||||
public function createCalendar() {
|
||||
$timezoneSelect = HoudiniForms::getTimezoneHtml( Date::getTimezone() );
|
||||
Components::set( 'timezoneSelect', $timezoneSelect );
|
||||
if ( ! Input::exists() ) {
|
||||
return Views::view( 'calendar.calendar.create' );
|
||||
}
|
||||
if ( ! Forms::check( 'createCalendar' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error creating your calendar111.' => Check::userErrors() ] );
|
||||
return Views::view( 'calendar.calendar.create' );
|
||||
}
|
||||
$calendar = self::$calendars->create( Input::post('title'), Input::post('description'), Input::post('timezone'), Input::post('color') );
|
||||
if ( ! $calendar ) {
|
||||
return Views::view( 'calendar.calendar.create' );
|
||||
}
|
||||
Session::flash( 'success', 'Your Calendar has been created.' );
|
||||
Redirect::to( 'calendar/'.self::$defaultView.'/');
|
||||
}
|
||||
public function editCalendar( $id = null ) {
|
||||
$calendar = $this->findCalendarOrFail( $id );
|
||||
|
||||
$timezoneSelect = HoudiniForms::getTimezoneHtml( Date::getTimezone() );
|
||||
Components::set( 'timezoneSelect', $timezoneSelect );
|
||||
Components::set( 'color', $calendar->color );
|
||||
|
||||
if ( ! Input::exists( 'submit' ) ) {
|
||||
return Views::view( 'calendar.calendar.edit', $calendar );
|
||||
}
|
||||
|
||||
if ( !Forms::check( 'editCalendar' ) ) {
|
||||
Issues::add( 'error', [ 'There was an error editing your calendar.' => Check::userErrors() ] );
|
||||
return Views::view( 'calendar.calendar.edit', $calendar );
|
||||
}
|
||||
$result = self::$calendars->update( $id, Input::post('title'), Input::post('description'), Input::post('timezone'), Input::post('color') );
|
||||
if ( !$result ) {
|
||||
Issues::add( 'error', [ 'There was an error updating your calendar.' => Check::userErrors() ] );
|
||||
return Views::view( 'calendar.calendar.edit', $calendar );
|
||||
}
|
||||
Session::flash( 'success', 'Your Calendar has been updated.' );
|
||||
Redirect::to( 'calendar/'.self::$defaultView.'/'. $calendar->ID );
|
||||
}
|
||||
public function deleteCalendar( $id = null ) {
|
||||
$calendar = self::$calendars->findById( $id );
|
||||
if ( $calendar == false ) {
|
||||
Issues::add( 'error', 'Calendar not found.' );
|
||||
return $this->index();
|
||||
}
|
||||
if ( $calendar->createdBy != App::$activeUser->ID ) {
|
||||
Issues::add( 'error', 'You do not have permission to modify this calendar.' );
|
||||
return $this->index();
|
||||
}
|
||||
$results = self::$events->deleteByCalendar( $id );
|
||||
$result = self::$calendars->delete( $id );
|
||||
if ( !$result ) {
|
||||
Session::flash( 'error', 'There was an error deleting the calendar(s)' );
|
||||
} else {
|
||||
Session::flash( 'success', 'Calendar deleted' );
|
||||
}
|
||||
Redirect::to( 'calendar/'.self::$defaultView.'/' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Views
|
||||
*/
|
||||
public function byDay( $id = 0 ) {
|
||||
// Set base components
|
||||
Components::set( 'currentView', __FUNCTION__ );
|
||||
Components::set( 'calendarID', $id );
|
||||
|
||||
// Set components for next / back arrows
|
||||
$nextDayMonth = date( 'M', strtotime( 'tomorrow', self::$selectedDate ) );
|
||||
$nextDay = date( 'd', strtotime( 'tomorrow', self::$selectedDate ) );
|
||||
$lastDayMonth = date( 'M', strtotime( 'yesterday', self::$selectedDate ) );
|
||||
$lastDay = date( 'd', strtotime( 'yesterday', self::$selectedDate ) );
|
||||
Components::set( 'nextDayMonth', $nextDayMonth );
|
||||
Components::set( 'nextDay', $nextDay );
|
||||
Components::set( 'lastDayMonth', $lastDayMonth );
|
||||
Components::set( 'lastDay', $lastDay );
|
||||
|
||||
// Get the data
|
||||
$dayArray = self::$events->dayArray( $id, self::$selectedDate );
|
||||
|
||||
// build the results
|
||||
$selectedHour = Date::getCurrentHour();
|
||||
$day = date( 'd', self::$selectedDate );
|
||||
$month = date( 'M', self::$selectedDate );
|
||||
$year = date( 'Y', self::$selectedDate );
|
||||
$fullDay = [];
|
||||
foreach ( $dayArray as $hour => $events ) {
|
||||
Components::set( 'hour', $hour );
|
||||
$hourCell = new \stdClass();
|
||||
$hourCell->hour = $hour;
|
||||
if ( $hour == $selectedHour ) {
|
||||
$hourCell->hourSelected = ' hour-active';
|
||||
} else {
|
||||
$hourCell->hourSelected = '';
|
||||
}
|
||||
$hourCell->day = $day;
|
||||
$hourCell->month = $month;
|
||||
$hourCell->year = $year;
|
||||
$hourCell->EventCells = Views::simpleView( 'calendar.nav.row', $events );
|
||||
$fullDay[] = $hourCell;
|
||||
}
|
||||
|
||||
// Calendar Top Tabs
|
||||
Components::unset( 'calendarDropdown');
|
||||
$calendarTabs = Views::simpleView('calendar.nav.topTabs');
|
||||
$tabsView = Navigation::activePageSelect( $calendarTabs, '/calendar/byDay/', false, true );
|
||||
// must be done after top-nav gets selected
|
||||
$calendarDropdown = Views::simpleView('calendar.nav.calendarDropdown', self::$calendars->simpleObjectByUser() );
|
||||
$calendarDropdownView = Navigation::activePageSelect( $calendarDropdown, Input::get( 'url' ), false, true ); // add notebookID as second param
|
||||
Components::set( 'calendarDropdown', $calendarDropdownView);
|
||||
Components::set( 'CalendarNav', Template::parse( $tabsView ) );
|
||||
|
||||
Components::set( 'activeDate', date( 'F d, Y', self::$selectedDate ) );
|
||||
Views::view( 'calendar.byDay', $fullDay );
|
||||
}
|
||||
public function byWeek( $id = 0 ) {
|
||||
// Set base components
|
||||
Components::set( 'currentView', __FUNCTION__ );
|
||||
Components::set( 'calendarID', $id );
|
||||
|
||||
// Set components for next / back arrows
|
||||
$lastWeekMonth = date( 'M', strtotime( '-7 days', self::$selectedDate) );
|
||||
$lastWeekDay = date( 'd', strtotime( '-7 days', self::$selectedDate) );
|
||||
$lastWeekYear = date( 'Y', strtotime( '-7 days', self::$selectedDate) );
|
||||
$nextWeekMonth = date( 'M', strtotime( '+7 days', self::$selectedDate) );
|
||||
$nextWeekDay = date( 'd', strtotime( '+7 days', self::$selectedDate) );
|
||||
$nextWeekYear = date( 'Y', strtotime( '+7 days', self::$selectedDate) );
|
||||
Components::set( 'lastWeekMonth', $lastWeekMonth );
|
||||
Components::set( 'lastWeek', $lastWeekDay );
|
||||
Components::set( 'lastYear', $lastWeekYear );
|
||||
Components::set( 'nextWeekMonth', $nextWeekMonth );
|
||||
Components::set( 'nextWeek', $nextWeekDay );
|
||||
Components::set( 'nextYear', $nextWeekYear );
|
||||
|
||||
// Get the data
|
||||
$weekArray = self::$events->weekArray( $id, self::$selectedDate );
|
||||
|
||||
// build the results
|
||||
$presentMonth = date( 'F', self::$selectedDate );
|
||||
$presentDay = date( 'd', self::$selectedDate );
|
||||
foreach ( $weekArray as $week => $days ) {
|
||||
$weekFormat = [];
|
||||
foreach ( $days as $day => $events ) {
|
||||
if ( empty( $first ) ) {
|
||||
$first = true;
|
||||
if ( intval( $presentDay ) >= $day ) {
|
||||
$month = date( 'F', self::$selectedDate );
|
||||
} else {
|
||||
$month = date( 'F', strtotime( '-7 days', self::$selectedDate ) );
|
||||
}
|
||||
}
|
||||
if ( $day == '01' ) {
|
||||
$month = date( 'F', strtotime( '+7 days', self::$selectedDate ) );
|
||||
}
|
||||
Components::set( 'currentMonth', $month );
|
||||
Components::set( 'currentDay', $day );
|
||||
$dayCell = new \stdClass();
|
||||
if ( $presentDay == $day && $presentMonth == $month ) {
|
||||
$dayCell->highlightedDate = ' today';
|
||||
} else {
|
||||
$dayCell->highlightedDate = '';
|
||||
}
|
||||
$dayCell->day = $day;
|
||||
$dayCell->dayEventList = Views::simpleView( 'calendar.nav.cell', $events );
|
||||
$weekFormat[] = $dayCell;
|
||||
}
|
||||
$weekView = Views::simpleView( 'calendar.nav.week', $weekFormat );
|
||||
Components::set( $week . 'Element', $weekView );
|
||||
}
|
||||
|
||||
// Calendar Top Tabs
|
||||
Components::unset( 'calendarDropdown');
|
||||
$calendarTabs = Views::simpleView('calendar.nav.topTabs');
|
||||
$tabsView = Navigation::activePageSelect( $calendarTabs, '/calendar/byWeek/', false, true );
|
||||
// must be done after top-nav gets selected
|
||||
$calendarDropdown = Views::simpleView('calendar.nav.calendarDropdown', self::$calendars->simpleObjectByUser() );
|
||||
$calendarDropdownView = Navigation::activePageSelect( $calendarDropdown, Input::get( 'url' ), false, true ); // add notebookID as second param
|
||||
Components::set( 'calendarDropdown', $calendarDropdownView);
|
||||
Components::set( 'CalendarNav', Template::parse( $tabsView ) );
|
||||
|
||||
Components::set( 'dateWeek', 'Week of ' . date( 'F d, Y', self::$selectedDate ) );
|
||||
Views::view( 'calendar.byWeek' );
|
||||
}
|
||||
public function byMonth( $id = 0 ) {
|
||||
// Set base components
|
||||
Components::set( 'currentView', __FUNCTION__ );
|
||||
Components::set( 'calendarID', $id );
|
||||
|
||||
// Set components for next / back arrows
|
||||
$month = date( 'F', strtotime( 'first day of last month', self::$selectedDate ) );
|
||||
$lastMonthYear = date( 'Y', strtotime( 'first day of last month', self::$selectedDate ) );
|
||||
$nextMonth = date( 'F', strtotime( 'first day of next month', self::$selectedDate ) );
|
||||
$nextMonthYear = date( 'Y', strtotime( 'first day of next month', self::$selectedDate ) );
|
||||
Components::set( 'lastMonth', $month );
|
||||
Components::set( 'lastMonthYear', $lastMonthYear );
|
||||
Components::set( 'nextMonth', $nextMonth );
|
||||
Components::set( 'nextMonthYear', $nextMonthYear );
|
||||
|
||||
// Get the data
|
||||
$monthArray = self::$events->monthArray( $id, self::$selectedDate );
|
||||
|
||||
// build the results
|
||||
$lastMonth = strtotime( 'last month', self::$selectedDate );
|
||||
$presentMonth = date( 'F', self::$selectedDate );
|
||||
$presentDay = date( 'd', self::$selectedDate );
|
||||
foreach ( $monthArray as $week => $days ) {
|
||||
$weekFormat = [];
|
||||
foreach ( $days as $day => $events ) {
|
||||
if ( $day == '01' ) {
|
||||
$month = date( 'F', strtotime( '+1 month', $lastMonth ) );
|
||||
$lastMonth = strtotime( '+1 month', $lastMonth) ;
|
||||
}
|
||||
Components::set( 'currentMonth', $month );
|
||||
Components::set( 'currentDay', $day );
|
||||
$dayCell = new \stdClass();
|
||||
if ( $presentDay == $day && $presentMonth == $month ) {
|
||||
$dayCell->highlightedDate = ' today';
|
||||
} else {
|
||||
$dayCell->highlightedDate = '';
|
||||
}
|
||||
$dayCell->day = $day;
|
||||
// prevent duplicated entries for previous/next month
|
||||
if ( $lastMonth < strtotime( 'this month',self::$selectedDate ) || $lastMonth == strtotime( 'next month',self::$selectedDate )) {
|
||||
$events = [];
|
||||
}
|
||||
$dayCell->dayEventList = Views::simpleView( 'calendar.nav.cell', $events );
|
||||
$weekFormat[] = $dayCell;
|
||||
}
|
||||
|
||||
$weekView = Views::simpleView( 'calendar.nav.week', $weekFormat );
|
||||
Components::set( $week . 'Element', $weekView );
|
||||
}
|
||||
|
||||
// Calendar Top Tabs
|
||||
Components::unset( 'calendarDropdown');
|
||||
$calendarTabs = Views::simpleView('calendar.nav.topTabs');
|
||||
$tabsView = Navigation::activePageSelect( $calendarTabs, '/calendar/byMonth/', false, true );
|
||||
// must be done after top-nav gets selected
|
||||
$calendarDropdown = Views::simpleView('calendar.nav.calendarDropdown', self::$calendars->simpleObjectByUser() );
|
||||
$calendarDropdownView = Navigation::activePageSelect( $calendarDropdown, Input::get( 'url' ), false, true ); // add notebookID as second param
|
||||
Components::set( 'calendarDropdown', $calendarDropdownView);
|
||||
Components::set( 'CalendarNav', Template::parse( $tabsView ) );
|
||||
|
||||
Components::set( 'dateMonth', date( 'F Y', self::$selectedDate ) );
|
||||
Views::view( 'calendar.byMonth' );
|
||||
}
|
||||
public function byYear( $id = 0 ) {
|
||||
// Set base components
|
||||
Components::set( 'calendarID', $id );
|
||||
Components::set( 'currentView', __FUNCTION__ );
|
||||
|
||||
// Set components for next / back arrows
|
||||
$nextYear = date( 'Y', strtotime( 'next year', self::$selectedDate ) );
|
||||
$lastYear = date( 'Y', strtotime( 'last year', self::$selectedDate ) );
|
||||
Components::set( 'lastYear', $lastYear );
|
||||
Components::set( 'nextYear', $nextYear );
|
||||
|
||||
// Get the data
|
||||
$eventList = self::$events->yearArray( $id, self::$selectedDate );
|
||||
|
||||
// Calendar Top Tabs
|
||||
Components::unset( 'calendarDropdown');
|
||||
$calendarTabs = Views::simpleView('calendar.nav.topTabs');
|
||||
$tabsView = Navigation::activePageSelect( $calendarTabs, '/calendar/byYear/', false, true );
|
||||
// must be done after top-nav gets selected
|
||||
$calendarDropdown = Views::simpleView('calendar.nav.calendarDropdown', self::$calendars->simpleObjectByUser() );
|
||||
$calendarDropdownView = Navigation::activePageSelect( $calendarDropdown, Input::get( 'url' ), false, true ); // add notebookID as second param
|
||||
Components::set( 'calendarDropdown', $calendarDropdownView);
|
||||
Components::set( 'CalendarNav', Template::parse( $tabsView ) );
|
||||
|
||||
Components::set( 'dateYear', date( 'Y', self::$selectedDate ) );
|
||||
Views::view( 'calendar.byYear', $eventList );
|
||||
}
|
||||
public function events( $id = 0 ) {
|
||||
Components::set( 'currentView', __FUNCTION__ );
|
||||
Components::set( 'calendarID', $id );
|
||||
if ( ! empty( $id ) ) {
|
||||
$calendar = self::$calendars->findById( $id );
|
||||
if ( $calendar == false ) {
|
||||
Issues::add( 'error', 'Calendar not found.' );
|
||||
return $this->index();
|
||||
}
|
||||
if ( $calendar->createdBy != App::$activeUser->ID ) {
|
||||
Issues::add( 'error', 'You do not have permission to view this calendar.' );
|
||||
return $this->index();
|
||||
}
|
||||
Components::set( 'calendarName', $calendar->title );
|
||||
$eventList = self::$events->findByCalendar( $id );
|
||||
} else {
|
||||
$eventList = self::$events->userEvents( 5 );
|
||||
}
|
||||
|
||||
// Calendar Top Tabs
|
||||
Components::unset( 'calendarDropdown');
|
||||
$calendarTabs = Views::simpleView('calendar.nav.topTabs');
|
||||
$tabsView = Navigation::activePageSelect( $calendarTabs, '/calendar/events/', false, true );
|
||||
// must be done after top-nav gets selected
|
||||
$calendarDropdown = Views::simpleView('calendar.nav.calendarDropdown', self::$calendars->simpleObjectByUser() );
|
||||
$calendarDropdownView = Navigation::activePageSelect( $calendarDropdown, Input::get( 'url' ), false, true ); // add notebookID as second param
|
||||
Components::set( 'calendarDropdown', $calendarDropdownView);
|
||||
Components::set( 'CalendarNav', Template::parse( $tabsView ) );
|
||||
|
||||
Views::view( 'calendar.events.list', $eventList );
|
||||
}
|
||||
|
||||
/**
|
||||
* Support Functions
|
||||
*/
|
||||
private function findCalendarOrFail( $id = null ) {
|
||||
$calendar = self::$calendars->findById( $id );
|
||||
if ( $calendar == false ) {
|
||||
Session::flash( 'error', 'Calendar not found.' );
|
||||
Redirect::to( 'calendar/'.self::$defaultView.'/' );
|
||||
}
|
||||
if ( $calendar->createdBy != App::$activeUser->ID ) {
|
||||
Session::flash( 'error', 'Permissions Error.' );
|
||||
Redirect::to( 'calendar/'.self::$defaultView.'/' );
|
||||
}
|
||||
return $calendar;
|
||||
}
|
||||
private function findEventOrFail( $id = null ) {
|
||||
$event = self::$events->findById( $id );
|
||||
if ( $event == false ) {
|
||||
Session::flash( 'error', 'Event not found.' );
|
||||
Redirect::to( 'calendar/'.self::$defaultView.'/' );
|
||||
}
|
||||
if ( $event->createdBy != App::$activeUser->ID ) {
|
||||
Session::flash( 'error', 'Permissions Error.' );
|
||||
Redirect::to( 'calendar/'.self::$defaultView.'/' );
|
||||
}
|
||||
return $event;
|
||||
}
|
||||
private function getEventBreakdown( $start_timestamp = 0, $end_timestamp = 0, $with_timezone = false ) {
|
||||
|
||||
|
||||
|
||||
$out = new \stdClass();
|
||||
if ( empty( $end_timestamp ) ) {
|
||||
$out->allDay = 'true';
|
||||
// $out->date = ;
|
||||
// $out->time = ;
|
||||
$out->endDate = $out->date;
|
||||
$out->endTime = $out->time;
|
||||
} else {
|
||||
$out->allDay = 'false';
|
||||
|
||||
// $out->date = ;
|
||||
// $out->time = ;
|
||||
$out->endDate = $out->date;
|
||||
$out->endTime = $out->time;
|
||||
}
|
||||
|
||||
|
||||
$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,
|
||||
];
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -1,153 +0,0 @@
|
||||
.calendar-container {
|
||||
margin-left: 20px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.calendar-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.calendar-cell {
|
||||
flex: 1;
|
||||
border: 1px solid #ddd;
|
||||
text-align: center;
|
||||
padding: 10px 0;
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
.calendar-cell h4 {
|
||||
margin: 0;
|
||||
padding: 5px;
|
||||
border-radius: 4px;
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
.hour-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.hour-body {
|
||||
display: flex; /* Add this line to use flexbox */
|
||||
flex-direction: row; /* Ensure the direction is row */
|
||||
flex: 4;
|
||||
border: 1px solid #ddd;
|
||||
text-align: center;
|
||||
padding: 10px 0;
|
||||
margin-left: 5px;
|
||||
margin-right: 5px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.hour-cell {
|
||||
flex: 1;
|
||||
border: 1px solid #ddd;
|
||||
text-align: center;
|
||||
padding: 10px 0;
|
||||
margin-left: 5px;
|
||||
margin-right: 5px;
|
||||
align-items: center;
|
||||
max-width: 250px;
|
||||
}
|
||||
|
||||
.today {
|
||||
background-color: #5cb85c !important;
|
||||
}
|
||||
|
||||
.hour-header, .hour-footer {
|
||||
flex: 0 0 10%;
|
||||
background-color: #f8f8f8;
|
||||
text-align: center;
|
||||
padding: 10px 0;
|
||||
margin: 0 5px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* Adjusting the first and last cell margins to align with the container edges */
|
||||
.calendar-cell:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.calendar-cell:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.select-container {
|
||||
color: white;
|
||||
}
|
||||
.custom-select {
|
||||
/* color: red; */
|
||||
color: #000;
|
||||
}
|
||||
.custom-select .white {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.custom-select .primary {
|
||||
background-color: #337ab7;
|
||||
}
|
||||
.custom-select .success {
|
||||
background-color: #5cb85c;
|
||||
}
|
||||
.custom-select .info {
|
||||
background-color: #5bc0de;
|
||||
}
|
||||
.custom-select .warning {
|
||||
background-color: #f0ad4e;
|
||||
}
|
||||
.custom-select .danger {
|
||||
background-color: #d9534f;
|
||||
}
|
||||
.select-container .primary {
|
||||
background-color: #337ab7;
|
||||
}
|
||||
.select-container .white {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.select-container .success {
|
||||
background-color: #5cb85c;
|
||||
}
|
||||
.select-container .info {
|
||||
background-color: #5bc0de;
|
||||
}
|
||||
.select-container .warning {
|
||||
background-color: #f0ad4e;
|
||||
}
|
||||
.select-container .danger {
|
||||
background-color: #d9534f;
|
||||
}
|
||||
|
||||
.dateDayContainer {
|
||||
width: 250px;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.dateWeekContainer {
|
||||
width: 450px;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.dateMonthContainer {
|
||||
width: 250px;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.dateYearContainer {
|
||||
width: 150px;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.hour-active {
|
||||
background-color: #217025 !important;
|
||||
/* color: #00ff0d !important; */
|
||||
background-image:none;
|
||||
}
|
@ -1,136 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/calendar/forms.php
|
||||
*
|
||||
* This houses all of the form checking functions for this plugin.
|
||||
*
|
||||
* @package TP Calendar
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Plugins\Calendar;
|
||||
|
||||
use TheTempusProject\Bedrock\Functions\Input;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Classes\Forms;
|
||||
|
||||
class CalendarForms extends Forms {
|
||||
/**
|
||||
* Adds these functions to the form list.
|
||||
*/
|
||||
public function __construct() {
|
||||
self::addHandler( 'calendarSelect', __CLASS__, 'calendarSelect' );
|
||||
self::addHandler( 'createEvent', __CLASS__, 'createEvent' );
|
||||
self::addHandler( 'createCalendar', __CLASS__, 'createCalendar' );
|
||||
self::addHandler( 'editEvent', __CLASS__, 'editEvent' );
|
||||
self::addHandler( 'editCalendar', __CLASS__, 'editCalendar' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the password re-send form.
|
||||
*
|
||||
* @return {bool}
|
||||
*/
|
||||
public static function calendarSelect() {
|
||||
if ( ! Input::exists( 'calendar_id' ) ) {
|
||||
Check::addUserError( 'You must include a title.' );
|
||||
return false;
|
||||
}
|
||||
// if ( !self::token() ) {
|
||||
// Check::addUserError( 'token - comment out later.' );
|
||||
// return false;
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function createEvent() {
|
||||
if ( ! Input::exists( 'title' ) ) {
|
||||
Check::addUserError( 'You must include a title.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'date' ) ) {
|
||||
Check::addUserError( 'You must include a date.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'time' ) ) {
|
||||
Check::addUserError( 'You must include a time.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'repeats' ) ) {
|
||||
Check::addUserError( 'You must include a frequency.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'calendar_id' ) ) {
|
||||
Check::addUserError( 'You must select a calendar.' );
|
||||
return false;
|
||||
}
|
||||
// if ( !self::token() ) {
|
||||
// Check::addUserError( 'token - comment out later.' );
|
||||
// return false;
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function createCalendar() {
|
||||
if ( ! Input::exists( 'title' ) ) {
|
||||
Check::addUserError( 'You must include a title.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'timezone' ) ) {
|
||||
Check::addUserError( 'You must include a timezone.' );
|
||||
return false;
|
||||
}
|
||||
// if ( ! self::token() ) {
|
||||
// Check::addUserError( 'token - comment out later.' );
|
||||
// return false;
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function editEvent() {
|
||||
if ( ! Input::exists( 'title' ) ) {
|
||||
Check::addUserError( 'You must include a title.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'date' ) ) {
|
||||
Check::addUserError( 'You must include a date.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'time' ) ) {
|
||||
Check::addUserError( 'You must include a time.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'repeats' ) ) {
|
||||
Check::addUserError( 'You must include a frequency.' );
|
||||
return false;
|
||||
}
|
||||
// if ( !self::token() ) {
|
||||
// Check::addUserError( 'token - comment out later.' );
|
||||
// return false;
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function editCalendar() {
|
||||
if ( ! Input::exists( 'submit' ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'title' ) ) {
|
||||
Check::addUserError( 'You must include a title.' );
|
||||
return false;
|
||||
}
|
||||
if ( ! Input::exists( 'timezone' ) ) {
|
||||
Check::addUserError( 'You must include a timezone.' );
|
||||
return false;
|
||||
}
|
||||
// if ( !self::token() ) {
|
||||
// Check::addUserError( 'token - comment out later.' );
|
||||
// return false;
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
new CalendarForms;
|
@ -1,157 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/calendar/models/events.php
|
||||
*
|
||||
* This class is used for the manipulation of the calendars database table.
|
||||
*
|
||||
* @package TP Calendar
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Models;
|
||||
|
||||
use TheTempusProject\Bedrock\Classes\Config;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Bedrock\Functions\Date;
|
||||
use TheTempusProject\Canary\Canary as Debug;
|
||||
use TheTempusProject\Classes\DatabaseModel;
|
||||
use TheTempusProject\TheTempusProject as App;
|
||||
use TheTempusProject\Houdini\Classes\Filters;
|
||||
use TheTempusProject\Bedrock\Classes\CustomException;
|
||||
|
||||
class Calendars extends DatabaseModel {
|
||||
public $tableName = 'calendars';
|
||||
public $databaseMatrix = [
|
||||
[ 'title', 'varchar', '256' ],
|
||||
[ 'color', 'varchar', '48' ],
|
||||
[ 'privacy', 'varchar', '48' ],
|
||||
[ 'description', 'text', '' ],
|
||||
[ 'createdBy', 'int', '11' ],
|
||||
[ 'createdAt', 'int', '11' ],
|
||||
[ 'timezone', 'varchar', '256' ],
|
||||
];
|
||||
|
||||
/**
|
||||
* The model constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function create( $title, $description = '', $timezone = '', $color = 'default' ) {
|
||||
if ( ! Check::dataTitle( $title ) ) {
|
||||
Debug::info( 'Calendars: illegal title.' );
|
||||
return false;
|
||||
}
|
||||
if ( empty( $timezone ) ) {
|
||||
$timezone = Date::getTimezone();
|
||||
}
|
||||
$fields = [
|
||||
'title' => $title,
|
||||
'description' => $description,
|
||||
'timezone' => $timezone,
|
||||
'color' => $color,
|
||||
'createdBy' => App::$activeUser->ID,
|
||||
'createdAt' => time(),
|
||||
];
|
||||
if ( ! self::$db->insert( $this->tableName, $fields ) ) {
|
||||
new CustomException( 'calendarCreate' );
|
||||
Debug::error( "Calendar: not created " . var_export($fields,true) );
|
||||
return false;
|
||||
}
|
||||
return self::$db->lastId();
|
||||
}
|
||||
|
||||
public function update( $id, $title, $description = '', $timezone = '', $color = 'default' ) {
|
||||
if ( empty( $timezone ) ) {
|
||||
$timezone = Date::getTimezone();
|
||||
}
|
||||
if ( !Check::id( $id ) ) {
|
||||
Debug::info( 'Calendars: illegal ID.' );
|
||||
return false;
|
||||
}
|
||||
if ( !Check::dataTitle( $title ) ) {
|
||||
Debug::info( 'Calendars: illegal title.' );
|
||||
return false;
|
||||
}
|
||||
$fields = [
|
||||
'title' => $title,
|
||||
'description' => $description,
|
||||
'timezone' => $timezone,
|
||||
'color' => $color,
|
||||
];
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'calendarUpdate' );
|
||||
Debug::error( "Calendar: $id not updated: $fields" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function byUser( $limit = null ) {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
if ( empty( $limit ) ) {
|
||||
$calendars = self::$db->get( $this->tableName, $whereClause );
|
||||
} else {
|
||||
$calendars = self::$db->get( $this->tableName, $whereClause, 'ID', 'DESC', [0, $limit] );
|
||||
}
|
||||
if ( !$calendars->count() ) {
|
||||
Debug::info( 'No Calendars found.' );
|
||||
return false;
|
||||
}
|
||||
return $this->filter( $calendars->results() );
|
||||
}
|
||||
|
||||
public function getName( $id ) {
|
||||
$calendar = self::findById( $id );
|
||||
if (false == $calendar) {
|
||||
return 'unknown';
|
||||
}
|
||||
return $calendar->title;
|
||||
}
|
||||
|
||||
public function getColor( $id ) {
|
||||
$calendar = self::findById( $id );
|
||||
if (false == $calendar) {
|
||||
return 'default';
|
||||
}
|
||||
return $calendar->color;
|
||||
}
|
||||
|
||||
public function simpleByUser() {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
$calendars = self::$db->get( $this->tableName, $whereClause );
|
||||
if ( !$calendars->count() ) {
|
||||
Debug::warn( 'Could not find any calendars' );
|
||||
return false;
|
||||
}
|
||||
|
||||
$calendars = $calendars->results();
|
||||
$out = [];
|
||||
foreach ( $calendars as &$calendar ) {
|
||||
$out[ $calendar->title ] = $calendar->ID;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function simpleObjectByUser() {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
$calendars = self::$db->get( $this->tableName, $whereClause );
|
||||
if ( !$calendars->count() ) {
|
||||
Debug::warn( 'Could not find any calendars' );
|
||||
return false;
|
||||
}
|
||||
|
||||
$calendars = $calendars->results();
|
||||
$out = [];
|
||||
foreach ( $calendars as &$calendar ) {
|
||||
$obj = new \stdClass();
|
||||
$obj->title = $calendar->title;
|
||||
$obj->ID = $calendar->ID;
|
||||
$out[] = $obj;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
}
|
@ -1,509 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/calendar/models/events.php
|
||||
*
|
||||
* This class is used for the manipulation of the events database table.
|
||||
*
|
||||
* @package TP Calendar
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Models;
|
||||
|
||||
use TheTempusProject\Bedrock\Classes\Config;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Canary\Canary as Debug;
|
||||
use TheTempusProject\Classes\DatabaseModel;
|
||||
use TheTempusProject\TheTempusProject as App;
|
||||
use TheTempusProject\Houdini\Classes\Filters;
|
||||
use TheTempusProject\Models\Calendars;
|
||||
use TheTempusProject\Bedrock\Classes\CustomException;
|
||||
use TheTempusProject\Bedrock\Functions\Date;
|
||||
use TheTempusProject\Houdini\Classes\Pagination;
|
||||
|
||||
class Events extends DatabaseModel {
|
||||
public $tableName = 'events';
|
||||
public $repeatOptions = [
|
||||
'Does Not Repeat' => 'none',
|
||||
'Every Day' => 'daily',
|
||||
'Every Week' => 'weekly',
|
||||
'Every Month' => 'monthly',
|
||||
'Every Year' => 'yearly',
|
||||
];
|
||||
public $databaseMatrix = [
|
||||
[ 'calendar_id', 'int', '11' ],
|
||||
[ 'title', 'varchar', '256' ],
|
||||
[ 'event_time', 'int', '11' ],
|
||||
[ 'event_ends', 'int', '11' ],
|
||||
[ 'description', 'text', '' ],
|
||||
[ 'location', 'varchar', '256' ],
|
||||
[ 'repeats', 'varchar', '48' ],
|
||||
[ 'color', 'varchar', '48' ],
|
||||
[ 'parent_id', 'int', '11' ],
|
||||
[ 'createdBy', 'int', '11' ],
|
||||
[ 'createdAt', 'int', '11' ],
|
||||
];
|
||||
protected static $calendars;
|
||||
|
||||
/**
|
||||
* The model constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
self::$calendars = new Calendars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a chat form to the db.
|
||||
*
|
||||
* @param string $message -contents of the chat form.
|
||||
* @return bool
|
||||
*/
|
||||
public function create( $calendar_id, $title, $event_time, $description = '', $location = '', $repeats = 'none', $color = 'default', $parent_id = 0 ) {
|
||||
if ( ! Check::id( $calendar_id ) ) {
|
||||
Debug::info( 'calendar event: illegal calendar ID.' );
|
||||
return false;
|
||||
}
|
||||
$fields = [
|
||||
'calendar_id' => $calendar_id,
|
||||
'title' => $title,
|
||||
'event_time' => $event_time,
|
||||
'description' => $description,
|
||||
'location' => $location,
|
||||
'repeats' => $repeats,
|
||||
'color' => $color,
|
||||
'parent_id' => $parent_id,
|
||||
'createdBy' => App::$activeUser->ID,
|
||||
'createdAt' => time(),
|
||||
];
|
||||
if ( !self::$db->insert( $this->tableName, $fields ) ) {
|
||||
Debug::info( 'Events::create - failed to insert to db' );
|
||||
return false;
|
||||
}
|
||||
return self::$db->lastId();
|
||||
}
|
||||
|
||||
public function update( $id, $title, $event_time, $description = '', $location ='', $repeats = 'none', $color = 'default', $parent_id = 0, $calendar_id = '' ) {
|
||||
if ( ! Check::id( $id ) ) {
|
||||
Debug::info( 'calendar event: illegal ID.' );
|
||||
return false;
|
||||
}
|
||||
$fields = [
|
||||
'title' => $title,
|
||||
'event_time' => $event_time,
|
||||
'description' => $description,
|
||||
'location' => $location,
|
||||
'repeats' => $repeats,
|
||||
'color' => $color,
|
||||
'parent_id' => $parent_id,
|
||||
];
|
||||
if ( ! self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'calendarEventUpdate' );
|
||||
Debug::error( "Event: $id not updated: $fields" );
|
||||
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function dayArray( $calendar_id = 0, $date = 0 ) {
|
||||
$whereClause = [ 'createdBy', '=', App::$activeUser->ID, 'AND' ];
|
||||
if ( ! empty( $calendar_id ) ) {
|
||||
$whereClause = array_merge( $whereClause, [ 'calendar_id', '=', $calendar_id, 'AND' ] );
|
||||
}
|
||||
|
||||
$whereClause = array_merge( $whereClause, [
|
||||
'event_time', '>=', Date::getDayStartTimestamp( $date, true ), 'AND',
|
||||
'event_time', '<=', Date::getDayEndTimestamp( $date, true ),
|
||||
] );
|
||||
|
||||
$events = self::$db->get( $this->tableName, $whereClause );
|
||||
if ( ! $events->count() ) {
|
||||
$results = [];
|
||||
} else {
|
||||
$results = $events->results();
|
||||
}
|
||||
$events = $this->sortByEventTimeHour(
|
||||
$this->filter(
|
||||
$results
|
||||
)
|
||||
);
|
||||
// Generate day array
|
||||
$currentDay = [];
|
||||
$currentHour = Date::getDayStartTimestamp( $date );
|
||||
$lastHour = Date::getDayEndTimestamp( $date );
|
||||
while ( $currentHour <= $lastHour ) {
|
||||
$hour = date( 'H', $currentHour );
|
||||
if ( ! empty( $events[ $hour ] ) ) {
|
||||
$dailyEvents = $events[ $hour ];
|
||||
} else {
|
||||
$dailyEvents = [];
|
||||
}
|
||||
$currentDay[ $hour ] = $dailyEvents;
|
||||
$currentHour = strtotime('+1 hour', $currentHour);
|
||||
}
|
||||
return $currentDay;
|
||||
}
|
||||
|
||||
public function weekArray( $calendar_id = 0, $date = null ) {
|
||||
$whereClause = [ 'createdBy', '=', App::$activeUser->ID, 'AND' ];
|
||||
if ( ! empty( $calendar_id ) ) {
|
||||
$whereClause = array_merge( $whereClause, [ 'calendar_id', '=', $calendar_id, 'AND' ] );
|
||||
}
|
||||
|
||||
$whereClause = array_merge( $whereClause, [
|
||||
'event_time', '>=', Date::getWeekStartTimestamp( $date, true ), 'AND',
|
||||
'event_time', '<=', Date::getWeekEndTimestamp( $date, true ),
|
||||
] );
|
||||
$events = self::$db->get( $this->tableName, $whereClause );
|
||||
if ( ! $events->count() ) {
|
||||
$results = [];
|
||||
} else {
|
||||
$results = $events->results();
|
||||
}
|
||||
$events = $this->sortByEventTime(
|
||||
$this->filter(
|
||||
$results
|
||||
),
|
||||
);
|
||||
|
||||
// Generate weeks array
|
||||
$output = [];
|
||||
$currentWeek = [];
|
||||
$currentDay = Date::getWeekStartTimestamp( $date );
|
||||
$weekCounter = 1;
|
||||
$dayCounter = 1;
|
||||
|
||||
// Re-index the array using the date derived from event_time as the key
|
||||
while ( $currentDay <= Date::getWeekEndTimestamp( $date ) ) {
|
||||
$month = date( 'F', $currentDay );
|
||||
$dayOfMonth = date( 'd', $currentDay );
|
||||
if ( ! empty( $events[ $month ][ $dayOfMonth ] ) ) {
|
||||
$dailyEvents = $events[ $month ][ $dayOfMonth ];
|
||||
} else {
|
||||
$dailyEvents = [];
|
||||
}
|
||||
$currentWeek[ $dayOfMonth ] = $dailyEvents;
|
||||
$currentDay = strtotime('+1 day', $currentDay);
|
||||
}
|
||||
|
||||
// Handle any remaining days in the last week
|
||||
if ( ! empty( $currentWeek ) ) {
|
||||
$output["week$weekCounter"] = $currentWeek;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function monthArray( $calendar_id = 0, $date = null ) {
|
||||
$whereClause = [ 'createdBy', '=', App::$activeUser->ID, 'AND' ];
|
||||
if ( ! empty( $calendar_id ) ) {
|
||||
$whereClause = array_merge( $whereClause, [ 'calendar_id', '=', $calendar_id, 'AND' ] );
|
||||
}
|
||||
$whereClause = array_merge( $whereClause, [
|
||||
'event_time', '>=', Date::getMonthStartTimestamp( $date, true ), 'AND',
|
||||
'event_time', '<=', Date::getMonthEndTimestamp( $date, true ),
|
||||
] );
|
||||
|
||||
$events = self::$db->get( $this->tableName, $whereClause );
|
||||
if ( ! $events->count() ) {
|
||||
$results = [];
|
||||
} else {
|
||||
$results = $events->results();
|
||||
}
|
||||
$events = $this->sortByEventTime(
|
||||
$this->filter(
|
||||
$results
|
||||
),
|
||||
);
|
||||
|
||||
// Generate weeks array
|
||||
$output = [];
|
||||
$currentWeek = [];
|
||||
$currentDay = Date::getMonthStartTimestamp( $date );
|
||||
$weekCounter = 1;
|
||||
$dayCounter = 1;
|
||||
|
||||
// Re-index the array using the date derived from event_time as the key
|
||||
while ( $currentDay <= Date::getMonthEndTimestamp( $date ) ) {
|
||||
$month = date( 'F', $currentDay );
|
||||
$dayOfMonth = date( 'd', $currentDay );
|
||||
if ( ! empty( $events[ $month ][ $dayOfMonth ] ) ) {
|
||||
$dailyEvents = $events[ $month ][ $dayOfMonth ];
|
||||
} else {
|
||||
$dailyEvents = [];
|
||||
}
|
||||
$currentWeek[$dayOfMonth] = $dailyEvents;
|
||||
if (count($currentWeek) == 7) {
|
||||
$output["week$weekCounter"] = $currentWeek;
|
||||
$currentWeek = [];
|
||||
$weekCounter++;
|
||||
}
|
||||
$currentDay = strtotime('+1 day', $currentDay);
|
||||
}
|
||||
|
||||
// Handle any remaining days in the last week
|
||||
if ( ! empty( $currentWeek ) ) {
|
||||
$output["week$weekCounter"] = $currentWeek;
|
||||
}
|
||||
while ( $weekCounter < 7 ) {
|
||||
$output["week$weekCounter"] = [];
|
||||
$weekCounter++;
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function yearArray( $calendar_id = 0, $date = null ) {
|
||||
if ( empty( $date ) ) {
|
||||
$date = time();
|
||||
}
|
||||
$year = date( 'Y', $date );
|
||||
$firstDayUnix = date( 'U', strtotime( "Jan 1, $year" ) );
|
||||
$lastDayUnix = date( 'U', strtotime( "December 31, $year" ) );
|
||||
$whereClause = [ 'createdBy', '=', App::$activeUser->ID, 'AND' ];
|
||||
if ( ! empty( $calendar_id ) ) {
|
||||
$whereClause = array_merge( $whereClause, [ 'calendar_id', '=', $calendar_id, 'AND' ] );
|
||||
}
|
||||
$whereClause = array_merge( $whereClause, [
|
||||
'event_time', '<=', $lastDayUnix, 'AND',
|
||||
'event_time', '>=', $firstDayUnix,
|
||||
] );
|
||||
$events = self::$db->get( $this->tableName, $whereClause );
|
||||
if ( ! $events->count() ) {
|
||||
Debug::info( 'No ' . $this->tableName . ' data found.' );
|
||||
return [];
|
||||
}
|
||||
return $this->filter( $events->results() );
|
||||
}
|
||||
|
||||
public function compareEventTime($a, $b) {
|
||||
return $a->event_time - $b->event_time;
|
||||
}
|
||||
|
||||
public function sortByEventTimeHour( $results ) {
|
||||
usort( $results, [ $this,'compareEventTime' ] );
|
||||
|
||||
$sortedResults = array();
|
||||
foreach ( $results as $result ) {
|
||||
$date = new \DateTime();
|
||||
$date->setTimestamp( $result->event_time );
|
||||
$timezone = new \DateTimeZone( Date::getTimezone() );
|
||||
$date->setTimezone( $timezone );
|
||||
$dateKey = $date->format('H');
|
||||
$sortedResults[ $dateKey ][] = $result;
|
||||
}
|
||||
return $sortedResults;
|
||||
}
|
||||
|
||||
public function sortByEventTime( $results ) {
|
||||
usort( $results, [ $this,'compareEventTime' ] );
|
||||
|
||||
$sortedResults = array();
|
||||
foreach ( $results as $result ) {
|
||||
$date = new \DateTime();
|
||||
$date->setTimestamp( $result->event_time );
|
||||
$timezone = new \DateTimeZone( Date::getTimezone() );
|
||||
$date->setTimezone( $timezone );
|
||||
$month = $date->format('F');
|
||||
$dateKey = $date->format('d');
|
||||
if ( ! isset( $sortedResults[ $month ] ) ) {
|
||||
$sortedResults[ $month ] = [];
|
||||
}
|
||||
if ( ! isset( $sortedResults[ $month ][ $dateKey ] ) ) {
|
||||
$sortedResults[ $month ][ $dateKey ] = [];
|
||||
}
|
||||
$sortedResults[ $month ][ $dateKey ][] = $result;
|
||||
}
|
||||
return $sortedResults;
|
||||
}
|
||||
|
||||
public function findByCalendar( $id ) {
|
||||
$calendar = $this->verifyCalendar( $id );
|
||||
if ( empty( $calendar ) ) {
|
||||
return [];
|
||||
}
|
||||
$whereClause = [ 'createdBy', '=', App::$activeUser->ID, 'AND' ];
|
||||
$whereClause = array_merge( $whereClause, [ 'calendar_id', '=', $id ] );
|
||||
$events = self::$db->getPaginated( $this->tableName, $whereClause );
|
||||
if ( ! $events->count() ) {
|
||||
Debug::info( 'No ' . $this->tableName . ' data found.' );
|
||||
return [];
|
||||
}
|
||||
return $this->filter( $events->results() );
|
||||
}
|
||||
|
||||
public function userEvents( $limit = 0 ) {
|
||||
$whereClause = [ 'createdBy', '=', App::$activeUser->ID ];
|
||||
$events = self::$db->getPaginated( $this->tableName, $whereClause );
|
||||
if ( ! $events->count() ) {
|
||||
Debug::info( 'No ' . $this->tableName . ' data found.' );
|
||||
return [];
|
||||
}
|
||||
return $this->filter( $events->results() );
|
||||
}
|
||||
|
||||
public function filter( $data, $params = [] ) {
|
||||
$out = [];
|
||||
foreach ( $data as $instance ) {
|
||||
if ( !is_object( $instance ) ) {
|
||||
$instance = $data;
|
||||
$end = true;
|
||||
}
|
||||
$instance->repeatsText = array_search('none', $this->repeatOptions);
|
||||
$instance->calendarName = self::$calendars->getName( $instance->calendar_id );
|
||||
if ( empty( $instance->color ) || $instance->color == 'default' || $instance->color == 'none') {
|
||||
$instance->displayColor = self::$calendars->getColor( $instance->calendar_id );
|
||||
} else {
|
||||
$instance->displayColor = $instance->color;
|
||||
}
|
||||
$out[] = $instance;
|
||||
if ( !empty( $end ) ) {
|
||||
$out = $out[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function today( $limit = 0 ) {
|
||||
$date = time();
|
||||
$day = date('d', $date);
|
||||
$month = date('M', $date);
|
||||
$year = date( 'Y', $date );
|
||||
$firstDayUnix = date( 'U', strtotime( "00:00:00 $day $month $year" ) );
|
||||
$lastDayUnix = date( 'U', strtotime( "23:59:59 $day $month $year" ) );
|
||||
$whereClause = [ 'createdBy', '=', App::$activeUser->ID, 'AND' ];
|
||||
$whereClause = array_merge( $whereClause, [
|
||||
'event_time', '<=', $lastDayUnix, 'AND',
|
||||
'event_time', '>=', $firstDayUnix,
|
||||
] );
|
||||
if ( empty( $limit ) ) {
|
||||
$events = self::$db->get( $this->tableName, $whereClause );
|
||||
} else {
|
||||
$events = self::$db->get( $this->tableName, $whereClause, 'ID', 'DESC', [0, $limit] );
|
||||
}
|
||||
if ( ! $events->count() ) {
|
||||
Debug::info( 'No ' . $this->tableName . ' data found.' );
|
||||
return [];
|
||||
}
|
||||
return $this->filter( $events->results() );
|
||||
}
|
||||
|
||||
private function verifyCalendar( $calendar_id ) {
|
||||
if ( ! Check::id( $calendar_id ) ) {
|
||||
Debug::info( 'Invalid Calendar ID' );
|
||||
return false;
|
||||
}
|
||||
$calendar = self::$calendars->findById( $calendar_id );
|
||||
if ( $calendar == false ) {
|
||||
Debug::info( 'Calendar not found' );
|
||||
return false;
|
||||
}
|
||||
if ( $calendar->createdBy != App::$activeUser->ID ) {
|
||||
Debug::info( 'You do not have permission to view this calendar' );
|
||||
return false;
|
||||
}
|
||||
return $calendar;
|
||||
}
|
||||
|
||||
public function deleteByCalendar( $calendar_id ) {
|
||||
$calendar = $this->verifyCalendar( $calendar_id );
|
||||
if ( empty( $calendar ) ) {
|
||||
return [];
|
||||
}
|
||||
$whereClause = [ 'createdBy', '=', App::$activeUser->ID, 'AND' ];
|
||||
$whereClause = array_merge( $whereClause, [ 'calendar_id', '=', $calendar_id ] );
|
||||
$events = self::$db->get( $this->tableName, $whereClause );
|
||||
if ( ! $events->count() ) {
|
||||
Debug::info( 'No ' . $this->tableName . ' data found.' );
|
||||
return [];
|
||||
}
|
||||
foreach( $events->results() as $event ) {
|
||||
$this->deleteByParent( $event->ID );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function deleteByParent( $event_id ) {
|
||||
$whereClause = [ 'createdBy', '=', App::$activeUser->ID, 'AND' ];
|
||||
$whereClause = array_merge( $whereClause, [ 'parent_id', '=', $event_id ] );
|
||||
$events = self::$db->get( $this->tableName, $whereClause );
|
||||
if ( ! $events->count() ) {
|
||||
Debug::info( 'No ' . $this->tableName . ' data found.' );
|
||||
return [];
|
||||
}
|
||||
foreach( $events->results() as $event ) {
|
||||
$this->delete( $event->ID );
|
||||
}
|
||||
// need to delete all child events accordingly
|
||||
return true;
|
||||
}
|
||||
|
||||
public function delete( $idArray ) {
|
||||
if ( !is_array( $idArray ) ) {
|
||||
$idArray = [ $idArray ];
|
||||
}
|
||||
return parent::delete( $idArray );
|
||||
}
|
||||
|
||||
public function generateChildEvents( $event_id, $remove_existing_children = true, $remove_history = false ) {
|
||||
$event = self::findById( $event_id );
|
||||
if (empty($event)) {
|
||||
return false;
|
||||
}
|
||||
if ($event->parent_id != 0) {
|
||||
return false;
|
||||
}
|
||||
if (!in_array($event->repeats, $this->repeatOptions)) {
|
||||
return false;
|
||||
}
|
||||
$startDate = time();
|
||||
$whereClause = [
|
||||
'parent_id', '=', $event_id,
|
||||
];
|
||||
if ( $remove_history && ! $remove_existing_children) {
|
||||
$whereClause = array_merge( $whereClause, [ 'AND', 'event_time', '<=', $startDate ] );
|
||||
} elseif ( $remove_existing_children && ! $remove_history ) {
|
||||
$whereClause = array_merge( $whereClause, [ 'AND', 'event_time', '>=', $startDate ] );
|
||||
} elseif ( !$remove_existing_children && !$remove_history ) {
|
||||
return false;
|
||||
}
|
||||
self::$db->delete($this->tableName, $whereClause);
|
||||
|
||||
switch ($event->repeats) {
|
||||
case 'daily':
|
||||
return $this->generateEvents( $event, 'P90D' );
|
||||
case 'weekly':
|
||||
return $this->generateEvents( $event, 'P1W' );
|
||||
case 'monthly':
|
||||
return $this->generateEvents( $event, 'P1M' );
|
||||
case 'yearly':
|
||||
return $this->generateEvents( $event, 'P1Y' );
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private function generateEvents( $event, $interval, $years = 2 ) {
|
||||
$endDate = strtotime('+'.$years.' years');
|
||||
$interval = new \DateInterval( $interval );
|
||||
$period = new \DatePeriod(new \DateTime('@' . $event->event_time), $interval, new \DateTime('@' . $endDate));
|
||||
foreach ($period as $date) {
|
||||
if ( $date->getTimestamp() <= time() ) {
|
||||
continue;
|
||||
}
|
||||
$result = $this->create(
|
||||
$event->calendar_id,
|
||||
$event->title,
|
||||
$date->getTimestamp(),
|
||||
$event->description,
|
||||
$event->location,
|
||||
$event->repeats,
|
||||
$event->color,
|
||||
$event->ID,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/calendar/plugin.php
|
||||
*
|
||||
* This houses all of the main plugin info and functionality.
|
||||
*
|
||||
* @package TP Calendar
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Plugins;
|
||||
|
||||
use TheTempusProject\Classes\Plugin;
|
||||
use TheTempusProject\Models\Events;
|
||||
use TheTempusProject\Models\Calendars;
|
||||
use TheTempusProject\Houdini\Classes\Components;
|
||||
use TheTempusProject\Houdini\Classes\Template;
|
||||
|
||||
class Calendar extends Plugin {
|
||||
public $pluginName = 'TP Calendar';
|
||||
public $configName = 'calendar';
|
||||
public $pluginAuthor = 'JoeyK';
|
||||
public $pluginWebsite = 'https://TheTempusProject.com';
|
||||
public $modelVersion = '1.0';
|
||||
public $pluginVersion = '3.0';
|
||||
public $pluginDescription = 'A simple plugin which adds a site wide calendar system.';
|
||||
public $permissionMatrix = [
|
||||
'useCalendar' => [
|
||||
'pretty' => 'Can use the calendar feature',
|
||||
'default' => false,
|
||||
],
|
||||
'createEvents' => [
|
||||
'pretty' => 'Can add events to calendars',
|
||||
'default' => false,
|
||||
],
|
||||
];
|
||||
public $main_links = [
|
||||
[
|
||||
'text' => 'Calendar',
|
||||
'url' => '{ROOT_URL}calendar/index',
|
||||
'filter' => 'loggedin',
|
||||
],
|
||||
];
|
||||
public $configMatrix = [
|
||||
'enabled' => [
|
||||
'type' => 'radio',
|
||||
'pretty' => 'Enable Calendar.',
|
||||
'default' => true,
|
||||
],
|
||||
];
|
||||
public $preferenceMatrix = [
|
||||
'calendarPreference' => [
|
||||
'pretty' => 'Default Calendar View',
|
||||
'type' => 'select',
|
||||
'default' => 'byMonth',
|
||||
'options' => [
|
||||
'Daily' => 'byDay',
|
||||
'Weekly' => 'byWeek',
|
||||
'Monthly' => 'byMonth',
|
||||
'Yearly' => 'byYear',
|
||||
'All Events' => 'events',
|
||||
],
|
||||
],
|
||||
'weekStart' => [
|
||||
'pretty' => 'First day of the week for the Calendar',
|
||||
'type' => 'select',
|
||||
'default' => 'sunday',
|
||||
'options' => [
|
||||
'Sunday' => '6',
|
||||
'Monday' => '7',
|
||||
],
|
||||
],
|
||||
];
|
||||
public $events;
|
||||
public $calendars;
|
||||
|
||||
public function __construct( $load = false ) {
|
||||
$this->events = new Events;
|
||||
$this->calendars = new Calendars;
|
||||
parent::__construct( $load );
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/blog/templates/blog.inc.php
|
||||
*
|
||||
* This is the loader for the blog template.
|
||||
*
|
||||
* @package TP Blog
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Templates;
|
||||
|
||||
use TheTempusProject\Plugins\Calendar;
|
||||
|
||||
use TheTempusProject\Houdini\Classes\Components;
|
||||
use TheTempusProject\Houdini\Classes\Navigation;
|
||||
use TheTempusProject\Houdini\Classes\Views;
|
||||
use TheTempusProject\Houdini\Classes\Template;
|
||||
use TheTempusProject\Bedrock\Functions\Input;
|
||||
use TheTempusProject\Models\Events;
|
||||
use TheTempusProject\Models\Calendars;
|
||||
|
||||
class CalendarLoader extends DefaultLoader {
|
||||
/**
|
||||
* This is the function used to generate any components that may be
|
||||
* needed by this template.
|
||||
*/
|
||||
public function __construct() {
|
||||
$events = new Events;
|
||||
$calendars = new Calendars;
|
||||
Navigation::setCrumbComponent( 'CALENDAR_BREADCRUMBS', Input::get( 'url' ) );
|
||||
Components::set( 'todaysDate', date( 'F d, Y', time()) );
|
||||
Components::set( 'currentDay', date( 'F d, Y', time()) );
|
||||
Components::set( 'weekOf', 'Week of ' . date( 'F d, Y', strtotime( 'this week' ) ) );
|
||||
Components::set( 'year', date( 'Y', time() ));
|
||||
Components::set( 'month', date( 'F', time() ));
|
||||
parent::__construct();
|
||||
}
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<!--
|
||||
* app/plugins/calendar/templates/calendar.tpl
|
||||
*
|
||||
* @package TP Calendar
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta property="og:url" content="{CURRENT_URL}">
|
||||
<meta name='twitter:card' content='summary' />
|
||||
<title>{TITLE}</title>
|
||||
<meta itemprop="name" content="{TITLE}">
|
||||
<meta name="twitter:title" content="{TITLE}">
|
||||
<meta property="og:title" content="{TITLE}">
|
||||
<meta name="description" content="{PAGE_DESCRIPTION}">
|
||||
<meta itemprop="description" content="{PAGE_DESCRIPTION}">
|
||||
<meta name="twitter:description" content="{PAGE_DESCRIPTION}">
|
||||
<meta property="og:description" content="{PAGE_DESCRIPTION}">
|
||||
<meta itemprop="image" content="{META_IMAGE}">
|
||||
<meta name="twitter:image" content="{META_IMAGE}">
|
||||
<meta property="og:image" content="{META_IMAGE}">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="author" content="The Tempus Project">
|
||||
{ROBOT}
|
||||
<link rel="alternate" hreflang="en-us" href="alternateURL">
|
||||
<link rel="icon" href="{ROOT_URL}images/favicon.ico">
|
||||
<!-- Required CSS -->
|
||||
<link rel="stylesheet" href="{FONT_AWESOME_URL}font-awesome.min.css" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="{BOOTSTRAP_CDN}css/bootstrap-theme.min.css" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="{BOOTSTRAP_CDN}css/bootstrap.min.css" crossorigin="anonymous">
|
||||
<!-- RSS -->
|
||||
<link rel="alternate" href="{ROOT_URL}blog/rss" title="{TITLE} Feed" type="application/rss+xml" />
|
||||
<!-- Custom styles for this template -->
|
||||
{TEMPLATE_CSS_INCLUDES}
|
||||
<link rel="stylesheet" href="{ROOT_URL}app/plugins/calendar/css/calendar.css" />
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
|
||||
<!--Brand and toggle should get grouped for better mobile display -->
|
||||
<div class="navbar-header">
|
||||
<a href="{ROOT_URL}" class="navbar-brand">{SITENAME}</a>
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse" style="">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="container-fluid">
|
||||
<div class="collapse navbar-collapse navbar-ex1-collapse">
|
||||
{topNavLeft}
|
||||
<div class="navbar-right">
|
||||
<ul class="nav navbar-nav">
|
||||
{topNavRight}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="container-fluid">
|
||||
<div class="foot-pad">
|
||||
{ISSUES}
|
||||
<div class="row">
|
||||
<div class="container">
|
||||
{ERROR}
|
||||
{NOTICE}
|
||||
{SUCCESS}
|
||||
</div>
|
||||
</div>
|
||||
{/ISSUES}
|
||||
<div class="row">
|
||||
<div class="container-fluid calendar-container">
|
||||
<div class="row">
|
||||
{CalendarNav}
|
||||
{CONTENT}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
{COPY}
|
||||
</footer>
|
||||
<!-- Bootstrap core JavaScript and jquery -->
|
||||
<script src="{JQUERY_CDN}jquery.min.js" crossorigin="anonymous"></script>
|
||||
<script src="{BOOTSTRAP_CDN}js/bootstrap.min.js" crossorigin="anonymous"></script>
|
||||
<!-- Custom javascript for this template -->
|
||||
{TEMPLATE_JS_INCLUDES}
|
||||
</body>
|
||||
</html>
|
@ -1,25 +0,0 @@
|
||||
<h2 class="pull-left">
|
||||
<a href="{ROOT_URL}calendar/byDay/{calendarID}?day={lastDay}&month={lastDayMonth}" role="button" class="btn btn-primary">
|
||||
<i class="glyphicon glyphicon-chevron-left"></i>
|
||||
</a>
|
||||
<span class="dateDayContainer">{activeDate}</span>
|
||||
<a href="{ROOT_URL}calendar/byDay/{calendarID}?day={nextDay}&month={nextDayMonth}" role="button" class="btn btn-primary">
|
||||
<i class="glyphicon glyphicon-chevron-right"></i>
|
||||
</a>
|
||||
</h2>
|
||||
{dateDropdown}
|
||||
<div class="container-fluid">
|
||||
{LOOP}
|
||||
<div class="hour-row{hourSelected}">
|
||||
<h2 class="hour-header">{hour}:00</h2>
|
||||
{EventCells}
|
||||
<span class="hour-footer">
|
||||
<a href="{ROOT_URL}calendar/createEvent?calendar_id={calendarID}&hour={hour}&day={day}" class="btn btn-sm btn-success" role="button"><i class="glyphicon glyphicon-plus"></i></a>
|
||||
</span>
|
||||
</div>
|
||||
{/LOOP}
|
||||
{ALT}
|
||||
<div class="hour-row{hourSelected}">
|
||||
</div>
|
||||
{/ALT}
|
||||
</div>
|
@ -1,34 +0,0 @@
|
||||
<h2 class="pull-left">
|
||||
<a href="{ROOT_URL}calendar/byMonth/{calendarID}?month={lastMonth}&year={lastMonthYear}" role="button" class="btn btn-primary">
|
||||
<i class="glyphicon glyphicon-chevron-left"></i>
|
||||
</a>
|
||||
<span class="dateMonthContainer">{dateMonth}</span>
|
||||
<a href="{ROOT_URL}calendar/byMonth/{calendarID}?month={nextMonth}&year={nextMonthYear}" role="button" class="btn btn-primary">
|
||||
<i class="glyphicon glyphicon-chevron-right"></i>
|
||||
</a>
|
||||
</h2>
|
||||
{dateDropdown}
|
||||
<div class="container-fluid">
|
||||
<!-- Header -->
|
||||
<div class="row calendar-row">
|
||||
<div class="col-xs-1 calendar-cell"><h4>Sunday</h4></div>
|
||||
<div class="col-xs-1 calendar-cell"><h4>Monday</h4></div>
|
||||
<div class="col-xs-1 calendar-cell"><h4>Tuesday</h4></div>
|
||||
<div class="col-xs-1 calendar-cell"><h4>Wednesday</h4></div>
|
||||
<div class="col-xs-1 calendar-cell"><h4>Thursday</h4></div>
|
||||
<div class="col-xs-1 calendar-cell"><h4>Friday</h4></div>
|
||||
<div class="col-xs-1 calendar-cell"><h4>Saturday</h4></div>
|
||||
</div>
|
||||
<!-- Week 1 -->
|
||||
{week1Element}
|
||||
<!-- Week 2 -->
|
||||
{week2Element}
|
||||
<!-- Week 3 -->
|
||||
{week3Element}
|
||||
<!-- Week 4 -->
|
||||
{week4Element}
|
||||
<!-- Week 5 -->
|
||||
{week5Element}
|
||||
<!-- Week 6 -->
|
||||
{week6Element}
|
||||
</div>
|
@ -1,25 +0,0 @@
|
||||
|
||||
<h2 class="pull-left">
|
||||
<a href="{ROOT_URL}calendar/byWeek/{calendarID}?month={lastWeekMonth}&day={lastWeek}&year={lastYear}" role="button" class="btn btn-primary">
|
||||
<i class="glyphicon glyphicon-chevron-left"></i>
|
||||
</a>
|
||||
<span class="dateWeekContainer">{dateWeek}</span>
|
||||
<a href="{ROOT_URL}calendar/byWeek/{calendarID}?month={nextWeekMonth}&day={nextWeek}&year={nextYear}" role="button" class="btn btn-primary">
|
||||
<i class="glyphicon glyphicon-chevron-right"></i>
|
||||
</a>
|
||||
</h2>
|
||||
{dateDropdown}
|
||||
<div class="container-fluid">
|
||||
<!-- Header -->
|
||||
<div class="row calendar-row">
|
||||
<div class="col-xs-1 calendar-cell"><h4>Sunday</h4></div>
|
||||
<div class="col-xs-1 calendar-cell"><h4>Monday</h4></div>
|
||||
<div class="col-xs-1 calendar-cell"><h4>Tuesday</h4></div>
|
||||
<div class="col-xs-1 calendar-cell"><h4>Wednesday</h4></div>
|
||||
<div class="col-xs-1 calendar-cell"><h4>Thursday</h4></div>
|
||||
<div class="col-xs-1 calendar-cell"><h4>Friday</h4></div>
|
||||
<div class="col-xs-1 calendar-cell"><h4>Saturday</h4></div>
|
||||
</div>
|
||||
<!-- Week 1 -->
|
||||
{week1Element}
|
||||
</div>
|
@ -1,42 +0,0 @@
|
||||
<h2 class="pull-left">
|
||||
<a href="{ROOT_URL}calendar/byYear/{calendarID}?year={lastYear}" role="button" class="btn btn-primary">
|
||||
<i class="glyphicon glyphicon-chevron-left"></i>
|
||||
</a>
|
||||
<span class="dateYearContainer">{dateYear}</span>
|
||||
<a href="{ROOT_URL}calendar/byYear/{calendarID}?year={nextYear}" role="button" class="btn btn-primary">
|
||||
<i class="glyphicon glyphicon-chevron-right"></i>
|
||||
</a>
|
||||
</h2>
|
||||
{dateDropdown}
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 10%">ID</th>
|
||||
<th style="width: 20%">Time</th>
|
||||
<th style="width: 40%">Title</th>
|
||||
<th style="width: 10%"></th>
|
||||
<th style="width: 10%"></th>
|
||||
<th style="width: 10%"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{LOOP}
|
||||
<tr>
|
||||
<td style="text-align: center;">{ID}</td>
|
||||
<td style="text-align: center;">{DTC}{event_time}{/DTC}</td>
|
||||
<td style="text-align: center;">{title}</td>
|
||||
<td><a href="{ROOT_URL}calendar/event/{ID}" class="btn btn-sm btn-primary" role="button"><i class="glyphicon glyphicon-open"></i></a></td>
|
||||
<td><a href="{ROOT_URL}calendar/editEvent/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a></td>
|
||||
<td><a href="{ROOT_URL}calendar/deleteEvent/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a></td>
|
||||
</tr>
|
||||
{/LOOP}
|
||||
{ALT}
|
||||
<tr>
|
||||
<td style="text-align: center;" colspan="6">
|
||||
No results to show.
|
||||
</td>
|
||||
</tr>
|
||||
{/ALT}
|
||||
</tbody>
|
||||
</table>
|
||||
<a href="{ROOT_URL}calendar/createEvent" class="btn btn-sm btn-primary" role="button">Create</a>
|
@ -1,34 +0,0 @@
|
||||
<legend>Create Calendar</legend>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<div class="form-group">
|
||||
<label for="title" class="col-lg-3 control-label">Title</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="title" id="title">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description" class="col-lg-3 control-label">Description</label>
|
||||
<div class="col-lg-3">
|
||||
<textarea class="form-control" name="description" maxlength="2000" rows="10" cols="50" id="description"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description" class="col-lg-3 control-label">Timezone</label>
|
||||
<div class="col-lg-3">
|
||||
{timezoneSelect}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="color" class="col-lg-3 control-label">Calendar Color</label>
|
||||
<div class="col-lg-3 select-container" id="colorContainer">
|
||||
{colorSelect}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="submit" class="col-lg-3 control-label"></label>
|
||||
<div class="col-lg-3">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block ">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -1,29 +0,0 @@
|
||||
<legend>Edit Calendar</legend>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<label for="title" class="col-lg-3 control-label">Title</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-check-input form-control" name="title" id="title" value="{title}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description" class="col-lg-3 control-label">Description</label>
|
||||
<div class="col-lg-6">
|
||||
<textarea class="form-control" name="description" maxlength="2000" rows="10" cols="50" id="description">{description}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description" class="col-lg-3 control-label">Timezone</label>
|
||||
<div class="col-lg-3">
|
||||
{timezoneSelect}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="color" class="col-lg-3 control-label">Calendar Color</label>
|
||||
<div class="col-lg-3 select-container" id="colorContainer">
|
||||
{colorSelect}
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block">Submit</button>
|
||||
</form>
|
@ -1,45 +0,0 @@
|
||||
<legend>Calendars</legend>
|
||||
<form action="{ROOT_URL}calendar/deleteCalendar" method="post">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 5%">ID</th>
|
||||
<th style="width: 20%">Title</th>
|
||||
<th style="width: 50%">Description</th>
|
||||
<th style="width: 5%"></th>
|
||||
<th style="width: 5%"></th>
|
||||
<th style="width: 5%"></th>
|
||||
<th style="width: 5%"></th>
|
||||
<th style="width: 5%">
|
||||
<input type="checkbox" onchange="checkAll(this)" name="check.br" value="CAL_[]"/>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{LOOP}
|
||||
<tr>
|
||||
<td align="center">{ID}</td>
|
||||
<td align="center">{title}</td>
|
||||
<td>{description}</td>
|
||||
<td><a href="{ROOT_URL}calendar/byMonth/{ID}" class="btn btn-sm btn-primary" role="button"><i class="glyphicon glyphicon-share-alt"></i></a></td>
|
||||
<td><a href="{ROOT_URL}calendar/calendar/{ID}" class="btn btn-sm btn-primary" role="button"><i class="glyphicon glyphicon-info-sign"></i></a></td>
|
||||
<td><a href="{ROOT_URL}calendar/editCalendar/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a></td>
|
||||
<td><a href="{ROOT_URL}calendar/deleteCalendar/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a></td>
|
||||
<td>
|
||||
<input type="checkbox" value="{ID}" name="CAL_[]">
|
||||
</td>
|
||||
</tr>
|
||||
{/LOOP}
|
||||
{ALT}
|
||||
<tr>
|
||||
<td align="center" colspan="7">
|
||||
No results to show.
|
||||
</td>
|
||||
</tr>
|
||||
{/ALT}
|
||||
</tbody>
|
||||
</table>
|
||||
<a href="{ROOT_URL}calendar/createCalendar" class="btn btn-sm btn-primary" role="button">Create</a>
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-sm btn-danger">Delete</button>
|
||||
</form>
|
||||
<br />
|
@ -1,42 +0,0 @@
|
||||
<div class="container col-md-4 col-lg-4">
|
||||
<div class="row">
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">Calendar</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
<div class="">
|
||||
<table class="table table-user-primary">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="left" width="200"><b>Title</b></td>
|
||||
<td align="right">{title}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Created</b></td>
|
||||
<td align="right">{DTC}{createdAt}{/DTC}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" colspan="2"><b>Description</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{description}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>TimeZone</b></td>
|
||||
<td align="right">{timezone}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
<a href="{ROOT_URL}calendar/deleteCalendar/{ID}" class="btn btn-md btn-danger" role="button">Delete</a>
|
||||
<a href="{ROOT_URL}calendar/editCalendar/{ID}" class="btn btn-md btn-warning" role="button">Edit</a>
|
||||
<a href="{ROOT_URL}calendar/byMonth/{ID}" class="btn btn-md btn-primary" role="button">View Events</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,20 +0,0 @@
|
||||
<div class="form-group">
|
||||
<label for="day" class="col-lg-3 control-label">All-Day Event</label>
|
||||
<div class="col-lg-3">
|
||||
<input class="" type="checkbox" name="allDay" id="allDay" value="true" {CHECKED:allDay=true}>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="month" class="col-lg-3 control-label">Event Start</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="date" name="date" id="date" class="form-control" value="{date}" />
|
||||
<input type="time" name="time" id="time" class="form-control" value="{time}" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="month" class="col-lg-3 control-label">Event End</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="date" name="endDate" id="endDate" class="form-control" value="{endDate}" />
|
||||
<input type="time" name="endTime" id="endTime" class="form-control" value="{endTime}" />
|
||||
</div>
|
||||
</div>
|
@ -1,37 +0,0 @@
|
||||
<legend>Create Event</legend>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
{calendarSelect}
|
||||
<div class="form-group">
|
||||
<label for="title" class="col-lg-3 control-label">Title</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="title" id="title">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description" class="col-lg-3 control-label">Description</label>
|
||||
<div class="col-lg-3">
|
||||
<textarea class="form-control" name="description" maxlength="2000" rows="6" cols="30" id="description"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="location" class="col-lg-3 control-label">Location</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="location" id="location">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="color" class="col-lg-3 control-label">Event Color</label>
|
||||
<div class="col-lg-3 select-container" id="colorContainer">
|
||||
{colorSelect}
|
||||
</div>
|
||||
</div>
|
||||
{dateSelect}
|
||||
{repeatSelect}
|
||||
<div class="form-group">
|
||||
<label for="submit" class="col-lg-3 control-label"></label>
|
||||
<div class="col-lg-3">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -1,31 +0,0 @@
|
||||
<legend>Edit Event</legend>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<label for="title" class="col-lg-3 control-label">Title</label>
|
||||
<div class="col-lg-3">
|
||||
<input type="text" class="form-control" name="title" id="title" value="{title}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description" class="col-lg-3 control-label">Description</label>
|
||||
<div class="col-lg-6">
|
||||
<textarea class="form-control" name="description" maxlength="2000" rows="10" cols="50" id="description">{description}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="location" class="col-lg-3 control-label">Location</label>
|
||||
<div class="col-lg-6">
|
||||
<input type="text" class="form-control" name="location" id="location" value="{location}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="color" class="col-lg-3 control-label">Event Color</label>
|
||||
<div class="col-lg-3 select-container" id="colorContainer">
|
||||
{colorSelect}
|
||||
</div>
|
||||
</div>
|
||||
{dateSelect}
|
||||
{repeatSelect}
|
||||
<input type="hidden" name="token" value="{TOKEN}">
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block">Submit</button>
|
||||
</form>
|
@ -1,34 +0,0 @@
|
||||
{PAGINATION}
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 10%">ID</th>
|
||||
<th style="width: 20%">Time</th>
|
||||
<th style="width: 40%">Title</th>
|
||||
<th style="width: 10%"></th>
|
||||
<th style="width: 10%"></th>
|
||||
<th style="width: 10%"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{LOOP}
|
||||
<tr>
|
||||
<td style="text-align: center;">{ID}</td>
|
||||
<td style="text-align: center;">{DTC}{event_time}{/DTC}</td>
|
||||
<td style="text-align: center;">{title}</td>
|
||||
<td><a href="{ROOT_URL}calendar/event/{ID}" class="btn btn-sm btn-primary" role="button"><i class="glyphicon glyphicon-open"></i></a></td>
|
||||
<td><a href="{ROOT_URL}calendar/editEvent/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a></td>
|
||||
<td><a href="{ROOT_URL}calendar/deleteEvent/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a></td>
|
||||
</tr>
|
||||
{/LOOP}
|
||||
{ALT}
|
||||
<tr>
|
||||
<td style="text-align: center;" colspan="6">
|
||||
No results to show.
|
||||
</td>
|
||||
</tr>
|
||||
{/ALT}
|
||||
</tbody>
|
||||
</table>
|
||||
{PAGINATION}
|
||||
<a href="{ROOT_URL}calendar/createEvent" class="btn btn-sm btn-primary" role="button">Create</a>
|
@ -1,52 +0,0 @@
|
||||
<div class="container col-md-4 col-lg-4">
|
||||
<div class="row">
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">Event</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
<table class="table table-user-primary">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="text-align: left;" width="200"><b>Title</b></td>
|
||||
<td style="text-align: right;">{title}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Created</b></td>
|
||||
<td style="text-align: right;">{DTC}{createdAt}{/DTC}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Event Time</b></td>
|
||||
<td style="text-align: right;">{DTC}{event_time}{/DTC}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;" colspan="2"><b>Description</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{description}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Location</b></td>
|
||||
<td style="text-align: right;">{location}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Frequency</b></td>
|
||||
<td style="text-align: right;">{repeatsText}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Calendar</b></td>
|
||||
<td style="text-align: right;">{calendarName}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
<a href="{ROOT_URL}calendar/deleteEvent/{ID}" class="btn btn-md btn-danger" role="button">Delete</a>
|
||||
<a href="{ROOT_URL}calendar/editEvent/{ID}" class="btn btn-md btn-warning" role="button">Edit</a>
|
||||
<a href="{ROOT_URL}calendar/byMonth/{calendar_id}" class="btn btn-md btn-primary" role="button">View Events</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,16 +0,0 @@
|
||||
<li class="pull-right dropdown">
|
||||
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
Calendars <span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="{ROOT_URL}calendar/{currentView}/">All</a></li>
|
||||
<li role="separator" class="divider"></li>
|
||||
{LOOP}
|
||||
<li><a href="{ROOT_URL}calendar/{currentView}/{ID}">{title}</a></li>
|
||||
{/LOOP}
|
||||
<li role="separator" class="divider"></li>
|
||||
<li><a href="{ROOT_URL}calendar/createCalendar">Create Calendar</a></li>
|
||||
<li><a href="{ROOT_URL}calendar/editCalendar/{calendarID}">Edit Calendar</a></li>
|
||||
<li><a href="{ROOT_URL}calendar/deleteCalendar/{calendarID}">Delete Calendar</a></li>
|
||||
</ul>
|
||||
</li>
|
@ -1,23 +0,0 @@
|
||||
<ul class="list-group">
|
||||
{LOOP}
|
||||
<li class="list-group-item btn-{displayColor}">
|
||||
<p style="text-align: center;">{title}</p>
|
||||
<p style="text-align: center;">{DTC}{event_time}{/DTC}</p>
|
||||
<p>
|
||||
<a href="{ROOT_URL}calendar/event/{ID}" class="btn btn-sm btn-primary" role="button"><i class="glyphicon glyphicon-open"></i></a>
|
||||
<a href="{ROOT_URL}calendar/editEvent/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a>
|
||||
<a href="{ROOT_URL}calendar/deleteEvent/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a>
|
||||
</p>
|
||||
</li>
|
||||
{/LOOP}
|
||||
{ALT}
|
||||
<li class="list-group-item">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
</li>
|
||||
{/ALT}
|
||||
<a href="{ROOT_URL}calendar/createEvent?calendar_id={calendarID}&month={currentMonth}&day={currentDay}" class="list-group-item list-group-item-success"><i class="glyphicon glyphicon-plus"></i></a>
|
||||
</ul>
|
@ -1,18 +0,0 @@
|
||||
<ul class="nav nav-pills">
|
||||
<li class="dropdown pull-right">
|
||||
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
Switch Date <span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<li><input type="date" name="date" id="date" class="form-control" value="{date}" /></li>
|
||||
<li role="separator" class="divider"></li>
|
||||
<li>
|
||||
<button name="submit" value="submit" type="submit" class="btn btn-primary center-block">
|
||||
Select Date
|
||||
</button>
|
||||
</li>
|
||||
</form>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
@ -1,12 +0,0 @@
|
||||
<span class="hour-body">
|
||||
{LOOP}
|
||||
<div class="hour-cell btn-{displayColor}">
|
||||
<p class="event-title">{title}</p>
|
||||
<a href="{ROOT_URL}calendar/event/{ID}" class="btn btn-sm btn-primary" role="button"><i class="glyphicon glyphicon-open"></i></a>
|
||||
<a href="{ROOT_URL}calendar/editEvent/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a>
|
||||
<a href="{ROOT_URL}calendar/deleteEvent/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a>
|
||||
</div>
|
||||
{/LOOP}
|
||||
{ALT}
|
||||
{/ALT}
|
||||
</span>
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user