1. Trang chủ
  2. » Công Nghệ Thông Tin

Tạo mạng xã hội với PHP - part 10 docx

10 279 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 3,48 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

} // password length if strlen $_POST['register_password'] < 6 { $allClear = false; $this->registrationErrors[] = 'Your password is too short, it must be at least 6 characters';

Trang 1

}

// password length

if( strlen( $_POST['register_password'] ) < 6 )

{

$allClear = false;

$this->registrationErrors[] = 'Your password is too short, it

must be at least 6 characters';

$this->registrationErrorLabels['register_password_label'] =

'error';

$this->registrationErrorLabels['register_password_confirm_

label'] = 'error';

}

Next, we have the e-mail address—we need to check it for header injection, and

that the format of the e-mail address is correct The first highlighted section of code

shows the header injection check, and the second shows the format check.

// email headers

if( strpos( ( urldecode( $_POST[ 'register_email' ] ) ), "\r" )

=== true || strpos( ( urldecode( $_POST[ 'register_email' ]

) ), "\n" ) === true )

{

$allClear = false;

$this->registrationErrors[] = 'Your email address is not

valid (security)';

$this->registrationErrorLabels['register_email_label'] =

'error';

}

// email valid

if( ! preg_match(

z0-9-]+)*(\.[a-z]{2,4})^", $_POST[ 'register_email' ] ) )

{

$allClear = false;

$this->registrationErrors[] = 'You must enter a valid email

address';

$this->registrationErrorLabels['register_email_label'] =

'error';

}

To help protect us from a legal perspective, we should get legal advice on the policies

and terms and conditions we need to enforce on our social network When we have

such terms in place, we will want our users to accept these before allowing them to

join—let's ensure they ticked the appropriate box on our registration form template:

Trang 2

// terms accepted

if( ! isset( $_POST['register_terms'] ) || $_POST['register_

terms'] != 1 )

{

$allClear = false;

$this->registrationErrors[] = 'You must accept our terms and

conditions.';

$this->registrationErrorLabels['register_terms_label'] =

'error';

}

If a user signs up with the e-mail address or username of an existing user, we will

have some problems—particularly when they come to log in, or request an e-mail to

reset their password To prevent this, we need to check that the username and e-mail

address are not currently in use by another user, which can be done with a simple

database query:

// duplicate user+email check

$u = $this->registry->getObject('db')->sanitizeData( $_

POST['register_user'] );

$e = $this->registry->getObject('db')->sanitizeData( $_

POST['register_email'] );

$sql = "SELECT * FROM users WHERE username='{$u}' OR

email='{$e}'";

$this->registry->getObject('db')->executeQuery( $sql );

if( $this->registry->getObject('db')->numRows() == 2 )

{

$allClear = false;

// both

$this->registrationErrors[] = 'Both your username and email

address are already in use on this site.';

$this->registrationErrorLabels['register_user_label'] =

'error';

$this->registrationErrorLabels['register_email_label'] =

'error';

}

elseif( $this->registry->getObject('db')->numRows() == 1 )

{

// possibly both, or just one

$u = $this->registry->getObject('db')->sanitizeData( $_

POST['register_user'] );

$e = $this->registry->getObject('db')->sanitizeData( $_

POST['register_email'] );

$data = $this->registry->getObject('db')->getRows();

if( $data['username'] == $u && $data['email'] == $e )

{

Trang 3

$allClear = false;

$this->registrationErrors[] = 'Both your username and

password are already in use on this site.';

$this->registrationErrorLabels['register_user_label'] =

'error';

$this->registrationErrorLabels['register_email_label'] =

'error';

// both

}

elseif( $data['username'] == $u )

{

$allClear = false;

// username

$this->registrationErrors[] = 'Your username is already

in use on this site.';

$this->registrationErrorLabels['register_user_label'] =

'error';

}

else

{

$allClear = false;

// email address

$this->registrationErrors[] = 'Your email address is

already in use on this site.';

$this->registrationErrorLabels['register_email_label'] =

'error';

}

}

Finally, before we go onto profile fields, we check to see if we have enabled

CAPTCHA If we have, then we should do a check that the user is a human

and not an automated spam bot We will discuss CAPTCHA implementation

later in this chapter.

// captcha

if( $this->registry->getSetting('captcha.enabled') == 1 )

{

// captcha check

}

Trang 4

Now that we have checked all of the core fields, we pass control to our registration

extension, which will process all of the profile related fields:

// hook

if( $this->registrationExtention->checkRegistrationSubmission()

== false )

{

$allClear = false;

}

If all is clear (that is, there were no errors either from this function, or the registration

controller extension), then we store our sanitized data, and return true—so that

another method can create the user account and profile:

if( $allClear == true )

{

$this->sanitizedValues['username'] = $u;

$this->sanitizedValues['email'] = $e;

$this->sanitizedValues['password_hash'] = md5( $_

POST['register_password'] );

$this->sanitizedValues['active'] = $this->activeValue;

$this->sanitizedValues['admin'] = 0;

$this->sanitizedValues['banned'] = 0;

$this->submittedValues['register_user'] = $_POST['register_

user'];

$this->submittedValues['register_password'] = $_

POST['register_password'];

return true;

}

else

{

$this->submittedValues['register_user'] = $_POST['register_

user'];

$this->submittedValues['register_email'] = $_POST['register_

email'];

$this->submittedValues['register_password'] = $_

POST['register_password'] ;

$this->submittedValues['register_password_confirm'] = $_

POST['register_password_confirm'] ;

$this->submittedValues['register_captcha'] = ( isset( $_

POST['register_captcha'] ) ?

$_POST['register_captcha'] : '' );

return false;

}

}

Trang 5

Hooking additional fields on

Depending on the social network we were developing, we will have different

profile fields To make our code flexible, these fields are abstracted to a registration

extension, so if we reuse our code, we simply need to change this one file to process

these additional fields, and we know that it won't interfere with our core fields In

Dino Space land, citizens are only permitted to keep one Dinosaur, after all, who

could cope with looking after more than one! This would need to be tweaked slightly

if we wanted to extend our registration form to accept any number of a particular

set of fields There is some JavaScript available to help with such a situation

(

http://www.michaelpeacock.co.uk/blog/entry/add-another-item-with-php-and-jquery and

http://www.michaelpeacock.co.uk/blog/entry/add-another-the-jquery-plugin should get you started if you want to try it).

For Dino Space, there are going to be certain profile fields we want, and some

examples include:

• Dinosaur's name

• Dinosaur's breed

• Dinosaur's gender

• Dinosaur's date of birth

The registry extension works in a similar way to the core registration controller,

except the data validation is more dynamic, based on how the additional profile

fields are defined For example, to create the four additional profile fields from

above, we would define the following:

private $registry;

private $extraFields = array();

private $errors = array();

private $submittedValues = array();

private $sanitizedValues = array();

private $errorLabels = array();

public function construct( $registry )

{

$this->registry = $registry;

$this->extraFields['dino_name'] = array( 'friendlyname' =>

'Pet Dinosaurs Name', 'table' => 'profile', 'field' =>

'dino_name', 'type' => 'text', 'required' => false );

$this->extraFields['dino_breed'] = array( 'friendlyname' =>

'Pet Dinosaurs Breed', 'table' => 'profile', 'field' =>

'dino_breed', 'type' => 'text', 'required' => false );

$this->extraFields['dino_gender'] = array( 'friendlyname' =>

Trang 6

'Pet Dnosaurs Gender', 'table' => 'profile', 'field' =>

'dino_gender', 'type' => 'list', 'required' => false,

'options' => array( 'male', 'female') );

$this->extraFields['dino_dob'] = array( 'friendlyname' => 'Pet

Dinosaurs Date of Birth', 'table' => 'profile', 'field' =>

'dino_dob', 'type' => 'DOB', 'required' => false );

}

Let's take a look at why we structure our extraFields like this To do this, we need

to look at how the extension validates the registration submission.

public function checkRegistrationSubmission()

{

We set a $valid variable (just like our allClear variable in the registration

controller) If there are errors, we set this to false.

$valid = true;

We now iterate through the fields to process them individually:

foreach( $this->extraFields as $field => $data )

{

Firstly, we check to see whether the field is required (from the required element of

the data array) If it is, we check that the user has submitted a value If they haven't,

we store the necessary errors.

if( ( ! isset( $_POST['register_' $field] ) ||

$_POST['register_' $field] == '' )

&& $data['required'] = true )

{

$this->submittedValues[ $field ] = $_POST['register_'

$field];

$this->errorLabels['register_' $field '_label'] =

'error';

$this->errors[] = 'Field ' $data['friendlyname'] '

cannot be blank';

$valid = false;

}

If the field isn't required, and hasn't been set, then we note that, and move on.

elseif( $_POST['register_' $field] == '' )

{

$this->submittedValues[ 'register_' $field ] = '';

}

else

{

Trang 7

If our field is set, we then validate it depending on the type of data we are expecting

By default, there are three options:

• Text—text inputs

• Int—integers

• List—list of predefined options

However, it has been designed to allow other types to be plugged in, for instance,

dates The type also dictates how the data should be sanitized.

if( $data['type'] == 'text' )

{

$this->sanitizedValues[ 'register_' $field ] = $this-

>registry->getObject('db')->sanitizeData( $_

POST['register_' $field] );

$this->submittedValues['register_' $field] = $_

POST['register_' $field];

}

elseif( $data['type'] == 'int' )

{

$this->sanitizedValues[ 'register_' $field ] =

intval( $_POST['register_' $field] );

$this->submittedValues['register_' $field] = $_

POST['register_' $field];

}

elseif( $data['type'] == 'list' )

{

If the data type is a list, we simply check to see whether the value is in the array of

options, if it isn't we have an error, if it is—everything is OK.

if( ! in_array( $_POST['register_' $field],

$data['options'] ) )

{

$this->submittedValues[ $field ] = $_

POST['register_' $field];

$this->errorLabels['register_' $field '_label'] =

'error';

$this->errors[] = 'Field ' $data['friendlyname']

' was not valid';

$valid = false;

}

else

{

$this->sanitizedValues[ 'register_' $field ] =

intval( $_POST['register_' $field] );

$this->submittedValues['register_' $field] = $_

POST['register_' $field];

Trang 8

}

}

else

{

Finally, for non-standard cases, we call a custom method, which we would create for

each such type:

$method = 'validate_' $data['type'];

if( $this->$method( $_POST['register_' $field] ) ==

true )

{

$this->sanitizedValues[ 'register_' $field ] =

$this->registry->getObject('db')->sanitizeData(

$_POST['register_' $field] );

$this->submittedValues['register_' $field] = $_

POST['register_' $field];

}

else

{

$this->sanitizedValues[ 'register_' $field ] =

$this->registry->getObject('db')->sanitizeData(

$_POST['register_' $field] );

$this->submittedValues['register_' $field] = $_

POST['register_' $field];

$this->errors[] = 'Field ' $data['friendlyname']

' was not valid';

$valid = false;

}

}

}

}

Once all the processing has been done, and sanitized data has been stored, we simply

return whether there were errors or not:

if( $valid == true )

{

return true;

}

else

{

return false;

}

}

Trang 9

Processing the registration

Once we have processed all of the fields submitted and checked that they are all

valid, we are then ready to create our user account and our profile Creating the user

is a simple case of inserting the serialized values into the users table Then, we pass

control to the extension so that it can process the profile fields.

/**

* Process the users registration, and create the user and users

profiles

* @return int

*/

private function processRegistration()

{

// insert

$this->registry->getObject('db')->insertRecords( 'users',

$this->sanitizedValues );

// get ID

$uid = $this->registry->getObject('db')->lastInsertID();

// call extension to insert the profile

$this->registrationExtention->processRegistration( $uid );

// return the ID for the frameworks reference - autologin?

return $uid;

}

Creating the profile

Within our extra fields array, we noted the table and field that the submitted value

should be inserted into This method goes through the array, and groups the values

for each table, to ensure that only one insert is performed per additional table.

The advantage of this means if we added fields for another table (perhaps

subscription information for paid user accounts), we can do this without

needing to add more functionality to our extension.

/**

* Create our user profile

* @param int $uid the user ID

* @return bool

*/

public function processRegistration( $uid )

{

$tables = array();

$tableData = array();

Trang 10

// group our profile fields by table, so we only need to do one

insert per table

foreach( $this->extraFields as $field => $data )

{

if( ! ( in_array( $data['table'], $tables ) ) )

{

$tables[] = $data['table'];

$tableData[ $data['table'] ] = array( 'user_id' => $uid,

$data['field'] => $this->sanitizedValues[ 'register_'

$field ]);

}

else

{

$tableData[ $data['table'] ] = array( 'user_id' => $uid,

$data['field'] => $this->sanitizedValues[ 'register_'

$field ]);

}

}

foreach( $tableData as $table => $data )

{

$this->registry->getObject('db')->insertRecords( $table,

$data );

}

return true;

}

Putting it all together: registration constructor

So, we have gone through our registration controller, and our registration controller

extension to see how they process data to create our user account and user profile

We now just need to bring this all together in the constructor.

Firstly, we assign our registry object:

$this->registry = $registry;

Next, we include the extension file, and create the object:

require_once FRAMEWORK_PATH 'controllers/authenticate/

registrationcontrollerextention.php';

$this->registrationExtention = new

Registrationcontrollerextention( $this->registry );

We then check to see if the user has tried to submit the registration form:

if( isset( $_POST['process_registration'] ) )

{

Ngày đăng: 04/07/2014, 21:20

TỪ KHÓA LIÊN QUAN