From a8a99b37e31fb47d86f937c56d3667adef91e1bf Mon Sep 17 00:00:00 2001 From: Joey Kimsey Date: Wed, 11 Dec 2024 08:00:06 -0500 Subject: [PATCH] Add new plugins: WIP, Suggestions, Reviews --- .../reviews/controllers/admin/reviews.php | 140 ++++++++++++++ app/plugins/reviews/controllers/reviews.php | 89 +++++++++ app/plugins/reviews/css/reviews.css | 9 + app/plugins/reviews/forms.php | 93 +++++++++ app/plugins/reviews/js/reviews.js | 20 ++ app/plugins/reviews/models/review.php | 149 ++++++++++++++ app/plugins/reviews/models/reviewcategory.php | 112 +++++++++++ app/plugins/reviews/plugin.php | 51 +++++ app/plugins/reviews/views/admin/category.html | 35 ++++ .../reviews/views/admin/categoryCreate.html | 22 +++ .../reviews/views/admin/categoryEdit.html | 22 +++ .../reviews/views/admin/categoryList.html | 33 ++++ .../reviews/views/admin/dashboard.html | 9 + app/plugins/reviews/views/admin/review.html | 42 ++++ .../reviews/views/admin/reviewList.html | 32 +++ app/plugins/reviews/views/admin/view.html | 0 app/plugins/reviews/views/create.html | 29 +++ app/plugins/reviews/views/index.html | 1 + app/plugins/reviews/views/list.html | 32 +++ .../controllers/admin/suggestions.php | 119 ++++++++++++ .../suggestions/controllers/suggestions.php | 133 +++++++++++++ app/plugins/suggestions/forms.php | 68 +++++++ .../suggestions/models/suggestions.php | 183 ++++++++++++++++++ app/plugins/suggestions/plugin.php | 47 +++++ app/plugins/suggestions/views/admin/edit.html | 22 +++ app/plugins/suggestions/views/admin/list.html | 56 ++++++ app/plugins/suggestions/views/admin/view.html | 17 ++ app/plugins/suggestions/views/create.html | 16 ++ app/plugins/suggestions/views/edit.html | 15 ++ app/plugins/suggestions/views/list.html | 19 ++ app/plugins/suggestions/views/view.html | 18 ++ app/plugins/wip/controllers/admin/wip.php | 102 ++++++++++ app/plugins/wip/controllers/wip.php | 36 ++++ app/plugins/wip/forms.php | 79 ++++++++ app/plugins/wip/models/projects.php | 85 ++++++++ app/plugins/wip/plugin.php | 44 +++++ app/plugins/wip/views/admin/create.html | 16 ++ app/plugins/wip/views/admin/edit.html | 16 ++ app/plugins/wip/views/admin/list.html | 41 ++++ app/plugins/wip/views/admin/view.html | 8 + app/plugins/wip/views/wip.html | 19 ++ 41 files changed, 2079 insertions(+) create mode 100644 app/plugins/reviews/controllers/admin/reviews.php create mode 100644 app/plugins/reviews/controllers/reviews.php create mode 100644 app/plugins/reviews/css/reviews.css create mode 100644 app/plugins/reviews/forms.php create mode 100644 app/plugins/reviews/js/reviews.js create mode 100644 app/plugins/reviews/models/review.php create mode 100644 app/plugins/reviews/models/reviewcategory.php create mode 100644 app/plugins/reviews/plugin.php create mode 100644 app/plugins/reviews/views/admin/category.html create mode 100644 app/plugins/reviews/views/admin/categoryCreate.html create mode 100644 app/plugins/reviews/views/admin/categoryEdit.html create mode 100644 app/plugins/reviews/views/admin/categoryList.html create mode 100644 app/plugins/reviews/views/admin/dashboard.html create mode 100644 app/plugins/reviews/views/admin/review.html create mode 100644 app/plugins/reviews/views/admin/reviewList.html create mode 100644 app/plugins/reviews/views/admin/view.html create mode 100644 app/plugins/reviews/views/create.html create mode 100644 app/plugins/reviews/views/index.html create mode 100644 app/plugins/reviews/views/list.html create mode 100644 app/plugins/suggestions/controllers/admin/suggestions.php create mode 100644 app/plugins/suggestions/controllers/suggestions.php create mode 100644 app/plugins/suggestions/forms.php create mode 100644 app/plugins/suggestions/models/suggestions.php create mode 100644 app/plugins/suggestions/plugin.php create mode 100644 app/plugins/suggestions/views/admin/edit.html create mode 100644 app/plugins/suggestions/views/admin/list.html create mode 100644 app/plugins/suggestions/views/admin/view.html create mode 100644 app/plugins/suggestions/views/create.html create mode 100644 app/plugins/suggestions/views/edit.html create mode 100644 app/plugins/suggestions/views/list.html create mode 100644 app/plugins/suggestions/views/view.html create mode 100644 app/plugins/wip/controllers/admin/wip.php create mode 100644 app/plugins/wip/controllers/wip.php create mode 100644 app/plugins/wip/forms.php create mode 100644 app/plugins/wip/models/projects.php create mode 100644 app/plugins/wip/plugin.php create mode 100644 app/plugins/wip/views/admin/create.html create mode 100644 app/plugins/wip/views/admin/edit.html create mode 100644 app/plugins/wip/views/admin/list.html create mode 100644 app/plugins/wip/views/admin/view.html create mode 100644 app/plugins/wip/views/wip.html diff --git a/app/plugins/reviews/controllers/admin/reviews.php b/app/plugins/reviews/controllers/admin/reviews.php new file mode 100644 index 0000000..6edae63 --- /dev/null +++ b/app/plugins/reviews/controllers/admin/reviews.php @@ -0,0 +1,140 @@ + + * @link https://TheTempusProject.com + * @license https://opensource.org/licenses/MIT [MIT LICENSE] + */ +namespace TheTempusProject\Controllers\Admin; + +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\Classes\AdminController; +use TheTempusProject\Models\Review; +use TheTempusProject\Models\Reviewcategory; +use TheTempusProject\Classes\Forms; + +class Reviews extends AdminController { + protected static $reviews; + protected static $categories; + + public function __construct() { + parent::__construct(); + self::$title = 'Admin - Reviews'; + self::$reviews = new Review; + self::$categories = new Reviewcategory; + $view = Navigation::activePageSelect( 'nav.admin', '/admin/reviews' ); + Components::set( 'ADMINNAV', $view ); + } + + public function index( $data = null ) { + $reviews = Views::simpleView( 'reviews.admin.reviewList', self::$reviews->list() ); + $categories = Views::simpleView( 'reviews.admin.categoryList', self::$categories->list() ); + Components::set( 'reviews', $reviews ); + Components::set( 'reviewCategories', $categories ); + Views::view( 'reviews.admin.dashboard' ); + } + + public function categoryView( $id = null ) { + $category = self::$categories->findById( $id ); + if ( ! $category ) { + Issues::add( 'error', 'Unknown Category.' ); + return $this->index(); + } + Views::view( 'reviews.admin.category', $category ); + } + + public function categoryCreate( ) { + if ( ! Input::exists( 'submit' ) ) { + return Views::view( 'reviews.admin.categoryCreate' ); + } + if ( ! Forms::check( 'categoryCreate' ) ) { + Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] ); + return Views::view( 'reviews.admin.categoryCreate' ); + } + $result = self::$categories->create( + Input::post( 'name' ), + Input::post( 'slug' ), + ); + if ( $result ) { + Issues::add( 'success', 'Your review category has been created.' ); + return $this->index(); + } + Issues::add( 'error', [ 'There was an unknown error submitting your data.' => Check::userErrors() ] ); + Views::view( 'reviews.admin.categoryCreate' ); + } + + public function categoryEdit( $id = null ) { + $category = self::$categories->findById( $id ); + if ( ! $category ) { + Issues::add( 'error', 'Unknown Category.' ); + return $this->index(); + } + if ( ! Input::exists( 'submit' ) ) { + return Views::view( 'reviews.admin.categoryEdit', $category ); + } + if ( ! Forms::check( 'categoryEdit' ) ) { + Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] ); + return Views::view( 'reviews.admin.categoryEdit', $category ); + } + $result = self::$categories->update( + $id, + Input::post( 'name' ), + Input::post( 'slug' ), + ); + if ( $result ) { + Issues::add( 'success', 'Your review category has been updated.' ); + return $this->index(); + } + Issues::add( 'error', [ 'There was an unknown error submitting your data.' => Check::userErrors() ] ); + Views::view( 'reviews.admin.categoryEdit', $category ); + } + + public function categoryDelete( $id = null ) { + if ( self::$categories->delete( $id ) ) { + Issues::add( 'success', 'review category deleted' ); + } else { + Issues::add( 'error', 'There was an error with your request.' ); + } + $this->index(); + } + + public function reviewView( $id = null ) { + Views::view( 'reviews.admin.review', self::$reviews->findById( $id ) ); + } + + public function reviewApprove( $id = null ) { + if ( self::$reviews->approve( $id ) ) { + Issues::add( 'success', 'review approved' ); + } else { + Issues::add( 'error', 'There was an error with your request.' ); + } + $this->index(); + } + + public function reviewHide( $id = null ) { + if ( self::$reviews->hide( $id ) ) { + Issues::add( 'success', 'review hidden' ); + } else { + Issues::add( 'error', 'There was an error with your request.' ); + } + $this->index(); + } + + public function reviewDelete( $id = null ) { + if ( self::$reviews->delete( $id ) ) { + Issues::add( 'success', 'review deleted' ); + } else { + Issues::add( 'error', 'There was an error with your request.' ); + } + $this->index(); + } +} diff --git a/app/plugins/reviews/controllers/reviews.php b/app/plugins/reviews/controllers/reviews.php new file mode 100644 index 0000000..cd4d0ea --- /dev/null +++ b/app/plugins/reviews/controllers/reviews.php @@ -0,0 +1,89 @@ + + * @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\Review; +use TheTempusProject\TheTempusProject as App; +use TheTempusProject\Houdini\Classes\Components; +use TheTempusProject\Houdini\Classes\Template; +use TheTempusProject\Models\Reviewcategory; +use TheTempusProject\Houdini\Classes\Forms as HoudiniForms; + +class Reviews extends Controller { + protected static $reviews; + protected static $categories; + + public function __construct() { + self::$title = 'Reviews - {SITENAME}'; + self::$pageDescription = 'On this page you can submit a reviews for a product from the site.'; + + if ( ! App::$isLoggedIn ) { + Session::flash( 'notice', 'You must be logged in to review products.' ); + return Redirect::home(); + } + + parent::__construct(); + self::$reviews = new Review; + self::$categories = new Reviewcategory; + Components::append( 'TEMPLATE_JS_INCLUDES', Template::parse('' ) ); + Components::append( 'TEMPLATE_CSS_INCLUDES', Template::parse('') ); + } + + public function index() { + $reviews = Views::simpleView( 'reviews.list', self::$reviews->byUser() ); + Components::set( 'reviews', $reviews ); + Views::view( 'reviews.index' ); + } + + public function review( $slug = null ) { + $category = self::$categories->findBySlug( $slug ); + if ( ! $category ) { + $selectedCategory = '0'; + $reviewCategorySelect = HoudiniForms::getSelectHtml( + 'review_category_id', + self::$categories->simple(), + $selectedCategory, + ); + Components::set( 'reviewCategorySelect', $reviewCategorySelect ); + } else { + $selectedCategory = $category->ID; + Components::set( + 'reviewCategorySelect', + '' + ); + } + if ( ! Input::exists('submit') ) { + return Views::view( 'reviews.create' ); + } + if ( ! Forms::check( 'createReview' ) ) { + Issues::add( 'error', [ 'There was an error with your review.' => Check::userErrors() ] ); + return Views::view( 'reviews.create' ); + } + $result = self::$reviews->create( Input::post('title'), Input::post('rating'), Input::post('review'), Input::post('review_category_id') ); + if ( true === $result ) { + Session::flash( 'success', 'Your review has been received.' ); + Redirect::to( 'home/index' ); + } else { + Issues::add( 'error', 'There was an unresolved error while submitting your review.' ); + return Views::view( 'reviews.create' ); + } + } +} \ No newline at end of file diff --git a/app/plugins/reviews/css/reviews.css b/app/plugins/reviews/css/reviews.css new file mode 100644 index 0000000..30d7809 --- /dev/null +++ b/app/plugins/reviews/css/reviews.css @@ -0,0 +1,9 @@ + + .star-rating .fa-star { + font-size: 24px; + color: grey; + cursor: pointer; + } + .star-rating .fa-star.checked { + color: gold; + } \ No newline at end of file diff --git a/app/plugins/reviews/forms.php b/app/plugins/reviews/forms.php new file mode 100644 index 0000000..03ccdcd --- /dev/null +++ b/app/plugins/reviews/forms.php @@ -0,0 +1,93 @@ + + * @link https://TheTempusProject.com + * @license https://opensource.org/licenses/MIT [MIT LICENSE] + */ +namespace TheTempusProject\Plugins\Reviews; + +use TheTempusProject\Bedrock\Functions\Input; +use TheTempusProject\Bedrock\Functions\Check; +use TheTempusProject\Classes\Forms; + +class ReviewForms extends Forms { + /** + * Adds these functions to the form list. + */ + public function __construct() { + self::addHandler( 'createReview', __CLASS__, 'createReview' ); + self::addHandler( 'editReview', __CLASS__, 'editReview' ); + self::addHandler( 'categoryCreate', __CLASS__, 'categoryCreate' ); + self::addHandler( 'categoryEdit', __CLASS__, 'categoryEdit' ); + } + + /** + * Validates the createReview form. + * + * @return {bool} + */ + public static function createReview() { + if ( ! Input::exists( 'review' ) ) { + Check::addUserError( 'You must provide a review.' ); + return false; + } + if ( ! Input::exists( 'title' ) ) { + Check::addUserError( 'You must provide a title.' ); + return false; + } + if ( ! Input::exists( 'rating' ) ) { + Check::addUserError( 'You must provide a rating.' ); + return false; + } + if ( ! Input::exists( 'review_category_id' ) ) { + Check::addUserError( 'You must provide a review_category_id.' ); + return false; + } + return true; + } + public static function editReview() { + if ( ! Input::exists( 'review' ) ) { + Check::addUserError( 'You must provide a review.' ); + return false; + } + if ( ! Input::exists( 'title' ) ) { + Check::addUserError( 'You must provide a title.' ); + return false; + } + if ( ! Input::exists( 'rating' ) ) { + Check::addUserError( 'You must provide a rating.' ); + return false; + } + return true; + } + public static function categoryCreate() { + if ( ! Input::exists( 'name' ) ) { + Check::addUserError( 'You must provide a name.' ); + return false; + } + if ( ! Input::exists( 'slug' ) ) { + Check::addUserError( 'You must provide a slug.' ); + return false; + } + return true; + } + public static function categoryEdit() { + if ( ! Input::exists( 'name' ) ) { + Check::addUserError( 'You must provide a name.' ); + return false; + } + if ( ! Input::exists( 'slug' ) ) { + Check::addUserError( 'You must provide a slug.' ); + return false; + } + return true; + } +} + +new ReviewForms; diff --git a/app/plugins/reviews/js/reviews.js b/app/plugins/reviews/js/reviews.js new file mode 100644 index 0000000..dfd6ad2 --- /dev/null +++ b/app/plugins/reviews/js/reviews.js @@ -0,0 +1,20 @@ +$(document).ready(function() { + var $star_rating = $('.star-rating .fa-star'); + + var SetRatingStar = function() { + return $star_rating.each(function() { + if (parseInt($(this).siblings('input.rating-value').val()) >= parseInt($(this).data('rating'))) { + return $(this).addClass('checked'); + } else { + return $(this).removeClass('checked'); + } + }); + }; + + $star_rating.on('click', function() { + $(this).siblings('input.rating-value').val($(this).data('rating')); + return SetRatingStar(); + }); + + SetRatingStar(); +}); \ No newline at end of file diff --git a/app/plugins/reviews/models/review.php b/app/plugins/reviews/models/review.php new file mode 100644 index 0000000..9e1dd80 --- /dev/null +++ b/app/plugins/reviews/models/review.php @@ -0,0 +1,149 @@ + + * @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\Plugins\Reviews as Plugin; +use TheTempusProject\TheTempusProject as App; +use TheTempusProject\Canary\Classes\CustomException; + +class Review extends DatabaseModel { + public $tableName = 'reviews'; + public $databaseMatrix = [ + [ 'review_category_id', 'int', '11' ], + [ 'title', 'varchar', '128' ], + [ 'rating', 'int', '1' ], + [ 'review', 'text', '' ], + [ 'createdBy', 'int', '11' ], + [ 'createdAt', 'int', '11' ], + [ 'approvedAt', 'int', '11' ], + [ 'approvedBy', 'int', '11' ], + ]; + public $plugin; + + /** + * The model constructor. + */ + public function __construct() { + parent::__construct(); + $this->plugin = new Plugin; + } + + public function create( $title, $rating, $review, $review_category_id = '0' ) { + if ( ! $this->plugin->checkEnabled() ) { + Debug::info( 'Reviews are disabled in the config.' ); + return false; + } + $fields = [ + 'title' => $title, + 'rating' => $rating, + 'review' => $review, + 'review_category_id' => $review_category_id, + 'createdAt' => time(), + 'createdBy' => App::$activeUser->ID, + ]; + if ( ! self::$db->insert( $this->tableName, $fields ) ) { + Debug::info( 'Reviews::create - failed to insert to db' ); + return false; + } + return self::$db->lastId(); + } + + public function update( $id, $title, $rating, $review, $review_category_id = '0' ) { + if ( ! $this->plugin->checkEnabled() ) { + Debug::info( 'Reviews are disabled in the config.' ); + return false; + } + if ( !Check::dataTitle( $slug ) ) { + Debug::info( 'Review Categories: illegal title.' ); + return false; + } + $fields = [ + 'title' => $title, + 'rating' => $rating, + 'review' => $review, + 'review_category_id' => $review_category_id, + ]; + if ( !self::$db->update( $this->tableName, $id, $fields ) ) { + new CustomException( 'reviewUpdate' ); + Debug::error( "Review: $id not updated: $fields" ); + return false; + } + return true; + } + + public function approve( $ID ) { + if ( !Check::id( $ID ) ) { + Debug::info( 'Review Categories: illegal ID.' ); + return false; + } + $fields = [ + 'approvedAt' => time(), + 'approvedBy' => App::$activeUser->ID, + ]; + if ( !self::$db->update( $this->tableName, $ID, $fields ) ) { + new CustomException( $this->tableName ); + Debug::error( "Review Categories: $ID Approved: $fields" ); + return false; + } + return true; + } + + public function hide( $ID ) { + // if ( !Check::id( $ID ) ) { + // Debug::info( 'Review Categories: illegal ID.' ); + // return false; + // } + // $fields = [ + // 'approvedAt' => null, + // 'approvedBy' => null, + // ]; + // if ( !self::$db->update( $this->tableName, $ID, $fields ) ) { + // new CustomException( $this->tableName ); + // Debug::error( "Review Categories: $ID not Approved: $fields" ); + // return false; + // } + return true; + } + + public function byUser( $limit = null ) { + $whereClause = ['createdBy', '=', App::$activeUser->ID]; + if ( empty( $limit ) ) { + $reviews = self::$db->get( $this->tableName, $whereClause ); + } else { + $reviews = self::$db->get( $this->tableName, $whereClause, 'ID', 'DESC', [0, $limit] ); + } + if ( !$reviews->count() ) { + Debug::info( 'No Reviews found.' ); + return false; + } + return $this->filter( $reviews->results() ); + } + + public function byCategory( $id, $limit = null ) { + $whereClause = [ 'review_category_id', '=', $id ]; + if ( empty( $limit ) ) { + $reviews = self::$db->get( $this->tableName, $whereClause ); + } else { + $reviews = self::$db->get( $this->tableName, $whereClause, 'ID', 'DESC', [0, $limit] ); + } + if ( !$reviews->count() ) { + Debug::info( 'No Reviews found.' ); + return false; + } + return $this->filter( $reviews->results() ); + } +} diff --git a/app/plugins/reviews/models/reviewcategory.php b/app/plugins/reviews/models/reviewcategory.php new file mode 100644 index 0000000..6de2e98 --- /dev/null +++ b/app/plugins/reviews/models/reviewcategory.php @@ -0,0 +1,112 @@ + + * @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\Plugins\Reviews as Plugin; +use TheTempusProject\TheTempusProject as App; +use TheTempusProject\Canary\Classes\CustomException; + +class Reviewcategory extends DatabaseModel { + public $tableName = 'review_categories'; + public $databaseMatrix = [ + [ 'name', 'varchar', '128' ], + [ 'slug', 'varchar', '64' ], + [ 'createdBy', 'int', '11' ], + [ 'createdAt', 'int', '11' ], + ]; + public $plugin; + + /** + * The model constructor. + */ + public function __construct() { + parent::__construct(); + $this->plugin = new Plugin; + } + + public function create( $name, $slug ) { + if ( ! $this->plugin->checkEnabled() ) { + Debug::info( 'Reviews are disabled in the config.' ); + return false; + } + if ( !Check::dataTitle( $slug ) ) { + Debug::info( 'Review Categories: illegal title.' ); + return false; + } + $fields = [ + 'name' => $name, + 'slug' => $slug, + 'createdAt' => time(), + 'createdBy' => App::$activeUser->ID, + ]; + if ( ! self::$db->insert( $this->tableName, $fields ) ) { + Debug::info( 'ReviewCategories::create - failed to insert to db' ); + return false; + } + return self::$db->lastId(); + } + + public function update( $id, $name, $slug ) { + if ( ! $this->plugin->checkEnabled() ) { + Debug::info( 'Reviews are disabled in the config.' ); + return false; + } + if ( !Check::dataTitle( $slug ) ) { + Debug::info( 'Review Categories: illegal title.' ); + return false; + } + $fields = [ + 'name' => $name, + 'slug' => $slug, + ]; + if ( !self::$db->update( $this->tableName, $id, $fields ) ) { + new CustomException( 'reviewCategoryUpdate' ); + Debug::error( "Review Categories: $id not updated: $fields" ); + return false; + } + return true; + } + + public function findBySlug( $slug, $limit = null ) { + $whereClause = [ 'slug', '=', $slug ]; + if ( empty( $limit ) ) { + $categories = self::$db->get( $this->tableName, $whereClause ); + } else { + $categories = self::$db->get( $this->tableName, $whereClause, 'ID', 'DESC', [0, $limit] ); + } + if ( !$categories->count() ) { + Debug::info( 'No categories found.' ); + return false; + } + return $this->filter( $categories->first() ); + } + + public function simple() { + $categories = self::$db->get( $this->tableName, '*' ); + if ( !$categories->count() ) { + Debug::warn( 'Could not find any categories' ); + return false; + } + + $categories = $categories->results(); + $out = []; + foreach ( $categories as &$category ) { + $out[ $category->name ] = $category->ID; + } + return $out; + } +} diff --git a/app/plugins/reviews/plugin.php b/app/plugins/reviews/plugin.php new file mode 100644 index 0000000..bde0fcc --- /dev/null +++ b/app/plugins/reviews/plugin.php @@ -0,0 +1,51 @@ + + * @link https://TheTempusProject.com + * @license https://opensource.org/licenses/MIT [MIT LICENSE] + */ +namespace TheTempusProject\Plugins; + +use TheTempusProject\Classes\Plugin; + +class Reviews extends Plugin { + public $pluginName = 'TP Reviews'; + 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 review system.'; + public $permissionMatrix = [ + 'review' => [ + 'pretty' => 'Can create reviews', + 'default' => false, + ], + 'createReviewCategory' => [ + 'pretty' => 'Can create review categories', + 'default' => false, + ], + ]; + public $admin_links = [ + [ + 'text' => ' Reviews', + 'url' => '{ROOT_URL}admin/reviews', + ], + ]; + public $footer_links = [ + [ + 'text' => 'Reviews', + 'url' => '{ROOT_URL}reviews/index/', + 'filter' => 'loggedin', + ], + ]; +} + +// need a setting to allow reviewing a category from the dropdown +// if disabled, "I'm sorry but reviews are invite only. If you have been asked to review a product, double check the link and make sure its been entered correctly +// if you have not been invited to review a product, please feel free to leave any feedback in the feedback section. \ No newline at end of file diff --git a/app/plugins/reviews/views/admin/category.html b/app/plugins/reviews/views/admin/category.html new file mode 100644 index 0000000..9d4717a --- /dev/null +++ b/app/plugins/reviews/views/admin/category.html @@ -0,0 +1,35 @@ +
+
+
+
+

