forked from GNUsocial/gnu-social
		
	Merge branch '0.8.x' into queuemanager
This commit is contained in:
		
							
								
								
									
										10
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								README
									
									
									
									
									
								
							| @@ -906,6 +906,9 @@ sslserver: use an alternate server name for SSL URLs, like | ||||
|            parameters correctly so that both the SSL server and the | ||||
|            "normal" server can access the session cookie and | ||||
|            preferably other cookies as well. | ||||
| shorturllength: Length of URL at which URLs in a message exceeding 140 | ||||
|                 characters will be sent to the user's chosen | ||||
|                 shortening service. | ||||
|  | ||||
| db | ||||
| -- | ||||
| @@ -1081,6 +1084,13 @@ debug: if turned on, this will make the XMPP library blurt out all of | ||||
| public: an array of JIDs to send _all_ notices to. This is useful for | ||||
| 	participating in third-party search and archiving services. | ||||
|  | ||||
| invite | ||||
| ------ | ||||
|  | ||||
| For configuring invites. | ||||
|  | ||||
| enabled: Whether to allow users to send invites. Default true. | ||||
|  | ||||
| tag | ||||
| --- | ||||
|  | ||||
|   | ||||
| @@ -58,6 +58,11 @@ class Attachment_ajaxAction extends AttachmentAction | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function handle($args) | ||||
|     { | ||||
|         $this->showPage(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Show core. | ||||
|      * | ||||
|   | ||||
| @@ -45,6 +45,12 @@ require_once INSTALLDIR.'/actions/attachment.php'; | ||||
|  | ||||
| class Attachment_thumbnailAction extends AttachmentAction | ||||
| { | ||||
|  | ||||
|     function handle($args) | ||||
|     { | ||||
|         $this->showPage(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Show page, a template method. | ||||
|      * | ||||
| @@ -74,45 +80,5 @@ class Attachment_thumbnailAction extends AttachmentAction | ||||
|         $this->element('img', array('src' => $file_thumbnail->url, 'alt' => 'Thumbnail')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Last-modified date for page | ||||
|      * | ||||
|      * When was the content of this page last modified? Based on notice, | ||||
|      * profile, avatar. | ||||
|      * | ||||
|      * @return int last-modified date as unix timestamp | ||||
|      */ | ||||
| /* | ||||
|     function lastModified() | ||||
|     { | ||||
|         return max(strtotime($this->notice->created), | ||||
|                    strtotime($this->profile->modified), | ||||
|                    ($this->avatar) ? strtotime($this->avatar->modified) : 0); | ||||
|     } | ||||
| */ | ||||
|  | ||||
|     /** | ||||
|      * An entity tag for this page | ||||
|      * | ||||
|      * Shows the ETag for the page, based on the notice ID and timestamps | ||||
|      * for the notice, profile, and avatar. It's weak, since we change | ||||
|      * the date text "one hour ago", etc. | ||||
|      * | ||||
|      * @return string etag | ||||
|      */ | ||||
| /* | ||||
|     function etag() | ||||
|     { | ||||
|         $avtime = ($this->avatar) ? | ||||
|           strtotime($this->avatar->modified) : 0; | ||||
|  | ||||
|         return 'W/"' . implode(':', array($this->arg('action'), | ||||
|                                           common_language(), | ||||
|                                           $this->notice->id, | ||||
|                                           strtotime($this->notice->created), | ||||
|                                           strtotime($this->profile->modified), | ||||
|                                           $avtime)) . '"'; | ||||
|     } | ||||
| */ | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -107,17 +107,11 @@ class ConversationAction extends Action | ||||
|  | ||||
|     function showContent() | ||||
|     { | ||||
|         $offset = ($this->page-1) * NOTICES_PER_PAGE; | ||||
|         $limit  = NOTICES_PER_PAGE + 1; | ||||
|  | ||||
|         $notices = Notice::conversationStream($this->id, $offset, $limit); | ||||
|         $notices = Notice::conversationStream($this->id, 0, null); | ||||
|  | ||||
|         $ct = new ConversationTree($notices, $this); | ||||
|  | ||||
|         $cnt = $ct->show(); | ||||
|  | ||||
|         $this->pagination($this->page > 1, $cnt > NOTICES_PER_PAGE, | ||||
|                           $this->page, 'conversation', array('id' => $this->id)); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -146,8 +140,25 @@ class ConversationTree extends NoticeList | ||||
|  | ||||
|     function show() | ||||
|     { | ||||
|         $cnt = 0; | ||||
|         $cnt = $this->_buildTree(); | ||||
|  | ||||
|         $this->out->elementStart('div', array('id' =>'notices_primary')); | ||||
|         $this->out->element('h2', null, _('Notices')); | ||||
|         $this->out->elementStart('ol', array('class' => 'notices xoxo')); | ||||
|  | ||||
|         if (array_key_exists('root', $this->tree)) { | ||||
|             $rootid = $this->tree['root'][0]; | ||||
|             $this->showNoticePlus($rootid); | ||||
|         } | ||||
|  | ||||
|         $this->out->elementEnd('ol'); | ||||
|         $this->out->elementEnd('div'); | ||||
|  | ||||
|         return $cnt; | ||||
|     } | ||||
|  | ||||
|     function _buildTree() | ||||
|     { | ||||
|         $this->tree  = array(); | ||||
|         $this->table = array(); | ||||
|  | ||||
| @@ -169,18 +180,6 @@ class ConversationTree extends NoticeList | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $this->out->elementStart('div', array('id' =>'notices_primary')); | ||||
|         $this->out->element('h2', null, _('Notices')); | ||||
|         $this->out->elementStart('ol', array('class' => 'notices xoxo')); | ||||
|  | ||||
|         if (array_key_exists('root', $this->tree)) { | ||||
|             $rootid = $this->tree['root'][0]; | ||||
|             $this->showNoticePlus($rootid); | ||||
|         } | ||||
|  | ||||
|         $this->out->elementEnd('ol'); | ||||
|         $this->out->elementEnd('div'); | ||||
|  | ||||
|         return $cnt; | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -75,7 +75,7 @@ class DisfavorAction extends Action | ||||
|             return; | ||||
|         } | ||||
|         $fave            = new Fave(); | ||||
|         $fave->user_id   = $this->id; | ||||
|         $fave->user_id   = $user->id; | ||||
|         $fave->notice_id = $notice->id; | ||||
|         if (!$fave->find(true)) { | ||||
|             $this->clientError(_('This notice is not a favorite!')); | ||||
|   | ||||
| @@ -12,8 +12,6 @@ | ||||
|  * @license  http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 | ||||
|  * @link     http://laconi.ca/ | ||||
|  * | ||||
|  | ||||
| /* | ||||
|  * Laconica - a distributed open-source microblogging tool | ||||
|  * Copyright (C) 2008, 2009, Control Yourself, Inc. | ||||
|  * | ||||
|   | ||||
| @@ -34,19 +34,37 @@ if (!defined('LACONICA')) { | ||||
|  | ||||
| require_once INSTALLDIR . '/lib/designsettings.php'; | ||||
|  | ||||
| /** | ||||
|  * Set a group's design | ||||
|  * | ||||
|  * Saves a design for a given group | ||||
|  * | ||||
|  * @category Settings | ||||
|  * @package  Laconica | ||||
|  * @author   Zach Copley <zach@controlyourself.ca> | ||||
|  * @author   Sarven Capadisli <csarven@controlyourself.ca> | ||||
|  * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 | ||||
|  * @link     http://laconi.ca/ | ||||
|  */ | ||||
|  | ||||
| class GroupDesignSettingsAction extends DesignSettingsAction | ||||
| { | ||||
|     var $group = null; | ||||
|  | ||||
|     /** | ||||
|      * Prepare to run | ||||
|      * Sets the right action for the form, and passes request args into | ||||
|      * the base action | ||||
|      * | ||||
|      * @param array $args misc. arguments | ||||
|      * | ||||
|      * @return boolean true | ||||
|      */ | ||||
|  | ||||
|     function prepare($args) | ||||
|     { | ||||
|         parent::prepare($args); | ||||
|  | ||||
|         if (!common_config('inboxes','enabled')) { | ||||
|         if (!common_config('inboxes', 'enabled')) { | ||||
|             $this->serverError(_('Inboxes must be enabled for groups to work')); | ||||
|             return false; | ||||
|         } | ||||
| @@ -57,7 +75,7 @@ class GroupDesignSettingsAction extends DesignSettingsAction | ||||
|         } | ||||
|  | ||||
|         $nickname_arg = $this->trimmed('nickname'); | ||||
|         $nickname = common_canonical_nickname($nickname_arg); | ||||
|         $nickname     = common_canonical_nickname($nickname_arg); | ||||
|  | ||||
|         // Permanent redirect on non-canonical nickname | ||||
|  | ||||
| @@ -158,7 +176,8 @@ class GroupDesignSettingsAction extends DesignSettingsAction | ||||
|      * @return Design | ||||
|      */ | ||||
|  | ||||
|     function getWorkingDesign() { | ||||
|     function getWorkingDesign() | ||||
|     { | ||||
|  | ||||
|         $design = null; | ||||
|  | ||||
| @@ -273,9 +292,9 @@ class GroupDesignSettingsAction extends DesignSettingsAction | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             $original = clone($this->group); | ||||
|             $original               = clone($this->group); | ||||
|             $this->group->design_id = $id; | ||||
|             $result = $this->group->update($original); | ||||
|             $result                 = $this->group->update($original); | ||||
|  | ||||
|             if (empty($result)) { | ||||
|                 common_log_db_error($original, 'UPDATE', __FILE__); | ||||
|   | ||||
| @@ -167,6 +167,15 @@ class GroupMemberListItem extends ProfileListItem | ||||
|         $this->group = $group; | ||||
|     } | ||||
|  | ||||
|     function showFullName() | ||||
|     { | ||||
|         parent::showFullName(); | ||||
|         if ($this->profile->isAdmin($this->group)) { | ||||
|             $this->out->text(' '); | ||||
|             $this->out->element('span', 'role', _('Admin')); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function showActions() | ||||
|     { | ||||
|         $this->startActions(); | ||||
|   | ||||
| @@ -116,6 +116,7 @@ class groupRssAction extends Rss10Action | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         $notices = array(); | ||||
|         $notice = $group->getNotices(0, ($limit == 0) ? NOTICES_PER_PAGE : $limit); | ||||
|  | ||||
|         while ($notice->fetch()) { | ||||
|   | ||||
| @@ -115,6 +115,7 @@ class GroupsAction extends Action | ||||
|         $groups->orderBy('created DESC'); | ||||
|         $groups->limit($offset, $limit); | ||||
|  | ||||
|         $cnt = 0; | ||||
|         if ($groups->find()) { | ||||
|             $gl = new GroupList($groups, null, $this); | ||||
|             $cnt = $gl->show(); | ||||
|   | ||||
| @@ -35,7 +35,9 @@ class InviteAction extends CurrentUserDesignAction | ||||
|     function handle($args) | ||||
|     { | ||||
|         parent::handle($args); | ||||
|         if (!common_logged_in()) { | ||||
|         if (!common_config('invite', 'enabled')) { | ||||
|             $this->clientError(_('Invites have been disabled.')); | ||||
|         } else if (!common_logged_in()) { | ||||
|             $this->clientError(sprintf(_('You must be logged in to invite other users to use %s'), | ||||
|                                         common_config('site', 'name'))); | ||||
|             return; | ||||
|   | ||||
| @@ -67,11 +67,16 @@ class NoticesearchrssAction extends Rss10Action | ||||
|  | ||||
|         if (!$limit) $limit = 20; | ||||
|         $search_engine->limit(0, $limit, true); | ||||
|         $search_engine->query($q); | ||||
|         $notice->find(); | ||||
|         if (false === $search_engine->query($q)) { | ||||
|             $cnt = 0; | ||||
|         } else { | ||||
|             $cnt = $notice->find(); | ||||
|         } | ||||
|  | ||||
|         while ($notice->fetch()) { | ||||
|             $notices[] = clone($notice); | ||||
|         if ($cnt > 0) { | ||||
|             while ($notice->fetch()) { | ||||
|                 $notices[] = clone($notice); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $notices; | ||||
|   | ||||
| @@ -182,8 +182,10 @@ class PublicAction extends Action | ||||
|             $message .= _('Be the first to post!'); | ||||
|         } | ||||
|         else { | ||||
|             $message .= _('Why not [register an account](%%action.register%%) and be the first to post!'); | ||||
|         } | ||||
|             if (! (common_config('site','closed') || common_config('site','inviteonly'))) { | ||||
|                 $message .= _('Why not [register an account](%%action.register%%) and be the first to post!'); | ||||
|             } | ||||
| 	} | ||||
|  | ||||
|         $this->elementStart('div', 'guide'); | ||||
|         $this->raw(common_markup_to_html($message)); | ||||
|   | ||||
| @@ -45,7 +45,7 @@ require_once INSTALLDIR.'/lib/feedlist.php'; | ||||
|  * @link     http://laconi.ca/ | ||||
|  */ | ||||
|  | ||||
| class ShowfavoritesAction extends CurrentUserDesignAction | ||||
| class ShowfavoritesAction extends OwnerDesignAction | ||||
| { | ||||
|     /** User we're getting the faves of */ | ||||
|     var $user = null; | ||||
|   | ||||
| @@ -331,6 +331,7 @@ class ShowgroupAction extends GroupDesignAction | ||||
|     { | ||||
|         $this->showMembers(); | ||||
|         $this->showStatistics(); | ||||
|         $this->showAdmins(); | ||||
|         $cloud = new GroupTagCloudSection($this, $this->group); | ||||
|         $cloud->show(); | ||||
|     } | ||||
| @@ -369,6 +370,18 @@ class ShowgroupAction extends GroupDesignAction | ||||
|         $this->elementEnd('div'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Show list of admins | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|  | ||||
|     function showAdmins() | ||||
|     { | ||||
|         $adminSection = new GroupAdminSection($this, $this->group); | ||||
|         $adminSection->show(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Show some statistics | ||||
|      * | ||||
| @@ -423,3 +436,34 @@ class ShowgroupAction extends GroupDesignAction | ||||
|         $this->elementEnd('div'); | ||||
|     } | ||||
| } | ||||
|  | ||||
| class GroupAdminSection extends ProfileSection | ||||
| { | ||||
|     var $group; | ||||
|  | ||||
|     function __construct($out, $group) | ||||
|     { | ||||
|         parent::__construct($out); | ||||
|         $this->group = $group; | ||||
|     } | ||||
|  | ||||
|     function getProfiles() | ||||
|     { | ||||
|         return $this->group->getAdmins(); | ||||
|     } | ||||
|  | ||||
|     function title() | ||||
|     { | ||||
|         return _('Admins'); | ||||
|     } | ||||
|  | ||||
|     function divId() | ||||
|     { | ||||
|         return 'group_admins'; | ||||
|     } | ||||
|  | ||||
|     function moreUrl() | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
| } | ||||
| @@ -45,7 +45,7 @@ require_once INSTALLDIR.'/lib/feedlist.php'; | ||||
|  * @link     http://laconi.ca/ | ||||
|  */ | ||||
|  | ||||
| class ShownoticeAction extends Action | ||||
| class ShownoticeAction extends OwnerDesignAction | ||||
| { | ||||
|     /** | ||||
|      * Notice object to show | ||||
| @@ -83,18 +83,25 @@ class ShownoticeAction extends Action | ||||
|  | ||||
|         $this->notice = Notice::staticGet($id); | ||||
|  | ||||
|         if (!$this->notice) { | ||||
|         if (empty($this->notice)) { | ||||
|             $this->clientError(_('No such notice.'), 404); | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         $this->profile = $this->notice->getProfile(); | ||||
|  | ||||
|         if (!$this->profile) { | ||||
|         if (empty($this->profile)) { | ||||
|             $this->serverError(_('Notice has no profile'), 500); | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         $this->user = User::staticGet('id', $this->profile->id); | ||||
|  | ||||
|         if (empty($this->user)) { | ||||
|             $this->serverError(_('Not a local notice'), 500); | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         $this->avatar = $this->profile->getAvatar(AVATAR_PROFILE_SIZE); | ||||
|  | ||||
|         return true; | ||||
| @@ -158,8 +165,14 @@ class ShownoticeAction extends Action | ||||
|  | ||||
|     function title() | ||||
|     { | ||||
|         if (!empty($this->profile->fullname)) { | ||||
|             $base = $this->profile->fullname . ' (' . $this->user->nickname . ') '; | ||||
|         } else { | ||||
|             $base = $this->user->nickname; | ||||
|         } | ||||
|  | ||||
|         return sprintf(_('%1$s\'s status on %2$s'), | ||||
|                        $this->profile->nickname, | ||||
|                        $base, | ||||
|                        common_exact_date($this->notice->created)); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -63,11 +63,13 @@ class SupAction extends Action | ||||
|         # XXX: cache this. Depends on how big this protocol becomes; | ||||
|         # Re-doing this query every 15 seconds isn't the end of the world. | ||||
|  | ||||
|         $divider = common_sql_date(time() - $seconds); | ||||
|  | ||||
|         $notice->query('SELECT profile_id, max(id) AS max_id ' . | ||||
|                        'FROM notice ' . | ||||
|                         ((common_config('db','type') == 'pgsql') ? | ||||
|                        'WHERE extract(epoch from created) > (extract(epoch from now()) - ' . $seconds . ') ' : | ||||
|                        'WHERE created > (now() - ' . $seconds . ') ' ) . | ||||
|                        'WHERE created > "'.$divider.'" ' ) . | ||||
|                        'GROUP BY profile_id'); | ||||
|  | ||||
|         $updates = array(); | ||||
|   | ||||
| @@ -165,24 +165,30 @@ class TwitapisearchatomAction extends TwitterapiAction | ||||
|         $search_engine->set_sort_mode('chron'); | ||||
|         $search_engine->limit(($this->page - 1) * $this->rpp, | ||||
|             $this->rpp + 1, true); | ||||
|         $search_engine->query($q); | ||||
|         $this->cnt = $notice->find(); | ||||
|         if (false === $search_engine->query($q)) { | ||||
|             $this->cnt = 0; | ||||
|         } else { | ||||
|             $this->cnt = $notice->find(); | ||||
|         } | ||||
|  | ||||
|         $cnt = 0; | ||||
|         $this->max_id = 0; | ||||
|  | ||||
|         while ($notice->fetch()) { | ||||
|         if ($this->cnt > 0) { | ||||
|             while ($notice->fetch()) { | ||||
|  | ||||
|             ++$cnt; | ||||
|                 ++$cnt; | ||||
|  | ||||
|             if (!$this->max_id) { | ||||
|                 $this->max_id = $notice->id; | ||||
|                 if (!$this->max_id) { | ||||
|                     $this->max_id = $notice->id; | ||||
|                 } | ||||
|  | ||||
|                 if ($cnt > $this->rpp) { | ||||
|                     break; | ||||
|                 } | ||||
|  | ||||
|                 $notices[] = clone($notice); | ||||
|             } | ||||
|  | ||||
|             if ($cnt > $this->rpp) { | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
|             $notices[] = clone($notice); | ||||
|         } | ||||
|  | ||||
|         return $notices; | ||||
|   | ||||
| @@ -124,8 +124,11 @@ class TwitapisearchjsonAction extends TwitterapiAction | ||||
|         $search_engine = $notice->getSearchEngine('identica_notices'); | ||||
|         $search_engine->set_sort_mode('chron'); | ||||
|         $search_engine->limit(($this->page - 1) * $this->rpp, $this->rpp + 1, true); | ||||
|         $search_engine->query($q); | ||||
|         $cnt = $notice->find(); | ||||
|         if (false === $search_engine->query($q)) { | ||||
|             $cnt = 0; | ||||
|         } else { | ||||
|             $cnt = $notice->find(); | ||||
|         } | ||||
|  | ||||
|         // TODO: since_id, lang, geocode | ||||
|  | ||||
|   | ||||
| @@ -34,8 +34,29 @@ if (!defined('LACONICA')) { | ||||
|  | ||||
| require_once INSTALLDIR . '/lib/designsettings.php'; | ||||
|  | ||||
| /** | ||||
|  * Set a user's design | ||||
|  * | ||||
|  * Saves a design for a given user | ||||
|  * | ||||
|  * @category Settings | ||||
|  * @package  Laconica | ||||
|  * @author   Zach Copley <zach@controlyourself.ca> | ||||
|  * @author   Sarven Capadisli <csarven@controlyourself.ca> | ||||
|  * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 | ||||
|  * @link     http://laconi.ca/ | ||||
|  */ | ||||
|  | ||||
| class UserDesignSettingsAction extends DesignSettingsAction | ||||
| { | ||||
|     /** | ||||
|      * Sets the right action for the form, and passes request args into | ||||
|      * the base action | ||||
|      * | ||||
|      * @param array $args misc. arguments | ||||
|      * | ||||
|      * @return boolean true | ||||
|      */ | ||||
|  | ||||
|     function prepare($args) | ||||
|     { | ||||
| @@ -73,9 +94,10 @@ class UserDesignSettingsAction extends DesignSettingsAction | ||||
|      * @return Design | ||||
|      */ | ||||
|  | ||||
|     function getWorkingDesign() { | ||||
|     function getWorkingDesign() | ||||
|     { | ||||
|  | ||||
|         $user = common_current_user(); | ||||
|         $user   = common_current_user(); | ||||
|         $design = $user->getDesign(); | ||||
|  | ||||
|         if (empty($design)) { | ||||
| @@ -106,14 +128,19 @@ class UserDesignSettingsAction extends DesignSettingsAction | ||||
|  | ||||
|     function saveDesign() | ||||
|     { | ||||
|         try { | ||||
|         foreach ($this->args as $key => $val) { | ||||
|             if (preg_match('/(#ho|ho)Td.*g/i', $val)) { | ||||
|                 $this->sethd(); | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|             $bgcolor = new WebColor($this->trimmed('design_background')); | ||||
|             $ccolor  = new WebColor($this->trimmed('design_content')); | ||||
|             $sbcolor = new WebColor($this->trimmed('design_sidebar')); | ||||
|             $tcolor  = new WebColor($this->trimmed('design_text')); | ||||
|             $lcolor  = new WebColor($this->trimmed('design_links')); | ||||
|  | ||||
|         } catch (WebColorException $e) { | ||||
|             $this->showForm($e->getMessage()); | ||||
|             return; | ||||
| @@ -137,7 +164,7 @@ class UserDesignSettingsAction extends DesignSettingsAction | ||||
|             $tile = true; | ||||
|         } | ||||
|  | ||||
|         $user = common_current_user(); | ||||
|         $user   = common_current_user(); | ||||
|         $design = $user->getDesign(); | ||||
|  | ||||
|         if (!empty($design)) { | ||||
| @@ -184,9 +211,9 @@ class UserDesignSettingsAction extends DesignSettingsAction | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             $original = clone($user); | ||||
|             $original        = clone($user); | ||||
|             $user->design_id = $id; | ||||
|             $result = $user->update($original); | ||||
|             $result          = $user->update($original); | ||||
|  | ||||
|             if (empty($result)) { | ||||
|                 common_log_db_error($original, 'UPDATE', __FILE__); | ||||
| @@ -203,4 +230,56 @@ class UserDesignSettingsAction extends DesignSettingsAction | ||||
|  | ||||
|         $this->showForm(_('Design preferences saved.'), true); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Alternate default colors | ||||
|      * | ||||
|      * @return nothing | ||||
|      */ | ||||
|  | ||||
|     function sethd() | ||||
|     { | ||||
|  | ||||
|         $user   = common_current_user(); | ||||
|         $design = $user->getDesign(); | ||||
|  | ||||
|         $user->query('BEGIN'); | ||||
|  | ||||
|         // alternate colors | ||||
|         $design = new Design(); | ||||
|  | ||||
|         $design->backgroundcolor = 16184329; | ||||
|         $design->contentcolor    = 16059904; | ||||
|         $design->sidebarcolor    = 16059904; | ||||
|         $design->textcolor       = 0; | ||||
|         $design->linkcolor       = 16777215; | ||||
|  | ||||
|         $design->setDisposition(false, true, false); | ||||
|  | ||||
|         $id = $design->insert(); | ||||
|  | ||||
|         if (empty($id)) { | ||||
|             common_log_db_error($id, 'INSERT', __FILE__); | ||||
|             $this->showForm(_('Unable to save your design settings!')); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         $original        = clone($user); | ||||
|         $user->design_id = $id; | ||||
|         $result          = $user->update($original); | ||||
|  | ||||
|         if (empty($result)) { | ||||
|             common_log_db_error($original, 'UPDATE', __FILE__); | ||||
|             $this->showForm(_('Unable to save your design settings!')); | ||||
|             $user->query('ROLLBACK'); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         $user->query('COMMIT'); | ||||
|  | ||||
|         $this->saveBackgroundImage($design); | ||||
|  | ||||
|         $this->showForm(_('Enjoy your hotdog!'), true); | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -795,7 +795,7 @@ class Notice extends Memcached_DataObject | ||||
|         $notice->selectAdd(); // clears it | ||||
|         $notice->selectAdd('id'); | ||||
|  | ||||
|         $notice->whereAdd('conversation = '.$id); | ||||
|         $notice->conversation = $id; | ||||
|  | ||||
|         $notice->orderBy('id DESC'); | ||||
|  | ||||
|   | ||||
| @@ -132,6 +132,13 @@ class Status_network extends DB_DataObject | ||||
|             } | ||||
|         } else { | ||||
|             $sn = self::memGet('hostname', strtolower($servername)); | ||||
|  | ||||
|             if (empty($sn)) { | ||||
|                 // Try for a no-www address | ||||
|                 if (0 == strncasecmp($servername, 'www.', 4)) { | ||||
|                     $sn = self::memGet('hostname', strtolower(substr($servername, 4))); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (!empty($sn)) { | ||||
|   | ||||
| @@ -126,6 +126,30 @@ class User_group extends Memcached_DataObject | ||||
|         return $members; | ||||
|     } | ||||
|  | ||||
|     function getAdmins($offset=0, $limit=null) | ||||
|     { | ||||
|         $qry = | ||||
|           'SELECT profile.* ' . | ||||
|           'FROM profile JOIN group_member '. | ||||
|           'ON profile.id = group_member.profile_id ' . | ||||
|           'WHERE group_member.group_id = %d ' . | ||||
|           'AND group_member.is_admin = 1 ' . | ||||
|           'ORDER BY group_member.modified ASC '; | ||||
|  | ||||
|         if ($limit != null) { | ||||
|             if (common_config('db','type') == 'pgsql') { | ||||
|                 $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset; | ||||
|             } else { | ||||
|                 $qry .= ' LIMIT ' . $offset . ', ' . $limit; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $admins = new Profile(); | ||||
|  | ||||
|         $admins->query(sprintf($qry, $this->id)); | ||||
|         return $admins; | ||||
|     } | ||||
|  | ||||
|     function getBlocked($offset=0, $limit=null) | ||||
|     { | ||||
|         $qry = | ||||
|   | ||||
| @@ -86,6 +86,9 @@ $config['sphinx']['port'] = 3312; | ||||
| // $config['xmpp']['public'][] = 'someindexer@example.net'; | ||||
| // $config['xmpp']['debug'] = false; | ||||
|  | ||||
| // Turn off invites | ||||
| // $config['invite']['enabled'] = false; | ||||
|  | ||||
| // Default locale info | ||||
| // $config['site']['timezone'] = 'Pacific/Auckland'; | ||||
| // $config['site']['language'] = 'en_NZ'; | ||||
|   | ||||
							
								
								
									
										849
									
								
								extlib/Mail/mimeDecode.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										849
									
								
								extlib/Mail/mimeDecode.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,849 @@ | ||||
| <?php | ||||
| /** | ||||
|  * The Mail_mimeDecode class is used to decode mail/mime messages | ||||
|  * | ||||
|  * This class will parse a raw mime email and return | ||||
|  * the structure. Returned structure is similar to | ||||
|  * that returned by imap_fetchstructure(). | ||||
|  * | ||||
|  *  +----------------------------- IMPORTANT ------------------------------+ | ||||
|  *  | Usage of this class compared to native php extensions such as        | | ||||
|  *  | mailparse or imap, is slow and may be feature deficient. If available| | ||||
|  *  | you are STRONGLY recommended to use the php extensions.              | | ||||
|  *  +----------------------------------------------------------------------+ | ||||
|  * | ||||
|  * Compatible with PHP versions 4 and 5 | ||||
|  * | ||||
|  * LICENSE: This LICENSE is in the BSD license style. | ||||
|  * Copyright (c) 2002-2003, Richard Heyes <richard@phpguru.org> | ||||
|  * Copyright (c) 2003-2006, PEAR <pear-group@php.net> | ||||
|  * All rights reserved. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or | ||||
|  * without modification, are permitted provided that the following | ||||
|  * conditions are met: | ||||
|  * | ||||
|  * - Redistributions of source code must retain the above copyright | ||||
|  *   notice, this list of conditions and the following disclaimer. | ||||
|  * - Redistributions in binary form must reproduce the above copyright | ||||
|  *   notice, this list of conditions and the following disclaimer in the | ||||
|  *   documentation and/or other materials provided with the distribution. | ||||
|  * - Neither the name of the authors, nor the names of its contributors  | ||||
|  *   may be used to endorse or promote products derived from this  | ||||
|  *   software without specific prior written permission. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||||
|  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||
|  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||||
|  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||||
|  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||||
|  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||||
|  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||||
|  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||||
|  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | ||||
|  * THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  * | ||||
|  * @category   Mail | ||||
|  * @package    Mail_Mime | ||||
|  * @author     Richard Heyes  <richard@phpguru.org> | ||||
|  * @author     George Schlossnagle <george@omniti.com> | ||||
|  * @author     Cipriano Groenendal <cipri@php.net> | ||||
|  * @author     Sean Coates <sean@php.net> | ||||
|  * @copyright  2003-2006 PEAR <pear-group@php.net> | ||||
|  * @license    http://www.opensource.org/licenses/bsd-license.php BSD License | ||||
|  * @version    CVS: $Id: mimeDecode.php,v 1.48 2006/12/03 13:43:33 cipri Exp $ | ||||
|  * @link       http://pear.php.net/package/Mail_mime | ||||
|  */ | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * require PEAR | ||||
|  * | ||||
|  * This package depends on PEAR to raise errors. | ||||
|  */ | ||||
| require_once 'PEAR.php'; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * The Mail_mimeDecode class is used to decode mail/mime messages | ||||
|  * | ||||
|  * This class will parse a raw mime email and return the structure. | ||||
|  * Returned structure is similar to that returned by imap_fetchstructure(). | ||||
|  * | ||||
|  *  +----------------------------- IMPORTANT ------------------------------+ | ||||
|  *  | Usage of this class compared to native php extensions such as        | | ||||
|  *  | mailparse or imap, is slow and may be feature deficient. If available| | ||||
|  *  | you are STRONGLY recommended to use the php extensions.              | | ||||
|  *  +----------------------------------------------------------------------+ | ||||
|  * | ||||
|  * @category   Mail | ||||
|  * @package    Mail_Mime | ||||
|  * @author     Richard Heyes  <richard@phpguru.org> | ||||
|  * @author     George Schlossnagle <george@omniti.com> | ||||
|  * @author     Cipriano Groenendal <cipri@php.net> | ||||
|  * @author     Sean Coates <sean@php.net> | ||||
|  * @copyright  2003-2006 PEAR <pear-group@php.net> | ||||
|  * @license    http://www.opensource.org/licenses/bsd-license.php BSD License | ||||
|  * @version    Release: @package_version@ | ||||
|  * @link       http://pear.php.net/package/Mail_mime | ||||
|  */ | ||||
| class Mail_mimeDecode extends PEAR | ||||
| { | ||||
|     /** | ||||
|      * The raw email to decode | ||||
|      * | ||||
|      * @var    string | ||||
|      * @access private | ||||
|      */ | ||||
|     var $_input; | ||||
|  | ||||
|     /** | ||||
|      * The header part of the input | ||||
|      * | ||||
|      * @var    string | ||||
|      * @access private | ||||
|      */ | ||||
|     var $_header; | ||||
|  | ||||
|     /** | ||||
|      * The body part of the input | ||||
|      * | ||||
|      * @var    string | ||||
|      * @access private | ||||
|      */ | ||||
|     var $_body; | ||||
|  | ||||
|     /** | ||||
|      * If an error occurs, this is used to store the message | ||||
|      * | ||||
|      * @var    string | ||||
|      * @access private | ||||
|      */ | ||||
|     var $_error; | ||||
|  | ||||
|     /** | ||||
|      * Flag to determine whether to include bodies in the | ||||
|      * returned object. | ||||
|      * | ||||
|      * @var    boolean | ||||
|      * @access private | ||||
|      */ | ||||
|     var $_include_bodies; | ||||
|  | ||||
|     /** | ||||
|      * Flag to determine whether to decode bodies | ||||
|      * | ||||
|      * @var    boolean | ||||
|      * @access private | ||||
|      */ | ||||
|     var $_decode_bodies; | ||||
|  | ||||
|     /** | ||||
|      * Flag to determine whether to decode headers | ||||
|      * | ||||
|      * @var    boolean | ||||
|      * @access private | ||||
|      */ | ||||
|     var $_decode_headers; | ||||
|  | ||||
|     /** | ||||
|      * Constructor. | ||||
|      * | ||||
|      * Sets up the object, initialise the variables, and splits and | ||||
|      * stores the header and body of the input. | ||||
|      * | ||||
|      * @param string The input to decode | ||||
|      * @access public | ||||
|      */ | ||||
|     function Mail_mimeDecode($input) | ||||
|     { | ||||
|         list($header, $body)   = $this->_splitBodyHeader($input); | ||||
|  | ||||
|         $this->_input          = $input; | ||||
|         $this->_header         = $header; | ||||
|         $this->_body           = $body; | ||||
|         $this->_decode_bodies  = false; | ||||
|         $this->_include_bodies = true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Begins the decoding process. If called statically | ||||
|      * it will create an object and call the decode() method | ||||
|      * of it. | ||||
|      * | ||||
|      * @param array An array of various parameters that determine | ||||
|      *              various things: | ||||
|      *              include_bodies - Whether to include the body in the returned | ||||
|      *                               object. | ||||
|      *              decode_bodies  - Whether to decode the bodies | ||||
|      *                               of the parts. (Transfer encoding) | ||||
|      *              decode_headers - Whether to decode headers | ||||
|      *              input          - If called statically, this will be treated | ||||
|      *                               as the input | ||||
|      * @return object Decoded results | ||||
|      * @access public | ||||
|      */ | ||||
|     function decode($params = null) | ||||
|     { | ||||
|         // determine if this method has been called statically | ||||
|         $isStatic = !(isset($this) && get_class($this) == __CLASS__); | ||||
|  | ||||
|         // Have we been called statically? | ||||
| 	// If so, create an object and pass details to that. | ||||
|         if ($isStatic AND isset($params['input'])) { | ||||
|  | ||||
|             $obj = new Mail_mimeDecode($params['input']); | ||||
|             $structure = $obj->decode($params); | ||||
|  | ||||
|         // Called statically but no input | ||||
|         } elseif ($isStatic) { | ||||
|             return PEAR::raiseError('Called statically and no input given'); | ||||
|  | ||||
|         // Called via an object | ||||
|         } else { | ||||
|             $this->_include_bodies = isset($params['include_bodies']) ? | ||||
| 	                             $params['include_bodies'] : false; | ||||
|             $this->_decode_bodies  = isset($params['decode_bodies']) ? | ||||
| 	                             $params['decode_bodies']  : false; | ||||
|             $this->_decode_headers = isset($params['decode_headers']) ? | ||||
| 	                             $params['decode_headers'] : false; | ||||
|  | ||||
|             $structure = $this->_decode($this->_header, $this->_body); | ||||
|             if ($structure === false) { | ||||
|                 $structure = $this->raiseError($this->_error); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $structure; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Performs the decoding. Decodes the body string passed to it | ||||
|      * If it finds certain content-types it will call itself in a | ||||
|      * recursive fashion | ||||
|      * | ||||
|      * @param string Header section | ||||
|      * @param string Body section | ||||
|      * @return object Results of decoding process | ||||
|      * @access private | ||||
|      */ | ||||
|     function _decode($headers, $body, $default_ctype = 'text/plain') | ||||
|     { | ||||
|         $return = new stdClass; | ||||
|         $return->headers = array(); | ||||
|         $headers = $this->_parseHeaders($headers); | ||||
|  | ||||
|         foreach ($headers as $value) { | ||||
|             if (isset($return->headers[strtolower($value['name'])]) AND !is_array($return->headers[strtolower($value['name'])])) { | ||||
|                 $return->headers[strtolower($value['name'])]   = array($return->headers[strtolower($value['name'])]); | ||||
|                 $return->headers[strtolower($value['name'])][] = $value['value']; | ||||
|  | ||||
|             } elseif (isset($return->headers[strtolower($value['name'])])) { | ||||
|                 $return->headers[strtolower($value['name'])][] = $value['value']; | ||||
|  | ||||
|             } else { | ||||
|                 $return->headers[strtolower($value['name'])] = $value['value']; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         reset($headers); | ||||
|         while (list($key, $value) = each($headers)) { | ||||
|             $headers[$key]['name'] = strtolower($headers[$key]['name']); | ||||
|             switch ($headers[$key]['name']) { | ||||
|  | ||||
|                 case 'content-type': | ||||
|                     $content_type = $this->_parseHeaderValue($headers[$key]['value']); | ||||
|  | ||||
|                     if (preg_match('/([0-9a-z+.-]+)\/([0-9a-z+.-]+)/i', $content_type['value'], $regs)) { | ||||
|                         $return->ctype_primary   = $regs[1]; | ||||
|                         $return->ctype_secondary = $regs[2]; | ||||
|                     } | ||||
|  | ||||
|                     if (isset($content_type['other'])) { | ||||
|                         while (list($p_name, $p_value) = each($content_type['other'])) { | ||||
|                             $return->ctype_parameters[$p_name] = $p_value; | ||||
|                         } | ||||
|                     } | ||||
|                     break; | ||||
|  | ||||
|                 case 'content-disposition': | ||||
|                     $content_disposition = $this->_parseHeaderValue($headers[$key]['value']); | ||||
|                     $return->disposition   = $content_disposition['value']; | ||||
|                     if (isset($content_disposition['other'])) { | ||||
|                         while (list($p_name, $p_value) = each($content_disposition['other'])) { | ||||
|                             $return->d_parameters[$p_name] = $p_value; | ||||
|                         } | ||||
|                     } | ||||
|                     break; | ||||
|  | ||||
|                 case 'content-transfer-encoding': | ||||
|                     $content_transfer_encoding = $this->_parseHeaderValue($headers[$key]['value']); | ||||
|                     break; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (isset($content_type)) { | ||||
|             switch (strtolower($content_type['value'])) { | ||||
|                 case 'text/plain': | ||||
|                     $encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit'; | ||||
|                     $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding) : $body) : null; | ||||
|                     break; | ||||
|  | ||||
|                 case 'text/html': | ||||
|                     $encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit'; | ||||
|                     $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding) : $body) : null; | ||||
|                     break; | ||||
|  | ||||
|                 case 'multipart/parallel': | ||||
|                 case 'multipart/appledouble': // Appledouble mail | ||||
|                 case 'multipart/report': // RFC1892 | ||||
|                 case 'multipart/signed': // PGP | ||||
|                 case 'multipart/digest': | ||||
|                 case 'multipart/alternative': | ||||
|                 case 'multipart/related': | ||||
|                 case 'multipart/mixed': | ||||
|                     if(!isset($content_type['other']['boundary'])){ | ||||
|                         $this->_error = 'No boundary found for ' . $content_type['value'] . ' part'; | ||||
|                         return false; | ||||
|                     } | ||||
|  | ||||
|                     $default_ctype = (strtolower($content_type['value']) === 'multipart/digest') ? 'message/rfc822' : 'text/plain'; | ||||
|  | ||||
|                     $parts = $this->_boundarySplit($body, $content_type['other']['boundary']); | ||||
|                     for ($i = 0; $i < count($parts); $i++) { | ||||
|                         list($part_header, $part_body) = $this->_splitBodyHeader($parts[$i]); | ||||
|                         $part = $this->_decode($part_header, $part_body, $default_ctype); | ||||
|                         if($part === false) | ||||
|                             $part = $this->raiseError($this->_error); | ||||
|                         $return->parts[] = $part; | ||||
|                     } | ||||
|                     break; | ||||
|  | ||||
|                 case 'message/rfc822': | ||||
|                     $obj = &new Mail_mimeDecode($body); | ||||
|                     $return->parts[] = $obj->decode(array('include_bodies' => $this->_include_bodies, | ||||
| 					                                      'decode_bodies'  => $this->_decode_bodies, | ||||
| 														  'decode_headers' => $this->_decode_headers)); | ||||
|                     unset($obj); | ||||
|                     break; | ||||
|  | ||||
|                 default: | ||||
|                     if(!isset($content_transfer_encoding['value'])) | ||||
|                         $content_transfer_encoding['value'] = '7bit'; | ||||
|                     $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $content_transfer_encoding['value']) : $body) : null; | ||||
|                     break; | ||||
|             } | ||||
|  | ||||
|         } else { | ||||
|             $ctype = explode('/', $default_ctype); | ||||
|             $return->ctype_primary   = $ctype[0]; | ||||
|             $return->ctype_secondary = $ctype[1]; | ||||
|             $this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body) : $body) : null; | ||||
|         } | ||||
|  | ||||
|         return $return; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Given the output of the above function, this will return an | ||||
|      * array of references to the parts, indexed by mime number. | ||||
|      * | ||||
|      * @param  object $structure   The structure to go through | ||||
|      * @param  string $mime_number Internal use only. | ||||
|      * @return array               Mime numbers | ||||
|      */ | ||||
|     function &getMimeNumbers(&$structure, $no_refs = false, $mime_number = '', $prepend = '') | ||||
|     { | ||||
|         $return = array(); | ||||
|         if (!empty($structure->parts)) { | ||||
|             if ($mime_number != '') { | ||||
|                 $structure->mime_id = $prepend . $mime_number; | ||||
|                 $return[$prepend . $mime_number] = &$structure; | ||||
|             } | ||||
|             for ($i = 0; $i < count($structure->parts); $i++) { | ||||
|  | ||||
|              | ||||
|                 if (!empty($structure->headers['content-type']) AND substr(strtolower($structure->headers['content-type']), 0, 8) == 'message/') { | ||||
|                     $prepend      = $prepend . $mime_number . '.'; | ||||
|                     $_mime_number = ''; | ||||
|                 } else { | ||||
|                     $_mime_number = ($mime_number == '' ? $i + 1 : sprintf('%s.%s', $mime_number, $i + 1)); | ||||
|                 } | ||||
|  | ||||
|                 $arr = &Mail_mimeDecode::getMimeNumbers($structure->parts[$i], $no_refs, $_mime_number, $prepend); | ||||
|                 foreach ($arr as $key => $val) { | ||||
|                     $no_refs ? $return[$key] = '' : $return[$key] = &$arr[$key]; | ||||
|                 } | ||||
|             } | ||||
|         } else { | ||||
|             if ($mime_number == '') { | ||||
|                 $mime_number = '1'; | ||||
|             } | ||||
|             $structure->mime_id = $prepend . $mime_number; | ||||
|             $no_refs ? $return[$prepend . $mime_number] = '' : $return[$prepend . $mime_number] = &$structure; | ||||
|         } | ||||
|          | ||||
|         return $return; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Given a string containing a header and body | ||||
|      * section, this function will split them (at the first | ||||
|      * blank line) and return them. | ||||
|      * | ||||
|      * @param string Input to split apart | ||||
|      * @return array Contains header and body section | ||||
|      * @access private | ||||
|      */ | ||||
|     function _splitBodyHeader($input) | ||||
|     { | ||||
|         if (preg_match("/^(.*?)\r?\n\r?\n(.*)/s", $input, $match)) { | ||||
|             return array($match[1], $match[2]); | ||||
|         } | ||||
|         $this->_error = 'Could not split header and body'; | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Parse headers given in $input and return | ||||
|      * as assoc array. | ||||
|      * | ||||
|      * @param string Headers to parse | ||||
|      * @return array Contains parsed headers | ||||
|      * @access private | ||||
|      */ | ||||
|     function _parseHeaders($input) | ||||
|     { | ||||
|  | ||||
|         if ($input !== '') { | ||||
|             // Unfold the input | ||||
|             $input   = preg_replace("/\r?\n/", "\r\n", $input); | ||||
|             $input   = preg_replace("/\r\n(\t| )+/", ' ', $input); | ||||
|             $headers = explode("\r\n", trim($input)); | ||||
|  | ||||
|             foreach ($headers as $value) { | ||||
|                 $hdr_name = substr($value, 0, $pos = strpos($value, ':')); | ||||
|                 $hdr_value = substr($value, $pos+1); | ||||
|                 if($hdr_value[0] == ' ') | ||||
|                     $hdr_value = substr($hdr_value, 1); | ||||
|  | ||||
|                 $return[] = array( | ||||
|                                   'name'  => $hdr_name, | ||||
|                                   'value' => $this->_decode_headers ? $this->_decodeHeader($hdr_value) : $hdr_value | ||||
|                                  ); | ||||
|             } | ||||
|         } else { | ||||
|             $return = array(); | ||||
|         } | ||||
|  | ||||
|         return $return; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Function to parse a header value, | ||||
|      * extract first part, and any secondary | ||||
|      * parts (after ;) This function is not as | ||||
|      * robust as it could be. Eg. header comments | ||||
|      * in the wrong place will probably break it. | ||||
|      * | ||||
|      * @param string Header value to parse | ||||
|      * @return array Contains parsed result | ||||
|      * @access private | ||||
|      */ | ||||
|     function _parseHeaderValue($input) | ||||
|     { | ||||
|  | ||||
|         if (($pos = strpos($input, ';')) !== false) { | ||||
|  | ||||
|             $return['value'] = trim(substr($input, 0, $pos)); | ||||
|             $input = trim(substr($input, $pos+1)); | ||||
|  | ||||
|             if (strlen($input) > 0) { | ||||
|  | ||||
|                 // This splits on a semi-colon, if there's no preceeding backslash | ||||
|                 // Now works with quoted values; had to glue the \; breaks in PHP | ||||
|                 // the regex is already bordering on incomprehensible | ||||
|                 $splitRegex = '/([^;\'"]*[\'"]([^\'"]*([^\'"]*)*)[\'"][^;\'"]*|([^;]+))(;|$)/'; | ||||
|                 preg_match_all($splitRegex, $input, $matches); | ||||
|                 $parameters = array(); | ||||
|                 for ($i=0; $i<count($matches[0]); $i++) { | ||||
|                     $param = $matches[0][$i]; | ||||
|                     while (substr($param, -2) == '\;') { | ||||
|                         $param .= $matches[0][++$i]; | ||||
|                     } | ||||
|                     $parameters[] = $param; | ||||
|                 } | ||||
|  | ||||
|                 for ($i = 0; $i < count($parameters); $i++) { | ||||
|                     $param_name  = trim(substr($parameters[$i], 0, $pos = strpos($parameters[$i], '=')), "'\";\t\\ "); | ||||
|                     $param_value = trim(str_replace('\;', ';', substr($parameters[$i], $pos + 1)), "'\";\t\\ "); | ||||
|                     if ($param_value[0] == '"') { | ||||
|                         $param_value = substr($param_value, 1, -1); | ||||
|                     } | ||||
|                     $return['other'][$param_name] = $param_value; | ||||
|                     $return['other'][strtolower($param_name)] = $param_value; | ||||
|                 } | ||||
|             } | ||||
|         } else { | ||||
|             $return['value'] = trim($input); | ||||
|         } | ||||
|  | ||||
|         return $return; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * This function splits the input based | ||||
|      * on the given boundary | ||||
|      * | ||||
|      * @param string Input to parse | ||||
|      * @return array Contains array of resulting mime parts | ||||
|      * @access private | ||||
|      */ | ||||
|     function _boundarySplit($input, $boundary) | ||||
|     { | ||||
|         $parts = array(); | ||||
|  | ||||
|         $bs_possible = substr($boundary, 2, -2); | ||||
|         $bs_check = '\"' . $bs_possible . '\"'; | ||||
|  | ||||
|         if ($boundary == $bs_check) { | ||||
|             $boundary = $bs_possible; | ||||
|         } | ||||
|  | ||||
|         $tmp = explode('--' . $boundary, $input); | ||||
|  | ||||
|         for ($i = 1; $i < count($tmp) - 1; $i++) { | ||||
|             $parts[] = $tmp[$i]; | ||||
|         } | ||||
|  | ||||
|         return $parts; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Given a header, this function will decode it | ||||
|      * according to RFC2047. Probably not *exactly* | ||||
|      * conformant, but it does pass all the given | ||||
|      * examples (in RFC2047). | ||||
|      * | ||||
|      * @param string Input header value to decode | ||||
|      * @return string Decoded header value | ||||
|      * @access private | ||||
|      */ | ||||
|     function _decodeHeader($input) | ||||
|     { | ||||
|         // Remove white space between encoded-words | ||||
|         $input = preg_replace('/(=\?[^?]+\?(q|b)\?[^?]*\?=)(\s)+=\?/i', '\1=?', $input); | ||||
|  | ||||
|         // For each encoded-word... | ||||
|         while (preg_match('/(=\?([^?]+)\?(q|b)\?([^?]*)\?=)/i', $input, $matches)) { | ||||
|  | ||||
|             $encoded  = $matches[1]; | ||||
|             $charset  = $matches[2]; | ||||
|             $encoding = $matches[3]; | ||||
|             $text     = $matches[4]; | ||||
|  | ||||
|             switch (strtolower($encoding)) { | ||||
|                 case 'b': | ||||
|                     $text = base64_decode($text); | ||||
|                     break; | ||||
|  | ||||
|                 case 'q': | ||||
|                     $text = str_replace('_', ' ', $text); | ||||
|                     preg_match_all('/=([a-f0-9]{2})/i', $text, $matches); | ||||
|                     foreach($matches[1] as $value) | ||||
|                         $text = str_replace('='.$value, chr(hexdec($value)), $text); | ||||
|                     break; | ||||
|             } | ||||
|  | ||||
|             $input = str_replace($encoded, $text, $input); | ||||
|         } | ||||
|  | ||||
|         return $input; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Given a body string and an encoding type, | ||||
|      * this function will decode and return it. | ||||
|      * | ||||
|      * @param  string Input body to decode | ||||
|      * @param  string Encoding type to use. | ||||
|      * @return string Decoded body | ||||
|      * @access private | ||||
|      */ | ||||
|     function _decodeBody($input, $encoding = '7bit') | ||||
|     { | ||||
|         switch (strtolower($encoding)) { | ||||
|             case '7bit': | ||||
|                 return $input; | ||||
|                 break; | ||||
|  | ||||
|             case 'quoted-printable': | ||||
|                 return $this->_quotedPrintableDecode($input); | ||||
|                 break; | ||||
|  | ||||
|             case 'base64': | ||||
|                 return base64_decode($input); | ||||
|                 break; | ||||
|  | ||||
|             default: | ||||
|                 return $input; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Given a quoted-printable string, this | ||||
|      * function will decode and return it. | ||||
|      * | ||||
|      * @param  string Input body to decode | ||||
|      * @return string Decoded body | ||||
|      * @access private | ||||
|      */ | ||||
|     function _quotedPrintableDecode($input) | ||||
|     { | ||||
|         // Remove soft line breaks | ||||
|         $input = preg_replace("/=\r?\n/", '', $input); | ||||
|  | ||||
|         // Replace encoded characters | ||||
| 		$input = preg_replace('/=([a-f0-9]{2})/ie', "chr(hexdec('\\1'))", $input); | ||||
|  | ||||
|         return $input; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Checks the input for uuencoded files and returns | ||||
|      * an array of them. Can be called statically, eg: | ||||
|      * | ||||
|      * $files =& Mail_mimeDecode::uudecode($some_text); | ||||
|      * | ||||
|      * It will check for the begin 666 ... end syntax | ||||
|      * however and won't just blindly decode whatever you | ||||
|      * pass it. | ||||
|      * | ||||
|      * @param  string Input body to look for attahcments in | ||||
|      * @return array  Decoded bodies, filenames and permissions | ||||
|      * @access public | ||||
|      * @author Unknown | ||||
|      */ | ||||
|     function &uudecode($input) | ||||
|     { | ||||
|         // Find all uuencoded sections | ||||
|         preg_match_all("/begin ([0-7]{3}) (.+)\r?\n(.+)\r?\nend/Us", $input, $matches); | ||||
|  | ||||
|         for ($j = 0; $j < count($matches[3]); $j++) { | ||||
|  | ||||
|             $str      = $matches[3][$j]; | ||||
|             $filename = $matches[2][$j]; | ||||
|             $fileperm = $matches[1][$j]; | ||||
|  | ||||
|             $file = ''; | ||||
|             $str = preg_split("/\r?\n/", trim($str)); | ||||
|             $strlen = count($str); | ||||
|  | ||||
|             for ($i = 0; $i < $strlen; $i++) { | ||||
|                 $pos = 1; | ||||
|                 $d = 0; | ||||
|                 $len=(int)(((ord(substr($str[$i],0,1)) -32) - ' ') & 077); | ||||
|  | ||||
|                 while (($d + 3 <= $len) AND ($pos + 4 <= strlen($str[$i]))) { | ||||
|                     $c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20); | ||||
|                     $c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20); | ||||
|                     $c2 = (ord(substr($str[$i],$pos+2,1)) ^ 0x20); | ||||
|                     $c3 = (ord(substr($str[$i],$pos+3,1)) ^ 0x20); | ||||
|                     $file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4)); | ||||
|  | ||||
|                     $file .= chr(((($c1 - ' ') & 077) << 4) | ((($c2 - ' ') & 077) >> 2)); | ||||
|  | ||||
|                     $file .= chr(((($c2 - ' ') & 077) << 6) |  (($c3 - ' ') & 077)); | ||||
|  | ||||
|                     $pos += 4; | ||||
|                     $d += 3; | ||||
|                 } | ||||
|  | ||||
|                 if (($d + 2 <= $len) && ($pos + 3 <= strlen($str[$i]))) { | ||||
|                     $c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20); | ||||
|                     $c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20); | ||||
|                     $c2 = (ord(substr($str[$i],$pos+2,1)) ^ 0x20); | ||||
|                     $file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4)); | ||||
|  | ||||
|                     $file .= chr(((($c1 - ' ') & 077) << 4) | ((($c2 - ' ') & 077) >> 2)); | ||||
|  | ||||
|                     $pos += 3; | ||||
|                     $d += 2; | ||||
|                 } | ||||
|  | ||||
|                 if (($d + 1 <= $len) && ($pos + 2 <= strlen($str[$i]))) { | ||||
|                     $c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20); | ||||
|                     $c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20); | ||||
|                     $file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4)); | ||||
|  | ||||
|                 } | ||||
|             } | ||||
|             $files[] = array('filename' => $filename, 'fileperm' => $fileperm, 'filedata' => $file); | ||||
|         } | ||||
|  | ||||
|         return $files; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * getSendArray() returns the arguments required for Mail::send() | ||||
|      * used to build the arguments for a mail::send() call  | ||||
|      * | ||||
|      * Usage: | ||||
|      * $mailtext = Full email (for example generated by a template) | ||||
|      * $decoder = new Mail_mimeDecode($mailtext); | ||||
|      * $parts =  $decoder->getSendArray(); | ||||
|      * if (!PEAR::isError($parts) { | ||||
|      *     list($recipents,$headers,$body) = $parts; | ||||
|      *     $mail = Mail::factory('smtp'); | ||||
|      *     $mail->send($recipents,$headers,$body); | ||||
|      * } else { | ||||
|      *     echo $parts->message; | ||||
|      * } | ||||
|      * @return mixed   array of recipeint, headers,body or Pear_Error | ||||
|      * @access public | ||||
|      * @author Alan Knowles <alan@akbkhome.com> | ||||
|      */ | ||||
|     function getSendArray() | ||||
|     { | ||||
|         // prevent warning if this is not set | ||||
|         $this->_decode_headers = FALSE; | ||||
|         $headerlist =$this->_parseHeaders($this->_header); | ||||
|         $to = ""; | ||||
|         if (!$headerlist) { | ||||
|             return $this->raiseError("Message did not contain headers"); | ||||
|         } | ||||
|         foreach($headerlist as $item) { | ||||
|             $header[$item['name']] = $item['value']; | ||||
|             switch (strtolower($item['name'])) { | ||||
|                 case "to": | ||||
|                 case "cc": | ||||
|                 case "bcc": | ||||
|                     $to = ",".$item['value']; | ||||
|                 default: | ||||
|                    break; | ||||
|             } | ||||
|         } | ||||
|         if ($to == "") { | ||||
|             return $this->raiseError("Message did not contain any recipents"); | ||||
|         } | ||||
|         $to = substr($to,1); | ||||
|         return array($to,$header,$this->_body); | ||||
|     }  | ||||
|  | ||||
|     /** | ||||
|      * Returns a xml copy of the output of | ||||
|      * Mail_mimeDecode::decode. Pass the output in as the | ||||
|      * argument. This function can be called statically. Eg: | ||||
|      * | ||||
|      * $output = $obj->decode(); | ||||
|      * $xml    = Mail_mimeDecode::getXML($output); | ||||
|      * | ||||
|      * The DTD used for this should have been in the package. Or | ||||
|      * alternatively you can get it from cvs, or here: | ||||
|      * http://www.phpguru.org/xmail/xmail.dtd. | ||||
|      * | ||||
|      * @param  object Input to convert to xml. This should be the | ||||
|      *                output of the Mail_mimeDecode::decode function | ||||
|      * @return string XML version of input | ||||
|      * @access public | ||||
|      */ | ||||
|     function getXML($input) | ||||
|     { | ||||
|         $crlf    =  "\r\n"; | ||||
|         $output  = '<?xml version=\'1.0\'?>' . $crlf . | ||||
|                    '<!DOCTYPE email SYSTEM "http://www.phpguru.org/xmail/xmail.dtd">' . $crlf . | ||||
|                    '<email>' . $crlf . | ||||
|                    Mail_mimeDecode::_getXML($input) . | ||||
|                    '</email>'; | ||||
|  | ||||
|         return $output; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Function that does the actual conversion to xml. Does a single | ||||
|      * mimepart at a time. | ||||
|      * | ||||
|      * @param  object  Input to convert to xml. This is a mimepart object. | ||||
|      *                 It may or may not contain subparts. | ||||
|      * @param  integer Number of tabs to indent | ||||
|      * @return string  XML version of input | ||||
|      * @access private | ||||
|      */ | ||||
|     function _getXML($input, $indent = 1) | ||||
|     { | ||||
|         $htab    =  "\t"; | ||||
|         $crlf    =  "\r\n"; | ||||
|         $output  =  ''; | ||||
|         $headers = @(array)$input->headers; | ||||
|  | ||||
|         foreach ($headers as $hdr_name => $hdr_value) { | ||||
|  | ||||
|             // Multiple headers with this name | ||||
|             if (is_array($headers[$hdr_name])) { | ||||
|                 for ($i = 0; $i < count($hdr_value); $i++) { | ||||
|                     $output .= Mail_mimeDecode::_getXML_helper($hdr_name, $hdr_value[$i], $indent); | ||||
|                 } | ||||
|  | ||||
|             // Only one header of this sort | ||||
|             } else { | ||||
|                 $output .= Mail_mimeDecode::_getXML_helper($hdr_name, $hdr_value, $indent); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (!empty($input->parts)) { | ||||
|             for ($i = 0; $i < count($input->parts); $i++) { | ||||
|                 $output .= $crlf . str_repeat($htab, $indent) . '<mimepart>' . $crlf . | ||||
|                            Mail_mimeDecode::_getXML($input->parts[$i], $indent+1) . | ||||
|                            str_repeat($htab, $indent) . '</mimepart>' . $crlf; | ||||
|             } | ||||
|         } elseif (isset($input->body)) { | ||||
|             $output .= $crlf . str_repeat($htab, $indent) . '<body><![CDATA[' . | ||||
|                        $input->body . ']]></body>' . $crlf; | ||||
|         } | ||||
|  | ||||
|         return $output; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Helper function to _getXML(). Returns xml of a header. | ||||
|      * | ||||
|      * @param  string  Name of header | ||||
|      * @param  string  Value of header | ||||
|      * @param  integer Number of tabs to indent | ||||
|      * @return string  XML version of input | ||||
|      * @access private | ||||
|      */ | ||||
|     function _getXML_helper($hdr_name, $hdr_value, $indent) | ||||
|     { | ||||
|         $htab   = "\t"; | ||||
|         $crlf   = "\r\n"; | ||||
|         $return = ''; | ||||
|  | ||||
|         $new_hdr_value = ($hdr_name != 'received') ? Mail_mimeDecode::_parseHeaderValue($hdr_value) : array('value' => $hdr_value); | ||||
|         $new_hdr_name  = str_replace(' ', '-', ucwords(str_replace('-', ' ', $hdr_name))); | ||||
|  | ||||
|         // Sort out any parameters | ||||
|         if (!empty($new_hdr_value['other'])) { | ||||
|             foreach ($new_hdr_value['other'] as $paramname => $paramvalue) { | ||||
|                 $params[] = str_repeat($htab, $indent) . $htab . '<parameter>' . $crlf . | ||||
|                             str_repeat($htab, $indent) . $htab . $htab . '<paramname>' . htmlspecialchars($paramname) . '</paramname>' . $crlf . | ||||
|                             str_repeat($htab, $indent) . $htab . $htab . '<paramvalue>' . htmlspecialchars($paramvalue) . '</paramvalue>' . $crlf . | ||||
|                             str_repeat($htab, $indent) . $htab . '</parameter>' . $crlf; | ||||
|             } | ||||
|  | ||||
|             $params = implode('', $params); | ||||
|         } else { | ||||
|             $params = ''; | ||||
|         } | ||||
|  | ||||
|         $return = str_repeat($htab, $indent) . '<header>' . $crlf . | ||||
|                   str_repeat($htab, $indent) . $htab . '<headername>' . htmlspecialchars($new_hdr_name) . '</headername>' . $crlf . | ||||
|                   str_repeat($htab, $indent) . $htab . '<headervalue>' . htmlspecialchars($new_hdr_value['value']) . '</headervalue>' . $crlf . | ||||
|                   $params . | ||||
|                   str_repeat($htab, $indent) . '</header>' . $crlf; | ||||
|  | ||||
|         return $return; | ||||
|     } | ||||
|  | ||||
| } // End of class | ||||
| @@ -27,7 +27,7 @@ | ||||
|  */ | ||||
|  | ||||
| /** XMPPHP_XMLStream */ | ||||
| require_once "XMPP.php"; | ||||
| require_once dirname(__FILE__) . "/XMPP.php"; | ||||
|  | ||||
| /** | ||||
|  * XMPPHP Main Class | ||||
|   | ||||
| @@ -27,13 +27,13 @@ | ||||
|  */ | ||||
|  | ||||
| /** XMPPHP_Exception */ | ||||
| require_once 'Exception.php'; | ||||
| require_once dirname(__FILE__) . '/Exception.php'; | ||||
|  | ||||
| /** XMPPHP_XMLObj */ | ||||
| require_once 'XMLObj.php'; | ||||
| require_once dirname(__FILE__) . '/XMLObj.php'; | ||||
|  | ||||
| /** XMPPHP_Log */ | ||||
| require_once 'Log.php'; | ||||
| require_once dirname(__FILE__) . '/Log.php'; | ||||
|  | ||||
| /** | ||||
|  * XMPPHP XML Stream | ||||
| @@ -375,7 +375,7 @@ class XMPPHP_XMLStream { | ||||
| 	 * integer -> process for this amount of time  | ||||
| 	 */ | ||||
| 	 | ||||
| 	private function __process($maximum=0) { | ||||
| 	private function __process($maximum=5) { | ||||
| 		 | ||||
| 		$remaining = $maximum; | ||||
| 		 | ||||
|   | ||||
| @@ -27,8 +27,8 @@ | ||||
|  */ | ||||
|  | ||||
| /** XMPPHP_XMLStream */ | ||||
| require_once "XMLStream.php"; | ||||
| require_once "Roster.php"; | ||||
| require_once dirname(__FILE__) . "/XMLStream.php"; | ||||
| require_once dirname(__FILE__) . "/Roster.php"; | ||||
|  | ||||
| /** | ||||
|  * XMPPHP Main Class | ||||
| @@ -208,6 +208,15 @@ class XMPPHP_XMPP extends XMPPHP_XMLStream { | ||||
| 		 | ||||
| 		$this->send($out); | ||||
| 	} | ||||
| 	/** | ||||
| 	 * Send Auth request | ||||
| 	 * | ||||
| 	 * @param string $jid | ||||
| 	 */ | ||||
| 	public function subscribe($jid) { | ||||
| 		$this->send("<presence type='subscribe' to='{$jid}' from='{$this->fulljid}' />"); | ||||
| 		#$this->send("<presence type='subscribed' to='{$jid}' from='{$this->fulljid}' />"); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Message handler | ||||
|   | ||||
| @@ -72,6 +72,12 @@ function checkPrereqs() | ||||
|          <? | ||||
| 	     $pass = false; | ||||
| 	} | ||||
| 	if (!is_writable(INSTALLDIR.'/background/')) { | ||||
|          ?><p class="error">Cannot write background directory: <code><?php echo INSTALLDIR; ?>/background/</code></p> | ||||
| 	       <p>On your server, try this command: <code>chmod a+w <?php echo INSTALLDIR; ?>/background/</code></p> | ||||
|          <? | ||||
| 	     $pass = false; | ||||
| 	} | ||||
|  | ||||
| 	return $pass; | ||||
| } | ||||
|   | ||||
							
								
								
									
										271
									
								
								js/jquery.joverlay.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										271
									
								
								js/jquery.joverlay.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,271 @@ | ||||
| /* Copyright (c) 2009 Alvaro A. Lima Jr http://alvarojunior.com/jquery/joverlay.html | ||||
|  * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) | ||||
|  * Version: 0.7.1 (JUN 15, 2009) | ||||
|  * Requires: jQuery 1.3+ | ||||
|  */ | ||||
|  | ||||
| (function($) { | ||||
|  | ||||
| 	// Global vars | ||||
| 	var isIE6 = $.browser.msie && $.browser.version == 6.0; // =( | ||||
| 	var JOVERLAY_TIMER = null; | ||||
| 	var	JOVERLAY_ELEMENT_PREV = null; | ||||
|  | ||||
| 	$.fn.jOverlay = function(options) { | ||||
|  | ||||
| 		// Element exist? | ||||
| 		if ( $('#jOverlay').length ) {$.closeOverlay();} | ||||
|  | ||||
| 		// Clear Element Prev | ||||
| 		JOVERLAY_ELEMENT_PREV = null; | ||||
|  | ||||
| 		// Clear Timer | ||||
| 		if (JOVERLAY_TIMER !== null) { | ||||
| 			clearTimeout( JOVERLAY_TIMER ); | ||||
| 		} | ||||
|  | ||||
| 		// Set Options | ||||
| 		var options = $.extend({}, $.fn.jOverlay.options, options); | ||||
|  | ||||
| 		// private function | ||||
| 		function center(id) { | ||||
| 			if (options.center) { | ||||
| 				$.center(id); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		var element = this.is('*') ? this : '#jOverlayContent'; | ||||
| 		var position = isIE6 ? 'absolute' : 'fixed'; | ||||
| 		var isImage = /([^\/\\]+)\.(png|gif|jpeg|jpg|bmp)$/i.test( options.url ); | ||||
|  | ||||
| 		var imgLoading = options.imgLoading ? "<img id='jOverlayLoading' src='"+options.imgLoading+"' style='position:"+position+"; z-index:"+(options.zIndex + 9)+";'/>" : ''; | ||||
|  | ||||
| 		$('body').prepend(imgLoading + "<div id='jOverlay' />" | ||||
| 			+ "<div id='jOverlayContent' style='position:"+position+"; z-index:"+(options.zIndex + 5)+"; display:none;'/>" | ||||
| 		); | ||||
|  | ||||
| 		// Loading Centered | ||||
| 		$('#jOverlayLoading').load(function(){ | ||||
| 			center(this); | ||||
| 		}); | ||||
|  | ||||
| 		//IE 6 FIX | ||||
| 		if ( isIE6 ) { | ||||
| 			$('select').hide(); | ||||
| 			$('#jOverlayContent select').show(); | ||||
| 		} | ||||
|  | ||||
| 		// Overlay Style | ||||
| 		$('#jOverlay').css({ | ||||
| 			backgroundColor : options.color, | ||||
| 			position : position, | ||||
| 			top : '0px', | ||||
| 			left : '0px', | ||||
| 			filter : 'alpha(opacity='+ (options.opacity * 100) +')', // IE =( | ||||
| 			opacity : options.opacity, // Good Browser =D | ||||
| 			zIndex : options.zIndex, | ||||
| 			width : !isIE6 ? '100%' : $(window).width() + 'px', | ||||
| 			height : !isIE6 ? '100%' : $(document).height() + 'px' | ||||
| 		}).show(); | ||||
|  | ||||
| 		// ELEMENT | ||||
| 		if ( this.is('*') ) { | ||||
|  | ||||
| 			JOVERLAY_ELEMENT_PREV = this.prev(); | ||||
|  | ||||
| 			$('#jOverlayContent').html( | ||||
| 				this.show().attr('display', options.autoHide ? 'none' : this.css('display') ) | ||||
| 			); | ||||
| 			 | ||||
| 			if ( !isImage ) { | ||||
|  | ||||
| 				center('#jOverlayContent'); | ||||
|  | ||||
| 				$('#jOverlayContent').show(); | ||||
| 				 | ||||
| 				// Execute callback | ||||
| 				if ( !options.url && $.isFunction( options.success ) ) { | ||||
| 					options.success( this ); | ||||
| 				} | ||||
|  | ||||
| 			} | ||||
|  | ||||
| 		} | ||||
|  | ||||
| 		// IMAGE | ||||
| 		if ( isImage ) { | ||||
|  | ||||
| 			$('<img/>').load(function(){ | ||||
| 				var resize = $.resize(this.width, this.height); | ||||
|  | ||||
| 				$(this).css({ | ||||
| 					width : resize.width, | ||||
| 					height : resize.height | ||||
| 				}); | ||||
|  | ||||
| 				$( element ).html(this); | ||||
|  | ||||
| 				center('#jOverlayContent'); | ||||
|  | ||||
| 				$('#jOverlayLoading').fadeOut(500); | ||||
| 				$('#jOverlayContent').show(); | ||||
|  | ||||
| 				// Execute callback | ||||
| 				if ( $.isFunction( options.success ) ) { | ||||
| 					options.success( this ); | ||||
| 				} | ||||
|  | ||||
| 			}).error(function(){ | ||||
| 				alert('Image ('+options.url+') not found.'); | ||||
| 				$.closeOverlay(); | ||||
| 			}).attr({'src' : options.url, 'alt' : options.url}); | ||||
|  | ||||
| 		} | ||||
|  | ||||
| 		// AJAX | ||||
| 		if ( options.url && !isImage ) { | ||||
|  | ||||
| 			$.ajax({ | ||||
| 				type: options.method, | ||||
| 				data: options.data, | ||||
| 				url: options.url, | ||||
| 				success: function(responseText) { | ||||
|  | ||||
| 					$('#jOverlayLoading').fadeOut(500); | ||||
|  | ||||
| 					$( element ).html(responseText).show(); | ||||
|  | ||||
| 					center('#jOverlayContent'); | ||||
|  | ||||
| 					// Execute callback | ||||
| 					if ($.isFunction( options.success )) { | ||||
| 						options.success(responseText); | ||||
| 					} | ||||
|  | ||||
| 				}, | ||||
| 				error : function() { | ||||
| 					alert('URL ('+options.url+') not found.'); | ||||
| 					$.closeOverlay(); | ||||
| 				} | ||||
| 			}); | ||||
|  | ||||
| 		} | ||||
|  | ||||
| 		// :( | ||||
| 		if ( isIE6 ) { | ||||
|  | ||||
| 			// Window scroll | ||||
| 			$(window).scroll(function(){ | ||||
| 				center('#jOverlayContent'); | ||||
| 			}); | ||||
|  | ||||
| 			// Window resize | ||||
| 			$(window).resize(function(){ | ||||
|  | ||||
| 				$('#jOverlay').css({ | ||||
| 					width: $(window).width() + 'px', | ||||
| 					height: $(document).height() + 'px' | ||||
| 				}); | ||||
|  | ||||
| 				center('#jOverlayContent'); | ||||
|  | ||||
| 			}); | ||||
|  | ||||
| 		} | ||||
|  | ||||
| 		// Press ESC to close | ||||
| 		$(document).keydown(function(event){ | ||||
| 			if (event.keyCode == 27) { | ||||
| 				$.closeOverlay(); | ||||
| 			} | ||||
| 		}); | ||||
|  | ||||
| 		// Click to close | ||||
| 		if ( options.bgClickToClose ) { | ||||
| 			$('#jOverlay').click($.closeOverlay); | ||||
| 		} | ||||
|  | ||||
| 		// Timeout (auto-close) | ||||
| 		// time in millis to wait before auto-close | ||||
| 		// set to 0 to disable | ||||
| 		if ( Number(options.timeout) > 0 ) { | ||||
| 			jOverlayTimer = setTimeout( $.closeOverlay, Number(options.timeout) ); | ||||
| 		} | ||||
|  | ||||
| 		// ADD CSS | ||||
| 		$('#jOverlayContent').css(options.css || {}); | ||||
| 	}; | ||||
|  | ||||
| 	// Resizing large images - orginal by Christian Montoya. | ||||
| 	// Edited by - Cody Lindley (http://www.codylindley.com) (Thickbox 3.1) | ||||
| 	$.resize = function(imageWidth, imageHeight) { | ||||
| 		var x = $(window).width() - 150; | ||||
| 		var y = $(window).height() - 150; | ||||
| 		if (imageWidth > x) { | ||||
| 			imageHeight = imageHeight * (x / imageWidth);  | ||||
| 			imageWidth = x;  | ||||
| 			if (imageHeight > y) {  | ||||
| 				imageWidth = imageWidth * (y / imageHeight);  | ||||
| 				imageHeight = y;  | ||||
| 			} | ||||
| 		} else if (imageHeight > y) {  | ||||
| 			imageWidth = imageWidth * (y / imageHeight);  | ||||
| 			imageHeight = y;  | ||||
| 			if (imageWidth > x) {  | ||||
| 				imageHeight = imageHeight * (x / imageWidth);  | ||||
| 				imageWidth = x; | ||||
| 			} | ||||
| 		} | ||||
| 		return {width:imageWidth, height:imageHeight}; | ||||
| 	}; | ||||
|  | ||||
| 	// Centered Element | ||||
| 	$.center = function(element) { | ||||
| 		var element = $(element); | ||||
| 		var elemWidth = element.width(); | ||||
|  | ||||
| 		element.css({ | ||||
| 			width : elemWidth + 'px', | ||||
| 			marginLeft : '-' + (elemWidth / 2) + 'px', | ||||
| 			marginTop : '-' + element.height() / 2 + 'px', | ||||
| 		 	height : 'auto', | ||||
|          	top : !isIE6 ? '50%' : $(window).scrollTop() + ($(window).height() / 2) + 'px', | ||||
|          	left : '50%' | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	// Options default | ||||
| 	$.fn.jOverlay.options = { | ||||
| 		method : 'GET', | ||||
| 		data : '', | ||||
| 		url : '', | ||||
| 		color : '#000', | ||||
| 		opacity : '0.6', | ||||
| 		zIndex : 9999, | ||||
| 		center : true, | ||||
| 		imgLoading : '', | ||||
| 		bgClickToClose : true, | ||||
| 		success : null, | ||||
| 		timeout : 0, | ||||
| 		autoHide : true, | ||||
| 		css : {} | ||||
| 	}; | ||||
|  | ||||
| 	// Close | ||||
| 	$.closeOverlay = function() { | ||||
|  | ||||
| 		if (isIE6) { $("select").show(); } | ||||
|  | ||||
| 		if ( JOVERLAY_ELEMENT_PREV !== null ) { | ||||
| 			if ( JOVERLAY_ELEMENT_PREV !== null ) { | ||||
| 				var element = $('#jOverlayContent').children(); | ||||
| 				JOVERLAY_ELEMENT_PREV.after( element.css('display', element.attr('display') ) ); | ||||
| 				element.removeAttr('display'); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		$('#jOverlayLoading, #jOverlayContent, #jOverlay').remove(); | ||||
|  | ||||
| 	}; | ||||
|  | ||||
| })(jQuery); | ||||
							
								
								
									
										5
									
								
								js/jquery.joverlay.min.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								js/jquery.joverlay.min.js
									
									
									
									
										vendored
									
									
								
							| @@ -1,6 +1,7 @@ | ||||
| /* Copyright (c) 2009 Alvaro A. Lima Jr http://alvarojunior.com/jquery/joverlay.html | ||||
|  * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) | ||||
|  * Version: 0.6 (Abr 23, 2009) | ||||
|  * Version: 0.7.1 (JUN 15, 2009 | ||||
|  * Requires: jQuery 1.3+ | ||||
|  * Packer from http://dean.edwards.name/packer/ | ||||
|  */ | ||||
| (function($){var f=$.browser.msie&&$.browser.version==6.0;var g=null;$.fn.jOverlay=function(b){var b=$.extend({},$.fn.jOverlay.options,b);if(g!=null){clearTimeout(g)}var c=this.is('*')?this:'#jOverlayContent';var d=f?'absolute':'fixed';var e=b.imgLoading?"<img id='jOverlayLoading' src='"+b.imgLoading+"' style='position:"+d+"; z-index:"+(b.zIndex+9)+";'/>":'';$('body').prepend(e+"<div id='jOverlay' />"+"<div id='jOverlayContent' style='position:"+d+"; z-index:"+(b.zIndex+5)+"; display:none;'/>");$('#jOverlayLoading').load(function(){if(b.center){$.center(this)}});if(f){$("select").hide();$("#jOverlayContent select").show()}$('#jOverlay').css({backgroundColor:b.color,position:d,top:'0px',left:'0px',filter:'alpha(opacity='+(b.opacity*100)+')',opacity:b.opacity,zIndex:b.zIndex,width:!f?'100%':$(window).width()+'px',height:!f?'100%':$(document).height()+'px'}).show();if(this.is('*')){$('#jOverlayContent').html(this.addClass('jOverlayChildren').show()).show();if(b.center){$.center('#jOverlayContent')}if(!b.url&&$.isFunction(b.success)){b.success(this.html())}}if(b.url){$.ajax({type:b.method,data:b.data,url:b.url,success:function(a){$('#jOverlayLoading').fadeOut(600);$(c).html(a).show();if(b.center){$.center('#jOverlayContent')}if($.isFunction(b.success)){b.success(a)}}})}if(f){$(window).scroll(function(){if(b.center){$.center('#jOverlayContent')}});$(window).resize(function(){$('#jOverlay').css({width:$(window).width()+'px',height:$(document).height()+'px'});if(b.center){$.center('#jOverlayContent')}})}$(document).keydown(function(a){if(a.keyCode==27){$.closeOverlay()}});if(b.bgClickToClose){$('#jOverlay').click($.closeOverlay)}if(Number(b.timeout)>0){g=setTimeout($.closeOverlay,Number(b.timeout))}};$.center=function(a){var a=$(a);var b=a.height();var c=a.width();a.css({width:c+'px',marginLeft:'-'+(c/2)+'px',marginTop:'-'+b/2+'px',height:'auto',top:!f?'50%':$(window).scrollTop()+($(window).height()/2)+"px",left:'50%'})};$.fn.jOverlay.options={method:'GET',data:'',url:'',color:'#000',opacity:'0.6',zIndex:9999,center:true,imgLoading:'',bgClickToClose:true,success:null,timeout:0};$.closeOverlay=function(){if(f){$("select").show()}$('#jOverlayContent .jOverlayChildren').hide().prependTo($('body'));$('#jOverlayLoading, #jOverlayContent, #jOverlay').remove()}})(jQuery); | ||||
| (function($){var g=$.browser.msie&&$.browser.version==6.0;var h=null;var i=null;$.fn.jOverlay=function(b){if($('#jOverlay').length){$.closeOverlay()}i=null;if(h!==null){clearTimeout(h)}var b=$.extend({},$.fn.jOverlay.options,b);function center(a){if(b.center){$.center(a)}}var c=this.is('*')?this:'#jOverlayContent';var d=g?'absolute':'fixed';var e=/([^\/\\]+)\.(png|gif|jpeg|jpg|bmp)$/i.test(b.url);var f=b.imgLoading?"<img id='jOverlayLoading' src='"+b.imgLoading+"' style='position:"+d+"; z-index:"+(b.zIndex+9)+";'/>":'';$('body').prepend(f+"<div id='jOverlay' />"+"<div id='jOverlayContent' style='position:"+d+"; z-index:"+(b.zIndex+5)+"; display:none;'/>");$('#jOverlayLoading').load(function(){center(this)});if(g){$('select').hide();$('#jOverlayContent select').show()}$('#jOverlay').css({backgroundColor:b.color,position:d,top:'0px',left:'0px',filter:'alpha(opacity='+(b.opacity*100)+')',opacity:b.opacity,zIndex:b.zIndex,width:!g?'100%':$(window).width()+'px',height:!g?'100%':$(document).height()+'px'}).show();if(this.is('*')){i=this.prev();$('#jOverlayContent').html(this.show().attr('display',b.autoHide?'none':this.css('display')));if(!e){center('#jOverlayContent');$('#jOverlayContent').show();if(!b.url&&$.isFunction(b.success)){b.success(this)}}}if(e){$('<img/>').load(function(){var a=$.resize(this.width,this.height);$(this).css({width:a.width,height:a.height});$(c).html(this);center('#jOverlayContent');$('#jOverlayLoading').fadeOut(500);$('#jOverlayContent').show();if($.isFunction(b.success)){b.success(this)}}).error(function(){alert('Image ('+b.url+') not found.');$.closeOverlay()}).attr({'src':b.url,'alt':b.url})}if(b.url&&!e){$.ajax({type:b.method,data:b.data,url:b.url,success:function(a){$('#jOverlayLoading').fadeOut(500);$(c).html(a).show();center('#jOverlayContent');if($.isFunction(b.success)){b.success(a)}},error:function(){alert('URL ('+b.url+') not found.');$.closeOverlay()}})}if(g){$(window).scroll(function(){center('#jOverlayContent')});$(window).resize(function(){$('#jOverlay').css({width:$(window).width()+'px',height:$(document).height()+'px'});center('#jOverlayContent')})}$(document).keydown(function(a){if(a.keyCode==27){$.closeOverlay()}});if(b.bgClickToClose){$('#jOverlay').click($.closeOverlay)}if(Number(b.timeout)>0){jOverlayTimer=setTimeout($.closeOverlay,Number(b.timeout))}$('#jOverlayContent').css(b.css||{})};$.resize=function(a,b){var x=$(window).width()-150;var y=$(window).height()-150;if(a>x){b=b*(x/a);a=x;if(b>y){a=a*(y/b);b=y}}else if(b>y){a=a*(y/b);b=y;if(a>x){b=b*(x/a);a=x}}return{width:a,height:b}};$.center=function(a){var a=$(a);var b=a.width();a.css({width:b+'px',marginLeft:'-'+(b/2)+'px',marginTop:'-'+a.height()/2+'px',height:'auto',top:!g?'50%':$(window).scrollTop()+($(window).height()/2)+'px',left:'50%'})};$.fn.jOverlay.options={method:'GET',data:'',url:'',color:'#000',opacity:'0.6',zIndex:9999,center:true,imgLoading:'',bgClickToClose:true,success:null,timeout:0,autoHide:true,css:{}};$.closeOverlay=function(){if(g){$("select").show()}if(i!==null){if(i!==null){var a=$('#jOverlayContent').children();i.after(a.css('display',a.attr('display')));a.removeAttr('display')}}$('#jOverlayLoading, #jOverlayContent, #jOverlay').remove()}})(jQuery); | ||||
|   | ||||
							
								
								
									
										10
									
								
								js/util.js
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								js/util.js
									
									
									
									
									
								
							| @@ -272,18 +272,20 @@ function NoticeAttachments() { | ||||
|         color : '#000', | ||||
|         opacity : '0.6', | ||||
|         zIndex : 99, | ||||
|         center : true, | ||||
|         center : false, | ||||
|         imgLoading : $('address .url')[0].href+'theme/base/images/illustrations/illu_progress_loading-01.gif', | ||||
|         bgClickToClose : true, | ||||
|         success : function() { | ||||
|             $('#jOverlayContent').append('<button>×</button>'); | ||||
|             $('#jOverlayContent button').click($.closeOverlay); | ||||
|         }, | ||||
|         timeout : 0 | ||||
|         timeout : 0, | ||||
|         autoHide : true, | ||||
|         css : {'max-width':'502px', 'top':'22.5%', 'left':'32.5%'} | ||||
|     }; | ||||
|  | ||||
|     $('#content .notice a.attachment').click(function() { | ||||
|         $().jOverlay({url: $('address .url')[0].href+'/attachment/' + ($(this).attr('id').substring('attachment'.length + 1)) + '/ajax'}); | ||||
|         $().jOverlay({url: $('address .url')[0].href+'attachment/' + ($(this).attr('id').substring('attachment'.length + 1)) + '/ajax'}); | ||||
|         return false; | ||||
|     }); | ||||
|  | ||||
| @@ -296,7 +298,7 @@ function NoticeAttachments() { | ||||
|  | ||||
|             if (anchor.children('img').length == 0) { | ||||
|                 t = setTimeout(function() { | ||||
|                     $.get($('address .url')[0].href+'/attachment/' + (anchor.attr('id').substring('attachment'.length + 1)) + '/thumbnail', null, function(data) { | ||||
|                     $.get($('address .url')[0].href+'attachment/' + (anchor.attr('id').substring('attachment'.length + 1)) + '/thumbnail', null, function(data) { | ||||
|                         anchor.append(data); | ||||
|                     }); | ||||
|                 }, 500); | ||||
|   | ||||
| @@ -40,7 +40,7 @@ class ShortUrlApi | ||||
|     } | ||||
|  | ||||
|     private function is_long($url) { | ||||
|         return strlen($url) >= $this->long_limit; | ||||
|         return strlen($url) >= common_config('site', 'shorturllength'); | ||||
|     } | ||||
|  | ||||
|     protected function http_post($data) { | ||||
|   | ||||
| @@ -247,7 +247,6 @@ class Action extends HTMLOutputter // lawsuit | ||||
|                                                'src' => common_path('js/jquery.joverlay.min.js')), | ||||
|                                ' '); | ||||
|  | ||||
|  | ||||
|                 Event::handle('EndShowJQueryScripts', array($this)); | ||||
|             } | ||||
|             if (Event::handle('StartShowLaconicaScripts', array($this))) { | ||||
| @@ -422,11 +421,13 @@ class Action extends HTMLOutputter // lawsuit | ||||
|                     $this->menuItem(common_local_url('smssettings'), | ||||
|                                     _('Connect'), _('Connect to SMS, Twitter'), false, 'nav_connect'); | ||||
|                 } | ||||
|                 $this->menuItem(common_local_url('invite'), | ||||
|                                 _('Invite'), | ||||
|                                 sprintf(_('Invite friends and colleagues to join you on %s'), | ||||
|                                         common_config('site', 'name')), | ||||
|                                 false, 'nav_invitecontact'); | ||||
|                 if (common_config('invite', 'enabled')) { | ||||
|                     $this->menuItem(common_local_url('invite'), | ||||
|                                     _('Invite'), | ||||
|                                     sprintf(_('Invite friends and colleagues to join you on %s'), | ||||
|                                             common_config('site', 'name')), | ||||
|                                     false, 'nav_invitecontact'); | ||||
|                 } | ||||
|                 $this->menuItem(common_local_url('logout'), | ||||
|                                 _('Logout'), _('Logout from the site'), false, 'nav_logout'); | ||||
|             } | ||||
| @@ -964,12 +965,16 @@ class Action extends HTMLOutputter // lawsuit | ||||
|         $action = $this->trimmed('action'); | ||||
|         $args   = $this->args; | ||||
|         unset($args['action']); | ||||
|         if (common_config('site', 'fancy')) { | ||||
|             unset($args['p']); | ||||
|         } | ||||
|         if (array_key_exists('submit', $args)) { | ||||
|             unset($args['submit']); | ||||
|         } | ||||
|         foreach (array_keys($_COOKIE) as $cookie) { | ||||
|             unset($args[$cookie]); | ||||
|         } | ||||
|  | ||||
|         return common_local_url($action, $args); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -120,6 +120,7 @@ $config = | ||||
|               'private' => false, | ||||
|               'ssl' => 'never', | ||||
|               'sslserver' => null, | ||||
|               'shorturllength' => 30, | ||||
|               'dupelimit' => 60), # default for same person saying the same thing | ||||
|         'syslog' => | ||||
|         array('appname' => 'laconica', # for syslog | ||||
| @@ -175,6 +176,8 @@ $config = | ||||
|               'host' => null, # only set if != server | ||||
|               'debug' => false, # print extra debug info | ||||
|               'public' => array()), # JIDs of users who want to receive the public stream | ||||
|         'invite' => | ||||
|         array('enabled' => true), | ||||
|         'sphinx' => | ||||
|         array('enabled' => false, | ||||
|               'server' => 'localhost', | ||||
|   | ||||
| @@ -23,6 +23,13 @@ if (!defined('LACONICA')) { | ||||
|  | ||||
| class Daemon | ||||
| { | ||||
|     var $daemonize = true; | ||||
|  | ||||
|     function __construct($daemonize = true) | ||||
|     { | ||||
|         $this->daemonize = $daemonize; | ||||
|     } | ||||
|  | ||||
|     function name() | ||||
|     { | ||||
|         return null; | ||||
| @@ -129,12 +136,16 @@ class Daemon | ||||
|             common_log(LOG_INFO, $this->name() . ' already running. Exiting.'); | ||||
|             exit(0); | ||||
|         } | ||||
|         if ($this->background()) { | ||||
|             $this->writePidFile(); | ||||
|             $this->changeUser(); | ||||
|             $this->run(); | ||||
|             $this->clearPidFile(); | ||||
|  | ||||
|         if ($this->daemonize) { | ||||
|             common_log(LOG_INFO, 'Backgrounding daemon "'.$this->name().'"'); | ||||
|             $this->background(); | ||||
|         } | ||||
|  | ||||
|         $this->writePidFile(); | ||||
|         $this->changeUser(); | ||||
|         $this->run(); | ||||
|         $this->clearPidFile(); | ||||
|     } | ||||
|  | ||||
|     function run() | ||||
|   | ||||
| @@ -35,6 +35,20 @@ if (!defined('LACONICA')) { | ||||
| require_once INSTALLDIR . '/lib/accountsettingsaction.php'; | ||||
| require_once INSTALLDIR . '/lib/webcolor.php'; | ||||
|  | ||||
| /** | ||||
|  * Base class for setting a user or group design | ||||
|  * | ||||
|  * Shows the design setting form and also handles some things like saving | ||||
|  * background images, and fetching a default design | ||||
|  * | ||||
|  * @category Settings | ||||
|  * @package  Laconica | ||||
|  * @author   Zach Copley <zach@controlyourself.ca> | ||||
|  * @author   Sarven Capadisli <csarven@controlyourself.ca> | ||||
|  * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 | ||||
|  * @link     http://laconi.ca/ | ||||
|  */ | ||||
|  | ||||
| class DesignSettingsAction extends AccountSettingsAction | ||||
| { | ||||
|  | ||||
| @@ -63,6 +77,14 @@ class DesignSettingsAction extends AccountSettingsAction | ||||
|         'with a background image and a colour palette of your choice.'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Shows the design settings form | ||||
|      * | ||||
|      * @param Design $design a working design to show | ||||
|      * | ||||
|      * @return nothing | ||||
|      */ | ||||
|  | ||||
|     function showDesignForm($design) | ||||
|     { | ||||
|  | ||||
| @@ -94,7 +116,8 @@ class DesignSettingsAction extends AccountSettingsAction | ||||
|  | ||||
|         if (!empty($design->backgroundimage)) { | ||||
|  | ||||
|             $this->elementStart('li', array('id' => 'design_background-image_onoff')); | ||||
|             $this->elementStart('li', array('id' => | ||||
|                 'design_background-image_onoff')); | ||||
|  | ||||
|             $this->element('img', array('src' => | ||||
|                 Design::url($design->backgroundimage))); | ||||
| @@ -136,7 +159,7 @@ class DesignSettingsAction extends AccountSettingsAction | ||||
|             $this->elementStart('li'); | ||||
|             $this->checkbox('design_background-image_repeat', | ||||
|                             _('Tile background image'), | ||||
|                             ($design->disposition & BACKGROUND_TILE) ? true : false ); | ||||
|                             ($design->disposition & BACKGROUND_TILE) ? true : false); | ||||
|             $this->elementEnd('li'); | ||||
|         } | ||||
|  | ||||
| @@ -212,18 +235,19 @@ class DesignSettingsAction extends AccountSettingsAction | ||||
|                                          'maxlength' => '7', | ||||
|                                          'size' => '7', | ||||
|                                          'value' => '#' . $lcolor->hexValue())); | ||||
|             $this->elementEnd('li'); | ||||
|  | ||||
|            $this->elementEnd('li'); | ||||
|         } catch (WebColorException $e) { | ||||
|             common_log(LOG_ERR, 'Bad color values in design ID: ' .$design->id); | ||||
|         } | ||||
|  | ||||
|        } catch (WebColorException $e) { | ||||
|            common_log(LOG_ERR, 'Bad color values in design ID: ' . | ||||
|                $design->id); | ||||
|        } | ||||
|         $this->elementEnd('ul'); | ||||
|         $this->elementEnd('fieldset'); | ||||
|  | ||||
|        $this->elementEnd('ul'); | ||||
|        $this->elementEnd('fieldset'); | ||||
|         $this->submit('defaults', _('Use defaults'), 'submit form_action-default', | ||||
|             'defaults', _('Restore default designs')); | ||||
|  | ||||
|        $this->element('input', array('id' => 'settings_design_reset', | ||||
|         $this->element('input', array('id' => 'settings_design_reset', | ||||
|                                      'type' => 'reset', | ||||
|                                      'value' => 'Reset', | ||||
|                                      'class' => 'submit form_action-primary', | ||||
| @@ -271,8 +295,8 @@ class DesignSettingsAction extends AccountSettingsAction | ||||
|  | ||||
|         if ($this->arg('save')) { | ||||
|             $this->saveDesign(); | ||||
|         } else if ($this->arg('reset')) { | ||||
|             $this->resetDesign(); | ||||
|         } else if ($this->arg('defaults')) { | ||||
|             $this->restoreDefaults(); | ||||
|         } else { | ||||
|             $this->showForm(_('Unexpected form submission.')); | ||||
|         } | ||||
| @@ -316,7 +340,7 @@ class DesignSettingsAction extends AccountSettingsAction | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get a default user design | ||||
|      * Get a default design | ||||
|      * | ||||
|      * @return Design design | ||||
|      */ | ||||
| @@ -358,7 +382,16 @@ class DesignSettingsAction extends AccountSettingsAction | ||||
|         return $design; | ||||
|     } | ||||
|  | ||||
|     function saveBackgroundImage($design) { | ||||
|     /** | ||||
|      * Save the background image, if any, and set its disposition | ||||
|      * | ||||
|      * @param Design $design a working design to attach the img to | ||||
|      * | ||||
|      * @return nothing | ||||
|      */ | ||||
|  | ||||
|     function saveBackgroundImage($design) | ||||
|     { | ||||
|  | ||||
|         // Now that we have a Design ID we can add a file to the design. | ||||
|         // XXX: This is an additional DB hit, but figured having the image | ||||
| @@ -371,12 +404,12 @@ class DesignSettingsAction extends AccountSettingsAction | ||||
|             $filepath = null; | ||||
|  | ||||
|             try { | ||||
|                     $imagefile = | ||||
|                         ImageFile::fromUpload('design_background-image_file'); | ||||
|                 } catch (Exception $e) { | ||||
|                     $this->showForm($e->getMessage()); | ||||
|                     return; | ||||
|                 } | ||||
|                 $imagefile = | ||||
|                     ImageFile::fromUpload('design_background-image_file'); | ||||
|             } catch (Exception $e) { | ||||
|                 $this->showForm($e->getMessage()); | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             $filename = Design::filename($design->id, | ||||
|                 image_type_to_extension($imagefile->type), | ||||
| @@ -386,7 +419,14 @@ class DesignSettingsAction extends AccountSettingsAction | ||||
|  | ||||
|             move_uploaded_file($imagefile->filepath, $filepath); | ||||
|  | ||||
|             // delete any old backround img laying around | ||||
|  | ||||
|             if (isset($design->backgroundimage)) { | ||||
|                 @unlink(Design::path($design->backgroundimage)); | ||||
|             } | ||||
|  | ||||
|             $original = clone($design); | ||||
|  | ||||
|             $design->backgroundimage = $filename; | ||||
|  | ||||
|             // default to on, no tile | ||||
| @@ -403,4 +443,35 @@ class DesignSettingsAction extends AccountSettingsAction | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Restore the user or group design to system defaults | ||||
|      * | ||||
|      * @return nothing | ||||
|      */ | ||||
|  | ||||
|     function restoreDefaults() | ||||
|     { | ||||
|         $design   = $this->getWorkingDesign(); | ||||
|         $default  = $this->defaultDesign(); | ||||
|         $original = clone($design); | ||||
|  | ||||
|         $design->backgroundcolor = $default->backgroundcolor; | ||||
|         $design->contentcolor    = $default->contentcolor; | ||||
|         $design->sidebarcolor    = $default->sidebarcolor; | ||||
|         $design->textcolor       = $default->textcolor; | ||||
|         $design->linkcolor       = $default->linkcolor; | ||||
|  | ||||
|         $design->setDisposition(false, true, false); | ||||
|  | ||||
|         $result = $design->update($original); | ||||
|  | ||||
|         if ($result === false) { | ||||
|             common_log_db_error($design, 'UPDATE', __FILE__); | ||||
|             $this->showForm(_('Couldn\'t update your design.')); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         $this->showForm(_('Design defaults restored.'), true); | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -213,12 +213,14 @@ class FacebookAction extends Action | ||||
|             array('href' => 'index.php', 'title' => _('Home')), _('Home')); | ||||
|         $this->elementEnd('li'); | ||||
|  | ||||
|         $this->elementStart('li', | ||||
|             array('class' => | ||||
|                 ($this->action == 'facebookinvite') ? 'current' : 'facebook_invite')); | ||||
|         $this->element('a', | ||||
|             array('href' => 'invite.php', 'title' => _('Invite')), _('Invite')); | ||||
|         $this->elementEnd('li'); | ||||
|         if (common_config('invite', 'enabled')) { | ||||
|             $this->elementStart('li', | ||||
|                 array('class' => | ||||
|                     ($this->action == 'facebookinvite') ? 'current' : 'facebook_invite')); | ||||
|             $this->element('a', | ||||
|                 array('href' => 'invite.php', 'title' => _('Invite')), _('Invite')); | ||||
|             $this->elementEnd('li'); | ||||
|         } | ||||
|  | ||||
|         $this->elementStart('li', | ||||
|             array('class' => | ||||
|   | ||||
| @@ -130,30 +130,46 @@ class GroupEditForm extends Form | ||||
|  | ||||
|     function formData() | ||||
|     { | ||||
|         if ($this->group) { | ||||
|             $id = $this->group->id; | ||||
|             $nickname = $this->group->nickname; | ||||
|             $fullname = $this->group->fullname; | ||||
|             $homepage = $this->group->homepage; | ||||
|             $description = $this->group->description; | ||||
|             $location = $this->group->location; | ||||
|         } else { | ||||
|             $id = ''; | ||||
|             $nickname = ''; | ||||
|             $fullname = ''; | ||||
|             $homepage = ''; | ||||
|             $description = ''; | ||||
|             $location = ''; | ||||
|         } | ||||
|  | ||||
|         $this->out->elementStart('ul', 'form_data'); | ||||
|         $this->out->elementStart('li'); | ||||
|         $this->out->hidden('groupid', $this->group->id); | ||||
|         $this->out->hidden('groupid', $id); | ||||
|         $this->out->input('nickname', _('Nickname'), | ||||
|                      ($this->out->arg('nickname')) ? $this->out->arg('nickname') : $this->group->nickname, | ||||
|                      ($this->out->arg('nickname')) ? $this->out->arg('nickname') : $nickname, | ||||
|                      _('1-64 lowercase letters or numbers, no punctuation or spaces')); | ||||
|         $this->out->elementEnd('li'); | ||||
|         $this->out->elementStart('li'); | ||||
|         $this->out->input('fullname', _('Full name'), | ||||
|                      ($this->out->arg('fullname')) ? $this->out->arg('fullname') : $this->group->fullname); | ||||
|                      ($this->out->arg('fullname')) ? $this->out->arg('fullname') : $fullname); | ||||
|         $this->out->elementEnd('li'); | ||||
|         $this->out->elementStart('li'); | ||||
|         $this->out->input('homepage', _('Homepage'), | ||||
|                      ($this->out->arg('homepage')) ? $this->out->arg('homepage') : $this->group->homepage, | ||||
|                      ($this->out->arg('homepage')) ? $this->out->arg('homepage') : $homepage, | ||||
|                      _('URL of the homepage or blog of the group or topic')); | ||||
|         $this->out->elementEnd('li'); | ||||
|         $this->out->elementStart('li'); | ||||
|         $this->out->textarea('description', _('Description'), | ||||
|                         ($this->out->arg('description')) ? $this->out->arg('description') : $this->group->description, | ||||
|                         ($this->out->arg('description')) ? $this->out->arg('description') : $description, | ||||
|                         _('Describe the group or topic in 140 chars')); | ||||
|         $this->out->elementEnd('li'); | ||||
|         $this->out->elementStart('li'); | ||||
|         $this->out->input('location', _('Location'), | ||||
|                      ($this->out->arg('location')) ? $this->out->arg('location') : $this->group->location, | ||||
|                      ($this->out->arg('location')) ? $this->out->arg('location') : $location, | ||||
|                      _('Location for the group, if any, like "City, State (or Region), Country"')); | ||||
|         $this->out->elementEnd('li'); | ||||
|         if (common_config('group', 'maxaliases') > 0) { | ||||
|   | ||||
| @@ -89,6 +89,7 @@ class JSONSearchResultsList | ||||
|     function show() | ||||
|     { | ||||
|         $cnt = 0; | ||||
|         $this->max_id = 0; | ||||
|  | ||||
|         $time_start = microtime(true); | ||||
|  | ||||
|   | ||||
| @@ -108,7 +108,7 @@ function get_all_languages() { | ||||
| 		'el'      => array('q' => 0.1, 'lang' => 'el',    'name' => 'Greek', 'direction' => 'ltr'), | ||||
| 		'en-us'   => array('q' => 1, 'lang' => 'en_US', 'name' => 'English (US)', 'direction' => 'ltr'), | ||||
| 		'en-gb'   => array('q' => 1, 'lang' => 'en_GB', 'name' => 'English (British)', 'direction' => 'ltr'), | ||||
| 		'en'      => array('q' => 1, 'lang' => 'en',    'name' => 'English', 'direction' => 'ltr'), | ||||
| 		'en'      => array('q' => 1, 'lang' => 'en_US',    'name' => 'English (US)', 'direction' => 'ltr'), | ||||
| 		'es'      => array('q' => 1, 'lang' => 'es',    'name' => 'Spanish', 'direction' => 'ltr'), | ||||
| 		'fi'      => array('q' => 1, 'lang' => 'fi', 'name' => 'Finnish', 'direction' => 'ltr'), | ||||
| 		'fr-fr'   => array('q' => 1, 'lang' => 'fr_FR', 'name' => 'French', 'direction' => 'ltr'), | ||||
|   | ||||
| @@ -108,7 +108,9 @@ class ProfileAction extends OwnerDesignAction | ||||
|  | ||||
|         $this->element('h2', null, _('Subscriptions')); | ||||
|  | ||||
|         if ($profile) { | ||||
|         $cnt = 0; | ||||
|  | ||||
|         if (!empty($profile)) { | ||||
|             $pml = new ProfileMiniList($profile, $this); | ||||
|             $cnt = $pml->show(); | ||||
|             if ($cnt == 0) { | ||||
| @@ -137,7 +139,9 @@ class ProfileAction extends OwnerDesignAction | ||||
|  | ||||
|         $this->element('h2', null, _('Subscribers')); | ||||
|  | ||||
|         if ($profile) { | ||||
|         $cnt = 0; | ||||
|  | ||||
|         if (!empty($profile)) { | ||||
|             $pml = new ProfileMiniList($profile, $this); | ||||
|             $cnt = $pml->show(); | ||||
|             if ($cnt == 0) { | ||||
|   | ||||
| @@ -47,6 +47,7 @@ define('PROFILES_PER_MINILIST', 27); | ||||
|  | ||||
| class ProfileMiniList extends ProfileList | ||||
| { | ||||
|  | ||||
|     function startList() | ||||
|     { | ||||
|         $this->out->elementStart('ul', 'entities users xoxo'); | ||||
| @@ -56,6 +57,23 @@ class ProfileMiniList extends ProfileList | ||||
|     { | ||||
|         return new ProfileMiniListItem($profile, $this->action); | ||||
|     } | ||||
|  | ||||
|     function showProfiles() | ||||
|     { | ||||
|         $cnt = 0; | ||||
|  | ||||
|         while ($this->profile->fetch()) { | ||||
|             $cnt++; | ||||
|             if ($cnt > PROFILES_PER_MINILIST) { | ||||
|                 break; | ||||
|             } | ||||
|             $pli = $this->newListItem($this->profile); | ||||
|             $pli->show(); | ||||
|         } | ||||
|  | ||||
|         return $cnt; | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| class ProfileMiniListItem extends ProfileListItem | ||||
|   | ||||
| @@ -31,8 +31,10 @@ class QueueHandler extends Daemon | ||||
| { | ||||
|     var $_id = 'generic'; | ||||
|  | ||||
|     function QueueHandler($id=null) | ||||
|     function __construct($id=null, $daemonize=true) | ||||
|     { | ||||
|         parent::__construct($daemonize); | ||||
|  | ||||
|         if ($id) { | ||||
|             $this->set_id($id); | ||||
|         } | ||||
|   | ||||
| @@ -100,7 +100,7 @@ class SubGroupNav extends Widget | ||||
|                                          $this->user->nickname), | ||||
|                                  $action == 'usergroups', | ||||
|                                  'nav_usergroups'); | ||||
|             if (!is_null($cur) && $this->user->id === $cur->id) { | ||||
|             if (common_config('invite', 'enabled') && !is_null($cur) && $this->user->id === $cur->id) { | ||||
|                 $this->out->menuItem(common_local_url('invite'), | ||||
|                                      _('Invite'), | ||||
|                                      sprintf(_('Invite friends and colleagues to join you on %s'), | ||||
|   | ||||
							
								
								
									
										63
									
								
								lib/util.php
									
									
									
									
									
								
							
							
						
						
									
										63
									
								
								lib/util.php
									
									
									
									
									
								
							| @@ -114,7 +114,7 @@ function common_check_user($nickname, $password) | ||||
|         return false; | ||||
|     } | ||||
|     $user = User::staticGet('nickname', $nickname); | ||||
|     if (is_null($user)) { | ||||
|     if (is_null($user) || $user === false) { | ||||
|         return false; | ||||
|     } else { | ||||
|         if (0 == strcmp(common_munge_password($password, $user->id), | ||||
| @@ -145,7 +145,6 @@ function common_ensure_session() | ||||
|     } | ||||
|     if (!common_have_session()) { | ||||
|         if (common_config('sessions', 'handle')) { | ||||
|             common_log(LOG_INFO, "Using our own session handler"); | ||||
|             Session::setSaveHandler(); | ||||
|         } | ||||
|         @session_start(); | ||||
| @@ -500,17 +499,19 @@ function common_linkify($url) { | ||||
|     // It comes in special'd, so we unspecial it before passing to the stringifying | ||||
|     // functions | ||||
|     $url = htmlspecialchars_decode($url); | ||||
|     $display = File_redirection::_canonUrl($url); | ||||
|  | ||||
|     $canon = File_redirection::_canonUrl($url); | ||||
|  | ||||
|     $longurl_data = File_redirection::where($url); | ||||
|     if (is_array($longurl_data)) { | ||||
|         $longurl = $longurl_data['url']; | ||||
|     } elseif (is_string($longurl_data)) { | ||||
|         $longurl = $longurl_data; | ||||
|     } else { | ||||
|         die('impossible to linkify'); | ||||
|         throw new ServerException("Can't linkify url '$url'"); | ||||
|     } | ||||
|  | ||||
|     $attrs = array('href' => $longurl, 'rel' => 'external'); | ||||
|     $attrs = array('href' => $canon, 'rel' => 'external'); | ||||
|  | ||||
|     $is_attachment = false; | ||||
|     $attachment_id = null; | ||||
| @@ -528,13 +529,13 @@ function common_linkify($url) { | ||||
|         } | ||||
|     } | ||||
|  | ||||
| // if this URL is an attachment, then we set class='attachment' and id='attahcment-ID' | ||||
| // where ID is the id of the attachment for the given URL. | ||||
| // | ||||
| // we need a better test telling what can be shown as an attachment | ||||
| // we're currently picking up oembeds only. | ||||
| // I think the best option is another file_view table in the db | ||||
| // and associated dbobject. | ||||
|     // if this URL is an attachment, then we set class='attachment' and id='attahcment-ID' | ||||
|     // where ID is the id of the attachment for the given URL. | ||||
|     // | ||||
|     // we need a better test telling what can be shown as an attachment | ||||
|     // we're currently picking up oembeds only. | ||||
|     // I think the best option is another file_view table in the db | ||||
|     // and associated dbobject. | ||||
|  | ||||
|     $query = "select file_oembed.file_id as file_id from file join file_oembed on file.id = file_oembed.file_id where file.url='$longurl'"; | ||||
|     $file = new File; | ||||
| @@ -564,7 +565,7 @@ function common_linkify($url) { | ||||
|         $attrs['id'] = "attachment-{$attachment_id}"; | ||||
|     } | ||||
|  | ||||
|     return XMLStringer::estring('a', $attrs, $display); | ||||
|     return XMLStringer::estring('a', $attrs, $url); | ||||
| } | ||||
|  | ||||
| function common_shorten_links($text) | ||||
| @@ -982,15 +983,20 @@ function common_ensure_syslog() | ||||
|     } | ||||
| } | ||||
|  | ||||
| function common_log_line($priority, $msg) | ||||
| { | ||||
|     static $syslog_priorities = array('LOG_EMERG', 'LOG_ALERT', 'LOG_CRIT', 'LOG_ERR', | ||||
|                                       'LOG_WARNING', 'LOG_NOTICE', 'LOG_INFO', 'LOG_DEBUG'); | ||||
|     return date('Y-m-d H:i:s') . ' ' . $syslog_priorities[$priority] . ': ' . $msg . "\n"; | ||||
| } | ||||
|  | ||||
| function common_log($priority, $msg, $filename=null) | ||||
| { | ||||
|     $logfile = common_config('site', 'logfile'); | ||||
|     if ($logfile) { | ||||
|         $log = fopen($logfile, "a"); | ||||
|         if ($log) { | ||||
|             static $syslog_priorities = array('LOG_EMERG', 'LOG_ALERT', 'LOG_CRIT', 'LOG_ERR', | ||||
|                                               'LOG_WARNING', 'LOG_NOTICE', 'LOG_INFO', 'LOG_DEBUG'); | ||||
|             $output = date('Y-m-d H:i:s') . ' ' . $syslog_priorities[$priority] . ': ' . $msg . "\n"; | ||||
|             $output = common_log_line($priority, $msg); | ||||
|             fwrite($log, $output); | ||||
|             fclose($log); | ||||
|         } | ||||
| @@ -1221,18 +1227,39 @@ function common_canonical_sms($sms) | ||||
| function common_error_handler($errno, $errstr, $errfile, $errline, $errcontext) | ||||
| { | ||||
|     switch ($errno) { | ||||
|  | ||||
|      case E_ERROR: | ||||
|      case E_COMPILE_ERROR: | ||||
|      case E_CORE_ERROR: | ||||
|      case E_USER_ERROR: | ||||
|         common_log(LOG_ERR, "[$errno] $errstr ($errfile:$errline)"); | ||||
|         exit(1); | ||||
|      case E_PARSE: | ||||
|      case E_RECOVERABLE_ERROR: | ||||
|         common_log(LOG_ERR, "[$errno] $errstr ($errfile:$errline) [ABORT]"); | ||||
|         die(); | ||||
|         break; | ||||
|  | ||||
|      case E_WARNING: | ||||
|      case E_COMPILE_WARNING: | ||||
|      case E_CORE_WARNING: | ||||
|      case E_USER_WARNING: | ||||
|         common_log(LOG_WARNING, "[$errno] $errstr ($errfile:$errline)"); | ||||
|         break; | ||||
|  | ||||
|      case E_NOTICE: | ||||
|      case E_USER_NOTICE: | ||||
|         common_log(LOG_NOTICE, "[$errno] $errstr ($errfile:$errline)"); | ||||
|         break; | ||||
|  | ||||
|      case E_STRICT: | ||||
|      case E_DEPRECATED: | ||||
|      case E_USER_DEPRECATED: | ||||
|         // XXX: config variable to log this stuff, too | ||||
|         break; | ||||
|  | ||||
|      default: | ||||
|         common_log(LOG_ERR, "[$errno] $errstr ($errfile:$errline) [UNKNOWN LEVEL, die()'ing]"); | ||||
|         die(); | ||||
|         break; | ||||
|     } | ||||
|  | ||||
|     // FIXME: show error page if we're on the Web | ||||
|   | ||||
| @@ -66,7 +66,7 @@ class FBConnectauthAction extends Action | ||||
|             // User is already logged in.  Does she already have a linked Facebook acct? | ||||
|             $flink = Foreign_link::getByForeignID($this->fbuid, FACEBOOK_CONNECT_SERVICE); | ||||
|  | ||||
|             if ($flink) { | ||||
|             if (!empty($flink)) { | ||||
|  | ||||
|                 // User already has a linked Facebook account and shouldn't be here | ||||
|                 common_debug('There is already a local user (' . $flink->user_id . | ||||
| @@ -337,7 +337,7 @@ class FBConnectauthAction extends Action | ||||
|         if ($flink) { | ||||
|             $user = $flink->getUser(); | ||||
|  | ||||
|             if ($user) { | ||||
|             if (!empty($user)) { | ||||
|  | ||||
|                 common_debug("Logged in Facebook user $flink->foreign_id as user $user->id ($user->nickname)"); | ||||
|  | ||||
|   | ||||
| @@ -10,22 +10,21 @@ | ||||
| #site_nav_global_primary #nav_fb { | ||||
| position:relative; | ||||
| margin-left:18px; | ||||
| margin-right:-7px; | ||||
| } | ||||
|  | ||||
| #nav_fb .fb_profile_pic_rendered img { | ||||
| position:relative; | ||||
| top:3px; | ||||
| left:0; | ||||
| #nav_fb #fbc_profile-pic { | ||||
| position:absolute; | ||||
| top:-3px; | ||||
| left:-18px; | ||||
| display:inline; | ||||
| border:1px solid #3B5998; | ||||
| padding:1px; | ||||
| } | ||||
|  | ||||
| #nav_fb img { | ||||
| #nav_fb #fb_favicon { | ||||
| position:absolute; | ||||
| top:-13px; | ||||
| left:-11px; | ||||
| left:-25px; | ||||
| display:inline; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -69,100 +69,158 @@ class FBConnectPlugin extends Plugin | ||||
|     // Add in xmlns:fb | ||||
|     function onStartShowHTML($action) | ||||
|     { | ||||
|         // XXX: Horrible hack to make Safari, FF2, and Chrome work with | ||||
|         // Facebook Connect. These browser cannot use Facebook's | ||||
|         // DOM parsing routines unless the mime type of the page is | ||||
|         // text/html even though Facebook Connect uses XHTML.  This is | ||||
|         // A bug in Facebook Connect, and this is a temporary solution | ||||
|         // until they fix their JavaScript libs. | ||||
|         header('Content-Type: text/html'); | ||||
|  | ||||
|         $action->extraHeaders(); | ||||
|         if ($this->reqFbScripts($action)) { | ||||
|  | ||||
|         $action->startXML('html', | ||||
|             '-//W3C//DTD XHTML 1.0 Strict//EN', | ||||
|             'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'); | ||||
|             // XXX: Horrible hack to make Safari, FF2, and Chrome work with | ||||
|             // Facebook Connect. These browser cannot use Facebook's | ||||
|             // DOM parsing routines unless the mime type of the page is | ||||
|             // text/html even though Facebook Connect uses XHTML.  This is | ||||
|             // A bug in Facebook Connect, and this is a temporary solution | ||||
|             // until they fix their JavaScript libs. | ||||
|             header('Content-Type: text/html'); | ||||
|  | ||||
|         $language = $action->getLanguage(); | ||||
|             $action->extraHeaders(); | ||||
|  | ||||
|         $action->elementStart('html', | ||||
|             array('xmlns'  => 'http://www.w3.org/1999/xhtml', | ||||
|                   'xmlns:fb' => 'http://www.facebook.com/2008/fbml', | ||||
|                   'xml:lang' => $language, | ||||
|                   'lang'     => $language)); | ||||
|             $action->startXML('html', | ||||
|                 '-//W3C//DTD XHTML 1.0 Strict//EN', | ||||
|                 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'); | ||||
|  | ||||
|         return false; | ||||
|             $language = $action->getLanguage(); | ||||
|  | ||||
|             $action->elementStart('html', | ||||
|                 array('xmlns'  => 'http://www.w3.org/1999/xhtml', | ||||
|                       'xmlns:fb' => 'http://www.facebook.com/2008/fbml', | ||||
|                       'xml:lang' => $language, | ||||
|                       'lang'     => $language)); | ||||
|  | ||||
|             return false; | ||||
|  | ||||
|         } else { | ||||
|  | ||||
|             return true; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Note: this script needs to appear in the <body> | ||||
|  | ||||
|     function onStartShowHeader($action) | ||||
|     { | ||||
|         $apikey = common_config('facebook', 'apikey'); | ||||
|         $plugin_path = common_path('plugins/FBConnect'); | ||||
|         if ($this->reqFbScripts($action)) { | ||||
|  | ||||
|         $login_url = common_local_url('FBConnectAuth'); | ||||
|         $logout_url = common_local_url('logout'); | ||||
|             $apikey = common_config('facebook', 'apikey'); | ||||
|             $plugin_path = common_path('plugins/FBConnect'); | ||||
|  | ||||
|         // XXX: Facebook says we don't need this FB_RequireFeatures(), | ||||
|         // but we actually do, for IE and Safari. Gar. | ||||
|             $login_url = common_local_url('FBConnectAuth'); | ||||
|             $logout_url = common_local_url('logout'); | ||||
|  | ||||
|         $html = sprintf('<script type="text/javascript"> | ||||
|                             window.onload = function () { | ||||
|                                 FB_RequireFeatures( | ||||
|                                     ["XFBML"], | ||||
|                                         function() { | ||||
|                                             FB.Facebook.init("%s", "../xd_receiver.html"); | ||||
|                                         } | ||||
|                                     ); } | ||||
|             // XXX: Facebook says we don't need this FB_RequireFeatures(), | ||||
|             // but we actually do, for IE and Safari. Gar. | ||||
|  | ||||
|                             function goto_login() { | ||||
|                                 window.location = "%s"; | ||||
|                             } | ||||
|             $html = sprintf('<script type="text/javascript"> | ||||
|                                 window.onload = function () { | ||||
|                                     FB_RequireFeatures( | ||||
|                                         ["XFBML"], | ||||
|                                             function() { | ||||
|                                                 FB.Facebook.init("%s", "../xd_receiver.html"); | ||||
|                                             } | ||||
|                                         ); } | ||||
|  | ||||
|                             function goto_logout() { | ||||
|                                 window.location = "%s"; | ||||
|                             } | ||||
|                           </script>', $apikey, | ||||
|                               $login_url, $logout_url); | ||||
|                                 function goto_login() { | ||||
|                                     window.location = "%s"; | ||||
|                                 } | ||||
|  | ||||
|                                 function goto_logout() { | ||||
|                                     window.location = "%s"; | ||||
|                                 } | ||||
|                               </script>', $apikey, | ||||
|                                   $login_url, $logout_url); | ||||
|  | ||||
|             $action->raw($html); | ||||
|         } | ||||
|  | ||||
|         $action->raw($html); | ||||
|     } | ||||
|  | ||||
|     // Note: this script needs to appear as close as possible to </body> | ||||
|  | ||||
|     function onEndShowFooter($action) | ||||
|     { | ||||
|         if ($this->reqFbScripts($action)) { | ||||
|  | ||||
|         $action->element('script', | ||||
|             array('type' => 'text/javascript', | ||||
|                   'src'  => 'http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php'), | ||||
|                   ''); | ||||
|             $action->element('script', | ||||
|                 array('type' => 'text/javascript', | ||||
|                       'src'  => 'http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php'), | ||||
|                       ''); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function onEndShowLaconicaStyles($action) | ||||
|     { | ||||
|         $action->element('link', array('rel' => 'stylesheet', | ||||
|             'type' => 'text/css', | ||||
|             'href' => common_path('plugins/FBConnect/FBConnectPlugin.css'))); | ||||
|  | ||||
|         if ($this->reqFbScripts($action)) { | ||||
|  | ||||
|             $action->element('link', array('rel' => 'stylesheet', | ||||
|                 'type' => 'text/css', | ||||
|                 'href' => common_path('plugins/FBConnect/FBConnectPlugin.css'))); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function onStartPrimaryNav($action) | ||||
|     /** | ||||
|      * Does the Action we're plugged into require the FB Scripts?  We only | ||||
|      * want to output FB namespace, scripts, CSS, etc. on the pages that | ||||
|      * really need them. | ||||
|      * | ||||
|      * @param Action the action in question | ||||
|      * | ||||
|      * @return boolean true | ||||
|      */ | ||||
|  | ||||
|     function reqFbScripts($action) { | ||||
|  | ||||
|         // If you're logged in w/FB Connect, you always need the FB stuff | ||||
|  | ||||
|         $fbuid = $this->loggedIn(); | ||||
|  | ||||
|         if (!empty($fbuid)) { | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         // List of actions that require FB stuff | ||||
|  | ||||
|         $needy = array('FBConnectLoginAction', | ||||
|                        'FBConnectauthAction', | ||||
|                        'FBConnectSettingsAction'); | ||||
|  | ||||
|         if (in_array(get_class($action), $needy)) { | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         return false; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Is the user currently logged in with FB Connect? | ||||
|      * | ||||
|      * @return mixed $fbuid the Facebook ID of the logged in user, or null | ||||
|      */ | ||||
|  | ||||
|     function loggedIn() | ||||
|     { | ||||
|         $user = common_current_user(); | ||||
|  | ||||
|         if ($user) { | ||||
|         if (!empty($user)) { | ||||
|  | ||||
|             $flink = Foreign_link::getByUserId($user->id, | ||||
|                 FACEBOOK_CONNECT_SERVICE); | ||||
|             $fbuid = 0; | ||||
|  | ||||
|             if ($flink) { | ||||
|             if (!empty($flink)) { | ||||
|  | ||||
|                 try { | ||||
|  | ||||
|                     $facebook = getFacebook(); | ||||
|                     $fbuid = getFacebook()->get_loggedin_user(); | ||||
|                     $fbuid    = getFacebook()->get_loggedin_user(); | ||||
|  | ||||
|                 } catch (Exception $e) { | ||||
|                     common_log(LOG_WARNING, | ||||
| @@ -170,24 +228,48 @@ class FBConnectPlugin extends Plugin | ||||
|                             $e->getMessage()); | ||||
|                 } | ||||
|  | ||||
|                 // Display Facebook Logged in indicator w/Facebook favicon | ||||
|  | ||||
|                 if ($fbuid > 0) { | ||||
|  | ||||
|                     $action->elementStart('li', array('id' => 'nav_fb')); | ||||
|                     $action->elementStart('fb:profile-pic', array('uid' => $flink->foreign_id, | ||||
|                         'linked' => 'false', | ||||
|                         'width' => 16, | ||||
|                         'height' => 16)); | ||||
|                     $action->elementEnd('fb:profile-pic'); | ||||
|  | ||||
|                     $iconurl =  common_path('/plugins/FBConnect/fbfavicon.ico'); | ||||
|                     $action->element('img', array('src' => $iconurl)); | ||||
|  | ||||
|                     $action->elementEnd('li'); | ||||
|  | ||||
|                     return $fbuid; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     function onStartPrimaryNav($action) | ||||
|     { | ||||
|  | ||||
|         $user = common_current_user(); | ||||
|  | ||||
|         if (!empty($user)) { | ||||
|  | ||||
|             $fbuid = $this->loggedIn(); | ||||
|  | ||||
|             if (!empty($fbuid)) { | ||||
|  | ||||
|                 /* Default FB silhouette pic for FB users who haven't | ||||
|                    uploaded a profile pic yet. */ | ||||
|  | ||||
|                 $silhouetteUrl = | ||||
|                     'http://static.ak.fbcdn.net/pics/q_silhouette.gif'; | ||||
|  | ||||
|                 $url = $this->getProfilePicURL($fbuid); | ||||
|  | ||||
|                 $action->elementStart('li', array('id' => 'nav_fb')); | ||||
|  | ||||
|                 $action->element('img', array('id' => 'fbc_profile-pic', | ||||
|                     'src' => (!empty($url)) ? $url : $silhouetteUrl, | ||||
|                     'alt' => 'Facebook Connect User', | ||||
|                     'width' => '16'), ''); | ||||
|  | ||||
|                 $iconurl =  common_path('plugins/FBConnect/fbfavicon.ico'); | ||||
|                 $action->element('img', array('id' => 'fb_favicon', | ||||
|                     'src' => $iconurl)); | ||||
|  | ||||
|                 $action->elementEnd('li'); | ||||
|  | ||||
|             } | ||||
|  | ||||
|             $action->menuItem(common_local_url('all', array('nickname' => $user->nickname)), | ||||
|                 _('Home'), _('Personal profile and friends timeline'), false, 'nav_home'); | ||||
| @@ -200,14 +282,16 @@ class FBConnectPlugin extends Plugin | ||||
|              $action->menuItem(common_local_url('smssettings'), | ||||
|                  _('Connect'), _('Connect to SMS, Twitter'), false, 'nav_connect'); | ||||
|             } | ||||
|             $action->menuItem(common_local_url('invite'), | ||||
|                 _('Invite'), | ||||
|                 sprintf(_('Invite friends and colleagues to join you on %s'), | ||||
|                 common_config('site', 'name')), | ||||
|                 false, 'nav_invitecontact'); | ||||
|             if (common_config('invite', 'enabled')) { | ||||
|                 $action->menuItem(common_local_url('invite'), | ||||
|                     _('Invite'), | ||||
|                     sprintf(_('Invite friends and colleagues to join you on %s'), | ||||
|                     common_config('site', 'name')), | ||||
|                     false, 'nav_invitecontact'); | ||||
|             } | ||||
|  | ||||
|             // Need to override the Logout link to make it do FB stuff | ||||
|             if ($flink && $fbuid > 0) { | ||||
|             if (!empty($fbuid)) { | ||||
|  | ||||
|                 $logout_url = common_local_url('logout'); | ||||
|                 $title =  _('Logout from the site'); | ||||
| @@ -245,7 +329,7 @@ class FBConnectPlugin extends Plugin | ||||
|  | ||||
|     function onStartShowLocalNavBlock($action) | ||||
|     { | ||||
|         $action_name = get_class($action); | ||||
|         $action_name   = get_class($action); | ||||
|  | ||||
|         $login_actions = array('LoginAction', 'RegisterAction', | ||||
|             'OpenidloginAction', 'FBConnectLoginAction'); | ||||
| @@ -256,7 +340,7 @@ class FBConnectPlugin extends Plugin | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         $connect_actions = array('SmssettingsAction', | ||||
|         $connect_actions = array('SmssettingsAction', 'ImsettingsAction', | ||||
|             'TwittersettingsAction', 'FBConnectSettingsAction'); | ||||
|  | ||||
|         if (in_array($action_name, $connect_actions)) { | ||||
| @@ -270,23 +354,13 @@ class FBConnectPlugin extends Plugin | ||||
|  | ||||
|     function onStartLogout($action) | ||||
|     { | ||||
|         $user = common_current_user(); | ||||
|  | ||||
|         $flink = Foreign_link::getByUserId($user->id, FACEBOOK_CONNECT_SERVICE); | ||||
|  | ||||
|         $action->logout(); | ||||
|         $fbuid = $this->loggedIn(); | ||||
|  | ||||
|         if ($flink) { | ||||
|  | ||||
|             $facebook = getFacebook(); | ||||
|  | ||||
|         if (!empty($fbuid)) { | ||||
|             try { | ||||
|                 $fbuid = $facebook->get_loggedin_user(); | ||||
|  | ||||
|                 if ($fbuid > 0) { | ||||
|                     $facebook->logout(common_local_url('public')); | ||||
|                 } | ||||
|  | ||||
|                 $facebook = getFacebook(); | ||||
|                 $facebook->expire_session(); | ||||
|             } catch (Exception $e) { | ||||
|                 common_log(LOG_WARNING, 'Could\'t logout of Facebook: ' . | ||||
|                     $e->getMessage()); | ||||
| @@ -296,4 +370,28 @@ class FBConnectPlugin extends Plugin | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     function getProfilePicURL($fbuid) | ||||
|     { | ||||
|  | ||||
|         $facebook = getFacebook(); | ||||
|         $url      = null; | ||||
|  | ||||
|         try { | ||||
|  | ||||
|             $fqry = 'SELECT pic_square FROM user WHERE uid = %s'; | ||||
|  | ||||
|             $result = $facebook->api_client->fql_query(sprintf($fqry, $fbuid)); | ||||
|  | ||||
|             if (!empty($result)) { | ||||
|                 $url = $result[0]['pic_square']; | ||||
|             } | ||||
|  | ||||
|         } catch (Exception $e) { | ||||
|             common_log(LOG_WARNING, "Facebook client failure requesting profile pic!"); | ||||
|         } | ||||
|  | ||||
|        return $url; | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -63,14 +63,21 @@ if (isset($longoptions)) { | ||||
|  | ||||
| $parser = new Console_Getopt(); | ||||
|  | ||||
| list($options, $args) = $parser->getopt($argv, $shortoptions, $longoptions); | ||||
| $result = $parser->getopt($argv, $shortoptions, $longoptions); | ||||
|  | ||||
| if (PEAR::isError($result)) { | ||||
|     print $result->getMessage()."\n"; | ||||
|     exit(1); | ||||
| } else { | ||||
|     list($options, $args) = $result; | ||||
| } | ||||
|  | ||||
| function show_help() | ||||
| { | ||||
|     global $helptext; | ||||
|  | ||||
|     $_default_help_text = <<<END_OF_DEFAULT | ||||
| General options: | ||||
|       General options: | ||||
|  | ||||
|     -q --quiet           Quiet (little output) | ||||
|     -v --verbose         Verbose (lots of output) | ||||
| @@ -80,11 +87,11 @@ General options: | ||||
|     -h --help            Show this message and quit. | ||||
|  | ||||
| END_OF_DEFAULT; | ||||
|         if (isset($helptext)) { | ||||
|             print $helptext; | ||||
|         } | ||||
|         print $_default_help_text; | ||||
|         exit(0); | ||||
|     if (isset($helptext)) { | ||||
|         print $helptext; | ||||
|     } | ||||
|     print $_default_help_text; | ||||
|     exit(0); | ||||
| } | ||||
|  | ||||
| foreach ($options as $option) { | ||||
| @@ -115,24 +122,53 @@ require_once INSTALLDIR . '/lib/common.php'; | ||||
|  | ||||
| set_error_handler('common_error_handler'); | ||||
|  | ||||
| function have_option($str) | ||||
| function _make_matches($opt, $alt) | ||||
| { | ||||
|    global $options; | ||||
|    foreach ($options as $option) { | ||||
|        if ($option[0] == $str) { | ||||
|           return true; | ||||
|        } | ||||
|    } | ||||
|    return false; | ||||
|     $matches = array(); | ||||
|  | ||||
|     if (strlen($opt) > 1 && 0 != strncmp($opt, '--', 2)) { | ||||
|         $matches[] = '--'.$opt; | ||||
|     } else { | ||||
|         $matches[] = $opt; | ||||
|     } | ||||
|  | ||||
|     if (!empty($alt)) { | ||||
|         if (strlen($alt) > 1 && 0 != strncmp($alt, '--', 2)) { | ||||
|             $matches[] = '--'.$alt; | ||||
|         } else { | ||||
|             $matches[] = $alt; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return $matches; | ||||
| } | ||||
|  | ||||
| function get_option_value($str) | ||||
| function have_option($opt, $alt=null) | ||||
| { | ||||
|    global $options; | ||||
|    foreach ($options as $option) { | ||||
|        if ($option[0] == $str) { | ||||
|           return $option[1]; | ||||
|        } | ||||
|    } | ||||
|    return null; | ||||
|     global $options; | ||||
|  | ||||
|     $matches = _make_matches($opt, $alt); | ||||
|  | ||||
|     foreach ($options as $option) { | ||||
|         if (in_array($option[0], $matches)) { | ||||
|             return true; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| function get_option_value($opt, $alt=null) | ||||
| { | ||||
|     global $options; | ||||
|  | ||||
|     $matches = _make_matches($opt, $alt); | ||||
|  | ||||
|     foreach ($options as $option) { | ||||
|         if (in_array($option[0], $matches)) { | ||||
|             return $option[1]; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return null; | ||||
| } | ||||
| @@ -24,22 +24,17 @@ require_once INSTALLDIR.'/scripts/commandline.inc'; | ||||
|  | ||||
| common_log(LOG_INFO, 'Fixing up conversations.'); | ||||
|  | ||||
| $notice = new Notice(); | ||||
| $notice->whereAdd('conversation is null'); | ||||
| $notice->orderBy('id'); | ||||
| $nid = new Notice(); | ||||
| $nid->query('select id, reply_to from notice where conversation is null'); | ||||
|  | ||||
| $cnt = $notice->find(); | ||||
| while ($nid->fetch()) { | ||||
|  | ||||
| print "Found $cnt notices.\n"; | ||||
|     $cid = null; | ||||
|      | ||||
| while ($notice->fetch()) { | ||||
|     $notice = new Notice(); | ||||
|      | ||||
|     print "$notice->id =>"; | ||||
|  | ||||
|     $orig = clone($notice); | ||||
|  | ||||
|     if (empty($notice->reply_to)) { | ||||
|         $notice->conversation = $notice->id; | ||||
|     if (empty($nid->reply_to)) { | ||||
|         $cid = $nid->id; | ||||
|     } else { | ||||
|         $reply = Notice::staticGet('id', $notice->reply_to); | ||||
|  | ||||
| @@ -52,6 +47,9 @@ while ($notice->fetch()) { | ||||
|         } else { | ||||
|             $notice->conversation = $reply->conversation; | ||||
|         } | ||||
| 	 | ||||
| 	unset($reply); | ||||
| 	$reply = null; | ||||
|     } | ||||
|  | ||||
|     print "$notice->conversation"; | ||||
| @@ -63,5 +61,10 @@ while ($notice->fetch()) { | ||||
|         continue; | ||||
|     } | ||||
|  | ||||
|     $notice = null; | ||||
|     $orig = null; | ||||
|     unset($notice); | ||||
|     unset($orig); | ||||
|      | ||||
|     print ".\n"; | ||||
| } | ||||
|   | ||||
							
								
								
									
										71
									
								
								scripts/showcache.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								scripts/showcache.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | ||||
| #!/usr/bin/env php | ||||
| <?php | ||||
| /* | ||||
|  * Laconica - a distributed open-source microblogging tool | ||||
|  * Copyright (C) 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/>. | ||||
|  */ | ||||
|  | ||||
| define('INSTALLDIR', realpath(dirname(__FILE__) . '/..')); | ||||
|  | ||||
| $shortoptions = "t:c:v:k:"; | ||||
|  | ||||
| $helptext = <<<ENDOFHELP | ||||
| USAGE: showcache.php <args> | ||||
| shows the cached object based on the args | ||||
|  | ||||
|   -t table     Table to look up | ||||
|   -c column    Column to look up, default "id" | ||||
|   -v value     Value to look up | ||||
|   -k key       Key to look up; other args are ignored | ||||
|  | ||||
| ENDOFHELP; | ||||
|  | ||||
| require_once INSTALLDIR.'/scripts/commandline.inc'; | ||||
|  | ||||
| $karg = get_option_value('k'); | ||||
|  | ||||
| if (!empty($karg)) { | ||||
|     $k = common_cache_key($karg); | ||||
| } else { | ||||
|     $table = get_option_value('t'); | ||||
|     if (empty($table)) { | ||||
|         die("No table or key specified\n"); | ||||
|     } | ||||
|     $column = get_option_value('c'); | ||||
|     if (empty($column)) { | ||||
|         $column = 'id'; | ||||
|     } | ||||
|     $value = get_option_value('v'); | ||||
|  | ||||
|     $k = Memcached_DataObject::cacheKey($table, $column, $value); | ||||
| } | ||||
|  | ||||
| print "Checking key '$k'...\n"; | ||||
|  | ||||
| $c = common_memcache(); | ||||
|  | ||||
| if (empty($c)) { | ||||
|     die("Can't initialize cache object!\n"); | ||||
| } | ||||
|  | ||||
| $obj = $c->get($k); | ||||
|  | ||||
| if (empty($obj)) { | ||||
|     print "Empty.\n"; | ||||
| } else { | ||||
|     var_dump($obj); | ||||
|     print "\n"; | ||||
| } | ||||
| @@ -25,9 +25,14 @@ define('INSTALLDIR', realpath(dirname(__FILE__) . '/..')); | ||||
| define('MAXCHILDREN', 2); | ||||
| define('POLL_INTERVAL', 60); // in seconds | ||||
|  | ||||
| $shortoptions = 'i::'; | ||||
| $longoptions = array('id::'); | ||||
|  | ||||
| $helptext = <<<END_OF_TRIM_HELP | ||||
| Batch script for retrieving Twitter messages from foreign service. | ||||
|  | ||||
|   -i --id      Identity (default 'generic') | ||||
|      | ||||
| END_OF_TRIM_HELP; | ||||
|  | ||||
| require_once INSTALLDIR.'/scripts/commandline.inc'; | ||||
| @@ -64,7 +69,7 @@ class TwitterStatusFetcher extends Daemon | ||||
|  | ||||
|     function name() | ||||
|     { | ||||
|         return ('twitterstatusfetcher.generic'); | ||||
|         return ('twitterstatusfetcher.'.$this->_id); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -625,6 +630,16 @@ class TwitterStatusFetcher extends Daemon | ||||
|  | ||||
| declare(ticks = 1); | ||||
|  | ||||
| $fetcher = new TwitterStatusFetcher(); | ||||
| if (have_option('i')) { | ||||
|     $id = get_option_value('i'); | ||||
| } else if (have_option('--id')) { | ||||
|     $id = get_option_value('--id'); | ||||
| } else if (count($args) > 0) { | ||||
|     $id = $args[0]; | ||||
| } else { | ||||
|     $id = null; | ||||
| } | ||||
|  | ||||
| $fetcher = new TwitterStatusFetcher($id); | ||||
| $fetcher->runOnce(); | ||||
|  | ||||
|   | ||||
| @@ -20,13 +20,14 @@ | ||||
|  | ||||
| define('INSTALLDIR', realpath(dirname(__FILE__) . '/..')); | ||||
|  | ||||
| $shortoptions = 'i::'; | ||||
| $longoptions = array('id::'); | ||||
| $shortoptions = 'fi::'; | ||||
| $longoptions = array('id::', 'foreground'); | ||||
|  | ||||
| $helptext = <<<END_OF_XMPP_HELP | ||||
| Daemon script for receiving new notices from Jabber users. | ||||
|  | ||||
|     -i --id           Identity (default none) | ||||
|     -f --foreground   Stay in the foreground (default background) | ||||
|  | ||||
| END_OF_XMPP_HELP; | ||||
|  | ||||
| @@ -42,8 +43,10 @@ require_once INSTALLDIR . '/lib/daemon.php'; | ||||
|  | ||||
| class XMPPDaemon extends Daemon | ||||
| { | ||||
|     function XMPPDaemon($resource=null) | ||||
|     function __construct($resource=null, $daemonize=true) | ||||
|     { | ||||
|         parent::__construct($daemonize); | ||||
|  | ||||
|         static $attrs = array('server', 'port', 'user', 'password', 'host'); | ||||
|  | ||||
|         foreach ($attrs as $attr) | ||||
| @@ -62,7 +65,6 @@ class XMPPDaemon extends Daemon | ||||
|  | ||||
|     function connect() | ||||
|     { | ||||
|  | ||||
|         $connect_to = ($this->host) ? $this->host : $this->server; | ||||
|  | ||||
|         $this->log(LOG_INFO, "Connecting to $connect_to on port $this->port"); | ||||
| @@ -73,10 +75,17 @@ class XMPPDaemon extends Daemon | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         $this->log(LOG_INFO, "Connected"); | ||||
|  | ||||
|         $this->conn->setReconnectTimeout(600); | ||||
|  | ||||
|         $this->log(LOG_INFO, "Sending initial presence."); | ||||
|  | ||||
|         jabber_send_presence("Send me a message to post a notice", 'available', | ||||
|                              null, 'available', 100); | ||||
|  | ||||
|         $this->log(LOG_INFO, "Done connecting."); | ||||
|  | ||||
|         return !$this->conn->isDisconnected(); | ||||
|     } | ||||
|  | ||||
| @@ -89,17 +98,23 @@ class XMPPDaemon extends Daemon | ||||
|     { | ||||
|         if ($this->connect()) { | ||||
|  | ||||
|             $this->log(LOG_DEBUG, "Initializing stanza handlers."); | ||||
|  | ||||
|             $this->conn->addEventHandler('message', 'handle_message', $this); | ||||
|             $this->conn->addEventHandler('presence', 'handle_presence', $this); | ||||
|             $this->conn->addEventHandler('reconnect', 'handle_reconnect', $this); | ||||
|  | ||||
|             $this->log(LOG_DEBUG, "Beginning processing loop."); | ||||
|  | ||||
|             $this->conn->process(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function handle_reconnect(&$pl) | ||||
|     { | ||||
|         $this->log(LOG_DEBUG, "Got reconnection callback."); | ||||
|         $this->conn->processUntil('session_start'); | ||||
|         $this->log(LOG_DEBUG, "Sending reconnection presence."); | ||||
|         $this->conn->presence('Send me a message to post a notice', 'available', null, 'available', 100); | ||||
|     } | ||||
|  | ||||
| @@ -111,21 +126,27 @@ class XMPPDaemon extends Daemon | ||||
|  | ||||
|     function handle_message(&$pl) | ||||
|     { | ||||
|         $from = jabber_normalize_jid($pl['from']); | ||||
|  | ||||
|         if ($pl['type'] != 'chat') { | ||||
|             return; | ||||
|         } | ||||
|         if (mb_strlen($pl['body']) == 0) { | ||||
|             $this->log(LOG_WARNING, "Ignoring message of type ".$pl['type']." from $from."); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         $from = jabber_normalize_jid($pl['from']); | ||||
|         if (mb_strlen($pl['body']) == 0) { | ||||
|             $this->log(LOG_WARNING, "Ignoring message with empty body from $from."); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         # Forwarded from another daemon (probably a broadcaster) for | ||||
|         # us to handle | ||||
|  | ||||
|         if ($this->is_self($from)) { | ||||
|             $this->log(LOG_INFO, "Got forwarded notice from self ($from)."); | ||||
|             $from = $this->get_ofrom($pl); | ||||
|             $this->log(LOG_INFO, "Originally sent by $from."); | ||||
|             if (is_null($from) || $this->is_self($from)) { | ||||
|                 $this->log(LOG_INFO, "Ignoring notice originally sent by $from."); | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
| @@ -140,6 +161,7 @@ class XMPPDaemon extends Daemon | ||||
|             return; | ||||
|         } | ||||
|         if ($this->handle_command($user, $pl['body'])) { | ||||
|             $this->log(LOG_INFO, "Command messag by $from handled."); | ||||
|             return; | ||||
|         } else if ($this->is_autoreply($pl['body'])) { | ||||
|             $this->log(LOG_INFO, 'Ignoring auto reply from ' . $from); | ||||
| @@ -148,12 +170,20 @@ class XMPPDaemon extends Daemon | ||||
|             $this->log(LOG_INFO, 'Ignoring OTR from ' . $from); | ||||
|             return; | ||||
|         } else if ($this->is_direct($pl['body'])) { | ||||
|             $this->log(LOG_INFO, 'Got a direct message ' . $from); | ||||
|  | ||||
|             preg_match_all('/d[\ ]*([a-z0-9]{1,64})/', $pl['body'], $to); | ||||
|  | ||||
|             $to = preg_replace('/^d([\ ])*/', '', $to[0][0]); | ||||
|             $body = preg_replace('/d[\ ]*('. $to .')[\ ]*/', '', $pl['body']); | ||||
|  | ||||
|             $this->log(LOG_INFO, 'Direct message from '. $user->nickname . ' to ' . $to); | ||||
|  | ||||
|             $this->add_direct($user, $body, $to, $from); | ||||
|         } else { | ||||
|  | ||||
|             $this->log(LOG_INFO, 'Posting a notice from ' . $user->nickname); | ||||
|  | ||||
|             $this->add_notice($user, $pl); | ||||
|         } | ||||
|  | ||||
| @@ -261,6 +291,7 @@ class XMPPDaemon extends Daemon | ||||
|         $notice = Notice::saveNew($user->id, $content_shortened, 'xmpp'); | ||||
|         if (is_string($notice)) { | ||||
|             $this->log(LOG_ERR, $notice); | ||||
|             $this->from_site($user->jabber, $notice); | ||||
|             return; | ||||
|         } | ||||
|         common_broadcast_notice($notice); | ||||
| @@ -307,7 +338,14 @@ class XMPPDaemon extends Daemon | ||||
|  | ||||
|     function log($level, $msg) | ||||
|     { | ||||
|         common_log($level, 'XMPPDaemon('.$this->resource.'): '.$msg); | ||||
|         $text = 'XMPPDaemon('.$this->resource.'): '.$msg; | ||||
|         common_log($level, $text); | ||||
|         if (!$this->daemonize) | ||||
|         { | ||||
|             $line = common_log_line($level, $text); | ||||
|             echo $line; | ||||
|             echo "\n"; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function subscribed($to) | ||||
| @@ -323,16 +361,16 @@ if (common_config('xmpp','enabled')==false) { | ||||
|     exit(); | ||||
| } | ||||
|  | ||||
| if (have_option('i')) { | ||||
|     $id = get_option_value('i'); | ||||
| } else if (have_option('--id')) { | ||||
|     $id = get_option_value('--id'); | ||||
| if (have_option('i', 'id')) { | ||||
|     $id = get_option_value('i', 'id'); | ||||
| } else if (count($args) > 0) { | ||||
|     $id = $args[0]; | ||||
| } else { | ||||
|     $id = null; | ||||
| } | ||||
|  | ||||
| $daemon = new XMPPDaemon($id); | ||||
| $foreground = have_option('f', 'foreground'); | ||||
|  | ||||
| $daemon = new XMPPDaemon($id, !$foreground); | ||||
|  | ||||
| $daemon->runOnce(); | ||||
|   | ||||
| @@ -206,7 +206,10 @@ border-radius:4px; | ||||
| padding:0 7px; | ||||
| } | ||||
|  | ||||
|  | ||||
| .form_settings input.form_action-default { | ||||
| margin-right:11px; | ||||
| } | ||||
| .form_settings input.form_action-default, | ||||
| .form_settings input.form_action-primary { | ||||
| padding:0; | ||||
| } | ||||
| @@ -270,7 +273,6 @@ clear:both; | ||||
| margin-bottom:18px; | ||||
| } | ||||
|  | ||||
|  | ||||
| #anon_notice { | ||||
| float:left; | ||||
| width:43.2%; | ||||
| @@ -285,7 +287,6 @@ font-size:1.1em; | ||||
| font-weight:bold; | ||||
| } | ||||
|  | ||||
|  | ||||
| #footer { | ||||
| float:left; | ||||
| width:64%; | ||||
| @@ -588,16 +589,16 @@ font-weight:normal; | ||||
| content: ")"; | ||||
| font-weight:normal; | ||||
| } | ||||
|  | ||||
| .entity_profile dt { | ||||
| display:none; | ||||
| } | ||||
| .entity_profile dt, | ||||
| .entity_profile h2 { | ||||
| display:none; | ||||
| } | ||||
| .entity_profile .role { | ||||
| margin-left:11px; | ||||
| font-style:italic; | ||||
| } | ||||
| /* entity_profile */ | ||||
|  | ||||
|  | ||||
| /*entity_actions*/ | ||||
| .entity_actions { | ||||
| float:right; | ||||
| @@ -726,7 +727,6 @@ margin-bottom:0; | ||||
| min-height:60px; | ||||
| } | ||||
|  | ||||
|  | ||||
| .profile .form_group_join legend, | ||||
| .profile .form_group_leave legend, | ||||
| .profile .form_user_subscribe legend, | ||||
| @@ -761,13 +761,11 @@ display:inline; | ||||
| margin-right:11px; | ||||
| } | ||||
|  | ||||
|  | ||||
| .profile .entity_profile .form_subscription_edit label { | ||||
| font-weight:normal; | ||||
| margin-right:11px; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* NOTICE */ | ||||
| .notice, | ||||
| .profile { | ||||
| @@ -790,7 +788,6 @@ width:95%; | ||||
| float:left; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* NOTICES */ | ||||
| #notices_primary { | ||||
| float:left; | ||||
| @@ -962,7 +959,6 @@ border:0; | ||||
| padding:0; | ||||
| } | ||||
|  | ||||
|  | ||||
| .notice .attachment { | ||||
| position:relative; | ||||
| padding-left:16px; | ||||
| @@ -1031,7 +1027,13 @@ border-radius:7px; | ||||
| -moz-border-radius:7px; | ||||
| -webkit-border-radius:7px; | ||||
| } | ||||
|  | ||||
| #jOverlayContent #content img { | ||||
| max-width:480px; | ||||
| } | ||||
| #jOverlayLoading { | ||||
| top:22.5%; | ||||
| left:40%; | ||||
| } | ||||
| #attachment_view #oembed_info { | ||||
| margin-top:11px; | ||||
| } | ||||
| @@ -1059,7 +1061,6 @@ margin-bottom:18px; | ||||
| padding-left:20px; | ||||
| } | ||||
|  | ||||
|  | ||||
| #filter_tags { | ||||
| margin-bottom:11px; | ||||
| float:left; | ||||
| @@ -1105,8 +1106,6 @@ top:3px; | ||||
| left:3px; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| .pagination { | ||||
| float:left; | ||||
| clear:both; | ||||
| @@ -1152,7 +1151,6 @@ padding-right:30px; | ||||
| } | ||||
| /* END: NOTICE */ | ||||
|  | ||||
|  | ||||
| .hentry .entry-content p { | ||||
| margin-bottom:18px; | ||||
| } | ||||
| @@ -1169,7 +1167,6 @@ margin-bottom:18px; | ||||
| margin-left:18px; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* TOP_POSTERS */ | ||||
| .section tbody td { | ||||
| padding-right:18px; | ||||
| @@ -1197,7 +1194,6 @@ margin-right:0; | ||||
| display:none; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* tagcloud */ | ||||
| .tag-cloud { | ||||
| list-style-type:none; | ||||
| @@ -1280,6 +1276,10 @@ clear:both; | ||||
| margin-bottom:0; | ||||
| } | ||||
|  | ||||
| #form_settings_design #settings_design_background-image img { | ||||
| max-width:480px; | ||||
| } | ||||
|  | ||||
| #form_settings_design #settings_design_color .form_data, | ||||
| #form_settings_design #color-picker { | ||||
| float:left; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user