diff --git a/actions/all.php b/actions/all.php index fb0b63577a..9cab91264f 100644 --- a/actions/all.php +++ b/actions/all.php @@ -41,13 +41,9 @@ class AllAction extends ProfileAction { var $notice; - protected function prepare(array $args=array()) + protected function profileActionPreparation() { - parent::prepare($args); - - $user = common_current_user(); - - if (!empty($user) && $user->streamModeOnly()) { + if ($this->scoped instanceof Profile && $this->scoped->isLocal() && $this->scoped->getUser()->streamModeOnly()) { $stream = new InboxNoticeStream($this->target, $this->scoped); } else { $stream = new ThreadingInboxNoticeStream($this->target, $this->scoped); @@ -60,8 +56,6 @@ class AllAction extends ProfileAction // TRANS: Client error when page not found (404). $this->clientError(_('No such page.'), 404); } - - return true; } function title() diff --git a/actions/showstream.php b/actions/showstream.php index 8dd6c7deff..64d85e63be 100644 --- a/actions/showstream.php +++ b/actions/showstream.php @@ -49,14 +49,12 @@ class ShowstreamAction extends ProfileAction { var $notice; - protected function prepare(array $args=array()) + protected function profileActionPreparation() { - parent::prepare($args); - if (empty($this->tag)) { - $stream = new ProfileNoticeStream($this->profile, $this->scoped); + $stream = new ProfileNoticeStream($this->target, $this->scoped); } else { - $stream = new TaggedProfileNoticeStream($this->profile, $this->tag, $this->scoped); + $stream = new TaggedProfileNoticeStream($this->target, $this->tag, $this->scoped); } $this->notice = $stream->getNotices(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1); @@ -67,7 +65,7 @@ class ShowstreamAction extends ProfileAction function title() { - $base = $this->profile->getFancyName(); + $base = $this->target->getFancyName(); if (!empty($this->tag)) { if ($this->page == 1) { // TRANS: Page title showing tagged notices in one user's timeline. @@ -98,7 +96,7 @@ class ShowstreamAction extends ProfileAction function showProfileBlock() { - $block = new AccountProfileBlock($this, $this->profile); + $block = new AccountProfileBlock($this, $this->target); $block->show(); } @@ -112,12 +110,12 @@ class ShowstreamAction extends ProfileAction if (!empty($this->tag)) { return array(new Feed(Feed::RSS1, common_local_url('userrss', - array('nickname' => $this->target->nickname, + array('nickname' => $this->target->getNickname(), 'tag' => $this->tag)), // TRANS: Title for link to notice feed. // TRANS: %1$s is a user nickname, %2$s is a hashtag. sprintf(_('Notice feed for %1$s tagged %2$s (RSS 1.0)'), - $this->target->nickname, $this->tag))); + $this->target->getNickname(), $this->tag))); } return array(new Feed(Feed::JSON, @@ -128,14 +126,14 @@ class ShowstreamAction extends ProfileAction // TRANS: Title for link to notice feed. // TRANS: %s is a user nickname. sprintf(_('Notice feed for %s (Activity Streams JSON)'), - $this->target->nickname)), + $this->target->getNickname())), new Feed(Feed::RSS1, common_local_url('userrss', - array('nickname' => $this->target->nickname)), + array('nickname' => $this->target->getNickname())), // TRANS: Title for link to notice feed. // TRANS: %s is a user nickname. sprintf(_('Notice feed for %s (RSS 1.0)'), - $this->target->nickname)), + $this->target->getNickname())), new Feed(Feed::RSS2, common_local_url('ApiTimelineUser', array( @@ -144,7 +142,7 @@ class ShowstreamAction extends ProfileAction // TRANS: Title for link to notice feed. // TRANS: %s is a user nickname. sprintf(_('Notice feed for %s (RSS 2.0)'), - $this->target->nickname)), + $this->target->getNickname())), new Feed(Feed::ATOM, common_local_url('ApiTimelineUser', array( @@ -153,24 +151,24 @@ class ShowstreamAction extends ProfileAction // TRANS: Title for link to notice feed. // TRANS: %s is a user nickname. sprintf(_('Notice feed for %s (Atom)'), - $this->target->nickname)), + $this->target->getNickname())), new Feed(Feed::FOAF, common_local_url('foaf', array('nickname' => - $this->target->nickname)), + $this->target->getNickname())), // TRANS: Title for link to notice feed. FOAF stands for Friend of a Friend. // TRANS: More information at http://www.foaf-project.org. %s is a user nickname. - sprintf(_('FOAF for %s'), $this->target->nickname))); + sprintf(_('FOAF for %s'), $this->target->getNickname()))); } function extraHead() { - if ($this->profile->bio) { + if ($this->target->bio) { $this->element('meta', array('name' => 'description', - 'content' => $this->profile->bio)); + 'content' => $this->target->getDescription())); } - if ($this->user->emailmicroid && $this->user->email && $this->profile->profileurl) { - $id = new Microid('mailto:'.$this->user->email, + if ($this->target->isLocal() && $this->target->getUser()->emailmicroid && $this->target->getUser()->email && $this->target->getUrl()) { + $id = new Microid('mailto:'.$this->target->getUser()->email, $this->selfUrl()); $this->element('meta', array('name' => 'microid', 'content' => $id->toString())); @@ -180,10 +178,10 @@ class ShowstreamAction extends ProfileAction $this->element('link', array('rel' => 'microsummary', 'href' => common_local_url('microsummary', - array('nickname' => $this->profile->nickname)))); + array('nickname' => $this->target->getNickname())))); $rsd = common_local_url('rsd', - array('nickname' => $this->profile->nickname)); + array('nickname' => $this->target->getNickname())); // RSD, http://tales.phrasewise.com/rfc/rsd $this->element('link', array('rel' => 'EditURI', @@ -192,7 +190,7 @@ class ShowstreamAction extends ProfileAction if ($this->page != 1) { $this->element('link', array('rel' => 'canonical', - 'href' => $this->profile->profileurl)); + 'href' => $this->target->getUrl())); } } @@ -273,10 +271,9 @@ class ShowstreamAction extends ProfileAction function noticeFormOptions() { $options = parent::noticeFormOptions(); - $cur = common_current_user(); - if (empty($cur) || $cur->id != $this->profile->id) { - $options['to_profile'] = $this->profile; + if (!$this->scoped instanceof Profile || $this->scoped->id != $this->target->id) { + $options['to_profile'] = $this->target; } return $options; diff --git a/actions/tagprofile.php b/actions/tagprofile.php index 79a401c6a9..47a66d0be4 100644 --- a/actions/tagprofile.php +++ b/actions/tagprofile.php @@ -19,8 +19,6 @@ if (!defined('GNUSOCIAL')) { exit(1); } -require_once INSTALLDIR . '/lib/peopletags.php'; - class TagprofileAction extends FormAction { var $error = null; diff --git a/classes/Conversation.php b/classes/Conversation.php index 343668cc49..537c214a4c 100644 --- a/classes/Conversation.php +++ b/classes/Conversation.php @@ -108,7 +108,13 @@ class Conversation extends Managed_DataObject static public function getUrlFromNotice(Notice $notice, $anchor=true) { - $conv = self::getKV('id', $notice->conversation); + $conv = new Conversation(); + $conv->id = $notice->conversation; + $conv->find(true); + if (!$conv instanceof Conversation) { + common_debug('Conversation does not exist for notice ID: '.$notice->id); + throw new NoResultException($conv); + } return $conv->getUrl($anchor ? $notice->id : null); } diff --git a/classes/File.php b/classes/File.php index 242da159c2..1e296242b7 100644 --- a/classes/File.php +++ b/classes/File.php @@ -569,6 +569,14 @@ class File extends Managed_DataObject $thumbs->delete(); } } + + $f2p = new File_to_post(); + $f2p->file_id = $this->id; + if ($f2p->find()) { + while ($f2p->fetch()) { + $f2p->delete(); + } + } } // And finally remove the entry from the database diff --git a/classes/File_redirection.php b/classes/File_redirection.php index 8c64c58a80..12619b0394 100644 --- a/classes/File_redirection.php +++ b/classes/File_redirection.php @@ -322,6 +322,7 @@ class File_redirection extends Managed_DataObject break; case 'mailto': + case 'magnet': case 'aim': case 'jabber': case 'xmpp': diff --git a/classes/File_to_post.php b/classes/File_to_post.php index 1d2733738f..4c751ae4f3 100644 --- a/classes/File_to_post.php +++ b/classes/File_to_post.php @@ -52,6 +52,7 @@ class File_to_post extends Managed_DataObject 'file_to_post_post_id_fkey' => array('notice', array('post_id' => 'id')), ), 'indexes' => array( + 'file_id_idx' => array('file_id'), 'post_id_idx' => array('post_id'), ), ); @@ -87,7 +88,7 @@ class File_to_post extends Managed_DataObject function delete($useWhere=false) { $f = File::getKV('id', $this->file_id); - if (!empty($f)) { + if ($f instanceof File) { $f->blowCache(); } return parent::delete($useWhere); diff --git a/classes/Local_group.php b/classes/Local_group.php index c0dcf02e4b..9e95102d85 100644 --- a/classes/Local_group.php +++ b/classes/Local_group.php @@ -40,16 +40,19 @@ class Local_group extends Managed_DataObject public function getProfile() { - $group = $this->getGroup(); - if (!$group instanceof User_group) { - return null; // TODO: Throw exception when other code is ready - } - return $group->getProfile(); + return $this->getGroup()->getProfile(); } public function getGroup() { - return User_group::getKV('id', $this->group_id); + $group = new User_group(); + $group->id = $this->group_id; + $group->find(true); + if (!$group instanceof User_group) { + common_log(LOG_ERR, 'User_group does not exist for Local_group: '.$this->group_id); + throw new NoResultException($group); + } + return $group; } function setNickname($nickname) diff --git a/classes/Profile.php b/classes/Profile.php index db8326f0f6..6eb09782b1 100644 --- a/classes/Profile.php +++ b/classes/Profile.php @@ -1380,6 +1380,11 @@ class Profile extends Managed_DataObject return $this->nickname; } + public function getFullname() + { + return $this->fullname; + } + public function getDescription() { return $this->bio; diff --git a/htaccess.sample b/htaccess.sample index f7513cc0c7..af6e19784d 100644 --- a/htaccess.sample +++ b/htaccess.sample @@ -45,9 +45,11 @@ - # For mod_access_compat in Apache <2.4 - #Order allow,deny - - # Use this instead for Apache >2.4 (mod_authz_host) - # Require all denied + + Order allow,deny + Deny from all + + = 2.3> + Require all denied + diff --git a/lib/accountprofileblock.php b/lib/accountprofileblock.php index fe11a0fc15..875acbb59c 100644 --- a/lib/accountprofileblock.php +++ b/lib/accountprofileblock.php @@ -28,13 +28,7 @@ * @link http://status.net/ */ -if (!defined('STATUSNET')) { - // This check helps protect against security problems; - // your code file can't be executed directly from the web. - exit(1); -} - -require_once INSTALLDIR.'/lib/peopletags.php'; +if (!defined('GNUSOCIAL')) { exit(1); } /** * Profile block to show for an account diff --git a/lib/command.php b/lib/command.php index 94e95f0ee9..830b97ee23 100644 --- a/lib/command.php +++ b/lib/command.php @@ -932,7 +932,7 @@ class HelpCommand extends Command // Give plugins a chance to add or override... Event::handle('HelpCommandMessages', array($this, &$commands)); - sort($commands); + ksort($commands); foreach ($commands as $command => $help) { $out[] = "$command - $help"; } diff --git a/lib/default.php b/lib/default.php index 5f4b806b81..6369fbddc6 100644 --- a/lib/default.php +++ b/lib/default.php @@ -337,7 +337,6 @@ $default = 'path' => null, 'sslpath' => null, ), - 'pluginlist' => array(), 'admin' => array('panels' => array('site', 'user', 'paths', 'access', 'sessions', 'sitenotice', 'license', 'plugins')), 'singleuser' => diff --git a/lib/framework.php b/lib/framework.php index b71f365c24..4ec8b083e0 100644 --- a/lib/framework.php +++ b/lib/framework.php @@ -144,7 +144,7 @@ require_once INSTALLDIR.'/lib/action.php'; require_once INSTALLDIR.'/lib/mail.php'; //set PEAR error handling to use regular PHP exceptions -function PEAR_ErrorToPEAR_Exception($err) +function PEAR_ErrorToPEAR_Exception(PEAR_Error $err) { //DB_DataObject throws error when an empty set would be returned //That behavior is weird, and not how the rest of StatusNet works. diff --git a/lib/htmloutputter.php b/lib/htmloutputter.php index 3409ff8f92..5e40037952 100644 --- a/lib/htmloutputter.php +++ b/lib/htmloutputter.php @@ -28,11 +28,7 @@ * @link http://status.net/ */ -if (!defined('STATUSNET') && !defined('LACONICA')) { - exit(1); -} - -require_once INSTALLDIR.'/lib/xmloutputter.php'; +if (!defined('GNUSOCIAL')) { exit(1); } // Can include XHTML options but these are too fragile in practice. define('PAGE_TYPE_PREFS', 'text/html'); @@ -58,6 +54,9 @@ define('PAGE_TYPE_PREFS', 'text/html'); class HTMLOutputter extends XMLOutputter { + protected $DTD = array('doctype' => 'html', + 'spec' => '-//W3C//DTD XHTML 1.0 Strict//EN', + 'uri' => 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'); /** * Constructor * @@ -120,9 +119,8 @@ class HTMLOutputter extends XMLOutputter // Required for XML documents $this->startXML(); } - $this->xw->writeDTD('html', - '-//W3C//DTD XHTML 1.0 Strict//EN', - 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'); + + $this->writeDTD(); $language = $this->getLanguage(); @@ -138,6 +136,18 @@ class HTMLOutputter extends XMLOutputter } } + public function setDTD($doctype, $spec, $uri) + { + $this->DTD = array('doctype' => $doctype, 'spec' => $spec, 'uri' => $uri); + } + + protected function writeDTD() + { + $this->xw->writeDTD($this->DTD['doctype'], + $this->DTD['spec'], + $this->DTD['uri']); + } + function getLanguage() { // FIXME: correct language for interface diff --git a/lib/inlineattachmentlist.php b/lib/inlineattachmentlist.php index 9016daf3f1..410b3b838d 100644 --- a/lib/inlineattachmentlist.php +++ b/lib/inlineattachmentlist.php @@ -35,7 +35,7 @@ class InlineAttachmentList extends AttachmentList { function showListStart() { - $this->out->element('h3', null, _('Attachments')); + $this->out->element('h3', 'attachments-title', _('Attachments')); parent::showListStart(); } diff --git a/lib/installer.php b/lib/installer.php index 9e2936ca82..eb7c5c8690 100644 --- a/lib/installer.php +++ b/lib/installer.php @@ -424,7 +424,11 @@ abstract class Installer // database "\$config['db']['database'] = {$vals['db_database']};\n\n". ($this->db['type'] == 'pgsql' ? "\$config['db']['quote_identifiers'] = true;\n\n":''). - "\$config['db']['type'] = {$vals['db_type']};\n\n"; + "\$config['db']['type'] = {$vals['db_type']};\n\n". + + "// Uncomment below for better performance. Just remember you must run\n". + "// php scripts/checkschema.php whenever your enabled plugins change!\n". + "//\$config['db']['schemacheck'] = 'script';\n\n"; // Normalize line endings for Windows servers $cfg = str_replace("\n", PHP_EOL, $cfg); diff --git a/lib/peopletags.php b/lib/peopletagswidget.php similarity index 92% rename from lib/peopletags.php rename to lib/peopletagswidget.php index 40f07c06b7..1da153c85f 100644 --- a/lib/peopletags.php +++ b/lib/peopletagswidget.php @@ -25,11 +25,7 @@ * @link http://status.net/ */ -if (!defined('STATUSNET') && !defined('LACONICA')) { - exit(1); -} - -require_once INSTALLDIR.'/lib/widget.php'; +if (!defined('GNUSOCIAL')) { exit(1); } /* * Show a bunch of peopletags @@ -178,18 +174,3 @@ class PeopletagsWidget extends Widget return !empty($this->user) && $this->tagger->id == $this->user->id; } } - -class SelftagsWidget extends PeopletagsWidget -{ - function url($tag) - { - // link to self tag page - return common_local_url('selftag', array('tag' => $tag)); - } - - function label() - { - // TRANS: Label in self tags widget. - return _m('LABEL','Tags'); - } -} diff --git a/lib/profileaction.php b/lib/profileaction.php index 83b3170bed..bd5bb5a148 100644 --- a/lib/profileaction.php +++ b/lib/profileaction.php @@ -28,12 +28,7 @@ * @link http://status.net/ */ -if (!defined('STATUSNET') && !defined('LACONICA')) { - exit(1); -} - -require_once INSTALLDIR.'/lib/profileminilist.php'; -require_once INSTALLDIR.'/lib/groupminilist.php'; +if (!defined('GNUSOCIAL')) { exit(1); } /** * Profile action common superclass @@ -46,17 +41,15 @@ require_once INSTALLDIR.'/lib/groupminilist.php'; * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ */ -class ProfileAction extends ManagedAction +abstract class ProfileAction extends ManagedAction { var $page = null; var $tag = null; protected $target = null; // Profile that we're showing - protected function prepare(array $args=array()) + protected function doPreparation() { - parent::prepare($args); - try { $nickname_arg = $this->arg('nickname'); $nickname = common_canonical_nickname($nickname_arg); @@ -73,6 +66,10 @@ class ProfileAction extends ManagedAction $this->user = User::getKV('nickname', $nickname); if (!$this->user) { + $group = Local_group::getKV('nickname', $nickname); + if ($group instanceof Local_group) { + common_redirect($group->getProfile()->getUrl()); + } // TRANS: Client error displayed when calling a profile action without specifying a user. $this->clientError(_('No such user.'), 404); } @@ -106,7 +103,13 @@ class ProfileAction extends ManagedAction $this->tag = $this->trimmed('tag'); $this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1; common_set_returnto($this->selfUrl()); - return true; + + return $this->profileActionPreparation(); + } + + protected function profileActionPreparation() + { + // No-op by default. } function isReadOnly($args) diff --git a/lib/profilelist.php b/lib/profilelist.php index 767e12bc25..177560cdf5 100644 --- a/lib/profilelist.php +++ b/lib/profilelist.php @@ -27,11 +27,7 @@ * @link http://status.net/ */ -if (!defined('STATUSNET') && !defined('LACONICA')) { - exit(1); -} - -require_once INSTALLDIR.'/lib/peopletags.php'; +if (!defined('GNUSOCIAL')) { exit(1); } /** * Widget to show a list of profiles @@ -107,215 +103,3 @@ class ProfileList extends Widget return PROFILES_PER_PAGE; } } - -class ProfileListItem extends Widget -{ - /** Current profile. */ - var $profile = null; - /** Action object using us. */ - var $action = null; - - function __construct($profile, $action) - { - parent::__construct($action); - - $this->profile = $profile; - $this->action = $action; - } - - function show() - { - if (Event::handle('StartProfileListItem', array($this))) { - $this->startItem(); - if (Event::handle('StartProfileListItemProfile', array($this))) { - $this->showProfile(); - Event::handle('EndProfileListItemProfile', array($this)); - } - if (Event::handle('StartProfileListItemActions', array($this))) { - $this->showActions(); - Event::handle('EndProfileListItemActions', array($this)); - } - $this->endItem(); - Event::handle('EndProfileListItem', array($this)); - } - } - - function startItem() - { - $this->out->elementStart('li', array('class' => 'profile', - 'id' => 'profile-' . $this->profile->id)); - } - - function showProfile() - { - $this->startProfile(); - if (Event::handle('StartProfileListItemProfileElements', array($this))) { - if (Event::handle('StartProfileListItemAvatar', array($this))) { - $aAttrs = $this->linkAttributes(); - $this->out->elementStart('a', $aAttrs); - $this->showAvatar($this->profile); - $this->out->elementEnd('a'); - Event::handle('EndProfileListItemAvatar', array($this)); - } - if (Event::handle('StartProfileListItemNickname', array($this))) { - $this->showNickname(); - Event::handle('EndProfileListItemNickname', array($this)); - } - if (Event::handle('StartProfileListItemFullName', array($this))) { - $this->showFullName(); - Event::handle('EndProfileListItemFullName', array($this)); - } - if (Event::handle('StartProfileListItemLocation', array($this))) { - $this->showLocation(); - Event::handle('EndProfileListItemLocation', array($this)); - } - if (Event::handle('StartProfileListItemHomepage', array($this))) { - $this->showHomepage(); - Event::handle('EndProfileListItemHomepage', array($this)); - } - if (Event::handle('StartProfileListItemBio', array($this))) { - $this->showBio(); - Event::handle('EndProfileListItemBio', array($this)); - } - if (Event::handle('StartProfileListItemTags', array($this))) { - $this->showTags(); - Event::handle('EndProfileListItemTags', array($this)); - } - Event::handle('EndProfileListItemProfileElements', array($this)); - } - $this->endProfile(); - } - - function startProfile() - { - $this->out->elementStart('div', 'entity_profile h-card'); - } - - function showNickname() - { - $this->out->element('a', array('href'=>$this->profile->getUrl(), - 'class'=>'p-nickname'), - $this->profile->getNickname()); - } - - function showFullName() - { - if (!empty($this->profile->fullname)) { - $this->out->element('span', 'p-name', $this->profile->fullname); - } - } - - function showLocation() - { - if (!empty($this->profile->location)) { - $this->out->element('span', 'label p-locality', $this->profile->location); - } - } - - function showHomepage() - { - if (!empty($this->profile->homepage)) { - $this->out->text(' '); - $aAttrs = $this->homepageAttributes(); - $this->out->elementStart('a', $aAttrs); - $this->out->raw($this->highlight($this->profile->homepage)); - $this->out->elementEnd('a'); - } - } - - function showBio() - { - if (!empty($this->profile->bio)) { - $this->out->elementStart('p', 'note'); - $this->out->raw($this->highlight($this->profile->bio)); - $this->out->elementEnd('p'); - } - } - - function showTags() - { - $user = common_current_user(); - if (!empty($user)) { - if ($user->id == $this->profile->id) { - $tags = new SelftagsWidget($this->out, $user, $this->profile); - $tags->show(); - } else if ($user->getProfile()->canTag($this->profile)) { - $tags = new PeopletagsWidget($this->out, $user, $this->profile); - $tags->show(); - } - } - } - - function endProfile() - { - $this->out->elementEnd('div'); - } - - function showActions() - { - $this->startActions(); - if (Event::handle('StartProfileListItemActionElements', array($this))) { - $this->showSubscribeButton(); - Event::handle('EndProfileListItemActionElements', array($this)); - } - $this->endActions(); - } - - function startActions() - { - $this->out->elementStart('div', 'entity_actions'); - $this->out->elementStart('ul'); - } - - function showSubscribeButton() - { - // Is this a logged-in user, looking at someone else's - // profile? - - $user = common_current_user(); - - if (!empty($user) && $this->profile->id != $user->id) { - $this->out->elementStart('li', 'entity_subscribe'); - if ($user->isSubscribed($this->profile)) { - $usf = new UnsubscribeForm($this->out, $this->profile); - $usf->show(); - } else { - if (Event::handle('StartShowProfileListSubscribeButton', array($this))) { - $sf = new SubscribeForm($this->out, $this->profile); - $sf->show(); - Event::handle('EndShowProfileListSubscribeButton', array($this)); - } - } - $this->out->elementEnd('li'); - } - } - - function endActions() - { - $this->out->elementEnd('ul'); - $this->out->elementEnd('div'); - } - - function endItem() - { - $this->out->elementEnd('li'); - } - - function highlight($text) - { - return htmlspecialchars($text); - } - - function linkAttributes() - { - return array('href' => $this->profile->profileurl, - 'class' => 'u-url', - 'rel' => 'contact'); - } - - function homepageAttributes() - { - return array('href' => $this->profile->homepage, - 'class' => 'u-url'); - } -} diff --git a/lib/profilelistitem.php b/lib/profilelistitem.php new file mode 100644 index 0000000000..e0b94ac76a --- /dev/null +++ b/lib/profilelistitem.php @@ -0,0 +1,242 @@ +. + * + * @category Public + * @package StatusNet + * @author Evan Prodromou + * @copyright 2008-2009 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://status.net/ + */ + +if (!defined('GNUSOCIAL')) { exit(1); } + +class ProfileListItem extends Widget +{ + /** Current profile. */ + var $profile = null; + /** Action object using us. */ + var $action = null; + + function __construct($profile, $action) + { + parent::__construct($action); + + $this->profile = $profile; + $this->action = $action; + } + + function show() + { + if (Event::handle('StartProfileListItem', array($this))) { + $this->startItem(); + if (Event::handle('StartProfileListItemProfile', array($this))) { + $this->showProfile(); + Event::handle('EndProfileListItemProfile', array($this)); + } + if (Event::handle('StartProfileListItemActions', array($this))) { + $this->showActions(); + Event::handle('EndProfileListItemActions', array($this)); + } + $this->endItem(); + Event::handle('EndProfileListItem', array($this)); + } + } + + function startItem() + { + $this->out->elementStart('li', array('class' => 'profile', + 'id' => 'profile-' . $this->profile->id)); + } + + function showProfile() + { + $this->startProfile(); + if (Event::handle('StartProfileListItemProfileElements', array($this))) { + if (Event::handle('StartProfileListItemAvatar', array($this))) { + $aAttrs = $this->linkAttributes(); + $this->out->elementStart('a', $aAttrs); + $this->showAvatar($this->profile); + $this->out->elementEnd('a'); + Event::handle('EndProfileListItemAvatar', array($this)); + } + if (Event::handle('StartProfileListItemNickname', array($this))) { + $this->showNickname(); + Event::handle('EndProfileListItemNickname', array($this)); + } + if (Event::handle('StartProfileListItemFullName', array($this))) { + $this->showFullName(); + Event::handle('EndProfileListItemFullName', array($this)); + } + if (Event::handle('StartProfileListItemLocation', array($this))) { + $this->showLocation(); + Event::handle('EndProfileListItemLocation', array($this)); + } + if (Event::handle('StartProfileListItemHomepage', array($this))) { + $this->showHomepage(); + Event::handle('EndProfileListItemHomepage', array($this)); + } + if (Event::handle('StartProfileListItemBio', array($this))) { + $this->showBio(); + Event::handle('EndProfileListItemBio', array($this)); + } + if (Event::handle('StartProfileListItemTags', array($this))) { + $this->showTags(); + Event::handle('EndProfileListItemTags', array($this)); + } + Event::handle('EndProfileListItemProfileElements', array($this)); + } + $this->endProfile(); + } + + function startProfile() + { + $this->out->elementStart('div', 'entity_profile h-card'); + } + + function showNickname() + { + $this->out->element('a', array('href'=>$this->profile->getUrl(), + 'class'=>'p-nickname'), + $this->profile->getNickname()); + } + + function showFullName() + { + if (!empty($this->profile->fullname)) { + $this->out->element('span', 'p-name', $this->profile->fullname); + } + } + + function showLocation() + { + if (!empty($this->profile->location)) { + $this->out->element('span', 'label p-locality', $this->profile->location); + } + } + + function showHomepage() + { + if (!empty($this->profile->homepage)) { + $this->out->text(' '); + $aAttrs = $this->homepageAttributes(); + $this->out->elementStart('a', $aAttrs); + $this->out->raw($this->highlight($this->profile->homepage)); + $this->out->elementEnd('a'); + } + } + + function showBio() + { + if (!empty($this->profile->bio)) { + $this->out->elementStart('p', 'note'); + $this->out->raw($this->highlight($this->profile->bio)); + $this->out->elementEnd('p'); + } + } + + function showTags() + { + $user = common_current_user(); + if (!empty($user)) { + if ($user->id == $this->profile->id) { + $tags = new SelftagsWidget($this->out, $user, $this->profile); + $tags->show(); + } else if ($user->getProfile()->canTag($this->profile)) { + $tags = new PeopletagsWidget($this->out, $user, $this->profile); + $tags->show(); + } + } + } + + function endProfile() + { + $this->out->elementEnd('div'); + } + + function showActions() + { + $this->startActions(); + if (Event::handle('StartProfileListItemActionElements', array($this))) { + $this->showSubscribeButton(); + Event::handle('EndProfileListItemActionElements', array($this)); + } + $this->endActions(); + } + + function startActions() + { + $this->out->elementStart('div', 'entity_actions'); + $this->out->elementStart('ul'); + } + + function showSubscribeButton() + { + // Is this a logged-in user, looking at someone else's + // profile? + + $user = common_current_user(); + + if (!empty($user) && $this->profile->id != $user->id) { + $this->out->elementStart('li', 'entity_subscribe'); + if ($user->isSubscribed($this->profile)) { + $usf = new UnsubscribeForm($this->out, $this->profile); + $usf->show(); + } else { + if (Event::handle('StartShowProfileListSubscribeButton', array($this))) { + $sf = new SubscribeForm($this->out, $this->profile); + $sf->show(); + Event::handle('EndShowProfileListSubscribeButton', array($this)); + } + } + $this->out->elementEnd('li'); + } + } + + function endActions() + { + $this->out->elementEnd('ul'); + $this->out->elementEnd('div'); + } + + function endItem() + { + $this->out->elementEnd('li'); + } + + function highlight($text) + { + return htmlspecialchars($text); + } + + function linkAttributes() + { + return array('href' => $this->profile->profileurl, + 'class' => 'u-url', + 'rel' => 'contact'); + } + + function homepageAttributes() + { + return array('href' => $this->profile->homepage, + 'class' => 'u-url'); + } +} diff --git a/lib/profileminilist.php b/lib/profileminilist.php index 33624a3c70..4f47487220 100644 --- a/lib/profileminilist.php +++ b/lib/profileminilist.php @@ -27,11 +27,7 @@ * @link http://status.net/ */ -if (!defined('STATUSNET') && !defined('LACONICA')) { - exit(1); -} - -require_once INSTALLDIR.'/lib/profilelist.php'; +if (!defined('GNUSOCIAL')) { exit(1); } define('PROFILES_PER_MINILIST', 8); @@ -69,39 +65,3 @@ class ProfileMiniList extends ProfileList return AVATAR_MINI_SIZE; } } - -class ProfileMiniListItem extends ProfileListItem -{ - function show() - { - $this->out->elementStart('li', 'h-card'); - if (Event::handle('StartProfileListItemProfileElements', array($this))) { - if (Event::handle('StartProfileListItemAvatar', array($this))) { - $aAttrs = $this->linkAttributes(); - $this->out->elementStart('a', $aAttrs); - $avatarUrl = $this->profile->avatarUrl(AVATAR_MINI_SIZE); - $this->out->element('img', array('src' => $avatarUrl, - 'width' => AVATAR_MINI_SIZE, - 'height' => AVATAR_MINI_SIZE, - 'class' => 'avatar u-photo', - 'alt' => $this->profile->getBestName())); - $this->out->elementEnd('a'); - Event::handle('EndProfileListItemAvatar', array($this)); - } - $this->out->elementEnd('li'); - } - } - - // default; overridden for nofollow lists - - function linkAttributes() - { - $aAttrs = parent::linkAttributes(); - - $aAttrs['title'] = $this->profile->getBestName(); - $aAttrs['rel'] = 'contact member'; // @todo: member? always? - $aAttrs['class'] = 'u-url p-name'; - - return $aAttrs; - } -} diff --git a/lib/profileminilistitem.php b/lib/profileminilistitem.php new file mode 100644 index 0000000000..c0121262eb --- /dev/null +++ b/lib/profileminilistitem.php @@ -0,0 +1,76 @@ +. + * + * @category Public + * @package StatusNet + * @author Evan Prodromou + * @copyright 2008-2009 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://status.net/ + */ + +if (!defined('GNUSOCIAL')) { exit(1); } + +/** + * Widget to show a list of profiles, good for sidebar + * + * @category Public + * @package StatusNet + * @author Evan Prodromou + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://status.net/ + */ + +class ProfileMiniListItem extends ProfileListItem +{ + function show() + { + $this->out->elementStart('li', 'h-card'); + if (Event::handle('StartProfileListItemProfileElements', array($this))) { + if (Event::handle('StartProfileListItemAvatar', array($this))) { + $aAttrs = $this->linkAttributes(); + $this->out->elementStart('a', $aAttrs); + $avatarUrl = $this->profile->avatarUrl(AVATAR_MINI_SIZE); + $this->out->element('img', array('src' => $avatarUrl, + 'width' => AVATAR_MINI_SIZE, + 'height' => AVATAR_MINI_SIZE, + 'class' => 'avatar u-photo', + 'alt' => $this->profile->getBestName())); + $this->out->elementEnd('a'); + Event::handle('EndProfileListItemAvatar', array($this)); + } + $this->out->elementEnd('li'); + } + } + + // default; overridden for nofollow lists + + function linkAttributes() + { + $aAttrs = parent::linkAttributes(); + + $aAttrs['title'] = $this->profile->getBestName(); + $aAttrs['rel'] = 'contact member'; // @todo: member? always? + $aAttrs['class'] = 'u-url p-name'; + + return $aAttrs; + } +} diff --git a/lib/schema.php b/lib/schema.php index 94cde28f9d..0421bcb810 100644 --- a/lib/schema.php +++ b/lib/schema.php @@ -350,7 +350,7 @@ class Schema $res = $this->conn->query("DROP TABLE $name"); if ($_PEAR->isError($res)) { - throw new Exception($res->getMessage()); + PEAR_ErrorToPEAR_Exception($res); } return true; @@ -389,7 +389,7 @@ class Schema implode(",", $columnNames).")"); if ($_PEAR->isError($res)) { - throw new Exception($res->getMessage()); + PEAR_ErrorToPEAR_Exception($res); } return true; @@ -411,7 +411,7 @@ class Schema $res = $this->conn->query("ALTER TABLE $table DROP INDEX $name"); if ($_PEAR->isError($res)) { - throw new Exception($res->getMessage()); + PEAR_ErrorToPEAR_Exception($res); } return true; @@ -436,7 +436,7 @@ class Schema $res = $this->conn->query($sql); if ($_PEAR->isError($res)) { - throw new Exception($res->getMessage()); + PEAR_ErrorToPEAR_Exception($res); } return true; @@ -463,7 +463,7 @@ class Schema $res = $this->conn->query($sql); if ($_PEAR->isError($res)) { - throw new Exception($res->getMessage()); + PEAR_ErrorToPEAR_Exception($res); } return true; @@ -489,7 +489,7 @@ class Schema $res = $this->conn->query($sql); if ($_PEAR->isError($res)) { - throw new Exception($res->getMessage()); + PEAR_ErrorToPEAR_Exception($res); } return true; @@ -535,7 +535,7 @@ class Schema $res = $this->conn->query($sql); if ($_PEAR->isError($res)) { - throw new Exception($res->getMessage()); + PEAR_ErrorToPEAR_Exception($res); } } return $ok; @@ -1045,7 +1045,7 @@ class Schema $res = $this->conn->query($sql); if ($_PEAR->isError($res)) { - throw new Exception($res->getMessage()); + PEAR_ErrorToPEAR_Exception($res); } $out = array(); diff --git a/lib/schemaupdater.php b/lib/schemaupdater.php index ae746c10b5..38b5b93865 100644 --- a/lib/schemaupdater.php +++ b/lib/schemaupdater.php @@ -98,7 +98,6 @@ class SchemaUpdater { $checksums = array(); - PEAR::pushErrorHandling(PEAR_ERROR_EXCEPTION); try { $sv = new Schema_version(); $sv->find(); @@ -111,7 +110,6 @@ class SchemaUpdater // no dice! common_log(LOG_DEBUG, "Possibly schema_version table doesn't exist yet."); } - PEAR::popErrorHandling(); return $checksums; } @@ -124,7 +122,6 @@ class SchemaUpdater */ protected function saveChecksum($table, $checksum) { - PEAR::pushErrorHandling(PEAR_ERROR_EXCEPTION); try { $sv = new Schema_version(); $sv->table_name = $table; @@ -139,7 +136,6 @@ class SchemaUpdater // no dice! common_log(LOG_DEBUG, "Possibly schema_version table doesn't exist yet."); } - PEAR::popErrorHandling(); $this->checksums[$table] = $checksum; } } diff --git a/lib/selftagswidget.php b/lib/selftagswidget.php new file mode 100644 index 0000000000..e2530769df --- /dev/null +++ b/lib/selftagswidget.php @@ -0,0 +1,43 @@ +. + * + * @category Action + * @package StatusNet + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://status.net/ + */ + +if (!defined('GNUSOCIAL')) { exit(1); } + +class SelftagsWidget extends PeopletagsWidget +{ + function url($tag) + { + // link to self tag page + return common_local_url('selftag', array('tag' => $tag)); + } + + function label() + { + // TRANS: Label in self tags widget. + return _m('LABEL','Tags'); + } +} diff --git a/lib/util.php b/lib/util.php index 14cfd96ee1..dbc036c461 100644 --- a/lib/util.php +++ b/lib/util.php @@ -896,6 +896,7 @@ function common_replace_urls_callback($text, $callback, $arg = null) { ')'. ')'. ')'. + '|(?:(?:magnet):)'. // URLs without domain name '|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'. //IPv4 '|(?:'. //IPv6 '\[?(?:(?:(?:[0-9A-Fa-f]{1,4}:){7}(?:(?:[0-9A-Fa-f]{1,4})|:))|(?:(?:[0-9A-Fa-f]{1,4}:){6}(?::|(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})|(?::[0-9A-Fa-f]{1,4})))|(?:(?:[0-9A-Fa-f]{1,4}:){5}(?:(?::(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|(?:(?::[0-9A-Fa-f]{1,4}){1,2})))|(?:(?:[0-9A-Fa-f]{1,4}:){4}(?::[0-9A-Fa-f]{1,4}){0,1}(?:(?::(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|(?:(?::[0-9A-Fa-f]{1,4}){1,2})))|(?:(?:[0-9A-Fa-f]{1,4}:){3}(?::[0-9A-Fa-f]{1,4}){0,2}(?:(?::(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|(?:(?::[0-9A-Fa-f]{1,4}){1,2})))|(?:(?:[0-9A-Fa-f]{1,4}:){2}(?::[0-9A-Fa-f]{1,4}){0,3}(?:(?::(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|(?:(?::[0-9A-Fa-f]{1,4}){1,2})))|(?:(?:[0-9A-Fa-f]{1,4}:)(?::[0-9A-Fa-f]{1,4}){0,4}(?:(?::(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|(?:(?::[0-9A-Fa-f]{1,4}){1,2})))|(?::(?::[0-9A-Fa-f]{1,4}){0,5}(?:(?::(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|(?:(?::[0-9A-Fa-f]{1,4}){1,2})))|(?:(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})))\]?(?inlineScript('var infinite_scroll_on_next_only = ' . ($this->on_next_only?'true':'false') . ';'); $action->inlineScript('var ajax_loader_url = "' . ($this->path('ajax-loader.gif')) . '";'); @@ -49,7 +41,7 @@ class InfiniteScrollPlugin extends Plugin $action->script($this->path('infinitescroll.js')); } - function onPluginVersion(&$versions) + function onPluginVersion(array &$versions) { $versions[] = array('name' => 'InfiniteScroll', 'version' => GNUSOCIAL_VERSION, diff --git a/plugins/MobileProfile/MobileProfilePlugin.php b/plugins/MobileProfile/MobileProfilePlugin.php index 98fcb472fa..2efc006879 100644 --- a/plugins/MobileProfile/MobileProfilePlugin.php +++ b/plugins/MobileProfile/MobileProfilePlugin.php @@ -27,9 +27,7 @@ * @link http://status.net/ */ -if (!defined('STATUSNET')) { - exit(1); -} +if (!defined('GNUSOCIAL')) { exit(1); } define('PAGE_TYPE_PREFS_MOBILEPROFILE', 'application/vnd.wap.xhtml+xml, application/xhtml+xml, text/html;q=0.9'); @@ -59,124 +57,120 @@ class MobileProfilePlugin extends WAP20Plugin parent::__construct(); } - function onStartShowHTML($action) + public function onStartShowHTML(Action $action) { - // XXX: This should probably graduate to WAP20Plugin + // TODO: A lot of this should probably graduate to WAP20Plugin + + $httpaccept = isset($_SERVER['HTTP_ACCEPT']) ? $_SERVER['HTTP_ACCEPT'] : null; + + $cp = common_accept_to_prefs($httpaccept); + $sp = common_accept_to_prefs(PAGE_TYPE_PREFS_MOBILEPROFILE); + + $type = common_negotiate_type($cp, $sp); + + if (!$type) { + // TRANS: Client exception thrown when requesting a not supported media type. + throw new ClientException(_m('This page is not available in a '. + 'media type you accept.'), 406); + } // If they are on the mobile site, serve them MP - if ((common_config('site', 'mobileserver').'/'. - common_config('site', 'path').'/' == - $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'])) { - + if ((common_config('site', 'mobileserver').'/'.common_config('site', 'path').'/' + == $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'])) { $this->serveMobile = true; - } else if (isset($_COOKIE['MobileOverride'])) { + } elseif (isset($_COOKIE['MobileOverride'])) { // Cookie override is controlled by link at bottom. $this->serveMobile = (bool)$_COOKIE['MobileOverride']; - } elseif (array_key_exists('HTTP_USER_AGENT', $_SERVER)) { + } elseif (strstr('application/vnd.wap.xhtml+xml', $type) !== false) { // If they like the WAP 2.0 mimetype, serve them MP - // @fixme $type is undefined, making this if case useless and spewing errors. - // What's the intent? - //if (strstr('application/vnd.wap.xhtml+xml', $type) !== false) { - // $this->serveMobile = true; - //} else { - // If they are a mobile device that supports WAP 2.0, - // serve them MP + $this->serveMobile = true; + } elseif (array_key_exists('HTTP_USER_AGENT', $_SERVER)) { + // If they are a mobile device that supports WAP 2.0, + // serve them MP - // XXX: Browser sniffing sucks + // XXX: Browser sniffing sucks - // I really don't like going through this every page, - // perhaps use $_SESSION or cookies + // I really don't like going through this every page, + // perhaps use $_SESSION or cookies - // May be better to group the devices in terms of - // low,mid,high-end + // May be better to group the devices in terms of + // low,mid,high-end - // Or, detect the mobile devices based on their support for - // MP 1.0, 1.1, or 1.2 may be ideal. Possible? + // Or, detect the mobile devices based on their support for + // MP 1.0, 1.1, or 1.2 may be ideal. Possible? - $this->mobiledevices = array( - 'alcatel', - 'android', - 'audiovox', - 'au-mic,', - 'avantgo', - 'blackberry', - 'blazer', - 'cldc-', - 'danger', - 'epoc', - 'ericsson', - 'ericy', - 'iphone', - 'ipaq', - 'ipod', - 'j2me', - 'lg', - 'maemo', - 'midp-', - 'mobile', - 'mot', - 'netfront', - 'nitro', - 'nokia', - 'opera mini', - 'palm', - 'palmsource', - 'panasonic', - 'philips', - 'pocketpc', - 'portalmmm', - 'rover', - 'samsung', - 'sanyo', - 'series60', - 'sharp', - 'sie-', - 'smartphone', - 'sony', - 'symbian', - 'up.browser', - 'up.link', - 'up.link', - 'vodafone', - 'wap1', - 'wap2', - 'webos', - 'windows ce' - ); + $this->mobiledevices = array( + 'alcatel', + 'android', + 'audiovox', + 'au-mic,', + 'avantgo', + 'blackberry', + 'blazer', + 'cldc-', + 'danger', + 'epoc', + 'ericsson', + 'ericy', + 'iphone', + 'ipaq', + 'ipod', + 'j2me', + 'lg', + 'maemo', + 'midp-', + 'mobile', + 'mot', + 'netfront', + 'nitro', + 'nokia', + 'opera mini', + 'palm', + 'palmsource', + 'panasonic', + 'philips', + 'pocketpc', + 'portalmmm', + 'rover', + 'samsung', + 'sanyo', + 'series60', + 'sharp', + 'sie-', + 'smartphone', + 'sony', + 'symbian', + 'up.browser', + 'up.link', + 'up.link', + 'vodafone', + 'wap1', + 'wap2', + 'webos', + 'windows ce' + ); - $blacklist = array( - 'ipad', // Larger screen handles the full theme fairly well. - ); + $blacklist = array( + 'ipad', // Larger screen handles the full theme fairly well. + ); - $httpuseragent = strtolower($_SERVER['HTTP_USER_AGENT']); + $httpuseragent = strtolower($_SERVER['HTTP_USER_AGENT']); - foreach ($blacklist as $md) { - if (strstr($httpuseragent, $md) !== false) { - $this->serveMobile = false; - return true; - } + foreach ($blacklist as $md) { + if (strstr($httpuseragent, $md) !== false) { + $this->serveMobile = false; + return true; } + } - foreach ($this->mobiledevices as $md) { - if (strstr($httpuseragent, $md) !== false) { - $this->setMobileFeatures($httpuseragent); + foreach ($this->mobiledevices as $md) { + if (strstr($httpuseragent, $md) !== false) { + $this->setMobileFeatures($httpuseragent); - $this->serveMobile = true; - $this->reallyMobile = true; - break; - } + $this->serveMobile = true; + $this->reallyMobile = true; + break; } - //} - - // If they are okay with MP, and the site has a mobile server, - // redirect there - if ($this->serveMobile && - common_config('site', 'mobileserver') !== false && - (common_config('site', 'mobileserver') != - common_config('site', 'server'))) { - - // FIXME: Redirect to equivalent page on mobile site instead - common_redirect($this->_common_path(''), 302); } } @@ -184,48 +178,23 @@ class MobileProfilePlugin extends WAP20Plugin return true; } - // @fixme $type is undefined, making this if case useless and spewing errors. - // What's the intent? - //if (!$type) { - $httpaccept = isset($_SERVER['HTTP_ACCEPT']) ? - $_SERVER['HTTP_ACCEPT'] : null; + // If they are okay with MP, and the site has a mobile server, + // redirect there + if (common_config('site', 'mobileserver') !== false && + common_config('site', 'mobileserver') != common_config('site', 'server')) { - $cp = common_accept_to_prefs($httpaccept); - $sp = common_accept_to_prefs(PAGE_TYPE_PREFS_MOBILEPROFILE); - - $type = common_negotiate_type($cp, $sp); - - if (!$type) { - // TRANS: Client exception thrown when requesting a not supported media type. - throw new ClientException(_m('This page is not available in a '. - 'media type you accept.'), 406); - } - //} + // FIXME: Redirect to equivalent page on mobile site instead + common_redirect($this->_common_path(''), 302); + } header('Content-Type: '.$type); if ($this->reallyMobile) { - - $action->extraHeaders(); - if (preg_match("/.*\/.*xml/", $type)) { - // Required for XML documents - $action->startXML(); - } - $action->xw->writeDTD('html', - '-//WAPFORUM//DTD XHTML Mobile 1.0//EN', - $this->DTD); - - $language = $action->getLanguage(); - - $action->elementStart('html', array('xmlns' => 'http://www.w3.org/1999/xhtml', - 'xml:lang' => $language)); - - return false; - - } else { - return true; + $action->setDTD('html', '-//WAPFORUM//DTD XHTML Mobile 1.0//EN', $this->DTD); } + // continue + return true; } function setMobileFeatures($useragent) @@ -268,7 +237,7 @@ class MobileProfilePlugin extends WAP20Plugin return false; } - function onStartShowUAStyles($action) { + public function onStartShowUAStyles(Action $action) { if (!$this->serveMobile) { return true; } @@ -276,7 +245,7 @@ class MobileProfilePlugin extends WAP20Plugin return false; } - function onStartShowHeader($action) + public function onStartShowHeader(Action $action) { if (!$this->serveMobile) { return true; @@ -290,7 +259,7 @@ class MobileProfilePlugin extends WAP20Plugin return false; } - function _showLogo($action) + protected function _showLogo(Action $action) { $action->elementStart('address'); if (common_config('singleuser', 'enabled')) { @@ -316,23 +285,22 @@ class MobileProfilePlugin extends WAP20Plugin $action->elementEnd('address'); } - function onStartShowAside($action) + public function onStartShowAside(Action $action) { if ($this->serveMobile) { return false; } } - function onStartShowLocalNavBlock($action) + public function onStartShowLocalNavBlock(Action $action) { if ($this->serveMobile) { // @todo FIXME: "Show Navigation" / "Hide Navigation" needs i18n $action->element('a', array('href' => '#', 'id' => 'navtoggle'), 'Show Navigation'); - return true; } } - function onEndShowScripts($action) + public function onEndShowScripts(Action $action) { // @todo FIXME: "Show Navigation" / "Hide Navigation" needs i18n $action->inlineScript(' @@ -357,18 +325,12 @@ class MobileProfilePlugin extends WAP20Plugin ); if ($this->serveMobile) { - $action->inlineScript(' - $(function() { - $(".checkbox-wrapper").unbind("click"); - });' - ); + $action->inlineScript('$(function() { $(".checkbox-wrapper").unbind("click"); });'); } - - } - function onEndShowInsideFooter($action) + public function onEndShowInsideFooter(Action $action) { if ($this->serveMobile) { // TRANS: Link to switch site layout from mobile to desktop mode. Appears at very bottom of page. diff --git a/plugins/StrictTransportSecurity/StrictTransportSecurityPlugin.php b/plugins/StrictTransportSecurity/StrictTransportSecurityPlugin.php index 682b10cad2..675642135c 100644 --- a/plugins/StrictTransportSecurity/StrictTransportSecurityPlugin.php +++ b/plugins/StrictTransportSecurity/StrictTransportSecurityPlugin.php @@ -27,14 +27,13 @@ * @link http://status.net/ */ -if (!defined('STATUSNET') && !defined('LACONICA')) { - exit(1); -} +if (!defined('GNUSOCIAL')) { exit(1); } class StrictTransportSecurityPlugin extends Plugin { public $max_age = 15552000; public $includeSubDomains = false; + public $preloadToken = false; function __construct() { @@ -45,7 +44,9 @@ class StrictTransportSecurityPlugin extends Plugin { $path = common_config('site', 'path'); if(common_config('site', 'ssl') == 'always' && ($path == '/' || ! $path )) { - header('Strict-Transport-Security: max-age=' . $this->max_age . + ($this->includeSubDomains?'; includeSubDomains':'')); + header('Strict-Transport-Security: max-age=' . $this->max_age + . ($this->includeSubDomains ? '; includeSubDomains' : '') + . ($this->preloadToken ? '; preload' : '')); } } diff --git a/scripts/deleteuser.php b/scripts/deleteprofile.php similarity index 60% rename from scripts/deleteuser.php rename to scripts/deleteprofile.php index 25af1c5ce2..8eed6ff97b 100755 --- a/scripts/deleteuser.php +++ b/scripts/deleteprofile.php @@ -20,15 +20,16 @@ define('INSTALLDIR', realpath(dirname(__FILE__) . '/..')); -$shortoptions = 'i::n::y'; -$longoptions = array('id=', 'nickname=', 'yes'); +$shortoptions = 'i::n::u::y'; +$longoptions = array('id=', 'nickname=', 'uri=', 'yes'); $helptext = <<getProfile(); +} else if (have_option('u', 'uri')) { + $uri = get_option_value('u', 'uri'); + $oprofile = Ostatus_profile::getKV('uri', $uri); + if (!$oprofile instanceof Ostatus_profile) { + print "Can't find profile with URI '$uri'\n"; + exit(1); + } + $profile = $oprofile->localProfile(); } else { - print "You must provide either an ID or a nickname.\n"; + print "You must provide either an ID, a URI or a nickname.\n"; exit(1); } if (!have_option('y', 'yes')) { - print "About to PERMANENTLY delete user '{$user->nickname}' ({$user->id}). Are you sure? [y/N] "; + print "About to PERMANENTLY delete profile '".$profile->getNickname()."' ({$profile->id}). Are you sure? [y/N] "; $response = fgets(STDIN); if (strtolower(trim($response)) != 'y') { print "Aborting.\n"; @@ -64,5 +74,5 @@ if (!have_option('y', 'yes')) { } print "Deleting..."; -$user->delete(); +$profile->delete(); print "DONE.\n"; diff --git a/scripts/remove_duplicate_file_urls.php b/scripts/remove_duplicate_file_urls.php new file mode 100755 index 0000000000..a4a7cd795b --- /dev/null +++ b/scripts/remove_duplicate_file_urls.php @@ -0,0 +1,86 @@ +#!/usr/bin/env php +. + */ + +define('INSTALLDIR', realpath(dirname(__FILE__) . '/..')); + +$shortoptions = 'y'; +$longoptions = array('yes'); + +$helptext = <<query('SELECT id, url, COUNT(*) AS c FROM file GROUP BY url HAVING c > 1'); +print "\nFound {$file->N} URLs with duplicate entries in file table"; +while ($file->fetch()) { + // We've got a URL that is duplicated in the file table + $dupfile = new File(); + $dupfile->url = $file->url; + if ($dupfile->find(true)) { + print "\nDeleting duplicate entries in file table for URL: {$file->url} ["; + // Leave one of the URLs in the database by using ->find(true) + // and only deleting starting with this fetch. + while($dupfile->fetch()) { + print "."; + $dupfile->delete(); + } + print "]\n"; + } else { + print "\nWarning! URL suddenly disappeared from database: {$file->url}\n"; + } +} + +$file = new File_redirection(); +$file->query('SELECT file_id, url, COUNT(*) AS c FROM file_redirection GROUP BY url HAVING c > 1'); +print "\nFound {$file->N} URLs with duplicate entries in file_redirection table"; +while ($file->fetch()) { + // We've got a URL that is duplicated in the file_redirection table + $dupfile = new File_redirection(); + $dupfile->url = $file->url; + if ($dupfile->find(true)) { + print "\nDeleting duplicate entries in file table for URL: {$file->url} ["; + // Leave one of the URLs in the database by using ->find(true) + // and only deleting starting with this fetch. + while($dupfile->fetch()) { + print "."; + $dupfile->delete(); + } + print "]\n"; + } else { + print "\nWarning! URL suddenly disappeared from database: {$file->url}\n"; + } +} +print "\nDONE.\n"; diff --git a/scripts/upgrade.php b/scripts/upgrade.php index 692eaac17a..126ef29036 100644 --- a/scripts/upgrade.php +++ b/scripts/upgrade.php @@ -520,7 +520,7 @@ function setFilehashOnLocalFiles() $file->filehash = hash_file(File::FILEHASH_ALG, $file->getPath()); $file->update($orig); } catch (FileNotFoundException $e) { - echo "\n WARNING: file ID {$file->id} does not exist on path '{$e->path}'. Clean up the file table?"; + echo "\n WARNING: file ID {$file->id} does not exist on path '{$e->path}'. If there is no file system error, run: php scripts/clean_file_table.php"; } } }