From 04e2890b5c50d0934f6c9a3c369bb22ff6b60421 Mon Sep 17 00:00:00 2001 From: Andrew Moore Date: Fri, 3 Dec 2021 10:53:46 -0500 Subject: [PATCH 1/2] Update Model.php Non static method 'openDatabaseConnection' should not be called statically. --- application/Core/Model.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/application/Core/Model.php b/application/Core/Model.php index 7602a2f..48517e4 100644 --- a/application/Core/Model.php +++ b/application/Core/Model.php @@ -17,7 +17,7 @@ class Model function __construct() { try { - self::openDatabaseConnection(); + $this->openDatabaseConnection(); } catch (\PDOException $e) { exit('Database connection could not be established.'); } @@ -34,6 +34,13 @@ private function openDatabaseConnection() // @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); From a6995f324a108440efcc95b4a27b1a20794b3acb Mon Sep 17 00:00:00 2001 From: Andrew Moore Date: Fri, 3 Dec 2021 18:24:23 -0500 Subject: [PATCH 2/2] Added query string support Updated the splitUrl function to check requests for query string then parse and create an object from that string. The application constructor will then pass it as a parameter to a constructor function in the Controller Class which populates a private $query_string variable. Note: This includes my fix for the non-static openDatabaseconnection function. --- application/Controller/SongsController.php | 35 ++++++++++++++++++++++ application/Core/Application.php | 28 ++++++++++++++++- application/Core/CoreFunctions.php | 16 ++++++++++ application/view/songs/index.php | 10 +++++++ public/js/application.js | 25 ++++++++++++++++ 5 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 application/Core/CoreFunctions.php diff --git a/application/Controller/SongsController.php b/application/Controller/SongsController.php index f572577..7a34ebf 100644 --- a/application/Controller/SongsController.php +++ b/application/Controller/SongsController.php @@ -18,6 +18,23 @@ class SongsController { + + /** @var object Query String (Key: Value pairs) + * Example: /Controller/action/?artist=Singer who Sings&track=Song of Awesomeness&link=http://example.com + */ + private $query_string = null; + + /** + * Class Constructor + * Accepts a $query_string object as a parameter or if none + * defaults it to null. Then assigns the object to the private + * $query_string variable. + */ + function __construct($query_string = null) + { + $this->query_string = $query_string; + } + /** * PAGE: index * This method handles what happens when you move to http://yourproject/songs/index @@ -58,6 +75,24 @@ public function addSong() header('location: ' . URL . 'songs/index'); } + /** + * ACTION: addSongFromQueryString + * This method handles what happens when you move to http://yourproject/songs/addsongFromQueryString + * IMPORTANT: This is not a normal page, it's an ACTION. This is where the "add a song (Using Ajax with Query String)" form on songs/index + * directs the ajax request. This method handles all the POST data from the query string + * This is an example of how to handle a POST request via JavaScript using Query Strings. + */ + public function addSongFromQueryString() + { + // if we have POST data to create a new song entry + if (!empty((array)$this->query_string)) { + // Instance new Model (Song) + $Song = new Song(); + // do addSong() in model/model.php + $Song->addSong($this->query_string->artist, $this->query_string->track, $this->query_string->link); + } + } + /** * ACTION: deleteSong * This method handles what happens when you move to http://yourproject/songs/deletesong diff --git a/application/Core/Application.php b/application/Core/Application.php index f6976ed..0f99433 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 */ @@ -13,6 +15,11 @@ class Application /** @var array URL parameters */ private $url_params = array(); + /** @var object Query String (Key: Value pairs) + * Example: \Controller\action\?artist=Singer&track=Song&link=http://example.com + */ + private $query_string = null; + /** * "Start" the application: * Analyze the URL elements and calls the according controller/method or the fallback @@ -34,7 +41,10 @@ public function __construct() // if so, then load this file and create this controller // like \Mini\Controller\CarController $controller = "\\Mini\\Controller\\" . ucfirst($this->url_controller) . 'Controller'; - $this->url_controller = new $controller(); + + // Construct the requested controller and pass in the $query_string variable as a parameter + // to the class constructor. + $this->url_controller = new $controller($this->query_string); // check for method: does such a method exist in the controller ? if (method_exists($this->url_controller, $this->url_action)) { @@ -84,6 +94,22 @@ private function splitUrl() // Rebase array keys and store the URL params $this->url_params = array_values($url); + if (isset($_SERVER['QUERY_STRING'])) { + // Parse the query string to retreive an array containing + // the URL and query string and assign it to a variable. + parse_str($_SERVER['QUERY_STRING'], $data); + + // Remove the URL index from the array. + unset($data['url']); + + // If the array is empty, no query string is present. + // Otherwise convert the array to an object and assign + // it to the $query_string variable. + if (!empty($data)) { + $this->query_string = (object) $data; + } + } + // for debugging. uncomment this if you have problems with the URL //echo 'Controller: ' . $this->url_controller . '
'; //echo 'Action: ' . $this->url_action . '
'; 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/view/songs/index.php b/application/view/songs/index.php index cbedeb0..9948444 100644 --- a/application/view/songs/index.php +++ b/application/view/songs/index.php @@ -13,6 +13,16 @@ +

Add a song (Using Ajax with Query String)

+
+ + + + + + + +
diff --git a/public/js/application.js b/public/js/application.js index 35c2882..4361055 100644 --- a/public/js/application.js +++ b/public/js/application.js @@ -36,4 +36,29 @@ $(function() { }); } + + // if #submit_add_song_button exists + if ($('#submit_add_song_button').length !== 0) { + + $('#submit_add_song_button').on('click', () => { + let artist = document.getElementById('artist') + let track = document.getElementById('track') + let link = document.getElementById('link') + + // send an ajax-request to this URL: current-server.com/songs/ajaxGetStats + // "url" is defined in views/_templates/footer.php + $.ajax({ + url: `${url}/songs/addSongFromQueryString/?artist=${artist.value}&track=${track.value}&link=${link.value}`, + success: () => { + console.log('Ajax request succeeded.') + + // Reload the page on success + window.location.reload() + }, + fail: () => { + console.log('Some error handling.') + } + }) + }); + } });