I'm building a survey data collection. Currently, I am done with building the prototype. It serves as wizard like control to navigate through various pages in a survey project.
app/index.php
$f3 = require_once __DIR__ . '/lib/f3/base.php';
require_once __DIR__ . '/controllers/PlayerController.php';
function glob_call($f3,$params){
$player_controller = new PlayerController($f3,$params);
$player_controller->displayForm();
}
$f3->route('GET|POST /project_id/@project_id',
'glob_call'
);
$f3->run();
app/controllers/PlayerController.php
require_once __DIR__ . '/../lib/Player.php';
class PlayerController{
public $player;
private $f3;
function __construct($f3,$params){
$this->f3 = $f3;
$project_id = $params["project_id"];
$resp_id = $f3->get("REQUEST.resp_id");
$player = new Player($project_id,$resp_id);
$action = $resp_id = $f3->get("POST.navigation");
if($action==="next"){
$player->nextPage();
}elseif ($action==="prev") {
$player->prevPage();
}
$this->player = $player;
}
public function displayForm(){
$this->f3->set('player',$this->player);
echo \Template::instance()->render('/templates/template.html');
}
}
app/lib/Page.php
require_once __DIR__ . '/rb_dbo.php';
class Page{
function __construct($page_id,$project_id){
$this->id = $page_id;
$this->project_id = $project_id;
if($this->id===NULL){
$this->id = PageDBO::get_first($project_id);
}
}
function getNextPage(){
$this->id = PageDBO::get_next($this->id,$this->project_id);
return $this->id;
}
function getPrevPage(){
$this->id = PageDBO::get_prev($this->id,$this->project_id);
return $this->id;
}
}
class PageDBO{
public static function get_first($project_id){
$first_id = R::getCell("
SELECT id from page
where project_id = ?
order by order_id asc
limit 1
",[$project_id]);
return $first_id;
}
public static function get_last($project_id){
$last_id = R::getCell("
SELECT id from page
where project_id = ?
order by order_id desc
limit 1
",[$project_id]);
return $last_id;
}
public static function get_next($id,$project_id){
$next_id = R::getCell("
select id from page where order_id >
(select order_id from page where id = ? and project_id = ? )
and project_id = ?
order by order_id asc
limit 1
",[$id,$project_id,$project_id]);
if($next_id===NULL){
return PageDBO::get_last($project_id);
}
return $next_id;
}
public static function get_prev($id,$project_id){
$prev_id = R::getCell("
select id from page where order_id <
(select order_id from page where id = ? and project_id = ? )
and project_id = ?
order by order_id desc
limit 1
",[$id,$project_id,$project_id]);
if($prev_id===NULL){
return PageDBO::get_first($project_id);
}
return $prev_id;
}
}
app/lib/Player.php
require_once __DIR__ . '/Project.php';
require_once __DIR__ . '/Page.php';
require_once __DIR__ . '/Respondent.php';
class Player{
public $project;
public $repsondent;
public $page;
function __construct($project_id,$repsondent_id){
$this->project = new Project($project_id);
$this->repsondent = new Respondent($repsondent_id,$this->project->id);
$this->page = new Page($this->repsondent->last_page_id,$this->project->id);
$this->repsondent->last_page_id = $this->page->id;
}
function nextPage(){
$this->repsondent->update_last_page($this->page->getNextPage());
}
function prevPage(){
$this->repsondent->update_last_page($this->page->getPrevPage());
}
}
app/lib/Project.php
require_once __DIR__ . '/rb_dbo.php';
class Project{
public $id;
public $title;
protected function bind(){
$temp_obj = ProjectDBO::find($this->id);
$this->id = $temp_obj->id;
}
function __construct($project_id){
$this->id = $project_id;
$this->bind();
$this->title = "The First one";
}
}
class ProjectDBO{
public static function find($id){
$db_obj = R::findOne('project', ' id = ?', [ $id ] );
if($db_obj===NULL){
throw new Exception($id . ": Not Found");
}
return $db_obj;
}
}
app/lib/Respondent.php
require_once __DIR__ . '/rb_dbo.php';
class Respondent{
public $id;
public $project_id;
public $last_page_id;
protected function bind(){
$resp_temp_obj = RespondentDBO::find($this->id);
$this->last_page_id = $resp_temp_obj->last_page_id;
}
function update_last_page($nav_num){
$this->last_page_id = RespondentDBO::update_last_page($this->id,$nav_num);
}
function __construct($repsondent_id = NULL,$project_id){
$this->id = $repsondent_id;
$this->project_id = $project_id;
if(is_null( $this->id) || empty($this->id)){
$this->id = RespondentDBO::create_respondent($this->project_id);
}
$this->bind();
}
}
class RespondentDBO{
public static function create_respondent($project_id){
$db_obj = R::dispense( 'respondent' );
$db_obj->project_id = $project_id;
$id = R::store( $db_obj );
return $id;
}
public static function find($id){
$db_obj = R::findOne('respondent', ' id = ?', [ $id ] );
if($db_obj===NULL){
throw new Exception($id . ": Not Found");
}
return $db_obj;
}
public static function update_last_page($id,$nav_num){
$db_obj = R::findOne('respondent', ' id = ?', [ $id ] );
$db_obj->last_page_id = $nav_num;
R::store( $db_obj );
return $nav_num;
}
}
Here is the initial DB schema diagram:

I want to make sure that the highly decoupled approach taken is fine for the Player class in "Data Collection/lib/Player.php". Furthermore, if there are ways to better the code and room for improvements.