diff options
Diffstat (limited to 'classes')
-rw-r--r-- | classes/Config.php | 131 | ||||
-rw-r--r-- | classes/Deleted_notice.php | 46 | ||||
-rw-r--r-- | classes/File.php | 55 | ||||
-rw-r--r-- | classes/File_oembed.php | 21 | ||||
-rw-r--r-- | classes/File_redirection.php | 3 | ||||
-rw-r--r-- | classes/Message.php | 51 | ||||
-rw-r--r-- | classes/Notice.php | 187 | ||||
-rw-r--r-- | classes/Profile.php | 21 | ||||
-rw-r--r-- | classes/User.php | 151 | ||||
-rw-r--r-- | classes/User_group.php | 18 | ||||
-rw-r--r-- | classes/User_openid.php | 25 | ||||
-rw-r--r-- | classes/User_role.php | 48 | ||||
-rw-r--r-- | classes/statusnet.ini | 39 |
13 files changed, 584 insertions, 212 deletions
diff --git a/classes/Config.php b/classes/Config.php new file mode 100644 index 000000000..92f237d7f --- /dev/null +++ b/classes/Config.php @@ -0,0 +1,131 @@ +<?php +/* + * Laconica - a distributed open-source microblogging tool + * Copyright (C) 2008, 2009, Control Yourself, Inc. + * + * 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/>. + */ + +if (!defined('STATUSNET')) { + exit(1); +} + +/** + * Table Definition for config + */ + +require_once INSTALLDIR.'/classes/Memcached_DataObject.php'; + +class Config extends Memcached_DataObject +{ + ###START_AUTOCODE + /* the code below is auto generated do not remove the above tag */ + + public $__table = 'config'; // table name + public $section; // varchar(32) primary_key not_null + public $setting; // varchar(32) primary_key not_null + public $value; // varchar(255) + + /* Static get */ + function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Config',$k,$v); } + + /* the code above is auto generated do not remove the tag below */ + ###END_AUTOCODE + + const settingsKey = 'config:settings'; + + static function loadSettings() + { + $settings = self::_getSettings(); + if (!empty($settings)) { + self::_applySettings($settings); + } + } + + static function _getSettings() + { + $c = self::memcache(); + + if (!empty($c)) { + $settings = $c->get(common_cache_key(self::settingsKey)); + if (!empty($settings)) { + return $settings; + } + } + + $settings = array(); + + $config = new Config(); + + $config->find(); + + while ($config->fetch()) { + $settings[] = array($config->section, $config->setting, $config->value); + } + + $config->free(); + + if (!empty($c)) { + $c->set(common_cache_key(self::settingsKey), $settings); + } + + return $settings; + } + + static function _applySettings($settings) + { + global $config; + + foreach ($settings as $s) { + list($section, $setting, $value) = $s; + $config[$section][$setting] = $value; + } + } + + function insert() + { + $result = parent::insert(); + if ($result) { + Config::_blowSettingsCache(); + } + return $result; + } + + function delete() + { + $result = parent::delete(); + if ($result) { + Config::_blowSettingsCache(); + } + return $result; + } + + function update($orig=null) + { + $result = parent::update($orig); + if ($result) { + Config::_blowSettingsCache(); + } + return $result; + } + + function _blowSettingsCache() + { + $c = self::memcache(); + + if (!empty($c)) { + $c->delete(common_cache_key(self::settingsKey)); + } + } +} diff --git a/classes/Deleted_notice.php b/classes/Deleted_notice.php new file mode 100644 index 000000000..64dc85da6 --- /dev/null +++ b/classes/Deleted_notice.php @@ -0,0 +1,46 @@ +<?php +/* + * Laconica - a distributed open-source microblogging tool + * Copyright (C) 2008, 2009, Control Yourself, Inc. + * + * 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/>. + */ + +if (!defined('STATUSNET')) { + exit(1); +} + +/** + * Table Definition for notice + */ +require_once INSTALLDIR.'/classes/Memcached_DataObject.php'; + +class Deleted_notice extends Memcached_DataObject +{ + ###START_AUTOCODE + /* the code below is auto generated do not remove the above tag */ + + public $__table = 'deleted_notice'; // table name + public $id; // int(4) primary_key not_null + public $profile_id; // int(4) not_null + public $uri; // varchar(255) unique_key + public $created; // datetime() not_null + public $deleted; // datetime() not_null + + /* Static get */ + function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Deleted_notice',$k,$v); } + + /* the code above is auto generated do not remove the tag below */ + ###END_AUTOCODE +} diff --git a/classes/File.php b/classes/File.php index 308d0a771..e04a9d525 100644 --- a/classes/File.php +++ b/classes/File.php @@ -94,7 +94,13 @@ class File extends Memcached_DataObject $file_redir = File_redirection::staticGet('url', $given_url); if (empty($file_redir)) { $redir_data = File_redirection::where($given_url); - $redir_url = $redir_data['url']; + if (is_array($redir_data)) { + $redir_url = $redir_data['url']; + } elseif (is_string($redir_data)) { + $redir_url = $redir_data; + } else { + throw new ServerException("Can't process url '$given_url'"); + } // TODO: max field length if ($redir_url === $given_url || strlen($redir_url) > 255) { $x = File::saveNew($redir_data, $given_url); @@ -197,17 +203,44 @@ class File extends Memcached_DataObject return 'http://'.$server.$path.$filename; } - function isEnclosure(){ - if(isset($this->filename)){ - return true; - } - $notEnclosureMimeTypes = array('text/html','application/xhtml+xml',null); - $mimetype = strtolower($this->mimetype); - $semicolon = strpos($mimetype,';'); - if($semicolon){ - $mimetype = substr($mimetype,0,$semicolon); + function getEnclosure(){ + $enclosure = (object) array(); + $enclosure->title=$this->title; + $enclosure->url=$this->url; + $enclosure->title=$this->title; + $enclosure->date=$this->date; + $enclosure->modified=$this->modified; + $enclosure->size=$this->size; + $enclosure->mimetype=$this->mimetype; + + if(! isset($this->filename)){ + $notEnclosureMimeTypes = array('text/html','application/xhtml+xml'); + $mimetype = strtolower($this->mimetype); + $semicolon = strpos($mimetype,';'); + if($semicolon){ + $mimetype = substr($mimetype,0,$semicolon); + } + if(in_array($mimetype,$notEnclosureMimeTypes)){ + $oembed = File_oembed::staticGet('file_id',$this->id); + if($oembed){ + $mimetype = strtolower($oembed->mimetype); + $semicolon = strpos($mimetype,';'); + if($semicolon){ + $mimetype = substr($mimetype,0,$semicolon); + } + if(in_array($mimetype,$notEnclosureMimeTypes)){ + return false; + }else{ + if($oembed->mimetype) $enclosure->mimetype=$oembed->mimetype; + if($oembed->url) $enclosure->url=$oembed->url; + if($oembed->title) $enclosure->title=$oembed->title; + if($oembed->modified) $enclosure->modified=$oembed->modified; + unset($oembed->size); + } + } + } } - return(! in_array($mimetype,$notEnclosureMimeTypes)); + return $enclosure; } } diff --git a/classes/File_oembed.php b/classes/File_oembed.php index 6be651815..e41ccfd09 100644 --- a/classes/File_oembed.php +++ b/classes/File_oembed.php @@ -20,6 +20,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } require_once INSTALLDIR.'/classes/Memcached_DataObject.php'; +require_once INSTALLDIR.'/classes/File_redirection.php'; /** * Table Definition for file_oembed @@ -34,6 +35,7 @@ class File_oembed extends Memcached_DataObject public $file_id; // int(4) primary_key not_null public $version; // varchar(20) public $type; // varchar(20) + public $mimetype; // varchar(50) public $provider; // varchar(50) public $provider_url; // varchar(255) public $width; // int(4) @@ -93,7 +95,24 @@ class File_oembed extends Memcached_DataObject if (!empty($data->title)) $file_oembed->title = $data->title; if (!empty($data->author_name)) $file_oembed->author_name = $data->author_name; if (!empty($data->author_url)) $file_oembed->author_url = $data->author_url; - if (!empty($data->url)) $file_oembed->url = $data->url; + if (!empty($data->url)){ + $file_oembed->url = $data->url; + $given_url = File_redirection::_canonUrl($file_oembed->url); + if (! empty($given_url)){ + $file = File::staticGet('url', $given_url); + if (empty($file)) { + $file_redir = File_redirection::staticGet('url', $given_url); + if (empty($file_redir)) { + $redir_data = File_redirection::where($given_url); + $file_oembed->mimetype = $redir_data['type']; + } else { + $file_id = $file_redir->file_id; + } + } else { + $file_oembed->mimetype=$file->mimetype; + } + } + } $file_oembed->insert(); if (!empty($data->thumbnail_url)) { File_thumbnail::saveNew($data, $file_id); diff --git a/classes/File_redirection.php b/classes/File_redirection.php index 76b18f672..79052bf7d 100644 --- a/classes/File_redirection.php +++ b/classes/File_redirection.php @@ -79,6 +79,9 @@ class File_redirection extends Memcached_DataObject } } + if(strpos($short_url,'://') === false){ + return $short_url; + } $curlh = File_redirection::_commonCurl($short_url, $redirs); // Don't include body in output curl_setopt($curlh, CURLOPT_NOBODY, true); diff --git a/classes/Message.php b/classes/Message.php index 4806057b4..979e6e87c 100644 --- a/classes/Message.php +++ b/classes/Message.php @@ -4,7 +4,7 @@ */ require_once INSTALLDIR.'/classes/Memcached_DataObject.php'; -class Message extends Memcached_DataObject +class Message extends Memcached_DataObject { ###START_AUTOCODE /* the code below is auto generated do not remove the above tag */ @@ -14,58 +14,73 @@ class Message extends Memcached_DataObject public $uri; // varchar(255) unique_key public $from_profile; // int(4) not_null public $to_profile; // int(4) not_null - public $content; // varchar(140) - public $rendered; // text() - public $url; // varchar(255) + public $content; // text() + public $rendered; // text() + public $url; // varchar(255) public $created; // datetime() not_null public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP - public $source; // varchar(32) + public $source; // varchar(32) /* Static get */ - function staticGet($k,$v=null) - { return Memcached_DataObject::staticGet('Message',$k,$v); } + function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Message',$k,$v); } /* the code above is auto generated do not remove the tag below */ ###END_AUTOCODE - + function getFrom() { return Profile::staticGet('id', $this->from_profile); } - + function getTo() { return Profile::staticGet('id', $this->to_profile); } - + static function saveNew($from, $to, $content, $source) { - + $msg = new Message(); - + $msg->from_profile = $from; $msg->to_profile = $to; $msg->content = common_shorten_links($content); $msg->rendered = common_render_text($content); $msg->created = common_sql_now(); $msg->source = $source; - + $result = $msg->insert(); - + if (!$result) { common_log_db_error($msg, 'INSERT', __FILE__); return _('Could not insert message.'); } - + $orig = clone($msg); $msg->uri = common_local_url('showmessage', array('message' => $msg->id)); - + $result = $msg->update($orig); - + if (!$result) { common_log_db_error($msg, 'UPDATE', __FILE__); return _('Could not update message with new URI.'); } - + return $msg; } + + static function maxContent() + { + $desclimit = common_config('message', 'contentlimit'); + // null => use global limit (distinct from 0!) + if (is_null($desclimit)) { + $desclimit = common_config('site', 'textlimit'); + } + return $desclimit; + } + + static function contentTooLong($content) + { + $contentlimit = self::maxContent(); + return ($contentlimit > 0 && !empty($content) && (mb_strlen($content) > $contentlimit)); + } } diff --git a/classes/Notice.php b/classes/Notice.php index 7d0502626..cd3906ca1 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -1,5 +1,5 @@ <?php -/* +/** * StatusNet - the distributed open-source microblogging tool * Copyright (C) 2008, 2009, StatusNet, Inc. * @@ -15,9 +15,26 @@ * * 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 Notices + * @package StatusNet + * @author Brenda Wallace <shiny@cpan.org> + * @author Christopher Vollick <psycotica0@gmail.com> + * @author CiaranG <ciaran@ciarang.com> + * @author Craig Andrews <candrews@integralblue.com> + * @author Evan Prodromou <evan@controlezvous.ca> + * @author Gina Haeussge <osd@foosel.net> + * @author Jeffery To <jeffery.to@gmail.com> + * @author Mike Cochrane <mikec@mikenz.geek.nz> + * @author Robin Millette <millette@controlyourself.ca> + * @author Sarven Capadisli <csarven@controlyourself.ca> + * @author Tom Adams <tom@holizz.com> + * @license GNU Affero General Public License http://www.gnu.org/licenses/ */ -if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } +if (!defined('STATUSNET') && !defined('LACONICA')) { + exit(1); +} /** * Table Definition for notice @@ -40,7 +57,7 @@ class Notice extends Memcached_DataObject public $id; // int(4) primary_key not_null public $profile_id; // int(4) not_null public $uri; // varchar(255) unique_key - public $content; // varchar(140) + public $content; // text() public $rendered; // text() public $url; // varchar(255) public $created; // datetime() not_null @@ -51,9 +68,7 @@ class Notice extends Memcached_DataObject public $conversation; // int(4) /* Static get */ - function staticGet($k,$v=NULL) { - return Memcached_DataObject::staticGet('Notice',$k,$v); - } + function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Notice',$k,$v); } /* the code above is auto generated do not remove the tag below */ ###END_AUTOCODE @@ -75,17 +90,30 @@ class Notice extends Memcached_DataObject $this->blowFavesCache(true); $this->blowSubsCache(true); + // For auditing purposes, save a record that the notice + // was deleted. + + $deleted = new Deleted_notice(); + + $deleted->id = $this->id; + $deleted->profile_id = $this->profile_id; + $deleted->uri = $this->uri; + $deleted->created = $this->created; + $deleted->deleted = common_sql_now(); + $this->query('BEGIN'); + + $deleted->insert(); + //Null any notices that are replies to this notice $this->query(sprintf("UPDATE notice set reply_to = null WHERE reply_to = %d", $this->id)); $related = array('Reply', 'Fave', 'Notice_tag', 'Group_inbox', - 'Queue_item'); - if (common_config('inboxes', 'enabled')) { - $related[] = 'Notice_inbox'; - } + 'Queue_item', + 'Notice_inbox'); + foreach ($related as $cls) { $inst = new $cls(); $inst->notice_id = $this->id; @@ -140,31 +168,31 @@ class Notice extends Memcached_DataObject $final = common_shorten_links($content); - if (mb_strlen($final) > 140) { - common_log(LOG_INFO, 'Rejecting notice that is too long.'); - return _('Problem saving notice. Too long.'); + if (Notice::contentTooLong($final)) { + throw new ClientException(_('Problem saving notice. Too long.')); } if (!$profile) { - common_log(LOG_ERR, 'Problem saving notice. Unknown user.'); - return _('Problem saving notice. Unknown user.'); + throw new ClientException(_('Problem saving notice. Unknown user.')); } if (common_config('throttle', 'enabled') && !Notice::checkEditThrottle($profile_id)) { common_log(LOG_WARNING, 'Excessive posting by profile #' . $profile_id . '; throttled.'); - return _('Too many notices too fast; take a breather and post again in a few minutes.'); + throw new ClientException(_('Too many notices too fast; take a breather '. + 'and post again in a few minutes.')); } if (common_config('site', 'dupelimit') > 0 && !Notice::checkDupes($profile_id, $final)) { common_log(LOG_WARNING, 'Dupe posting by profile #' . $profile_id . '; throttled.'); - return _('Too many duplicate messages too quickly; take a breather and post again in a few minutes.'); + throw new ClientException(_('Too many duplicate messages too quickly;'. + ' take a breather and post again in a few minutes.')); } - $banned = common_config('profile', 'banned'); + $banned = common_config('profile', 'banned'); if ( in_array($profile_id, $banned) || in_array($profile->nickname, $banned)) { common_log(LOG_WARNING, "Attempted post from banned user: $profile->nickname (user id = $profile_id)."); - return _('You are banned from posting notices on this site.'); + throw new ClientException(_('You are banned from posting notices on this site.')); } $notice = new Notice(); @@ -188,12 +216,12 @@ class Notice extends Memcached_DataObject $notice->created = common_sql_now(); } - $notice->content = $final; - $notice->rendered = common_render_content($final, $notice); - $notice->source = $source; - $notice->uri = $uri; + $notice->content = $final; + $notice->rendered = common_render_content($final, $notice); + $notice->source = $source; + $notice->uri = $uri; - $notice->reply_to = self::getReplyTo($reply_to, $profile_id, $source, $final); + $notice->reply_to = self::getReplyTo($reply_to, $profile_id, $source, $final); if (!empty($notice->reply_to)) { $reply = Notice::staticGet('id', $notice->reply_to); @@ -210,7 +238,7 @@ class Notice extends Memcached_DataObject if (!$id) { common_log_db_error($notice, 'INSERT', __FILE__); - return _('Problem saving notice.'); + throw new ServerException(_('Problem saving notice.')); } // Update ID-dependent columns: URI, conversation @@ -235,7 +263,7 @@ class Notice extends Memcached_DataObject if ($changed) { if (!$notice->update($orig)) { common_log_db_error($notice, 'UPDATE', __FILE__); - return _('Problem saving notice.'); + throw new ServerException(_('Problem saving notice.')); } } @@ -854,66 +882,61 @@ class Notice extends Memcached_DataObject function addToInboxes() { - $enabled = common_config('inboxes', 'enabled'); + // XXX: loads constants - if ($enabled === true || $enabled === 'transitional') { + $inbox = new Notice_inbox(); - // XXX: loads constants + $users = $this->getSubscribedUsers(); - $inbox = new Notice_inbox(); + // FIXME: kind of ignoring 'transitional'... + // we'll probably stop supporting inboxless mode + // in 0.9.x - $users = $this->getSubscribedUsers(); + $ni = array(); - // FIXME: kind of ignoring 'transitional'... - // we'll probably stop supporting inboxless mode - // in 0.9.x + foreach ($users as $id) { + $ni[$id] = NOTICE_INBOX_SOURCE_SUB; + } - $ni = array(); + $groups = $this->saveGroups(); + foreach ($groups as $group) { + $users = $group->getUserMembers(); foreach ($users as $id) { - $ni[$id] = NOTICE_INBOX_SOURCE_SUB; - } - - $groups = $this->saveGroups(); - - foreach ($groups as $group) { - $users = $group->getUserMembers(); - foreach ($users as $id) { - if (!array_key_exists($id, $ni)) { - $ni[$id] = NOTICE_INBOX_SOURCE_GROUP; - } + if (!array_key_exists($id, $ni)) { + $ni[$id] = NOTICE_INBOX_SOURCE_GROUP; } } + } - $cnt = 0; - - $qryhdr = 'INSERT INTO notice_inbox (user_id, notice_id, source, created) VALUES '; - $qry = $qryhdr; + $cnt = 0; - foreach ($ni as $id => $source) { - if ($cnt > 0) { - $qry .= ', '; - } - $qry .= '('.$id.', '.$this->id.', '.$source.", '".$this->created. "') "; - $cnt++; - if (rand() % NOTICE_INBOX_SOFT_LIMIT == 0) { - // FIXME: Causes lag in replicated servers - // Notice_inbox::gc($id); - } - if ($cnt >= MAX_BOXCARS) { - $inbox = new Notice_inbox(); - $inbox->query($qry); - $qry = $qryhdr; - $cnt = 0; - } - } + $qryhdr = 'INSERT INTO notice_inbox (user_id, notice_id, source, created) VALUES '; + $qry = $qryhdr; + foreach ($ni as $id => $source) { if ($cnt > 0) { + $qry .= ', '; + } + $qry .= '('.$id.', '.$this->id.', '.$source.", '".$this->created. "') "; + $cnt++; + if (rand() % NOTICE_INBOX_SOFT_LIMIT == 0) { + // FIXME: Causes lag in replicated servers + // Notice_inbox::gc($id); + } + if ($cnt >= MAX_BOXCARS) { $inbox = new Notice_inbox(); $inbox->query($qry); + $qry = $qryhdr; + $cnt = 0; } } + if ($cnt > 0) { + $inbox = new Notice_inbox(); + $inbox->query($qry); + } + return; } @@ -948,11 +971,6 @@ class Notice extends Memcached_DataObject { $groups = array(); - $enabled = common_config('inboxes', 'enabled'); - if ($enabled !== true && $enabled !== 'transitional') { - return $groups; - } - /* extract all !group */ $count = preg_match_all('/(?:^|\s)!([A-Za-z0-9]{1,64})/', strtolower($this->content), @@ -1181,10 +1199,11 @@ class Notice extends Memcached_DataObject $attachments = $this->attachments(); if($attachments){ foreach($attachments as $attachment){ - if ($attachment->isEnclosure()) { - $attributes = array('rel'=>'enclosure','href'=>$attachment->url,'type'=>$attachment->mimetype,'length'=>$attachment->size); - if($attachment->title){ - $attributes['title']=$attachment->title; + $enclosure=$attachment->getEnclosure(); + if ($enclosure) { + $attributes = array('rel'=>'enclosure','href'=>$enclosure->url,'type'=>$enclosure->mimetype,'length'=>$enclosure->size); + if($enclosure->title){ + $attributes['title']=$enclosure->title; } $xs->element('link', $attributes, null); } @@ -1335,4 +1354,20 @@ class Notice extends Memcached_DataObject return $last->id; } } + + static function maxContent() + { + $contentlimit = common_config('notice', 'contentlimit'); + // null => use global limit (distinct from 0!) + if (is_null($contentlimit)) { + $contentlimit = common_config('site', 'textlimit'); + } + return $contentlimit; + } + + static function contentTooLong($content) + { + $contentlimit = self::maxContent(); + return ($contentlimit > 0 && !empty($content) && (mb_strlen($content) > $contentlimit)); + } } diff --git a/classes/Profile.php b/classes/Profile.php index 8385ebf88..4a069ee84 100644 --- a/classes/Profile.php +++ b/classes/Profile.php @@ -35,14 +35,13 @@ class Profile extends Memcached_DataObject public $fullname; // varchar(255) multiple_key public $profileurl; // varchar(255) public $homepage; // varchar(255) multiple_key - public $bio; // varchar(140) multiple_key + public $bio; // text() multiple_key public $location; // varchar(255) multiple_key public $created; // datetime() not_null public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP /* Static get */ - function staticGet($k,$v=null) - { return Memcached_DataObject::staticGet('Profile',$k,$v); } + function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Profile',$k,$v); } /* the code above is auto generated do not remove the tag below */ ###END_AUTOCODE @@ -462,6 +461,22 @@ class Profile extends Memcached_DataObject } } + static function maxBio() + { + $biolimit = common_config('profile', 'biolimit'); + // null => use global limit (distinct from 0!) + if (is_null($biolimit)) { + $biolimit = common_config('site', 'textlimit'); + } + return $biolimit; + } + + static function bioTooLong($bio) + { + $biolimit = self::maxBio(); + return ($biolimit > 0 && !empty($bio) && (mb_strlen($bio) > $biolimit)); + } + function delete() { $this->_deleteNotices(); diff --git a/classes/User.php b/classes/User.php index 007662131..0a70c9801 100644 --- a/classes/User.php +++ b/classes/User.php @@ -103,10 +103,7 @@ class User extends Memcached_DataObject } $toupdate = implode(', ', $parts); - $table = $this->tableName(); - if(common_config('db','quote_identifiers')) { - $table = '"' . $table . '"'; - } + $table = common_database_tablename($this->tableName()); $qry = 'UPDATE ' . $table . ' SET ' . $toupdate . ' WHERE id = ' . $this->id; $orig->decache(); @@ -230,11 +227,9 @@ class User extends Memcached_DataObject } } - $inboxes = common_config('inboxes', 'enabled'); + // This flag is ignored but still set to 1 - if ($inboxes === true || $inboxes == 'transitional') { - $user->inboxed = 1; - } + $user->inboxed = 1; $user->created = common_sql_now(); $user->uri = common_user_uri($user); @@ -436,55 +431,16 @@ class User extends Memcached_DataObject function noticesWithFriends($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null) { - $enabled = common_config('inboxes', 'enabled'); - - // Complicated code, depending on whether we support inboxes yet - // XXX: make this go away when inboxes become mandatory - - if ($enabled === false || - ($enabled == 'transitional' && $this->inboxed == 0)) { - $qry = - 'SELECT notice.* ' . - 'FROM notice JOIN subscription ON notice.profile_id = subscription.subscribed ' . - 'WHERE subscription.subscriber = %d ' . - 'AND notice.is_local != ' . Notice::GATEWAY; - return Notice::getStream(sprintf($qry, $this->id), - 'user:notices_with_friends:' . $this->id, - $offset, $limit, $since_id, $before_id, - $order, $since); - } else if ($enabled === true || - ($enabled == 'transitional' && $this->inboxed == 1)) { + $ids = Notice_inbox::stream($this->id, $offset, $limit, $since_id, $before_id, $since, false); - $ids = Notice_inbox::stream($this->id, $offset, $limit, $since_id, $before_id, $since, false); - - return Notice::getStreamByIds($ids); - } + return Notice::getStreamByIds($ids); } function noticeInbox($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null) { - $enabled = common_config('inboxes', 'enabled'); + $ids = Notice_inbox::stream($this->id, $offset, $limit, $since_id, $before_id, $since, true); - // Complicated code, depending on whether we support inboxes yet - // XXX: make this go away when inboxes become mandatory - - if ($enabled === false || - ($enabled == 'transitional' && $this->inboxed == 0)) { - $qry = - 'SELECT notice.* ' . - 'FROM notice JOIN subscription ON notice.profile_id = subscription.subscribed ' . - 'WHERE subscription.subscriber = %d '; - return Notice::getStream(sprintf($qry, $this->id), - 'user:notices_with_friends:' . $this->id, - $offset, $limit, $since_id, $before_id, - $order, $since); - } else if ($enabled === true || - ($enabled == 'transitional' && $this->inboxed == 1)) { - - $ids = Notice_inbox::stream($this->id, $offset, $limit, $since_id, $before_id, $since, true); - - return Notice::getStreamByIds($ids); - } + return Notice::getStreamByIds($ids); } function blowFavesCache() @@ -634,11 +590,7 @@ class User extends Memcached_DataObject 'ORDER BY subscription.created DESC '; if ($offset) { - if (common_config('db','type') == 'pgsql') { - $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset; - } else { - $qry .= ' LIMIT ' . $offset . ', ' . $limit; - } + $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset; } $profile = new Profile(); @@ -661,11 +613,7 @@ class User extends Memcached_DataObject 'AND subscription.subscribed != subscription.subscriber ' . 'ORDER BY subscription.created DESC '; - if (common_config('db','type') == 'pgsql') { - $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset; - } else { - $qry .= ' LIMIT ' . $offset . ', ' . $limit; - } + $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset; $profile = new Profile(); @@ -674,20 +622,82 @@ class User extends Memcached_DataObject return $profile; } - function hasOpenID() + function getDesign() { - $oid = new User_openid(); + return Design::staticGet('id', $this->design_id); + } - $oid->user_id = $this->id; + function hasRole($name) + { + $role = User_role::pkeyGet(array('user_id' => $this->id, + 'role' => $name)); + return (!empty($role)); + } - $cnt = $oid->find(); + function grantRole($name) + { + $role = new User_role(); + + $role->user_id = $this->id; + $role->role = $name; + $role->created = common_sql_now(); + + $result = $role->insert(); + + if (!$result) { + common_log_db_error($role, 'INSERT', __FILE__); + return false; + } - return ($cnt > 0); + return true; } - function getDesign() + function revokeRole($name) { - return Design::staticGet('id', $this->design_id); + $role = User_role::pkeyGet(array('user_id' => $this->id, + 'role' => $name)); + + if (empty($role)) { + throw new Exception('Cannot revoke role "'.$name.'" for user #'.$this->id.'; does not exist.'); + } + + $result = $role->delete(); + + if (!$result) { + common_log_db_error($role, 'DELETE', __FILE__); + throw new Exception('Cannot revoke role "'.$name.'" for user #'.$this->id.'; database error.'); + } + + return true; + } + + /** + * Does this user have the right to do X? + * + * With our role-based authorization, this is merely a lookup for whether the user + * has a particular role. The implementation currently uses a switch statement + * to determine if the user has the pre-defined role to exercise the right. Future + * implementations may allow per-site roles, and different mappings of roles to rights. + * + * @param $right string Name of the right, usually a constant in class Right + * @return boolean whether the user has the right in question + */ + + function hasRight($right) + { + $result = false; + if (Event::handle('UserRightsCheck', array($this, $right, &$result))) { + switch ($right) + { + case Right::deleteOthersNotice: + $result = $this->hasRole('moderator'); + break; + default: + $result = false; + break; + } + } + return $result; } function delete() @@ -701,12 +711,9 @@ class User extends Memcached_DataObject 'Remember_me', 'Foreign_link', 'Invitation', + 'Notice_inbox', ); - if (common_config('inboxes', 'enabled')) { - $related[] = 'Notice_inbox'; - } - foreach ($related as $cls) { $inst = new $cls(); $inst->user_id = $this->id; diff --git a/classes/User_group.php b/classes/User_group.php index ea19cbb97..310ecff1e 100644 --- a/classes/User_group.php +++ b/classes/User_group.php @@ -13,7 +13,7 @@ class User_group extends Memcached_DataObject public $nickname; // varchar(64) unique_key public $fullname; // varchar(255) public $homepage; // varchar(255) - public $description; // varchar(140) + public $description; // text() public $location; // varchar(255) public $original_logo; // varchar(255) public $homepage_logo; // varchar(255) @@ -298,6 +298,22 @@ class User_group extends Memcached_DataObject return $ids; } + static function maxDescription() + { + $desclimit = common_config('group', 'desclimit'); + // null => use global limit (distinct from 0!) + if (is_null($desclimit)) { + $desclimit = common_config('site', 'textlimit'); + } + return $desclimit; + } + + static function descriptionTooLong($desc) + { + $desclimit = self::maxDescription(); + return ($desclimit > 0 && !empty($desc) && (mb_strlen($desc) > $desclimit)); + } + function asAtomEntry($namespace=false, $source=false) { $xs = new XMLStringer(true); diff --git a/classes/User_openid.php b/classes/User_openid.php deleted file mode 100644 index f4fda1c72..000000000 --- a/classes/User_openid.php +++ /dev/null @@ -1,25 +0,0 @@ -<?php -/** - * Table Definition for user_openid - */ -require_once INSTALLDIR.'/classes/Memcached_DataObject.php'; - -class User_openid extends Memcached_DataObject -{ - ###START_AUTOCODE - /* the code below is auto generated do not remove the above tag */ - - public $__table = 'user_openid'; // table name - public $canonical; // varchar(255) primary_key not_null - public $display; // varchar(255) unique_key not_null - public $user_id; // int(4) not_null - public $created; // datetime() not_null - public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP - - /* Static get */ - function staticGet($k,$v=null) - { return Memcached_DataObject::staticGet('User_openid',$k,$v); } - - /* the code above is auto generated do not remove the tag below */ - ###END_AUTOCODE -} diff --git a/classes/User_role.php b/classes/User_role.php new file mode 100644 index 000000000..85ecfb422 --- /dev/null +++ b/classes/User_role.php @@ -0,0 +1,48 @@ +<?php +/* + * StatusNet - the distributed open-source microblogging tool + * Copyright (C) 2008, 2009, StatusNet, Inc. + * + * 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/>. + */ + +if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } + +/** + * Table Definition for user_role + */ + +require_once INSTALLDIR.'/classes/Memcached_DataObject.php'; + +class User_role extends Memcached_DataObject +{ + ###START_AUTOCODE + /* the code below is auto generated do not remove the above tag */ + + public $__table = 'user_role'; // table name + public $user_id; // int(4) primary_key not_null + public $role; // varchar(32) primary_key not_null + public $created; // datetime() not_null + + /* Static get */ + function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('User_role',$k,$v); } + + /* the code above is auto generated do not remove the tag below */ + ###END_AUTOCODE + + function &pkeyGet($kv) + { + return Memcached_DataObject::pkeyGet('User_role', $kv); + } +} diff --git a/classes/statusnet.ini b/classes/statusnet.ini index 766bed75d..453981cd6 100644 --- a/classes/statusnet.ini +++ b/classes/statusnet.ini @@ -1,4 +1,3 @@ - [avatar] profile_id = 129 original = 17 @@ -16,6 +15,15 @@ width = K height = K url = U +[config] +section = 130 +setting = 130 +value = 2 + +[config__keys] +section = K +setting = K + [confirm_address] code = 130 user_id = 129 @@ -38,6 +46,17 @@ modified = 384 [consumer__keys] consumer_key = K +[deleted_notice] +id = 129 +profile_id = 129 +uri = 2 +created = 142 +deleted = 142 + +[deleted_notice__keys] +id = K +uri = U + [design] id = 129 backgroundcolor = 1 @@ -78,6 +97,7 @@ id = N file_id = 129 version = 2 type = 2 +mimetype = 2 provider = 2 provider_url = 2 width = 1 @@ -228,7 +248,7 @@ id = 129 uri = 2 from_profile = 129 to_profile = 129 -content = 2 +content = 34 rendered = 34 url = 2 created = 142 @@ -255,7 +275,7 @@ ts = K id = 129 profile_id = 129 uri = 2 -content = 2 +content = 34 rendered = 34 url = 2 created = 142 @@ -303,7 +323,7 @@ nickname = 130 fullname = 2 profileurl = 2 homepage = 2 -bio = 2 +bio = 34 location = 2 created = 142 modified = 384 @@ -475,7 +495,7 @@ id = 129 nickname = 2 fullname = 2 homepage = 2 -description = 2 +description = 34 location = 2 original_logo = 2 homepage_logo = 2 @@ -498,3 +518,12 @@ modified = 384 [user_openid__keys] canonical = K display = U + +[user_role] +user_id = 129 +role = 130 +created = 142 + +[user_role__keys] +user_id = K +role = K |