Proles and Statuses [ 162 ] return false; } else { $l = strlen( $_FILES[ $postfield ]['name'] ) - $i; $ext = strtolower ( substr( $_FILES[ $postfield ] ['name'], $i+1, $l ) ); if( in_array( $ext, $this->uploadExtentions ) ) { if( in_array( $_FILES[ $postfield ]['type'], $this- >uploadTypes ) ) { $name = str_replace( ' ', '', $_FILES[ $postfield ]['name'] ); $this->name = $name_prefix . $name; $path = $moveto . $name_prefix.$name; move_uploaded_file( $_FILES[ $postfield ] ['tmp_name'] , $path ); $this->loadFromFile( $path ); return true; } else { // 'invalid type'; return false; } } else { // 'invalid extention'; return false; } } } else { // 'not uploaded file'; return false; } } Download from Wow! eBook <www.wowebook.com> Chapter 5 [ 163 ] /** * Get the image name * @return String */ public function getName() { return $this->name; } When we have nished processing an image, the save method nds the appropriate image function for the format of the image, and then saves the le. /** * Save changes to an image e.g. after resize * @param String $location location of image * @param String $type type of the image * @param int $quality image quality /100 * @return void */ public function save( $location, $type='', $quality=100 ) { $type = ( $type == '' ) ? $this->type : $type; if( $type == IMAGETYPE_JPEG ) { imagejpeg( $this->image, $location, $quality); } elseif( $type == IMAGETYPE_GIF ) { imagegif( $this->image, $location ); } elseif( $type == IMAGETYPE_PNG ) { imagepng( $this->image, $location ); } } } ?> Download from Wow! eBook <www.wowebook.com> Proles and Statuses [ 164 ] Back to the controller Now, we have an excellent class available to process our prole image uploads, which should make things much easier for us; let's look at actually allowing the user to edit their prole page, with a new function in our prole information controller ( controllers/profile/profileinformationcontroller.php). /** * Edit your profile * @return void */ private function editProfile() { if( $this->registry->getObject('authenticate')->isLoggedIn() == true ) { We rst check that the user is logged into the site, and if they are, we get their user ID. $user = $this->registry->getObject('authenticate')->getUser()- >getUserID(); if( isset( $_POST ) && count( $_POST ) > 0 ) { If the edit form has been submitted, include the model and set the new values. // edit form submitted $profile = new Profile( $this->registry, $user ); $profile->setBio( $this->registry->getObject('db')- >sanitizeData( $_POST['bio'] ) ); $profile->setName( $this->registry->getObject('db')- >sanitizeData( $_POST['name'] ) ); $profile->setDinoName( $this->registry->getObject('db')- >sanitizeData( $_POST['dino_name'] ) ); $profile->setDinoBreed( $this->registry->getObject('db')- >sanitizeData( $_POST['dino_breed'] ) ); $profile->setDinoGender( $this->registry->getObject('db')- >sanitizeData( $_POST['dino_gender'] ), false ); $profile->setDinoDOB( $this->registry->getObject('db')- >sanitizeData( $_POST['dino_dob'] ), false ); If a prole picture was uploaded, call the image manager, check that the image is an image, upload it, resize it, and set the prole picture eld. if( isset( $_POST['profile_picture'] ) ) { require_once( FRAMEWORK_PATH . 'lib/images/imagemanager. class.php' ); Download from Wow! eBook <www.wowebook.com> Chapter 5 [ 165 ] $im = new Imagemanager(); $im->loadFromPost( 'profile_picture', $this->registry- >getSetting('uploads_path') .'profile/', time() ); if( $im == true ) { $im->resizeScaleHeight( 150 ); $im->save( $this->registry->getSetting('uploads_path') .'profile/' . $im->getName() ); $profile->setPhoto( $im->getName() ); } } We then save the prole, and redirect the user back to the edit page after informing them that the prole has been saved. $profile->save(); $this->registry->redirectUser( array('profile', 'view', 'edit' ), 'Profile saved', 'The changes to your profile have been saved', false ); } else { If the user hasn't submitted the edit form, show them the form and populate it with prole data from the prole model. // show the edit form $this->registry->getObject('template')->buildFromTemplates( 'header.tpl.php', 'profile/information/edit.tpl.php', 'footer.tpl.php' ); // get the profile information to pre-populate the form fields require_once( FRAMEWORK_PATH . 'models/profile.php' ); $profile = new Profile( $this->registry, $user ); $profile->toTags( 'p_' ); } } else { If the user isn't logged in, they shouldn't be trying to edit a prole, so show them an error message. $this->registry->errorPage('Please login', 'You need to be logged in to edit your profile'); } } Download from Wow! eBook <www.wowebook.com> Proles and Statuses [ 166 ] We also need a switch statement at the top of our prole information controller, to either call the viewProfile method or the editProfile method, depending on the user's request. $urlBits = $this->registry->getObject('url')->getURLBits(); if( isset( $urlBits[3] ) ) { switch( $urlBits[3] ) { case 'edit': $this->editProfile(); break; default: $this->viewProfile( $user ); break; } } else { $this->viewProfile( $user ); } Template Next, we need a template le for our edit page. This needs to contain a form, with template variables as the values for the form elds, to be pre-populated with the user's prole information. The template le The template le should be similar to that of the view prole template, as the name, picture, and selection of friends will still be generated and inserted into the view. The code for the template (views/default/templates/profile/information/ edit.tpl.php ) is below, with the form highlighted: <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 > Download from Wow! eBook <www.wowebook.com> Chapter 5 [ 167 ] <li><a href="relationships/all/{p_user_id}">View all</a> </li> <li><a href="relationships/mutual/{p_user_id}">View mutual friends</a></li> </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}: Edit Profile</h1> <form action="profile/view/{p_user_id}/edit" method="post" enctype="multipart/form-data"> <label for="name">Name</label><br /> <input type="text" id="name" name="name" value="{p_name}" /><br /> <label for="profile_picture">Photograph</label> <br /> <input type="file" id="profile_picture" name="profile_ picture" /> <br /> <label for="bio">Biography</label> <textarea id="bio" name="bio" cols="40" rows="6">{p_bio}</ textarea> <label for="dino_name">Dinosaur Name</label><br /> <input type="text" id="dino_name" name="dino_name" value=" {p_dino_name}" /><br /> <label for="dino_breed">Dinosaur Breed</label><br /> <input type="text" id="dino_breed" name="dino_breed" value="{p_dino_breed}" /><br /> <label for="dino_dob">Dinosaur Date of Birth</label><br /> <input type="text" id="dino_dob" class="selectdate" name="dino_dob" value="{p_dino_dob}" /><br /> <label for="dino_gender">Dinosaur Gender</label><br /> <select id="dino_gender" name="dino_gender"> <option value="">Please select</option> <option value="male">Male</option> <option value="female">Female</option> </select> <br /> <input type="submit" id="" name="" value="Save profile" /> </form> </div> </div> Download from Wow! eBook <www.wowebook.com> Proles and Statuses [ 168 ] Datepicker The date format is something users are likely to get confused with, being unsure of how to format the date correctly or putting in incorrect details. To make this easier, we should use the jQuery datepicker plugin, which can take a textbox, and present the user with a nice calendar popup to select the date from. We will need jQuery, jQuery UI, and the datepicker plugin, which can be downloaded from: http://jqueryui.com/download. With the les downloaded and placed suitably within our framework, we need to edit our views/default/templates/header.tpl.php le to include the les, and assign certain textboxes with the datepicker plugin. The code below shows referencing the new les, and some JavaScript that links textboxes with a class of selectdate to the datepicker plugin: <link type="text/css" href="external/ui-lightness/jquery-ui- 1.7.1.custom.css" rel="stylesheet" /> <script type="text/javascript" src="external/jquery-1.3.2.min. js"></script> <script type="text/javascript" src="external/jquery-ui- 1.7.2.custom.min.js"></script> <script type="text/javascript"> $(function() { $('.selectdate').datepicker({ numberOfMonths: 1, showButtonPanel: false }); $('.selectdate').datepicker('option', 'dateFormat', 'dd/mm/ yy'); }); </script> In action If we now take a look at the edit screen, we have our form as shown in the following screenshot: Download from Wow! eBook <www.wowebook.com> Chapter 5 [ 169 ] And if we click the date, a datepicker is displayed as shown in the following screenshot: Download from Wow! eBook <www.wowebook.com> Proles and Statuses [ 170 ] Statuses If we assume for the moment that statuses are not the only things we would want to display on our users proles, this can help us plan out this feature more appropriately. Because of this, we would want to have a single database table that keeps a central record of all the different types of content, and the proles it relates to. Statuses database table Below is a suitable structure for the statuses database table. Field Type Description ID Integer, Primary Key, Auto-increment ID of the status Update Longtext The content of the update Type Integer Reference to the status types table Creator Integer The ID of the poster Created Timestamp Time status was posted Prole Integer Prole the status was posted on Approved Boolean If the status is approved or notIf the status is approved or not Statuses types database table We also need a status types table, to relate to the type eld, giving a name of the type of status update (for example, if it is a posted URL, an image, and so on), and a reference for the template bit to be used for that status update (we will discuss that shortly). Field Type Description ID Integer, Primary Key, Auto-increment ID of the status type Type_name Varchar The name of the type of status Type_reference Varchar A machine readable name for the type, used as the le name of template bits (that is, no spaces or punctuation) Active Boolean Indicates whether the status type is active or not Download from Wow! eBook <www.wowebook.com> Chapter 5 [ 171 ] Different types of status Each type of prole update, if appropriate, would have its own database table to store data specic to that type of update. For instance, if the user posted a URL we would use the status text as a description of the URL and include the user's comment about it, but we would also want to store the URL itself; this is where we would use another table to extend the status. This keeps a central table of statuses that we can query to provide our status list, while allowing us to have specialist tables to contain only the data required for different types of status. We will look into different types of status, in Chapter 8, Statuses—Other Media. Template improvements Depending on posted comments, messages, and statuses on a user's prole, we may need to insert different template bits to the page, for instance one for a status update, one for a public post, one for an image posted on the prole and so on. And, for each of these, we may need to display a number of comments, a number of likes, and a number of dislikes. To facilitate this, we would need to upgrade our template system. For instance, the rst stage would be to create a template loop of updates to a user's prole, then each of these would require a new template bit to be inserted within. However, since we may have more than one of each type, for example, three status updates, the template bit would need to have a unique template tag within there, for example, status-message-1, status-message-2. Otherwise, the three statuses will all be the same. We need to allow the template system to dynamically update some of its template variables on the y, as it is inserted into the page. To do this, we simply add a new optional parameter to the addTemplateBit method, which is an array of template variables assigned specically with that instance of the template bit. This new parameter, $replacements, needs to be passed to the appropriate addTemplateBit method in the page object too. /** * Add a template bit from a view to our page * @param String $tag the tag where we insert the template e.g. {hello} * @param String $bit the template bit (path to file, or just the filename) * @param Array $replacements template bit specific replacements * @return void */ Download from Wow! eBook <www.wowebook.com> . $this->registry, $user ); $profile->setBio( $this->registry->getObject('db' )- >sanitizeData( $_POST['bio'] ) ); $profile->setName( $this->registry->getObject('db' )-. ); $profile->setDinoBreed( $this->registry->getObject('db' )- >sanitizeData( $_POST['dino_breed'] ) ); $profile->setDinoGender( $this->registry->getObject('db' )-. { $im->resizeScaleHeight( 150 ); $im->save( $this->registry->getSetting('uploads_path') .'profile/' . $im->getName() ); $profile->setPhoto( $im->getName()