# Nathan MVC Framework (ok)

{% file src="/files/ig3NHZAsKgFD96lcN9Rf" %}

**👌 Nghiên cứu một chút về cách hoạt động**

C:\xampp\htdocs\wpclidemo.htaccess

```
Options +FollowSymLinks
RewriteEngine on
RewriteRule ^([a-zA-Z]*)/?([a-zA-Z]*)?/?([a-zA-Z0-9]*)?/?$ index.php?controller=$1&action=$2&id=$3 [NC,L]
```

## **Trang Home**

C:\xampp\htdocs\wpclidemo\classes\basecontroller.php

```
<?php
/*
 * Project: Nathan MVC
 * File: /classes/basecontroller.php
 * Purpose: abstract class from which controllers extend
 * Author: Nathan Davison
 */
abstract class BaseController {
  protected $urlValues;
  protected $action;
  protected $model;
  protected $view;
  public function __construct($action, $urlValues) {
    $this->action    = $action;
    $this->urlValues = $urlValues;
    //establish the view object
    $this->view = new View(get_class($this), $action);
  }
  //executes the requested method
  public function executeAction() {
    return $this->{$this->action}();
  }
}
?>
```

C:\xampp\htdocs\wpclidemo\controllers\home.php

```
<?php
/*
 * Project: Nathan MVC
 * File: /controllers/home.php
 * Purpose: controller for the home of the app.
 * Author: Nathan Davison
 */
class HomeController extends BaseController {
  //add to the parent constructor
  public function __construct($action, $urlValues) {
    parent::__construct($action, $urlValues);
    //create the model object
    require "models/home.php";
    $this->model = new HomeModel();
  }
  //default method
  protected function index() {
    $this->view->output($this->model->index());
  }
}
?>
```

C:\xampp\htdocs\wpclidemo\classes\view\.php

```
<?php
/*
 * Project: Nathan MVC
 * File: /classes/view.php
 * Purpose: class for the view object.
 * Author: Nathan Davison
 */
class View {
  protected $viewFile;
  //establish view location on object creation
  public function __construct($controllerClass, $action) {
    $controllerName = str_replace("Controller", "", $controllerClass);
    $this->viewFile = "views/" . $controllerName . "/" . $action . ".php";
  }
  //output the view
  public function output($viewModel, $template = "maintemplate") {
    $templateFile = "views/" . $template . ".php";
    if (file_exists($this->viewFile)) {
      if ($template) {
        //include the full template
        if (file_exists($templateFile)) {
          require $templateFile;
        } else {
          require "views/error/badtemplate.php";
        }
      } else {
        //we're not using a template view so just output the method's view directly
        require $this->viewFile;
      }
    } else {
      require "views/error/badview.php";
    }
  }
}
?>
```

C:\xampp\htdocs\wpclidemo\classes\viewmodel.php

```
<?php
/*
 * Project: Nathan MVC
 * File: /classes/viewmodel.php
 * Purpose: class for the optional data object returned by model methods which the controller sends to the view.
 * Author: Nathan Davison
 */
class ViewModel {
  //dynamically adds a property or method to the ViewModel instance
  public function set($name, $val) {
    $this->$name = $val;
  }
  //returns the requested property value
  public function get($name) {
    if (isset($this->{$name})) {
      return $this->{$name};
    } else {
      return null;
    }
  }
}
?>
```

C:\xampp\htdocs\wpclidemo\classes\viewmodel.php

```
<?php
/*
 * Project: Nathan MVC
 * File: /classes/viewmodel.php
 * Purpose: class for the optional data object returned by model methods which the controller sends to the view.
 * Author: Nathan Davison
 */
class ViewModel {
  //dynamically adds a property or method to the ViewModel instance
  public function set($name, $val) {
    $this->$name = $val;
  }
  //returns the requested property value
  public function get($name) {
    if (isset($this->{$name})) {
      return $this->{$name};
    } else {
      return null;
    }
  }
}
?>
```

C:\xampp\htdocs\wpclidemo\classes\basemodel.php

```
<?php
/*
 * Project: Nathan MVC
 * File: /classes/basemodel.php
 * Purpose: abstract class from which models extend.
 * Author: Nathan Davison
 */
class BaseModel {
  protected $viewModel;
  //create the base and utility objects available to all models on model creation
  public function __construct() {
    $this->viewModel = new ViewModel();
    $this->commonViewData();
  }
  //establish viewModel data that is required for all views in this method (i.e. the main template)
  protected function commonViewData() {
    //e.g. $this->viewModel->set("mainMenu",array("Home" => "/home", "Help" => "/help"));
  }
}
?>
```

C:\xampp\htdocs\wpclidemo\views\Home\index.php

```
<h1>Page Home</h1>
<p>Description</p>
```

![](/files/fLLofkFJDhCSX5bbblM0)

## **Trang Test**

C:\xampp\htdocs\wpclidemo\controllers\test.php

```
<?php
/*
 * Project: Nathan MVC
 * File: /controllers/home.php
 * Purpose: controller for the home of the app.
 * Author: Nathan Davison
 */
class TestController extends BaseController {
  //add to the parent constructor
  public function __construct($action, $urlValues) {
    parent::__construct($action, $urlValues);
    //create the model object
    require "models/test.php";
    $this->model = new TestModel();
  }
  //default method
  protected function index() {
    $this->view->output($this->model->abc());
  }
}
?>
```

C:\xampp\htdocs\wpclidemo\models\test.php

```
<?php
/*
 * Project: Nathan MVC
 * File: /models/home.php
 * Purpose: model for the home controller.
 * Author: Nathan Davison
 */
class TestModel extends BaseModel {
  //data passed to the home index view
  public function index() {
    $this->viewModel->set("pageTitle", "TestModel MVC");
    return $this->viewModel;
  }
  public function abc() {
    $this->viewModel->set("pageTitle", "TestModel abc");
    return $this->viewModel;
  }
}
?>
```

C:\xampp\htdocs\wpclidemo\views\Test\index.php

```
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  Lorem, ipsum dolor sit amet.
</body>
</html>
```

![](/files/4RuSjgQ3p97cisUkVfeU)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://learnphp.gitbook.io/learnphp/nathan-mvc-framework-ok.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