Review Category

+
+
+
+
+ + + + + + + + + + + + + + + +
Name{name}
Slug{slug}
Created{DTC}{createdAt}{/DTC}
+
+
+
+ +
+
+
\ No newline at end of file diff --git a/app/plugins/reviews/views/admin/categoryCreate.html b/app/plugins/reviews/views/admin/categoryCreate.html new file mode 100644 index 0000000..ff77224 --- /dev/null +++ b/app/plugins/reviews/views/admin/categoryCreate.html @@ -0,0 +1,22 @@ +Create Review Category +
+ +
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
\ No newline at end of file diff --git a/app/plugins/reviews/views/admin/categoryEdit.html b/app/plugins/reviews/views/admin/categoryEdit.html new file mode 100644 index 0000000..6be8a5d --- /dev/null +++ b/app/plugins/reviews/views/admin/categoryEdit.html @@ -0,0 +1,22 @@ +Edit Review Category +
+ +
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
\ No newline at end of file diff --git a/app/plugins/reviews/views/admin/categoryList.html b/app/plugins/reviews/views/admin/categoryList.html new file mode 100644 index 0000000..93ec77e --- /dev/null +++ b/app/plugins/reviews/views/admin/categoryList.html @@ -0,0 +1,33 @@ +Review Categories + + + + + + + + + + + + + {LOOP} + + + + + + + + + {/LOOP} + {ALT} + + + + {/ALT} + +
IDNameSlug
{ID}{name}{slug}
+ No results to show. +
+Create \ No newline at end of file diff --git a/app/plugins/reviews/views/admin/dashboard.html b/app/plugins/reviews/views/admin/dashboard.html new file mode 100644 index 0000000..52682fa --- /dev/null +++ b/app/plugins/reviews/views/admin/dashboard.html @@ -0,0 +1,9 @@ + +
+
+ {reviews} +
+
+ {reviewCategories} +
+
\ No newline at end of file diff --git a/app/plugins/reviews/views/admin/review.html b/app/plugins/reviews/views/admin/review.html new file mode 100644 index 0000000..37aad42 --- /dev/null +++ b/app/plugins/reviews/views/admin/review.html @@ -0,0 +1,42 @@ +
+
+
+
+

