From 36e5d2b45f9ec240c0cecbb78afcce92e2962a49 Mon Sep 17 00:00:00 2001 From: Eric Helgeson Date: Tue, 4 Aug 2009 22:11:20 -0500 Subject: Added correct null check. Created noisey errors on fresh install. $id is not defined, should be $this->id --- classes/Design.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'classes') diff --git a/classes/Design.php b/classes/Design.php index 43544f1c9..b53096aa2 100644 --- a/classes/Design.php +++ b/classes/Design.php @@ -107,7 +107,7 @@ class Design extends Memcached_DataObject static function toWebColor($color) { - if (is_null($color)) { + if ($color == null) { return null; } @@ -115,7 +115,7 @@ class Design extends Memcached_DataObject return new WebColor($color); } catch (WebColorException $e) { // This shouldn't happen - common_log(LOG_ERR, "Unable to create color for design $id.", + common_log(LOG_ERR, "Unable to create color for design $this->id.", __FILE__); return null; } -- cgit v1.2.3-54-g00ecf From fe507928ae09294d4a59d2f85e83a886f04310c3 Mon Sep 17 00:00:00 2001 From: Adrian Lang Date: Wed, 5 Aug 2009 15:58:18 +0200 Subject: Fix reference to undefined variable in Design::toWebColor. --- classes/Design.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'classes') diff --git a/classes/Design.php b/classes/Design.php index 43544f1c9..5d8364be5 100644 --- a/classes/Design.php +++ b/classes/Design.php @@ -115,7 +115,7 @@ class Design extends Memcached_DataObject return new WebColor($color); } catch (WebColorException $e) { // This shouldn't happen - common_log(LOG_ERR, "Unable to create color for design $id.", + common_log(LOG_ERR, 'Unable to create color for design '.$this->id, __FILE__); return null; } -- cgit v1.2.3-54-g00ecf From ecc709001160a81f7f9a98bac63ff4ee25655d8b Mon Sep 17 00:00:00 2001 From: Adrian Lang Date: Wed, 5 Aug 2009 16:05:29 +0200 Subject: Argh, first commit for ages and such a stupid error. Sorry. --- classes/Design.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'classes') diff --git a/classes/Design.php b/classes/Design.php index 5d8364be5..dc1712aff 100644 --- a/classes/Design.php +++ b/classes/Design.php @@ -115,7 +115,7 @@ class Design extends Memcached_DataObject return new WebColor($color); } catch (WebColorException $e) { // This shouldn't happen - common_log(LOG_ERR, 'Unable to create color for design '.$this->id, + common_log(LOG_ERR, "Unable to create web color for $color", __FILE__); return null; } -- cgit v1.2.3-54-g00ecf From 44b2b6424714f82dc199fbe9780843638122e3ad Mon Sep 17 00:00:00 2001 From: Adrian Lang Date: Wed, 5 Aug 2009 16:05:29 +0200 Subject: Argh, first commit for ages and such a stupid error. Sorry. --- classes/Design.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'classes') diff --git a/classes/Design.php b/classes/Design.php index b53096aa2..9354bfcda 100644 --- a/classes/Design.php +++ b/classes/Design.php @@ -115,7 +115,7 @@ class Design extends Memcached_DataObject return new WebColor($color); } catch (WebColorException $e) { // This shouldn't happen - common_log(LOG_ERR, "Unable to create color for design $this->id.", + common_log(LOG_ERR, "Unable to create web color for $color", __FILE__); return null; } -- cgit v1.2.3-54-g00ecf From 11086c78239a30dc47622837a2800d899ebf9b0f Mon Sep 17 00:00:00 2001 From: Craig Andrews Date: Fri, 7 Aug 2009 18:00:04 -0400 Subject: Implemented the list_all and list groups API methods as defined at http://laconi.ca/trac/wiki/ProposedGroupsAPI Made the Autocomplete plugin also autocomplete groups --- actions/api.php | 5 +- actions/twitapigroups.php | 97 +++++++++++++++++++++++++++ classes/User_group.php | 41 ++++++++++++ lib/router.php | 22 +++++++ lib/twitterapi.php | 123 +++++++++++++++++++++++++++++++++++ plugins/Autocomplete/Autocomplete.js | 19 ++++++ 6 files changed, 306 insertions(+), 1 deletion(-) (limited to 'classes') diff --git a/actions/api.php b/actions/api.php index 99ab262ad..6d226af7e 100644 --- a/actions/api.php +++ b/actions/api.php @@ -131,6 +131,8 @@ class ApiAction extends Action 'tags/timeline', 'oembed/oembed', 'groups/show', + 'groups/timeline', + 'groups/list_all', 'groups/timeline'); static $bareauth = array('statuses/user_timeline', @@ -140,7 +142,8 @@ class ApiAction extends Action 'statuses/mentions', 'statuses/followers', 'favorites/favorites', - 'friendships/show'); + 'friendships/show', + 'groups/list_groups'); $fullname = "$this->api_action/$this->api_method"; diff --git a/actions/twitapigroups.php b/actions/twitapigroups.php index 82604ebff..bebc07fa1 100644 --- a/actions/twitapigroups.php +++ b/actions/twitapigroups.php @@ -51,6 +51,103 @@ require_once INSTALLDIR.'/lib/twitterapi.php'; class TwitapigroupsAction extends TwitterapiAction { + function list_groups($args, $apidata) + { + parent::handle($args); + + common_debug("in groups api action"); + + $this->auth_user = $apidata['user']; + $user = $this->get_user($apidata['api_arg'], $apidata); + + if (empty($user)) { + $this->clientError('Not Found', 404, $apidata['content-type']); + return; + } + + $page = (int)$this->arg('page', 1); + $count = (int)$this->arg('count', 20); + $max_id = (int)$this->arg('max_id', 0); + $since_id = (int)$this->arg('since_id', 0); + $since = $this->arg('since'); + $group = $user->getGroups(($page-1)*$count, + $count, $since_id, $max_id, $since); + + $sitename = common_config('site', 'name'); + $title = sprintf(_("%s's groups"), $user->nickname); + $taguribase = common_config('integration', 'taguri'); + $id = "tag:$taguribase:Groups"; + $link = common_root_url(); + $subtitle = sprintf(_("groups %s is a member of on %s"), $user->nickname, $sitename); + + switch($apidata['content-type']) { + case 'xml': + $this->show_xml_groups($group); + break; + case 'rss': + $this->show_rss_groups($group, $title, $link, $subtitle); + break; + case 'atom': + $selfuri = common_root_url() . 'api/laconica/groups/list/' . $user->id . '.atom'; + $this->show_atom_groups($group, $title, $id, $link, + $subtitle, $selfuri); + break; + case 'json': + $this->show_json_groups($group); + break; + default: + $this->clientError(_('API method not found!'), $code = 404); + break; + } + } + + function list_all($args, $apidata) + { + parent::handle($args); + + common_debug("in groups api action"); + + $page = (int)$this->arg('page', 1); + $count = (int)$this->arg('count', 20); + $max_id = (int)$this->arg('max_id', 0); + $since_id = (int)$this->arg('since_id', 0); + $since = $this->arg('since'); + + /* TODO: + Use the $page, $count, $max_id, $since_id, and $since parameters + */ + $group = new User_group(); + $group->orderBy('created DESC'); + $group->find(); + + $sitename = common_config('site', 'name'); + $title = sprintf(_("%s groups"), $sitename); + $taguribase = common_config('integration', 'taguri'); + $id = "tag:$taguribase:Groups"; + $link = common_root_url(); + $subtitle = sprintf(_("groups on %s"), $sitename); + + switch($apidata['content-type']) { + case 'xml': + $this->show_xml_groups($group); + break; + case 'rss': + $this->show_rss_groups($group, $title, $link, $subtitle); + break; + case 'atom': + $selfuri = common_root_url() . 'api/laconica/groups/list_all.atom'; + $this->show_atom_groups($group, $title, $id, $link, + $subtitle, $selfuri); + break; + case 'json': + $this->show_json_groups($group); + break; + default: + $this->clientError(_('API method not found!'), $code = 404); + break; + } + } + function show($args, $apidata) { parent::handle($args); diff --git a/classes/User_group.php b/classes/User_group.php index b1ab1c2d3..ea19cbb97 100644 --- a/classes/User_group.php +++ b/classes/User_group.php @@ -297,4 +297,45 @@ class User_group extends Memcached_DataObject return $ids; } + + function asAtomEntry($namespace=false, $source=false) + { + $xs = new XMLStringer(true); + + if ($namespace) { + $attrs = array('xmlns' => 'http://www.w3.org/2005/Atom', + 'xmlns:thr' => 'http://purl.org/syndication/thread/1.0'); + } else { + $attrs = array(); + } + + $xs->elementStart('entry', $attrs); + + if ($source) { + $xs->elementStart('source'); + $xs->element('title', null, $profile->nickname . " - " . common_config('site', 'name')); + $xs->element('link', array('href' => $this->permalink())); + } + + if ($source) { + $xs->elementEnd('source'); + } + + $xs->element('title', null, $this->nickname); + $xs->element('summary', null, $this->description); + + $xs->element('link', array('rel' => 'alternate', + 'href' => $this->permalink())); + + $xs->element('id', null, $this->permalink()); + + $xs->element('published', null, common_date_w3dtf($this->created)); + $xs->element('updated', null, common_date_w3dtf($this->modified)); + + $xs->element('content', array('type' => 'html'), $this->description); + + $xs->elementEnd('entry'); + + return $xs->getString(); + } } diff --git a/lib/router.php b/lib/router.php index 19839b997..9ab46856d 100644 --- a/lib/router.php +++ b/lib/router.php @@ -409,6 +409,28 @@ class Router 'apiaction' => 'laconica')); // Groups + //'list' has to be handled differently, as php will not allow a method to be named 'list' + $m->connect('api/laconica/groups/list/:argument', + array('action' => 'api', + 'method' => 'list_groups', + 'apiaction' => 'groups')); + foreach (array('xml', 'json', 'rss', 'atom') as $e) { + $m->connect('api/laconica/groups/list.' . $e, + array('action' => 'api', + 'method' => 'list_groups.' . $e, + 'apiaction' => 'groups')); + } + + $m->connect('api/laconica/groups/:method', + array('action' => 'api', + 'apiaction' => 'statuses'), + array('method' => '(list_all|)(\.(atom|rss|xml|json))?')); + + $m->connect('api/statuses/:method/:argument', + array('action' => 'api', + 'apiaction' => 'statuses'), + array('method' => '(|user_timeline|friends_timeline|replies|mentions|show|destroy|friends|followers)')); + $m->connect('api/laconica/groups/:method/:argument', array('action' => 'api', 'apiaction' => 'groups')); diff --git a/lib/twitterapi.php b/lib/twitterapi.php index 4737c5874..a5dc2067f 100644 --- a/lib/twitterapi.php +++ b/lib/twitterapi.php @@ -233,6 +233,24 @@ class TwitterapiAction extends Action return $twitter_group; } + function twitter_rss_group_array($group) + { + $entry = array(); + $entry['content']=$group->description; + $entry['title']=$group->nickname; + $entry['link']=$group->permalink(); + $entry['published']=common_date_iso8601($group->created); + $entry['updated']==common_date_iso8601($group->modified); + $taguribase = common_config('integration', 'groupuri'); + $entry['id'] = "group:$groupuribase:$entry[link]"; + + $entry['description'] = $entry['content']; + $entry['pubDate'] = common_date_rfc2822($group->created); + $entry['guid'] = $entry['link']; + + return $entry; + } + function twitter_rss_entry_array($notice) { $profile = $notice->getProfile(); @@ -644,6 +662,65 @@ class TwitterapiAction extends Action } + function show_rss_groups($group, $title, $link, $subtitle) + { + + $this->init_document('rss'); + + $this->elementStart('channel'); + $this->element('title', null, $title); + $this->element('link', null, $link); + $this->element('description', null, $subtitle); + $this->element('language', null, 'en-us'); + $this->element('ttl', null, '40'); + + if (is_array($group)) { + foreach ($group as $g) { + $twitter_group = $this->twitter_rss_group_array($g); + $this->show_twitter_rss_item($twitter_group); + } + } else { + while ($group->fetch()) { + $twitter_group = $this->twitter_rss_group_array($group); + $this->show_twitter_rss_item($twitter_group); + } + } + + $this->elementEnd('channel'); + $this->end_twitter_rss(); + } + + function show_atom_groups($group, $title, $id, $link, $subtitle=null, $selfuri=null) + { + + $this->init_document('atom'); + + $this->element('title', null, $title); + $this->element('id', null, $id); + $this->element('link', array('href' => $link, 'rel' => 'alternate', 'type' => 'text/html'), null); + + if (!is_null($selfuri)) { + $this->element('link', array('href' => $selfuri, + 'rel' => 'self', 'type' => 'application/atom+xml'), null); + } + + $this->element('updated', null, common_date_iso8601('now')); + $this->element('subtitle', null, $subtitle); + + if (is_array($group)) { + foreach ($group as $g) { + $this->raw($g->asAtomEntry()); + } + } else { + while ($group->fetch()) { + $this->raw($group->asAtomEntry()); + } + } + + $this->end_document('atom'); + + } + function show_json_timeline($notice) { @@ -668,6 +745,52 @@ class TwitterapiAction extends Action $this->end_document('json'); } + function show_json_groups($group) + { + + $this->init_document('json'); + + $groups = array(); + + if (is_array($group)) { + foreach ($group as $g) { + $twitter_group = $this->twitter_group_array($g); + array_push($groups, $twitter_group); + } + } else { + while ($group->fetch()) { + $twitter_group = $this->twitter_group_array($group); + array_push($groups, $twitter_group); + } + } + + $this->show_json_objects($groups); + + $this->end_document('json'); + } + + function show_xml_groups($group) + { + + $this->init_document('xml'); + $this->elementStart('groups', array('type' => 'array')); + + if (is_array($group)) { + foreach ($group as $g) { + $twitter_group = $this->twitter_group_array($g); + $this->show_twitter_xml_group($twitter_group); + } + } else { + while ($group->fetch()) { + $twitter_group = $this->twitter_group_array($group); + $this->show_twitter_xml_group($twitter_group); + } + } + + $this->elementEnd('groups'); + $this->end_document('xml'); + } + function show_single_json_group($group) { $this->init_document('json'); diff --git a/plugins/Autocomplete/Autocomplete.js b/plugins/Autocomplete/Autocomplete.js index 759ed60ae..e799c11e5 100644 --- a/plugins/Autocomplete/Autocomplete.js +++ b/plugins/Autocomplete/Autocomplete.js @@ -4,6 +4,7 @@ $(document).ready(function(){ $('#notice_data-text').autocomplete(friends, { multiple: true, multipleSeparator: " ", + minChars: 1, formatItem: function(row, i, max){ return '@' + row.screen_name + ' (' + row.name + ')'; }, @@ -16,4 +17,22 @@ $(document).ready(function(){ }); } ); + $.getJSON($('address .url')[0].href+'/api/laconica/groups/list.json?user_id=' + current_user['id'] + '&callback=?', + function(groups){ + $('#notice_data-text').autocomplete(groups, { + multiple: true, + multipleSeparator: " ", + minChars: 1, + formatItem: function(row, i, max){ + return '!' + row.nickname + ' (' + row.fullname + ')'; + }, + formatMatch: function(row, i, max){ + return '!' + row.nickname; + }, + formatResult: function(row){ + return '!' + row.nickname; + } + }); + } + ); }); -- cgit v1.2.3-54-g00ecf From bbf10e5bdf3ee0dfa372b170da6e25bee859b3c5 Mon Sep 17 00:00:00 2001 From: Adrian Lang Date: Mon, 10 Aug 2009 15:01:00 +0200 Subject: common_config returns false if the config value is not set. Design::toWebColor checks with is_null. Hence the common_config value should be adjusted. --- classes/Design.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'classes') diff --git a/classes/Design.php b/classes/Design.php index 9354bfcda..19c9e0292 100644 --- a/classes/Design.php +++ b/classes/Design.php @@ -204,7 +204,10 @@ class Design extends Memcached_DataObject 'disposition'); foreach ($attrs as $attr) { - $siteDesign->$attr = common_config('design', $attr); + $val = common_config('design', $attr); + if ($val !== false) { + $siteDesign->$attr = $val; + } } } -- cgit v1.2.3-54-g00ecf From 3243612e7636b095cbcea1ceaaba00f964b1d097 Mon Sep 17 00:00:00 2001 From: Brett Taylor Date: Wed, 12 Aug 2009 16:00:46 +1200 Subject: Prevents redirect URLs that have canonical URLs longer than 255 chars from being written to the database as their canonical. Redirecting URLs will instead be saved to the database as given. The reason for this is that table 'file' column 'url' is a VARCHAR(255) in MySQL and it silently truncates URLs longer than 255 characters, breaking the url. The proper fix for this is to improve this column, making its type TEXT, but there are no database changes for 0.8.x, so this is the next best thing for data integrity. A migration script for 0.9.x could be written to audit the database checking for redirects and updating these urls to their proper canonical url. --- classes/File.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'classes') diff --git a/classes/File.php b/classes/File.php index 959301eda..b2c510340 100644 --- a/classes/File.php +++ b/classes/File.php @@ -95,7 +95,8 @@ class File extends Memcached_DataObject if (empty($file_redir)) { $redir_data = File_redirection::where($given_url); $redir_url = $redir_data['url']; - if ($redir_url === $given_url) { + // TODO: max field length + if ($redir_url === $given_url || strlen($redir_url) > 255) { $x = File::saveNew($redir_data, $given_url); $file_id = $x->id; } else { -- cgit v1.2.3-54-g00ecf From c049931dc735d7767c5199d2d2816edb5f0487a2 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Tue, 18 Aug 2009 22:59:14 +0000 Subject: Return null if all columns in the compound primary key aren't specified --- classes/Foreign_link.php | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) (limited to 'classes') diff --git a/classes/Foreign_link.php b/classes/Foreign_link.php index c0b356ece..ae8c22fd8 100644 --- a/classes/Foreign_link.php +++ b/classes/Foreign_link.php @@ -29,34 +29,38 @@ class Foreign_link extends Memcached_DataObject /* the code above is auto generated do not remove the tag below */ ###END_AUTOCODE - // XXX: This only returns a 1->1 single obj mapping. Change? Or make - // a getForeignUsers() that returns more than one? --Zach static function getByUserID($user_id, $service) { + if (empty($user_id) || empty($service)) { + return null; + } + $flink = new Foreign_link(); + $flink->service = $service; $flink->user_id = $user_id; $flink->limit(1); - if ($flink->find(true)) { - return $flink; - } + $result = $flink->find(true); + + return empty($result) ? null : $flink; - return null; } static function getByForeignID($foreign_id, $service) { - $flink = new Foreign_link(); - $flink->service = $service; - $flink->foreign_id = $foreign_id; - $flink->limit(1); + if (empty($foreign_id) || empty($service)) { + return null; + } else { + $flink = new Foreign_link(); + $flink->service = $service; + $flink->foreign_id = $foreign_id; + $flink->limit(1); - if ($flink->find(true)) { - return $flink; - } + $result = $flink->find(true); - return null; + return empty($result) ? null : $flink; + } } function set_flags($noticesend, $noticerecv, $replysync, $friendsync) @@ -66,7 +70,7 @@ class Foreign_link extends Memcached_DataObject } else { $this->noticesync &= ~FOREIGN_NOTICE_SEND; } - + if ($noticerecv) { $this->noticesync |= FOREIGN_NOTICE_RECV; } else { -- cgit v1.2.3-54-g00ecf From 418a5a95ab4831ec905dd849fa2632dec24b96da Mon Sep 17 00:00:00 2001 From: Marcel van der Boom Date: Wed, 19 Aug 2009 08:34:17 +0200 Subject: Change the notice type defines all into class constants and adapt all files. --- actions/shownotice.php | 2 +- classes/Notice.php | 23 ++++++++++++----------- lib/search_engines.php | 2 +- lib/unqueuemanager.php | 4 ++-- lib/util.php | 4 ++-- 5 files changed, 18 insertions(+), 17 deletions(-) (limited to 'classes') diff --git a/actions/shownotice.php b/actions/shownotice.php index 8f2ffd6b9..fb15dddcf 100644 --- a/actions/shownotice.php +++ b/actions/shownotice.php @@ -190,7 +190,7 @@ class ShownoticeAction extends OwnerDesignAction { parent::handle($args); - if ($this->notice->is_local == 0) { + if ($this->notice->is_local == Notice::REMOTE_OMB) { if (!empty($this->notice->url)) { common_redirect($this->notice->url, 301); } else if (!empty($this->notice->uri) && preg_match('/^https?:/', $this->notice->uri)) { diff --git a/classes/Notice.php b/classes/Notice.php index ebd5e1efd..442eb00fd 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -29,10 +29,6 @@ require_once INSTALLDIR.'/classes/Memcached_DataObject.php'; define('NOTICE_CACHE_WINDOW', 61); -define('NOTICE_LOCAL_PUBLIC', 1); -define('NOTICE_REMOTE_OMB', 0); -define('NOTICE_LOCAL_NONPUBLIC', -1); - define('MAX_BOXCARS', 128); class Notice extends Memcached_DataObject @@ -62,7 +58,11 @@ class Notice extends Memcached_DataObject /* the code above is auto generated do not remove the tag below */ ###END_AUTOCODE - const GATEWAY = -2; + /* Notice types */ + const LOCAL_PUBLIC = 1; + const REMOTE_OMB = 0; + const LOCAL_NONPUBLIC = -1; + const GATEWAY = -2; function getProfile() { @@ -134,7 +134,7 @@ class Notice extends Memcached_DataObject } static function saveNew($profile_id, $content, $source=null, - $is_local=1, $reply_to=null, $uri=null, $created=null) { + $is_local=Notice::LOCAL_PUBLIC, $reply_to=null, $uri=null, $created=null) { $profile = Profile::staticGet($profile_id); @@ -177,7 +177,7 @@ class Notice extends Memcached_DataObject if (($blacklist && in_array($profile_id, $blacklist)) || ($source && $autosource && in_array($source, $autosource))) { - $notice->is_local = -1; + $notice->is_local = Notice::LOCAL_NONPUBLIC; } else { $notice->is_local = $is_local; } @@ -509,7 +509,7 @@ class Notice extends Memcached_DataObject function blowPublicCache($blowLast=false) { - if ($this->is_local == 1) { + if ($this->is_local == Notice::LOCAL_PUBLIC) { $cache = common_memcache(); if ($cache) { $cache->delete(common_cache_key('public')); @@ -775,10 +775,11 @@ class Notice extends Memcached_DataObject } if (common_config('public', 'localonly')) { - $notice->whereAdd('is_local = 1'); + $notice->whereAdd('is_local = ' . Notice::LOCAL_PUBLIC); } else { - # -1 == blacklisted - $notice->whereAdd('is_local != -1'); + # -1 == blacklisted, -2 == gateway (i.e. Twitter) + $notice->whereAdd('is_local !='. Notice::LOCAL_NONPUBLIC); + $notice->whereAdd('is_local !='. Notice::GATEWAY); } if ($since_id != 0) { diff --git a/lib/search_engines.php b/lib/search_engines.php index 772f41883..7c26363fc 100644 --- a/lib/search_engines.php +++ b/lib/search_engines.php @@ -120,7 +120,7 @@ class MySQLSearch extends SearchEngine } else if ('identica_notices' === $this->table) { // Don't show imported notices - $this->target->whereAdd('notice.is_local != ' . NOTICE_GATEWAY); + $this->target->whereAdd('notice.is_local != ' . Notice::GATEWAY); if (strtolower($q) != $q) { $this->target->whereAdd("( MATCH(content) AGAINST ('" . addslashes($q) . diff --git a/lib/unqueuemanager.php b/lib/unqueuemanager.php index 515461072..a10ca339a 100644 --- a/lib/unqueuemanager.php +++ b/lib/unqueuemanager.php @@ -79,7 +79,7 @@ class UnQueueManager function _isLocal($notice) { - return ($notice->is_local == NOTICE_LOCAL_PUBLIC || - $notice->is_local == NOTICE_LOCAL_NONPUBLIC); + return ($notice->is_local == Notice::LOCAL_PUBLIC || + $notice->is_local == Notice::LOCAL_NONPUBLIC); } } \ No newline at end of file diff --git a/lib/util.php b/lib/util.php index ba3760678..748c8332f 100644 --- a/lib/util.php +++ b/lib/util.php @@ -854,8 +854,8 @@ function common_enqueue_notice($notice) $transports[] = 'jabber'; } - if ($notice->is_local == NOTICE_LOCAL_PUBLIC || - $notice->is_local == NOTICE_LOCAL_NONPUBLIC) { + if ($notice->is_local == Notice::LOCAL_PUBLIC || + $notice->is_local == Notice::LOCAL_NONPUBLIC) { $transports = array_merge($transports, $localTransports); if ($xmpp) { $transports[] = 'public'; -- cgit v1.2.3-54-g00ecf From d213a8cf90d2c6273b32618ddd2bd1c4c252b332 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 20 Aug 2009 16:56:26 -0400 Subject: update data classes for TEXT content in notice --- classes/Notice.php | 6 ++---- classes/laconica.ini | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'classes') diff --git a/classes/Notice.php b/classes/Notice.php index 9578d87b2..ba74a98a8 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -44,7 +44,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 @@ -55,9 +55,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 diff --git a/classes/laconica.ini b/classes/laconica.ini index f8d4eebd3..4f57ba3da 100755 --- a/classes/laconica.ini +++ b/classes/laconica.ini @@ -266,7 +266,7 @@ ts = K id = 129 profile_id = 129 uri = 2 -content = 2 +content = 34 rendered = 34 url = 2 created = 142 -- cgit v1.2.3-54-g00ecf From 4b443089884a30806aa5a3d00665fbd6296ccd43 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 20 Aug 2009 17:03:49 -0400 Subject: Messages can be >140c in classes --- classes/Message.php | 35 +++++++++++++++++------------------ classes/laconica.ini | 2 +- 2 files changed, 18 insertions(+), 19 deletions(-) (limited to 'classes') diff --git a/classes/Message.php b/classes/Message.php index 4806057b4..71362d9b7 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,57 @@ 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; } } diff --git a/classes/laconica.ini b/classes/laconica.ini index 4f57ba3da..a3ef82b4c 100755 --- a/classes/laconica.ini +++ b/classes/laconica.ini @@ -239,7 +239,7 @@ id = 129 uri = 2 from_profile = 129 to_profile = 129 -content = 2 +content = 34 rendered = 34 url = 2 created = 142 -- cgit v1.2.3-54-g00ecf From fa6b49ab38ab8588c1505f6f0ac7c96d49295e68 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 20 Aug 2009 17:09:04 -0400 Subject: data classes allow >140 bios in profiles --- classes/Profile.php | 5 ++--- classes/laconica.ini | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'classes') diff --git a/classes/Profile.php b/classes/Profile.php index f926b2cef..a34f4cf4b 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 diff --git a/classes/laconica.ini b/classes/laconica.ini index a3ef82b4c..de5979f35 100755 --- a/classes/laconica.ini +++ b/classes/laconica.ini @@ -314,7 +314,7 @@ nickname = 130 fullname = 2 profileurl = 2 homepage = 2 -bio = 2 +bio = 34 location = 2 created = 142 modified = 384 -- cgit v1.2.3-54-g00ecf From 900ca5c50c3ed4311d67c546a3a289b8eaa0ea0e Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 20 Aug 2009 17:12:52 -0400 Subject: data classes allow >140c in user group descriptions --- classes/User_group.php | 2 +- classes/laconica.ini | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'classes') diff --git a/classes/User_group.php b/classes/User_group.php index b1ab1c2d3..7b0daad94 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) diff --git a/classes/laconica.ini b/classes/laconica.ini index de5979f35..c02996b3f 100755 --- a/classes/laconica.ini +++ b/classes/laconica.ini @@ -486,7 +486,7 @@ id = 129 nickname = 2 fullname = 2 homepage = 2 -description = 2 +description = 34 location = 2 original_logo = 2 homepage_logo = 2 -- cgit v1.2.3-54-g00ecf From cd688acceb131312e10a219700ba21d4a3566695 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Fri, 21 Aug 2009 06:13:41 -0400 Subject: allow configurable length for user group description --- actions/editgroup.php | 4 ++-- actions/newgroup.php | 4 ++-- classes/User_group.php | 15 +++++++++++++++ 3 files changed, 19 insertions(+), 4 deletions(-) (limited to 'classes') diff --git a/actions/editgroup.php b/actions/editgroup.php index 6aa6f8b11..aeeea2b63 100644 --- a/actions/editgroup.php +++ b/actions/editgroup.php @@ -196,8 +196,8 @@ class EditgroupAction extends GroupDesignAction } else if (!is_null($fullname) && mb_strlen($fullname) > 255) { $this->showForm(_('Full name is too long (max 255 chars).')); return; - } else if (!is_null($description) && mb_strlen($description) > 140) { - $this->showForm(_('description is too long (max 140 chars).')); + } else if (User_group::descriptionTooLong($description)) { + $this->showForm(sprintf(_('description is too long (max %d chars).'), User_group::maxDescription())); return; } else if (!is_null($location) && mb_strlen($location) > 255) { $this->showForm(_('Location is too long (max 255 chars).')); diff --git a/actions/newgroup.php b/actions/newgroup.php index 0289e77c2..71647d834 100644 --- a/actions/newgroup.php +++ b/actions/newgroup.php @@ -146,8 +146,8 @@ class NewgroupAction extends Action } else if (!is_null($fullname) && mb_strlen($fullname) > 255) { $this->showForm(_('Full name is too long (max 255 chars).')); return; - } else if (!is_null($description) && mb_strlen($description) > 140) { - $this->showForm(_('description is too long (max 140 chars).')); + } else if (User_group::descriptionTooLong($description)) { + $this->showForm(sprintf(_('description is too long (max %d chars).'), User_group::maxDescription())); return; } else if (!is_null($location) && mb_strlen($location) > 255) { $this->showForm(_('Location is too long (max 255 chars).')); diff --git a/classes/User_group.php b/classes/User_group.php index 7b0daad94..38e0058c1 100644 --- a/classes/User_group.php +++ b/classes/User_group.php @@ -297,4 +297,19 @@ class User_group extends Memcached_DataObject return $ids; } + + static function maxDescription() + { + $desclimit = common_config('group', 'desclimit'); + if (empty($desclimit)) { + $desclimit = common_config('site', 'textlimit'); + } + return $desclimit; + } + + static function descriptionTooLong($desc) + { + $desclimit = self::maxDescription(); + return (!empty($desclimit) && !empty($desc) && (mb_strlen($desc) > $desclimit)); + } } -- cgit v1.2.3-54-g00ecf From 92ef4895b40498d97150a40b2f24fe9604e4c944 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Fri, 21 Aug 2009 06:36:55 -0400 Subject: can set group desc limit to unlimited without resetting global limit --- classes/User_group.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'classes') diff --git a/classes/User_group.php b/classes/User_group.php index 38e0058c1..e6e79ca6a 100644 --- a/classes/User_group.php +++ b/classes/User_group.php @@ -301,7 +301,8 @@ class User_group extends Memcached_DataObject static function maxDescription() { $desclimit = common_config('group', 'desclimit'); - if (empty($desclimit)) { + // null => use global limit (distinct from 0!) + if (is_null($desclimit)) { $desclimit = common_config('site', 'textlimit'); } return $desclimit; @@ -310,6 +311,6 @@ class User_group extends Memcached_DataObject static function descriptionTooLong($desc) { $desclimit = self::maxDescription(); - return (!empty($desclimit) && !empty($desc) && (mb_strlen($desc) > $desclimit)); + return ($desclimit > 0 && !empty($desc) && (mb_strlen($desc) > $desclimit)); } } -- cgit v1.2.3-54-g00ecf From d88839d167e136c5f585e3584b4fee5ba6e5795f Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Fri, 21 Aug 2009 07:20:59 -0400 Subject: methods for Message to check max content length --- classes/Message.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'classes') diff --git a/classes/Message.php b/classes/Message.php index 71362d9b7..979e6e87c 100644 --- a/classes/Message.php +++ b/classes/Message.php @@ -67,4 +67,20 @@ class Message extends Memcached_DataObject 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)); + } } -- cgit v1.2.3-54-g00ecf From d2d3418b8ae6986c14e8eda25779d621443e9e0a Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Fri, 21 Aug 2009 07:40:46 -0400 Subject: Profile class has methods to check bio length --- classes/Profile.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'classes') diff --git a/classes/Profile.php b/classes/Profile.php index a34f4cf4b..ff233666a 100644 --- a/classes/Profile.php +++ b/classes/Profile.php @@ -460,4 +460,20 @@ class Profile extends Memcached_DataObject $c->delete(common_cache_key('profile:notice_count:'.$this->id)); } } + + static function maxBio() + { + $biolimit = common_config('message', '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)); + } } -- cgit v1.2.3-54-g00ecf From 4d3e2daf536c32d46fffb4defac7cbe89bdf3a1c Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Fri, 21 Aug 2009 07:48:14 -0400 Subject: check correct setting in Profile bio length --- classes/Profile.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'classes') diff --git a/classes/Profile.php b/classes/Profile.php index ff233666a..8f92b386e 100644 --- a/classes/Profile.php +++ b/classes/Profile.php @@ -463,7 +463,7 @@ class Profile extends Memcached_DataObject static function maxBio() { - $biolimit = common_config('message', 'biolimit'); + $biolimit = common_config('profile', 'biolimit'); // null => use global limit (distinct from 0!) if (is_null($biolimit)) { $biolimit = common_config('site', 'textlimit'); -- cgit v1.2.3-54-g00ecf From 4d05afae302f1870af369a713ab7ed291c821165 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Fri, 21 Aug 2009 08:05:13 -0400 Subject: Notice class has methods to check content length --- classes/Notice.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'classes') diff --git a/classes/Notice.php b/classes/Notice.php index ba74a98a8..e27f09c2c 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -1352,4 +1352,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)); + } } -- cgit v1.2.3-54-g00ecf From d5825893c8982a9856f0b7a1731c178160237cdf Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Fri, 21 Aug 2009 08:12:57 -0400 Subject: validation code in Notice correctly checks length of content --- classes/Notice.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'classes') diff --git a/classes/Notice.php b/classes/Notice.php index e27f09c2c..2133247b8 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -152,7 +152,7 @@ class Notice extends Memcached_DataObject $final = common_shorten_links($content); - if (mb_strlen($final) > 140) { + if (Notice::contentTooLong($final)) { common_log(LOG_INFO, 'Rejecting notice that is too long.'); return _('Problem saving notice. Too long.'); } -- cgit v1.2.3-54-g00ecf From 888ed474a161a278579debdb492acc44fbcd7790 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Fri, 21 Aug 2009 15:22:02 -0400 Subject: new class for configuration settings --- classes/Config.php | 22 ++++++++++++++++++++++ classes/laconica.ini | 9 +++++++++ 2 files changed, 31 insertions(+) create mode 100755 classes/Config.php (limited to 'classes') diff --git a/classes/Config.php b/classes/Config.php new file mode 100755 index 000000000..2538a1426 --- /dev/null +++ b/classes/Config.php @@ -0,0 +1,22 @@ + Date: Fri, 21 Aug 2009 16:14:32 -0400 Subject: load configuration options from database at runtime --- classes/Config.php | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++- lib/common.php | 40 ++++++++++++-------- 2 files changed, 132 insertions(+), 17 deletions(-) (limited to 'classes') diff --git a/classes/Config.php b/classes/Config.php index 2538a1426..5bec13fdc 100755 --- a/classes/Config.php +++ b/classes/Config.php @@ -1,8 +1,29 @@ . + */ + +if (!defined('LACONICA')) { exit(1); } + /** * Table Definition for config */ -require_once 'classes/Memcached_DataObject.php'; + +require_once INSTALLDIR.'/classes/Memcached_DataObject.php'; class Config extends Memcached_DataObject { @@ -19,4 +40,90 @@ class Config extends Memcached_DataObject /* 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/lib/common.php b/lib/common.php index a9eef13ff..d95622ecd 100644 --- a/lib/common.php +++ b/lib/common.php @@ -21,6 +21,8 @@ if (!defined('LACONICA')) { exit(1); } define('LACONICA_VERSION', '0.9.0dev'); +// XXX: move these to class variables + define('AVATAR_PROFILE_SIZE', 96); define('AVATAR_STREAM_SIZE', 48); define('AVATAR_MINI_SIZE', 24); @@ -369,7 +371,25 @@ if ($_db_name != 'laconica' && !array_key_exists('ini_'.$_db_name, $config['db'] $config['db']['ini_'.$_db_name] = INSTALLDIR.'/classes/laconica.ini'; } +function __autoload($cls) +{ + if (file_exists(INSTALLDIR.'/classes/' . $cls . '.php')) { + require_once(INSTALLDIR.'/classes/' . $cls . '.php'); + } else if (file_exists(INSTALLDIR.'/lib/' . strtolower($cls) . '.php')) { + require_once(INSTALLDIR.'/lib/' . strtolower($cls) . '.php'); + } else if (mb_substr($cls, -6) == 'Action' && + file_exists(INSTALLDIR.'/actions/' . strtolower(mb_substr($cls, 0, -6)) . '.php')) { + require_once(INSTALLDIR.'/actions/' . strtolower(mb_substr($cls, 0, -6)) . '.php'); + } else if ($cls == 'OAuthRequest') { + require_once('OAuth.php'); + } else { + Event::handle('Autoload', array(&$cls)); + } +} + // XXX: how many of these could be auto-loaded on use? +// XXX: note that these files should not use config options +// at compile time since DB config options are not yet loaded. require_once 'Validate.php'; require_once 'markdown.php'; @@ -385,26 +405,14 @@ require_once INSTALLDIR.'/lib/twitter.php'; require_once INSTALLDIR.'/lib/clientexception.php'; require_once INSTALLDIR.'/lib/serverexception.php'; +// Load settings from database; note we need autoload for this + +Config::loadSettings(); + // XXX: other formats here define('NICKNAME_FMT', VALIDATE_NUM.VALIDATE_ALPHA_LOWER); -function __autoload($cls) -{ - if (file_exists(INSTALLDIR.'/classes/' . $cls . '.php')) { - require_once(INSTALLDIR.'/classes/' . $cls . '.php'); - } else if (file_exists(INSTALLDIR.'/lib/' . strtolower($cls) . '.php')) { - require_once(INSTALLDIR.'/lib/' . strtolower($cls) . '.php'); - } else if (mb_substr($cls, -6) == 'Action' && - file_exists(INSTALLDIR.'/actions/' . strtolower(mb_substr($cls, 0, -6)) . '.php')) { - require_once(INSTALLDIR.'/actions/' . strtolower(mb_substr($cls, 0, -6)) . '.php'); - } else if ($cls == 'OAuthRequest') { - require_once('OAuth.php'); - } else { - Event::handle('Autoload', array(&$cls)); - } -} - // Give plugins a chance to initialize in a fully-prepared environment Event::handle('InitializePlugin'); -- cgit v1.2.3-54-g00ecf