mirror of
https://github.com/bckelley/SimpleMVC.git
synced 2026-08-24 03:34:11 -05:00
init commit
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
.git
|
||||
.vscode
|
||||
@@ -0,0 +1,5 @@
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine on
|
||||
RewriteRule ^$ public/ [L]
|
||||
RewriteRule (.*) public/$1 [L]
|
||||
</IfModule>
|
||||
@@ -0,0 +1,447 @@
|
||||
Attribution-NonCommercial-ShareAlike 4.0 International
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons Corporation ("Creative Commons") is not a law firm and
|
||||
does not provide legal services or legal advice. Distribution of
|
||||
Creative Commons public licenses does not create a lawyer-client or
|
||||
other relationship. Creative Commons makes its licenses and related
|
||||
information available on an "as-is" basis. Creative Commons gives no
|
||||
warranties regarding its licenses, any material licensed under their
|
||||
terms and conditions, or any related information. Creative Commons
|
||||
disclaims all liability for damages resulting from their use to the
|
||||
fullest extent possible.
|
||||
|
||||
Using Creative Commons Public Licenses
|
||||
|
||||
Creative Commons public licenses provide a standard set of terms and
|
||||
conditions that creators and other rights holders may use to share
|
||||
original works of authorship and other material subject to copyright
|
||||
and certain other rights specified in the public license below. The
|
||||
following considerations are for informational purposes only, are not
|
||||
exhaustive, and do not form part of our licenses.
|
||||
|
||||
Considerations for licensors: Our public licenses are
|
||||
intended for use by those authorized to give the public
|
||||
permission to use material in ways otherwise restricted by
|
||||
copyright and certain other rights. Our licenses are
|
||||
irrevocable. Licensors should read and understand the terms
|
||||
and conditions of the license they choose before applying it.
|
||||
Licensors should also secure all rights necessary before
|
||||
applying our licenses so that the public can reuse the
|
||||
material as expected. Licensors should clearly mark any
|
||||
material not subject to the license. This includes other CC-
|
||||
licensed material, or material used under an exception or
|
||||
limitation to copyright. More considerations for licensors:
|
||||
wiki.creativecommons.org/Considerations_for_licensors
|
||||
|
||||
Considerations for the public: By using one of our public
|
||||
licenses, a licensor grants the public permission to use the
|
||||
licensed material under specified terms and conditions. If
|
||||
the licensor's permission is not necessary for any reason--for
|
||||
example, because of any applicable exception or limitation to
|
||||
copyright--then that use is not regulated by the license. Our
|
||||
licenses grant only permissions under copyright and certain
|
||||
other rights that a licensor has authority to grant. Use of
|
||||
the licensed material may still be restricted for other
|
||||
reasons, including because others have copyright or other
|
||||
rights in the material. A licensor may make special requests,
|
||||
such as asking that all changes be marked or described.
|
||||
Although not required by our licenses, you are encouraged to
|
||||
respect those requests where reasonable. More considerations
|
||||
for the public:
|
||||
wiki.creativecommons.org/Considerations_for_licensees
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
|
||||
Public License
|
||||
|
||||
By exercising the Licensed Rights (defined below), You accept and agree
|
||||
to be bound by the terms and conditions of this Creative Commons
|
||||
Attribution-NonCommercial-ShareAlike 4.0 International Public License
|
||||
("Public License"). To the extent this Public License may be
|
||||
interpreted as a contract, You are granted the Licensed Rights in
|
||||
consideration of Your acceptance of these terms and conditions, and the
|
||||
Licensor grants You such rights in consideration of benefits the
|
||||
Licensor receives from making the Licensed Material available under
|
||||
these terms and conditions.
|
||||
|
||||
Section 1 -- Definitions.
|
||||
|
||||
a. Adapted Material means material subject to Copyright and Similar
|
||||
Rights that is derived from or based upon the Licensed Material
|
||||
and in which the Licensed Material is translated, altered,
|
||||
arranged, transformed, or otherwise modified in a manner requiring
|
||||
permission under the Copyright and Similar Rights held by the
|
||||
Licensor. For purposes of this Public License, where the Licensed
|
||||
Material is a musical work, performance, or sound recording,
|
||||
Adapted Material is always produced where the Licensed Material is
|
||||
synched in timed relation with a moving image.
|
||||
|
||||
b. Adapter's License means the license You apply to Your Copyright
|
||||
and Similar Rights in Your contributions to Adapted Material in
|
||||
accordance with the terms and conditions of this Public License.
|
||||
|
||||
c. BY-NC-SA Compatible License means a license listed at
|
||||
creativecommons.org/compatiblelicenses, approved by Creative
|
||||
Commons as essentially the equivalent of this Public License.
|
||||
|
||||
d. Copyright and Similar Rights means copyright and/or similar rights
|
||||
closely related to copyright including, without limitation,
|
||||
performance, broadcast, sound recording, and Sui Generis Database
|
||||
Rights, without regard to how the rights are labeled or
|
||||
categorized. For purposes of this Public License, the rights
|
||||
specified in Section 2(b)(1)-(2) are not Copyright and Similar
|
||||
Rights.
|
||||
|
||||
e. Effective Technological Measures means those measures that, in the
|
||||
absence of proper authority, may not be circumvented under laws
|
||||
fulfilling obligations under Article 11 of the WIPO Copyright
|
||||
Treaty adopted on December 20, 1996, and/or similar international
|
||||
agreements.
|
||||
|
||||
f. Exceptions and Limitations means fair use, fair dealing, and/or
|
||||
any other exception or limitation to Copyright and Similar Rights
|
||||
that applies to Your use of the Licensed Material.
|
||||
|
||||
g. License Elements means the license attributes listed in the name
|
||||
of a Creative Commons Public License. The License Elements of this
|
||||
Public License are Attribution, NonCommercial, and ShareAlike.
|
||||
|
||||
h. Licensed Material means the artistic or literary work, database,
|
||||
or other material to which the Licensor applied this Public
|
||||
License.
|
||||
|
||||
i. Licensed Rights means the rights granted to You subject to the
|
||||
terms and conditions of this Public License, which are limited to
|
||||
all Copyright and Similar Rights that apply to Your use of the
|
||||
Licensed Material and that the Licensor has authority to license.
|
||||
|
||||
j. Licensor means the individual(s) or entity(ies) granting rights
|
||||
under this Public License.
|
||||
|
||||
k. NonCommercial means not primarily intended for or directed towards
|
||||
commercial advantage or monetary compensation. For purposes of
|
||||
this Public License, the exchange of the Licensed Material for
|
||||
other material subject to Copyright and Similar Rights by digital
|
||||
file-sharing or similar means is NonCommercial provided there is
|
||||
no payment of monetary compensation in connection with the
|
||||
exchange.
|
||||
|
||||
l. Share means to provide material to the public by any means or
|
||||
process that requires permission under the Licensed Rights, such
|
||||
as reproduction, public display, public performance, distribution,
|
||||
dissemination, communication, or importation, and to make material
|
||||
available to the public including in ways that members of the
|
||||
public may access the material from a place and at a time
|
||||
individually chosen by them.
|
||||
|
||||
m. Sui Generis Database Rights means rights other than copyright
|
||||
resulting from Directive 96/9/EC of the European Parliament and of
|
||||
the Council of 11 March 1996 on the legal protection of databases,
|
||||
as amended and/or succeeded, as well as other essentially
|
||||
equivalent rights anywhere in the world.
|
||||
|
||||
n. You means the individual or entity exercising the Licensed Rights
|
||||
under this Public License. Your has a corresponding meaning.
|
||||
|
||||
Section 2 -- Scope.
|
||||
|
||||
a. License grant.
|
||||
|
||||
1. Subject to the terms and conditions of this Public License,
|
||||
the Licensor hereby grants You a worldwide, royalty-free,
|
||||
non-sublicensable, non-exclusive, irrevocable license to
|
||||
exercise the Licensed Rights in the Licensed Material to:
|
||||
|
||||
a. reproduce and Share the Licensed Material, in whole or
|
||||
in part, for NonCommercial purposes only by individuals,
|
||||
non-profit organizations, and small businesses
|
||||
(not qualifying as major corporations); and
|
||||
|
||||
b. produce, reproduce, and Share Adapted Material for
|
||||
NonCommercial purposes only by individuals, non-profit
|
||||
organizations, and small businesses
|
||||
(not qualifying as major corporations).
|
||||
|
||||
5. Exceptions and Limitations. For the avoidance of doubt, where
|
||||
Exceptions and Limitations apply to Your use, this Public
|
||||
License does not apply, and You do not need to comply with
|
||||
its terms and conditions.
|
||||
|
||||
6. Term. The term of this Public License is specified in Section
|
||||
6(a).
|
||||
|
||||
7. Media and formats; technical modifications allowed. The
|
||||
Licensor authorizes You to exercise the Licensed Rights in
|
||||
all media and formats whether now known or hereafter created,
|
||||
and to make technical modifications necessary to do so. The
|
||||
Licensor waives and/or agrees not to assert any right or
|
||||
authority to forbid You from making technical modifications
|
||||
necessary to exercise the Licensed Rights, including
|
||||
technical modifications necessary to circumvent Effective
|
||||
Technological Measures. For purposes of this Public License,
|
||||
simply making modifications authorized by this Section 2(a)
|
||||
(4) never produces Adapted Material.
|
||||
|
||||
8. Downstream recipients.
|
||||
|
||||
a. Offer from the Licensor -- Licensed Material. Every
|
||||
recipient of the Licensed Material automatically
|
||||
receives an offer from the Licensor to exercise the
|
||||
Licensed Rights under the terms and conditions of this
|
||||
Public License.
|
||||
|
||||
b. Additional offer from the Licensor -- Adapted Material.
|
||||
Every recipient of Adapted Material from You
|
||||
automatically receives an offer from the Licensor to
|
||||
exercise the Licensed Rights in the Adapted Material
|
||||
under the conditions of the Adapter's License You apply.
|
||||
|
||||
c. No downstream restrictions. You may not offer or impose
|
||||
any additional or different terms or conditions on, or
|
||||
apply any Effective Technological Measures to, the
|
||||
Licensed Material if doing so restricts exercise of the
|
||||
Licensed Rights by any recipient of the Licensed
|
||||
Material.
|
||||
|
||||
9. No endorsement. Nothing in this Public License constitutes or
|
||||
may be construed as permission to assert or imply that You
|
||||
are, or that Your use of the Licensed Material is, connected
|
||||
with, or sponsored, endorsed, or granted official status by,
|
||||
the Licensor or others designated to receive attribution as
|
||||
provided in Section 3(a)(1)(A)(i).
|
||||
|
||||
b. Restrictions on Major Corporations.
|
||||
|
||||
1. The use of the Licensed Material by major corporations is
|
||||
strictly prohibited under this license. Major corporations
|
||||
are defined as entities with a significant market presence,
|
||||
substantial financial resources, and a broad customer base.
|
||||
|
||||
c. Share Back Requirement.
|
||||
|
||||
1. All users are required to share any Adapted Material back
|
||||
to the original source, prominently mentioning the original
|
||||
creator and providing a URI or hyperlink to the original
|
||||
Licensed Material to the extent reasonably practicable.
|
||||
|
||||
d. Other rights.
|
||||
|
||||
1. Moral rights, such as the right of integrity, are not
|
||||
licensed under this Public License, nor are publicity,
|
||||
privacy, and/or other similar personality rights; however, to
|
||||
the extent possible, the Licensor waives and/or agrees not to
|
||||
assert any such rights held by the Licensor to the limited
|
||||
extent necessary to allow You to exercise the Licensed
|
||||
Rights, but not otherwise.
|
||||
|
||||
2. Patent and trademark rights are not licensed under this
|
||||
Public License.
|
||||
|
||||
3. To the extent possible, the Licensor waives any right to
|
||||
collect royalties from You for the exercise of the Licensed
|
||||
Rights, whether directly or through a collecting society
|
||||
under any voluntary or waivable statutory or compulsory
|
||||
licensing scheme. In all other cases the Licensor expressly
|
||||
reserves any right to collect such royalties, including when
|
||||
the Licensed Material is used other than for NonCommercial
|
||||
purposes.
|
||||
|
||||
Section 3 -- License Conditions.
|
||||
|
||||
Your exercise of the Licensed Rights is expressly made subject to the
|
||||
following conditions.
|
||||
|
||||
a. Attribution.
|
||||
|
||||
1. If You Share the Licensed Material (including in modified
|
||||
form), You must:
|
||||
|
||||
a. retain the following if it is supplied by the Licensor
|
||||
with the Licensed Material:
|
||||
|
||||
i. identification of the creator(s) of the Licensed
|
||||
Material and any others designated to receive
|
||||
attribution, in any reasonable manner requested by
|
||||
the Licensor (including by pseudonym if
|
||||
designated);
|
||||
|
||||
ii. a copyright notice;
|
||||
|
||||
iii. a notice that refers to this Public License;
|
||||
|
||||
iv. a notice that refers to the disclaimer of
|
||||
warranties;
|
||||
|
||||
v. a URI or hyperlink to the Licensed Material to the
|
||||
extent reasonably practicable;
|
||||
|
||||
b. indicate if You modified the Licensed Material and
|
||||
retain an indication of any previous modifications; and
|
||||
|
||||
c. indicate the Licensed Material is licensed under this
|
||||
Public License, and include the text of, or the URI or
|
||||
hyperlink to, this Public License.
|
||||
|
||||
2. You may satisfy the conditions in Section 3(a)(1) in any
|
||||
reasonable manner based on the medium, means, and context in
|
||||
which You Share the Licensed Material. For example, it may be
|
||||
reasonable to satisfy the conditions by providing a URI or
|
||||
hyperlink to a resource that includes the required
|
||||
information.
|
||||
3. If requested by the Licensor, You must remove any of the
|
||||
information required by Section 3(a)(1)(A) to the extent
|
||||
reasonably practicable.
|
||||
|
||||
b. ShareAlike.
|
||||
|
||||
In addition to the conditions in Section 3(a), if You Share
|
||||
Adapted Material You produce, the following conditions also apply.
|
||||
|
||||
1. The Adapter's License You apply must be a Creative Commons
|
||||
license with the same License Elements, this version or
|
||||
later, or a BY-NC-SA Compatible License.
|
||||
|
||||
2. You must include the text of, or the URI or hyperlink to, the
|
||||
Adapter's License You apply. You may satisfy this condition
|
||||
in any reasonable manner based on the medium, means, and
|
||||
context in which You Share Adapted Material.
|
||||
|
||||
3. You may not offer or impose any additional or different terms
|
||||
or conditions on, or apply any Effective Technological
|
||||
Measures to, Adapted Material that restrict exercise of the
|
||||
rights granted under the Adapter's License You apply.
|
||||
|
||||
Section 4 -- Sui Generis Database Rights.
|
||||
|
||||
Where the Licensed Rights include Sui Generis Database Rights that
|
||||
apply to Your use of the Licensed Material:
|
||||
|
||||
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
|
||||
to extract, reuse, reproduce, and Share all or a substantial
|
||||
portion of the contents of the database for NonCommercial purposes
|
||||
only;
|
||||
|
||||
b. if You include all or a substantial portion of the database
|
||||
contents in a database in which You have Sui Generis Database
|
||||
Rights, then the database in which You have Sui Generis Database
|
||||
Rights (but not its individual contents) is Adapted Material,
|
||||
including for purposes of Section 3(b); and
|
||||
|
||||
c. You must comply with the conditions in Section 3(a) if You Share
|
||||
all or a substantial portion of the contents of the database.
|
||||
|
||||
For the avoidance of doubt, this Section 4 supplements and does not
|
||||
replace Your obligations under this Public License where the Licensed
|
||||
Rights include other Copyright and Similar Rights.
|
||||
|
||||
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
|
||||
|
||||
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
|
||||
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
|
||||
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
|
||||
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
|
||||
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
|
||||
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
|
||||
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
|
||||
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
|
||||
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
|
||||
|
||||
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
|
||||
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
|
||||
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
|
||||
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
|
||||
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
|
||||
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
|
||||
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
|
||||
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
|
||||
|
||||
c. The disclaimer of warranties and limitation of liability provided
|
||||
above shall be interpreted in a manner that, to the extent
|
||||
possible, most closely approximates an absolute disclaimer and
|
||||
waiver of all liability.
|
||||
|
||||
Section 6 -- Term and Termination.
|
||||
|
||||
a. This Public License applies for the term of the Copyright and
|
||||
Similar Rights licensed here. However, if You fail to comply with
|
||||
this Public License, then Your rights under this Public License
|
||||
terminate automatically.
|
||||
|
||||
b. Where Your right to use the Licensed Material has terminated under
|
||||
Section 6(a), it reinstates:
|
||||
|
||||
1. automatically as of the date the violation is cured, provided
|
||||
it is cured within 30 days of Your discovery of the
|
||||
violation; or
|
||||
|
||||
2. upon express reinstatement by the Licensor.
|
||||
|
||||
For the avoidance of doubt, this Section 6(b) does not affect any
|
||||
right the Licensor may have to seek remedies for Your violations
|
||||
of this Public License.
|
||||
|
||||
c. For the avoidance of doubt, the Licensor may also offer the
|
||||
Licensed Material under separate terms or conditions or stop
|
||||
distributing the Licensed Material at any time; however, doing so
|
||||
will not terminate this Public License.
|
||||
|
||||
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
|
||||
License.
|
||||
|
||||
Section 7 -- Other Terms and Conditions.
|
||||
|
||||
a. The Licensor shall not be bound by any additional or different
|
||||
terms or conditions communicated by You unless expressly agreed.
|
||||
|
||||
b. Any arrangements, understandings, or agreements regarding the
|
||||
Licensed Material not stated herein are separate from and
|
||||
independent of the terms and conditions of this Public License.
|
||||
|
||||
Section 8 -- Interpretation.
|
||||
|
||||
a. For the avoidance of doubt, this Public License does not, and
|
||||
shall not be interpreted to, reduce, limit, restrict, or impose
|
||||
conditions on any use of the Licensed Material that could lawfully
|
||||
be made without permission under this Public License.
|
||||
|
||||
b. To the extent possible, if any provision of this Public License is
|
||||
deemed unenforceable, it shall be automatically reformed to the
|
||||
minimum extent necessary to make it enforceable. If the provision
|
||||
cannot be reformed, it shall be severed from this Public License
|
||||
without affecting the enforceability of the remaining terms and
|
||||
conditions.
|
||||
|
||||
c. No term or condition of this Public License will be waived and no
|
||||
failure to comply consented to unless expressly agreed to by the
|
||||
Licensor.
|
||||
|
||||
d. Nothing in this Public License constitutes or may be interpreted
|
||||
as a limitation upon, or waiver of, any privileges and immunities
|
||||
that apply to the Licensor or You, including from the legal
|
||||
processes of any jurisdiction or authority.
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons is not a party to its public
|
||||
licenses. Notwithstanding, Creative Commons may elect to apply one of
|
||||
its public licenses to material it publishes and in those instances
|
||||
will be considered the “Licensor.” The text of the Creative Commons
|
||||
public licenses is dedicated to the public domain under the CC0 Public
|
||||
Domain Dedication. Except for the limited purpose of indicating that
|
||||
material is shared under a Creative Commons public license or as
|
||||
otherwise permitted by the Creative Commons policies published at
|
||||
creativecommons.org/policies, Creative Commons does not authorize the
|
||||
use of the trademark "Creative Commons" or any other trademark or logo
|
||||
of Creative Commons without its prior written consent including,
|
||||
without limitation, in connection with any unauthorized modifications
|
||||
to any of its public licenses or any other arrangements,
|
||||
understandings, or agreements concerning use of licensed material. For
|
||||
the avoidance of doubt, this paragraph does not form part of the
|
||||
public licenses.
|
||||
|
||||
Creative Commons may be contacted at creativecommons.org.
|
||||
@@ -0,0 +1 @@
|
||||
Options -Indexes
|
||||
@@ -0,0 +1,25 @@
|
||||
<?PHP
|
||||
|
||||
/*
|
||||
* Explanation:
|
||||
* - The code loads the configuration file, which typically contains constants and settings.
|
||||
* - It includes helper files for URL and session-related functions.
|
||||
* - The spl_autoload_register function is used to automatically load class files when needed.
|
||||
* - The anonymous function within spl_autoload_register dynamically requires the class file based on its name.
|
||||
* - This allows for a more organized and modular structure in loading core libraries.
|
||||
*/
|
||||
|
||||
// Load Config
|
||||
require_once 'config/config.php';
|
||||
|
||||
// Include URL Helper Functions
|
||||
require_once 'helpers/url.php';
|
||||
|
||||
// Include Session Helper Functions
|
||||
require_once 'helpers/sessions.php';
|
||||
|
||||
// Autoload Core Libraries using spl_autoload_register
|
||||
spl_autoload_register(function ($className) {
|
||||
// Require the specified class file from the libraries directory
|
||||
require_once 'libraries/' . $className . '.php';
|
||||
});
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
// DB Params
|
||||
define('DBHOST', 'localhost');
|
||||
define('DBUSER', 'root');
|
||||
define('DBPASS', '');
|
||||
define('DBNAME', 'nomadmvc');
|
||||
|
||||
// App Root
|
||||
define('APP_ROOT', dirname(dirname(__FILE__)));
|
||||
|
||||
// URL Root
|
||||
define('URL_ROOT', 'https://routeeasemvc.local');
|
||||
|
||||
// Site Name
|
||||
define('SITENAME', 'RouteEase MVC');
|
||||
|
||||
// App Version
|
||||
/**
|
||||
* TODO: make APP_VERSION a protected class
|
||||
*/
|
||||
define('APP_VERSION', '0.0.1');
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/**
|
||||
* Pages Controller Class
|
||||
*
|
||||
* This class handles the main pages of the application.
|
||||
*/
|
||||
class Pages extends Controller {
|
||||
/**
|
||||
* Constructor method.
|
||||
*/
|
||||
public function __construct(){
|
||||
// Constructor logic (if any)
|
||||
}
|
||||
|
||||
/**
|
||||
* Index Method
|
||||
*
|
||||
* Handles the homepage of the application.
|
||||
*/
|
||||
public function index(){
|
||||
// Check if the user is logged in
|
||||
if (isLoggedIn()) {
|
||||
// Redirect to the posts index page
|
||||
redirect('/posts/index');
|
||||
}
|
||||
|
||||
// Data for the view
|
||||
$data = [
|
||||
'title' => 'Home',
|
||||
'description' => '',
|
||||
];
|
||||
|
||||
// Load the view with the specified data
|
||||
$this->view('pages/index', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* About Method
|
||||
*
|
||||
* Handles the about us page of the application.
|
||||
*/
|
||||
public function about(){
|
||||
// Data for the view
|
||||
$data = [
|
||||
'title' => 'About Us',
|
||||
'description' => '',
|
||||
'version' => APP_VERSION,
|
||||
];
|
||||
|
||||
// Load the view with the specified data
|
||||
$this->view('pages/about', $data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
<?php
|
||||
/**
|
||||
* Posts Controller Class
|
||||
*
|
||||
* This class handles the functionality related to posts in the application.
|
||||
*/
|
||||
class Posts extends Controller {
|
||||
private $postModel;
|
||||
private $userModel;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
*/
|
||||
public function __construct() {
|
||||
// Check if the user is logged in
|
||||
if (!isLoggedIn()) {
|
||||
// Redirect to the login page if not logged in
|
||||
redirect('/users/login');
|
||||
}
|
||||
|
||||
// Initialize models
|
||||
$this->postModel = $this->model('Post');
|
||||
$this->userModel = $this->model('User');
|
||||
}
|
||||
|
||||
/**
|
||||
* Index Method
|
||||
*
|
||||
* Displays a list of posts.
|
||||
*/
|
||||
public function index() {
|
||||
// Get all posts
|
||||
$posts = $this->postModel->getPosts();
|
||||
|
||||
// Data for the view
|
||||
$data = [
|
||||
'posts' => $posts,
|
||||
];
|
||||
|
||||
// Load the view with the specified data
|
||||
$this->view('/posts/index', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show Method
|
||||
*
|
||||
* Displays a single post.
|
||||
*
|
||||
* @param int $id Post ID
|
||||
*/
|
||||
public function show($id) {
|
||||
// Get post and user information
|
||||
$post = $this->postModel->getPost($id);
|
||||
$user = $this->userModel->getUserById($post->user_id);
|
||||
|
||||
// Data for the view
|
||||
$data = [
|
||||
'post' => $post,
|
||||
'user' => $user,
|
||||
];
|
||||
|
||||
// Load the view with the specified data
|
||||
$this->view('/posts/show', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Method
|
||||
*
|
||||
* Adds a new post.
|
||||
*/
|
||||
public function add() {
|
||||
// Check if the form is submitted
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
// Sanitize input data
|
||||
$_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_SPECIAL_CHARS);
|
||||
|
||||
// Extract form data
|
||||
$data = [
|
||||
'title' => trim($_POST['title']),
|
||||
'summary' => trim($_POST['summary']),
|
||||
'body' => trim($_POST['body']),
|
||||
'userId' => $_SESSION['userId'],
|
||||
'titleErr' => '',
|
||||
'summaryErr' => '',
|
||||
'bodyErr' => '',
|
||||
];
|
||||
|
||||
// Validate form data
|
||||
if (empty($data['title'])) {
|
||||
$data['titleErr'] = 'Please enter a title.';
|
||||
}
|
||||
|
||||
if (empty($data['summary'])) {
|
||||
$data['summaryErr'] = 'Please enter a summary.';
|
||||
}
|
||||
|
||||
if (empty($data['body'])) {
|
||||
$data['bodyErr'] = 'Please enter a body.';
|
||||
}
|
||||
|
||||
// Check for errors
|
||||
if (empty($data['titleErr']) && empty($data['summaryErr']) && empty($data['bodyErr'])) {
|
||||
// Add post to the database
|
||||
if ($this->postModel->addPost($data)) {
|
||||
message('post_message', 'Your post has been added.', 'alert alert-success');
|
||||
redirect('/posts/index');
|
||||
} else {
|
||||
die('Something went wrong.');
|
||||
}
|
||||
} else {
|
||||
// Load the view with the specified data and errors
|
||||
$this->view('/posts/add', $data);
|
||||
}
|
||||
} else {
|
||||
// Display the form
|
||||
$data = [
|
||||
'title' => '',
|
||||
'summary' => '',
|
||||
'body' => '',
|
||||
];
|
||||
|
||||
// Load the view with the specified data
|
||||
$this->view('/posts/add', $data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit Method
|
||||
*
|
||||
* Edits an existing post.
|
||||
*
|
||||
* @param int $id Post ID
|
||||
*/
|
||||
public function edit($id) {
|
||||
// Check if the form is submitted
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
// Sanitize input data
|
||||
$_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_SPECIAL_CHARS);
|
||||
|
||||
// Extract form data
|
||||
$data = [
|
||||
'id' => $id,
|
||||
'title' => trim($_POST['title']),
|
||||
'summary' => trim($_POST['summary']),
|
||||
'body' => trim($_POST['body']),
|
||||
'userId' => $_SESSION['userId'],
|
||||
'titleErr' => '',
|
||||
'summaryErr' => '',
|
||||
'bodyErr' => '',
|
||||
];
|
||||
|
||||
// Validate form data
|
||||
if (empty($data['title'])) {
|
||||
$data['titleErr'] = 'Please enter a title.';
|
||||
}
|
||||
|
||||
if (empty($data['summary'])) {
|
||||
$data['summaryErr'] = 'Please enter a summary.';
|
||||
}
|
||||
|
||||
if (empty($data['body'])) {
|
||||
$data['bodyErr'] = 'Please enter a body.';
|
||||
}
|
||||
|
||||
// Check for errors
|
||||
if (empty($data['titleErr']) && empty($data['summaryErr']) && empty($data['bodyErr'])) {
|
||||
// Update post in the database
|
||||
if ($this->postModel->updatePost($data)) {
|
||||
message('post_message', 'Your post has been updated.', 'alert alert-success');
|
||||
redirect('/posts/index');
|
||||
} else {
|
||||
die('Something went wrong.');
|
||||
}
|
||||
} else {
|
||||
// Load the view with the specified data and errors
|
||||
$this->view('/posts/edit', $data);
|
||||
}
|
||||
} else {
|
||||
// Display the form with existing post data
|
||||
$post = $this->postModel->getPost($id);
|
||||
|
||||
// Check if the user is authorized to edit the post
|
||||
if ($post->user_id != $_SESSION['userId']) {
|
||||
redirect('/posts/index');
|
||||
}
|
||||
|
||||
// Data for the view
|
||||
$data = [
|
||||
'id' => $id,
|
||||
'title' => $post->title,
|
||||
'summary' => $post->summary,
|
||||
'body' => $post->body,
|
||||
];
|
||||
|
||||
// Load the view with the specified data
|
||||
$this->view('/posts/edit', $data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete Method
|
||||
*
|
||||
* Deletes a post.
|
||||
*
|
||||
* @param int $id Post ID
|
||||
*/
|
||||
public function delete($id) {
|
||||
// Check if the form is submitted
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
// Delete post from the database
|
||||
if ($this->postModel->deletePost($id)) {
|
||||
message('post_message', 'Your post has been removed.');
|
||||
redirect('/posts/index');
|
||||
} else {
|
||||
die('Something went wrong');
|
||||
}
|
||||
} else {
|
||||
// Redirect to the posts index page if form is not submitted
|
||||
redirect('/posts/index');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
<?php
|
||||
/**
|
||||
* Users Controller Class
|
||||
*
|
||||
* This class handles user-related functionality such as registration, login, and logout.
|
||||
*/
|
||||
class Users extends Controller {
|
||||
private $userModel;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
*/
|
||||
public function __construct() {
|
||||
// Initialize the user model
|
||||
$this->userModel = $this->model('User');
|
||||
}
|
||||
|
||||
/**
|
||||
* Register Method
|
||||
*
|
||||
* Handles user registration.
|
||||
*/
|
||||
public function register() {
|
||||
// Check if the form is submitted
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
// Sanitize input data
|
||||
$_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_SPECIAL_CHARS);
|
||||
|
||||
// Extract form data
|
||||
$data = [
|
||||
'username' => trim($_POST['username']),
|
||||
'email' => trim($_POST['email']),
|
||||
'password' => trim($_POST['password']),
|
||||
'again' => trim($_POST['again']),
|
||||
'usernameErr' => '',
|
||||
'emailErr' => '',
|
||||
'passErr' => '',
|
||||
'againErr' => '',
|
||||
];
|
||||
|
||||
// Validate form data
|
||||
if (empty($data['email'])) {
|
||||
$data['emailErr'] = 'Please provide an email.';
|
||||
} else {
|
||||
if ($this->userModel->findUserByEmail($data['email'])) {
|
||||
$data['emailErr'] = 'Email exists.';
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($data['username'])) {
|
||||
$data['usernameErr'] = 'Please provide a valid username.';
|
||||
}
|
||||
|
||||
if (empty($data['password'])) {
|
||||
$data['passErr'] = 'Please provide a valid password.';
|
||||
} elseif (strlen($data['password']) < 6) {
|
||||
$data['passErr'] = 'Please provide a password 6 or more characters in length.';
|
||||
}
|
||||
|
||||
if (empty($data['again'])) {
|
||||
$data['againErr'] = 'Please confirm your password.';
|
||||
} else {
|
||||
if ($data['password'] != $data['again']) {
|
||||
$data['passErr'] = 'Passwords do not match.';
|
||||
}
|
||||
}
|
||||
|
||||
// Check for errors
|
||||
if (empty($data['usernameErr']) && empty($data['emailErr']) &&
|
||||
empty($data['passErr']) && empty($data['againErr'])) {
|
||||
|
||||
// Hash the password
|
||||
$data['password'] = password_hash($data['password'], PASSWORD_BCRYPT);
|
||||
|
||||
// Register the user
|
||||
if ($this->userModel->register($data)) {
|
||||
message('reg_success', 'You are now registered and can login.', 'alert alert-success');
|
||||
redirect('/users/login');
|
||||
} else {
|
||||
die('Something went wrong.');
|
||||
}
|
||||
} else {
|
||||
// Load the view with the specified data and errors
|
||||
$this->view('users/register', $data);
|
||||
}
|
||||
|
||||
} else {
|
||||
// Display the registration form
|
||||
$data = [
|
||||
'username' => '',
|
||||
'email' => '',
|
||||
'password' => '',
|
||||
'again' => '',
|
||||
'usernameErr' => '',
|
||||
'emailErr' => '',
|
||||
'passErr' => '',
|
||||
'againErr' => '',
|
||||
];
|
||||
|
||||
// Load the view with the specified data
|
||||
$this->view('users/register', $data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Login Method
|
||||
*
|
||||
* Handles user login.
|
||||
*/
|
||||
public function login() {
|
||||
// Check if the form is submitted
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
// Sanitize input data
|
||||
$_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_SPECIAL_CHARS);
|
||||
|
||||
// Extract form data
|
||||
$data = [
|
||||
'email' => trim($_POST['email']),
|
||||
'password' => trim($_POST['password']),
|
||||
'emailErr' => '',
|
||||
'passErr' => '',
|
||||
];
|
||||
|
||||
// Validate form data
|
||||
if (empty($data['email'])) {
|
||||
$data['emailErr'] = 'Please provide an email.';
|
||||
}
|
||||
|
||||
if (empty($data['password'])) {
|
||||
$data['passErr'] = 'Please provide a valid password.';
|
||||
} elseif (strlen($data['password']) < 6) {
|
||||
$data['passErr'] = 'Please provide a password 6 or more characters in length.';
|
||||
}
|
||||
|
||||
// Check if the user exists
|
||||
if ($this->userModel->findUserByEmail($data['email'])) {
|
||||
|
||||
} else {
|
||||
$data['emailErr'] = 'No user found.';
|
||||
}
|
||||
|
||||
// Check for errors
|
||||
if (empty($data['emailErr']) && empty($data['passErr'])) {
|
||||
// Attempt to log in the user
|
||||
$loggedIn = $this->userModel->login($data['email'], $data['password']);
|
||||
|
||||
if ($loggedIn) {
|
||||
$this->createUserSession($loggedIn);
|
||||
} else {
|
||||
$data['passErr'] = 'Password was incorrect.';
|
||||
}
|
||||
} else {
|
||||
// Load the view with the specified data and errors
|
||||
$this->view('users/login', $data);
|
||||
}
|
||||
|
||||
} else {
|
||||
// Display the login form
|
||||
$data = [
|
||||
// 'username' => '',
|
||||
'email' => '',
|
||||
'password' => '',
|
||||
// 'usernameErr' => '',
|
||||
'emailErr' => '',
|
||||
'passErr' => '',
|
||||
];
|
||||
|
||||
// Load the view with the specified data
|
||||
$this->view('users/login', $data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* createUserSession Method
|
||||
*
|
||||
* Creates a user session upon successful login.
|
||||
*
|
||||
* @param object $user User object
|
||||
*/
|
||||
public function createUserSession($user) {
|
||||
// Set session variables
|
||||
$_SESSION['userId'] = $user->id;
|
||||
$_SESSION['username'] = $user->name;
|
||||
$_SESSION['userEmail'] = $user->email;
|
||||
|
||||
// Redirect to the posts index page
|
||||
redirect('/posts/index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Logout Method
|
||||
*
|
||||
* Logs out the user.
|
||||
*/
|
||||
public function logout() {
|
||||
// Unset session variables
|
||||
unset($_SESSION['userId']);
|
||||
unset($_SESSION['username']);
|
||||
unset($_SESSION['userEmail']);
|
||||
|
||||
// Redirect to the login page
|
||||
redirect('/users/login');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
/**
|
||||
* Start Session
|
||||
*
|
||||
* Start the PHP session.
|
||||
*/
|
||||
session_start();
|
||||
|
||||
/**
|
||||
* Message Function
|
||||
*
|
||||
* Set or display a flash message.
|
||||
*
|
||||
* @param string $name Name of the message session variable
|
||||
* @param string $msg Message content
|
||||
* @param string $class CSS class for styling the message (default: 'alert alert-primary')
|
||||
*/
|
||||
function message($name='', $msg='', $class='alert alert-primary') {
|
||||
if (!empty($name)) {
|
||||
if (!empty($msg) && empty($_SESSION[$name])) {
|
||||
// Set the message and its class in the session
|
||||
if (!empty($_SESSION[$name])) {
|
||||
unset($_SESSION[$name]);
|
||||
}
|
||||
|
||||
if (!empty($_SESSION[$name . '_class'])) {
|
||||
unset($_SESSION[$name . '_class']);
|
||||
}
|
||||
|
||||
$_SESSION[$name] = $msg;
|
||||
$_SESSION[$name . '_class'] = $class;
|
||||
} elseif (empty($msg) && !empty($_SESSION[$name])) {
|
||||
// Display the message and its class
|
||||
$class = !empty($_SESSION[$name . '_class']) ? $_SESSION[$name . '_class'] : '';
|
||||
echo '<div class="'. $class .'" id="route-msg">' . $_SESSION[$name] . '</div>';
|
||||
|
||||
// Clear the session variables
|
||||
unset($_SESSION[$name]);
|
||||
unset($_SESSION[$name . '_class']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Logged In Function
|
||||
*
|
||||
* Check if a user is logged in.
|
||||
*
|
||||
* @return bool Returns true if the user is logged in, false otherwise.
|
||||
*/
|
||||
function isLoggedIn() {
|
||||
if (isset($_SESSION['userId'])) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
/**
|
||||
* Redirect Function
|
||||
*
|
||||
* Redirect the user to a specified page.
|
||||
*
|
||||
* @param string $page The page to redirect to
|
||||
*/
|
||||
function redirect($page) {
|
||||
// Use the header function to perform the redirection
|
||||
header('Location: ' . URL_ROOT . $page);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
/**
|
||||
* Base Controller Class
|
||||
*
|
||||
* This class serves as the base controller, responsible for loading models and views.
|
||||
*/
|
||||
class Controller {
|
||||
/**
|
||||
* Load Model Method
|
||||
*
|
||||
* Loads and instantiates the specified model.
|
||||
*
|
||||
* @param string $model The name of the model to be loaded
|
||||
* @return object An instance of the specified model
|
||||
*/
|
||||
public function model($model) {
|
||||
// Require the model file
|
||||
require_once '../app/models/' . $model . '.php';
|
||||
|
||||
// Instantiate the model
|
||||
return new $model();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load View Method
|
||||
*
|
||||
* Loads the specified view file and passes data to it.
|
||||
*
|
||||
* @param string $view The name of the view file to be loaded
|
||||
* @param array $data Data to be passed to the view (default: [])
|
||||
* @param array $class Additional classes to be applied to the view (default: [])
|
||||
*/
|
||||
public function view($view, $data = [], $class = []) {
|
||||
// Check if the view file exists
|
||||
if (file_exists('../app/views/' . $view . '.php')) {
|
||||
// Require the view file
|
||||
require_once '../app/views/' . $view . '.php';
|
||||
} else {
|
||||
// View does not exist
|
||||
die('View does not exist');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/**
|
||||
* App Core Class
|
||||
*
|
||||
* This class creates the URL and loads the core controller.
|
||||
* URL FORMAT - /controller/method/params
|
||||
*/
|
||||
class Core {
|
||||
protected $currentController = 'Pages';
|
||||
protected $currentMethod = 'index';
|
||||
protected $params = [];
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
*/
|
||||
public function __construct() {
|
||||
// Get the URL
|
||||
$url = $this->getUrl();
|
||||
|
||||
// Look in controllers for the first value
|
||||
if (!empty($url[0])) {
|
||||
if (file_exists('../app/controllers/' . ucwords($url[0]) . '.php')) {
|
||||
// If exists, set as controller
|
||||
$this->currentController = ucwords($url[0]);
|
||||
// Unset 0 Index
|
||||
unset($url[0]);
|
||||
}
|
||||
}
|
||||
|
||||
// Require the controller
|
||||
require_once '../app/controllers/' . $this->currentController . '.php';
|
||||
|
||||
// Instantiate the controller class
|
||||
$this->currentController = new $this->currentController;
|
||||
|
||||
// Check for the second part of the URL
|
||||
if (isset($url[1])) {
|
||||
// Check to see if the method exists in the controller
|
||||
if (method_exists($this->currentController, $url[1])) {
|
||||
$this->currentMethod = $url[1];
|
||||
// Unset 1 index
|
||||
unset($url[1]);
|
||||
}
|
||||
}
|
||||
|
||||
// Get params
|
||||
$this->params = $url ? array_values($url) : [];
|
||||
|
||||
// Call a callback with an array of params
|
||||
call_user_func_array([$this->currentController, $this->currentMethod], $this->params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get URL Method
|
||||
*
|
||||
* Gets the URL and prepares it for processing.
|
||||
*
|
||||
* @return array An array representing the URL
|
||||
*/
|
||||
public function getUrl() {
|
||||
if (isset($_GET['url'])) {
|
||||
$url = rtrim($_GET['url'], '/');
|
||||
$url = filter_var($url, FILTER_SANITIZE_URL);
|
||||
$url = explode('/', $url);
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
/**
|
||||
* PDO Database Class
|
||||
*
|
||||
* This class is responsible for connecting to the database, creating prepared statements,
|
||||
* binding values, and returning rows and results.
|
||||
*/
|
||||
class Database {
|
||||
private $host = DBHOST;
|
||||
private $user = DBUSER;
|
||||
private $pass = DBPASS;
|
||||
private $dbname = DBNAME;
|
||||
|
||||
private $dbh; // PDO instance
|
||||
private $stmt; // Prepared statement
|
||||
private $error; // Error message
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
*/
|
||||
public function __construct() {
|
||||
// Set DSN
|
||||
$dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname;
|
||||
$options = array(
|
||||
PDO::ATTR_PERSISTENT => true,
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
|
||||
);
|
||||
|
||||
// Create PDO instance
|
||||
try {
|
||||
$this->dbh = new PDO($dsn, $this->user, $this->pass, $options);
|
||||
} catch (PDOException $e) {
|
||||
$this->error = $e->getMessage();
|
||||
echo $this->error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Query Method
|
||||
*
|
||||
* Prepares a statement with the provided SQL query.
|
||||
*
|
||||
* @param string $sql The SQL query
|
||||
*/
|
||||
public function query($sql) {
|
||||
$this->stmt = $this->dbh->prepare($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind Method
|
||||
*
|
||||
* Binds a value to a parameter in the prepared statement.
|
||||
*
|
||||
* @param mixed $param The parameter to bind
|
||||
* @param mixed $value The value to bind
|
||||
* @param string $type The data type (default: null)
|
||||
*/
|
||||
public function bind($param, $value, $type = null) {
|
||||
if (is_null($type)) {
|
||||
switch (true) {
|
||||
case is_int($value):
|
||||
$type = PDO::PARAM_INT;
|
||||
break;
|
||||
case is_bool($value):
|
||||
$type = PDO::PARAM_BOOL;
|
||||
break;
|
||||
case is_null($value):
|
||||
$type = PDO::PARAM_NULL;
|
||||
break;
|
||||
default:
|
||||
$type = PDO::PARAM_STR;
|
||||
}
|
||||
}
|
||||
|
||||
$this->stmt->bindValue($param, $value, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute Method
|
||||
*
|
||||
* Executes the prepared statement.
|
||||
*
|
||||
* @return bool Returns true on success, false on failure
|
||||
*/
|
||||
public function execute() {
|
||||
return $this->stmt->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* ResultSet Method
|
||||
*
|
||||
* Gets the result set as an array of objects.
|
||||
*
|
||||
* @return array An array of objects representing the result set
|
||||
*/
|
||||
public function resultSet() {
|
||||
$this->execute();
|
||||
return $this->stmt->fetchAll(PDO::FETCH_OBJ);
|
||||
}
|
||||
|
||||
/**
|
||||
* Single Method
|
||||
*
|
||||
* Gets a single record as an object.
|
||||
*
|
||||
* @return object An object representing a single record
|
||||
*/
|
||||
public function single() {
|
||||
$this->execute();
|
||||
return $this->stmt->fetch(PDO::FETCH_OBJ);
|
||||
}
|
||||
|
||||
/**
|
||||
* RowCount Method
|
||||
*
|
||||
* Gets the row count of the result set.
|
||||
*
|
||||
* @return int The number of rows affected by the last SQL statement
|
||||
*/
|
||||
public function rowCount() {
|
||||
return $this->stmt->rowCount();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
/**
|
||||
* Post Class
|
||||
*
|
||||
* This class is responsible for handling post-related database operations.
|
||||
*/
|
||||
class Post {
|
||||
private $db; // Database instance
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->db = new Database;
|
||||
}
|
||||
|
||||
/**
|
||||
* GetPosts Method
|
||||
*
|
||||
* Fetches all posts from the database.
|
||||
*
|
||||
* @return array An array of post objects
|
||||
*/
|
||||
public function getPosts() {
|
||||
$this->db->query('SELECT *, posts.id as postId,
|
||||
users.id as userId,
|
||||
posts.created_at as postCreated,
|
||||
users.created_at as userCreated
|
||||
FROM posts INNER JOIN users ON posts.user_id = users.id ORDER BY posts.created_at DESC');
|
||||
|
||||
$res = $this->db->resultSet();
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* GetPost Method
|
||||
*
|
||||
* Fetches a single post by its ID.
|
||||
*
|
||||
* @param int $id The ID of the post
|
||||
* @return object An object representing a single post
|
||||
*/
|
||||
public function getPost($id) {
|
||||
$this->db->query('SELECT * FROM posts WHERE id = :id');
|
||||
$this->db->bind(':id', $id);
|
||||
|
||||
$row = $this->db->single();
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* AddPost Method
|
||||
*
|
||||
* Inserts a new post into the database.
|
||||
*
|
||||
* @param array $data An associative array containing post data
|
||||
* @return bool Returns true on success, false on failure
|
||||
*/
|
||||
public function addPost($data) {
|
||||
$this->db->query('INSERT INTO posts (user_id, title, summary, body) VALUES(:userId, :title, :summary, :body)');
|
||||
|
||||
$this->db->bind(':userId', $data['userId']);
|
||||
$this->db->bind(':title', $data['title']);
|
||||
$this->db->bind(':summary', $data['summary']);
|
||||
$this->db->bind(':body', $data['body']);
|
||||
|
||||
if ($this->db->execute()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* UpdatePost Method
|
||||
*
|
||||
* Updates an existing post in the database.
|
||||
*
|
||||
* @param array $data An associative array containing post data
|
||||
* @return bool Returns true on success, false on failure
|
||||
*/
|
||||
public function updatePost($data) {
|
||||
$this->db->query('UPDATE posts SET title=:title, summary=:summary, body=:body WHERE id=:id');
|
||||
|
||||
$this->db->bind(':id', $data['id']);
|
||||
$this->db->bind(':title', $data['title']);
|
||||
$this->db->bind(':summary', $data['summary']);
|
||||
$this->db->bind(':body', $data['body']);
|
||||
|
||||
if ($this->db->execute()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DeletePost Method
|
||||
*
|
||||
* Deletes a post from the database by its ID.
|
||||
*
|
||||
* @param int $id The ID of the post
|
||||
* @return bool Returns true on success, false on failure
|
||||
*/
|
||||
public function deletePost($id) {
|
||||
$this->db->query('DELETE FROM posts WHERE id = :id');
|
||||
$this->db->bind(':id', $id);
|
||||
|
||||
if ($this->db->execute()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
/**
|
||||
* User Class
|
||||
*
|
||||
* This class is responsible for handling user-related database operations.
|
||||
*/
|
||||
class User {
|
||||
private $db; // Database instance
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->db = new Database;
|
||||
}
|
||||
|
||||
/**
|
||||
* GetUserById Method
|
||||
*
|
||||
* Fetches a user by their ID.
|
||||
*
|
||||
* @param int $id The ID of the user
|
||||
* @return object An object representing the user
|
||||
*/
|
||||
public function getUserById($id) {
|
||||
$this->db->query('SELECT * FROM users WHERE id = :id');
|
||||
$this->db->bind(':id', $id);
|
||||
|
||||
$row = $this->db->single();
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* FindUserByEmail Method
|
||||
*
|
||||
* Checks if a user with the given email exists.
|
||||
*
|
||||
* @param string $email The email of the user
|
||||
* @return bool Returns true if the user exists, false otherwise
|
||||
*/
|
||||
public function findUserByEmail($email) {
|
||||
$this->db->query('SELECT * FROM users WHERE email = :email');
|
||||
$this->db->bind(':email', $email);
|
||||
|
||||
$row = $this->db->single();
|
||||
|
||||
if ($this->db->rowCount() > 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register Method
|
||||
*
|
||||
* Registers a new user in the database.
|
||||
*
|
||||
* @param array $data An associative array containing user data
|
||||
* @return bool Returns true on success, false on failure
|
||||
*/
|
||||
public function register($data) {
|
||||
$this->db->query('INSERT INTO users (name, email, password) VALUES(:name, :email, :password)');
|
||||
|
||||
$this->db->bind(':name', $data['username']);
|
||||
$this->db->bind(':email', $data['email']);
|
||||
$this->db->bind(':password', $data['password']);
|
||||
|
||||
if ($this->db->execute()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Login Method
|
||||
*
|
||||
* Performs user login based on email and password.
|
||||
*
|
||||
* @param string $email The email of the user
|
||||
* @param string $password The password of the user
|
||||
* @return mixed Returns the user object on success, false on failure
|
||||
*/
|
||||
public function login($email, $password) {
|
||||
$this->db->query('SELECT * FROM users WHERE email = :email');
|
||||
$this->db->bind(':email', $email);
|
||||
|
||||
$row = $this->db->single();
|
||||
|
||||
$hashedPassword = $row->password;
|
||||
if (password_verify($password, $hashedPassword)) {
|
||||
return $row;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
</div>
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.12.9/dist/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
|
||||
|
||||
<script src="<?php echo URL_ROOT; ?>/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,24 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
|
||||
<link rel="stylesheet" href="<?php echo URL_ROOT; ?>/css/style.css">
|
||||
<title><?php echo SITENAME; ?></title>
|
||||
|
||||
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<?php require APP_ROOT . '/views/inc/navbar.php' ?>
|
||||
|
||||
<div class="container">
|
||||
@@ -0,0 +1,53 @@
|
||||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark mb-3">
|
||||
<div class="container">
|
||||
<!-- Brand Logo and Link -->
|
||||
<a class="navbar-brand" href="<?php echo URL_ROOT ?>"><?php echo SITENAME ?></a>
|
||||
|
||||
<!-- Navbar Toggler Button for Responsive Design -->
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#topNavbarMain" aria-controls="topNavbarMain" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<?php
|
||||
// TODO: Add bootstrap active class dynamically based on the current page
|
||||
?>
|
||||
|
||||
<!-- Navbar Links -->
|
||||
<div class="collapse navbar-collapse" id="topNavbarMain">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<!-- Home Link -->
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="<?php echo URL_ROOT ?>">Home</a>
|
||||
</li>
|
||||
|
||||
<!-- About Link -->
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="<?php echo URL_ROOT ?>/pages/about">About</a>
|
||||
</li>
|
||||
|
||||
<!-- Posts Link -->
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="<?php echo URL_ROOT ?>/posts/">Posts</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!-- Right-aligned Navbar Links -->
|
||||
<ul class="navbar-nav ml-auto">
|
||||
<?php if (isset($_SESSION['userId'])) : ?>
|
||||
<!-- Logout Link if User is Logged In -->
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="<?php echo URL_ROOT ?>/users/logout">Logout</a>
|
||||
</li>
|
||||
<?php else : ?>
|
||||
<!-- Register and Login Links if User is Not Logged In -->
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="<?php echo URL_ROOT ?>/users/register">Register</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="<?php echo URL_ROOT ?>/users/login">Login</a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php require APP_ROOT . '/views/inc/header.php'; ?>
|
||||
<div class="jumbotron jumbotron-fluid text-center">
|
||||
<div class="container">
|
||||
<h1 class="display-3"><?PHP echo $data['title']; ?></h1>
|
||||
<p class="lead"><?PHP echo $data['description'] ?></p>
|
||||
<p class="lead"><span class="h5">Version: </span> <?PHP echo $data['version'] ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<?php require APP_ROOT . '/views/inc/footer.php'; ?>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php require APP_ROOT . '/views/inc/header.php'; ?>
|
||||
<div class="jumbotron jumbotron-fluid text-center">
|
||||
<div class="container">
|
||||
<h1 class="display-3"><?php echo $data['title']; ?></h1>
|
||||
<p class="lead"><?PHP echo $data['description'] ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<?php require APP_ROOT . '/views/inc/footer.php'; ?>
|
||||
@@ -0,0 +1,28 @@
|
||||
<?PHP require APP_ROOT.'/views/inc/header.php' ?>
|
||||
<a href="<?PHP echo URL_ROOT ?>/posts/index" class="btn btn-secondary"><i class="fa fa-backward"></i> Back</a>
|
||||
<div class="card card-body bg-light mt-5">
|
||||
<h2>Add Post</h2>
|
||||
<p>Create a new post.</p>
|
||||
<form action="<?PHP echo URL_ROOT ?>/posts/add" method="post">
|
||||
<div class="form-group">
|
||||
<label for="title">Title: <sup class="is-invalid">*</sup></label>
|
||||
<input type="text" name="title" id="" class="form-control form-control-lg <?PHP echo (!empty($data['titleErr'])) ? 'is-invalid' : '' ?>" value="<?PHP echo $data['title']?>" />
|
||||
<span class="invalid-feedback"><?PHP echo $data['titleErr'] ?></span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="summary">Summary: <sup class="is-invalid">*</sup></label>
|
||||
<input type="text" name="summary" id="" class="form-control form-control-lg <?PHP echo (!empty($data['summaryErr'])) ? 'is-invalid' : '' ?>" value="<?PHP echo $data['summary']?>" />
|
||||
<span class="invalid-feedback"><?PHP echo $data['summaryErr'] ?></span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="body">Body: <sup class="is-invalid">*</sup></label>
|
||||
<textarea name="body" id="" class="form-control form-control-lg <?PHP echo (!empty($data['bodyErr'])) ? 'is-invalid' : '' ?>"><?PHP echo $data['body']?></textarea>
|
||||
<span class="invalid-feedback"><?PHP echo $data['bodyErr'] ?></span>
|
||||
</div>
|
||||
<input type="submit" class="btn btn-primary" value="Submit">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<?PHP require APP_ROOT.'/views/inc/footer.php' ?>
|
||||
@@ -0,0 +1,28 @@
|
||||
<?PHP require APP_ROOT.'/views/inc/header.php' ?>
|
||||
<a href="<?PHP echo URL_ROOT ?>/posts/index" class="btn btn-secondary"><i class="fa fa-backward"></i> Back</a>
|
||||
<div class="card card-body bg-light mt-5">
|
||||
<h2>Edit Post</h2>
|
||||
<p>Create a new post.</p>
|
||||
<form action="<?PHP echo URL_ROOT ?>/posts/edit/<?PHP echo $data['id'] ?>" method="post">
|
||||
<div class="form-group">
|
||||
<label for="title">Title: <sup class="is-invalid">*</sup></label>
|
||||
<input type="text" name="title" id="" class="form-control form-control-lg <?PHP echo (!empty($data['titleErr'])) ? 'is-invalid' : '' ?>" value="<?PHP echo $data['title']?>" />
|
||||
<span class="invalid-feedback"><?PHP echo $data['titleErr'] ?></span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="summary">Summary: <sup class="is-invalid">*</sup></label>
|
||||
<input type="text" name="summary" id="" class="form-control form-control-lg <?PHP echo (!empty($data['summaryErr'])) ? 'is-invalid' : '' ?>" value="<?PHP echo $data['summary']?>" />
|
||||
<span class="invalid-feedback"><?PHP echo $data['summaryErr'] ?></span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="body">Body: <sup class="is-invalid">*</sup></label>
|
||||
<textarea name="body" id="" class="form-control form-control-lg <?PHP echo (!empty($data['bodyErr'])) ? 'is-invalid' : '' ?>"><?PHP echo $data['body']?></textarea>
|
||||
<span class="invalid-feedback"><?PHP echo $data['bodyErr'] ?></span>
|
||||
</div>
|
||||
<input type="submit" class="btn btn-primary" value="Submit">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<?PHP require APP_ROOT.'/views/inc/footer.php' ?>
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php require APP_ROOT . '/views/inc/header.php'; ?>
|
||||
<?PHP echo message('post_message'); ?>
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-6">
|
||||
<h1>Posts</h1>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<a href="<?PHP echo URL_ROOT; ?>/posts/add" class="btn btn-primary pull-right">
|
||||
<i class="fa fa-pencil"></i> Add Post
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<?PHP foreach ($data['posts'] as $post) : ?>
|
||||
<div class="card card-body mb-3">
|
||||
<h4 class="card-title"><?PHP echo $post->title ?></h4>
|
||||
<div class="bg-light p-2 mb-3">
|
||||
written by: <?PHP echo $post->name ?> on <?PHP echo $post->postCreated ?>
|
||||
</div>
|
||||
<p class="card-text"><?PHP echo $post->summary ?></p>
|
||||
<a href="<?PHP echo URL_ROOT ?>/posts/show/<?PHP echo $post->postId ?>" class="btn btn-dark">Read More</a>
|
||||
</div>
|
||||
<?PHP endforeach; ?>
|
||||
<?php require APP_ROOT . '/views/inc/footer.php'; ?>
|
||||
@@ -0,0 +1,21 @@
|
||||
<?PHP require APP_ROOT.'/views/inc/header.php' ?>
|
||||
|
||||
<a href="<?PHP echo URL_ROOT ?>/posts/index" class="btn btn-secondary"><i class="fa fa-backward"></i> Back</a>
|
||||
<div class="card card-body bg-light mt-5">
|
||||
<h1><?PHP echo $data['post']->title ?></h1>
|
||||
<div class="bg-secondary text-white p-2 mb-3">
|
||||
Written by <?PHP echo $data['user']->name ?> on <?PHP echo $data['post']->created_at ?></div>
|
||||
</div>
|
||||
|
||||
<p><?PHP echo $data['post']->body ?></p>
|
||||
|
||||
<?PHP if ($data['post']->user_id == $_SESSION['userId']) : ?>
|
||||
<hr>
|
||||
<a href="<?PHP echo URL_ROOT ?>/posts/edit/<?PHP echo $data['post']->id ?>" class="btn btn-dark"><i class="fa fa-edit"></i> Edit Post</a>
|
||||
|
||||
<form method="post" action="<?PHP echo URL_ROOT ?>/posts/delete/<?PHP echo $data['post']->id ?>" class="pull-right">
|
||||
<input type="submit" value="Delete Post" class="btn btn-danger">
|
||||
</form>
|
||||
<?PHP endif;?>
|
||||
|
||||
<?PHP require APP_ROOT.'/views/inc/footer.php' ?>
|
||||
@@ -0,0 +1,35 @@
|
||||
<?PHP require APP_ROOT.'/views/inc/header.php' ?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 mx-auto">
|
||||
<div class="card card-body bg-light mt-5">
|
||||
<?PHP echo message('reg_success') ?>
|
||||
<h2>Login to your Account</h2>
|
||||
<p>Fill in your information to continue.</p>
|
||||
<form action="<?PHP echo URL_ROOT ?>/users/login" method="post">
|
||||
<div class="form-group">
|
||||
<label for="email">Email: <sup class="is-invalid">*</sup></label>
|
||||
<input type="email" name="email" id="" class="form-control form-control-lg <?PHP echo (!empty($data['emailErr'])) ? 'is-invalid' : '' ?>" value="<?PHP echo $data['email']?>" />
|
||||
<span class="invalid-feedback"><?PHP echo $data['emailErr'] ?></span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="password">Password: <sup class="is-invalid">*</sup></label>
|
||||
<input type="password" name="password" id="" class="form-control form-control-lg <?PHP echo (!empty($data['passErr'])) ? 'is-invalid' : '' ?>" value="<?PHP echo $data['password']?>" />
|
||||
<span class="invalid-feedback"><?PHP echo $data['passErr'] ?></span>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<input type="submit" value="Login" class="btn btn-success btn-block" />
|
||||
</div>
|
||||
<div class="col">
|
||||
<a href="<?PHP echo URL_ROOT ?>/users/register" class="btn btn-light btn-block">Register</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?PHP require APP_ROOT.'/views/inc/footer.php' ?>
|
||||
@@ -0,0 +1,42 @@
|
||||
<?PHP require APP_ROOT.'/views/inc/header.php' ?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 mx-auto">
|
||||
<div class="card card-body bg-light mt-5">
|
||||
<h2>Create an Account</h2>
|
||||
<p>Fill out to Register</p>
|
||||
<form action="<?PHP echo URL_ROOT ?>/users/register" method="post">
|
||||
<div class="form-group">
|
||||
<label for="username">Username: <sup class="is-invalid">*</sup></label>
|
||||
<input type="text" name="username" id="" class="form-control form-control-lg <?PHP echo (!empty($data['usernameErr'])) ? 'is-invalid' : '' ?>" value="<?PHP echo $data['username']?>" />
|
||||
<span class="invalid-feedback"><?PHP echo $data['usernameErr'] ?></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="email">Email: <sup class="is-invalid">*</sup></label>
|
||||
<input type="text" name="email" id="" class="form-control form-control-lg <?PHP echo (!empty($data['emailErr'])) ? 'is-invalid' : '' ?>" value="<?PHP echo $data['email']?>" />
|
||||
<span class="invalid-feedback"><?PHP echo $data['emailErr'] ?></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="password">Password: <sup class="is-invalid">*</sup></label>
|
||||
<input type="password" name="password" id="" class="form-control form-control-lg <?PHP echo (!empty($data['passErr'])) ? 'is-invalid' : '' ?>" value="<?PHP echo $data['password']?>" />
|
||||
<span class="invalid-feedback"><?PHP echo $data['passErr'] ?></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="again">Confirm: <sup class="is-invalid">*</sup></label>
|
||||
<input type="password" name="again" id="" class="form-control form-control-lg <?PHP echo (!empty($data['againErr'])) ? 'is-invalid' : '' ?>" value="<?PHP echo $data['again']?>" />
|
||||
<span class="invalid-feedback"><?PHP echo $data['againErr'] ?></span>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<input type="submit" value="Register" class="btn btn-success btn-block" />
|
||||
</div>
|
||||
<div class="col">
|
||||
<a href="<?PHP echo URL_ROOT ?>/users/login" class="btn btn-light btn-block">Already Registered? Login</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?PHP require APP_ROOT.'/views/inc/footer.php' ?>
|
||||
@@ -0,0 +1,8 @@
|
||||
<IfModule mod_rewrite.c>
|
||||
Options -Multiviews
|
||||
RewriteEngine On
|
||||
RewriteBase /
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]
|
||||
</IfModule>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
require_once '../app/bootstrap.php';
|
||||
|
||||
// Init Core Library
|
||||
$init = new Core;
|
||||
@@ -0,0 +1,78 @@
|
||||
# RouteEase MVC
|
||||
|
||||
## Description
|
||||
|
||||
Welcome to RouteEaseMVC, a web application built with PHP that provides
|
||||
a versatile platform for creating, managing, and sharing posts.
|
||||
This project follows the MVC (Model-View-Controller) architecture,
|
||||
ensuring a clean and organized codebase.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [RouteEase MVC](#routeease-mvc)
|
||||
- [Description](#description)
|
||||
- [Table of Contents](#table-of-contents)
|
||||
- [Installation](#installation)
|
||||
- [Usage](#usage)
|
||||
- [File Structure](#file-structure)
|
||||
- [Code Documentation](#code-documentation)
|
||||
- [Contributing](#contributing)
|
||||
- [TODO: Lists](#todo-lists)
|
||||
- [License](#license)
|
||||
|
||||
## Installation
|
||||
|
||||
1. Clone the repository: `git clone https://github.com/bckelley/routeeasemvc.git`
|
||||
2. Navigate to the project directory: `cd RouteEaseMVC`
|
||||
3. Set up the configuration file: `config/config.php` with required values.
|
||||
4. Ensure the following PHP and MySQL and Apache are installed.
|
||||
a. PHP version 8.1
|
||||
b. MySQL version 8.0
|
||||
c. Apache version 2.4
|
||||
5. Visit the project URL in your browser.
|
||||
|
||||
## Usage
|
||||
|
||||
1. Setup Configuration
|
||||
a. Open the `config/config.php` file and configure settings such
|
||||
as database connection details and other constants.
|
||||
2. Setup Database
|
||||
a. Create a MySQL database based on the configured details in `config/config.php`.
|
||||
b. Import the provided SQL file to set up the necessary tables and data.
|
||||
|
||||
## File Structure
|
||||
|
||||
- `config/`: Contains configuration files.
|
||||
- `helpers/`: Includes helper functions for URL and sessions.
|
||||
- `libraries/`: Core libraries with autoloading.
|
||||
- `app/`: Application files including controllers, models, and views.
|
||||
- `public/`: Publicly accessible files (CSS, JS, images).
|
||||
- `README.md`: Project documentation.
|
||||
- `LICENSE`: Project License.
|
||||
|
||||
## Code Documentation
|
||||
|
||||
- `Controller.php`: Base controller class.
|
||||
- `Core.php`: Core class for URL handling and loading controllers.
|
||||
- `Database.php`: PDO Database class for database operations.
|
||||
- `Post.php`: Class handling post-related database operations.
|
||||
- `User.php`: Class handling user-related database operations.
|
||||
- ...
|
||||
|
||||
## Contributing
|
||||
|
||||
If you'd like to contribute to the project, please follow the standard procedures:
|
||||
|
||||
1. Fork the repository.
|
||||
2. Create a new branch: `git checkout -b feature/new-feature`
|
||||
3. Make your changes and commit them: `git commit -m '[Your feature commit message]'`
|
||||
4. Push to the branch: `git push origin feature/new-feature`
|
||||
5. Create a pull request.
|
||||
|
||||
## TODO: Lists
|
||||
|
||||
[TODO](.todo)
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under a derivative of the [CC-BY-NC-SA License](https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode.txt) - see the [LICENSE](LICENSE) file for details.
|
||||
Reference in New Issue
Block a user