[ 152 ]The link to view a user's profile will simply be: profile/view/userid,.. Members List {letter} {name} Keeper of {dino_name} a {dino_gender} {dino_breed} {form_relationship} Con
Trang 1[ 152 ]
The link to view a user's profile will simply be: profile/view/userid, This
enacts the profile controller, which in turn passes control to the profile 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 profile information controller (controllers/profile/
profileinformationcontroller.php) needs to communicate with the model,
to get the data for the profile, 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 profile 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 );
Trang 2}
/**
* 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 profile 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 profile
(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>
Trang 3[ 154 ]
<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 profile (
http://localhost/folder-containing-socialnetwork/profile/view/1), we see the user's profile on the screen as
shown in the following screenshot:
Trang 4Relationships—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 profile 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 profile
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');
Trang 5[ 156 ]
$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 file 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 profile, we are shown a list
of all of their contacts as shown in the following screenshot:
Trang 6Editing the profile
Again, our model will make things much easier for us here, as it allows us to get all
of the information from the profile (to populate the edit form fields) and includes
provisions for saving changes to a profile 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 profile This will then interact
with the model, calling the save method to save the profile 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
profile 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 file (lib/images/imagemanager.class.php)
Some important aspects are highlighted and discussed within.
<?php
/**
* Image manager class
* @author Michael Peacock
*/
class Imagemanager
Trang 7[ 158 ]
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 file 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()
Trang 8{
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
Trang 9[ 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 )
Trang 10{
$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 file has been uploaded,
checks the type of file, 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'], '.');