Proles and Statuses [ 152 ] Prole link The link to view a user's prole will simply be: profile/view/userid,. This enacts the prole controller, which in turn passes control to the prole information controller. We need to add this link to the following templates we already have: • Views/default/templates/members/list.tpl.php • Views/default/templates/members/search.tpl.php The link is shown below: <h1>DINO SPACE! Members List {letter}</h1> <! START members > <p><strong><a href="profile/view/{ID}">{name}</a></strong></p> <p>Keeper of <strong>{dino_name}</strong> a <strong>{dino_gender} {dino_breed}</strong></p> {form_relationship} <hr /> <! END members > Controller The prole information controller (controllers/profile/ profileinformationcontroller.php ) needs to communicate with the model, to get the data for the prole, and have the data assigned to template variables. We already have a method in the controller to do this, so it should be a fairly trivial task: include the model, and call the toTags method to push the prole information to template tags, as highlighted in the code below: <?php /** * Profile information controller */ class Profileinformationcontroller { /** * Constructor * @param Registry $registry * @param int $user the user id * @return void */ public function __construct( $registry, $user ) { $this->registry = $registry; $this->viewProfile( $user ); 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 5 [ 153 ] } /** * View a users profile information * @param int $user the user id * @return void */ private function viewProfile( $user ) { // load the template $this->registry->getObject('template')->buildFromTemplates( 'header.tpl.php', 'profile/information/view.tpl.php', 'footer. tpl.php' ); // get all the profile information, and send it to the template require_once( FRAMEWORK_PATH . 'models/profile.php' ); $profile = new Profile( $this->registry, $user ); $profile->toTags( 'p_' ); } } ?> Template The template for this aspect of the prole is shown below (views/default/ templates/profile/information/view.tpl.php ); the highlighted aspects show the common template information shared by all aspects of the prole (including aspects we may add in the future). <div id="main"> <div id="rightside"> <div style="text-align:center; padding-top: 5px;"> <img src="uploads/profile/{profile_photo}" /> </div> <div style="padding: 5px;"> <h2>Friends</h2> <ul> <! START profile_friends_sample > <li><a href="profile/view/{ID}">{users_name}</a></li> <! END profile_friends_sample > <li><a href="relationships/all/{profile_user_id}">View all</ a></li> <li><a href="relationships/mutual/{profile_user_id}">View mutual friends</a></li> 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 Proles and Statuses [ 154 ] </ul> <h2>Rest of my profile</h2> <ul> <li><a href="profile/statuses/{ID}">Status updates</a></li> </ul> </div> </div> <div id="content"><h1>{profile_name}</h1> <p>{p_bio}</p> <h2>My Dinosaur</h2> <table> <tr> <th>Name</th> <td>{p_dino_name}</td> </tr> <tr> <th>DOB</th> <td>{p_dino_dob}</td> </tr> <tr> <th>Breed</th> <td>{p_dino_breed}</td> </tr> <tr> <th>Gender</th> <td>{p_dino_gender}</td> </tr> </table> </div> </div> In action If we now visit a user's prole (http://localhost/folder-containing- socialnetwork/profile/view/1 ), we see the user's prole on the screen as shown in the following screenshot: 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 5 [ 155 ] Relationships—some improvements At present, our relationships controller is only set to either list our relationships with other users, or pending relationship requests. It isn't set up to show all of the contacts of a user, or all of the mutual contacts we have in common with a user. Let's extend our relationships controller to facilitate these; after all, we have placed a link to them on our prole pages. All contacts To get a list of all the contacts of a user, we simply require the relationships model, and call the getRelationships method, passing the user whose prole we were viewing: /** * View all users connections * @param int $user * @return void */ private function viewAll( $user ) { if( $this->registry->getObject('authenticate')->isLoggedIn() ) { require_once( FRAMEWORK_PATH . 'models/relationships.php'); $relationships = new Relationships( $this->registry ); $all = $relationships->getByUser( $user, false, 0 ); $this->registry->getObject('template')- 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 Proles and Statuses [ 156 ] >buildFromTemplates('header.tpl.php', 'friends/all.tpl.php', 'footer.tpl.php'); $this->registry->getObject('template')->getPage()->addTag('all', array( 'SQL', $all ) ); require_once( FRAMEWORK_PATH . 'models/profile.php'); $p = new Profile( $this->registry, $user ); $name = $p->getName(); $this->registry->getObject('template')->getPage()->addTag( 'connecting_name', $name ); } else { $this->registry->errorPage( 'Please login', 'Please login to view a users connections'); } } Template We need a template le called views/default/templates/friends/all.tpl.php to act as the template for viewing all of a user's friends. <div id="main"> <div id="rightside"> </div> <div id="content"> <h1>Connections of {connecting_name}</h1> <ul> <! START all > <li>{plural_name} with {users_name}</p> <! END all > </ul> </div> </div> In action Now, if we click the view all contacts link on a user's prole, we are shown a list of all of their contacts as shown in the following screenshot: 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 5 [ 157 ] Editing the prole Again, our model will make things much easier for us here, as it allows us to get all of the information from the prole (to populate the edit form elds) and includes provisions for saving changes to a prole. It won't, however, deal with a user requesting to change their password or update their e-mail address; we will discuss that separately. Controller additions Our controller needs to have a new method added to display an edit page, and process the form submission when a user edits their prole. This will then interact with the model, calling the save method to save the prole changes in the database. Uploading a photograph—an image handler As we are going to be uploading and scaling a user's photograph to act as their prole picture, we should consider developing an image handler class, which can process uploads, save images, and deal with resizing, keeping all of our image related code in a single place. Following is the code for such a le ( lib/images/imagemanager.class.php). Some important aspects are highlighted and discussed within. <?php /** * Image manager class * @author Michael Peacock */ class Imagemanager { private $type = ''; 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 Proles and Statuses [ 158 ] We dene extensions and le types that we wish to allow users to upload. private $uploadExtentions = array( 'png', 'jpg', 'jpeg', 'gif' ); private $uploadTypes = array( 'image/gif', 'image/jpg', 'image/ jpeg', 'image/pjpeg', 'image/png' ); private $image; private $name; public function __construct(){} If we load the image from the le system, we need to know the type of image it is, so we can use the correct imagecreate function, we can get the type of image from the getimagesize function. . This requires the GD image library to be enabled with PHP. /** * Load image from local file system * @param String $filepath * @return void */ public function loadFromFile( $filepath ) { $info = getimagesize( $filepath ); $this->type = $info[2]; if( $this->type == IMAGETYPE_JPEG ) { $this->image = imagecreatefromjpeg($filepath); } elseif( $this->type == IMAGETYPE_GIF ) { $this->image = imagecreatefromgif($filepath); } elseif( $this->type == IMAGETYPE_PNG ) { $this->image = imagecreatefrompng($filepath); } } This class can also wrap the imagesx and imagesy functions to provide a nice way to get the width and height of the image. /** * Get the image width * @return int */ public function getWidth() 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 5 [ 159 ] { return imagesx($this->image); } /** * Get the height of the image * @return int */ public function getHeight() { return imagesy($this->image); } Using imagecopyresampled, we can resize the image. Imagecopyresampled allows us to resize the image without distorting the image, whereas imagecopyresized does result in some distortion. /** * Resize the image * @param int $x width * @param int $y height * @return void */ public function resize( $x, $y ) { $new = imagecreatetruecolor($x, $y); imagecopyresampled($new, $this->image, 0, 0, 0, 0, $x, $y, $this->getWidth(), $this->getHeight()); $this->image = $new; } In most cases, we, or the user, won't know the exact dimensions to resize an image to. To get around this, we can resize one dimension based on a set amount (for example , a thumbnail width) and scale the other dimension to match. /** * Resize the image, scaling the width, based on a new height * @param int $height * @return void */ public function resizeScaleWidth( $height ) 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 Proles and Statuses [ 160 ] { $width = $this->getWidth() * ( $height / $this->getHeight() ); $this->resize( $width, $height ); } /** * Resize the image, scaling the height, based on a new width * @param int $width * @return void */ public function resizeScaleHeight( $width ) { $height = $this->getHeight() * ( $width / $this->getWidth() ); $this->resize( $width, $height ); } Similar to the two methods above, we can also scale both dimensions by a percentage. /** * Scale an image * @param int $percentage * @return void */ public function scale( $percentage ) { $width = $this->getWidth() * $percentage / 100; $height = $this->getheight() * $percentage / 100; $this->resize( $width, $height ); } The display method can be used to display the image in the user's browser. /** * Display the image to the browser - called before output is sent, exit() should be called straight after. * @return void */ public function display() { $type = ''; if( $this->type == IMAGETYPE_JPEG ) { $type = 'image/jpeg'; } elseif( $this->type == IMAGETYPE_GIF ) 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 5 [ 161 ] { $type = 'image/gif'; } elseif( $this->type == IMAGETYPE_PNG ) { $type = 'image/png'; } header('Content-Type: ' . $type ); if( $this->type == IMAGETYPE_JPEG ) { imagejpeg( $this->image ); } elseif( $this->type == IMAGETYPE_GIF ) { imagegif( $this->image ); } elseif( $this->type == IMAGETYPE_PNG ) { imagepng( $this->image ); } } The most useful aspect for our current requirements is this loadFromPost method; the postfield is passed so the method can check to see if a le has been uploaded, checks the type of le, and then uploads it to the moveto location. /** * Load image from postdata * @param String $postfield the field the image was uploaded via * @param String $moveto the location for the upload * @param String $name_prefix a prefix for the filename * @return boolean */ public function loadFromPost( $postfield, $moveto, $name_prefix='' ) { if( is_uploaded_file( $_FILES[ $postfield ]['tmp_name'] ) ) { $i = strrpos( $_FILES[ $postfield ]['name'], '.'); if (! $i ) { //'no extention'; 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 . >buildFromTemplates('header.tpl .php& apos;, 'friends/all.tpl .php& apos;, 'footer.tpl .php& apos;); $this->registry->getObject('template' )-& gt;getPage( )-& gt;addTag('all',. 'models/profile .php& apos;); $p = new Profile( $this->registry, $user ); $name = $p->getName(); $this->registry->getObject('template' )-& gt;getPage( )-& gt;addTag( 'connecting_name',. template $this->registry->getObject('template' )-& gt;buildFromTemplates( 'header.tpl .php& apos;, 'profile/information/view.tpl .php& apos;, 'footer. tpl .php& apos; );