2
\$\begingroup\$

I made my own extra slim flat file CMS with PHP, for a website that needs simple updates. You can have a look at its functional current state here (username is Username, password is Password).

I tried to follow an MVC architecture for the project, and I am stuck with having the Controllers as classes.

Let me describe the project simply.


Models classes include:

  • Projects class, describes a list of all the projects
  • Project class, describes a project and interact with its “database” text file
  • Info class, describes the individual information in each project (title, date, description)

They have methods similar to $Projects->return_list() and $Project->return_title() and $Info->return_uppercased() that I can use in my views.


Views are snippets of HTML/PHP code for each component of the CMS. They include:

The select view displays a list of all projects

<p>
    Select project to edit:
    <select name="Select">
<?php foreach ($projects as $project): ?>
        <option value="<?php echo $project->filename(); ?>"><?php echo $project->title(); ?></option>
<?php endforeach ?>
    </select>
    <button type="submit" id="edit" name="Submit" value="edit_project">Edit</button>
    <button type="submit" name="Submit" value="new_project">New project</button>
</p>

The edit view displays a form to edit the selected project

<p>
    File name: <?php echo $selectedProject->filename(); ?><br>
    Title: <input type="text" name="Title" value="<?php echo $selectedProject->title(); ?>"><br>
    Date: <input type="text" name="Date" value="<?php echo $selectedProject->date(); ?>"><br>
    Length: <input type="text" name="Length" value="<?php echo $selectedProject->length(); ?>"><br>
    Video ID: <input type="text" name="Video" value="<?php echo $selectedProject->video(); ?>"><br>
    Description: <textarea name="Description"><?php echo $selectedProject->description(); ?></textarea>
</p>

and the submit view only displays an “Update” and “Delete” button

<button type="submit" name="Submit" value="delete_project">Delete</button>
<button type="submit" name="Submit" value="update_project">Update</button>

I have only one front Controller file (index.php) which lists all possible user interactions (checks if “Edit”, “Create new project”, “Update” or “Delete” have been clicked) and displays the necessary views.

It also manipulates the Models objects (e. g. calls $Projects->add_new_project() when “Create project” is clicked).

Here is a simplified part of it, the whole commented front controller code is accessible here.

<?php

echo '<form method="post">';

# first arrive on the page: if no project has been selected and no "Submit" button has been clicked
# — only displays the "select a project" snippet
if ( ! $_POST['Select'] && ! $_POST['Submit'] )
{
    require 'views/select.php';
}

# else if "Edit" has been clicked (and a project has been selected)
# — displays the "select a project", "edit the project" and "submit the changes" snippets
# — the "edit the project" snippet gets filled with the info from the selected project
else if ($_POST['Select'] && $_POST['Submit'] == 'edit_project')
{
    $selectedProject = $projects->{$_POST['Select']};
    require 'views/select.php';
    require 'views/edit.php';
    require 'views/submit.php';
}

# else if "Create new project" has been clicked
# — creates a new project
# — displays the "select a project", "edit the project" and "submit the changes" snippets
# — the "edit the project" snippet gets filled with the info from the new created project
else if ($_POST['Submit'] == 'new_project')
{
    $newProject = new Project();
    $newProject->create_blank(); # fills the Project object with blank properties (title, date, etc.)
    $projects->add_project($newProject); # new project is added to Projects object

    $selectedProject = $projects->{$newProject->filename()};
    $selectedProject->update_file($projects_folder); # the new project gets saved as a text file

    require 'views/select.php';
    require 'views/edit.php';
    require 'views/create.php';
}

echo '</form>';

?>

The real extended code links the views and models for the the following tasks:

  • login/logout
  • select a project
  • edit a project
  • create a project
  • delete a project
  • reorder the projects

This front controller code is long, does not separate tasks so clearly and is complex to update/maintain.

I have no clues how to handle everything the front controller file does using classes and objects, with the aim of having both a reusable and more segmented/maintainable code.

Any directions? Other critical reviews and advises would be much appreciated.

\$\endgroup\$
1
\$\begingroup\$

The gap between what you currently have and an MVC-based, object-oriented framework is quite large. I would expect your best learning opportunity would be to work with one or two of the popular PHP frameworks to see how they structure things.

It is really quite hard to give you a meaningful review, as you have just shown some assorted fragments of code, none of which gives clear understanding to what is taking place in your application.

From looking at what you have posted, my guess is your framework has significant problems with regards to security (for example, you seem to be trusting user input without performing any validation) and with regards to truly separating your code along areas of responsibility.

\$\endgroup\$
  • \$\begingroup\$ Thanks for the repsonse! My Info (model) class actually has a $Info->secure() method performing trim(), stripslashes() and htmlspecialchars() on the user input. This MVC structure seems to be quite far out! I really thought of it as a simple separation of data structure, template and something that links between the two of them… am I wrong? Concerning the code I think it would be more confusing to show the whole thing, I tried to reduce it to something clearer. \$\endgroup\$ – Raoulito Mar 17 '17 at 16:13
  • \$\begingroup\$ @Raoulito I would really look into the gist of this comment. Look into Symfony and/or Laravel and note how far of you are from a MVC :) \$\endgroup\$ – Pinoniq Jan 11 '18 at 22:46

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.