Review

+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + +
Title{title}
Rating{rating}
Created{DTC}{createdAt}{/DTC}
Review
{review}
+
+
+
+ +
+
+
\ No newline at end of file diff --git a/app/plugins/reviews/views/admin/reviewList.html b/app/plugins/reviews/views/admin/reviewList.html new file mode 100644 index 0000000..b3fb56c --- /dev/null +++ b/app/plugins/reviews/views/admin/reviewList.html @@ -0,0 +1,32 @@ +Reviews + + + + + + + + + + + + + {LOOP} + + + + + + + + + {/LOOP} + {ALT} + + + + {/ALT} + +
IDTitleRating
{ID}{title}{rating}
+ No results to show. +
\ No newline at end of file diff --git a/app/plugins/reviews/views/admin/view.html b/app/plugins/reviews/views/admin/view.html new file mode 100644 index 0000000..e69de29 diff --git a/app/plugins/reviews/views/create.html b/app/plugins/reviews/views/create.html new file mode 100644 index 0000000..6852a83 --- /dev/null +++ b/app/plugins/reviews/views/create.html @@ -0,0 +1,29 @@ +
+

Write a Review

+
+
+ + {reviewCategorySelect} +
+
+ + +
+
+ +
+ + + + + + +
+
+
+ + +
+ +
+
\ No newline at end of file diff --git a/app/plugins/reviews/views/index.html b/app/plugins/reviews/views/index.html new file mode 100644 index 0000000..4338bc5 --- /dev/null +++ b/app/plugins/reviews/views/index.html @@ -0,0 +1 @@ +{reviews} \ No newline at end of file diff --git a/app/plugins/reviews/views/list.html b/app/plugins/reviews/views/list.html new file mode 100644 index 0000000..b3fb56c --- /dev/null +++ b/app/plugins/reviews/views/list.html @@ -0,0 +1,32 @@ +Reviews + + + + + + + + + + + + + {LOOP} + + + + + + + + + {/LOOP} + {ALT} + + + + {/ALT} + +
IDTitleRating
{ID}{title}{rating}
+ No results to show. +
\ No newline at end of file diff --git a/app/plugins/suggestions/controllers/admin/suggestions.php b/app/plugins/suggestions/controllers/admin/suggestions.php new file mode 100644 index 0000000..ed238ba --- /dev/null +++ b/app/plugins/suggestions/controllers/admin/suggestions.php @@ -0,0 +1,119 @@ + + * @link https://TheTempusProject.com + * @license https://opensource.org/licenses/MIT [MIT LICENSE] + */ +namespace TheTempusProject\Controllers\Admin; + +use TheTempusProject\Houdini\Classes\Issues; +use TheTempusProject\Houdini\Classes\Views; +use TheTempusProject\Houdini\Classes\Components; +use TheTempusProject\Bedrock\Functions\Input; +use TheTempusProject\Bedrock\Functions\Check; +use TheTempusProject\Classes\Forms; +use TheTempusProject\Classes\AdminController; +use TheTempusProject\Models\Suggestions as SuggestionsModel; +use TheTempusProject\Models\Comments; +use TheTempusProject\Houdini\Classes\Forms as TemplateForm; + +class Suggestions extends AdminController { + protected static $suggestions; + protected static $comments; + + public function __construct() { + parent::__construct(); + self::$title = 'Admin - Suggestions'; + self::$suggestions = new SuggestionsModel; + } + + public function index( $data = null ) { + Views::view( 'suggestions.admin.list', self::$suggestions->list() ); + } + + public function view( $id = null ) { + $data = self::$suggestions->findById( $id ); + if ( $data == false ) { + Issues::add( 'error', 'Suggestion not found.' ); + return $this->index(); + } + if ( empty( self::$comments ) ) { + self::$comments = new Comments; + } + Components::set( 'COMMENT_TYPE', 'suggestions' ); + Components::set( 'count', self::$comments->count( 'suggestion', $id ) ); + Components::set( 'COMMENTS', Views::simpleView( 'comments.list', self::$comments->display( 10, 'suggestion', $id ) ) ); + Views::view( 'suggestions.admin.view', $data ); + } + + public function approve( $id = null ) { + $data = self::$suggestions->findById( $id ); + if ( $data == false ) { + Issues::add( 'error', 'Suggestion not found.' ); + return $this->index(); + } + if ( !self::$suggestions->approve( $id ) ) { + Issues::add( 'error', 'Suggestion not approved.' ); + return $this->index(); + } + Issues::add( 'success', 'Suggestion Approved' ); + return $this->index(); + } + + public function reject( $id = null ) { + $data = self::$suggestions->findById( $id ); + if ( $data == false ) { + Issues::add( 'error', 'Suggestion not found.' ); + return $this->index(); + } + if ( !self::$suggestions->reject( $id ) ) { + Issues::add( 'error', 'Suggestion not rejected.' ); + return $this->index(); + } + Issues::add( 'success', 'Suggestion Rejected' ); + return $this->index(); + } + + public function edit( $id = null ) { + $data = self::$suggestions->findById( $id ); + if ( false == $data ) { + return $this->index(); + } + TemplateForm::selectRadio( 'approved', $data->approved ); + if ( !Input::exists( 'submit' ) ) { + return Views::view( 'suggestions.admin.edit', $data ); + } + if ( !Forms::check( 'editSuggestion' ) ) { + Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] ); + return Views::view( 'suggestions.admin.edit', $data ); + } + if ( self::$suggestions->update( $id, Input::post( 'title' ), Input::post( 'suggestion' ), Input::post( 'approved' ) ) ) { + Issues::add( 'success', 'Suggestion updated' ); + } else { + return Views::view( 'suggestions.edit', $data ); + } + } + + public function delete( $data = null ) { + if ( Input::exists( 'submit' ) ) { + $data = Input::post( 'S_' ); + } + if ( !self::$suggestions->delete( $data ) ) { + Issues::add( 'error', 'There was an error with your request.' ); + } else { + Issues::add( 'success', 'Suggestions has been deleted' ); + } + $this->index(); + } + + public function clear( $data = null ) { + self::$suggestions->empty(); + $this->index(); + } +} diff --git a/app/plugins/suggestions/controllers/suggestions.php b/app/plugins/suggestions/controllers/suggestions.php new file mode 100644 index 0000000..1b843ce --- /dev/null +++ b/app/plugins/suggestions/controllers/suggestions.php @@ -0,0 +1,133 @@ + + * @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\Hermes\Functions\Redirect; +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\Suggestions as SuggestionModel; +use TheTempusProject\TheTempusProject as App; +use TheTempusProject\Models\Comments as CommentsModel; +use TheTempusProject\Plugins\Comments; +use TheTempusProject\Houdini\Classes\Components; + +class Suggestions extends Controller { + protected static $suggestions; + protected static $comments; + + public function __construct() { + parent::__construct(); + if ( !App::$isLoggedIn ) { + Session::flash( 'notice', 'You must be logged in to view suggestions.' ); + return Redirect::home(); + } + self::$suggestions = new SuggestionModel; + self::$title = 'Suggestions - {SITENAME}'; + self::$pageDescription = 'On this page you can view, submit, or comment-on suggestions for the site.'; + } + + public function index() { + Views::view( 'suggestions.list', self::$suggestions->recent() ); + } + + public function view( $id = null ) { + $data = self::$suggestions->findById( $id ); + if ( $data == false ) { + Issues::add( 'error', 'Suggestion not found.' ); + return $this->index(); + } + if ( empty( self::$comments ) ) { + self::$comments = new CommentsModel; + } + if ( Input::exists( 'contentId' ) ) { + $this->comments( 'post', Input::post( 'contentId' ) ); + } + Components::set( 'CONTENT_ID', $id ); + Components::set( 'COMMENT_TYPE', 'suggestions' ); + Components::set( 'NEWCOMMENT', Views::simpleView( 'comments.create' ) ); + Components::set( 'count', self::$comments->count( 'suggestion', $id ) ); + Components::set( 'COMMENTS', Views::simpleView( 'comments.list', self::$comments->display( 10, self::$suggestions->tableName, $id ) ) ); + Views::view( 'suggestions.view', $data ); + } + + public function create() { + if ( !Input::exists() ) { + return Views::view( 'suggestions.create' ); + } + if ( !Forms::check( 'newSuggestion' ) ) { + Issues::add( 'error', [ 'There was an error with your suggestion.' => Check::userErrors() ] ); + return Views::view( 'suggestions.create' ); + } + if ( !self::$suggestions->create( Input::post( 'title' ), Input::post( 'suggestion' ) ) ) { + Issues::add( 'error', [ 'There was an error with your suggestion.' => Check::userErrors() ] ); + return Views::view( 'suggestions.create' ); + } + Session::flash( 'success', 'Your Suggestion has been received. We must verify all suggestions before they are published, but as long as it doesn\'t violate our code of conduct, it should be available to view and comment on publicly within 24 hours.' ); + Redirect::to( 'suggestions/index' ); + } + + public function edit( $data = null ) { + if ( !Input::exists( 'submit' ) ) { + return Views::view( 'suggestions.edit', self::$suggestions->findById( $data ) ); + } + if ( !Forms::check( 'editSuggestion' ) ) { + Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] ); + return Views::view( 'suggestions.edit', self::$suggestions->findById( $data ) ); + } + if ( self::$suggestions->update( $data, Input::post( 'title' ), Input::post( 'suggestion' ) ) ) { + Issues::add( 'success', 'Suggestion updated' ); + } else { + return Views::view( 'suggestions.edit', self::$suggestions->findById( $data ) ); + } + $this->index(); + } + + public function comments( $sub = null, $data = null ) { + if ( empty( self::$comments ) ) { + self::$comments = new CommentsModel; + } + $commentsPlugin = new Comments; + if ( empty( $sub ) || empty( $data ) ) { + Session::flash( 'error', 'Whoops, try again.' ); + Redirect::to( 'suggestions' ); + } + switch ( $sub ) { + case 'post': + $content = self::$suggestions->findById( $data ); + if ( empty( $content ) ) { + Session::flash( 'error', 'Unknown Content.' ); + Redirect::to( 'suggestions' ); + } + return $commentsPlugin->formPost( self::$suggestions->tableName, $content, 'suggestions/view/' ); + case 'edit': + $content = self::$comments->findById( $data ); + if ( empty( $content ) ) { + Session::flash( 'error', 'Unknown Comment.' ); + Redirect::to( 'suggestions' ); + } + return $commentsPlugin->formEdit( self::$suggestions->tableName, $content, 'suggestions/view/' ); + case 'delete': + $content = self::$comments->findById( $data ); + if ( empty( $content ) ) { + Session::flash( 'error', 'Unknown Comment.' ); + Redirect::to( 'suggestions' ); + } + return $commentsPlugin->formDelete( self::$suggestions->tableName, $content, 'suggestions/view/' ); + } + } +} \ No newline at end of file diff --git a/app/plugins/suggestions/forms.php b/app/plugins/suggestions/forms.php new file mode 100644 index 0000000..2b206b0 --- /dev/null +++ b/app/plugins/suggestions/forms.php @@ -0,0 +1,68 @@ + + * @link https://TheTempusProject.com + * @license https://opensource.org/licenses/MIT [MIT LICENSE] + */ +namespace TheTempusProject\Plugins\Suggestions; + +use TheTempusProject\Bedrock\Functions\Input; +use TheTempusProject\Classes\Forms; + +class SuggestionForms extends Forms { + /** + * Adds these functions to the form list. + */ + public function __construct() { + self::addHandler( 'newSuggestion', __CLASS__, 'newSuggestion' ); + self::addHandler( 'editSuggestion', __CLASS__, 'editSuggestion' ); + } + + /** + * Validates the suggestion create form. + * + * @return {bool} + */ + public static function newSuggestion() { + if ( !Input::exists( 'title' ) ) { + self::addUserError( 'You must specify title' ); + return false; + } + if ( !Input::exists( 'suggestion' ) ) { + self::addUserError( 'You must write a Suggestion' ); + return false; + } + if ( !self::token() ) { + return false; + } + return true; + } + + /** + * Validates the suggestion create form. + * + * @return {bool} + */ + public static function editSuggestion() { + if ( !Input::exists( 'title' ) ) { + self::addUserError( 'You must specify title' ); + return false; + } + if ( !Input::exists( 'suggestion' ) ) { + self::addUserError( 'You must write a Suggestion' ); + return false; + } + if ( !self::token() ) { + return false; + } + return true; + } +} + +new SuggestionForms; diff --git a/app/plugins/suggestions/models/suggestions.php b/app/plugins/suggestions/models/suggestions.php new file mode 100644 index 0000000..6ed6de8 --- /dev/null +++ b/app/plugins/suggestions/models/suggestions.php @@ -0,0 +1,183 @@ + + * @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\Bin\Canary as Debug; +use TheTempusProject\Canary\Classes\CustomException; +use TheTempusProject\Classes\DatabaseModel; +use TheTempusProject\TheTempusProject as App; + +class Suggestions extends DatabaseModel { + public $tableName = 'suggestions'; + public $databaseMatrix = [ + [ 'title', 'varchar', '86' ], + [ 'suggestion', 'text', '' ], + [ 'suggestedOn', 'int', '10' ], + [ 'approved', 'varchar', '5' ], + [ 'approvedOn', 'int', '10' ], + [ 'approvedBy', 'int', '11' ], + [ 'author', 'int', '11' ], + ]; + + /** + * The model constructor. + */ + public function __construct() { + parent::__construct(); + } + + // @TODO: Add a config for some of these things + // public function enabled() { + // if ( true === parent::enabled() ) { + // return Config::getValue( $this->configName . '/enabled' ) === true; + // } + // return false; + // } + public function filter( $data, $params = [] ) { + foreach ( $data as $instance ) { + if ( !is_object( $instance ) ) { + $instance = $data; + $end = true; + } + if ( !empty($instance->approvedBy)) { + $instance->approvedByName = self::$user->getUsername( $instance->approvedBy ); + } else { + $instance->approvedByName = ''; + } + $instance->submittedBy = self::$user->getUsername( $instance->author ); + $out[] = $instance; + if ( !empty( $end ) ) { + $out = $out[0]; + break; + } + } + return $out; + } + + /** + * Logs a Suggestion 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( $title, $suggestion, $approved = 'false' ) { + if ( !$this->enabled() ) { + Debug::info( 'Suggestions are disabled in the config.' ); + return false; + } + $fields = [ + 'author' => App::$activeUser->ID, + 'suggestedOn' => time(), + 'suggestion' => $suggestion, + 'approved' => $approved, + 'title' => $title, + ]; + if ( !self::$db->insert( $this->tableName, $fields ) ) { + new CustomException( $this->tableName ); + return false; + } + return self::$db->lastId(); + } + + public function update( $ID, $title, $suggestion, $approved = 'false' ) { + if ( empty( self::$log ) ) { + self::$log = new Log; + } + if ( !Check::id( $ID ) ) { + Debug::info( 'Suggestion: illegal ID.' ); + return false; + } + $fields = [ + 'suggestion' => $suggestion, + 'approved' => $approved, + 'title' => $title, + ]; + if ( !self::$db->update( $this->tableName, $ID, $fields ) ) { + new CustomException( $this->tableName ); + Debug::error( "Suggestion: $ID not updated: $fields" ); + + return false; + } + self::$log->admin( "Updated Suggestion: $ID" ); + return true; + } + + public function approve( $ID ) { + if ( empty( self::$log ) ) { + self::$log = new Log; + } + if ( !Check::id( $ID ) ) { + Debug::info( 'Suggestion: illegal ID.' ); + return false; + } + $fields = [ + 'approved' => 'true', + 'approvedOn' => time(), + 'approvedBy' => App::$activeUser->ID, + ]; + if ( !self::$db->update( $this->tableName, $ID, $fields ) ) { + new CustomException( $this->tableName ); + Debug::error( "Suggestion: $ID not Rejected: $fields" ); + return false; + } + self::$log->admin( "Suggestion Rejected: $ID" ); + return true; + } + + public function reject( $ID ) { + if ( empty( self::$log ) ) { + self::$log = new Log; + } + if ( !Check::id( $ID ) ) { + Debug::info( 'Suggestion: illegal ID.' ); + return false; + } + $fields = [ + 'approved' => 'false', + 'approvedOn' => null, + 'approvedBy' => null, + ]; + if ( !self::$db->update( $this->tableName, $ID, $fields ) ) { + new CustomException( $this->tableName ); + Debug::error( "Suggestion: $ID not Approved: $fields" ); + return false; + } + self::$log->admin( "Suggestion Approved: $ID" ); + return true; + } + + public function recent( $approvedOnly = true, $limit = 0 ) { + if ( true === $approvedOnly ) { + $where = ['approved', '=', 'true']; + } else { + $where = ['ID', '>', '0']; + } + if ( empty( $limit ) ) { + $data = self::$db->getPaginated( $this->tableName, $where, 'suggestedOn', 'DESC' ); + } else { + $data = self::$db->get( $this->tableName, $where, 'suggestedOn', 'DESC', [0, $limit] ); + } + if ( !$data->count() ) { + Debug::info( 'No Suggestions found.' ); + return false; + } + return $this->filter( $data->results() ); + } +} diff --git a/app/plugins/suggestions/plugin.php b/app/plugins/suggestions/plugin.php new file mode 100644 index 0000000..f12e737 --- /dev/null +++ b/app/plugins/suggestions/plugin.php @@ -0,0 +1,47 @@ + + * @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 Suggestions extends Plugin { + public $pluginName = 'TP Suggest'; + 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 suggestion system.'; + public $permissionMatrix = [ + 'suggest' => [ + 'pretty' => 'Can create suggestions', + 'default' => false, + ], + ]; + public $admin_links = [ + [ + 'text' => ' Suggestions', + 'url' => '{ROOT_URL}admin/suggestions', + ], + ]; + public $footer_links = [ + [ + 'text' => 'Suggestions', + 'url' => '{ROOT_URL}suggestions/index', + 'filter' => 'loggedin', + ], + ]; +} diff --git a/app/plugins/suggestions/views/admin/edit.html b/app/plugins/suggestions/views/admin/edit.html new file mode 100644 index 0000000..8346454 --- /dev/null +++ b/app/plugins/suggestions/views/admin/edit.html @@ -0,0 +1,22 @@ +
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+ + +
\ No newline at end of file diff --git a/app/plugins/suggestions/views/admin/list.html b/app/plugins/suggestions/views/admin/list.html new file mode 100644 index 0000000..7e11444 --- /dev/null +++ b/app/plugins/suggestions/views/admin/list.html @@ -0,0 +1,56 @@ +Suggestions +{PAGINATION} +
+ + + + + + + + + + + + + + + + + {LOOP} + + + + + + + + + + + + + {/LOOP} + {ALT} + + + + {/ALT} + +
IDSuggestionSuggested OnSuggested ByApprovedApproved OnApproved By + +
{ID}{suggestion}{DTC}{suggestedOn}{/DTC}{submittedBy}{approved}{DTC}{approvedOn}{/DTC}{approvedByName} + + + + + + + +
+ No results to show. +
+ +
+
+clear all \ No newline at end of file diff --git a/app/plugins/suggestions/views/admin/view.html b/app/plugins/suggestions/views/admin/view.html new file mode 100644 index 0000000..0d044b3 --- /dev/null +++ b/app/plugins/suggestions/views/admin/view.html @@ -0,0 +1,17 @@ +
+
+
+

