2008-05-07 18:15:42 +01:00
< ? php
2008-05-20 20:14:12 +01:00
/*
2009-08-25 23:14:12 +01:00
* StatusNet - the distributed open - source microblogging tool
2009-08-25 23:12:20 +01:00
* Copyright ( C ) 2008 , 2009 , StatusNet , Inc .
2008-05-20 20:14:12 +01:00
*
2008-05-14 20:26:48 +01:00
* 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 .
2008-05-20 20:14:12 +01:00
*
2008-05-14 20:26:48 +01:00
* 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 .
2008-05-20 20:14:12 +01:00
*
2008-05-14 20:26:48 +01:00
* 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 />.
*/
2009-08-26 15:41:36 +01:00
if ( ! defined ( 'STATUSNET' ) && ! defined ( 'LACONICA' )) {
2009-03-28 21:42:45 +00:00
exit ( 1 );
}
2008-09-15 07:56:16 +01:00
2008-05-07 18:15:42 +01:00
/**
* Table Definition for user
*/
2009-03-28 21:42:45 +00:00
2008-09-26 17:18:24 +01:00
require_once INSTALLDIR . '/classes/Memcached_DataObject.php' ;
2008-05-20 19:57:56 +01:00
require_once 'Validate.php' ;
2008-05-07 18:15:42 +01:00
2008-12-11 16:34:34 +00:00
class User extends Memcached_DataObject
2008-05-07 18:15:42 +01:00
{
2011-03-28 23:13:59 +01:00
const SUBSCRIBE_POLICY_OPEN = 0 ;
const SUBSCRIBE_POLICY_MODERATE = 1 ;
2008-05-07 18:15:42 +01:00
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'user' ; // table name
public $id ; // int(4) primary_key not_null
2008-05-15 17:28:44 +01:00
public $nickname ; // varchar(64) unique_key
2008-12-11 16:34:34 +00:00
public $password ; // varchar(255)
2008-05-07 18:15:42 +01:00
public $email ; // varchar(255) unique_key
2008-07-17 14:25:33 +01:00
public $incomingemail ; // varchar(255) unique_key
2008-07-15 23:20:26 +01:00
public $emailnotifysub ; // tinyint(1) default_1
2008-09-08 19:16:24 +01:00
public $emailnotifyfav ; // tinyint(1) default_1
2008-11-20 20:54:21 +00:00
public $emailnotifynudge ; // tinyint(1) default_1
2008-09-17 18:47:41 +01:00
public $emailnotifymsg ; // tinyint(1) default_1
2009-02-16 23:24:43 +00:00
public $emailnotifyattn ; // tinyint(1) default_1
2008-07-21 14:56:37 +01:00
public $emailmicroid ; // tinyint(1) default_1
2008-12-11 16:34:34 +00:00
public $language ; // varchar(50)
public $timezone ; // varchar(50)
2008-07-21 14:56:37 +01:00
public $emailpost ; // tinyint(1) default_1
2008-06-22 16:50:28 +01:00
public $sms ; // varchar(64) unique_key
2008-12-11 16:34:34 +00:00
public $carrier ; // int(4)
public $smsnotify ; // tinyint(1)
public $smsreplies ; // tinyint(1)
public $smsemail ; // varchar(255)
2008-05-22 19:41:09 +01:00
public $uri ; // varchar(255) unique_key
2008-12-11 16:34:34 +00:00
public $autosubscribe ; // tinyint(1)
2011-03-28 23:13:59 +01:00
public $subscribe_policy ; // tinyint(1)
2008-11-20 20:54:21 +00:00
public $urlshorteningservice ; // varchar(50) default_ur1.ca
2008-12-11 16:34:34 +00:00
public $inboxed ; // tinyint(1)
2009-05-24 04:26:29 +01:00
public $design_id ; // int(4)
public $viewdesigns ; // tinyint(1) default_1
2011-03-30 13:16:30 +01:00
public $private_stream ; // tinyint(1) default_0
2008-05-07 18:15:42 +01:00
public $created ; // datetime() not_null
public $modified ; // timestamp() not_null default_CURRENT_TIMESTAMP
/* Static get */
2009-05-24 04:26:29 +01:00
function staticGet ( $k , $v = NULL ) { return Memcached_DataObject :: staticGet ( 'User' , $k , $v ); }
2008-05-07 18:15:42 +01:00
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
2008-05-20 20:14:12 +01:00
2011-04-07 21:55:32 +01:00
protected $_profile = - 1 ;
2011-03-21 21:35:29 +00:00
/**
* @ return Profile
*/
2008-12-23 19:33:23 +00:00
function getProfile ()
{
2011-04-09 17:46:52 +01:00
if ( is_int ( $this -> _profile ) && $this -> _profile == - 1 ) { // invalid but distinct from null
2011-04-07 21:55:32 +01:00
$this -> _profile = Profile :: staticGet ( 'id' , $this -> id );
if ( empty ( $this -> _profile )) {
throw new UserNoProfileException ( $this );
}
2010-03-18 13:35:10 +00:00
}
2011-04-07 21:55:32 +01:00
return $this -> _profile ;
2008-12-23 19:19:07 +00:00
}
2008-12-23 19:33:23 +00:00
function isSubscribed ( $other )
{
2010-11-15 23:32:57 +00:00
$profile = $this -> getProfile ();
return $profile -> isSubscribed ( $other );
2008-12-23 19:19:07 +00:00
}
2011-03-29 00:12:51 +01:00
function hasPendingSubscription ( $other )
{
$profile = $this -> getProfile ();
return $profile -> hasPendingSubscription ( $other );
}
2009-11-09 19:01:46 +00:00
// 'update' won't write key columns, so we have to do it ourselves.
2008-12-23 19:19:07 +00:00
2008-12-23 19:33:23 +00:00
function updateKeys ( & $orig )
{
2010-03-18 16:22:08 +00:00
$this -> _connect ();
2008-12-23 19:19:07 +00:00
$parts = array ();
2010-01-23 06:25:27 +00:00
foreach ( array ( 'nickname' , 'email' , 'incomingemail' , 'sms' , 'carrier' , 'smsemail' , 'language' , 'timezone' ) as $k ) {
2008-12-23 19:19:07 +00:00
if ( strcmp ( $this -> $k , $orig -> $k ) != 0 ) {
$parts [] = $k . ' = ' . $this -> _quote ( $this -> $k );
}
}
if ( count ( $parts ) == 0 ) {
2009-03-28 21:42:45 +00:00
// No changes
2008-12-23 19:19:07 +00:00
return true ;
}
$toupdate = implode ( ', ' , $parts );
2009-08-28 09:42:13 +01:00
$table = common_database_tablename ( $this -> tableName ());
2008-12-23 19:19:07 +00:00
$qry = 'UPDATE ' . $table . ' SET ' . $toupdate .
' WHERE id = ' . $this -> id ;
$orig -> decache ();
$result = $this -> query ( $qry );
if ( $result ) {
$this -> encache ();
}
return $result ;
}
2010-11-29 19:57:27 +00:00
/**
* Check whether the given nickname is potentially usable , or if it ' s
* excluded by any blacklists on this system .
*
* WARNING : INPUT IS NOT VALIDATED OR NORMALIZED . NON - NORMALIZED INPUT
* OR INVALID INPUT MAY LEAD TO FALSE RESULTS .
*
* @ param string $nickname
* @ return boolean true if clear , false if blacklisted
*/
2009-11-13 01:12:00 +00:00
static function allowed_nickname ( $nickname )
2008-12-23 19:33:23 +00:00
{
2009-03-28 21:42:45 +00:00
// XXX: should already be validated for size, content, etc.
2009-11-02 20:18:04 +00:00
$blacklist = common_config ( 'nickname' , 'blacklist' );
2009-09-18 22:53:06 +01:00
//all directory and file names should be blacklisted
$d = dir ( INSTALLDIR );
while ( false !== ( $entry = $d -> read ())) {
$blacklist [] = $entry ;
}
$d -> close ();
2009-11-02 20:18:04 +00:00
//all top level names in the router should be blacklisted
$router = Router :: get ();
foreach ( array_keys ( $router -> m -> getPaths ()) as $path ){
if ( preg_match ( '/^\/(.*?)[\/\?]/' , $path , $matches )){
$blacklist [] = $matches [ 1 ];
}
}
return ! in_array ( $nickname , $blacklist );
2008-12-23 19:19:07 +00:00
}
2010-03-11 19:01:01 +00:00
/**
* Get the most recent notice posted by this user , if any .
*
* @ return mixed Notice or null
*/
function getCurrentNotice ()
2008-12-23 19:33:23 +00:00
{
2008-12-23 19:19:07 +00:00
$profile = $this -> getProfile ();
2010-03-11 19:01:01 +00:00
return $profile -> getCurrentNotice ();
2008-12-23 19:19:07 +00:00
}
2008-12-23 19:33:23 +00:00
function getCarrier ()
{
2008-12-23 19:19:07 +00:00
return Sms_carrier :: staticGet ( 'id' , $this -> carrier );
}
2010-03-18 21:26:32 +00:00
/**
* @ deprecated use Subscription :: start ( $sub , $other );
*/
2008-12-23 19:33:23 +00:00
function subscribeTo ( $other )
{
2010-03-18 21:26:32 +00:00
return Subscription :: start ( $this -> getProfile (), $other );
2008-12-23 19:19:07 +00:00
}
2008-07-22 17:15:49 +01:00
2008-12-23 19:33:23 +00:00
function hasBlocked ( $other )
{
2010-02-19 13:16:45 +00:00
$profile = $this -> getProfile ();
return $profile -> hasBlocked ( $other );
2008-12-08 03:10:08 +00:00
}
2009-12-15 23:27:03 +00:00
/**
* Register a new user account and profile and set up default subscriptions .
* If a new - user welcome message is configured , this will be sent .
*
* @ param array $fields associative array of optional properties
* string 'bio'
* string 'email'
* bool 'email_confirmed' pass true to mark email as pre - confirmed
* string 'fullname'
* string 'homepage'
* string 'location' informal string description of geolocation
* float 'lat' decimal latitude for geolocation
* float 'lon' decimal longitude for geolocation
* int 'location_id' geoname identifier
* int 'location_ns' geoname namespace to interpret location_id
* string 'nickname' REQUIRED
* string 'password' ( may be missing for eg OpenID registrations )
* string 'code' invite code
* ? string 'uri' permalink to notice ; defaults to local notice URL
* @ return mixed User object or false on failure
*/
2008-12-23 19:19:07 +00:00
static function register ( $fields ) {
2008-08-14 01:20:38 +01:00
2009-03-28 21:42:45 +00:00
// MAGICALLY put fields into current scope
2008-08-27 01:19:27 +01:00
2008-12-23 19:19:07 +00:00
extract ( $fields );
2008-08-27 01:19:27 +01:00
2008-12-23 19:19:07 +00:00
$profile = new Profile ();
2008-08-14 01:20:38 +01:00
2009-11-13 01:12:00 +00:00
if ( ! empty ( $email ))
{
$email = common_canonical_email ( $email );
}
$nickname = common_canonical_nickname ( $nickname );
2008-12-23 19:19:07 +00:00
$profile -> nickname = $nickname ;
2009-11-13 01:12:00 +00:00
if ( ! User :: allowed_nickname ( $nickname )){
common_log ( LOG_WARNING , sprintf ( " Attempted to register a nickname that is not allowed: %s " , $profile -> nickname ),
2010-01-29 22:54:54 +00:00
__FILE__ );
2010-02-26 20:50:35 +00:00
return false ;
2009-11-13 01:12:00 +00:00
}
2008-12-23 19:19:07 +00:00
$profile -> profileurl = common_profile_url ( $nickname );
2008-08-27 01:19:27 +01:00
2009-02-18 04:22:56 +00:00
if ( ! empty ( $fullname )) {
2008-12-23 19:19:07 +00:00
$profile -> fullname = $fullname ;
}
2009-02-18 04:22:56 +00:00
if ( ! empty ( $homepage )) {
2008-12-23 19:19:07 +00:00
$profile -> homepage = $homepage ;
}
2009-02-18 04:22:56 +00:00
if ( ! empty ( $bio )) {
2008-12-23 19:19:07 +00:00
$profile -> bio = $bio ;
}
2009-02-18 04:22:56 +00:00
if ( ! empty ( $location )) {
2008-12-23 19:19:07 +00:00
$profile -> location = $location ;
2009-10-23 16:46:44 +01:00
$loc = Location :: fromName ( $location );
if ( ! empty ( $loc )) {
$profile -> lat = $loc -> lat ;
$profile -> lon = $loc -> lon ;
$profile -> location_id = $loc -> location_id ;
$profile -> location_ns = $loc -> location_ns ;
}
2008-12-23 19:19:07 +00:00
}
2008-08-27 01:19:27 +01:00
2008-12-23 19:19:07 +00:00
$profile -> created = common_sql_now ();
2008-08-27 01:19:27 +01:00
2008-12-23 19:19:07 +00:00
$user = new User ();
2008-08-27 01:19:27 +01:00
2008-12-23 19:19:07 +00:00
$user -> nickname = $nickname ;
2008-08-27 01:19:27 +01:00
2011-05-23 22:25:00 +01:00
$invite = null ;
2009-03-28 21:42:45 +00:00
// Users who respond to invite email have proven their ownership of that address
2008-12-23 19:19:07 +00:00
2009-02-18 04:22:56 +00:00
if ( ! empty ( $code )) {
2008-12-23 19:19:07 +00:00
$invite = Invitation :: staticGet ( $code );
if ( $invite && $invite -> address && $invite -> address_type == 'email' && $invite -> address == $email ) {
$user -> email = $invite -> address ;
}
}
2009-11-13 01:12:00 +00:00
if ( isset ( $email_confirmed ) && $email_confirmed ) {
$user -> email = $email ;
}
2009-10-13 22:38:27 +01:00
// This flag is ignored but still set to 1
2008-08-27 01:19:27 +01:00
2009-10-13 22:38:27 +01:00
$user -> inboxed = 1 ;
2008-12-23 19:19:07 +00:00
2010-09-21 01:37:21 +01:00
// Set default-on options here, otherwise they'll be disabled
// initially for sites using caching, since the initial encache
// doesn't know about the defaults in the database.
$user -> emailnotifysub = 1 ;
$user -> emailnotifyfav = 1 ;
$user -> emailnotifynudge = 1 ;
$user -> emailnotifymsg = 1 ;
$user -> emailnotifyattn = 1 ;
$user -> emailmicroid = 1 ;
$user -> emailpost = 1 ;
$user -> jabbermicroid = 1 ;
$user -> viewdesigns = 1 ;
2008-12-23 19:19:07 +00:00
$user -> created = common_sql_now ();
2010-01-29 22:54:54 +00:00
if ( Event :: handle ( 'StartUserRegister' , array ( & $user , & $profile ))) {
2009-12-30 19:06:07 +00:00
2010-01-29 22:54:54 +00:00
$profile -> query ( 'BEGIN' );
2009-12-30 19:06:07 +00:00
2010-01-29 22:54:54 +00:00
$id = $profile -> insert ();
2009-12-30 19:06:07 +00:00
2010-01-29 22:54:54 +00:00
if ( empty ( $id )) {
common_log_db_error ( $profile , 'INSERT' , __FILE__ );
return false ;
}
2009-12-30 19:06:07 +00:00
2010-01-29 22:54:54 +00:00
$user -> id = $id ;
2010-09-22 17:08:17 +01:00
if ( ! empty ( $uri )) {
$user -> uri = $uri ;
} else {
$user -> uri = common_user_uri ( $user );
}
2010-02-01 05:47:50 +00:00
if ( ! empty ( $password )) { // may not have a password for OpenID users
$user -> password = common_munge_password ( $password , $id );
}
2009-12-30 19:06:07 +00:00
2010-01-29 22:54:54 +00:00
$result = $user -> insert ();
2008-08-14 01:20:38 +01:00
2010-01-29 22:54:54 +00:00
if ( ! $result ) {
common_log_db_error ( $user , 'INSERT' , __FILE__ );
return false ;
}
2008-08-27 01:19:27 +01:00
2010-01-29 22:54:54 +00:00
// Everyone gets an inbox
2008-12-23 19:19:07 +00:00
2010-01-29 22:54:54 +00:00
$inbox = new Inbox ();
2008-12-23 19:19:07 +00:00
2010-01-29 22:54:54 +00:00
$inbox -> user_id = $user -> id ;
$inbox -> notice_ids = '' ;
2008-12-23 19:19:07 +00:00
2010-01-29 22:54:54 +00:00
$result = $inbox -> insert ();
2008-12-23 19:19:07 +00:00
if ( ! $result ) {
2010-01-29 22:54:54 +00:00
common_log_db_error ( $inbox , 'INSERT' , __FILE__ );
2008-12-23 19:44:28 +00:00
return false ;
2008-12-23 19:19:07 +00:00
}
2010-01-29 22:54:54 +00:00
// Everyone is subscribed to themself
2008-08-27 01:19:27 +01:00
2010-01-29 22:54:54 +00:00
$subscription = new Subscription ();
$subscription -> subscriber = $user -> id ;
$subscription -> subscribed = $user -> id ;
$subscription -> created = $user -> created ;
2009-03-28 21:36:39 +00:00
2010-01-29 22:54:54 +00:00
$result = $subscription -> insert ();
2009-03-28 21:36:39 +00:00
2010-01-29 22:54:54 +00:00
if ( ! $result ) {
common_log_db_error ( $subscription , 'INSERT' , __FILE__ );
return false ;
}
2011-05-23 22:25:00 +01:00
// Mark that this invite was converted
if ( ! empty ( $invite )) {
$invite -> convert ( $user );
}
2010-01-29 22:54:54 +00:00
if ( ! empty ( $email ) && ! $user -> email ) {
$confirm = new Confirm_address ();
$confirm -> code = common_confirmation_code ( 128 );
$confirm -> user_id = $user -> id ;
$confirm -> address = $email ;
$confirm -> address_type = 'email' ;
2009-03-28 21:36:39 +00:00
2010-01-29 22:54:54 +00:00
$result = $confirm -> insert ();
2009-03-28 21:36:39 +00:00
if ( ! $result ) {
2010-01-29 22:54:54 +00:00
common_log_db_error ( $confirm , 'INSERT' , __FILE__ );
2009-03-28 21:36:39 +00:00
return false ;
}
}
2010-01-29 22:54:54 +00:00
if ( ! empty ( $code ) && $user -> email ) {
$user -> emailChanged ();
}
2008-08-27 01:19:27 +01:00
2010-01-29 22:54:54 +00:00
// Default system subscription
2008-08-27 01:19:27 +01:00
2010-01-29 22:54:54 +00:00
$defnick = common_config ( 'newuser' , 'default' );
2008-08-14 01:20:38 +01:00
2010-01-29 22:54:54 +00:00
if ( ! empty ( $defnick )) {
$defuser = User :: staticGet ( 'nickname' , $defnick );
if ( empty ( $defuser )) {
common_log ( LOG_WARNING , sprintf ( " Default user %s does not exist. " , $defnick ),
__FILE__ );
} else {
2010-03-18 21:26:32 +00:00
Subscription :: start ( $user , $defuser );
2010-01-29 22:54:54 +00:00
}
2009-03-28 21:36:39 +00:00
}
2010-01-25 23:08:21 +00:00
2010-01-29 22:54:54 +00:00
$profile -> query ( 'COMMIT' );
if ( ! empty ( $email ) && ! $user -> email ) {
mail_confirm_address ( $user , $confirm -> code , $profile -> nickname , $email );
}
// Welcome message
$welcome = common_config ( 'newuser' , 'welcome' );
if ( ! empty ( $welcome )) {
$welcomeuser = User :: staticGet ( 'nickname' , $welcome );
if ( empty ( $welcomeuser )) {
common_log ( LOG_WARNING , sprintf ( " Welcome user %s does not exist. " , $defnick ),
__FILE__ );
} else {
$notice = Notice :: saveNew ( $welcomeuser -> id ,
2010-07-29 12:36:08 +01:00
// TRANS: Notice given on user registration.
// TRANS: %1$s is the sitename, $2$s is the registering user's nickname.
2010-01-29 22:54:54 +00:00
sprintf ( _ ( 'Welcome to %1$s, @%2$s!' ),
common_config ( 'site' , 'name' ),
$user -> nickname ),
'system' );
}
2009-03-28 21:36:39 +00:00
}
2010-01-29 22:54:54 +00:00
Event :: handle ( 'EndUserRegister' , array ( & $profile , & $user ));
2009-03-28 21:36:39 +00:00
}
2008-12-23 19:19:07 +00:00
return $user ;
}
2008-08-25 19:41:04 +01:00
2009-03-28 21:42:45 +00:00
// Things we do when the email changes
2008-12-23 19:33:23 +00:00
function emailChanged ()
{
2008-08-27 01:19:27 +01:00
2008-12-23 19:19:07 +00:00
$invites = new Invitation ();
$invites -> address = $this -> email ;
$invites -> address_type = 'email' ;
2008-08-27 01:19:27 +01:00
2008-12-23 19:19:07 +00:00
if ( $invites -> find ()) {
while ( $invites -> fetch ()) {
$other = User :: staticGet ( $invites -> user_id );
subs_subscribe_to ( $other , $this );
}
}
}
2008-08-27 01:19:27 +01:00
2008-12-23 19:33:23 +00:00
function hasFave ( $notice )
{
2010-09-27 23:01:03 +01:00
$profile = $this -> getProfile ();
return $profile -> hasFave ( $notice );
2008-12-23 19:19:07 +00:00
}
2009-03-28 21:42:45 +00:00
2008-12-23 19:33:23 +00:00
function mutuallySubscribed ( $other )
{
2010-11-15 23:32:57 +00:00
$profile = $this -> getProfile ();
return $profile -> mutuallySubscribed ( $other );
2008-12-23 19:19:07 +00:00
}
2008-12-11 16:34:34 +00:00
2009-03-28 21:42:45 +00:00
function mutuallySubscribedUsers ()
{
// 3-way join; probably should get cached
$UT = common_config ( 'db' , 'type' ) == 'pgsql' ? '"user"' : 'user' ;
2009-01-26 21:10:32 +00:00
$qry = " SELECT $UT .* " .
" FROM subscription sub1 JOIN $UT ON sub1.subscribed = $UT .id " .
" JOIN subscription sub2 ON $UT .id = sub2.subscriber " .
2008-12-23 19:19:07 +00:00
'WHERE sub1.subscriber = %d and sub2.subscribed = %d ' .
2009-01-26 21:10:32 +00:00
" ORDER BY $UT .nickname " ;
2008-12-23 19:19:07 +00:00
$user = new User ();
$user -> query ( sprintf ( $qry , $this -> id , $this -> id ));
return $user ;
}
2010-03-02 19:54:02 +00:00
function getReplies ( $offset = 0 , $limit = NOTICES_PER_PAGE , $since_id = 0 , $before_id = 0 )
2008-12-23 19:33:23 +00:00
{
2011-03-23 15:29:55 +00:00
return Reply :: stream ( $this -> id , $offset , $limit , $since_id , $before_id );
2008-12-23 19:19:07 +00:00
}
2008-12-11 16:34:34 +00:00
2010-03-02 19:54:02 +00:00
function getTaggedNotices ( $tag , $offset = 0 , $limit = NOTICES_PER_PAGE , $since_id = 0 , $before_id = 0 ) {
2009-05-18 22:18:57 +01:00
$profile = $this -> getProfile ();
2010-03-18 13:35:10 +00:00
return $profile -> getTaggedNotices ( $tag , $offset , $limit , $since_id , $before_id );
2009-05-18 22:18:57 +01:00
}
2010-03-02 19:54:02 +00:00
function getNotices ( $offset = 0 , $limit = NOTICES_PER_PAGE , $since_id = 0 , $before_id = 0 )
2009-03-28 21:42:45 +00:00
{
2008-12-11 16:34:34 +00:00
$profile = $this -> getProfile ();
2010-03-18 13:35:10 +00:00
return $profile -> getNotices ( $offset , $limit , $since_id , $before_id );
2008-12-23 19:19:07 +00:00
}
2008-12-11 16:34:34 +00:00
2010-05-05 22:46:36 +01:00
function favoriteNotices ( $own = false , $offset = 0 , $limit = NOTICES_PER_PAGE , $since_id = 0 , $max_id = 0 )
2009-03-28 21:42:45 +00:00
{
2011-03-23 15:29:55 +00:00
return Fave :: stream ( $this -> id , $offset , $limit , $own , $since_id , $max_id );
2008-12-23 19:19:07 +00:00
}
2008-12-11 16:34:34 +00:00
2011-04-07 19:52:44 +01:00
function noticeInbox ( $offset = 0 , $limit = NOTICES_PER_PAGE , $since_id = 0 , $before_id = 0 )
2009-03-28 21:42:45 +00:00
{
2011-04-07 19:52:44 +01:00
$stream = new InboxNoticeStream ( $this );
return $stream -> getNotices ( $offset , $limit , $since_id , $before_id );
2009-06-18 19:45:48 +01:00
}
2011-04-07 19:52:44 +01:00
// DEPRECATED, use noticeInbox()
function noticesWithFriends ( $offset = 0 , $limit = NOTICES_PER_PAGE , $since_id = 0 , $before_id = 0 )
2011-03-01 23:16:39 +00:00
{
2011-04-07 20:27:40 +01:00
return $this -> noticeInbox ( $offset , $limit , $since_id , $before_id );
2011-03-01 23:16:39 +00:00
}
2011-04-07 19:52:44 +01:00
// DEPRECATED, use noticeInbox()
function noticesWithFriendsThreaded ( $offset = 0 , $limit = NOTICES_PER_PAGE , $since_id = 0 , $before_id = 0 )
2009-06-18 19:45:48 +01:00
{
2011-04-07 20:27:40 +01:00
return $this -> noticeInbox ( $offset , $limit , $since_id , $before_id );
2008-12-23 19:19:07 +00:00
}
2008-12-11 16:34:34 +00:00
2011-04-07 19:52:44 +01:00
// DEPRECATED, use noticeInbox()
2011-03-01 23:16:39 +00:00
function noticeInboxThreaded ( $offset = 0 , $limit = NOTICES_PER_PAGE , $since_id = 0 , $before_id = 0 )
{
2011-04-07 20:27:40 +01:00
return $this -> noticeInbox ( $offset , $limit , $since_id , $before_id );
2011-03-01 23:16:39 +00:00
}
2011-04-07 19:52:44 +01:00
// DEPRECATED, use noticeInbox()
2010-03-02 19:54:02 +00:00
function friendsTimeline ( $offset = 0 , $limit = NOTICES_PER_PAGE , $since_id = 0 , $before_id = 0 )
2009-12-14 21:41:25 +00:00
{
2011-04-07 20:27:40 +01:00
return $this -> noticeInbox ( $offset , $limit , $since_id , $before_id );
2009-12-14 21:41:25 +00:00
}
2011-04-07 19:52:44 +01:00
// DEPRECATED, use noticeInbox()
2010-03-02 19:54:02 +00:00
function ownFriendsTimeline ( $offset = 0 , $limit = NOTICES_PER_PAGE , $since_id = 0 , $before_id = 0 )
2009-12-14 21:41:25 +00:00
{
2011-04-07 19:52:44 +01:00
$this -> noticeInbox ( $offset , $limit , $since_id , $before_id );
2009-12-14 21:41:25 +00:00
}
2009-03-28 21:42:45 +00:00
function blowFavesCache ()
{
2009-07-10 01:28:38 +01:00
$profile = $this -> getProfile ();
2010-09-28 23:46:14 +01:00
$profile -> blowFavesCache ();
2008-12-23 19:19:07 +00:00
}
2008-12-11 16:34:34 +00:00
2009-03-28 21:42:45 +00:00
function getSelfTags ()
{
2011-03-06 17:58:03 +00:00
return Profile_tag :: getTagsArray ( $this -> id , $this -> id , $this -> id );
2008-12-23 19:19:07 +00:00
}
2008-12-11 16:34:34 +00:00
2011-03-06 17:58:03 +00:00
function setSelfTags ( $newtags , $privacy )
2009-03-28 21:42:45 +00:00
{
2011-03-06 17:58:03 +00:00
return Profile_tag :: setTags ( $this -> id , $this -> id , $newtags , $privacy );
2008-12-23 19:19:07 +00:00
}
2008-12-08 18:57:28 +00:00
2008-12-23 19:33:23 +00:00
function block ( $other )
{
2009-03-28 21:42:45 +00:00
// Add a new block record
2008-12-08 18:57:28 +00:00
2009-12-04 01:06:58 +00:00
// no blocking (and thus unsubbing from) yourself
if ( $this -> id == $other -> id ) {
common_log ( LOG_WARNING ,
sprintf (
2010-07-20 03:09:09 +01:00
" Profile ID %d (%s) tried to block themself. " ,
2010-03-31 20:20:16 +01:00
$this -> id ,
$this -> nickname
2009-12-04 01:06:58 +00:00
)
);
return false ;
}
2008-12-08 18:57:28 +00:00
$block = new Profile_block ();
2009-03-28 21:42:45 +00:00
// Begin a transaction
2008-12-08 18:57:28 +00:00
$block -> query ( 'BEGIN' );
$block -> blocker = $this -> id ;
$block -> blocked = $other -> id ;
$result = $block -> insert ();
if ( ! $result ) {
common_log_db_error ( $block , 'INSERT' , __FILE__ );
return false ;
}
2010-04-11 01:52:40 +01:00
$self = $this -> getProfile ();
if ( Subscription :: exists ( $other , $self )) {
Subscription :: cancel ( $other , $self );
}
2010-09-20 23:57:46 +01:00
if ( Subscription :: exists ( $self , $other )) {
Subscription :: cancel ( $self , $other );
}
2008-12-08 18:57:28 +00:00
$block -> query ( 'COMMIT' );
return true ;
}
2008-12-23 19:33:23 +00:00
function unblock ( $other )
{
2009-03-28 21:42:45 +00:00
// Get the block record
2008-12-08 18:57:28 +00:00
2008-12-09 04:16:48 +00:00
$block = Profile_block :: get ( $this -> id , $other -> id );
2008-12-08 18:57:28 +00:00
if ( ! $block ) {
return false ;
}
$result = $block -> delete ();
if ( ! $result ) {
common_log_db_error ( $block , 'DELETE' , __FILE__ );
return false ;
}
return true ;
}
2009-01-21 07:22:10 +00:00
function isMember ( $group )
{
2009-01-21 18:57:18 +00:00
$profile = $this -> getProfile ();
return $profile -> isMember ( $group );
2009-01-21 07:22:10 +00:00
}
function isAdmin ( $group )
{
2009-01-21 18:57:18 +00:00
$profile = $this -> getProfile ();
return $profile -> isAdmin ( $group );
2009-01-21 07:22:10 +00:00
}
2009-01-21 17:19:23 +00:00
2009-01-21 18:00:30 +00:00
function getGroups ( $offset = 0 , $limit = null )
2009-01-21 17:19:23 +00:00
{
2010-03-03 19:00:02 +00:00
$profile = $this -> getProfile ();
return $profile -> getGroups ( $offset , $limit );
2009-01-21 18:00:30 +00:00
}
2011-03-21 21:35:29 +00:00
/**
* Request to join the given group .
* May throw exceptions on failure .
*
* @ param User_group $group
* @ return Group_member
*/
function joinGroup ( User_group $group )
{
$profile = $this -> getProfile ();
return $profile -> joinGroup ( $group );
}
/**
* Leave a group that this user is a member of .
*
* @ param User_group $group
*/
function leaveGroup ( User_group $group )
{
$profile = $this -> getProfile ();
return $profile -> leaveGroup ( $group );
}
2009-01-21 18:00:30 +00:00
function getSubscriptions ( $offset = 0 , $limit = null )
{
2009-06-26 07:00:46 +01:00
$profile = $this -> getProfile ();
return $profile -> getSubscriptions ( $offset , $limit );
2009-01-21 18:00:30 +00:00
}
function getSubscribers ( $offset = 0 , $limit = null )
{
2009-06-26 07:00:46 +01:00
$profile = $this -> getProfile ();
return $profile -> getSubscribers ( $offset , $limit );
2009-01-21 17:19:23 +00:00
}
2009-01-22 22:38:10 +00:00
function getTaggedSubscribers ( $tag , $offset = 0 , $limit = null )
{
$qry =
'SELECT profile.* ' .
'FROM profile JOIN subscription ' .
'ON profile.id = subscription.subscriber ' .
'JOIN profile_tag ON (profile_tag.tagged = subscription.subscriber ' .
'AND profile_tag.tagger = subscription.subscribed) ' .
'WHERE subscription.subscribed = %d ' .
2009-03-05 16:18:31 +00:00
" AND profile_tag.tag = '%s' " .
2009-01-22 22:38:10 +00:00
'AND subscription.subscribed != subscription.subscriber ' .
'ORDER BY subscription.created DESC ' ;
if ( $offset ) {
2009-08-28 09:44:11 +01:00
$qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset ;
2009-01-22 22:38:10 +00:00
}
$profile = new Profile ();
$cnt = $profile -> query ( sprintf ( $qry , $this -> id , $tag ));
return $profile ;
}
function getTaggedSubscriptions ( $tag , $offset = 0 , $limit = null )
{
$qry =
'SELECT profile.* ' .
'FROM profile JOIN subscription ' .
'ON profile.id = subscription.subscribed ' .
'JOIN profile_tag on (profile_tag.tagged = subscription.subscribed ' .
'AND profile_tag.tagger = subscription.subscriber) ' .
'WHERE subscription.subscriber = %d ' .
2009-03-05 16:18:31 +00:00
" AND profile_tag.tag = '%s' " .
2009-01-22 22:38:10 +00:00
'AND subscription.subscribed != subscription.subscriber ' .
'ORDER BY subscription.created DESC ' ;
2009-08-28 09:45:12 +01:00
$qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset ;
2009-01-22 22:38:10 +00:00
$profile = new Profile ();
$profile -> query ( sprintf ( $qry , $this -> id , $tag ));
return $profile ;
}
2009-02-05 16:46:17 +00:00
2009-05-24 04:27:42 +01:00
function getDesign ()
{
return Design :: staticGet ( 'id' , $this -> design_id );
}
2009-08-27 19:38:31 +01:00
2009-09-15 20:28:11 +01:00
function hasRight ( $right )
{
2009-11-16 18:03:59 +00:00
$profile = $this -> getProfile ();
return $profile -> hasRight ( $right );
2009-09-15 20:28:11 +01:00
}
2009-07-26 20:06:38 +01:00
function delete ()
{
2010-03-28 16:58:16 +01:00
try {
$profile = $this -> getProfile ();
$profile -> delete ();
} catch ( UserNoProfileException $unp ) {
common_log ( LOG_INFO , " User { $this -> nickname } has no profile; continuing deletion. " );
}
2009-07-26 20:06:38 +01:00
$related = array ( 'Fave' ,
'Confirm_address' ,
'Remember_me' ,
'Foreign_link' ,
'Invitation' ,
);
2010-03-28 16:58:16 +01:00
2009-11-08 13:33:22 +00:00
Event :: handle ( 'UserDeleteRelated' , array ( $this , & $related ));
2009-07-26 20:06:38 +01:00
foreach ( $related as $cls ) {
$inst = new $cls ();
$inst -> user_id = $this -> id ;
$inst -> delete ();
}
$this -> _deleteTags ();
2009-10-02 20:29:57 +01:00
$this -> _deleteBlocks ();
2009-07-26 20:06:38 +01:00
parent :: delete ();
}
function _deleteTags ()
{
$tag = new Profile_tag ();
$tag -> tagger = $this -> id ;
$tag -> delete ();
}
function _deleteBlocks ()
{
$block = new Profile_block ();
$block -> blocker = $this -> id ;
$block -> delete ();
// XXX delete group block? Reset blocker?
}
2009-11-15 14:59:10 +00:00
2009-11-16 14:52:33 +00:00
function hasRole ( $name )
{
$profile = $this -> getProfile ();
return $profile -> hasRole ( $name );
}
function grantRole ( $name )
{
$profile = $this -> getProfile ();
return $profile -> grantRole ( $name );
}
function revokeRole ( $name )
{
$profile = $this -> getProfile ();
return $profile -> revokeRole ( $name );
}
2009-11-15 14:59:10 +00:00
function isSandboxed ()
{
2009-11-16 14:52:33 +00:00
$profile = $this -> getProfile ();
return $profile -> isSandboxed ();
2009-11-15 14:59:10 +00:00
}
function isSilenced ()
{
2009-11-16 14:52:33 +00:00
$profile = $this -> getProfile ();
return $profile -> isSilenced ();
2009-11-15 14:59:10 +00:00
}
2009-12-12 20:35:05 +00:00
function repeatedByMe ( $offset = 0 , $limit = 20 , $since_id = null , $max_id = null )
{
2011-03-24 22:04:19 +00:00
$stream = new RepeatedByMeNoticeStream ( $this );
2011-03-23 15:29:55 +00:00
return $stream -> getNotices ( $offset , $limit , $since_id , $max_id );
2009-12-12 20:35:05 +00:00
}
2009-12-12 21:00:27 +00:00
function repeatsOfMe ( $offset = 0 , $limit = 20 , $since_id = null , $max_id = null )
{
2011-03-24 22:04:19 +00:00
$stream = new RepeatsOfMeNoticeStream ( $this );
2009-12-12 21:00:27 +00:00
2011-03-23 15:29:55 +00:00
return $stream -> getNotices ( $offset , $limit , $since_id , $max_id );
2009-12-12 21:00:27 +00:00
}
2009-12-12 21:15:23 +00:00
function repeatedToMe ( $offset = 0 , $limit = 20 , $since_id = null , $max_id = null )
{
2011-04-10 18:59:55 +01:00
// TRANS: Exception thrown when trying view "repeated to me".
throw new Exception ( _ ( 'Not implemented since inbox change.' ));
2009-12-12 21:15:23 +00:00
}
2009-12-28 22:21:07 +00:00
function shareLocation ()
{
2009-12-28 22:43:34 +00:00
$cfg = common_config ( 'location' , 'share' );
2009-12-28 22:21:07 +00:00
2009-12-28 22:43:34 +00:00
if ( $cfg == 'always' ) {
return true ;
} else if ( $cfg == 'never' ) {
return false ;
} else { // user
$share = true ;
2009-12-28 22:21:07 +00:00
2009-12-28 22:43:34 +00:00
$prefs = User_location_prefs :: staticGet ( 'user_id' , $this -> id );
2009-12-28 22:21:07 +00:00
2009-12-28 22:43:34 +00:00
if ( empty ( $prefs )) {
$share = common_config ( 'location' , 'sharedefault' );
} else {
$share = $prefs -> share_location ;
$prefs -> free ();
}
return $share ;
}
2009-12-28 22:21:07 +00:00
}
2010-01-29 20:15:23 +00:00
static function siteOwner ()
{
$owner = self :: cacheGet ( 'user:site_owner' );
if ( $owner === false ) { // cache miss
$pr = new Profile_role ();
$pr -> role = Profile_role :: OWNER ;
$pr -> orderBy ( 'created' );
2010-02-01 03:55:07 +00:00
$pr -> limit ( 1 );
2010-01-29 20:15:23 +00:00
2010-02-01 03:55:07 +00:00
if ( $pr -> find ( true )) {
2010-01-29 20:15:23 +00:00
$owner = User :: staticGet ( 'id' , $pr -> profile_id );
} else {
$owner = null ;
}
self :: cacheSet ( 'user:site_owner' , $owner );
}
return $owner ;
}
2010-10-20 22:34:25 +01:00
/**
* Pull the primary site account to use in single - user mode .
* If a valid user nickname is listed in 'singleuser' : 'nickname'
* in the config , this will be used ; otherwise the site owner
* account is taken by default .
*
* @ return User
* @ throws ServerException if no valid single user account is present
* @ throws ServerException if called when not in single - user mode
*/
static function singleUser ()
{
if ( common_config ( 'singleuser' , 'enabled' )) {
2010-10-28 15:46:57 +01:00
$user = null ;
2010-10-20 22:34:25 +01:00
$nickname = common_config ( 'singleuser' , 'nickname' );
2010-10-28 15:46:57 +01:00
if ( ! empty ( $nickname )) {
2010-10-20 22:34:25 +01:00
$user = User :: staticGet ( 'nickname' , $nickname );
2010-10-28 15:46:57 +01:00
}
// if there was no nickname or no user by that nickname,
// try the site owner.
if ( empty ( $user )) {
2010-10-20 22:34:25 +01:00
$user = User :: siteOwner ();
}
2010-10-28 15:46:57 +01:00
if ( ! empty ( $user )) {
2010-10-20 22:34:25 +01:00
return $user ;
} else {
2010-10-21 00:12:56 +01:00
// TRANS: Server exception.
throw new ServerException ( _ ( 'No single user defined for single-user mode.' ));
2010-10-20 22:34:25 +01:00
}
} else {
2010-10-21 00:12:56 +01:00
// TRANS: Server exception.
2010-10-20 22:34:25 +01:00
throw new ServerException ( _ ( 'Single-user mode code called when not enabled.' ));
}
}
2010-12-02 18:56:44 +00:00
2010-12-06 20:39:09 +00:00
/**
* This is kind of a hack for using external setup code that ' s trying to
* build single - user sites .
*
* Will still return a username if the config singleuser / nickname is set
* even if the account doesn ' t exist , which normally indicates that the
* site is horribly misconfigured .
*
* At the moment , we need to let it through so that router setup can
* complete , otherwise we won ' t be able to create the account .
*
* This will be easier when we can more easily create the account and
* * then * switch the site to 1 user mode without jumping through hoops .
*
* @ return string
* @ throws ServerException if no valid single user account is present
* @ throws ServerException if called when not in single - user mode
*/
static function singleUserNickname ()
{
try {
$user = User :: singleUser ();
return $user -> nickname ;
} catch ( Exception $e ) {
if ( common_config ( 'singleuser' , 'enabled' ) && common_config ( 'singleuser' , 'nickname' )) {
common_log ( LOG_WARN , " Warning: code attempting to pull single-user nickname when the account does not exist. If this is not setup time, this is probably a bug. " );
return common_config ( 'singleuser' , 'nickname' );
}
throw $e ;
}
}
2010-12-06 20:44:19 +00:00
2010-12-02 18:56:44 +00:00
/**
* Find and shorten links in the given text using this user ' s URL shortening
* settings .
*
* By default , links will be left untouched if the text is shorter than the
* configured maximum notice length . Pass true for the $always parameter
* to force all links to be shortened regardless .
*
* Side effects : may save file and file_redirection records for referenced URLs .
*
* @ param string $text
* @ param boolean $always
* @ return string
*/
public function shortenLinks ( $text , $always = false )
{
return common_shorten_links ( $text , $always , $this );
}
2010-12-13 01:37:42 +00:00
/*
2011-01-19 23:52:18 +00:00
* Get a list of OAuth client applications that have access to this
2010-12-13 01:37:42 +00:00
* user ' s account .
*/
function getConnectedApps ( $offset = 0 , $limit = null )
{
$qry =
'SELECT u.* ' .
'FROM oauth_application_user u, oauth_application a ' .
'WHERE u.profile_id = %d ' .
'AND a.id = u.application_id ' .
'AND u.access_type > 0 ' .
'ORDER BY u.created DESC ' ;
if ( $offset > 0 ) {
if ( common_config ( 'db' , 'type' ) == 'pgsql' ) {
$qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset ;
} else {
$qry .= ' LIMIT ' . $offset . ', ' . $limit ;
}
}
$apps = new Oauth_application_user ();
$cnt = $apps -> query ( sprintf ( $qry , $this -> id ));
return $apps ;
}
2011-04-18 23:23:06 +01:00
/**
* Magic function called at serialize () time .
*
* We use this to drop a couple process - specific references
* from DB_DataObject which can cause trouble in future
* processes .
*
* @ return array of variable names to include in serialization .
*/
function __sleep ()
{
$vars = parent :: __sleep ();
$skip = array ( '_profile' );
return array_diff ( $vars , $skip );
}
2011-06-07 16:22:19 +01:00
static function recoverPassword ( $nore )
{
$user = User :: staticGet ( 'email' , common_canonical_email ( $nore ));
if ( ! $user ) {
try {
$user = User :: staticGet ( 'nickname' , common_canonical_nickname ( $nore ));
} catch ( NicknameException $e ) {
// invalid
}
}
// See if it's an unconfirmed email address
if ( ! $user ) {
// Warning: it may actually be legit to have multiple folks
// who have claimed, but not yet confirmed, the same address.
// We'll only send to the first one that comes up.
$confirm_email = new Confirm_address ();
$confirm_email -> address = common_canonical_email ( $nore );
$confirm_email -> address_type = 'email' ;
$confirm_email -> find ();
if ( $confirm_email -> fetch ()) {
$user = User :: staticGet ( $confirm_email -> user_id );
} else {
$confirm_email = null ;
}
} else {
$confirm_email = null ;
}
if ( ! $user ) {
// TRANS: Information on password recovery form if no known username or e-mail address was specified.
throw new ClientError ( _ ( 'No user with that email address or username.' ));
return ;
}
// Try to get an unconfirmed email address if they used a user name
if ( ! $user -> email && ! $confirm_email ) {
$confirm_email = new Confirm_address ();
$confirm_email -> user_id = $user -> id ;
$confirm_email -> address_type = 'email' ;
$confirm_email -> find ();
if ( ! $confirm_email -> fetch ()) {
$confirm_email = null ;
}
}
if ( ! $user -> email && ! $confirm_email ) {
// TRANS: Client error displayed on password recovery form if a user does not have a registered e-mail address.
throw new ClientException ( _ ( 'No registered email address for that user.' ));
return ;
}
// Success! We have a valid user and a confirmed or unconfirmed email address
$confirm = new Confirm_address ();
$confirm -> code = common_confirmation_code ( 128 );
$confirm -> address_type = 'recover' ;
$confirm -> user_id = $user -> id ;
$confirm -> address = ( ! empty ( $user -> email )) ? $user -> email : $confirm_email -> address ;
if ( ! $confirm -> insert ()) {
common_log_db_error ( $confirm , 'INSERT' , __FILE__ );
// TRANS: Server error displayed if e-mail address confirmation fails in the database on the password recovery form.
throw new ServerException ( _ ( 'Error saving address confirmation.' ));
return ;
}
// @todo FIXME: needs i18n.
$body = " Hey, $user->nickname . " ;
$body .= " \n \n " ;
$body .= 'Someone just asked for a new password ' .
'for this account on ' . common_config ( 'site' , 'name' ) . '.' ;
$body .= " \n \n " ;
$body .= 'If it was you, and you want to confirm, use the URL below:' ;
$body .= " \n \n " ;
$body .= " \t " . common_local_url ( 'recoverpassword' ,
array ( 'code' => $confirm -> code ));
$body .= " \n \n " ;
$body .= 'If not, just ignore this message.' ;
$body .= " \n \n " ;
$body .= 'Thanks for your time, ' ;
$body .= " \n " ;
$body .= common_config ( 'site' , 'name' );
$body .= " \n " ;
$headers = _mail_prepare_headers ( 'recoverpassword' , $user -> nickname , $user -> nickname );
// TRANS: Subject for password recovery e-mail.
mail_to_user ( $user , _ ( 'Password recovery requested' ), $body , $headers , $confirm -> address );
}
2008-05-07 18:15:42 +01:00
}