# **Chapter 4: Page Events - Handling Browser Requests** > **File Extension Reference:** > - Gate Files: `*.gate.php` (e.g., `Index.gate.php`) > - Front Files: `*.front` (e.g., `index_main.front`) > - Master Files: `*.mast.php` (e.g., `default/master.mast.php`) > - Front Places: `*.place.front` or `*.place.php` --- ## **4.1 Understanding Page Events** Page Events are the methods in your Gate class that handle actual browser requests. Unlike lifecycle events which fire automatically, Page Events are triggered by URLs. The URL pattern is: ``` gate-event-parameter.html ``` Examples: - `index.html` → Gate: index, Event: new - `product.html` → Gate: product, Event: new - `product-view-5.html` → Gate: product, Event: view, Parameter: 5 - `user-edit-10.html` → Gate: user, Event: edit, Parameter: 10 ## **4.2 Built-in Page Events** SartajPhp provides several built-in Page Events for common scenarios: ### **page_new() - Default Page Load** Triggered when browser simply loads a page (GET request). ```php // URL: index.html public function page_new() { // Display the main page $this->setFrontFile($this->frtMain); } ``` ### **page_submit() - Form Submission** Triggered when form is submitted (POST request). This is the main handler for form processing. ```php // URL: index.html (when form with action POST is submitted) public function page_submit() { // Get submitted values $name = $this->Client->post("txtName"); $email = $this->Client->post("txtEmail"); // Get submitted Component values $password = $this->frtMain->getComponent("txtpassword")->getValue(); // Process the data // check any validation,sql or any other error set with setErr if (!getCheckErr()) { echo "Form submitted successfully!"; } } ``` ### **page_insert() - Insert New Record** Auto-triggered AFTER `page_submit()` when no record ID exists (new record). ```php public function page_submit() { // Check if validation passed if (!getCheckErr()) { // If no record ID = new record // page_insert() will be called automatically } } public function page_insert() { // Insert new record into database $data = [ "name" => $this->Client->post("txtName"), "email" => $this->Client->post("txtEmail") ]; $this->dbEngine->runSQL("users", $data); echo "Record inserted!"; } ``` ### **page_update() - Update Existing Record** Auto-triggered AFTER `page_submit()` when record ID exists (update record). ```php public function page_submit() { // Check if validation passed if (!getCheckErr()) { // If has record ID = update // page_update() will be called automatically } } public function page_update() { $recordId = $this->frtMain->form->getRecID(); // Update existing record $data = [ "name" => $this->Client->post("txtName"), "email" => $this->Client->post("txtEmail") ]; $sql = $this->dbEngine->updateSQL("users", $data, "WHERE id='$recordId'"); $this->dbEngine->executeQueryQuick($sql); echo "Record updated!"; } ``` ### **page_view() - View Single Record** Triggered when viewing a specific record. ```php // URL: user-view-5.html public function page_view() { // $this->page->evtp contains "5" $userId = (int)$this->page->evtp; // Fetch user from database $user = $this->getUser($userId); // Display in FrontFile $this->frtMain->getComponent("txtName")->fu_setValue($user["name"]); $this->frtMain->getComponent("txtEmail")->fu_setValue($user["email"]); $this->setFrontFile($this->frtMain); } ``` ### **page_delete() - Delete Record** Triggered when deleting a record. ```php // URL: user-delete-5.html public function page_delete() { $userId = (int)$this->page->evtp; // Delete from database $this->dbEngine->executeQuery("DELETE FROM users WHERE id = $userId"); // Redirect to list $this->page->forward(getGateURL("user")); } ``` ## **4.3 Custom Page Events** Create your own events using the `page_event_*` naming pattern: ### **Basic Custom Event** ```php // URL: product-search-laptop.html public function page_event_search($evtp) { // $evtp = "laptop" $results = $this->searchProducts($evtp); $this->frtMain->getComponent("divResults")->setInnerHTML($results); $this->setFrontFile($this->frtMain); } ``` ### **Multiple Parameter Custom Event** ```php // URL: shop-filter-category-electronics-price-100-500.html public function page_event_filter($evtp) { // $evtp = "category-electronics-price-100-500" // Parse the parameter $parts = explode('-', $evtp); // $parts = ["category", "electronics", "price", "100", "500"] $category = $parts[1]; // "electronics" $minPrice = $parts[3]; // "100" $maxPrice = $parts[4]; // "500" $products = $this->filterProducts($category, $minPrice, $maxPrice); $this->frtMain->getComponent("divProducts")->setInnerHTML($products); $this->setFrontFile($this->frtMain); } ``` ### **AJAX Custom Event** ```php // Called via AJAX: getAJAX('product', 'checkstock', '123') public function page_event_checkstock($evtp) { // $evtp = "123" - product ID $stock = $this->getProductStock($evtp); // Return JSON response $this->JSServer->addJSONReturnBlock([ "product_id" => $evtp, "in_stock" => $stock > 0, "quantity" => $stock ]); } ``` ## **4.4 Getting Request Data** In your Page Events, access request data using `$this->Client`: ### **GET Parameters** ```php public function page_new() { // From URL: product.html?sort=price&order=asc $sort = $this->Client->request("sort"); // "price" $order = $this->Client->request("order"); // "asc" $products = $this->getProducts($sort, $order); } ``` ### **POST Parameters (Form Data)** ```php public function page_submit() { // From form submission $name = $this->Client->post("txtName"); // text field $email = $this->Client->post("txtEmail"); // text field $country = $this->Client->post("sltCountry"); // dropdown $agree = $this->Client->post("chkAgree"); // checkbox } ``` ### **All Request Types** ```php public function page_new() { // Get any parameter (GET or POST) $value = $this->Client->request("param"); // Get Raw POST data without security, same as $_POST["json1"] $rawData = $this->Client->post("json1", true); // Check if parameter exists if ($this->Client->isRequest("search")) { // do search } } ``` ## **4.5 Sending Responses** ### **HTML Response (Most Common)** ```php public function page_new() { // Set FrontFile to render $this->setFrontFile($this->frtMain); } ``` ### **JSON/AJAX Response** ```php public function page_event_checkstock($evtp) { // Send JSON data $this->JSServer->addJSONReturnBlock([ "success" => true, "stock" => 50 ]); // Or update HTML element $this->JSServer->addJSONHTMLBlock("divStatus", "In Stock!"); // Or execute JavaScript $this->JSServer->addJSONJSBlock("$('#btnBuy').prop('disabled', false);"); } ``` ### **Redirect Response** ```php public function page_submit() { // After processing, redirect to another page $this->page->forward(getGateURL("product")); // Or redirect with event $this->page->forward(getEventURL("view", $newId)); } ``` ## **4.6 Complete Example - Blog Application** Here's a complete Blog Gate showing various Page Events: ```php <?php // apps/Blog.gate.php use Sphp\tools\BasicGate; class Blog extends BasicGate { private $frtList; private $frtPost; private $frtEdit; public function onstart() { // Allow guests to view, require login to create/edit $this->getAuthenticate("GUEST,MEMBER,ADMIN"); // Create FrontFiles $this->frtList = new \Sphp\tools\FrontFile($this->mypath . "/fronts/blog_list.front"); $this->frtPost = new \Sphp\tools\FrontFile($this->mypath . "/fronts/blog_post.front"); $this->frtEdit = new \Sphp\tools\FrontFile($this->mypath . "/fronts/blog_edit.front"); } /** * URL: blog.html * Display list of blog posts */ public function page_new() { $this->dbEngine->connect(); $result = $this->dbEngine->executeQuery( "SELECT * FROM posts ORDER BY created_at DESC LIMIT 10" ); $html = ""; while ($post = $this->dbEngine->row_fetch_assoc($result)) { $html .= "<h2>{$post['title']}</h2><p>{$post['excerpt']}</p>"; } $this->dbEngine->disconnect(); $this->frtList->getComponent("divPosts")->setInnerHTML($html); $this->setFrontFile($this->frtList); } /** * URL: blog-view-5.html * View single post */ public function page_view() { $postId = (int)$this->page->evtp; $this->dbEngine->connect(); $result = $this->dbEngine->executeQuery( "SELECT * FROM posts WHERE id = $postId" ); $post = $this->dbEngine->row_fetch_assoc($result); $this->dbEngine->disconnect(); if (!$post) { $this->page->forward(getGateURL("blog")); return; } $this->frtPost->getComponent("txtTitle")->fu_setValue($post['title']); $this->frtPost->getComponent("txtContent")->fu_setValue($post['content']); $this->setFrontFile($this->frtPost); } /** * URL: blog-create.html * Show create form (requires MEMBER or ADMIN) */ public function page_event_create($evtp) { if (!$this->page->isAuthenticate("MEMBER,ADMIN")) { $this->page->forward(getGateURL("login")); return; } $this->setFrontFile($this->frtEdit); } /** * URL: blog.html (POST) * Handle form submission - insert or update */ public function page_submit() { // Validation already done by Components if (getCheckErr()) { // Show form again with errors $this->setFrontFile($this->frtEdit); return; } // Check if insert or update if ($this->frtEdit->form->getRecID() == "") { // Will trigger page_insert() automatically // But we can also handle here $this->insertPost(); } else { $this->updatePost(); } // Redirect to list $this->page->forward(getGateURL("blog")); } /** * URL: blog-delete-5.html * Delete a post */ public function page_event_delete($evtp) { // Require ADMIN $this->getAuthenticate("ADMIN"); $postId = (int)$evtp; $this->dbEngine->executeQuery("DELETE FROM posts WHERE id = $postId"); // Redirect back to list $this->page->forward(getGateURL("blog")); } /** * URL: blog-search-keyword.html * Search posts */ public function page_event_search($evtp) { $keyword = $evtp; // "keyword" $this->dbEngine->connect(); $result = $this->dbEngine->executeQuery( "SELECT * FROM posts WHERE title LIKE '%$keyword%' OR content LIKE '%$keyword%'" ); $html = ""; while ($post = $this->dbEngine->row_fetch_assoc($result)) { $html .= "<h2>{$post['title']}</h2><p>Found in: {$post['excerpt']}</p>"; } $this->dbEngine->disconnect(); $this->frtList->getComponent("divPosts")->setInnerHTML($html); $this->setFrontFile($this->frtList); } // Helper methods private function insertPost() { /* ... */ } private function updatePost() { /* ... */ } } ``` ## **4.7 URL Mapping Reference** | URL | Gate | Event | Parameter | Page Event Called | Parameter Access | |-----|------|-------|-----------|-------------------|------------------| | `index.html` | index | new | - | `page_new()` | `$this->page->evtp` | | `blog.html` | blog | new | - | `page_new()` | `$this->page->evtp` | | `blog.html` (POST) | blog | submit | - | `page_submit()` → `page_insert()`/`page_update()` | `$this->page->evtp` | | `blog-view-5.html` | blog | view | 5 | `page_view()` | `$this->page->evtp` returns "5" | | `blog-delete-5.html` | blog | delete | 5 | `page_event_delete($evtp)` | `$evtp = "5"` | | `blog-search-php.html` | blog | search | php | `page_event_search($evtp)` | `$evtp = "php"` | | `blog-create.html` | blog | create | - | `page_event_create($evtp)` | `$evtp = ""` | **Note:** Built-in page events (`page_new`, `page_view`, `page_delete`, etc.) do NOT receive parameters directly in the method signature. Access parameters via `$this->page->evtp`. Custom events (`page_event_*`) DO receive `$evtp` as a parameter. ## **4.8 Chapter Summary** 1. **Page Events** handle browser requests mapped from URLs 2. **Built-in events**: `page_new()`, `page_submit()`, `page_insert()`, `page_update()`, `page_view()`, `page_delete()` - access parameter via `$this->page->evtp` 3. **Custom events**: Use `page_event_name($evtp)` pattern - parameter passed directly to method 4. **Get data**: `$this->Client->request()`, `$this->Client->post()` 5. **Send responses**: `setFrontFile()`, `JSServer` for AJAX, `page->forward()` for redirect ## **4.9 What's Next?** In the next chapter, you'll learn about FrontFile Events - how to interact with your templates from within your Gate class. --- *Next: Chapter 5 - FrontFile Events: Interacting with Templates*