Suggestion

+
+ + {suggestion} + {ADMIN} +
+ Delete + Edit +
+ {/ADMIN} +
+ {COMMENTS} +
+
\ No newline at end of file diff --git a/app/plugins/suggestions/views/create.html b/app/plugins/suggestions/views/create.html new file mode 100644 index 0000000..479bfaa --- /dev/null +++ b/app/plugins/suggestions/views/create.html @@ -0,0 +1,16 @@ +
+ Submit a Suggestion +
+ +
+ +
+
+
+
+ +
+
+ + +
\ No newline at end of file diff --git a/app/plugins/suggestions/views/edit.html b/app/plugins/suggestions/views/edit.html new file mode 100644 index 0000000..63d2d70 --- /dev/null +++ b/app/plugins/suggestions/views/edit.html @@ -0,0 +1,15 @@ +
+
+ +
+ +
+
+
+
+ +
+
+ + +
\ No newline at end of file diff --git a/app/plugins/suggestions/views/list.html b/app/plugins/suggestions/views/list.html new file mode 100644 index 0000000..ee7ac85 --- /dev/null +++ b/app/plugins/suggestions/views/list.html @@ -0,0 +1,19 @@ +Suggestions +{PAGINATION} +{LOOP} +
+

{title}

+
+ {suggestion} + +
+
+{/LOOP} +{ALT} +
+ +
+{/ALT} +Create \ No newline at end of file diff --git a/app/plugins/suggestions/views/view.html b/app/plugins/suggestions/views/view.html new file mode 100644 index 0000000..c3645b9 --- /dev/null +++ b/app/plugins/suggestions/views/view.html @@ -0,0 +1,18 @@ +
+
+
+

