Welcome Guest, Not a member yet? Register   Sign In
Moving to MVC and CI
#1

[eluser]Unknown[/eluser]
Hello,

Sorry for the long post, but my explanation is so long because I want my methodology to be understood and receive as much criticism/suggestions as possible.

Maybe my problem has an easy fix, maybe my approach is just wrong or unrational. Any suggestion or criticism is welcome.

I recently decided it's time to try out CI as my first framework, so far I had been coding from scratch. I am trying to recode a blog/gallery project with CI and MVC. However I think I'm stuck with my old ways and I'm having difficulty implementing the MVC pattern.

The basic functionality
A user can create categories and add posts and photos to every category. If the user clicks on a category, the posts of this category are displayed by default, in the category header, there are the title of the category and two links, which let you choose whether to display the blog posts or photos of this category.

The old project had this overall structure:
For every database object, I have a class, the classes are: Category, Post, Photo.
They are all a subclass of another class: DatabaseObject.
DatabaseObject contains the functionality for CRUD for every object and basically every database action goes through this class.
Sample code from the DatabaseObject class:
Code:
public static function findByID($id=0){
  $sql="SELECT * FROM ".static::$table_name." WHERE id=? LIMIT 1";
  $result_set=self::findBySQL($sql,array($id));
  return array_shift($result_set);
}

public static function findBySQL($sql="",$prep_values=array()){
     global $database;
try{
  $handle=$database->prepare($sql);
  $handle->execute($prep_values);
  return $handle->fetchALL(PDO::FETCH_CLASS, get_called_class());
}catch (PDOException $e){self::sqlErrorHandler($e,$sql);}
}
The rest of the CRUD also goes like that, create(), update(), delete() functions are all located in the DatabaseObject class, so for example after validating and setting all the needed variables(like $category->title='post value here' etc), I just run $category->create() and it gets inserted to the database. The Category, Post and Photo class have static variables $table_name and $db_fields array, which enable the DatabaseObject class create the queries dynamically based on the class that called them.

So if the client goes to the URL index.php?category=17&sub=posts
I would use this code to display the posts/photos
Code:
$category=Category::findById(intval($_GET['c']));
echo 'There are '.$category->post_count.' posts and '.$category->photo_count.' photos in '.$category->title;
if($_GET['sub']=='posts'){
$posts=$category->findPosts();//which in turn calls Post::findAll(' WHERE category_id=$this->id');
//display the posts
}else{//if the sub==photos, do the same but instead of posts, find all the photos}
I'm sorry if my explanation was a bit hard to follow.


Now for the new implementation in CI. I'm not sure how the setup should look like. I came up with this:
index.php/site/category/17/posts (displays the posts of category id 17)
index.php/site/category/17/photos (displays the posts of category id 17)
index.php/site/tag/php/posts (displays the posts with the tag php)
index.php/site/keyword/programming/posts (displays the posts which contain the search term)
index.php/site/photo/28 (displays the large view of the photo id 28

The other controller would be 'Admin' which deals with all the adding categories,photos, posts etc.

The problem is that when I move to CodeIgniter I kind of want the same logic and structure I had before. But when I extend my Category model from the CI_Model, I can't use the DatabaseObject class, which could be used by all the Post, Photo and Category models.
So for example the controller Site in the function category();
Code:
public function category ($id) {
$this->load->model('category');
//this creates an instance class $category, but for me, it is logical, that an instance should only created when it is loaded from a database i.e. the object has all the needed properties(id, title etc) OR when it is about to be created i.e. inserted to the database.
//so to get the title, post_count and photo_count of the category, should I just use something like $category->getInfo($id) or something like that?
//instead I'd like to instantiate an object $category (but only if the category with the given $id exists)
$current_category=$category->findById($id);
//I'd still like to store the findById() and create(), update() etc in a general class, not have the same function in each model.
$data['post_count']=$current_category->post_count;
$data['photo_count']=$current_category->photo_count;
//but this means now there are two instances of the Category class, one for model and one for the actual category, that exists in the database, which is kind of unconsistent.
  
$data['posts']=$current_category->findPosts();
$this->load->view('posts',$data);
}

What I'd like to use is something like
Code:
$this->load->model('category',$id);
$posts=$category->findPosts();
Which will automatically call the findById($id) and create the object, if it doesn't find the category with the given $id, then it just returns FALSE or an empty array. Then I would just check if the $category object got created, if not then there are obviously no photos or posts, so don't display anything.




Theme © iAndrew 2016 - Forum software by © MyBB