> For the complete documentation index, see [llms.txt](https://learnphp.gitbook.io/learnphp/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://learnphp.gitbook.io/learnphp/nathan-mvc-framework-ok.md).

# Nathan MVC Framework (ok)

https\://github.com/dloewith/Nathan-MVC

{% 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>
```

![](https://3988971916-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LXUV09EJOZ8BKB8YL5I%2Fuploads%2Fm7ZmwINKQk5rOztSgqi3%2FScreenshot_1.png?alt=media\&token=6f1513ed-9689-4831-86bb-8a622c1eb223)

## **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>
```

![](https://3988971916-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LXUV09EJOZ8BKB8YL5I%2Fuploads%2F56iqu0F85RzK41OYGa5E%2FScreenshot_2.png?alt=media\&token=bc4ed012-ab13-4dc3-abb3-e4ae1a85fb40)