{title}

+
+ + {suggestion} + {ADMIN} +
+ Delete + Edit +
+ {/ADMIN} +
+ {COMMENTS} + {NEWCOMMENT} +
+
\ No newline at end of file diff --git a/app/plugins/wip/controllers/admin/wip.php b/app/plugins/wip/controllers/admin/wip.php new file mode 100644 index 0000000..b40f383 --- /dev/null +++ b/app/plugins/wip/controllers/admin/wip.php @@ -0,0 +1,102 @@ + + * @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\Input; +use TheTempusProject\Houdini\Classes\Issues; +use TheTempusProject\Houdini\Classes\Views; +use TheTempusProject\Houdini\Classes\Navigation; +use TheTempusProject\Houdini\Classes\Components; +use TheTempusProject\Classes\AdminController; +use TheTempusProject\Classes\Forms; +use TheTempusProject\Models\Projects; + +class Wip extends AdminController { + public static $projects; + + public function __construct() { + parent::__construct(); + self::$projects = new Projects; + self::$title = 'Admin - Projects'; + $view = Navigation::activePageSelect( 'nav.admin', '/admin/wip' ); + Components::set( 'ADMINNAV', $view ); + } + + public function index( $data = null ) { + Views::view( 'wip.admin.list', self::$projects->listPaginated() ); + } + + public function create( $data = null ) { + if ( !Input::exists( 'submit' ) ) { + return Views::view( 'wip.admin.create' ); + } + if ( !Forms::check( 'newProject' ) ) { + Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] ); + return $this->index(); + } + $result = self::$projects->create( Input::post( 'title' ), Input::post( 'description' ), Input::post( 'progress' ), Input::post( 'startDate' ) ); + if ( $result ) { + Issues::add( 'success', 'Your projects 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' ) ) { + return Views::view( 'wip.admin.edit', self::$projects->findById( $data ) ); + } + if ( !Forms::check( 'editProject' ) ) { + Issues::add( 'error', [ 'There was an error with your form.' => Check::userErrors() ] ); + return $this->index(); + } + $fields = [ + 'title' => Input::post( 'title' ), + 'description' => Input::post( 'description' ), + 'progress' => Input::post( 'progress' ), + 'startDate' => Input::post( 'startDate' ), + ]; + if ( self::$projects->update( $data, $fields ) ) { + Issues::add( 'success', 'Projects Updated.' ); + return $this->index(); + } + Issues::add( 'error', 'There was an error with your request.' ); + $this->index(); + } + + public function view( $data = null ) { + $projectData = self::$projects->findById( $data ); + if ( $projectData !== false ) { + return Views::view( 'wip.admin.view', $projectData ); + } + Issues::add( 'error', 'Projects not found.' ); + $this->index(); + } + + public function delete( $data = null ) { + if ( $data == null ) { + if ( Input::exists( 'P_' ) ) { + $data = Input::post( 'P_' ); + } + } + if ( !self::$projects->delete( (array) $data ) ) { + Issues::add( 'error', 'There was an error with your request.' ); + } else { + Issues::add( 'success', 'Projects has been deleted' ); + } + $this->index(); + } +} diff --git a/app/plugins/wip/controllers/wip.php b/app/plugins/wip/controllers/wip.php new file mode 100644 index 0000000..374602a --- /dev/null +++ b/app/plugins/wip/controllers/wip.php @@ -0,0 +1,36 @@ + + * @link https://TheTempusProject.com + * @license https://opensource.org/licenses/MIT [MIT LICENSE] + */ +namespace TheTempusProject\Controllers; + +use TheTempusProject\Houdini\Classes\Issues; +use TheTempusProject\Houdini\Classes\Views; +use TheTempusProject\Classes\Controller; +use TheTempusProject\Models\Projects; + +class Wip extends Controller { + protected static $projects; + + public function index() { + self::$projects = new Projects; + self::$title = '{SITENAME} - Works in Progress'; + self::$pageDescription = 'Its not the longest wip in the world, but I\'m certainly proud of it.'; + + $projects = self::$projects->listPaginated(); + if ( false == $projects ) { + Issues::add( 'error', 'Well, this is embarrassing, surely he wouldn\'t just have no wip..... right.... Dave? ... erm Joey?' ); + return; + } else { + Views::view( 'wip.wip', self::$projects->listPaginated() ); + } + } +} diff --git a/app/plugins/wip/forms.php b/app/plugins/wip/forms.php new file mode 100644 index 0000000..5dcb3c7 --- /dev/null +++ b/app/plugins/wip/forms.php @@ -0,0 +1,79 @@ + + * @link https://TheTempusProject.com + * @license https://opensource.org/licenses/MIT [MIT LICENSE] + */ +namespace TheTempusProject\Plugins\Wip; + +use TheTempusProject\Bedrock\Functions\Input; +use TheTempusProject\Bedrock\Functions\Check; +use TheTempusProject\Classes\Forms; + +class WipForms extends Forms { + /** + * Adds these functions to the form list. + */ + public function __construct() { + self::addHandler( 'newProject', __CLASS__, 'newProject' ); + self::addHandler( 'editProject', __CLASS__, 'editProject' ); + } + + /** + * Validates the new project post form. + * + * @return {bool} + */ + public static function newProject() { + if ( !Input::exists( 'title' ) ) { + self::addUserError( 'You must specify title' ); + return false; + } + if ( !Input::exists( 'description' ) ) { + self::addUserError( 'You must specify description' ); + return false; + } + if ( !Input::exists( 'progress' ) ) { + self::addUserError( 'You must specify progress' ); + return false; + } + if ( !Input::exists( 'startDate' ) ) { + self::addUserError( 'You must specify startDate' ); + return false; + } + return true; + } + + /** + * Validates the edit project post form. + * + * @return {bool} + */ + public static function editProject() { + if ( !Input::exists( 'title' ) ) { + self::addUserError( 'You must specify title' ); + return false; + } + if ( !Input::exists( 'description' ) ) { + self::addUserError( 'You must specify description' ); + return false; + } + if ( !Input::exists( 'progress' ) ) { + self::addUserError( 'You must specify progress' ); + return false; + } + if ( !Input::exists( 'startDate' ) ) { + self::addUserError( 'You must specify startDate' ); + return false; + } + return true; + } +} + +new WipForms; diff --git a/app/plugins/wip/models/projects.php b/app/plugins/wip/models/projects.php new file mode 100644 index 0000000..3968843 --- /dev/null +++ b/app/plugins/wip/models/projects.php @@ -0,0 +1,85 @@ + + * @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\Bin\Canary as Debug; +use TheTempusProject\Classes\DatabaseModel; +use TheTempusProject\Plugins\Wip as Plugin; + +class Projects extends DatabaseModel { + public $tableName = 'projects'; + public $databaseMatrix = [ + [ 'title', 'varchar', '128' ], + [ 'description', 'text', '' ], + [ 'progress', 'int', '3' ], + [ 'startDate', 'varchar', '32' ], + ]; + public $plugin; + + /** + * The model constructor. + */ + public function __construct() { + parent::__construct(); + $this->plugin = new Plugin; + } + + public function create( $title, $description, $progress, $startDate ) { + if ( !$this->plugin->checkEnabled() ) { + Debug::info( 'Wip is disabled in the config.' ); + return false; + } + $fields = [ + 'title' => $title, + 'description' => $description, + 'progress' => $progress, + 'startDate' => $startDate, + ]; + if ( !self::$db->insert( $this->tableName, $fields ) ) { + Debug::info( 'Projects::create - failed to insert to db' ); + return false; + } + return self::$db->lastId(); + } + + public function update( $id, $fields ) { + if ( !Check::id( $id ) ) { + Debug::info( 'Project:update: illegal ID.' ); + return false; + } + if ( !self::$db->update( $this->tableName, $id, $fields ) ) { + // new CustomException( 'projectUpdate' ); + Debug::error( "Project:update: $id not updated: $fields" ); + return false; + } + return true; + } + + public function filter( $postArray, $params = [] ) { + foreach ( $postArray as $instance ) { + if ( !is_object( $instance ) ) { + $instance = $postArray; + $end = true; + } + $instance->prettyStart = $instance->startDate; + $out[] = $instance; + if ( !empty( $end ) ) { + $out = $out[0]; + break; + } + } + return $out; + } +} diff --git a/app/plugins/wip/plugin.php b/app/plugins/wip/plugin.php new file mode 100644 index 0000000..cdede98 --- /dev/null +++ b/app/plugins/wip/plugin.php @@ -0,0 +1,44 @@ + + * @link https://TheTempusProject.com + * @license https://opensource.org/licenses/MIT [MIT LICENSE] + */ +namespace TheTempusProject\Plugins; + +use TheTempusProject\Classes\Plugin; + +class Wip extends Plugin { + public $pluginName = 'TP Wip'; + public $pluginAuthor = 'JoeyK'; + public $pluginWebsite = 'https://TheTempusProject.com'; + public $modelVersion = '1.0'; + public $pluginVersion = '3.0'; + public $pluginDescription = 'A simple plugin which adds management for a wip.'; + public $configName = 'wip'; + public $configMatrix = [ + 'enabled' => [ + 'type' => 'radio', + 'pretty' => 'Enable the wip Feature.', + 'default' => true, + ], + ]; + public $main_links = [ + [ + 'text' => 'WIP', + 'url' => '{ROOT_URL}wip/index', + ], + ]; + public $admin_links = [ + [ + 'text' => ' Wip', + 'url' => '{ROOT_URL}admin/wip', + ], + ]; +} diff --git a/app/plugins/wip/views/admin/create.html b/app/plugins/wip/views/admin/create.html new file mode 100644 index 0000000..c730ee3 --- /dev/null +++ b/app/plugins/wip/views/admin/create.html @@ -0,0 +1,16 @@ +

