I'm creating a MVC structured content management system as both a means to learn better OOP and redesign my tacky website to me more modular and simplistic. My aim is to approach everything with regard for minimalism so I want all my code to be precise and to the point. As this is my first go at both MVC and true OOP php I'd like to get some feedback on my progress thus far. Below is a sample of my websites blog code, this is been my main area of focus and is where I try out new code before implementing them elsewhere. If other snippets of code are required I'll append them at the bottom.
Controller - controllers/Blog.php
<?php
class Blogs extends AdminController {
function __construct(Request $request, $config) {
parent::__construct($request, $config);
}
function show() {
$blog = new Blog();
$post['title'] = "TITLE";
$post['id'] = "IDENT";
$blog->newPost(1, $post);
$content['blogs'] = $blog->get_where();
$al = new Post();
$content['posts'] = $al->get_where();
$this->view->load('content', 'blogs/list', $content);
$this->view->render("theme_admin");
}
function edit() {
$id = $this->request->segment(2);
$al = new Post($id);
$content['post'] = $al;
$this->view->load('content', 'blogs/edit', $content);
$this->view->render("theme_admin");
}
function save() {
$al = new Post();
$_POST['title'] = htmlspecialchars($_POST['title'], ENT_QUOTES);
$_POST['content'] = htmlspecialchars($_POST['content'], ENT_QUOTES);
$_POST['likes'] = htmlspecialchars($_POST['likes'], ENT_QUOTES);
$al->save($_POST);
// redirect('admin/blogs');
}
function delete() {
$id = $this->request->segment(2);
$al = new Post($id);
$al->delete();
last_page();
}
}
View - views/blog/list.php
<div class="box">
<div class="box-header">
<h1>Typography</h1>
</div>
<div class="box-content">
<table>
<thead>
<tr>
<th>ID</th>
<th>Blog</th>
<th>Title</th>
<th>Content</th>
<th>Likes</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<? if ($posts): ?>
<? foreach ($posts as $post) : ?>
<tr>
<td><?= $post->id ?></td>
<td><?= $post->blogID ?></td>
<td><?= $post->title ?></td>
<td><?= $post->content ?></td>
<td><?= $post->likes ?></td>
<td>
<a href="<?= url('admin/blogs/edit/' . $post->id) ?>" class="button plain">Edit</a>
<a href="<?= url('admin/blogs/delete/' . $post->id) ?>" class="button plain">Delete</a>
<a href="<?= url('blogs/' . $post->id) ?>" class="button plain">View</a>
</td>
</tr>
<? endforeach; ?>
<? endif; ?>
</tbody>
</table>
<div class="action_bar">
<a href="<?= url('admin/blogs/edit') ?>" class="button blue">Add New Post</a>
</div>
</div>
<? if ($blogs): ?>
<? foreach ($blogs as $blog) : ?>
<tr>
<td><?= $blog->id ?></td>
<td><?= $blog->title ?></td>
</tr>
<? endforeach; ?>
<? endif; ?>
<form enctype="multipart/form-data" action="<?= url('admin/blogs/upload') ?>" method="post">
<input type="hidden" name="MAX_FILE_SIZE" value="2000000" />
<p>File to upload <input name="userfile" type="file" />
<input type="submit" name="send" value="Upload File" /></p>
</form>
Models models/Blog.php
<?php
class Blog extends Model {
}
Right now there's no actual unique code for the blog, everythings simply loaded through the main model class below. This is something that I've probably messed up so I'd love to get feedback here
Models lib/Model.php
<?php
require LIB . 'Database.php';
class Model {
public $model;
public $table;
public $fields;
public $db;
function __construct($id = null) {
$this->db = new Database();
$this->model = get_class($this);
$this->table = strtolower($this->model) . 's';
$this->init_fields($id);
}
function init_fields($id = null) {
$this->fields = $this->fields();
if (!empty($id)) {
$this->get($id);
} else {
foreach ($this->fields as $field) {
$this->{$field} = null;
}
}
}
function fields() {
$res = $this->db->query('SHOW COLUMNS FROM ' . $this->table);
$fields = array();
while ($row = $res->fetch()) {
// var_dump($row);
$fields[] = $row->Field;
}
return $fields;
}
function get($id) {
$res = $this->db->query('SELECT * FROM ' . $this->table . ' WHERE id=?', array($id));
$row = $res->fetch();
if ($row) {
foreach ($row as $key => $val) {
$this->{$key} = $val;
}
}
return $this;
}
function exists() {
if (!empty($this->id)) {
$res = $this->db->query('SELECT * FROM ' . $this->table . ' WHERE id=?', array($this->id));
return $res->num_rows() ? true : false;
}
return false;
}
function get_where() {
$res = $this->db->query('SELECT * FROM ' . $this->table);
$arr = array();
while ($row = $res->fetch()) {
$arr[] = $row;
}
return $arr;
}
function save($arr = null) {
//append values from assoc array
if ($arr) {
foreach ($this->fields as $key) {
if (array_key_exists($key, $arr)) {
$this->{$key} = $arr[$key];
}
}
}
$update_arr = array();
$update_str = array();
foreach ($this->fields as $key) {
if (!empty($this->{$key})) {
$update_str[] = "$key = ?";
$update_arr[] = $this->{$key};
}
}
$sql = ' SET ' . implode(',', $update_str);
if ($this->exists()) {
$sql = "UPDATE " . $this->table . $sql . " WHERE id=?";
$update_arr[] = $this->id;
} else {
$sql = "INSERT INTO " . $this->table . $sql;
}
$res = $this->db->query($sql, $update_arr);
if (empty($this->id)) {
$this->id = $res->insert_id();
}
return $res->affected_rows();
}
function delete() {
if( isset($this->id) ) {
$res = $this->db->query('DELETE FROM ' . $this->table . ' WHERE id=?', $this->id);
return $res->affected_rows();
}
return false;
}
}