Groups [ 312 ] If we are setting the rst post, our controllers can access this post object by calling the getFirstPost method, and then calling the appropriate public methods on the post object. /** * Return the object for the first post, for setting fields * @return Object */ public function getFirstPost() { return $this->post; } We have a number of setter methods, as standard. /** * Set the group this topic should be part of * @param int $group * @return void */ public function setGroup( $group ) { $this->group = $group; } /** * Set the creator of the topic * @param int $creator * @return void */ public function setCreator( $creator ) { $this->creator = $creator; } /** * Set the name of the topic * @param String $name * @return void */ public function setName( $name ) { $this->name = $name; } This material is copyright and is licensed for the sole use by RAYMOND ERAZO on 25th October 2010 3146 KERNAN LAKE CIRCLE, JACKSONVILLE, 32246 Download from www.eBookTM.com Chapter 10 [ 313 ] We have our save method, which if appropriate, also saves the post once the topic has been created. /** * Save the topic into the database * @return void */ public function save() { if( $this->id > 0 ) { $update = array(); $update['creator'] = $this->creator; $update['name'] = $this->name; $update['group'] = $this->group; $this->registry->getObject('db')->updateRecords( 'topics', $update, 'ID=' . $this->id ); } else { $insert = array(); $insert['creator'] = $this->creator; $insert['name'] = $this->name; $insert['group'] = $this->group; $this->registry->getObject('db')->insertRecords( 'topics', $insert ); $this->id = $this->registry->getObject('db')->lastInsertID(); if( $this->includeFirstPost == true ) { $this->post->setTopic( $this->id ); $this->post->save(); } } } Next, we have a getter for the name property, and also a toTags method, which is now almost a standard for most of our models. /** * Get the name of the topic */ public function getName() { return $this->name; } This material is copyright and is licensed for the sole use by RAYMOND ERAZO on 25th October 2010 3146 KERNAN LAKE CIRCLE, JACKSONVILLE, 32246 Download from www.eBookTM.com Groups [ 314 ] /** * Convert the topic data to template tags * @param String $prefix prefix for the template tags * @return void */ public function toTags( $prefix='' ) { foreach( $this as $field => $data ) { if( ! is_object( $data ) && ! is_array( $data ) ) { $this->registry->getObject('template')->getPage()->addTag( $prefix.$field, $data ); } } } /** * Get the group this topic was posted within * @return int */ public function getGroup() { return $this->group; } Finally, we have a delete method, which in addition to deleting the current topic from the database, also removes any posts related to it in the posts table. /** * Delete the current topic * @return boolean */ public function delete() { $sql = "DELETE FROM topics WHERE ID=" . $this->id; $this->registry->getObject('db')->executeQuery( $sql ); if( $this->registry->getObject('db')->affectedRows() > 0 ) { $sql = "DELETE FROM posts WHERE topic=" . $this->id; $this->registry->getObject('db')->executeQuery( $sql ); $this->id =0; return true; } This material is copyright and is licensed for the sole use by RAYMOND ERAZO on 25th October 2010 3146 KERNAN LAKE CIRCLE, JACKSONVILLE, 32246 Download from www.eBookTM.com Chapter 10 [ 315 ] else { return false; } } } ?> The group itself With the models for topics and posts (which we will be using shortly) in place, we can now focus our attention on the group itself, as the group will need to make use of these models so that users of the groups can communicate and collaborate with one another. Group table The rst stage, as with the other aspects of our social network, is the database table. We've already discussed what information the group needs to store; the following database structure simply formalizes that: Field Type Description ID Integer, Auto-increment, Primary Key Internal ID / reference for the group Name Varchar Name of the group Description Longtext Detailed description of the group Type ENUM The type of the group Creator Integer The user who created the group Created Timestamp The time the group was created Active Boolean If the group is active, gives us the ability to de-activate groups later without deleting them Model The model required for groups (models/group.php) is fairly standard with a few minor additions. We have some validation on the type of group, and we also have a method to cache a query of topics posted in the group. <?php /** * Group model object */ This material is copyright and is licensed for the sole use by RAYMOND ERAZO on 25th October 2010 3146 KERNAN LAKE CIRCLE, JACKSONVILLE, 32246 Download from www.eBookTM.com Groups [ 316 ] class Group { /** * Types of group that are available */ private $types = array('public', 'private', 'private-member- invite', 'private-self-invite'); /** * The registry object */ private $registry; /** * ID of the group */ private $id; /** * The name of the group */ private $name; /** * Description of the group */ private $description; /** * The creator of the group */ private $creator; /** * Name of the creator of the group */ private $creatorName; /** * Time the group was created */ private $created; /** * Friendly representation of when the group was created This material is copyright and is licensed for the sole use by RAYMOND ERAZO on 25th October 2010 3146 KERNAN LAKE CIRCLE, JACKSONVILLE, 32246 Download from www.eBookTM.com Chapter 10 [ 317 ] */ private $createdFriendly; /** * Type of group */ private $type; /** * If the group is active or not */ private $active=1; /** * If the selected group is valid or not */ private $valid; /** * Group constructor * @param Registry $registry the registry * @param int $id the ID of the group * @return void */ public function __construct( Registry $registry, $id=0 ) { $this->registry = $registry; if( $id > 0 ) { $this->id = $id; $sql = "SELECT g.*, DATE_FORMAT(g.created, '%D %M %Y') as created_friendly, p.name as creator_name FROM groups g, profile p WHERE p.user_id=g.creator AND g.ID=" . $this->id; $this->registry->getObject('db')->executeQuery( $sql ); if( $this->registry->getObject('db')->numRows() == 1 ) { $data = $this->registry->getObject('db')->getRows(); $this->name = $data['name']; $this->description = $data['description']; $this->creator = $data['creator']; $this->valid = true; $this->active = $data['active']; $this->type = $data['type']; $this->created = $data['created']; This material is copyright and is licensed for the sole use by RAYMOND ERAZO on 25th October 2010 3146 KERNAN LAKE CIRCLE, JACKSONVILLE, 32246 Download from www.eBookTM.com Groups [ 318 ] $this->createdFriendly = $data['created_friendly']; $this->creator = $data['creator']; $this->creatorName = $data['creator_name']; } else { $this->valid = false; } } else { $this->id = 0; } } /** * Set the name of the group * @param String $name * @return void */ public function setName( $name ) { $this->name = $name; } /** * Set the description of the group * @param String $description the description * @return void */ public function setDescription( $description ) { $this->description = $description; } /** * Set the creator of the group * @param int $creator * @return void */ public function setCreator( $creator ) { $this->creator = $creator; } This material is copyright and is licensed for the sole use by RAYMOND ERAZO on 25th October 2010 3146 KERNAN LAKE CIRCLE, JACKSONVILLE, 32246 Download from www.eBookTM.com Chapter 10 [ 319 ] When setting the type of the group, it is validated against an array of available group types. /** * Set the type of the group * @param String $type * @return void */ public function setType( $type ) { if( in_array( $type, $this->types ) ) { $this->type = $type; } } /** * Save the group * @return void */ public function save() { if( $this->id > 0 ) { $update = array(); $update['description'] = $this->description; $update['name'] = $this->name; $update['type'] = $this->type; $update['creator'] = $this->creator; $update['active'] = $this->active; $update['created'] = $this->created; $this->registry->getObject('db')->updateRecords( 'groups', $update, 'ID=' . $this->id ); } else { $insert = array(); $insert['description'] = $this->description; $insert['name'] = $this->name; $insert['type'] = $this->type; $insert['creator'] = $this->creator; $insert['active'] = $this->active; $this->registry->getObject('db')->insertRecords( 'groups', $insert ); $this->id = $this->registry->getObject('db')->lastInsertID(); } } This material is copyright and is licensed for the sole use by RAYMOND ERAZO on 25th October 2010 3146 KERNAN LAKE CIRCLE, JACKSONVILLE, 32246 Download from www.eBookTM.com Groups [ 320 ] With the above code, we can easily populate our group page with topics related to it. We also have a method to cache a suitable query and return the cache. /** * Get a list of topics assigned to this group ( we could paginate this if we wanted to later) * @return int (database cache) */ public function getTopics() { $sql = "SELECT t.*, (SELECT COUNT(*) FROM posts po WHERE po.topic=t.ID) as posts, DATE_FORMAT(t.created, '%D %M %Y') as created_friendly, p.name as creator_name FROM topics t, profile p WHERE p.user_id=t.creator AND t.group=" . $this->id . " ORDER BY t.ID DESC"; $cache = $this->registry->getObject('db')->cacheQuery( $sql ); return $cache; } /** * Get the ID of the group */ public function getID() { return $this->id; } /** * Convert the group data to template tags * @param String $prefix prefix for the template tags * @return void */ public function toTags( $prefix='' ) { foreach( $this as $field => $data ) { if( ! is_object( $data ) && ! is_array( $data ) ) { $this->registry->getObject('template')->getPage()->addTag( $prefix.$field, $data ); } } } } ?> This material is copyright and is licensed for the sole use by RAYMOND ERAZO on 25th October 2010 3146 KERNAN LAKE CIRCLE, JACKSONVILLE, 32246 Download from www.eBookTM.com Chapter 10 [ 321 ] Creating a group With our model in place, we now need to work on our group's controller, rstly to facilitate the creation of new groups. We will shortly also create a group controller, for viewing a group and performing tasks within a group. Controller Since we are creating a new controller (controllers/groups/controller.php), we need to put some skeleton code in there, in addition to our create group code. We need a constructor that detects if the user is logged in, and if they are not, reverts to displaying a list of public groups. If the user is logged in, the default still lists public groups, but they can also create a group (and shortly, also search groups). The highlighted section of code shows how the group is created: <?php class Groupscontroller { /** * Controller constructor - direct call to false when being embedded via another controller * @param Registry $registry our registry * @param bool $directCall - are we calling it directly via the framework (true), or via another controller (false) */ public function __construct( Registry $registry, $directCall ) { $this->registry = $registry; $urlBits = $this->registry->getObject('url')->getURLBits(); if( $this->registry->getObject('authenticate')->isLoggedIn() ) { if( isset( $urlBits[1] ) ) { switch( $urlBits[1] ) { case 'create': $this->createGroup(); break; default: $this->listPublicGroups(0); break; } } else { This material is copyright and is licensed for the sole use by RAYMOND ERAZO on 25th October 2010 3146 KERNAN LAKE CIRCLE, JACKSONVILLE, 32246 Download from www.eBookTM.com . $this->id; $this->registry->getObject('db' )-& gt;executeQuery( $sql ); if( $this->registry->getObject('db' )-& gt;numRows() == 1 ) { $data = $this->registry->getObject('db' )-& gt;getRows(); . $this->registry->getObject('db' )-& gt;lastInsertID(); if( $this->includeFirstPost == true ) { $this->post->setTopic( $this->id ); $this->post->save(); } . = $this->active; $this->registry->getObject('db' )-& gt;insertRecords( 'groups', $insert ); $this->id = $this->registry->getObject('db' )-& gt;lastInsertID();