Create Project

+
+
+

+ +
+

+ +
+

+ +
+

+ + +
\ No newline at end of file diff --git a/app/plugins/wip/views/admin/edit.html b/app/plugins/wip/views/admin/edit.html new file mode 100644 index 0000000..fa82c9f --- /dev/null +++ b/app/plugins/wip/views/admin/edit.html @@ -0,0 +1,16 @@ +

Edit Project

+
+
+

+ +
+

+ +
+

+ +
+

+ + +
\ No newline at end of file diff --git a/app/plugins/wip/views/admin/list.html b/app/plugins/wip/views/admin/list.html new file mode 100644 index 0000000..8cf8197 --- /dev/null +++ b/app/plugins/wip/views/admin/list.html @@ -0,0 +1,41 @@ +Works in Progress +{PAGINATION} +
+ + + + + + + + + + + + + {LOOP} + + + + + + + + + {/LOOP} + {ALT} + + + + {/ALT} + +
TitleProgressStart Date + +
{title}{progress}{startDate} + +
+ No results to show. +
+ Create + +
\ No newline at end of file diff --git a/app/plugins/wip/views/admin/view.html b/app/plugins/wip/views/admin/view.html new file mode 100644 index 0000000..24e8a7c --- /dev/null +++ b/app/plugins/wip/views/admin/view.html @@ -0,0 +1,8 @@ +WIP +
+

{name}

+

{position} from {prettyStart} to {prettyEnd}

+
+ {details} +
+
\ No newline at end of file diff --git a/app/plugins/wip/views/wip.html b/app/plugins/wip/views/wip.html new file mode 100644 index 0000000..f2ef3b4 --- /dev/null +++ b/app/plugins/wip/views/wip.html @@ -0,0 +1,19 @@ +

Work in Progress

+
+{LOOP} +
+

{title}

+

Started: {prettyStart}

+
+
+
+
+ {description} +
+
+{/LOOP} +{ALT} +
+

None Found

+
+{/ALT} \ No newline at end of file