diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..208a599 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +vendor/* \ No newline at end of file diff --git a/README.md b/README.md index 5656cc4..3ee8115 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ of the original MINI, made by [JaoNoctus](https://github.com/JaoNoctus). Big tha ## Requirements -- PHP 5.6 or PHP 7.0 +- PHP 5.6 or PHP 7.x (PHP 8.0 should also work fine) - MySQL - mod_rewrite activated (see below for tutorials) - basic knowledge of Composer for sure @@ -39,10 +39,10 @@ Vagrant-file (defines your Vagrant box) and a demo bootstrap.sh which automatica PHPMyAdmin, git and Composer, sets a chosen password in MySQL and PHPMyadmin and even inside the application code, downloads the Composer-dependencies, activates mod_rewrite and edits the Apache settings, downloads the code from GitHub and runs the demo SQL statements (for demo data). This is 100% automatic, you'll end up after +/- 5 minutes with a fully -running installation of MINI3 inside an Ubuntu 14.04 LTS Vagrant box. +running installation of MINI3 inside an Ubuntu 20.04 Vagrant box on PHP 7.4.x. To do so, put `Vagrantfile` and `bootstrap.sh` from `_vagrant` inside a folder (and nothing else). -Do `vagrant box add ubuntu/trusty64` to add Ubuntu 14.04 LTS ("Trusty Thar") 64bit to Vagrant (unless you already have +Do `vagrant box add ubuntu/focal64` to add Ubuntu 20.04 64bit to Vagrant (unless you already have it), then do `vagrant up` to run the box. When installation is finished you can directly use the fully installed demo app on `192.168.33.66`. As this just a quick demo environment the MySQL root password and the PHPMyAdmin root password are set to `12345678`, the project is installed in `/var/www/html/myproject`. You can change this for sure inside @@ -92,7 +92,7 @@ server { location / { index index.php; - try_files /$uri /$uri/ /index.php?url=$uri; + try_files /$uri /$uri/ /index.php?url=$uri&$args; } location ~ \.(php)$ { diff --git a/_vagrant/Vagrantfile b/_vagrant/Vagrantfile index 0737289..42d9b39 100644 --- a/_vagrant/Vagrantfile +++ b/_vagrant/Vagrantfile @@ -7,7 +7,7 @@ VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| # Every Vagrant virtual environment requires a box to build off of. - config.vm.box = "ubuntu/trusty64" + config.vm.box = "ubuntu/focal64" # Create a private network, which allows host-only access to the machine using a specific IP. config.vm.network "private_network", ip: "192.168.33.66" diff --git a/_vagrant/bootstrap.sh b/_vagrant/bootstrap.sh index c50878e..4b02af7 100644 --- a/_vagrant/bootstrap.sh +++ b/_vagrant/bootstrap.sh @@ -10,12 +10,12 @@ sudo apt-get update sudo apt-get -y upgrade sudo apt-get install -y apache2 -sudo apt-get install -y php5 +sudo apt-get install -y php sudo debconf-set-selections <<< "mysql-server mysql-server/root_password password $PASSWORD" sudo debconf-set-selections <<< "mysql-server mysql-server/root_password_again password $PASSWORD" sudo apt-get -y install mysql-server -sudo apt-get install php5-mysql +sudo apt-get install php-mysql sudo debconf-set-selections <<< "phpmyadmin phpmyadmin/dbconfig-install boolean true" sudo debconf-set-selections <<< "phpmyadmin phpmyadmin/app-password-confirm password $PASSWORD" diff --git a/application/Controller/ErrorController.php b/application/Controller/ErrorController.php index f87a7d5..3845a7d 100644 --- a/application/Controller/ErrorController.php +++ b/application/Controller/ErrorController.php @@ -20,8 +20,8 @@ class ErrorController public function index() { // load views - require APP . 'view/_templates/header.php'; - require APP . 'view/error/index.php'; - require APP . 'view/_templates/footer.php'; + view('_templates/header.php'); + view('error/index.php'); + view('_templates/footer.php'); } } diff --git a/application/Controller/HomeController.php b/application/Controller/HomeController.php index 0f3b0af..994e7a7 100644 --- a/application/Controller/HomeController.php +++ b/application/Controller/HomeController.php @@ -20,9 +20,10 @@ class HomeController public function index() { // load views - require APP . 'view/_templates/header.php'; - require APP . 'view/home/index.php'; - require APP . 'view/_templates/footer.php'; + view('_templates/header.php'); + view('home/index.php'); + view('_templates/footer.php'); + } /** @@ -33,9 +34,9 @@ public function index() public function exampleOne() { // load views - require APP . 'view/_templates/header.php'; - require APP . 'view/home/example_one.php'; - require APP . 'view/_templates/footer.php'; + view('_templates/header.php'); + view('home/example_one.php'); + view('_templates/footer.php'); } /** @@ -46,8 +47,8 @@ public function exampleOne() public function exampleTwo() { // load views - require APP . 'view/_templates/header.php'; - require APP . 'view/home/example_two.php'; - require APP . 'view/_templates/footer.php'; + view('_templates/header.php'); + view('home/example_two.php'); + view('_templates/footer.php'); } } diff --git a/application/Controller/SongsController.php b/application/Controller/SongsController.php index f572577..1e10e3d 100644 --- a/application/Controller/SongsController.php +++ b/application/Controller/SongsController.php @@ -30,10 +30,10 @@ public function index() $songs = $Song->getAllSongs(); $amount_of_songs = $Song->getAmountOfSongs(); - // load views. within the views we can echo out $songs and $amount_of_songs easily - require APP . 'view/_templates/header.php'; - require APP . 'view/songs/index.php'; - require APP . 'view/_templates/footer.php'; + // load views. within the views we can echo out $songs and $amount_of_songs easily + view('_templates/header.php'); + view('songs/index.php', ["songs" => $songs]); + view('_templates/footer.php'); } /** @@ -51,11 +51,11 @@ public function addSong() // Instance new Model (Song) $Song = new Song(); // do addSong() in model/model.php - $Song->addSong($_POST["artist"], $_POST["track"], $_POST["link"]); + $Song->addSong($_POST["artist"], $_POST["track"], $_POST["link"]); } // where to go after song has been added - header('location: ' . URL . 'songs/index'); + redirect('songs/index'); } /** @@ -78,10 +78,10 @@ public function deleteSong($song_id) } // where to go after song has been deleted - header('location: ' . URL . 'songs/index'); + redirect('songs/index'); } - /** + /** * ACTION: editSong * This method handles what happens when you move to http://yourproject/songs/editsong * @param int $song_id Id of the to-edit song @@ -95,16 +95,19 @@ public function editSong($song_id) // do getSong() in model/model.php $song = $Song->getSong($song_id); - // in a real application we would also check if this db entry exists and therefore show the result or - // redirect the user to an error page or similar - - // load views. within the views we can echo out $song easily - require APP . 'view/_templates/header.php'; - require APP . 'view/songs/edit.php'; - require APP . 'view/_templates/footer.php'; + // If the song wasn't found, then it would have returned false, and we need to display the error page + if ($song === false) { + $page = new \Mini\Controller\ErrorController(); + $page->index(); + } else { + // load views. within the views we can echo out $song easily + view('_templates/header.php'); + view('songs/edit.php', ["song" => $song]); + view('_templates/footer.php'); + } } else { // redirect user to songs index page (as we don't have a song_id) - header('location: ' . URL . 'songs/index'); + redirect('songs/index'); } } @@ -123,11 +126,11 @@ public function updateSong() // Instance new Model (Song) $Song = new Song(); // do updateSong() from model/model.php - $Song->updateSong($_POST["artist"], $_POST["track"], $_POST["link"], $_POST['song_id']); + $Song->updateSong($_POST["artist"], $_POST["track"], $_POST["link"], $_POST['song_id']); } // where to go after song has been added - header('location: ' . URL . 'songs/index'); + redirect('songs/index'); } /** diff --git a/application/Core/Application.php b/application/Core/Application.php index f6976ed..ed42bff 100644 --- a/application/Core/Application.php +++ b/application/Core/Application.php @@ -2,6 +2,8 @@ /** For more info about namespaces plase @see http://php.net/manual/en/language.namespaces.importing.php */ namespace Mini\Core; +require APP . 'core/CoreFunctions.php'; + class Application { /** @var null The controller */ @@ -37,7 +39,8 @@ public function __construct() $this->url_controller = new $controller(); // check for method: does such a method exist in the controller ? - if (method_exists($this->url_controller, $this->url_action)) { + if (method_exists($this->url_controller, $this->url_action) && + is_callable(array($this->url_controller, $this->url_action))) { if (!empty($this->url_params)) { // Call the method and pass arguments to it @@ -52,11 +55,13 @@ public function __construct() // no action defined: call the default index() method of a selected controller $this->url_controller->index(); } else { - header('location: ' . URL . 'error'); + $page = new \Mini\Controller\ErrorController(); + $page->index(); } } } else { - header('location: ' . URL . 'error'); + $page = new \Mini\Controller\ErrorController(); + $page->index(); } } diff --git a/application/Core/CoreFunctions.php b/application/Core/CoreFunctions.php new file mode 100644 index 0000000..4caccf1 --- /dev/null +++ b/application/Core/CoreFunctions.php @@ -0,0 +1,16 @@ + $v) { + $$k = $v; + } + require APP . "view/{$path}"; +} + + +function redirect($path) { + header('location: ' . URL . $path); +} \ No newline at end of file diff --git a/application/Core/Model.php b/application/Core/Model.php index 7602a2f..7b2ba24 100644 --- a/application/Core/Model.php +++ b/application/Core/Model.php @@ -33,9 +33,16 @@ private function openDatabaseConnection() // For example, fetch mode FETCH_ASSOC would return results like this: $result["user_name] ! // @see http://www.php.net/manual/en/pdostatement.fetch.php $options = array(PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ, PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING); + + // setting the encoding is different when using PostgreSQL + if (DB_TYPE == "pgsql") { + $databaseEncodingenc = " options='--client_encoding=" . DB_CHARSET . "'"; + } else { + $databaseEncodingenc = "; charset=" . DB_CHARSET; + } // generate a database connection, using the PDO connector // @see http://net.tutsplus.com/tutorials/php/why-you-should-be-using-phps-pdo-for-database-access/ - $this->db = new PDO(DB_TYPE . ':host=' . DB_HOST . ';dbname=' . DB_NAME . ';charset=' . DB_CHARSET, DB_USER, DB_PASS, $options); + $this->db = new PDO(DB_TYPE . ':host=' . DB_HOST . ';dbname=' . DB_NAME . $databaseEncodingenc, DB_USER, DB_PASS, $options); } } diff --git a/application/libs/helper.php b/application/Libs/helper.php similarity index 100% rename from application/libs/helper.php rename to application/Libs/helper.php diff --git a/application/Model/Song.php b/application/Model/Song.php index 1750116..7ff4812 100644 --- a/application/Model/Song.php +++ b/application/Model/Song.php @@ -89,7 +89,7 @@ public function getSong($song_id) $query->execute($parameters); // fetch() is the PDO method that get exactly one result - return $query->fetch(); + return ($query->rowcount() ? $query->fetch() : false); } /** diff --git a/application/config/config.php b/application/config/config.php index d756ce3..1cdbbcc 100644 --- a/application/config/config.php +++ b/application/config/config.php @@ -58,4 +58,4 @@ define('DB_NAME', 'mini'); define('DB_USER', 'root'); define('DB_PASS', '12345678'); -define('DB_CHARSET', 'utf8'); +define('DB_CHARSET', 'utf8mb4');