cleanup
2
.gitignore
vendored
@ -63,4 +63,4 @@ vendor/canary/logs/*
|
|||||||
components/*
|
components/*
|
||||||
mailhog.log
|
mailhog.log
|
||||||
uploads/*
|
uploads/*
|
||||||
images/qr-codes/
|
images/qr-codes/*
|
||||||
|
Before Width: | Height: | Size: 117 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 47 KiB |
@ -1,121 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* app/controllers/messages.php
|
|
||||||
*
|
|
||||||
* This is the user messages controller.
|
|
||||||
*
|
|
||||||
* @version 5.0.1
|
|
||||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
|
||||||
* @link https://TheTempusProject.com
|
|
||||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
|
||||||
*/
|
|
||||||
namespace TheTempusProject\Controllers;
|
|
||||||
|
|
||||||
use TheTempusProject\Classes\Controller;
|
|
||||||
use TheTempusProject\Classes\Forms as FormChecker;
|
|
||||||
use TheTempusProject\Models\Message;
|
|
||||||
use TheTempusProject\Houdini\Classes\Components;
|
|
||||||
use TheTempusProject\Houdini\Classes\Views;
|
|
||||||
use TheTempusProject\Houdini\Classes\Issues;
|
|
||||||
use TheTempusProject\Bedrock\Functions\Check;
|
|
||||||
use TheTempusProject\Bedrock\Functions\Input;
|
|
||||||
use TheTempusProject\TheTempusProject as App;
|
|
||||||
use TheTempusProject\Hermes\Functions\Redirect;
|
|
||||||
use TheTempusProject\Bedrock\Functions\Session;
|
|
||||||
|
|
||||||
class Messages extends Controller {
|
|
||||||
private static $message;
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
parent::__construct();
|
|
||||||
self::$title = 'Messages';
|
|
||||||
self::$message = new Message;
|
|
||||||
if ( ! App::$isLoggedIn ) {
|
|
||||||
Session::flash( 'error', 'You do not have permission to access this page.' );
|
|
||||||
return Redirect::home();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function create() {
|
|
||||||
self::$title .= ' - New Message';
|
|
||||||
if ( Input::get( 'prepopuser' ) ) {
|
|
||||||
$data = Input::get( 'prepopuser' );
|
|
||||||
}
|
|
||||||
if ( !empty( $data ) && self::$user->checkUsername( $data ) ) {
|
|
||||||
Components::set( 'prepopuser', $data );
|
|
||||||
} else {
|
|
||||||
Components::set( 'prepopuser', '' );
|
|
||||||
}
|
|
||||||
if ( !Input::exists( 'submit' ) ) {
|
|
||||||
return Views::view( 'messages.create' );
|
|
||||||
}
|
|
||||||
if ( !FormChecker::check( 'newMessage' ) ) {
|
|
||||||
Issues::add( 'error', [ 'There was an problem sending your messages.' => Check::userErrors() ] );
|
|
||||||
return Views::view( 'messages.create' );
|
|
||||||
}
|
|
||||||
if ( self::$message->newThread( Input::post( 'toUser' ), Input::post( 'subject' ), Input::post( 'message' ) ) ) {
|
|
||||||
Issues::add( 'success', 'Message Sent.' );
|
|
||||||
} else {
|
|
||||||
Issues::add( 'notice', 'There was an problem sending your messages.' );
|
|
||||||
}
|
|
||||||
return $this->index();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function delete( $id = '' ) {
|
|
||||||
if ( Input::exists( 'T_' ) ) {
|
|
||||||
self::$message->delete( Input::post( 'T_' ) );
|
|
||||||
}
|
|
||||||
if ( Input::exists( 'F_' ) ) {
|
|
||||||
self::$message->delete( Input::post( 'F_' ) );
|
|
||||||
}
|
|
||||||
if ( Input::exists( 'ID' ) ) {
|
|
||||||
self::$message->delete( Input::get( 'ID' ) );
|
|
||||||
}
|
|
||||||
if ( !empty( $id ) ) {
|
|
||||||
self::$message->delete( $id );
|
|
||||||
}
|
|
||||||
return $this->index();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function index() {
|
|
||||||
Components::set( 'message_inbox', Views::simpleView( 'messages.inbox', self::$message->getInbox() ) );
|
|
||||||
Components::set( 'message_outbox', Views::simpleView( 'messages.outbox', self::$message->getOutbox() ) );
|
|
||||||
Views::view( 'messages.index' );
|
|
||||||
}
|
|
||||||
|
|
||||||
public function read( $id = '' ) {
|
|
||||||
self::$message->markRead( $id );
|
|
||||||
return $this->index();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function reply() {
|
|
||||||
if ( Input::exists( 'messageID' ) ) {
|
|
||||||
$data = Input::post( 'messageID' );
|
|
||||||
}
|
|
||||||
if ( !Check::id( $data ) ) {
|
|
||||||
Issues::add( 'error', 'There was an error with your request.' );
|
|
||||||
return $this->index();
|
|
||||||
}
|
|
||||||
self::$title .= ' - Reply to: ' . self::$message->messageTitle( $data );
|
|
||||||
if ( !Input::exists( 'message' ) ) {
|
|
||||||
Components::set( 'messageID', $data );
|
|
||||||
return Views::view( 'messages.reply' );
|
|
||||||
}
|
|
||||||
if ( !FormChecker::check( 'replyMessage' ) ) {
|
|
||||||
Issues::add( 'error', [ 'There was an problem sending your messages.' => Check::userErrors() ] );
|
|
||||||
Components::set( 'messageID', $data );
|
|
||||||
return Views::view( 'messages.reply' );
|
|
||||||
}
|
|
||||||
if ( !self::$message->newMessageReply( $data, Input::post( 'message' ) ) ) {
|
|
||||||
Issues::add( 'error', 'There was an error with your request.' );
|
|
||||||
return $this->index();
|
|
||||||
}
|
|
||||||
Issues::add( 'success', 'Reply Sent.' );
|
|
||||||
return $this->index();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function view( $id = '' ) {
|
|
||||||
self::$title = self::$message->messageTitle( $id );
|
|
||||||
return Views::view( 'messages.message', self::$message->getThread( $id, true ) );
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,454 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* app/models/message.php
|
|
||||||
*
|
|
||||||
* Houses all of the functions for the core messaging system.
|
|
||||||
*
|
|
||||||
* @version 5.0.1
|
|
||||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
|
||||||
* @link https://TheTempusProject.com
|
|
||||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
|
||||||
*/
|
|
||||||
namespace TheTempusProject\Models;
|
|
||||||
|
|
||||||
use TheTempusProject\Classes\DatabaseModel;
|
|
||||||
use TheTempusProject\Houdini\Classes\Components;
|
|
||||||
use TheTempusProject\Houdini\Classes\Views;
|
|
||||||
use TheTempusProject\Canary\Bin\Canary as Debug;
|
|
||||||
use TheTempusProject\Bedrock\Functions\Check;
|
|
||||||
use TheTempusProject\Bedrock\Functions\Sanitize;
|
|
||||||
use TheTempusProject\TheTempusProject as App;
|
|
||||||
use TheTempusProject\Canary\Classes\CustomException;
|
|
||||||
|
|
||||||
class Message extends DatabaseModel {
|
|
||||||
public $tableName = 'messages';
|
|
||||||
public $databaseMatrix = [
|
|
||||||
[ 'userTo', 'int', '11' ],
|
|
||||||
[ 'userFrom', 'int', '11' ],
|
|
||||||
[ 'parent', 'int', '11' ],
|
|
||||||
[ 'sent', 'int', '10' ],
|
|
||||||
[ 'lastReply', 'int', '10' ],
|
|
||||||
[ 'senderDeleted', 'int', '1' ],
|
|
||||||
[ 'recieverDeleted', 'int', '1' ],
|
|
||||||
[ 'isRead', 'int', '1' ],
|
|
||||||
[ 'message', 'text', '' ],
|
|
||||||
[ 'subject', 'text', '' ],
|
|
||||||
];
|
|
||||||
private $messages;
|
|
||||||
private $usernames;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The model constructor.
|
|
||||||
*/
|
|
||||||
public function __construct() {
|
|
||||||
parent::__construct();
|
|
||||||
self::$message = $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the most recent relative message in a thread
|
|
||||||
*
|
|
||||||
* @param int $parent - the id of the parent message
|
|
||||||
* @param string $user - the id of the relative user
|
|
||||||
* @return object
|
|
||||||
*/
|
|
||||||
public function getLatestMessage( $parent, $user, $type = null ) {
|
|
||||||
if ( !Check::id( $parent ) ) {
|
|
||||||
Debug::info( 'Invalid message ID' );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if ( !Check::id( $user ) ) {
|
|
||||||
Debug::info( 'Invalid user ID' );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$messageData = self::$db->get( $this->tableName, [ 'ID', '=', $parent ] );
|
|
||||||
if ( $messageData->count() == 0 ) {
|
|
||||||
Debug::info( 'Message not found.' );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$message = $messageData->first();
|
|
||||||
$params = [ 'parent', '=', $parent ];
|
|
||||||
if ( $type !== null ) {
|
|
||||||
$params = array_merge( $params, [ 'AND', $type, '=', $user ] );
|
|
||||||
}
|
|
||||||
$messageData = self::$db->get( $this->tableName, $params, 'ID', 'DESC', [ 0, 1 ] );
|
|
||||||
if ( $messageData->count() != 0 ) {
|
|
||||||
if ( $messageData->first()->recieverDeleted == 0 ) {
|
|
||||||
$message = $messageData->first();
|
|
||||||
} else {
|
|
||||||
$message->recieverDeleted = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $message;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This calls a view of the requested message.
|
|
||||||
*
|
|
||||||
* @param int $ID - The message ID you are looking for.
|
|
||||||
* @return null
|
|
||||||
*/
|
|
||||||
public function getThread( $id, $markRead = false ) {
|
|
||||||
if ( !Check::id( $id ) ) {
|
|
||||||
Debug::info( 'Invalid ID' );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$messageData = self::$db->get( $this->tableName, [ 'ID', '=', $id ] );
|
|
||||||
if ( $messageData->count() == 0 ) {
|
|
||||||
Debug::info( 'Message not found.' );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$message = $messageData->first();
|
|
||||||
if ( $message->userTo == App::$activeUser->ID ) {
|
|
||||||
$permissionCheck = 1;
|
|
||||||
if ( $message->recieverDeleted == 1 ) {
|
|
||||||
Debug::info( 'User has already deleted this message.' );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( $message->userFrom == App::$activeUser->ID ) {
|
|
||||||
$permissionCheck = 1;
|
|
||||||
if ( $message->senderDeleted == 1 ) {
|
|
||||||
Debug::info( 'User has already deleted this message.' );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( empty( $permissionCheck ) ) {
|
|
||||||
Debug::info( 'You do not have permission to view this message.' );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if ( $message->parent != 0 ) {
|
|
||||||
$find = $message->parent;
|
|
||||||
} else {
|
|
||||||
$find = $message->ID;
|
|
||||||
}
|
|
||||||
$messageData = self::$db->get( $this->tableName, [ 'ID', '=', $find, 'OR', 'Parent', '=', $find ], 'ID', 'ASC' )->results();
|
|
||||||
Components::set( 'PID', $find );
|
|
||||||
|
|
||||||
if ( $markRead == true ) {
|
|
||||||
foreach ( $messageData as $instance ) {
|
|
||||||
$this->markRead( $instance->ID );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $this->filter( $messageData );
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getInbox( $limit = null ) {
|
|
||||||
if ( empty( $limit ) ) {
|
|
||||||
$limit = 10;
|
|
||||||
}
|
|
||||||
$limit = [ 0, $limit ];
|
|
||||||
$messageData = self::$db->get(
|
|
||||||
$this->tableName,
|
|
||||||
[
|
|
||||||
'parent', '=', 0,
|
|
||||||
'AND',
|
|
||||||
'userFrom', '=', App::$activeUser->ID,
|
|
||||||
'OR',
|
|
||||||
'parent', '=', 0,
|
|
||||||
'AND',
|
|
||||||
'userTo', '=', App::$activeUser->ID,
|
|
||||||
],
|
|
||||||
'ID',
|
|
||||||
'DESC',
|
|
||||||
$limit
|
|
||||||
);
|
|
||||||
if ( $messageData->count() == 0 ) {
|
|
||||||
Debug::info( 'getInbox: No messages found' );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$filters = [
|
|
||||||
'importantUser' => App::$activeUser->ID,
|
|
||||||
'deleted' => false,
|
|
||||||
'type' => 'userTo',
|
|
||||||
];
|
|
||||||
return $this->filter( $messageData->results(), $filters );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function calls the view for the message outbox.
|
|
||||||
*
|
|
||||||
* @return null
|
|
||||||
*/
|
|
||||||
public function getOutbox( $limit = null ) {
|
|
||||||
if ( empty( $limit ) ) {
|
|
||||||
$limit = 10;
|
|
||||||
}
|
|
||||||
$limit = [ 0, $limit ];
|
|
||||||
$messageData = self::$db->get(
|
|
||||||
$this->tableName,
|
|
||||||
[
|
|
||||||
'parent', '=', 0,
|
|
||||||
'AND',
|
|
||||||
'userFrom', '=', App::$activeUser->ID,
|
|
||||||
],
|
|
||||||
'ID',
|
|
||||||
'DESC',
|
|
||||||
$limit
|
|
||||||
);
|
|
||||||
if ( $messageData->count() == 0 ) {
|
|
||||||
Debug::info( 'getOutbox: No messages found' );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$filters = [
|
|
||||||
'importantUser' => App::$activeUser->ID,
|
|
||||||
'deleted' => false,
|
|
||||||
'type' => 'userFrom',
|
|
||||||
];
|
|
||||||
return $this->filter( $messageData->results(), $filters );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function is to prep our messages for display. An array of raw messages
|
|
||||||
* sent through this function will automatically have all the user ID's filter
|
|
||||||
* into actual usernames.
|
|
||||||
*
|
|
||||||
* @param $messageArray - This is an array of messages that need to be processed.
|
|
||||||
* @return array - It will return the same message array after being processed.
|
|
||||||
* @todo add filtering for BB-code.
|
|
||||||
*/
|
|
||||||
public function filter( $messageArray, $filters = [] ) {
|
|
||||||
$out = [];
|
|
||||||
foreach ( $messageArray as $message ) {
|
|
||||||
if ( !is_object( $message ) ) {
|
|
||||||
$message = $messageArray;
|
|
||||||
$end = true;
|
|
||||||
}
|
|
||||||
if ( isset( $filters['type'] ) && isset( $filters['importantUser'] ) ) {
|
|
||||||
$type = $filters['type'];
|
|
||||||
} else {
|
|
||||||
$type = null;
|
|
||||||
}
|
|
||||||
if ( isset( $filters['importantUser'] ) ) {
|
|
||||||
$user = $filters['importantUser'];
|
|
||||||
} else {
|
|
||||||
$user = App::$activeUser->ID;
|
|
||||||
}
|
|
||||||
if ( $message->parent == 0 ) {
|
|
||||||
$last = $this->getLatestMessage( $message->ID, $user, $type );
|
|
||||||
} else {
|
|
||||||
$last = $message;
|
|
||||||
}
|
|
||||||
if ( $type != null && $message->$type != $user && $last->$type != $user ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ( isset( $filters['deleted'] ) && $filters['deleted'] == false ) {
|
|
||||||
if ( $type == 'userFrom' ) {
|
|
||||||
if ( $last->senderDeleted == 1 ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( $type == 'userTo' ) {
|
|
||||||
if ( $last->recieverDeleted == 1 ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$messageOut = (array) $message;
|
|
||||||
$short = explode( ' ', Sanitize::contentShort( $message->message ) );
|
|
||||||
$summary = implode( ' ', array_splice( $short, 0, 25 ) );
|
|
||||||
if ( count( $short, 1 ) >= 25 ) {
|
|
||||||
$messageOut['summary'] = $summary . '...';
|
|
||||||
} else {
|
|
||||||
$messageOut['summary'] = $summary;
|
|
||||||
}
|
|
||||||
if ( $last->isRead == 0 ) {
|
|
||||||
$messageOut['unreadBadge'] = Views::simpleView( 'messages.unreadBadge' );
|
|
||||||
} else {
|
|
||||||
$messageOut['unreadBadge'] = '';
|
|
||||||
}
|
|
||||||
$messageOut['fromAvatar'] = self::$user->getAvatar( $message->userFrom );
|
|
||||||
$messageOut['userTo'] = self::$user->getUsername( $message->userTo );
|
|
||||||
$messageOut['userToPretty'] = \ucfirst( $messageOut['userTo'] );
|
|
||||||
$messageOut['userFrom'] = self::$user->getUsername( $message->userFrom );
|
|
||||||
$messageOut['userFromPretty'] = \ucfirst( $messageOut['userFrom'] );
|
|
||||||
$out[] = (object) $messageOut;
|
|
||||||
if ( !empty( $end ) ) {
|
|
||||||
$out = $out[0];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to check input and save messages to the DB.
|
|
||||||
*
|
|
||||||
* @param string $data - Username of the person receiving the sent message.
|
|
||||||
* @return function
|
|
||||||
*/
|
|
||||||
public function newThread( $to, $subject, $message ) {
|
|
||||||
if ( !self::$user->usernameExists( $to ) ) {
|
|
||||||
Debug::info( 'Message->sendMessage: User not found.' );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$fields = [
|
|
||||||
'userTo' => self::$user->getID( $to ),
|
|
||||||
'userFrom' => App::$activeUser->ID,
|
|
||||||
'parent' => 0,
|
|
||||||
'sent' => time(),
|
|
||||||
'lastReply' => time(),
|
|
||||||
'senderDeleted' => 0,
|
|
||||||
'recieverDeleted' => 0,
|
|
||||||
'isRead' => 0,
|
|
||||||
'subject' => $subject,
|
|
||||||
'message' => $message,
|
|
||||||
];
|
|
||||||
if ( !self::$db->insert( $this->tableName, $fields ) ) {
|
|
||||||
new CustomException( 'messageSend' );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getUnreadCount( $userId ) {
|
|
||||||
$result = self::$db->get(
|
|
||||||
$this->tableName,
|
|
||||||
[
|
|
||||||
'userTo', '=', $userId,
|
|
||||||
'AND',
|
|
||||||
'isRead', '=', 0,
|
|
||||||
'AND',
|
|
||||||
'parent', '=', 0,
|
|
||||||
'AND',
|
|
||||||
'recieverDeleted', '=', 0,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
return $result->count();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function unreadCount() {
|
|
||||||
if ( empty( App::$activeUser->ID ) ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return $this->getUnreadCount( App::$activeUser->ID );
|
|
||||||
}
|
|
||||||
|
|
||||||
public function hasPermission( $id ) {
|
|
||||||
if ( !Check::id( $id ) ) {
|
|
||||||
Debug::info( 'Invalid ID' );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$messageData = self::$db->get( 'messages', [ 'ID', '=', $id ] );
|
|
||||||
if ( $messageData->count() == 0 ) {
|
|
||||||
Debug::info( 'Message not found.' );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$message = $messageData->first();
|
|
||||||
if ( $message->userTo != App::$activeUser->ID && $message->userFrom != App::$activeUser->ID ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Marks a message as read. This is setup to only work
|
|
||||||
* if the message was sent to the active user.
|
|
||||||
*
|
|
||||||
* @param int - The message ID you are marking as read.
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function markRead( $id ) {
|
|
||||||
if ( !Check::id( $id ) ) {
|
|
||||||
Debug::info( 'Invalid ID' );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$result = self::$db->get( $this->tableName, [ 'ID', '=', $id, 'AND', 'userTo', '=', App::$activeUser->ID, 'AND', 'isRead', '=', '0' ] );
|
|
||||||
if ( $result->count() == 0 ) {
|
|
||||||
Debug::info( 'Failed to mark message as read.' );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if ( !self::$db->update( $this->tableName, $id, [ 'isRead' => 1 ] ) ) {
|
|
||||||
Debug::error( 'Failed to mark message as read.' );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function newMessageReply( $id, $message ) {
|
|
||||||
if ( !$this->hasPermission( $id ) ) {
|
|
||||||
Debug::info( 'Permission Denied.' );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$messageData = self::$db->get( $this->tableName, [ 'ID', '=', $id ] )->first();
|
|
||||||
if ( $messageData->userTo == App::$activeUser->ID ) {
|
|
||||||
$recipient = $messageData->userFrom;
|
|
||||||
} else {
|
|
||||||
$recipient = $messageData->userTo;
|
|
||||||
}
|
|
||||||
if ( $recipient === App::$activeUser->ID ) {
|
|
||||||
Debug::info( 'Cannot send messages to yourself' );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if ( !self::$db->update( $this->tableName, $messageData->ID, [ 'lastReply' => time() ] ) ) {
|
|
||||||
new CustomException( 'messagesReplyUpdate' );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$fields = [
|
|
||||||
'senderDeleted' => 0,
|
|
||||||
'recieverDeleted' => 0,
|
|
||||||
'isRead' => 0,
|
|
||||||
'userTo' => $recipient,
|
|
||||||
'userFrom' => App::$activeUser->ID,
|
|
||||||
'message' => $message,
|
|
||||||
'subject' => 're: ' . $messageData->subject,
|
|
||||||
'sent' => time(),
|
|
||||||
'parent' => $messageData->ID,
|
|
||||||
'lastReply' => time(),
|
|
||||||
];
|
|
||||||
if ( !self::$db->insert( $this->tableName, $fields ) ) {
|
|
||||||
new CustomException( 'messagesReplySend' );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function messageTitle( $id ) {
|
|
||||||
if ( !$this->hasPermission( $id ) ) {
|
|
||||||
Debug::info( 'Permission Denied.' );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$message = self::$db->get( $this->tableName, [ 'ID', '=', $id ] )->first();
|
|
||||||
return $message->subject;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to delete messages from the DB.
|
|
||||||
*
|
|
||||||
* @param int $data - The ID of the message you are trying to delete.
|
|
||||||
* @todo - done at 5 am after no sleep. This can be simplified a lot, i just wanted a working solution ASAP
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function delete( $data ) {
|
|
||||||
if ( !is_array( $data ) ) {
|
|
||||||
$data = [ $data ];
|
|
||||||
}
|
|
||||||
foreach ( $data as $instance ) {
|
|
||||||
if ( !Check::id( $instance ) ) {
|
|
||||||
$error = true;
|
|
||||||
}
|
|
||||||
if ( !$this->hasPermission( $instance ) ) {
|
|
||||||
Debug::info( 'Permission Denied.' );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$message = self::$db->get( $this->tableName, [ 'ID', '=', $instance ] )->first();
|
|
||||||
if ( $message->userTo == App::$activeUser->ID ) {
|
|
||||||
$fields = [ 'recieverDeleted' => '1' ];
|
|
||||||
} else {
|
|
||||||
$fields = [ 'senderDeleted' => '1' ];
|
|
||||||
}
|
|
||||||
if ( !self::$db->update( $this->tableName, $instance, $fields ) ) {
|
|
||||||
$error = true;
|
|
||||||
}
|
|
||||||
Debug::info( "message Deleted: $instance" );
|
|
||||||
if ( !empty( $end ) ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( !empty( $error ) ) {
|
|
||||||
Debug::info( 'There was an error deleting one or more messages.' );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* app/plugins/messages/plugin.php
|
|
||||||
*
|
|
||||||
* This houses all of the main plugin info and functionality.
|
|
||||||
*
|
|
||||||
* @package TP Messages
|
|
||||||
* @version 5.0.1
|
|
||||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
|
||||||
* @link https://TheTempusProject.com
|
|
||||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
|
||||||
*/
|
|
||||||
namespace TheTempusProject\Plugins;
|
|
||||||
|
|
||||||
use TheTempusProject\TheTempusProject as App;
|
|
||||||
use TheTempusProject\Classes\Plugin;
|
|
||||||
use TheTempusProject\Models\Message;
|
|
||||||
use TheTempusProject\Houdini\Classes\Components;
|
|
||||||
use TheTempusProject\Houdini\Classes\Views;
|
|
||||||
|
|
||||||
class Messages extends Plugin {
|
|
||||||
public $pluginName = 'TP Messages';
|
|
||||||
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 messaging system.';
|
|
||||||
public $permissionMatrix = [
|
|
||||||
'sendMessages' => [
|
|
||||||
'pretty' => 'Can send Messages',
|
|
||||||
'default' => false,
|
|
||||||
],
|
|
||||||
];
|
|
||||||
private static $loaded = false;
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
if ( ! self::$loaded ) {
|
|
||||||
$messages = new Message;
|
|
||||||
Components::set( 'MESSAGE_COUNT', $messages->unreadCount() );
|
|
||||||
if ( $messages->unreadCount() > 0 ) {
|
|
||||||
$messageBadge = Views::simpleView( 'messages.badge' );
|
|
||||||
} else {
|
|
||||||
$messageBadge = '';
|
|
||||||
}
|
|
||||||
Components::set( 'MBADGE', $messageBadge );
|
|
||||||
if ( App::$isLoggedIn ) {
|
|
||||||
Components::set( 'RECENT_MESSAGES', Views::simpleView( 'messages.nav.recentMessagesDropdown', $messages->getInbox( 5 ) ) );
|
|
||||||
} else {
|
|
||||||
Components::set( 'RECENT_MESSAGES', '' );
|
|
||||||
}
|
|
||||||
App::$topNavRight .= '{RECENT_MESSAGES}';
|
|
||||||
App::$topNavRightDropdown .= '<li><a href="{ROOT_URL}messages" class="dropdown-item"><i class="fa fa-fw fa-envelope"></i> Inbox {MBADGE}</a></li>';
|
|
||||||
self::$loaded = true;
|
|
||||||
}
|
|
||||||
parent::__construct();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
<span class="badge bg-danger rounded-pill">{MESSAGE_COUNT}</span>
|
|
@ -1,73 +0,0 @@
|
|||||||
<div class="m-2 m-lg-4">
|
|
||||||
<div class="col-12 mx-5 col-sm-10 col-lg-8 mx-auto p-4 rounded shadow-sm context-main-bg">
|
|
||||||
<nav aria-label="breadcrumb">
|
|
||||||
<ol class="breadcrumb">
|
|
||||||
<li class="breadcrumb-item">
|
|
||||||
<a href="{ROOT_URL}messages" class="text-decoration-none">
|
|
||||||
Messages
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="breadcrumb-item active" aria-current="page">
|
|
||||||
Create
|
|
||||||
</li>
|
|
||||||
</ol>
|
|
||||||
</nav>
|
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-md-6 col-lg-6">
|
|
||||||
<form method="post" class="needs-validation">
|
|
||||||
<legend class="mb-3">New Message</legend>
|
|
||||||
<fieldset>
|
|
||||||
<!-- To User Field -->
|
|
||||||
<div class="mb-3 row">
|
|
||||||
<label for="toUser" class="col-sm-6 col-form-label">To:</label>
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
class="form-control"
|
|
||||||
name="toUser"
|
|
||||||
id="toUser"
|
|
||||||
value="{prepopuser}"
|
|
||||||
required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Subject Field -->
|
|
||||||
<div class="mb-3 row">
|
|
||||||
<label for="subject" class="col-sm-6 col-form-label">Subject:</label>
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
class="form-control"
|
|
||||||
name="subject"
|
|
||||||
id="subject"
|
|
||||||
required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Message Field -->
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="message" class="form-label">Message:</label>
|
|
||||||
<textarea
|
|
||||||
class="form-control"
|
|
||||||
name="message"
|
|
||||||
id="message"
|
|
||||||
rows="6"
|
|
||||||
maxlength="2000"
|
|
||||||
required></textarea>
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
|
||||||
<input type="hidden" name="token" value="{TOKEN}">
|
|
||||||
<div class="text-center text-md-start">
|
|
||||||
<button
|
|
||||||
type="submit"
|
|
||||||
name="submit"
|
|
||||||
value="submit"
|
|
||||||
class="btn btn-primary btn-lg">
|
|
||||||
Send
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,40 +0,0 @@
|
|||||||
<h2>Inbox</h2>
|
|
||||||
<form action="{ROOT_URL}messages/delete" method="post">
|
|
||||||
<table class="table table-striped text-center">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th style="width: 15%">From</th>
|
|
||||||
<th style="width: 40%">Subject</th>
|
|
||||||
<th style="width: 20%">Last Reply</th>
|
|
||||||
<th style="width: 10%"></th>
|
|
||||||
<th style="width: 10%"></th>
|
|
||||||
<th style="width: 5%">
|
|
||||||
<INPUT type="checkbox" onchange="checkAll(this)" name="check.t" value="T_[]"/>
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{LOOP}
|
|
||||||
<tr {unreadBadge}>
|
|
||||||
<td><a href="{ROOT_URL}home/profile/{userFrom}" class="text-decoration-none">{userFromPretty}</a></td>
|
|
||||||
<td><a href="{ROOT_URL}messages/view/{ID}" class="text-decoration-none">{subject}</a></td>
|
|
||||||
<td>{DTC date}{lastReply}{/DTC}</td>
|
|
||||||
<td><a href="{ROOT_URL}messages/read/{ID}" class="btn btn-sm btn-info"><i class="fa-solid fa-envelope-open"></i></a></td>
|
|
||||||
<td><a href="{ROOT_URL}messages/delete/{ID}" class="btn btn-sm btn-danger"><i class="fa fa-fw fa-trash"></i></a></td>
|
|
||||||
<td>
|
|
||||||
<input type="checkbox" value="{ID}" name="T_[]">
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{/LOOP}
|
|
||||||
{ALT}
|
|
||||||
<tr>
|
|
||||||
<td align="center" colspan="6">
|
|
||||||
No Messages.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{/ALT}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<button name="submit" value="submit" type="submit" class="btn btn-sm btn-danger"><i class="fa fa-fw fa-trash"></i></button>
|
|
||||||
<a href="{ROOT_URL}messages/create" class="btn btn-sm btn-primary">New message</a>
|
|
||||||
</form>
|
|
@ -1,10 +0,0 @@
|
|||||||
<div class="m-2 m-lg-4">
|
|
||||||
<div class="col-12 col-sm-10 col-lg-8 mx-auto p-md-2 p-lg-4 rounded shadow-sm context-main-bg context-main">
|
|
||||||
<div class="my-3 p-3">
|
|
||||||
{message_inbox}
|
|
||||||
</div>
|
|
||||||
<div class="my-3 p-3">
|
|
||||||
{message_outbox}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,53 +0,0 @@
|
|||||||
<div class="m-2 m-lg-4">
|
|
||||||
<div class="col-12 mx-5 col-sm-10 col-lg-8 mx-auto p-4 rounded shadow-sm context-main-bg context-main">
|
|
||||||
<nav aria-label="breadcrumb">
|
|
||||||
<ol class="breadcrumb">
|
|
||||||
<li class="breadcrumb-item">
|
|
||||||
<a href="{ROOT_URL}messages" class="text-decoration-none">
|
|
||||||
Messages
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="breadcrumb-item active" aria-current="page">
|
|
||||||
View
|
|
||||||
</li>
|
|
||||||
</ol>
|
|
||||||
</nav>
|
|
||||||
<div class="card panel-primary col-lg-8 mx-auto text-center">
|
|
||||||
{LOOP}
|
|
||||||
{SINGLE}
|
|
||||||
<div class="card-header context-second-bg">
|
|
||||||
<p class="card-title context-main text-center h3">{subject}</p>
|
|
||||||
</div>
|
|
||||||
{/SINGLE}
|
|
||||||
<div class="card-body context-other-bg">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-4 col-lg-3 text-center">
|
|
||||||
<a href="{ROOT_URL}home/profile/{userFrom}" class="text-decoration-none">{userFromPretty}</a><br>
|
|
||||||
<img alt="User Pic" src="{ROOT_URL}{fromAvatar}" class="img-circle img-fluid mt-2">
|
|
||||||
</div>
|
|
||||||
<div class="col-8 col-lg-9 text-start">
|
|
||||||
{message}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-footer context-second-bg">
|
|
||||||
{ADMIN}
|
|
||||||
<div class="d-flex justify-content-between">
|
|
||||||
<div class="">
|
|
||||||
{ID}
|
|
||||||
</div>
|
|
||||||
<div class="">
|
|
||||||
{DTC}{sent}{/DTC}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/ADMIN}
|
|
||||||
</div>
|
|
||||||
{/LOOP}
|
|
||||||
</div>
|
|
||||||
<form action="{ROOT_URL}messages/reply" method="post">
|
|
||||||
<input type="hidden" name="token" value="{TOKEN}">
|
|
||||||
<input type="hidden" name="messageID" value="{PID}">
|
|
||||||
<button name="submit" value="reply" type="submit" class="btn btn-md btn-primary my-4">Reply</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,46 +0,0 @@
|
|||||||
<div class="dropdown nav-item mx-2 my-2 my-lg-0">
|
|
||||||
<a
|
|
||||||
href="#"
|
|
||||||
class="d-flex align-items-center text-white text-decoration-none dropdown-toggle"
|
|
||||||
id="messagesDropdown"
|
|
||||||
data-bs-toggle="dropdown"
|
|
||||||
aria-haspopup="true"
|
|
||||||
aria-expanded="false">
|
|
||||||
<i class="fa fa-fw fa-envelope"></i><span class="">{MBADGE}</span>
|
|
||||||
</a>
|
|
||||||
<ul class="dropdown-menu dropdown-menu-dark dropdown-menu-end text-small shadow" aria-labelledby="messagesDropdown">
|
|
||||||
{LOOP}
|
|
||||||
<!-- Message Item -->
|
|
||||||
<li>
|
|
||||||
<a href="{ROOT_URL}messages/view/{ID}" class="dropdown-item">
|
|
||||||
<div class="d-flex">
|
|
||||||
<h5 class="media-heading text-start">
|
|
||||||
<img class="" style="width: 40px;" src="{ROOT_URL}{fromAvatar}" alt="">
|
|
||||||
<strong>{userFrom}</strong>
|
|
||||||
</h5>
|
|
||||||
<div class="text-end">
|
|
||||||
<div class="media-body">
|
|
||||||
<p class="small text-muted mb-1"><i class="fa fa-clock-o me-1"></i> {DTC}{lastReply}{/DTC}</p>
|
|
||||||
<span>{summary}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{/LOOP}
|
|
||||||
{ALT}
|
|
||||||
<li class="px-3 text-center">
|
|
||||||
<strong>No Messages</strong>
|
|
||||||
</li>
|
|
||||||
{/ALT}
|
|
||||||
<!-- Footer -->
|
|
||||||
<li>
|
|
||||||
<hr class="dropdown-divider">
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="/messages" class="dropdown-item text-center">
|
|
||||||
Read All New Messages
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
@ -1,37 +0,0 @@
|
|||||||
<h2>Outbox</h2>
|
|
||||||
<form action="{ROOT_URL}messages/delete" method="post">
|
|
||||||
<table class="table table-striped text-center">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th style="width: 20%">To</th>
|
|
||||||
<th style="width: 40%">Subject</th>
|
|
||||||
<th style="width: 20%">Sent</th>
|
|
||||||
<th style="width: 10%"></th>
|
|
||||||
<th style="width: 10%">
|
|
||||||
<INPUT type="checkbox" onchange="checkAll(this)" name="check.e" value="F_[]"/>
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{LOOP}
|
|
||||||
<tr>
|
|
||||||
<td><a href="{ROOT_URL}home/profile/{userTo}" class="text-decoration-none">{userToPretty}</a></td>
|
|
||||||
<td><a href="{ROOT_URL}messages/view/{ID}" class="text-decoration-none">{subject}</a></td>
|
|
||||||
<td>{DTC date}{sent}{/DTC}</td>
|
|
||||||
<td><a href="{ROOT_URL}messages/delete/{ID}" class="btn btn-sm btn-danger"><i class="fa fa-fw fa-trash"></i></a></td>
|
|
||||||
<td>
|
|
||||||
<input type="checkbox" value="{ID}" name="F_[]">
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{/LOOP}
|
|
||||||
{ALT}
|
|
||||||
<tr>
|
|
||||||
<td align="center" colspan="6">
|
|
||||||
No Messages
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{/ALT}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<button name="submit" value="submit" type="submit" class="btn btn-sm btn-danger"><i class="fa fa-fw fa-trash"></i></button>
|
|
||||||
</form>
|
|
@ -1,18 +0,0 @@
|
|||||||
<div class="context-main context-main-bg col-8 offset-2 my-3 p-3">
|
|
||||||
<form method="post">
|
|
||||||
<legend class="text-center">Reply</legend>
|
|
||||||
<fieldset>
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="col-6 offset-3">
|
|
||||||
<label for="message" class="control-label">Message:</label>
|
|
||||||
<textarea class="form-control" name="message" maxlength="2000" rows="10" cols="50" id="message"></textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
|
||||||
<input type="hidden" name="messageID" value="{messageID}">
|
|
||||||
<input type="hidden" name="token" value="{TOKEN}">
|
|
||||||
<div class="text-center">
|
|
||||||
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block my-3">Send</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
@ -1 +0,0 @@
|
|||||||
class="bg-info"
|
|
@ -1,32 +0,0 @@
|
|||||||
<div class="container py-5">
|
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-lg-8 text-center">
|
|
||||||
<!-- Success Icon -->
|
|
||||||
<div class="mb-4">
|
|
||||||
<i class="fa fa-check-circle text-success display-3"></i>
|
|
||||||
</div>
|
|
||||||
<!-- Title -->
|
|
||||||
<h1 class="display-5 fw-bold text-success">Success</h1>
|
|
||||||
<!-- Subtitle -->
|
|
||||||
<h3 class="mt-3">
|
|
||||||
The Tempus Project has been successfully installed.
|
|
||||||
</h3>
|
|
||||||
<p class="lead mt-3">
|
|
||||||
You can now log in and manage your site or jump straight into building your new features!
|
|
||||||
</p>
|
|
||||||
<!-- Info Readout Placeholder -->
|
|
||||||
<p class="mt-4 text-muted">
|
|
||||||
<em>Some plugins may need additional configuration and there are already some pre-made resources to get you started. (Both in the files and the Admin Panel)</em>
|
|
||||||
</p>
|
|
||||||
<!-- Call-to-Action Buttons -->
|
|
||||||
<div class="d-flex justify-content-center gap-3 mt-4">
|
|
||||||
<a href="/home/login" class="btn btn-success btn-lg">
|
|
||||||
<i class="fa fa-sign-in-alt me-2"></i> Log In
|
|
||||||
</a>
|
|
||||||
<a href="/home/index" class="btn btn-outline-success btn-lg">
|
|
||||||
<i class="fa fa-cogs me-2"></i> Go to Homepage
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,44 +0,0 @@
|
|||||||
<div class="context-main-bg my-3 pb-3 rounded col-10 offset-1">
|
|
||||||
{installer-nav}
|
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-md-10">
|
|
||||||
<legend class="my-3 text-center">Configure</legend>
|
|
||||||
<form method="post" enctype="multipart/form-data">
|
|
||||||
<fieldset>
|
|
||||||
<div class="mb-3 col-md-4 offset-md-4">
|
|
||||||
<label for="siteName" class="form-label">Site Name:</label>
|
|
||||||
<input class="form-control" type="text" name="siteName" id="siteName" value="">
|
|
||||||
</div>
|
|
||||||
<div class="mb-3 col-md-4 offset-md-4">
|
|
||||||
<label for="logo" class="form-label">Logo (200 x 200px):</label>
|
|
||||||
<input class="form-control" type="file" name="logo" id="logo">
|
|
||||||
</div>
|
|
||||||
<div class="mb-3 col-md-4 offset-md-4">
|
|
||||||
<label for="dbPrefix" class="form-label">Database Table Prefix:</label>
|
|
||||||
<input class="form-control" type="text" name="dbPrefix" id="dbPrefix" value="">
|
|
||||||
</div>
|
|
||||||
<div class="mb-3 col-md-4 offset-md-4">
|
|
||||||
<label for="dbHost" class="form-label">Database Host:</label>
|
|
||||||
<input class="form-control" type="text" name="dbHost" id="dbHost" value="">
|
|
||||||
</div>
|
|
||||||
<div class="mb-3 col-md-4 offset-md-4">
|
|
||||||
<label for="dbName" class="form-label">Database Name:</label>
|
|
||||||
<input class="form-control" type="text" name="dbName" id="dbName" value="">
|
|
||||||
</div>
|
|
||||||
<div class="mb-3 col-md-4 offset-md-4">
|
|
||||||
<label for="dbUsername" class="form-label">Database Username:</label>
|
|
||||||
<input class="form-control" type="text" name="dbUsername" id="dbUsername" value="">
|
|
||||||
</div>
|
|
||||||
<div class="mb-3 col-md-4 offset-md-4">
|
|
||||||
<label for="dbPassword" class="form-label">Database Password:</label>
|
|
||||||
<input class="form-control" type="password" name="dbPassword" id="dbPassword">
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
|
||||||
<input type="hidden" name="token" value="{TOKEN}">
|
|
||||||
<div class="text-center mb-3">
|
|
||||||
<button class="btn btn-lg btn-primary center-block" type="submit" name="submit" value="submit">Save</button><br>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,37 +0,0 @@
|
|||||||
<div class="context-main-bg my-3 pb-3 rounded col-10 offset-1">
|
|
||||||
{installer-nav}
|
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-md-10">
|
|
||||||
<p class="my-4">All models are required for proper installation of The Tempus Project. In this step, we will add the database tables required for these models. In the next step, you'll be able to select which plugins you would like installed.</p>
|
|
||||||
<form method="post">
|
|
||||||
<table class="table table-striped">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th class="px-5" style="width: 70%">Model Name</th>
|
|
||||||
<th class="text-center" style="width: 20%">Version</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{LOOP}
|
|
||||||
<tr>
|
|
||||||
<td class="px-5">{name}</td>
|
|
||||||
<td class="text-center">{version}</td>
|
|
||||||
</tr>
|
|
||||||
{/LOOP}
|
|
||||||
{ALT}
|
|
||||||
<tr>
|
|
||||||
<td class="text-center" colspan="3">
|
|
||||||
No models to install.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{/ALT}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<input type="hidden" name="token" value="{TOKEN}">
|
|
||||||
<div class="text-center">
|
|
||||||
<button class="btn btn-lg btn-primary center-block" type="submit" name="submit" value="submit">Install</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,12 +0,0 @@
|
|||||||
<div class="nav nav-tabs justify-content-center pt-3 col-10 offset-1" id="nav-tab" role="tablist">
|
|
||||||
<button class="nav-link {menu-Welcome}" type="button" role="tab">Welcome</button>
|
|
||||||
<button class="nav-link {menu-Terms}" type="button" role="tab">Terms</button>
|
|
||||||
<button class="nav-link {menu-Verify}" type="button" role="tab">Verify</button>
|
|
||||||
<button class="nav-link {menu-Configure}" type="button" role="tab">Configure</button>
|
|
||||||
<button class="nav-link {menu-Routing}" type="button" role="tab">Routing</button>
|
|
||||||
<button class="nav-link {menu-Models}" type="button" role="tab">Models</button>
|
|
||||||
<button class="nav-link {menu-Plugins}" type="button" role="tab">Plugins</button>
|
|
||||||
<button class="nav-link {menu-Resources}" type="button" role="tab">Resources</button>
|
|
||||||
<button class="nav-link {menu-User}" type="button" role="tab">User</button>
|
|
||||||
<button class="nav-link {menu-Complete}" type="button" role="tab">Complete</button>
|
|
||||||
</div>
|
|
@ -1,45 +0,0 @@
|
|||||||
<div class="context-main-bg my-3 pb-3 rounded col-10 offset-1">
|
|
||||||
{installer-nav}
|
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-md-10">
|
|
||||||
<p class="my-4">
|
|
||||||
The Tempus Project was built to utilize all of the plugins provided with the installer. You can choose not to enable any one of them, but it may negatively impact the operation of your site.
|
|
||||||
</p>
|
|
||||||
<form method="post">
|
|
||||||
<table class="table table-striped">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th class="px-5" style="width: 70%">Plugin Name</th>
|
|
||||||
<th class="text-center" style="width: 20%">Version</th>
|
|
||||||
<th class="text-center" style="width: 10%">
|
|
||||||
<input type="checkbox" onchange="checkAll(this)" name="check.m" value="P_[]" checked="checked">
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{LOOP}
|
|
||||||
<tr>
|
|
||||||
<td class="px-5">{name}</td>
|
|
||||||
<td class="text-center">{version}</td>
|
|
||||||
<td class="text-center">
|
|
||||||
<input type="checkbox" value="{name}" name="P_[]" checked="checked">
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{/LOOP}
|
|
||||||
{ALT}
|
|
||||||
<tr>
|
|
||||||
<td align="center" colspan="3">
|
|
||||||
No models to install.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{/ALT}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<input type="hidden" name="token" value="{TOKEN}">
|
|
||||||
<div class="text-center mb-3">
|
|
||||||
<button class="btn btn-lg btn-primary center-block" type="submit" name="submit" value="submit">Install</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,16 +0,0 @@
|
|||||||
<div class="context-main-bg my-3 pb-3 rounded col-10 offset-1">
|
|
||||||
{installer-nav}
|
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-md-10">
|
|
||||||
<p class="my-4">
|
|
||||||
Some models such as groups will need additional database resources and configurations to function properly. In this step, we will install those features.
|
|
||||||
</p>
|
|
||||||
<form method="post">
|
|
||||||
<input type="hidden" name="token" value="{TOKEN}">
|
|
||||||
<div class="text-center my-3">
|
|
||||||
<button class="btn btn-lg btn-primary center-block" type="submit" name="submit" value="submit">Install Resources</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,18 +0,0 @@
|
|||||||
<div class="context-main-bg my-3 pb-3 rounded col-10 offset-1">
|
|
||||||
{installer-nav}
|
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-md-10">
|
|
||||||
<p class="mt-4">The Tempus Project uses rewrites in htaccess files (Apache), or location directives (Nginx), to automatically route all incoming traffic through the app. In this step, we will help set-up and then test that the required configurations have been made.</p>
|
|
||||||
<h3>Apache Users</h3>
|
|
||||||
<p>In this step, we will attempt to generate the appropriate files for Apache servers.</p>
|
|
||||||
<h3>Nginx Users</h3>
|
|
||||||
<p>If you are using Nginx, you will need to update your server's configuration manually. Please see the documentation, for convenience, an example configuration has been provided with TheTempusProject and can be found in the app/resources directory.</p>
|
|
||||||
<form method="post">
|
|
||||||
<input type="hidden" name="token" value="{TOKEN}">
|
|
||||||
<div class="text-center">
|
|
||||||
<button class="btn btn-lg btn-primary center-block mb-3" type="submit" name="submit" value="submit">Generate</button><br>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,16 +0,0 @@
|
|||||||
<div class="context-main-bg my-3 pb-3 rounded col-10 offset-1">
|
|
||||||
{installer-nav}
|
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-10">
|
|
||||||
<div class="install-terms col-lg-8 mx-auto mt-4">
|
|
||||||
{TERMS}
|
|
||||||
</div>
|
|
||||||
<div class="text-center my-4">
|
|
||||||
<form method="post">
|
|
||||||
<input type="hidden" name="token" value="{TOKEN}">
|
|
||||||
<button class="btn btn-lg btn-primary center-block mb-3" type="submit" name="submit" value="submit">I Agree</button><br>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,35 +0,0 @@
|
|||||||
<div class="context-main-bg my-3 pb-3 rounded col-10 offset-1">
|
|
||||||
{installer-nav}
|
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-md-10 pt-4">
|
|
||||||
<form method="post">
|
|
||||||
<fieldset>
|
|
||||||
<div class="mb-3 col-md-4 offset-md-4">
|
|
||||||
<label for="newUsername" class="form-label">Username:</label>
|
|
||||||
<input class="form-control" type="text" name="newUsername" id="newUsername" value="">
|
|
||||||
</div>
|
|
||||||
<div class="mb-3 col-md-4 offset-md-4">
|
|
||||||
<label for="userEmail" class="form-label">Email:</label>
|
|
||||||
<input class="form-control" type="email" name="userEmail" id="userEmail" value="">
|
|
||||||
</div>
|
|
||||||
<div class="mb-3 col-md-4 offset-md-4">
|
|
||||||
<label for="userEmail2" class="form-label">Re-enter Email:</label>
|
|
||||||
<input class="form-control" type="email" name="userEmail2" id="userEmail2" value="">
|
|
||||||
</div>
|
|
||||||
<div class="mb-3 col-md-4 offset-md-4">
|
|
||||||
<label for="userPassword" class="form-label">Password:</label>
|
|
||||||
<input class="form-control" type="password" name="userPassword" id="userPassword">
|
|
||||||
</div>
|
|
||||||
<div class="mb-3 col-md-4 offset-md-4">
|
|
||||||
<label for="userPassword2" class="form-label">Re-enter Password:</label>
|
|
||||||
<input class="form-control" type="password" name="userPassword2" id="userPassword2">
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
|
||||||
<input type="hidden" name="token" value="{TOKEN}">
|
|
||||||
<div class="text-center">
|
|
||||||
<button class="btn btn-lg btn-primary center-block" type="submit" name="submit" value="submit">Complete</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,23 +0,0 @@
|
|||||||
<div class="context-main-bg my-3 pb-3 rounded col-10 offset-1">
|
|
||||||
{installer-nav}
|
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-md-10">
|
|
||||||
<h2 class="mt-4">Requirements</h2>
|
|
||||||
<ul>
|
|
||||||
<li>PHP version greater than 5.6</li>
|
|
||||||
<li>Session storage must be enabled</li>
|
|
||||||
<li>PHP mail must be enabled.</li>
|
|
||||||
<li>Safe mode must be disabled.</li>
|
|
||||||
<li>Rewrite rule must be on</li>
|
|
||||||
<li>file uploads must be on</li>
|
|
||||||
<li>mysql_pdo must be enabled</li>
|
|
||||||
</ul>
|
|
||||||
<div class="text-center">
|
|
||||||
<form method="post">
|
|
||||||
<input type="hidden" name="token" value="{TOKEN}">
|
|
||||||
<button class="btn btn-lg btn-primary center-block mb-3" type="submit" name="submit" value="submit">Check</button><br>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,17 +0,0 @@
|
|||||||
<div class="container">
|
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-md-10 text-center">
|
|
||||||
<div class="context-main-bg my-3 pb-3 rounded">
|
|
||||||
{installer-nav}
|
|
||||||
<h1 class="mt-5 mb-4">Welcome to The Tempus Project Installer.</h1>
|
|
||||||
<p class="lead p-3">
|
|
||||||
This installer will guide you through the process of installing and configuring The Tempus Project. Do not forget to delete this file once you have completed installation.
|
|
||||||
</p>
|
|
||||||
<form method="post">
|
|
||||||
<input type="hidden" name="token" value="{TOKEN}">
|
|
||||||
<button class="btn btn-lg btn-primary center-block mb-3" type="submit" name="submit" id="submit" value="submit">Begin Installation</button><br>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,26 +0,0 @@
|
|||||||
<div class="m-2 m-lg-4">
|
|
||||||
<div class="col-12 mx-5 col-sm-10 col-lg-8 mx-auto p-4 rounded shadow-sm context-main-bg">
|
|
||||||
<h2 class="text-center mb-4">Getting Started with {SITENAME}</h2>
|
|
||||||
<p class="lead text-center text-lg-start">
|
|
||||||
{SITENAME} has been open source for many years now. The hopes and intentions for it were always to give others a leg-up to get started building web-apps like i wish i had as a kid.
|
|
||||||
There were so many tutorials and ideas, expansions and plans for the project.
|
|
||||||
Unfortunately no person is given unlimited time to accomplish their dreams and over the years the idea for a huge repository for learning and education has taken a back seat.
|
|
||||||
</p>
|
|
||||||
<p class="text-center text-lg-start">
|
|
||||||
At this time, the best recommendation available is to contact us for more information.
|
|
||||||
The site here is actively maintained so feel free to utilize any of our available resources for contact.
|
|
||||||
In addition to the site here, you can contact the lead developer (me) directly through <a href="https://joeykimsey.com">JoeyKimsey.com</a>.
|
|
||||||
</p>
|
|
||||||
<p class="text-muted text-center text-lg-start">
|
|
||||||
Right now, this entire system was built and managed by myself. As stated, I have used my own version of this for years, but translating it to a publicly available product is not a 1-to-1 job. There may be bugs or issues encountered while you use the product. I can't guarantee a fix for every need in every case immediately, but I do actively keep track of bugs and work hard to ensure everyone has a great experience using the app.
|
|
||||||
</p>
|
|
||||||
<p class="text-center text-lg-start">
|
|
||||||
If you encounter any bugs, feel free to report them <a href="/bugreport" class="text-decoration-none">here</a>. Likewise, there are forms for feedback, reviews, suggestions, and a general contact form. Thanks for taking the time to check out the product!
|
|
||||||
</p>
|
|
||||||
<div class="text-center mt-4 pb-4">
|
|
||||||
{loggedin}
|
|
||||||
<a href="/bugreport" class="btn btn-primary px-3 btn-lg m-2">Report a Bug</a>
|
|
||||||
{/loggedin}
|
|
||||||
<a href="/contact" class="btn btn-outline-primary px-3 m-2 btn-lg">Contact Us</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -25,6 +25,7 @@
|
|||||||
{
|
{
|
||||||
"endroid/qr-code": "^6.0",
|
"endroid/qr-code": "^6.0",
|
||||||
"fortawesome/font-awesome": "4.7",
|
"fortawesome/font-awesome": "4.7",
|
||||||
|
"stripe/stripe-php": "^16.3",
|
||||||
"thetempusproject/bedrock": "1.1.6",
|
"thetempusproject/bedrock": "1.1.6",
|
||||||
"thetempusproject/canary": "1.0.9",
|
"thetempusproject/canary": "1.0.9",
|
||||||
"thetempusproject/houdini": "2.0.5",
|
"thetempusproject/houdini": "2.0.5",
|
||||||
|
61
composer.lock
generated
@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "10e7ce6b744b46b0c10780dbd7786ecb",
|
"content-hash": "1a35931e4b6b82cdcc4c3cd9824421b1",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "bacon/bacon-qr-code",
|
"name": "bacon/bacon-qr-code",
|
||||||
@ -234,6 +234,65 @@
|
|||||||
},
|
},
|
||||||
"time": "2016-10-24T15:52:54+00:00"
|
"time": "2016-10-24T15:52:54+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "stripe/stripe-php",
|
||||||
|
"version": "v16.5.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/stripe/stripe-php.git",
|
||||||
|
"reference": "3fb22256317344e049fce02ff289af3b776b0464"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/stripe/stripe-php/zipball/3fb22256317344e049fce02ff289af3b776b0464",
|
||||||
|
"reference": "3fb22256317344e049fce02ff289af3b776b0464",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-curl": "*",
|
||||||
|
"ext-json": "*",
|
||||||
|
"ext-mbstring": "*",
|
||||||
|
"php": ">=5.6.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"friendsofphp/php-cs-fixer": "3.5.0",
|
||||||
|
"phpstan/phpstan": "^1.2",
|
||||||
|
"phpunit/phpunit": "^5.7 || ^9.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "2.0-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Stripe\\": "lib/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Stripe and contributors",
|
||||||
|
"homepage": "https://github.com/stripe/stripe-php/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Stripe PHP Library",
|
||||||
|
"homepage": "https://stripe.com/",
|
||||||
|
"keywords": [
|
||||||
|
"api",
|
||||||
|
"payment processing",
|
||||||
|
"stripe"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/stripe/stripe-php/issues",
|
||||||
|
"source": "https://github.com/stripe/stripe-php/tree/v16.5.0"
|
||||||
|
},
|
||||||
|
"time": "2025-01-27T20:20:33+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "thetempusproject/bedrock",
|
"name": "thetempusproject/bedrock",
|
||||||
"version": "1.1.6",
|
"version": "1.1.6",
|
||||||
|
Before Width: | Height: | Size: 42 KiB |
BIN
images/logo.png
Before Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 60 KiB |