2010-11-01 23:50:45 +00:00
< ? php
/**
* StatusNet , the distributed open - source microblogging tool
*
2010-11-05 06:34:06 +00:00
* Login or register a local user based on a Facebook user
2010-11-01 23:50:45 +00:00
*
* PHP version 5
*
* LICENCE : This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU Affero General Public License for more details .
*
* You should have received a copy of the GNU Affero General Public License
* along with this program . If not , see < http :// www . gnu . org / licenses />.
*
* @ category Plugin
* @ package StatusNet
* @ author Zach Copley < zach @ status . net >
2011-09-26 06:32:19 +01:00
* @ copyright 2010 - 2011 StatusNet , Inc .
2010-11-01 23:50:45 +00:00
* @ license http :// www . fsf . org / licensing / licenses / agpl - 3.0 . html GNU Affero General Public License version 3.0
* @ link http :// status . net /
*/
if ( ! defined ( 'STATUSNET' )) {
exit ( 1 );
}
2010-11-05 06:34:06 +00:00
class FacebookfinishloginAction extends Action
2010-11-01 23:50:45 +00:00
{
2011-09-26 06:32:19 +01:00
private $fbuid = null ; // Facebook user ID
private $fbuser = null ; // Facebook user object (JSON)
private $accessToken = null ; // Access token provided by Facebook JS API
2010-11-01 23:50:45 +00:00
function prepare ( $args ) {
parent :: prepare ( $args );
2011-09-26 06:32:19 +01:00
// Check cookie for a valid access_token
2011-09-27 05:09:47 +01:00
if ( isset ( $_COOKIE [ 'fb_access_token' ])) {
$this -> accessToken = $_COOKIE [ 'fb_access_token' ];
2011-09-27 17:59:10 +01:00
}
if ( empty ( $this -> accessToken )) {
$this -> clientError ( _m ( " Unable to authenticate you with Facebook. " ));
2011-09-27 05:09:47 +01:00
}
2010-11-01 23:50:45 +00:00
2011-09-27 05:09:47 +01:00
$graphUrl = 'https://graph.facebook.com/me?access_token=' . urlencode ( $this -> accessToken );
$this -> fbuser = json_decode ( file_get_contents ( $graphUrl ));
2010-11-01 23:50:45 +00:00
2014-03-09 22:22:05 +00:00
if ( empty ( $this -> fbuser )) {
2011-09-27 05:09:47 +01:00
// log badness
2010-11-01 23:50:45 +00:00
list ( $proxy , $ip ) = common_client_ip ();
common_log (
LOG_WARNING ,
sprintf (
'Failed Facebook authentication attempt, proxy = %s, ip = %s.' ,
$proxy ,
$ip
),
__FILE__
);
$this -> clientError (
2011-04-08 09:59:10 +01:00
// TRANS: Client error displayed when trying to connect to Facebook while not logged in.
2010-11-01 23:50:45 +00:00
_m ( 'You must be logged into Facebook to register a local account using Facebook.' )
);
}
2014-03-09 22:22:05 +00:00
$this -> fbuid = $this -> fbuser -> id ;
// OKAY, all is well... proceed to register
return true ;
2010-11-01 23:50:45 +00:00
}
2011-09-26 06:32:19 +01:00
function handle ( $args )
{
parent :: handle ( $args );
2010-11-01 23:50:45 +00:00
2011-09-26 06:32:19 +01:00
if ( common_is_real_login ()) {
2010-11-01 23:50:45 +00:00
2011-09-26 06:32:19 +01:00
// This will throw a client exception if the user already
// has some sort of foreign_link to Facebook.
2010-11-01 23:50:45 +00:00
2011-09-26 06:32:19 +01:00
$this -> checkForExistingLink ();
2010-11-01 23:50:45 +00:00
2011-09-26 06:32:19 +01:00
// Possibly reconnect an existing account
2010-11-16 02:30:08 +00:00
2011-09-26 06:32:19 +01:00
$this -> connectUser ();
2010-11-01 23:50:45 +00:00
} else if ( $_SERVER [ 'REQUEST_METHOD' ] == 'POST' ) {
2010-11-16 02:30:08 +00:00
$this -> handlePost ();
} else {
$this -> tryLogin ();
}
}
2010-11-01 23:50:45 +00:00
2011-09-26 06:32:19 +01:00
function checkForExistingLink () {
// User is already logged in, are her accounts already linked?
$flink = Foreign_link :: getByForeignID ( $this -> fbuid , FACEBOOK_SERVICE );
if ( ! empty ( $flink )) {
// User already has a linked Facebook account and shouldn't be here!
$this -> clientError (
// TRANS: Client error displayed when trying to connect to a Facebook account that is already linked
// TRANS: in the same StatusNet site.
_m ( 'There is already a local account linked with that Facebook account.' )
);
}
$cur = common_current_user ();
$flink = Foreign_link :: getByUserID ( $cur -> id , FACEBOOK_SERVICE );
if ( ! empty ( $flink )) {
// There's already a local user linked to this Facebook account.
$this -> clientError (
// TRANS: Client error displayed when trying to connect to a Facebook account that is already linked
// TRANS: in the same StatusNet site.
_m ( 'There is already a local account linked with that Facebook account.' )
);
}
}
2010-11-16 02:30:08 +00:00
function handlePost ()
{
$token = $this -> trimmed ( 'token' );
2010-11-01 23:50:45 +00:00
2011-09-27 05:09:47 +01:00
// CSRF protection
2010-11-16 02:30:08 +00:00
if ( ! $token || $token != common_session_token ()) {
$this -> showForm (
2011-04-08 09:59:10 +01:00
// TRANS: Client error displayed when the session token does not match or is not given.
2010-11-16 02:30:08 +00:00
_m ( 'There was a problem with your session token. Try again, please.' )
);
return ;
}
if ( $this -> arg ( 'create' )) {
if ( ! $this -> boolean ( 'license' )) {
2010-11-01 23:50:45 +00:00
$this -> showForm (
2011-04-08 09:59:10 +01:00
// TRANS: Form validation error displayed when user has not agreed to the license.
2011-04-01 21:32:56 +01:00
_m ( 'You cannot register if you do not agree to the license.' ),
2010-11-16 02:30:08 +00:00
$this -> trimmed ( 'newname' )
);
2010-11-01 23:50:45 +00:00
return ;
}
2010-11-16 02:30:08 +00:00
// We has a valid Facebook session and the Facebook user has
// agreed to the SN license, so create a new user
$this -> createNewUser ();
2010-11-01 23:50:45 +00:00
2010-11-16 02:30:08 +00:00
} else if ( $this -> arg ( 'connect' )) {
2010-11-01 23:50:45 +00:00
2010-11-16 02:30:08 +00:00
$this -> connectNewUser ();
2010-11-01 23:50:45 +00:00
} else {
2010-11-16 02:30:08 +00:00
$this -> showForm (
2011-04-08 09:59:10 +01:00
// TRANS: Form validation error displayed when an unhandled error occurs.
2010-11-16 02:30:08 +00:00
_m ( 'An unknown error has occured.' ),
$this -> trimmed ( 'newname' )
);
2010-11-01 23:50:45 +00:00
}
}
function showPageNotice ()
{
if ( $this -> error ) {
$this -> element ( 'div' , array ( 'class' => 'error' ), $this -> error );
} else {
2010-11-16 02:30:08 +00:00
2010-11-01 23:50:45 +00:00
$this -> element (
'div' , 'instructions' ,
sprintf (
2011-04-08 09:59:10 +01:00
// TRANS: Form instructions for connecting to Facebook.
// TRANS: %s is the site name.
2011-04-01 21:32:56 +01:00
_m ( 'This is the first time you have logged into %s so we must connect your Facebook to a local account. You can either create a new local account, or connect with an existing local account.' ),
2010-11-01 23:50:45 +00:00
common_config ( 'site' , 'name' )
)
);
}
}
function title ()
{
// TRANS: Page title.
return _m ( 'Facebook Setup' );
}
function showForm ( $error = null , $username = null )
{
$this -> error = $error ;
$this -> username = $username ;
$this -> showPage ();
}
function showPage ()
{
parent :: showPage ();
}
/**
2011-04-08 09:59:10 +01:00
* @ todo FIXME : Much of this duplicates core code , which is very fragile .
2010-11-01 23:50:45 +00:00
* Should probably be replaced with an extensible mini version of
* the core registration form .
*/
function showContent ()
{
if ( ! empty ( $this -> message_text )) {
$this -> element ( 'p' , null , $this -> message );
return ;
}
$this -> elementStart ( 'form' , array ( 'method' => 'post' ,
'id' => 'form_settings_facebook_connect' ,
'class' => 'form_settings' ,
2010-11-05 06:34:06 +00:00
'action' => common_local_url ( 'facebookfinishlogin' )));
2010-11-01 23:50:45 +00:00
$this -> elementStart ( 'fieldset' , array ( 'id' => 'settings_facebook_connect_options' ));
2011-04-08 09:59:10 +01:00
// TRANS: Fieldset legend.
2010-11-01 23:50:45 +00:00
$this -> element ( 'legend' , null , _m ( 'Connection options' ));
$this -> elementStart ( 'ul' , 'form_data' );
$this -> elementStart ( 'li' );
$this -> element ( 'input' , array ( 'type' => 'checkbox' ,
'id' => 'license' ,
'class' => 'checkbox' ,
'name' => 'license' ,
'value' => 'true' ));
$this -> elementStart ( 'label' , array ( 'class' => 'checkbox' , 'for' => 'license' ));
// TRANS: %s is the name of the license used by the user for their status updates.
$message = _m ( 'My text and files are available under %s ' .
'except this private data: password, ' .
'email address, IM address, and phone number.' );
$link = '<a href="' .
htmlspecialchars ( common_config ( 'license' , 'url' )) .
'">' .
htmlspecialchars ( common_config ( 'license' , 'title' )) .
'</a>' ;
$this -> raw ( sprintf ( htmlspecialchars ( $message ), $link ));
$this -> elementEnd ( 'label' );
$this -> elementEnd ( 'li' );
$this -> elementEnd ( 'ul' );
$this -> elementStart ( 'fieldset' );
$this -> hidden ( 'token' , common_session_token ());
$this -> element ( 'legend' , null ,
2011-04-08 09:59:10 +01:00
// TRANS: Fieldset legend.
2010-11-01 23:50:45 +00:00
_m ( 'Create new account' ));
$this -> element ( 'p' , null ,
2011-04-08 09:59:10 +01:00
// TRANS: Form instructions.
2010-11-01 23:50:45 +00:00
_m ( 'Create a new user with this nickname.' ));
$this -> elementStart ( 'ul' , 'form_data' );
2011-01-20 23:55:36 +00:00
// Hook point for captcha etc
Event :: handle ( 'StartRegistrationFormData' , array ( $this ));
2010-11-01 23:50:45 +00:00
$this -> elementStart ( 'li' );
// TRANS: Field label.
$this -> input ( 'newname' , _m ( 'New nickname' ),
( $this -> username ) ? $this -> username : '' ,
2011-04-08 09:59:10 +01:00
// TRANS: Field title.
2011-04-01 21:32:56 +01:00
_m ( '1-64 lowercase letters or numbers, no punctuation or spaces.' ));
2010-11-01 23:50:45 +00:00
$this -> elementEnd ( 'li' );
2011-01-20 23:55:36 +00:00
// Hook point for captcha etc
Event :: handle ( 'EndRegistrationFormData' , array ( $this ));
2010-11-01 23:50:45 +00:00
$this -> elementEnd ( 'ul' );
2011-04-08 09:59:10 +01:00
// TRANS: Submit button to create a new account.
2010-11-01 23:50:45 +00:00
$this -> submit ( 'create' , _m ( 'BUTTON' , 'Create' ));
$this -> elementEnd ( 'fieldset' );
$this -> elementStart ( 'fieldset' );
$this -> element ( 'legend' , null ,
2011-04-08 09:59:10 +01:00
// TRANS: Fieldset legend.
2010-11-01 23:50:45 +00:00
_m ( 'Connect existing account' ));
$this -> element ( 'p' , null ,
2011-04-08 09:59:10 +01:00
// TRANS: Form instructions.
2010-11-01 23:50:45 +00:00
_m ( 'If you already have an account, login with your username and password to connect it to your Facebook.' ));
$this -> elementStart ( 'ul' , 'form_data' );
$this -> elementStart ( 'li' );
// TRANS: Field label.
$this -> input ( 'nickname' , _m ( 'Existing nickname' ));
$this -> elementEnd ( 'li' );
$this -> elementStart ( 'li' );
2011-04-08 09:59:10 +01:00
// TRANS: Field label.
2010-11-01 23:50:45 +00:00
$this -> password ( 'password' , _m ( 'Password' ));
$this -> elementEnd ( 'li' );
$this -> elementEnd ( 'ul' );
2011-04-08 09:59:10 +01:00
// TRANS: Submit button to connect a Facebook account to an existing StatusNet account.
2010-11-01 23:50:45 +00:00
$this -> submit ( 'connect' , _m ( 'BUTTON' , 'Connect' ));
$this -> elementEnd ( 'fieldset' );
$this -> elementEnd ( 'fieldset' );
$this -> elementEnd ( 'form' );
}
function message ( $msg )
{
$this -> message_text = $msg ;
$this -> showPage ();
}
function createNewUser ()
{
2011-01-06 20:15:59 +00:00
if ( ! Event :: handle ( 'StartRegistrationTry' , array ( $this ))) {
return ;
}
2010-11-01 23:50:45 +00:00
if ( common_config ( 'site' , 'closed' )) {
// TRANS: Client error trying to register with registrations not allowed.
$this -> clientError ( _m ( 'Registration not allowed.' ));
}
$invite = null ;
if ( common_config ( 'site' , 'inviteonly' )) {
$code = $_SESSION [ 'invitecode' ];
if ( empty ( $code )) {
// TRANS: Client error trying to register with registrations 'invite only'.
$this -> clientError ( _m ( 'Registration not allowed.' ));
}
2013-08-18 12:04:58 +01:00
$invite = Invitation :: getKV ( $code );
2010-11-01 23:50:45 +00:00
if ( empty ( $invite )) {
// TRANS: Client error trying to register with an invalid invitation code.
$this -> clientError ( _m ( 'Not a valid invitation code.' ));
}
}
2010-11-29 23:11:07 +00:00
try {
2013-10-16 13:58:22 +01:00
$nickname = Nickname :: normalize ( $this -> trimmed ( 'newname' ), true );
2010-11-29 23:11:07 +00:00
} catch ( NicknameException $e ) {
$this -> showForm ( $e -> getMessage ());
2010-11-01 23:50:45 +00:00
return ;
}
$args = array (
2011-09-26 06:32:19 +01:00
'nickname' => $nickname ,
'fullname' => $this -> fbuser -> name ,
'homepage' => $this -> fbuser -> website ,
'location' => $this -> fbuser -> location -> name
2010-11-01 23:50:45 +00:00
);
2010-11-16 02:30:08 +00:00
// It's possible that the email address is already in our
// DB. It's a unique key, so we need to check
2011-09-26 06:32:19 +01:00
if ( $this -> isNewEmail ( $this -> fbuser -> email )) {
$args [ 'email' ] = $this -> fbuser -> email ;
if ( isset ( $this -> fuser -> verified ) && $this -> fuser -> verified == true ) {
$args [ 'email_confirmed' ] = true ;
}
2010-11-16 02:30:08 +00:00
}
2010-11-01 23:50:45 +00:00
if ( ! empty ( $invite )) {
$args [ 'code' ] = $invite -> code ;
}
2010-11-16 02:30:08 +00:00
$user = User :: register ( $args );
2010-11-01 23:50:45 +00:00
$result = $this -> flinkUser ( $user -> id , $this -> fbuid );
if ( ! $result ) {
2011-04-08 09:59:10 +01:00
// TRANS: Server error displayed when connecting to Facebook fails.
2010-11-01 23:50:45 +00:00
$this -> serverError ( _m ( 'Error connecting user to Facebook.' ));
}
2010-11-16 02:30:08 +00:00
// Add a Foreign_user record
Facebookclient :: addFacebookUser ( $this -> fbuser );
2010-11-09 23:14:50 +00:00
$this -> setAvatar ( $user );
2010-11-01 23:50:45 +00:00
common_set_user ( $user );
common_real_login ( true );
common_log (
LOG_INFO ,
sprintf (
2010-11-16 02:30:08 +00:00
'Registered new user %s (%d) from Facebook user %s, (fbuid %d)' ,
$user -> nickname ,
2010-11-01 23:50:45 +00:00
$user -> id ,
2011-09-26 06:32:19 +01:00
$this -> fbuser -> name ,
2010-11-01 23:50:45 +00:00
$this -> fbuid
),
__FILE__
);
2011-01-06 20:15:59 +00:00
Event :: handle ( 'EndRegistrationTry' , array ( $this ));
2010-11-16 02:30:08 +00:00
$this -> goHome ( $user -> nickname );
2010-11-01 23:50:45 +00:00
}
2010-11-09 23:14:50 +00:00
/*
* Attempt to download the user ' s Facebook picture and create a
* StatusNet avatar for the new user .
*/
function setAvatar ( $user )
{
2011-09-27 05:09:47 +01:00
try {
$picUrl = sprintf (
'http://graph.facebook.com/%d/picture?type=large' ,
$this -> fbuser -> id
);
2010-11-09 23:14:50 +00:00
2011-09-27 05:09:47 +01:00
// fetch the picture from Facebook
$client = new HTTPClient ();
2010-11-09 23:14:50 +00:00
2011-09-27 05:09:47 +01:00
// fetch the actual picture
$response = $client -> get ( $picUrl );
2010-11-09 23:14:50 +00:00
2011-09-27 05:09:47 +01:00
if ( $response -> isOk ()) {
2010-11-09 23:14:50 +00:00
2011-09-27 05:09:47 +01:00
// seems to always be jpeg, but not sure
2013-10-21 12:20:30 +01:00
$tmpname = " facebook-avatar-tmp- " . common_random_hexstr ( 4 );
2010-11-09 23:14:50 +00:00
2011-09-27 05:09:47 +01:00
$ok = file_put_contents (
Avatar :: path ( $tmpname ),
$response -> getBody ()
2010-11-09 23:14:50 +00:00
);
2011-09-27 05:09:47 +01:00
if ( ! $ok ) {
common_log ( LOG_WARNING , 'Couldn\'t save tmp Facebook avatar: ' . $tmpname , __FILE__ );
} else {
// save it as an avatar
2011-09-27 05:31:41 +01:00
$file = new ImageFile ( $user -> id , Avatar :: path ( $tmpname ));
$filename = $file -> resize ( 180 ); // size of the biggest img we get from Facebook
2011-09-27 05:09:47 +01:00
$profile = $user -> getProfile ();
2011-09-27 05:31:41 +01:00
if ( $profile -> setOriginal ( $filename )) {
2011-09-27 05:09:47 +01:00
common_log (
LOG_INFO ,
sprintf (
'Saved avatar for %s (%d) from Facebook picture for '
. '%s (fbuid %d), filename = %s' ,
$user -> nickname ,
$user -> id ,
$this -> fbuser -> name ,
$this -> fbuid ,
$filename
),
__FILE__
);
2011-09-27 05:31:41 +01:00
// clean up tmp file
2011-09-27 05:09:47 +01:00
@ unlink ( Avatar :: path ( $tmpname ));
}
2010-11-09 23:14:50 +00:00
}
}
2011-09-27 05:09:47 +01:00
} catch ( Exception $e ) {
common_log ( LOG_WARNING , 'Couldn\'t save Facebook avatar: ' . $e -> getMessage (), __FILE__ );
// error isn't fatal, continue
2010-11-09 23:14:50 +00:00
}
}
2010-11-01 23:50:45 +00:00
function connectNewUser ()
{
$nickname = $this -> trimmed ( 'nickname' );
$password = $this -> trimmed ( 'password' );
if ( ! common_check_user ( $nickname , $password )) {
2011-04-08 09:59:10 +01:00
// TRANS: Form validation error displayed when username/password combination is incorrect.
2010-11-01 23:50:45 +00:00
$this -> showForm ( _m ( 'Invalid username or password.' ));
return ;
}
2013-08-18 12:04:58 +01:00
$user = User :: getKV ( 'nickname' , $nickname );
2010-11-01 23:50:45 +00:00
2010-11-16 02:30:08 +00:00
$this -> tryLinkUser ( $user );
2010-11-01 23:50:45 +00:00
common_set_user ( $user );
common_real_login ( true );
2011-09-27 05:09:47 +01:00
// clear out the stupid cookie
setcookie ( 'fb_access_token' , '' , time () - 3600 ); // one hour ago
2010-11-01 23:50:45 +00:00
$this -> goHome ( $user -> nickname );
}
function connectUser ()
{
$user = common_current_user ();
2010-11-16 02:30:08 +00:00
$this -> tryLinkUser ( $user );
2011-09-27 05:09:47 +01:00
// clear out the stupid cookie
setcookie ( 'fb_access_token' , '' , time () - 3600 ); // one hour ago
2010-11-16 02:30:08 +00:00
common_redirect ( common_local_url ( 'facebookfinishlogin' ), 303 );
}
2010-11-01 23:50:45 +00:00
2010-11-16 02:30:08 +00:00
function tryLinkUser ( $user )
{
2010-11-01 23:50:45 +00:00
$result = $this -> flinkUser ( $user -> id , $this -> fbuid );
if ( empty ( $result )) {
2011-04-08 09:59:10 +01:00
// TRANS: Server error displayed when connecting to Facebook fails.
2010-11-01 23:50:45 +00:00
$this -> serverError ( _m ( 'Error connecting user to Facebook.' ));
}
}
function tryLogin ()
{
2010-11-05 06:34:06 +00:00
$flink = Foreign_link :: getByForeignID ( $this -> fbuid , FACEBOOK_SERVICE );
2010-11-01 23:50:45 +00:00
if ( ! empty ( $flink )) {
$user = $flink -> getUser ();
if ( ! empty ( $user )) {
2010-11-05 06:34:06 +00:00
common_log (
LOG_INFO ,
sprintf (
'Logged in Facebook user %s as user %d (%s)' ,
$this -> fbuid ,
$user -> nickname ,
$user -> id
),
__FILE__
);
2010-11-01 23:50:45 +00:00
common_set_user ( $user );
common_real_login ( true );
2011-09-27 05:09:47 +01:00
// clear out the stupid cookie
setcookie ( 'fb_access_token' , '' , time () - 3600 ); // one hour ago
2010-11-01 23:50:45 +00:00
$this -> goHome ( $user -> nickname );
}
} else {
$this -> showForm ( null , $this -> bestNewNickname ());
}
}
function goHome ( $nickname )
{
$url = common_get_returnto ();
if ( $url ) {
// We don't have to return to it again
common_set_returnto ( null );
} else {
$url = common_local_url ( 'all' ,
array ( 'nickname' =>
$nickname ));
}
common_redirect ( $url , 303 );
}
function flinkUser ( $user_id , $fbuid )
{
$flink = new Foreign_link ();
2010-11-16 02:30:08 +00:00
2011-09-27 05:09:47 +01:00
$flink -> user_id = $user_id ;
$flink -> foreign_id = $fbuid ;
$flink -> service = FACEBOOK_SERVICE ;
2011-09-26 06:32:19 +01:00
$flink -> credentials = $this -> accessToken ;
2011-09-27 05:09:47 +01:00
$flink -> created = common_sql_now ();
2010-11-01 23:50:45 +00:00
$flink_id = $flink -> insert ();
return $flink_id ;
}
function bestNewNickname ()
{
2013-10-16 13:58:22 +01:00
try {
$nickname = Nickname :: normalize ( $this -> fbuser -> username , true );
return $nickname ;
} catch ( NicknameException $e ) {
// Failed to normalize nickname, but let's try the full name
2010-11-01 23:50:45 +00:00
}
2013-10-16 13:58:22 +01:00
try {
$nickname = Nickname :: normalize ( $this -> fbuser -> name , true );
return $nickname ;
} catch ( NicknameException $e ) {
// Any more ideas? Nope.
2010-11-01 23:50:45 +00:00
}
return null ;
}
2010-11-16 02:30:08 +00:00
/*
* Do we already have a user record with this email ?
* ( emails have to be unique but they can change )
*
* @ param string $email the email address to check
*
* @ return boolean result
*/
function isNewEmail ( $email )
{
// we shouldn't have to validate the format
2013-08-18 12:04:58 +01:00
$result = User :: getKV ( 'email' , $email );
2010-11-16 02:30:08 +00:00
if ( empty ( $result )) {
return true ;
}
return false ;
}
2010-11-01 23:50:45 +00:00
}