From 31bbdacbf330c28c5ebc900864ccd148ea1b23e0 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 7 Nov 2009 18:51:57 -0500 Subject: [PATCH 01/25] add a method to Action to check session token --- lib/action.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/lib/action.php b/lib/action.php index 1b2f737521..78ca9137a5 100644 --- a/lib/action.php +++ b/lib/action.php @@ -1101,4 +1101,22 @@ class Action extends HTMLOutputter // lawsuit { return Design::siteDesign(); } + + /** + * Check the session token. + * + * Checks that the current form has the correct session token, + * and throw an exception if it does not. + * + * @return void + */ + + function checkSessionToken() + { + // CSRF protection + $token = $this->trimmed('token'); + if (empty($token) || $token != common_session_token()) { + $this->clientError(_('There was a problem with your session token.')); + } + } } From 589185ce872743c146285fca6980db087f96cd4a Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 7 Nov 2009 19:16:15 -0500 Subject: [PATCH 02/25] uppercase right constants --- lib/right.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/right.php b/lib/right.php index 4e0096d46a..4fc981af04 100644 --- a/lib/right.php +++ b/lib/right.php @@ -45,6 +45,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { class Right { - const deleteOthersNotice = 'deleteothersnotice'; + const DELETEOTHERSNOTICE = 'deleteothersnotice'; + const CONFIGURESITE = 'configuresite'; } From eaec5b03f59b0ac5bcde4a973d72946a52cbd2a6 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 7 Nov 2009 19:16:33 -0500 Subject: [PATCH 03/25] add constants for user roles --- classes/User_role.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/classes/User_role.php b/classes/User_role.php index 85ecfb422d..fc3806897f 100644 --- a/classes/User_role.php +++ b/classes/User_role.php @@ -45,4 +45,7 @@ class User_role extends Memcached_DataObject { return Memcached_DataObject::pkeyGet('User_role', $kv); } + + const MODERATOR = 'moderator'; + const ADMINISTRATOR = 'administrator'; } From 38833af6f18ae48caed0cc7939803c89e3104ef9 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 7 Nov 2009 19:16:54 -0500 Subject: [PATCH 04/25] use upper-case constants for roles and rights in hasRight() --- classes/User.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/classes/User.php b/classes/User.php index 96a64ccb29..546406f71e 100644 --- a/classes/User.php +++ b/classes/User.php @@ -705,10 +705,12 @@ class User extends Memcached_DataObject if (Event::handle('UserRightsCheck', array($this, $right, &$result))) { switch ($right) { - case Right::deleteOthersNotice: - $result = $this->hasRole('moderator'); + case Right::DELETEOTHERSNOTICE: + $result = $this->hasRole(User_role::MODERATOR); break; - default: + case Right::CONFIGURESITE: + $result = $this->hasRole(User_role::ADMINISTRATOR); + default: $result = false; break; } From 1de9496c7fed16c2675c3d5136c131c07534c2cc Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 7 Nov 2009 22:26:03 -0500 Subject: [PATCH 05/25] fix constant for deleteothersnotice --- actions/deletenotice.php | 2 +- lib/noticelist.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/actions/deletenotice.php b/actions/deletenotice.php index 4a48a9c346..ba8e86d0f4 100644 --- a/actions/deletenotice.php +++ b/actions/deletenotice.php @@ -67,7 +67,7 @@ class DeletenoticeAction extends Action common_user_error(_('Not logged in.')); exit; } else if ($this->notice->profile_id != $this->user_profile->id && - !$this->user->hasRight(Right::deleteOthersNotice)) { + !$this->user->hasRight(Right::DELETEOTHERSNOTICE)) { common_user_error(_('Can\'t delete this notice.')); exit; } diff --git a/lib/noticelist.php b/lib/noticelist.php index 8b3015cc3e..bf12bb73c5 100644 --- a/lib/noticelist.php +++ b/lib/noticelist.php @@ -513,7 +513,7 @@ class NoticeListItem extends Widget $user = common_current_user(); if (!empty($user) && - ($this->notice->profile_id == $user->id || $user->hasRight(Right::deleteOthersNotice))) { + ($this->notice->profile_id == $user->id || $user->hasRight(Right::DELETEOTHERSNOTICE))) { $deleteurl = common_local_url('deletenotice', array('notice' => $this->notice->id)); From 321ac38884125f1af9e8f07323f096505d0b2644 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 7 Nov 2009 22:35:35 -0500 Subject: [PATCH 06/25] script for granting/revoking user roles --- scripts/userrole.php | 85 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 scripts/userrole.php diff --git a/scripts/userrole.php b/scripts/userrole.php new file mode 100644 index 0000000000..7b6a9b3fd8 --- /dev/null +++ b/scripts/userrole.php @@ -0,0 +1,85 @@ +#!/usr/bin/env php +. + */ + +define('INSTALLDIR', realpath(dirname(__FILE__) . '/..')); + +$shortoptions = 'i:n:r:d'; +$longoptions = array('id=', 'nickname=', 'role=', 'delete'); + +$helptext = <<nickname' ($user->id)..."; + try { + $user->revokeRole($role); + print "OK\n"; + } catch (Exception $e) { + print "FAIL\n"; + print $e->getMessage(); + print "\n"; + } +} else { + print "Granting role '$role' to user '$user->nickname' ($user->id)..."; + try { + $user->grantRole($role); + print "OK\n"; + } catch (Exception $e) { + print "FAIL\n"; + print $e->getMessage(); + print "\n"; + } +} From 81b4a381d9ddc71ed8a53c074ea10910882d3156 Mon Sep 17 00:00:00 2001 From: Siebrand Mazeland Date: Sun, 8 Nov 2009 22:26:13 +0100 Subject: [PATCH 07/25] * check usage of 'people' in UI and change it to 'users' or something else in most places * change some contractions to full text in UI messages --- actions/all.php | 2 +- actions/foaf.php | 4 ++-- actions/groups.php | 7 ++++--- actions/imsettings.php | 2 +- actions/invite.php | 10 +++++----- actions/noticesearch.php | 2 +- actions/opensearch.php | 2 +- actions/peoplesearch.php | 2 +- actions/peopletag.php | 2 +- actions/profilesettings.php | 4 ++-- actions/register.php | 10 +++++----- actions/replies.php | 4 ++-- actions/subscribers.php | 8 ++++---- actions/subscriptions.php | 10 +++++----- actions/tagother.php | 2 +- lib/action.php | 2 +- 16 files changed, 37 insertions(+), 36 deletions(-) diff --git a/actions/all.php b/actions/all.php index 61cedce749..b0fd8ee77c 100644 --- a/actions/all.php +++ b/actions/all.php @@ -129,7 +129,7 @@ class AllAction extends ProfileAction if (common_logged_in()) { $current_user = common_current_user(); if ($this->user->id === $current_user->id) { - $message .= _('Try subscribing to more people, [join a group](%%action.groups%%) or post something yourself.'); + $message .= _('Try subscribing to more users, [join a group](%%action.groups%%) or post something yourself.'); } else { $message .= sprintf(_('You can try to [nudge %s](../%s) from his profile or [post something to his or her attention](%%%%action.newnotice%%%%?status_textarea=%s).'), $this->user->nickname, $this->user->nickname, '@' . $this->user->nickname); } diff --git a/actions/foaf.php b/actions/foaf.php index 356393304e..dd27470698 100644 --- a/actions/foaf.php +++ b/actions/foaf.php @@ -136,7 +136,7 @@ class FoafAction extends Action $person = $this->showMicrobloggingAccount($this->profile, common_root_url(), $this->user->uri, false); - // Get people who subscribe to user + // Get users who subscribe to user $sub = new Subscription(); $sub->subscribed = $this->profile->id; @@ -250,7 +250,7 @@ class FoafAction extends Action if ($isSubscriber) { $this->element('sioc:follows', array('rdf:resource'=>$this->user->uri . '#acct')); } else { - // Get people user is subscribed to + // Get users user is subscribed to $sub = new Subscription(); $sub->subscriber = $profile->id; $sub->whereAdd('subscriber != subscribed'); diff --git a/actions/groups.php b/actions/groups.php index 10a1d5964d..c713d0a98e 100644 --- a/actions/groups.php +++ b/actions/groups.php @@ -88,11 +88,12 @@ class GroupsAction extends Action { $notice = sprintf(_('%%%%site.name%%%% groups let you find and talk with ' . - 'people of similar interests. After you join a group ' . + 'users of similar interests. After you join a group ' . 'you can send messages to all other members using the ' . - 'syntax "!groupname". Don\'t see a group you like? Try ' . + 'syntax "!groupname". Are you not seeing any groups ' . + 'you like? Try ' . '[searching for one](%%%%action.groupsearch%%%%) or ' . - '[start your own!](%%%%action.newgroup%%%%)')); + '[start your own](%%%%action.newgroup%%%%)!')); $this->elementStart('div', 'instructions'); $this->raw(common_markup_to_html($notice)); $this->elementEnd('div'); diff --git a/actions/imsettings.php b/actions/imsettings.php index f57933b43f..b76679f346 100644 --- a/actions/imsettings.php +++ b/actions/imsettings.php @@ -151,7 +151,7 @@ class ImsettingsAction extends ConnectSettingsAction $this->elementStart('li'); $this->checkbox('jabberreplies', _('Send me replies through Jabber/GTalk '. - 'from people I\'m not subscribed to.'), + 'from users I am not subscribed to.'), $user->jabberreplies); $this->elementEnd('li'); $this->elementStart('li'); diff --git a/actions/invite.php b/actions/invite.php index 3015202e9e..8a0ac8a1b0 100644 --- a/actions/invite.php +++ b/actions/invite.php @@ -133,7 +133,7 @@ class InviteAction extends CurrentUserDesignAction $this->elementEnd('ul'); } if ($this->subbed) { - $this->element('p', null, _('These people are already users and you were automatically subscribed to them:')); + $this->element('p', null, _('These are already users and you were automatically subscribed to them:')); $this->elementStart('ul'); foreach ($this->subbed as $other) { $this->element('li', null, sprintf(_('%s (%s)'), $other->nickname, $other->email)); @@ -141,7 +141,7 @@ class InviteAction extends CurrentUserDesignAction $this->elementEnd('ul'); } if ($this->sent) { - $this->element('p', null, _('Invitation(s) sent to the following people:')); + $this->element('p', null, _('Invitation(s) sent to the following e-mail addresses:')); $this->elementStart('ul'); foreach ($this->sent as $other) { $this->element('li', null, $other); @@ -226,9 +226,9 @@ class InviteAction extends CurrentUserDesignAction $headers['Subject'] = sprintf(_('%1$s has invited you to join them on %2$s'), $bestname, $sitename); $body = sprintf(_("%1\$s has invited you to join them on %2\$s (%3\$s).\n\n". - "%2\$s is a micro-blogging service that lets you keep up-to-date with people you know and people who interest you.\n\n". - "You can also share news about yourself, your thoughts, or your life online with people who know about you. ". - "It's also great for meeting new people who share your interests.\n\n". + "%2\$s is a micro-blogging service that lets you keep up-to-date with those you know and those who interest you.\n\n". + "You can also share news about yourself, your thoughts, or your life online with users who know about you. ". + "It is also great for meeting others who share your interests.\n\n". "%1\$s said:\n\n%4\$s\n\n". "You can see %1\$s's profile page on %2\$s here:\n\n". "%5\$s\n\n". diff --git a/actions/noticesearch.php b/actions/noticesearch.php index 79cf572cca..fe86c8cd3d 100644 --- a/actions/noticesearch.php +++ b/actions/noticesearch.php @@ -44,7 +44,7 @@ require_once INSTALLDIR.'/lib/searchaction.php'; * @author Robin Millette * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 * @link http://status.net/ - * @todo common parent for people and content search? + * @todo common parent for user and content search? */ class NoticesearchAction extends SearchAction { diff --git a/actions/opensearch.php b/actions/opensearch.php index d5e6698f38..b2186f0e94 100644 --- a/actions/opensearch.php +++ b/actions/opensearch.php @@ -61,7 +61,7 @@ class OpensearchAction extends Action $short_name = ''; if ($type == 'people') { $type = 'peoplesearch'; - $short_name = _('People Search'); + $short_name = _('User Search'); } else { $type = 'noticesearch'; $short_name = _('Notice Search'); diff --git a/actions/peoplesearch.php b/actions/peoplesearch.php index 38135ecbde..63a5c88f33 100644 --- a/actions/peoplesearch.php +++ b/actions/peoplesearch.php @@ -49,7 +49,7 @@ class PeoplesearchAction extends SearchAction { function getInstructions() { - return _('Search for people on %%site.name%% by their name, location, or interests. ' . + return _('Search for users on %%site.name%% by their name, location, or interests. ' . 'Separate the terms by spaces; they must be 3 characters or more.'); } diff --git a/actions/peopletag.php b/actions/peopletag.php index 6dbbc92616..dbce417df3 100644 --- a/actions/peopletag.php +++ b/actions/peopletag.php @@ -67,7 +67,7 @@ class PeopletagAction extends Action $this->tag = $this->trimmed('tag'); if (!common_valid_profile_tag($this->tag)) { - $this->clientError(sprintf(_('Not a valid people tag: %s'), + $this->clientError(sprintf(_('Not a valid user tag: %s'), $this->tag)); return; } diff --git a/actions/profilesettings.php b/actions/profilesettings.php index 0a0cc59973..6a1c07f9d2 100644 --- a/actions/profilesettings.php +++ b/actions/profilesettings.php @@ -68,8 +68,8 @@ class ProfilesettingsAction extends AccountSettingsAction function getInstructions() { - return _('You can update your personal profile info here '. - 'so people know more about you.'); + return _('You can update your personal profile info here ' . + 'so readers know more about you.'); } function showScripts() diff --git a/actions/register.php b/actions/register.php index 57f8e7bdf0..584ad3ead4 100644 --- a/actions/register.php +++ b/actions/register.php @@ -82,14 +82,14 @@ class RegisterAction extends Action } if (common_config('site', 'inviteonly') && empty($this->code)) { - $this->clientError(_('Sorry, only invited people can register.')); + $this->clientError(_('Sorry. Only those invited can register.')); return false; } if (!empty($this->code)) { $this->invite = Invitation::staticGet('code', $this->code); if (empty($this->invite)) { - $this->clientError(_('Sorry, invalid invitation code.')); + $this->clientError(_('Sorry. This is an invalid invitation code.')); return false; } // Store this in case we need it @@ -186,7 +186,7 @@ class RegisterAction extends Action } if (common_config('site', 'inviteonly') && !($code && $invite)) { - $this->clientError(_('Sorry, only invited people can register.')); + $this->clientError(_('Sorry. Only those invited can register.')); return; } @@ -401,7 +401,7 @@ class RegisterAction extends Action } if (common_config('site', 'inviteonly') && !($code && $invite)) { - $this->clientError(_('Sorry, only invited people can register.')); + $this->clientError(_('Sorry. Only those invited can register.')); return; } @@ -542,7 +542,7 @@ class RegisterAction extends Action '(%%%%action.imsettings%%%%) '. 'so you can send notices '. 'through instant messages.' . "\n" . - '* [Search for people](%%%%action.peoplesearch%%%%) '. + '* [Search for users](%%%%action.peoplesearch%%%%) '. 'that you may know or '. 'that share your interests. ' . "\n" . '* Update your [profile settings]'. diff --git a/actions/replies.php b/actions/replies.php index a13b5a2273..2829a73350 100644 --- a/actions/replies.php +++ b/actions/replies.php @@ -195,12 +195,12 @@ class RepliesAction extends OwnerDesignAction function showEmptyListMessage() { - $message = sprintf(_('This is the timeline showing replies to %s but %s hasn\'t received a notice to his attention yet.'), $this->user->nickname, $this->user->nickname) . ' '; + $message = sprintf(_('This is the timeline showing replies to %s but %s has not received a notice to his attention yet.'), $this->user->nickname, $this->user->nickname) . ' '; if (common_logged_in()) { $current_user = common_current_user(); if ($this->user->id === $current_user->id) { - $message .= _('You can engage other users in a conversation, subscribe to more people or [join groups](%%action.groups%%).'); + $message .= _('You can engage other users in a conversation, subscribe to more users or [join groups](%%action.groups%%).'); } else { $message .= sprintf(_('You can try to [nudge %s](../%s) or [post something to his or her attention](%%%%action.newnotice%%%%?status_textarea=%s).'), $this->user->nickname, $this->user->nickname, '@' . $this->user->nickname); } diff --git a/actions/subscribers.php b/actions/subscribers.php index df9ec99615..1f584e2c14 100644 --- a/actions/subscribers.php +++ b/actions/subscribers.php @@ -60,12 +60,12 @@ class SubscribersAction extends GalleryAction $user =& common_current_user(); if ($user && ($user->id == $this->profile->id)) { $this->element('p', null, - _('These are the people who listen to '. + _('These are the users who have subscribed to '. 'your notices.')); } else { $this->element('p', null, - sprintf(_('These are the people who '. - 'listen to %s\'s notices.'), + sprintf(_('These are the users who '. + 'have subscribed to %s\'s notices.'), $this->profile->nickname)); } } @@ -105,7 +105,7 @@ class SubscribersAction extends GalleryAction if (common_logged_in()) { $current_user = common_current_user(); if ($this->user->id === $current_user->id) { - $message = _('You have no subscribers. Try subscribing to people you know and they might return the favor'); + $message = _('You have no subscribers. Try subscribing to users you know and they might return the favor'); } else { $message = sprintf(_('%s has no subscribers. Want to be the first?'), $this->user->nickname); } diff --git a/actions/subscriptions.php b/actions/subscriptions.php index cc7b38ee46..4f65e9bf1f 100644 --- a/actions/subscriptions.php +++ b/actions/subscriptions.php @@ -62,12 +62,12 @@ class SubscriptionsAction extends GalleryAction $user =& common_current_user(); if ($user && ($user->id == $this->profile->id)) { $this->element('p', null, - _('These are the people whose notices '. - 'you listen to.')); + _('These are the users whose notices '. + 'you have subscribed to.')); } else { $this->element('p', null, - sprintf(_('These are the people whose '. - 'notices %s listens to.'), + sprintf(_('These are the users whose '. + 'notices %s has subscribed to.'), $this->profile->nickname)); } } @@ -118,7 +118,7 @@ class SubscriptionsAction extends GalleryAction if (common_logged_in()) { $current_user = common_current_user(); if ($this->user->id === $current_user->id) { - $message = _('You\'re not listening to anyone\'s notices right now, try subscribing to people you know. Try [people search](%%action.peoplesearch%%), look for members in groups you\'re interested in and in our [featured users](%%action.featured%%). If you\'re a [Twitter user](%%action.twittersettings%%), you can automatically subscribe to people you already follow there.'); + $message = _('You have not subscribed to anyone\'s notices right now. Try subscribing to users you know. Try [user search](%%action.peoplesearch%%), look for members in groups you\'re interested in and in our [featured users](%%action.featured%%). If you are a [Twitter user](%%action.twittersettings%%), you can automatically subscribe to users you already follow there.'); } else { $message = sprintf(_('%s is not listening to anyone.'), $this->user->nickname); } diff --git a/actions/tagother.php b/actions/tagother.php index c3f43be8ba..80fa9cc95d 100644 --- a/actions/tagother.php +++ b/actions/tagother.php @@ -190,7 +190,7 @@ class TagotherAction extends Action !Subscription::pkeyGet(array('subscriber' => $this->profile->id, 'subscribed' => $user->id))) { - $this->clientError(_('You can only tag people you are subscribed to or who are subscribed to you.')); + $this->clientError(_('You can only tag users you are subscribed to or who are subscribed to you.')); return; } diff --git a/lib/action.php b/lib/action.php index 1b2f737521..7765498546 100644 --- a/lib/action.php +++ b/lib/action.php @@ -456,7 +456,7 @@ class Action extends HTMLOutputter // lawsuit _('Help'), _('Help me!'), false, 'nav_help'); if ($user || !common_config('site', 'private')) { $this->menuItem(common_local_url('peoplesearch'), - _('Search'), _('Search for people or text'), false, 'nav_search'); + _('Search'), _('Search for users or text'), false, 'nav_search'); } Event::handle('EndPrimaryNav', array($this)); } From 99a3c3abd2eaa8a049d80766903d724af915e2f9 Mon Sep 17 00:00:00 2001 From: Siebrand Mazeland Date: Sun, 8 Nov 2009 22:29:09 +0100 Subject: [PATCH 08/25] Remove unused message from pot --- locale/statusnet.po | 4 ---- 1 file changed, 4 deletions(-) diff --git a/locale/statusnet.po b/locale/statusnet.po index 7054feaf20..a8c952bd68 100644 --- a/locale/statusnet.po +++ b/locale/statusnet.po @@ -188,10 +188,6 @@ msgstr "" msgid "**%%site.name%%** is a microblogging service. " msgstr "" -#: ../lib/util.php:274 lib/util.php:290 -msgid ". Contributors should be attributed by full name or nickname." -msgstr "" - #: ../actions/finishopenidlogin.php:73 ../actions/profilesettings.php:43 #: actions/finishopenidlogin.php:79 actions/profilesettings.php:76 #: actions/finishopenidlogin.php:101 actions/profilesettings.php:100 From 6483fbd8fa4c7bc8da83a9a2e334db9d9a19a77b Mon Sep 17 00:00:00 2001 From: Siebrand Mazeland Date: Sun, 8 Nov 2009 22:34:52 +0100 Subject: [PATCH 09/25] More precise field label --- actions/smssettings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actions/smssettings.php b/actions/smssettings.php index 672abcef8c..9fa7f62fb2 100644 --- a/actions/smssettings.php +++ b/actions/smssettings.php @@ -101,7 +101,7 @@ class SmssettingsAction extends ConnectSettingsAction common_local_url('smssettings'))); $this->elementStart('fieldset', array('id' => 'settings_sms_address')); - $this->element('legend', null, _('Address')); + $this->element('legend', null, _('SMS address')); $this->hidden('token', common_session_token()); if ($user->sms) { From 1872d07602f50b4991d0da26aca3a5d775338e47 Mon Sep 17 00:00:00 2001 From: Siebrand Mazeland Date: Sun, 8 Nov 2009 22:37:09 +0100 Subject: [PATCH 10/25] More specifics on 'address' --- actions/imsettings.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/actions/imsettings.php b/actions/imsettings.php index b76679f346..49c7b2a0e0 100644 --- a/actions/imsettings.php +++ b/actions/imsettings.php @@ -69,7 +69,7 @@ class ImsettingsAction extends ConnectSettingsAction { return _('You can send and receive notices through '. 'Jabber/GTalk [instant messages](%%doc.im%%). '. - 'Configure your address and settings below.'); + 'Configure your instant messages address and settings below.'); } /** @@ -97,7 +97,7 @@ class ImsettingsAction extends ConnectSettingsAction 'action' => common_local_url('imsettings'))); $this->elementStart('fieldset', array('id' => 'settings_im_address')); - $this->element('legend', null, _('Address')); + $this->element('legend', null, _('IM address')); $this->hidden('token', common_session_token()); if ($user->jabber) { @@ -111,7 +111,7 @@ class ImsettingsAction extends ConnectSettingsAction if ($confirm) { $this->element('p', 'form_unconfirmed', $confirm->address); $this->element('p', 'form_note', - sprintf(_('Awaiting confirmation on this address. '. + sprintf(_('Awaiting confirmation on this IM address. '. 'Check your Jabber/GTalk account for a '. 'message with further instructions. '. '(Did you add %s to your buddy list?)'), From 99ebb565297d442f4721fe575f1bed2826cadbd5 Mon Sep 17 00:00:00 2001 From: Siebrand Mazeland Date: Sun, 8 Nov 2009 22:39:02 +0100 Subject: [PATCH 11/25] !. => ! --- lib/subs.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/subs.php b/lib/subs.php index 68c89c8421..934380b76e 100644 --- a/lib/subs.php +++ b/lib/subs.php @@ -45,7 +45,7 @@ function subs_subscribe_user($user, $other_nickname) function subs_subscribe_to($user, $other) { if ($user->isSubscribed($other)) { - return _('Already subscribed!.'); + return _('Already subscribed!'); } if ($other->hasBlocked($user)) { From c10e3903951e5002ab0d5bd139d8a8ac0a7b7210 Mon Sep 17 00:00:00 2001 From: Siebrand Mazeland Date: Sun, 8 Nov 2009 22:41:11 +0100 Subject: [PATCH 12/25] Remove unused message --- locale/statusnet.po | 4 ---- 1 file changed, 4 deletions(-) diff --git a/locale/statusnet.po b/locale/statusnet.po index a8c952bd68..acfb0b866a 100644 --- a/locale/statusnet.po +++ b/locale/statusnet.po @@ -799,10 +799,6 @@ msgstr "" msgid "Current confirmed email address." msgstr "" -#: ../actions/showstream.php:356 actions/showstream.php:367 -msgid "Currently" -msgstr "" - #: ../classes/Notice.php:72 classes/Notice.php:86 classes/Notice.php:91 #: classes/Notice.php:114 classes/Notice.php:124 classes/Notice.php:164 #, php-format From 43132eb55ee68f45ad776c8b95db5c8d130411da Mon Sep 17 00:00:00 2001 From: Siebrand Mazeland Date: Sun, 8 Nov 2009 22:45:18 +0100 Subject: [PATCH 13/25] Several updates to UI messages --- actions/recoverpassword.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/actions/recoverpassword.php b/actions/recoverpassword.php index 9776c1fb44..dcff35f6ed 100644 --- a/actions/recoverpassword.php +++ b/actions/recoverpassword.php @@ -149,13 +149,13 @@ class RecoverpasswordAction extends Action $this->elementStart('div', 'instructions'); if ($this->mode == 'recover') { $this->element('p', null, - _('If you\'ve forgotten or lost your' . + _('If you have forgotten or lost your' . ' password, you can get a new one sent to' . ' the email address you have stored' . ' in your account.')); } else if ($this->mode == 'reset') { $this->element('p', null, - _('You\'ve been identified. Enter a' . + _('You have been identified. Enter a' . ' new password below. ')); } $this->elementEnd('div'); @@ -185,10 +185,10 @@ class RecoverpasswordAction extends Action 'class' => 'form_settings', 'action' => common_local_url('recoverpassword'))); $this->elementStart('fieldset'); - $this->element('legend', null, _('Password recover')); + $this->element('legend', null, _('Password recovery')); $this->elementStart('ul', 'form_data'); $this->elementStart('li'); - $this->input('nicknameoremail', _('Nickname or email'), + $this->input('nicknameoremail', _('Nickname or email address'), $this->trimmed('nicknameoremail'), _('Your nickname on this server, ' . 'or your registered email address.')); From da444f8a15043f326aa9a629ba5f0b25bc35b1e5 Mon Sep 17 00:00:00 2001 From: Siebrand Mazeland Date: Sun, 8 Nov 2009 22:46:30 +0100 Subject: [PATCH 14/25] Remove unused message --- locale/statusnet.po | 6 ------ 1 file changed, 6 deletions(-) diff --git a/locale/statusnet.po b/locale/statusnet.po index acfb0b866a..4331b906e3 100644 --- a/locale/statusnet.po +++ b/locale/statusnet.po @@ -1112,12 +1112,6 @@ msgid "" "click \"Add\"." msgstr "" -#: ../actions/recoverpassword.php:137 actions/recoverpassword.php:152 -msgid "" -"If you've forgotten or lost your password, you can get a new one sent to the " -"email address you have stored in your account." -msgstr "" - #: ../actions/emailsettings.php:67 ../actions/smssettings.php:76 #: actions/emailsettings.php:68 actions/smssettings.php:76 #: actions/emailsettings.php:127 actions/smssettings.php:140 From b7e2e3fd2b7e36f75c810a599334c2ca8abcca55 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 8 Nov 2009 17:04:46 -0500 Subject: [PATCH 15/25] Restructure theme.php to define a class Theme For various reasons, it's nicer to have a class for theme-file paths and such. So, I've rewritten the code for determining the locations of theme files to be more OOPy. I changed all the uses of the two functions in the module (theme_file and theme_path) to use Theme::file and Theme::path respectively. I've also removed the code in common.php that require's the module; using a class means we can autoload it instead. --- actions/opensearch.php | 2 +- classes/Avatar.php | 2 +- classes/User_group.php | 2 +- lib/action.php | 16 ++-- lib/common.php | 1 - lib/htmloutputter.php | 4 +- lib/noticesection.php | 2 +- lib/theme.php | 188 +++++++++++++++++++++++++++++------------ 8 files changed, 150 insertions(+), 67 deletions(-) diff --git a/actions/opensearch.php b/actions/opensearch.php index d5e6698f38..861b53d7d8 100644 --- a/actions/opensearch.php +++ b/actions/opensearch.php @@ -75,7 +75,7 @@ class OpensearchAction extends Action $this->element('Url', array('type' => 'text/html', 'method' => 'get', 'template' => str_replace('---', '{searchTerms}', common_local_url($type, array('q' => '---'))))); $this->element('Image', array('height' => 16, 'width' => 16, 'type' => 'image/vnd.microsoft.icon'), common_path('favicon.ico')); - $this->element('Image', array('height' => 50, 'width' => 50, 'type' => 'image/png'), theme_path('logo.png')); + $this->element('Image', array('height' => 50, 'width' => 50, 'type' => 'image/png'), Theme::path('logo.png')); $this->element('AdultContent', null, 'false'); $this->element('Language', null, common_language()); $this->element('OutputEncoding', null, 'UTF-8'); diff --git a/classes/Avatar.php b/classes/Avatar.php index 64f105179c..cc7a6b6471 100644 --- a/classes/Avatar.php +++ b/classes/Avatar.php @@ -102,6 +102,6 @@ class Avatar extends Memcached_DataObject static $sizenames = array(AVATAR_PROFILE_SIZE => 'profile', AVATAR_STREAM_SIZE => 'stream', AVATAR_MINI_SIZE => 'mini'); - return theme_path('default-avatar-'.$sizenames[$size].'.png'); + return Theme::path('default-avatar-'.$sizenames[$size].'.png'); } } diff --git a/classes/User_group.php b/classes/User_group.php index 310ecff1ef..b92638f7aa 100644 --- a/classes/User_group.php +++ b/classes/User_group.php @@ -34,7 +34,7 @@ class User_group extends Memcached_DataObject static $sizenames = array(AVATAR_PROFILE_SIZE => 'profile', AVATAR_STREAM_SIZE => 'stream', AVATAR_MINI_SIZE => 'mini'); - return theme_path('default-avatar-'.$sizenames[$size].'.png'); + return Theme::path('default-avatar-'.$sizenames[$size].'.png'); } function homeUrl() diff --git a/lib/action.php b/lib/action.php index 78ca9137a5..80f398fbd7 100644 --- a/lib/action.php +++ b/lib/action.php @@ -168,7 +168,7 @@ class Action extends HTMLOutputter // lawsuit { if (is_readable(INSTALLDIR . '/theme/' . common_config('site', 'theme') . '/favicon.ico')) { $this->element('link', array('rel' => 'shortcut icon', - 'href' => theme_path('favicon.ico'))); + 'href' => Theme::path('favicon.ico'))); } else { $this->element('link', array('rel' => 'shortcut icon', 'href' => common_path('favicon.ico'))); @@ -177,7 +177,7 @@ class Action extends HTMLOutputter // lawsuit if (common_config('site', 'mobile')) { if (is_readable(INSTALLDIR . '/theme/' . common_config('site', 'theme') . '/apple-touch-icon.png')) { $this->element('link', array('rel' => 'apple-touch-icon', - 'href' => theme_path('apple-touch-icon.png'))); + 'href' => Theme::path('apple-touch-icon.png'))); } else { $this->element('link', array('rel' => 'apple-touch-icon', 'href' => common_path('apple-touch-icon.png'))); @@ -210,16 +210,16 @@ class Action extends HTMLOutputter // lawsuit if (Event::handle('StartShowUAStyles', array($this))) { $this->comment('[if IE]>comment('[if lte IE '.$ver.']>comment('[if IE]>elementStart('a', array('class' => 'url home bookmark', 'href' => common_local_url('public'))); - if (common_config('site', 'logo') || file_exists(theme_file('logo.png'))) { + if (common_config('site', 'logo') || file_exists(Theme::file('logo.png'))) { $this->element('img', array('class' => 'logo photo', - 'src' => (common_config('site', 'logo')) ? common_config('site', 'logo') : theme_path('logo.png'), + 'src' => (common_config('site', 'logo')) ? common_config('site', 'logo') : Theme::path('logo.png'), 'alt' => common_config('site', 'name'))); } $this->element('span', array('class' => 'fn org'), common_config('site', 'name')); diff --git a/lib/common.php b/lib/common.php index 68bdbf2293..6aac468075 100644 --- a/lib/common.php +++ b/lib/common.php @@ -227,7 +227,6 @@ require_once 'markdown.php'; require_once INSTALLDIR.'/lib/util.php'; require_once INSTALLDIR.'/lib/action.php'; -require_once INSTALLDIR.'/lib/theme.php'; require_once INSTALLDIR.'/lib/mail.php'; require_once INSTALLDIR.'/lib/subs.php'; require_once INSTALLDIR.'/lib/Shorturl_api.php'; diff --git a/lib/htmloutputter.php b/lib/htmloutputter.php index ce83295fb3..c2ec83c284 100644 --- a/lib/htmloutputter.php +++ b/lib/htmloutputter.php @@ -375,8 +375,8 @@ class HTMLOutputter extends XMLOutputter $url = parse_url($src); if( empty($url->scheme) && empty($url->host) && empty($url->query) && empty($url->fragment)) { - if(file_exists(theme_file($src,$theme))){ - $src = theme_path($src, $theme) . '?version=' . STATUSNET_VERSION; + if(file_exists(Theme::file($src,$theme))){ + $src = Theme::path($src, $theme) . '?version=' . STATUSNET_VERSION; }else{ $src = common_path($src); } diff --git a/lib/noticesection.php b/lib/noticesection.php index b223932efe..24465f8baf 100644 --- a/lib/noticesection.php +++ b/lib/noticesection.php @@ -114,7 +114,7 @@ class NoticeSection extends Section $att_class = 'attachments'; } - $clip = theme_path('images/icons/clip.png', 'base'); + $clip = Theme::path('images/icons/clip.png', 'base'); $this->out->elementStart('a', array('class' => $att_class, 'style' => "font-style: italic;", 'href' => $href, 'title' => "# of attachments: $count")); $this->out->raw(" ($count "); $this->out->element('img', array('style' => 'display: inline', 'align' => 'top', 'width' => 20, 'height' => 20, 'src' => $clip, 'alt' => 'alt')); diff --git a/lib/theme.php b/lib/theme.php index 08e3e85383..c658058ffc 100644 --- a/lib/theme.php +++ b/lib/theme.php @@ -23,7 +23,7 @@ * @package StatusNet * @author Evan Prodromou * @author Sarven Capadisli - * @copyright 2008 StatusNet, Inc. + * @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/ */ @@ -33,62 +33,146 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { } /** - * Gets the full path of a file in a theme dir based on its relative name + * Class for querying and manipulating a theme * - * @param string $relative relative path within the theme directory - * @param string $theme name of the theme; defaults to current theme + * Themes are directories with some expected sub-directories and files + * in them. They're found in either local/theme (for locally-installed themes) + * or theme/ subdir of installation dir. * - * @return string File path to the theme file + * This used to be a couple of functions, but for various reasons it's nice + * to have a class instead. + * + * @category Output + * @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/ */ -function theme_file($relative, $theme=null) +class Theme { - if (empty($theme)) { - $theme = common_config('site', 'theme'); + var $dir = null; + var $path = null; + + /** + * Constructor + * + * Determines the proper directory and path for this theme. + * + * @param string $name Name of the theme; defaults to config value + */ + + function __construct($name=null) + { + if (empty($name)) { + $name = common_config('site', 'theme'); + } + + // Check to see if it's in the local dir + + $localroot = INSTALLDIR.'/local/theme'; + + $fulldir = $localroot.'/'.$name; + + if (file_exists($fulldir) && is_dir($fulldir)) { + $this->dir = $fulldir; + $this->path = common_path('local/theme/'.$name.'/'); + return; + } + + // Check to see if it's in the distribution dir + + $instroot = common_config('theme', 'dir'); + + if (empty($instroot)) { + $instroot = INSTALLDIR.'/theme'; + } + + $fulldir = $instroot.'/'.$name; + + if (file_exists($fulldir) && is_dir($fulldir)) { + + $this->dir = $fulldir; + + $path = common_config('theme', 'path'); + + if (empty($path)) { + $path = common_config('site', 'path') . '/theme/'; + } + + if ($path[strlen($path)-1] != '/') { + $path .= '/'; + } + + if ($path[0] != '/') { + $path = '/'.$path; + } + + $server = common_config('theme', 'server'); + + if (empty($server)) { + $server = common_config('site', 'server'); + } + + // XXX: protocol + + $this->path = 'http://'.$server.$path.$name; + } } - $dir = common_config('theme', 'dir'); - if (empty($dir)) { - $dir = INSTALLDIR.'/theme'; + + /** + * Gets the full local filename of a file in this theme. + * + * @param string $relative relative name, like 'logo.png' + * + * @return string full pathname, like /var/www/mublog/theme/default/logo.png + */ + + function getFile($relative) + { + return $this->dir.'/'.$relative; + } + + /** + * Gets the full HTTP url of a file in this theme + * + * @param string $relative relative name, like 'logo.png' + * + * @return string full URL, like 'http://example.com/theme/default/logo.png' + */ + + function getPath($relative) + { + return $this->path.'/'.$relative; + } + + /** + * Gets the full path of a file in a theme dir based on its relative name + * + * @param string $relative relative path within the theme directory + * @param string $name name of the theme; defaults to current theme + * + * @return string File path to the theme file + */ + + static function file($relative, $name=null) + { + $theme = new Theme($name); + return $theme->getFile($relative); + } + + /** + * Gets the full URL of a file in a theme dir based on its relative name + * + * @param string $relative relative path within the theme directory + * @param string $name name of the theme; defaults to current theme + * + * @return string URL of the file + */ + + static function path($relative, $name=null) + { + $theme = new Theme($name); + return $theme->getPath($relative); } - return $dir.'/'.$theme.'/'.$relative; -} - -/** - * Gets the full URL of a file in a theme dir based on its relative name - * - * @param string $relative relative path within the theme directory - * @param string $theme name of the theme; defaults to current theme - * - * @return string URL of the file - */ - -function theme_path($relative, $theme=null) -{ - if (empty($theme)) { - $theme = common_config('site', 'theme'); - } - - $path = common_config('theme', 'path'); - - if (empty($path)) { - $path = common_config('site', 'path') . '/theme/'; - } - - if ($path[strlen($path)-1] != '/') { - $path .= '/'; - } - - if ($path[0] != '/') { - $path = '/'.$path; - } - - $server = common_config('theme', 'server'); - - if (empty($server)) { - $server = common_config('site', 'server'); - } - - // XXX: protocol - - return 'http://'.$server.$path.$theme.'/'.$relative; } From 221b779e88e51b70a2c3509798154c461203e636 Mon Sep 17 00:00:00 2001 From: Siebrand Mazeland Date: Sun, 8 Nov 2009 23:10:44 +0100 Subject: [PATCH 16/25] Harmonise UI message "No such user." --- actions/apiaccountupdateprofileimage.php | 2 +- actions/apiblockcreate.php | 2 +- actions/apiblockdestroy.php | 2 +- actions/apidirectmessage.php | 2 +- actions/apidirectmessagenew.php | 2 +- actions/apigroupcreate.php | 2 +- actions/apigroupismember.php | 2 +- actions/apigroupjoin.php | 2 +- actions/apigroupleave.php | 2 +- actions/apigrouplist.php | 2 +- actions/apistatusesupdate.php | 2 +- actions/apisubscriptions.php | 2 +- actions/apitimelinefavorites.php | 2 +- actions/apitimelinefriends.php | 2 +- actions/apitimelinementions.php | 2 +- actions/apitimelineuser.php | 2 +- actions/microsummary.php | 2 +- actions/newmessage.php | 2 +- actions/remotesubscribe.php | 2 +- lib/oauthstore.php | 4 ++-- 20 files changed, 21 insertions(+), 21 deletions(-) diff --git a/actions/apiaccountupdateprofileimage.php b/actions/apiaccountupdateprofileimage.php index 72fb361bf8..2f8e9628c4 100644 --- a/actions/apiaccountupdateprofileimage.php +++ b/actions/apiaccountupdateprofileimage.php @@ -102,7 +102,7 @@ class ApiAccountUpdateProfileImageAction extends ApiAuthAction } if (empty($this->user)) { - $this->clientError(_('No such user!'), 404, $this->format); + $this->clientError(_('No such user.'), 404, $this->format); return; } diff --git a/actions/apiblockcreate.php b/actions/apiblockcreate.php index 1cab2df5d0..4f941f6c32 100644 --- a/actions/apiblockcreate.php +++ b/actions/apiblockcreate.php @@ -94,7 +94,7 @@ class ApiBlockCreateAction extends ApiAuthAction } if (empty($this->user) || empty($this->other)) { - $this->clientError(_('No such user!'), 404, $this->format); + $this->clientError(_('No such user.'), 404, $this->format); return; } diff --git a/actions/apiblockdestroy.php b/actions/apiblockdestroy.php index 16dbf94caf..328f18ab0d 100644 --- a/actions/apiblockdestroy.php +++ b/actions/apiblockdestroy.php @@ -93,7 +93,7 @@ class ApiBlockDestroyAction extends ApiAuthAction } if (empty($this->user) || empty($this->other)) { - $this->clientError(_('No such user!'), 404, $this->format); + $this->clientError(_('No such user.'), 404, $this->format); return; } diff --git a/actions/apidirectmessage.php b/actions/apidirectmessage.php index a21fe86d20..5b3f412adc 100644 --- a/actions/apidirectmessage.php +++ b/actions/apidirectmessage.php @@ -74,7 +74,7 @@ class ApiDirectMessageAction extends ApiAuthAction $this->user = $this->auth_user; if (empty($this->user)) { - $this->clientError(_('No such user!'), 404, $this->format); + $this->clientError(_('No such user.'), 404, $this->format); return; } diff --git a/actions/apidirectmessagenew.php b/actions/apidirectmessagenew.php index ca1ee70dde..fed6acc30e 100644 --- a/actions/apidirectmessagenew.php +++ b/actions/apidirectmessagenew.php @@ -72,7 +72,7 @@ class ApiDirectMessageNewAction extends ApiAuthAction $this->user = $this->auth_user; if (empty($this->user)) { - $this->clientError(_('No such user!'), 404, $this->format); + $this->clientError(_('No such user.'), 404, $this->format); return; } diff --git a/actions/apigroupcreate.php b/actions/apigroupcreate.php index f66e830738..895dfb7aba 100644 --- a/actions/apigroupcreate.php +++ b/actions/apigroupcreate.php @@ -109,7 +109,7 @@ class ApiGroupCreateAction extends ApiAuthAction } if (empty($this->user)) { - $this->clientError(_('No such user!'), 404, $this->format); + $this->clientError(_('No such user.'), 404, $this->format); return; } diff --git a/actions/apigroupismember.php b/actions/apigroupismember.php index a8a40a6b3b..a822d18ddd 100644 --- a/actions/apigroupismember.php +++ b/actions/apigroupismember.php @@ -87,7 +87,7 @@ class ApiGroupIsMemberAction extends ApiBareAuthAction parent::handle($args); if (empty($this->user)) { - $this->clientError(_('No such user!'), 404, $this->format); + $this->clientError(_('No such user.'), 404, $this->format); return; } diff --git a/actions/apigroupjoin.php b/actions/apigroupjoin.php index 071cd9290f..ffda3986ff 100644 --- a/actions/apigroupjoin.php +++ b/actions/apigroupjoin.php @@ -96,7 +96,7 @@ class ApiGroupJoinAction extends ApiAuthAction } if (empty($this->user)) { - $this->clientError(_('No such user!'), 404, $this->format); + $this->clientError(_('No such user.'), 404, $this->format); return; } diff --git a/actions/apigroupleave.php b/actions/apigroupleave.php index 0d4bb9e4d3..8665ea1aa8 100644 --- a/actions/apigroupleave.php +++ b/actions/apigroupleave.php @@ -96,7 +96,7 @@ class ApiGroupLeaveAction extends ApiAuthAction } if (empty($this->user)) { - $this->clientError(_('No such user!'), 404, $this->format); + $this->clientError(_('No such user.'), 404, $this->format); return; } diff --git a/actions/apigrouplist.php b/actions/apigrouplist.php index c529c1e408..7b05f8a96c 100644 --- a/actions/apigrouplist.php +++ b/actions/apigrouplist.php @@ -87,7 +87,7 @@ class ApiGroupListAction extends ApiBareAuthAction parent::handle($args); if (empty($this->user)) { - $this->clientError(_('No such user!'), 404, $this->format); + $this->clientError(_('No such user.'), 404, $this->format); return; } diff --git a/actions/apistatusesupdate.php b/actions/apistatusesupdate.php index e369fa71ee..5c23acccae 100644 --- a/actions/apistatusesupdate.php +++ b/actions/apistatusesupdate.php @@ -136,7 +136,7 @@ class ApiStatusesUpdateAction extends ApiAuthAction } if (empty($this->user)) { - $this->clientError(_('No such user!'), 404, $this->format); + $this->clientError(_('No such user.'), 404, $this->format); return; } diff --git a/actions/apisubscriptions.php b/actions/apisubscriptions.php index bc68dd192a..2c691bb84c 100644 --- a/actions/apisubscriptions.php +++ b/actions/apisubscriptions.php @@ -84,7 +84,7 @@ class ApiSubscriptionsAction extends ApiBareAuthAction $this->user = $this->getTargetUser($this->arg('id')); if (empty($this->user)) { - $this->clientError(_('No such user!'), 404, $this->format); + $this->clientError(_('No such user.'), 404, $this->format); return false; } diff --git a/actions/apitimelinefavorites.php b/actions/apitimelinefavorites.php index b8ae74f137..f84d7b4cb7 100644 --- a/actions/apitimelinefavorites.php +++ b/actions/apitimelinefavorites.php @@ -67,7 +67,7 @@ class ApiTimelineFavoritesAction extends ApiBareAuthAction $this->user = $this->getTargetUser($this->arg('id')); if (empty($this->user)) { - $this->clientError(_('No such user!'), 404, $this->format); + $this->clientError(_('No such user.'), 404, $this->format); return; } diff --git a/actions/apitimelinefriends.php b/actions/apitimelinefriends.php index 66dd3f2b29..e84f773723 100644 --- a/actions/apitimelinefriends.php +++ b/actions/apitimelinefriends.php @@ -76,7 +76,7 @@ class ApiTimelineFriendsAction extends ApiBareAuthAction $this->user = $this->getTargetUser($this->arg('id')); if (empty($this->user)) { - $this->clientError(_('No such user!'), 404, $this->format); + $this->clientError(_('No such user.'), 404, $this->format); return; } diff --git a/actions/apitimelinementions.php b/actions/apitimelinementions.php index fe5ff0f28f..0956ccdceb 100644 --- a/actions/apitimelinementions.php +++ b/actions/apitimelinementions.php @@ -76,7 +76,7 @@ class ApiTimelineMentionsAction extends ApiBareAuthAction $this->user = $this->getTargetUser($this->arg('id')); if (empty($this->user)) { - $this->clientError(_('No such user!'), 404, $this->format); + $this->clientError(_('No such user.'), 404, $this->format); return; } diff --git a/actions/apitimelineuser.php b/actions/apitimelineuser.php index 285735fd1a..ca1d217725 100644 --- a/actions/apitimelineuser.php +++ b/actions/apitimelineuser.php @@ -78,7 +78,7 @@ class ApiTimelineUserAction extends ApiBareAuthAction $this->user = $this->getTargetUser($this->arg('id')); if (empty($this->user)) { - $this->clientError(_('No such user!'), 404, $this->format); + $this->clientError(_('No such user.'), 404, $this->format); return; } diff --git a/actions/microsummary.php b/actions/microsummary.php index 5c01a9ce0f..5c761e8bb6 100644 --- a/actions/microsummary.php +++ b/actions/microsummary.php @@ -59,7 +59,7 @@ class MicrosummaryAction extends Action $user = User::staticGet('nickname', $nickname); if (!$user) { - $this->clientError(_('No such user'), 404); + $this->clientError(_('No such user.'), 404); return; } diff --git a/actions/newmessage.php b/actions/newmessage.php index 095a7d1d34..0db2e7181c 100644 --- a/actions/newmessage.php +++ b/actions/newmessage.php @@ -113,7 +113,7 @@ class NewmessageAction extends Action $this->other = User::staticGet('id', $this->to); if (!$this->other) { - $this->clientError(_('No such user'), 404); + $this->clientError(_('No such user.'), 404); return false; } diff --git a/actions/remotesubscribe.php b/actions/remotesubscribe.php index aee2a5d8e7..74025cf807 100644 --- a/actions/remotesubscribe.php +++ b/actions/remotesubscribe.php @@ -151,7 +151,7 @@ class RemotesubscribeAction extends Action $this->profile_url = $this->trimmed('profile_url'); if (!$this->profile_url) { - $this->showForm(_('No such user')); + $this->showForm(_('No such user.')); return; } diff --git a/lib/oauthstore.php b/lib/oauthstore.php index d617a7df7e..a4ea5ad4d0 100644 --- a/lib/oauthstore.php +++ b/lib/oauthstore.php @@ -351,7 +351,7 @@ class StatusNetOAuthDataStore extends OAuthDataStore $author = User::staticGet('uri', $author_uri); } if (!$author) { - throw new Exception('No such user'); + throw new Exception('No such user.'); } common_log(LOG_DEBUG, print_r($author, true), __FILE__); @@ -407,7 +407,7 @@ class StatusNetOAuthDataStore extends OAuthDataStore $user = User::staticGet('uri', $uri); } if (!$user) { - throw new Exception('No such user'); + throw new Exception('No such user.'); } return $user; } From a034fb0b82dc586bdec10523100f628a2ecf0fe4 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Sun, 8 Nov 2009 23:22:13 +0100 Subject: [PATCH 17/25] Revert "* check usage of 'people' in UI and change it to 'users' or something else in most places" This reverts commit 81b4a381d9ddc71ed8a53c074ea10910882d3156. IMO "user" is a bit impersonal and we shouldn't go changing the tone of the UI willy-nilly when we're updating localisations. --- actions/all.php | 2 +- actions/foaf.php | 4 ++-- actions/groups.php | 7 +++---- actions/imsettings.php | 2 +- actions/invite.php | 10 +++++----- actions/noticesearch.php | 2 +- actions/opensearch.php | 2 +- actions/peoplesearch.php | 2 +- actions/peopletag.php | 2 +- actions/profilesettings.php | 4 ++-- actions/register.php | 10 +++++----- actions/replies.php | 4 ++-- actions/subscribers.php | 8 ++++---- actions/subscriptions.php | 10 +++++----- actions/tagother.php | 2 +- lib/action.php | 2 +- 16 files changed, 36 insertions(+), 37 deletions(-) diff --git a/actions/all.php b/actions/all.php index b0fd8ee77c..61cedce749 100644 --- a/actions/all.php +++ b/actions/all.php @@ -129,7 +129,7 @@ class AllAction extends ProfileAction if (common_logged_in()) { $current_user = common_current_user(); if ($this->user->id === $current_user->id) { - $message .= _('Try subscribing to more users, [join a group](%%action.groups%%) or post something yourself.'); + $message .= _('Try subscribing to more people, [join a group](%%action.groups%%) or post something yourself.'); } else { $message .= sprintf(_('You can try to [nudge %s](../%s) from his profile or [post something to his or her attention](%%%%action.newnotice%%%%?status_textarea=%s).'), $this->user->nickname, $this->user->nickname, '@' . $this->user->nickname); } diff --git a/actions/foaf.php b/actions/foaf.php index dd27470698..356393304e 100644 --- a/actions/foaf.php +++ b/actions/foaf.php @@ -136,7 +136,7 @@ class FoafAction extends Action $person = $this->showMicrobloggingAccount($this->profile, common_root_url(), $this->user->uri, false); - // Get users who subscribe to user + // Get people who subscribe to user $sub = new Subscription(); $sub->subscribed = $this->profile->id; @@ -250,7 +250,7 @@ class FoafAction extends Action if ($isSubscriber) { $this->element('sioc:follows', array('rdf:resource'=>$this->user->uri . '#acct')); } else { - // Get users user is subscribed to + // Get people user is subscribed to $sub = new Subscription(); $sub->subscriber = $profile->id; $sub->whereAdd('subscriber != subscribed'); diff --git a/actions/groups.php b/actions/groups.php index c713d0a98e..10a1d5964d 100644 --- a/actions/groups.php +++ b/actions/groups.php @@ -88,12 +88,11 @@ class GroupsAction extends Action { $notice = sprintf(_('%%%%site.name%%%% groups let you find and talk with ' . - 'users of similar interests. After you join a group ' . + 'people of similar interests. After you join a group ' . 'you can send messages to all other members using the ' . - 'syntax "!groupname". Are you not seeing any groups ' . - 'you like? Try ' . + 'syntax "!groupname". Don\'t see a group you like? Try ' . '[searching for one](%%%%action.groupsearch%%%%) or ' . - '[start your own](%%%%action.newgroup%%%%)!')); + '[start your own!](%%%%action.newgroup%%%%)')); $this->elementStart('div', 'instructions'); $this->raw(common_markup_to_html($notice)); $this->elementEnd('div'); diff --git a/actions/imsettings.php b/actions/imsettings.php index 49c7b2a0e0..b5bf72f452 100644 --- a/actions/imsettings.php +++ b/actions/imsettings.php @@ -151,7 +151,7 @@ class ImsettingsAction extends ConnectSettingsAction $this->elementStart('li'); $this->checkbox('jabberreplies', _('Send me replies through Jabber/GTalk '. - 'from users I am not subscribed to.'), + 'from people I\'m not subscribed to.'), $user->jabberreplies); $this->elementEnd('li'); $this->elementStart('li'); diff --git a/actions/invite.php b/actions/invite.php index 8a0ac8a1b0..3015202e9e 100644 --- a/actions/invite.php +++ b/actions/invite.php @@ -133,7 +133,7 @@ class InviteAction extends CurrentUserDesignAction $this->elementEnd('ul'); } if ($this->subbed) { - $this->element('p', null, _('These are already users and you were automatically subscribed to them:')); + $this->element('p', null, _('These people are already users and you were automatically subscribed to them:')); $this->elementStart('ul'); foreach ($this->subbed as $other) { $this->element('li', null, sprintf(_('%s (%s)'), $other->nickname, $other->email)); @@ -141,7 +141,7 @@ class InviteAction extends CurrentUserDesignAction $this->elementEnd('ul'); } if ($this->sent) { - $this->element('p', null, _('Invitation(s) sent to the following e-mail addresses:')); + $this->element('p', null, _('Invitation(s) sent to the following people:')); $this->elementStart('ul'); foreach ($this->sent as $other) { $this->element('li', null, $other); @@ -226,9 +226,9 @@ class InviteAction extends CurrentUserDesignAction $headers['Subject'] = sprintf(_('%1$s has invited you to join them on %2$s'), $bestname, $sitename); $body = sprintf(_("%1\$s has invited you to join them on %2\$s (%3\$s).\n\n". - "%2\$s is a micro-blogging service that lets you keep up-to-date with those you know and those who interest you.\n\n". - "You can also share news about yourself, your thoughts, or your life online with users who know about you. ". - "It is also great for meeting others who share your interests.\n\n". + "%2\$s is a micro-blogging service that lets you keep up-to-date with people you know and people who interest you.\n\n". + "You can also share news about yourself, your thoughts, or your life online with people who know about you. ". + "It's also great for meeting new people who share your interests.\n\n". "%1\$s said:\n\n%4\$s\n\n". "You can see %1\$s's profile page on %2\$s here:\n\n". "%5\$s\n\n". diff --git a/actions/noticesearch.php b/actions/noticesearch.php index fe86c8cd3d..79cf572cca 100644 --- a/actions/noticesearch.php +++ b/actions/noticesearch.php @@ -44,7 +44,7 @@ require_once INSTALLDIR.'/lib/searchaction.php'; * @author Robin Millette * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 * @link http://status.net/ - * @todo common parent for user and content search? + * @todo common parent for people and content search? */ class NoticesearchAction extends SearchAction { diff --git a/actions/opensearch.php b/actions/opensearch.php index 8ebb5fc824..861b53d7d8 100644 --- a/actions/opensearch.php +++ b/actions/opensearch.php @@ -61,7 +61,7 @@ class OpensearchAction extends Action $short_name = ''; if ($type == 'people') { $type = 'peoplesearch'; - $short_name = _('User Search'); + $short_name = _('People Search'); } else { $type = 'noticesearch'; $short_name = _('Notice Search'); diff --git a/actions/peoplesearch.php b/actions/peoplesearch.php index 63a5c88f33..38135ecbde 100644 --- a/actions/peoplesearch.php +++ b/actions/peoplesearch.php @@ -49,7 +49,7 @@ class PeoplesearchAction extends SearchAction { function getInstructions() { - return _('Search for users on %%site.name%% by their name, location, or interests. ' . + return _('Search for people on %%site.name%% by their name, location, or interests. ' . 'Separate the terms by spaces; they must be 3 characters or more.'); } diff --git a/actions/peopletag.php b/actions/peopletag.php index dbce417df3..6dbbc92616 100644 --- a/actions/peopletag.php +++ b/actions/peopletag.php @@ -67,7 +67,7 @@ class PeopletagAction extends Action $this->tag = $this->trimmed('tag'); if (!common_valid_profile_tag($this->tag)) { - $this->clientError(sprintf(_('Not a valid user tag: %s'), + $this->clientError(sprintf(_('Not a valid people tag: %s'), $this->tag)); return; } diff --git a/actions/profilesettings.php b/actions/profilesettings.php index 6a1c07f9d2..0a0cc59973 100644 --- a/actions/profilesettings.php +++ b/actions/profilesettings.php @@ -68,8 +68,8 @@ class ProfilesettingsAction extends AccountSettingsAction function getInstructions() { - return _('You can update your personal profile info here ' . - 'so readers know more about you.'); + return _('You can update your personal profile info here '. + 'so people know more about you.'); } function showScripts() diff --git a/actions/register.php b/actions/register.php index 584ad3ead4..57f8e7bdf0 100644 --- a/actions/register.php +++ b/actions/register.php @@ -82,14 +82,14 @@ class RegisterAction extends Action } if (common_config('site', 'inviteonly') && empty($this->code)) { - $this->clientError(_('Sorry. Only those invited can register.')); + $this->clientError(_('Sorry, only invited people can register.')); return false; } if (!empty($this->code)) { $this->invite = Invitation::staticGet('code', $this->code); if (empty($this->invite)) { - $this->clientError(_('Sorry. This is an invalid invitation code.')); + $this->clientError(_('Sorry, invalid invitation code.')); return false; } // Store this in case we need it @@ -186,7 +186,7 @@ class RegisterAction extends Action } if (common_config('site', 'inviteonly') && !($code && $invite)) { - $this->clientError(_('Sorry. Only those invited can register.')); + $this->clientError(_('Sorry, only invited people can register.')); return; } @@ -401,7 +401,7 @@ class RegisterAction extends Action } if (common_config('site', 'inviteonly') && !($code && $invite)) { - $this->clientError(_('Sorry. Only those invited can register.')); + $this->clientError(_('Sorry, only invited people can register.')); return; } @@ -542,7 +542,7 @@ class RegisterAction extends Action '(%%%%action.imsettings%%%%) '. 'so you can send notices '. 'through instant messages.' . "\n" . - '* [Search for users](%%%%action.peoplesearch%%%%) '. + '* [Search for people](%%%%action.peoplesearch%%%%) '. 'that you may know or '. 'that share your interests. ' . "\n" . '* Update your [profile settings]'. diff --git a/actions/replies.php b/actions/replies.php index 2829a73350..a13b5a2273 100644 --- a/actions/replies.php +++ b/actions/replies.php @@ -195,12 +195,12 @@ class RepliesAction extends OwnerDesignAction function showEmptyListMessage() { - $message = sprintf(_('This is the timeline showing replies to %s but %s has not received a notice to his attention yet.'), $this->user->nickname, $this->user->nickname) . ' '; + $message = sprintf(_('This is the timeline showing replies to %s but %s hasn\'t received a notice to his attention yet.'), $this->user->nickname, $this->user->nickname) . ' '; if (common_logged_in()) { $current_user = common_current_user(); if ($this->user->id === $current_user->id) { - $message .= _('You can engage other users in a conversation, subscribe to more users or [join groups](%%action.groups%%).'); + $message .= _('You can engage other users in a conversation, subscribe to more people or [join groups](%%action.groups%%).'); } else { $message .= sprintf(_('You can try to [nudge %s](../%s) or [post something to his or her attention](%%%%action.newnotice%%%%?status_textarea=%s).'), $this->user->nickname, $this->user->nickname, '@' . $this->user->nickname); } diff --git a/actions/subscribers.php b/actions/subscribers.php index 1f584e2c14..df9ec99615 100644 --- a/actions/subscribers.php +++ b/actions/subscribers.php @@ -60,12 +60,12 @@ class SubscribersAction extends GalleryAction $user =& common_current_user(); if ($user && ($user->id == $this->profile->id)) { $this->element('p', null, - _('These are the users who have subscribed to '. + _('These are the people who listen to '. 'your notices.')); } else { $this->element('p', null, - sprintf(_('These are the users who '. - 'have subscribed to %s\'s notices.'), + sprintf(_('These are the people who '. + 'listen to %s\'s notices.'), $this->profile->nickname)); } } @@ -105,7 +105,7 @@ class SubscribersAction extends GalleryAction if (common_logged_in()) { $current_user = common_current_user(); if ($this->user->id === $current_user->id) { - $message = _('You have no subscribers. Try subscribing to users you know and they might return the favor'); + $message = _('You have no subscribers. Try subscribing to people you know and they might return the favor'); } else { $message = sprintf(_('%s has no subscribers. Want to be the first?'), $this->user->nickname); } diff --git a/actions/subscriptions.php b/actions/subscriptions.php index 4f65e9bf1f..cc7b38ee46 100644 --- a/actions/subscriptions.php +++ b/actions/subscriptions.php @@ -62,12 +62,12 @@ class SubscriptionsAction extends GalleryAction $user =& common_current_user(); if ($user && ($user->id == $this->profile->id)) { $this->element('p', null, - _('These are the users whose notices '. - 'you have subscribed to.')); + _('These are the people whose notices '. + 'you listen to.')); } else { $this->element('p', null, - sprintf(_('These are the users whose '. - 'notices %s has subscribed to.'), + sprintf(_('These are the people whose '. + 'notices %s listens to.'), $this->profile->nickname)); } } @@ -118,7 +118,7 @@ class SubscriptionsAction extends GalleryAction if (common_logged_in()) { $current_user = common_current_user(); if ($this->user->id === $current_user->id) { - $message = _('You have not subscribed to anyone\'s notices right now. Try subscribing to users you know. Try [user search](%%action.peoplesearch%%), look for members in groups you\'re interested in and in our [featured users](%%action.featured%%). If you are a [Twitter user](%%action.twittersettings%%), you can automatically subscribe to users you already follow there.'); + $message = _('You\'re not listening to anyone\'s notices right now, try subscribing to people you know. Try [people search](%%action.peoplesearch%%), look for members in groups you\'re interested in and in our [featured users](%%action.featured%%). If you\'re a [Twitter user](%%action.twittersettings%%), you can automatically subscribe to people you already follow there.'); } else { $message = sprintf(_('%s is not listening to anyone.'), $this->user->nickname); } diff --git a/actions/tagother.php b/actions/tagother.php index 80fa9cc95d..c3f43be8ba 100644 --- a/actions/tagother.php +++ b/actions/tagother.php @@ -190,7 +190,7 @@ class TagotherAction extends Action !Subscription::pkeyGet(array('subscriber' => $this->profile->id, 'subscribed' => $user->id))) { - $this->clientError(_('You can only tag users you are subscribed to or who are subscribed to you.')); + $this->clientError(_('You can only tag people you are subscribed to or who are subscribed to you.')); return; } diff --git a/lib/action.php b/lib/action.php index 34b17063a9..80f398fbd7 100644 --- a/lib/action.php +++ b/lib/action.php @@ -456,7 +456,7 @@ class Action extends HTMLOutputter // lawsuit _('Help'), _('Help me!'), false, 'nav_help'); if ($user || !common_config('site', 'private')) { $this->menuItem(common_local_url('peoplesearch'), - _('Search'), _('Search for users or text'), false, 'nav_search'); + _('Search'), _('Search for people or text'), false, 'nav_search'); } Event::handle('EndPrimaryNav', array($this)); } From 0ab17f382b9993ada3d12d4cdace72cca53fb545 Mon Sep 17 00:00:00 2001 From: Siebrand Mazeland Date: Sun, 8 Nov 2009 23:22:38 +0100 Subject: [PATCH 18/25] * [Cc]an't -> [Cc]annot * [Cc]ould't -> [Cc]ould not --- actions/emailsettings.php | 4 +- actions/smssettings.php | 2 +- classes/File.php | 2 +- classes/Notice.php | 4 +- extlib/Auth/OpenID/Consumer.php | 2 +- extlib/Auth/OpenID/Discover.php | 4 +- extlib/Auth/OpenID/FileStore.php | 2 +- extlib/DB.php | 2 +- extlib/DB/DataObject/Generator.php | 4 +- extlib/DB/dbase.php | 6 +- extlib/DB/fbsql.php | 8 +- extlib/DB/ibase.php | 6 +- extlib/DB/ifx.php | 12 +- extlib/DB/msql.php | 8 +- extlib/DB/mssql.php | 10 +- extlib/DB/mysql.php | 14 +- extlib/DB/mysqli.php | 14 +- extlib/DB/oci8.php | 10 +- extlib/DB/odbc.php | 8 +- extlib/DB/pgsql.php | 10 +- extlib/DB/sqlite.php | 8 +- extlib/DB/sybase.php | 12 +- extlib/HTTP/Request2/Adapter/Socket.php | 1940 +-- extlib/MIME/Type.php | 4 +- extlib/MIME/Type/Extension.php | 4 +- extlib/Mail/mail.php | 2 +- extlib/Mail/sendmail.php | 2 +- extlib/Net/LDAP2/Entry.php | 2 +- extlib/Net/LDAP2/Filter.php | 2 +- extlib/System/Command.php | 2 +- extlib/markdown.php | 2 +- install.php | 16 +- lib/attachmentlist.php | 2 +- lib/noticelist.php | 2 +- lib/profilelist.php | 2 +- lib/serverexception.php | 2 +- lib/settingsaction.php | 2 +- lib/util.php | 2 +- lib/xmppqueuehandler.php | 2 +- locale/statusnet.po | 10410 ++++++---------- .../facebook/facebookapi_php5_restlib.php | 2 +- .../facebook/jsonwrapper/JSON/JSON.php | 2 +- plugins/Facebook/facebookaction.php | 2 +- plugins/Facebook/facebookhome.php | 2 +- plugins/LinkbackPlugin.php | 2 +- plugins/Meteor/MeteorPlugin.php | 2 +- plugins/OpenID/openid.php | 4 +- .../daemons/synctwitterfriends.php | 8 +- .../daemons/twitterstatusfetcher.php | 8 +- plugins/UserFlag/flagprofile.php | 2 +- scripts/console.php | 2 +- scripts/createsim.php | 4 +- scripts/deleteuser.php | 4 +- scripts/fixup_utf8.php | 2 +- scripts/makegroupadmin.php | 4 +- scripts/registeruser.php | 4 +- scripts/showcache.php | 2 +- scripts/sitemap.php | 4 +- scripts/update_translations.php | 2 +- 59 files changed, 4873 insertions(+), 7741 deletions(-) diff --git a/actions/emailsettings.php b/actions/emailsettings.php index 67b991cdc8..715457eab2 100644 --- a/actions/emailsettings.php +++ b/actions/emailsettings.php @@ -452,7 +452,7 @@ class EmailsettingsAction extends AccountSettingsAction if (!$user->updateKeys($orig)) { common_log_db_error($user, 'UPDATE', __FILE__); - $this->serverError(_("Couldn't update user record.")); + $this->serverError(_("Could not update user record.")); } $this->showForm(_('Incoming email address removed.'), true); @@ -474,7 +474,7 @@ class EmailsettingsAction extends AccountSettingsAction if (!$user->updateKeys($orig)) { common_log_db_error($user, 'UPDATE', __FILE__); - $this->serverError(_("Couldn't update user record.")); + $this->serverError(_("Could not update user record.")); } $this->showForm(_('New incoming email address added.'), true); diff --git a/actions/smssettings.php b/actions/smssettings.php index 9fa7f62fb2..4debe19673 100644 --- a/actions/smssettings.php +++ b/actions/smssettings.php @@ -525,7 +525,7 @@ class SmssettingsAction extends ConnectSettingsAction if (!$user->updateKeys($orig)) { common_log_db_error($user, 'UPDATE', __FILE__); - $this->serverError(_("Couldn't update user record.")); + $this->serverError(_("Could not update user record.")); } $this->showForm(_('Incoming email address removed.'), true); diff --git a/classes/File.php b/classes/File.php index e04a9d5255..dd0c3227e1 100644 --- a/classes/File.php +++ b/classes/File.php @@ -99,7 +99,7 @@ class File extends Memcached_DataObject } elseif (is_string($redir_data)) { $redir_url = $redir_data; } else { - throw new ServerException("Can't process url '$given_url'"); + throw new ServerException("Cannot process url '$given_url'"); } // TODO: max field length if ($redir_url === $given_url || strlen($redir_url) > 255) { diff --git a/classes/Notice.php b/classes/Notice.php index 9886875cb7..862d4c762b 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -680,7 +680,7 @@ class Notice extends Memcached_DataObject return Notice::getStreamDirect($qry, $offset, $limit, null, null, $order, null); } - # Get the cache; if we can't, just go to the DB + # Get the cache; if we cannot, just go to the DB $cache = common_memcache(); @@ -1364,7 +1364,7 @@ class Notice extends Memcached_DataObject } } - // If it's not a "low bandwidth" source (one where you can't set + // If it's not a "low bandwidth" source (one where you cannot set // a reply_to argument), we return. This is mostly web and API // clients. diff --git a/extlib/Auth/OpenID/Consumer.php b/extlib/Auth/OpenID/Consumer.php index 500890b656..c75ef4c06f 100644 --- a/extlib/Auth/OpenID/Consumer.php +++ b/extlib/Auth/OpenID/Consumer.php @@ -1059,7 +1059,7 @@ class Auth_OpenID_GenericConsumer { } } - // Fragments do not influence discovery, so we can't compare a + // Fragments do not influence discovery, so we cannot compare a // claimed identifier with a fragment to discovered // information. list($defragged_claimed_id, $_) = diff --git a/extlib/Auth/OpenID/Discover.php b/extlib/Auth/OpenID/Discover.php index 62aeb1d2bc..9bb3ee357a 100644 --- a/extlib/Auth/OpenID/Discover.php +++ b/extlib/Auth/OpenID/Discover.php @@ -515,7 +515,7 @@ function Auth_OpenID_discoverXRI($iname, &$fetcher) function Auth_OpenID_discover($uri, &$fetcher) { - // If the fetcher (i.e., PHP) doesn't support SSL, we can't do + // If the fetcher (i.e., PHP) doesn't support SSL, we cannot do // discovery on an HTTPS URL. if ($fetcher->isHTTPS($uri) && !$fetcher->supportsSSL()) { return array($uri, array()); @@ -527,7 +527,7 @@ function Auth_OpenID_discover($uri, &$fetcher) $result = Auth_OpenID_discoverURI($uri, $fetcher); } - // If the fetcher doesn't support SSL, we can't interact with + // If the fetcher doesn't support SSL, we cannot interact with // HTTPS server URLs; remove those endpoints from the list. if (!$fetcher->supportsSSL()) { $http_endpoints = array(); diff --git a/extlib/Auth/OpenID/FileStore.php b/extlib/Auth/OpenID/FileStore.php index 29d8d20e76..d9962e153f 100644 --- a/extlib/Auth/OpenID/FileStore.php +++ b/extlib/Auth/OpenID/FileStore.php @@ -496,7 +496,7 @@ class Auth_OpenID_FileStore extends Auth_OpenID_OpenIDStore { return true; } else { - // Couldn't open directory. + // Could not open directory. return false; } } diff --git a/extlib/DB.php b/extlib/DB.php index a511979e67..4ef66f66f5 100644 --- a/extlib/DB.php +++ b/extlib/DB.php @@ -1341,7 +1341,7 @@ class DB_result * returning the total number of rows that would have been returned, * rather than the real number. As a result, we'll just do the limit * calculations for fbsql in the same way as a database with emulated - * limits. Unfortunately, we can't just do this in DB_fbsql::numRows() + * limits. Unfortunately, we cannot just do this in DB_fbsql::numRows() * because that only gets the result resource, rather than the full * DB_Result object. */ if (($this->dbh->features['limit'] === 'emulate' diff --git a/extlib/DB/DataObject/Generator.php b/extlib/DB/DataObject/Generator.php index ff6e42c7db..e14e3ef7f9 100644 --- a/extlib/DB/DataObject/Generator.php +++ b/extlib/DB/DataObject/Generator.php @@ -632,7 +632,7 @@ class DB_DataObject_Generator extends DB_DataObject echo "*****************************************************************\n". "** WARNING COLUMN NAME UNUSABLE **\n". "** Found column '{$t->name}', of type '{$t->type}' **\n". - "** Since this column name can't be converted to a php variable **\n". + "** Since this column name cannot be converted to a php variable **\n". "** name, and the whole idea of mapping would result in a mess **\n". "** This column has been ignored... **\n". "*****************************************************************\n"; @@ -910,7 +910,7 @@ class DB_DataObject_Generator extends DB_DataObject echo "*****************************************************************\n". "** WARNING COLUMN NAME UNUSABLE **\n". "** Found column '{$t->name}', of type '{$t->type}' **\n". - "** Since this column name can't be converted to a php variable **\n". + "** Since this column name cannot be converted to a php variable **\n". "** name, and the whole idea of mapping would result in a mess **\n". "** This column has been ignored... **\n". "*****************************************************************\n"; diff --git a/extlib/DB/dbase.php b/extlib/DB/dbase.php index 67afc897d7..15d259c4d0 100644 --- a/extlib/DB/dbase.php +++ b/extlib/DB/dbase.php @@ -287,7 +287,7 @@ class DB_dbase extends DB_common * See DB_result::fetchInto() for more information. * * This method is not meant to be called directly. Use - * DB_result::fetchInto() instead. It can't be declared "protected" + * DB_result::fetchInto() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result the query result resource @@ -352,7 +352,7 @@ class DB_dbase extends DB_common * Gets the number of columns in a result set * * This method is not meant to be called directly. Use - * DB_result::numCols() instead. It can't be declared "protected" + * DB_result::numCols() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource @@ -373,7 +373,7 @@ class DB_dbase extends DB_common * Gets the number of rows in a result set * * This method is not meant to be called directly. Use - * DB_result::numRows() instead. It can't be declared "protected" + * DB_result::numRows() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource diff --git a/extlib/DB/fbsql.php b/extlib/DB/fbsql.php index 4de4078f77..48ff705cf2 100644 --- a/extlib/DB/fbsql.php +++ b/extlib/DB/fbsql.php @@ -262,7 +262,7 @@ class DB_fbsql extends DB_common * See DB_result::fetchInto() for more information. * * This method is not meant to be called directly. Use - * DB_result::fetchInto() instead. It can't be declared "protected" + * DB_result::fetchInto() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result the query result resource @@ -309,7 +309,7 @@ class DB_fbsql extends DB_common * Deletes the result set and frees the memory occupied by the result set * * This method is not meant to be called directly. Use - * DB_result::free() instead. It can't be declared "protected" + * DB_result::free() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource @@ -376,7 +376,7 @@ class DB_fbsql extends DB_common * Gets the number of columns in a result set * * This method is not meant to be called directly. Use - * DB_result::numCols() instead. It can't be declared "protected" + * DB_result::numCols() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource @@ -401,7 +401,7 @@ class DB_fbsql extends DB_common * Gets the number of rows in a result set * * This method is not meant to be called directly. Use - * DB_result::numRows() instead. It can't be declared "protected" + * DB_result::numRows() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource diff --git a/extlib/DB/ibase.php b/extlib/DB/ibase.php index ee19c55890..1e444d6341 100644 --- a/extlib/DB/ibase.php +++ b/extlib/DB/ibase.php @@ -353,7 +353,7 @@ class DB_ibase extends DB_common * See DB_result::fetchInto() for more information. * * This method is not meant to be called directly. Use - * DB_result::fetchInto() instead. It can't be declared "protected" + * DB_result::fetchInto() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result the query result resource @@ -402,7 +402,7 @@ class DB_ibase extends DB_common * Deletes the result set and frees the memory occupied by the result set * * This method is not meant to be called directly. Use - * DB_result::free() instead. It can't be declared "protected" + * DB_result::free() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource @@ -449,7 +449,7 @@ class DB_ibase extends DB_common * Gets the number of columns in a result set * * This method is not meant to be called directly. Use - * DB_result::numCols() instead. It can't be declared "protected" + * DB_result::numCols() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource diff --git a/extlib/DB/ifx.php b/extlib/DB/ifx.php index baa6f2867c..dcb3dbd3ee 100644 --- a/extlib/DB/ifx.php +++ b/extlib/DB/ifx.php @@ -147,7 +147,7 @@ class DB_ifx extends DB_common /** * The quantity of transactions begun * - * {@internal While this is private, it can't actually be designated + * {@internal While this is private, it cannot actually be designated * private in PHP 5 because it is directly accessed in the test suite.}} * * @var integer @@ -328,7 +328,7 @@ class DB_ifx extends DB_common * See DB_result::fetchInto() for more information. * * This method is not meant to be called directly. Use - * DB_result::fetchInto() instead. It can't be declared "protected" + * DB_result::fetchInto() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result the query result resource @@ -387,7 +387,7 @@ class DB_ifx extends DB_common * Gets the number of columns in a result set * * This method is not meant to be called directly. Use - * DB_result::numCols() instead. It can't be declared "protected" + * DB_result::numCols() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource @@ -411,7 +411,7 @@ class DB_ifx extends DB_common * Deletes the result set and frees the memory occupied by the result set * * This method is not meant to be called directly. Use - * DB_result::free() instead. It can't be declared "protected" + * DB_result::free() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource @@ -555,7 +555,7 @@ class DB_ifx extends DB_common * * If analyzing a query result and the result has duplicate field names, * an error will be raised saying - * can't distinguish duplicate field names. + * cannot distinguish duplicate field names. * * @param object|string $result DB_result object from a query or a * string containing the name of a table. @@ -604,7 +604,7 @@ class DB_ifx extends DB_common $count = @ifx_num_fields($id); if (count($flds) != $count) { - return $this->raiseError("can't distinguish duplicate field names"); + return $this->raiseError("cannot distinguish duplicate field names"); } if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { diff --git a/extlib/DB/msql.php b/extlib/DB/msql.php index 34854f4720..ee64f932f5 100644 --- a/extlib/DB/msql.php +++ b/extlib/DB/msql.php @@ -288,7 +288,7 @@ class DB_msql extends DB_common * See DB_result::fetchInto() for more information. * * This method is not meant to be called directly. Use - * DB_result::fetchInto() instead. It can't be declared "protected" + * DB_result::fetchInto() instead. It cannot be declared "protected" * because DB_result is a separate object. * * PHP's mSQL extension did weird things with NULL values prior to PHP @@ -339,7 +339,7 @@ class DB_msql extends DB_common * Deletes the result set and frees the memory occupied by the result set * * This method is not meant to be called directly. Use - * DB_result::free() instead. It can't be declared "protected" + * DB_result::free() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource @@ -360,7 +360,7 @@ class DB_msql extends DB_common * Gets the number of columns in a result set * * This method is not meant to be called directly. Use - * DB_result::numCols() instead. It can't be declared "protected" + * DB_result::numCols() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource @@ -385,7 +385,7 @@ class DB_msql extends DB_common * Gets the number of rows in a result set * * This method is not meant to be called directly. Use - * DB_result::numRows() instead. It can't be declared "protected" + * DB_result::numRows() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource diff --git a/extlib/DB/mssql.php b/extlib/DB/mssql.php index 511a2b686a..1aad756712 100644 --- a/extlib/DB/mssql.php +++ b/extlib/DB/mssql.php @@ -156,7 +156,7 @@ class DB_mssql extends DB_common /** * The quantity of transactions begun * - * {@internal While this is private, it can't actually be designated + * {@internal While this is private, it cannot actually be designated * private in PHP 5 because it is directly accessed in the test suite.}} * * @var integer @@ -324,7 +324,7 @@ class DB_mssql extends DB_common * See DB_result::fetchInto() for more information. * * This method is not meant to be called directly. Use - * DB_result::fetchInto() instead. It can't be declared "protected" + * DB_result::fetchInto() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result the query result resource @@ -371,7 +371,7 @@ class DB_mssql extends DB_common * Deletes the result set and frees the memory occupied by the result set * * This method is not meant to be called directly. Use - * DB_result::free() instead. It can't be declared "protected" + * DB_result::free() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource @@ -392,7 +392,7 @@ class DB_mssql extends DB_common * Gets the number of columns in a result set * * This method is not meant to be called directly. Use - * DB_result::numCols() instead. It can't be declared "protected" + * DB_result::numCols() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource @@ -417,7 +417,7 @@ class DB_mssql extends DB_common * Gets the number of rows in a result set * * This method is not meant to be called directly. Use - * DB_result::numRows() instead. It can't be declared "protected" + * DB_result::numRows() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource diff --git a/extlib/DB/mysql.php b/extlib/DB/mysql.php index c672545205..bfe34dbe87 100644 --- a/extlib/DB/mysql.php +++ b/extlib/DB/mysql.php @@ -139,7 +139,7 @@ class DB_mysql extends DB_common /** * The quantity of transactions begun * - * {@internal While this is private, it can't actually be designated + * {@internal While this is private, it cannot actually be designated * private in PHP 5 because it is directly accessed in the test suite.}} * * @var integer @@ -359,7 +359,7 @@ class DB_mysql extends DB_common * See DB_result::fetchInto() for more information. * * This method is not meant to be called directly. Use - * DB_result::fetchInto() instead. It can't be declared "protected" + * DB_result::fetchInto() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result the query result resource @@ -411,7 +411,7 @@ class DB_mysql extends DB_common * Deletes the result set and frees the memory occupied by the result set * * This method is not meant to be called directly. Use - * DB_result::free() instead. It can't be declared "protected" + * DB_result::free() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource @@ -432,7 +432,7 @@ class DB_mysql extends DB_common * Gets the number of columns in a result set * * This method is not meant to be called directly. Use - * DB_result::numCols() instead. It can't be declared "protected" + * DB_result::numCols() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource @@ -457,7 +457,7 @@ class DB_mysql extends DB_common * Gets the number of rows in a result set * * This method is not meant to be called directly. Use - * DB_result::numRows() instead. It can't be declared "protected" + * DB_result::numRows() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource @@ -722,7 +722,7 @@ class DB_mysql extends DB_common return $result; } if ($result == 0) { - // Failed to get the lock, can't do the conversion, bail + // Failed to get the lock, cannot do the conversion, bail // with a DB_ERROR_NOT_LOCKED error return $this->mysqlRaiseError(DB_ERROR_NOT_LOCKED); } @@ -757,7 +757,7 @@ class DB_mysql extends DB_common * Quotes a string so it can be safely used as a table or column name * (WARNING: using names that require this is a REALLY BAD IDEA) * - * WARNING: Older versions of MySQL can't handle the backtick + * WARNING: Older versions of MySQL cannot handle the backtick * character (`) in table or column names. * * @param string $str identifier name to be quoted diff --git a/extlib/DB/mysqli.php b/extlib/DB/mysqli.php index c6941b170e..b6196dfcc1 100644 --- a/extlib/DB/mysqli.php +++ b/extlib/DB/mysqli.php @@ -142,7 +142,7 @@ class DB_mysqli extends DB_common /** * The quantity of transactions begun * - * {@internal While this is private, it can't actually be designated + * {@internal While this is private, it cannot actually be designated * private in PHP 5 because it is directly accessed in the test suite.}} * * @var integer @@ -434,7 +434,7 @@ class DB_mysqli extends DB_common * See DB_result::fetchInto() for more information. * * This method is not meant to be called directly. Use - * DB_result::fetchInto() instead. It can't be declared "protected" + * DB_result::fetchInto() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result the query result resource @@ -486,7 +486,7 @@ class DB_mysqli extends DB_common * Deletes the result set and frees the memory occupied by the result set * * This method is not meant to be called directly. Use - * DB_result::free() instead. It can't be declared "protected" + * DB_result::free() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource @@ -507,7 +507,7 @@ class DB_mysqli extends DB_common * Gets the number of columns in a result set * * This method is not meant to be called directly. Use - * DB_result::numCols() instead. It can't be declared "protected" + * DB_result::numCols() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource @@ -532,7 +532,7 @@ class DB_mysqli extends DB_common * Gets the number of rows in a result set * * This method is not meant to be called directly. Use - * DB_result::numRows() instead. It can't be declared "protected" + * DB_result::numRows() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource @@ -796,7 +796,7 @@ class DB_mysqli extends DB_common return $result; } if ($result == 0) { - // Failed to get the lock, can't do the conversion, bail + // Failed to get the lock, cannot do the conversion, bail // with a DB_ERROR_NOT_LOCKED error return $this->mysqliRaiseError(DB_ERROR_NOT_LOCKED); } @@ -832,7 +832,7 @@ class DB_mysqli extends DB_common * Quotes a string so it can be safely used as a table or column name * (WARNING: using names that require this is a REALLY BAD IDEA) * - * WARNING: Older versions of MySQL can't handle the backtick + * WARNING: Older versions of MySQL cannot handle the backtick * character (`) in table or column names. * * @param string $str identifier name to be quoted diff --git a/extlib/DB/oci8.php b/extlib/DB/oci8.php index d307948713..6ad36643a6 100644 --- a/extlib/DB/oci8.php +++ b/extlib/DB/oci8.php @@ -251,7 +251,7 @@ class DB_oci8 extends DB_common $char); $error = OCIError(); if (!empty($error) && $error['code'] == 12541) { - // Couldn't find TNS listener. Try direct connection. + // Could not find TNS listener. Try direct connection. $this->connection = @$connect_function($dsn['username'], $dsn['password'], null, @@ -368,7 +368,7 @@ class DB_oci8 extends DB_common * See DB_result::fetchInto() for more information. * * This method is not meant to be called directly. Use - * DB_result::fetchInto() instead. It can't be declared "protected" + * DB_result::fetchInto() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result the query result resource @@ -415,7 +415,7 @@ class DB_oci8 extends DB_common * Deletes the result set and frees the memory occupied by the result set * * This method is not meant to be called directly. Use - * DB_result::free() instead. It can't be declared "protected" + * DB_result::free() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource @@ -468,7 +468,7 @@ class DB_oci8 extends DB_common * is turned on. * * This method is not meant to be called directly. Use - * DB_result::numRows() instead. It can't be declared "protected" + * DB_result::numRows() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource @@ -511,7 +511,7 @@ class DB_oci8 extends DB_common * Gets the number of columns in a result set * * This method is not meant to be called directly. Use - * DB_result::numCols() instead. It can't be declared "protected" + * DB_result::numCols() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource diff --git a/extlib/DB/odbc.php b/extlib/DB/odbc.php index eba43659a7..b0dc83ab56 100644 --- a/extlib/DB/odbc.php +++ b/extlib/DB/odbc.php @@ -301,7 +301,7 @@ class DB_odbc extends DB_common * See DB_result::fetchInto() for more information. * * This method is not meant to be called directly. Use - * DB_result::fetchInto() instead. It can't be declared "protected" + * DB_result::fetchInto() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result the query result resource @@ -356,7 +356,7 @@ class DB_odbc extends DB_common * Deletes the result set and frees the memory occupied by the result set * * This method is not meant to be called directly. Use - * DB_result::free() instead. It can't be declared "protected" + * DB_result::free() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource @@ -377,7 +377,7 @@ class DB_odbc extends DB_common * Gets the number of columns in a result set * * This method is not meant to be called directly. Use - * DB_result::numCols() instead. It can't be declared "protected" + * DB_result::numCols() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource @@ -427,7 +427,7 @@ class DB_odbc extends DB_common * a DB_Error object for DB_ERROR_UNSUPPORTED is returned. * * This method is not meant to be called directly. Use - * DB_result::numRows() instead. It can't be declared "protected" + * DB_result::numRows() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource diff --git a/extlib/DB/pgsql.php b/extlib/DB/pgsql.php index 6030bb4c16..498ef8adeb 100644 --- a/extlib/DB/pgsql.php +++ b/extlib/DB/pgsql.php @@ -115,7 +115,7 @@ class DB_pgsql extends DB_common /** * The quantity of transactions begun * - * {@internal While this is private, it can't actually be designated + * {@internal While this is private, it cannot actually be designated * private in PHP 5 because it is directly accessed in the test suite.}} * * @var integer @@ -397,7 +397,7 @@ class DB_pgsql extends DB_common * See DB_result::fetchInto() for more information. * * This method is not meant to be called directly. Use - * DB_result::fetchInto() instead. It can't be declared "protected" + * DB_result::fetchInto() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result the query result resource @@ -445,7 +445,7 @@ class DB_pgsql extends DB_common * Deletes the result set and frees the memory occupied by the result set * * This method is not meant to be called directly. Use - * DB_result::free() instead. It can't be declared "protected" + * DB_result::free() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource @@ -535,7 +535,7 @@ class DB_pgsql extends DB_common * Gets the number of columns in a result set * * This method is not meant to be called directly. Use - * DB_result::numCols() instead. It can't be declared "protected" + * DB_result::numCols() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource @@ -560,7 +560,7 @@ class DB_pgsql extends DB_common * Gets the number of rows in a result set * * This method is not meant to be called directly. Use - * DB_result::numRows() instead. It can't be declared "protected" + * DB_result::numRows() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource diff --git a/extlib/DB/sqlite.php b/extlib/DB/sqlite.php index 5c4b396e5e..96d5c934a8 100644 --- a/extlib/DB/sqlite.php +++ b/extlib/DB/sqlite.php @@ -334,7 +334,7 @@ class DB_sqlite extends DB_common * See DB_result::fetchInto() for more information. * * This method is not meant to be called directly. Use - * DB_result::fetchInto() instead. It can't be declared "protected" + * DB_result::fetchInto() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result the query result resource @@ -396,7 +396,7 @@ class DB_sqlite extends DB_common * Deletes the result set and frees the memory occupied by the result set * * This method is not meant to be called directly. Use - * DB_result::free() instead. It can't be declared "protected" + * DB_result::free() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource @@ -422,7 +422,7 @@ class DB_sqlite extends DB_common * Gets the number of columns in a result set * * This method is not meant to be called directly. Use - * DB_result::numCols() instead. It can't be declared "protected" + * DB_result::numCols() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource @@ -447,7 +447,7 @@ class DB_sqlite extends DB_common * Gets the number of rows in a result set * * This method is not meant to be called directly. Use - * DB_result::numRows() instead. It can't be declared "protected" + * DB_result::numRows() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource diff --git a/extlib/DB/sybase.php b/extlib/DB/sybase.php index 3befbf6ea9..97ab41a22b 100644 --- a/extlib/DB/sybase.php +++ b/extlib/DB/sybase.php @@ -118,7 +118,7 @@ class DB_sybase extends DB_common /** * The quantity of transactions begun * - * {@internal While this is private, it can't actually be designated + * {@internal While this is private, it cannot actually be designated * private in PHP 5 because it is directly accessed in the test suite.}} * * @var integer @@ -302,7 +302,7 @@ class DB_sybase extends DB_common * See DB_result::fetchInto() for more information. * * This method is not meant to be called directly. Use - * DB_result::fetchInto() instead. It can't be declared "protected" + * DB_result::fetchInto() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result the query result resource @@ -359,7 +359,7 @@ class DB_sybase extends DB_common * Deletes the result set and frees the memory occupied by the result set * * This method is not meant to be called directly. Use - * DB_result::free() instead. It can't be declared "protected" + * DB_result::free() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource @@ -380,7 +380,7 @@ class DB_sybase extends DB_common * Gets the number of columns in a result set * * This method is not meant to be called directly. Use - * DB_result::numCols() instead. It can't be declared "protected" + * DB_result::numCols() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource @@ -405,7 +405,7 @@ class DB_sybase extends DB_common * Gets the number of rows in a result set * * This method is not meant to be called directly. Use - * DB_result::numRows() instead. It can't be declared "protected" + * DB_result::numRows() instead. It cannot be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource @@ -835,7 +835,7 @@ class DB_sybase extends DB_common $tableName = $table; /* We're running sp_helpindex directly because it doesn't exist in - * older versions of ASE -- unfortunately, we can't just use + * older versions of ASE -- unfortunately, we cannot just use * DB::isError() because the user may be using callback error * handling. */ $res = @sybase_query("sp_helpindex $table", $this->connection); diff --git a/extlib/HTTP/Request2/Adapter/Socket.php b/extlib/HTTP/Request2/Adapter/Socket.php index ff44d49594..13cd6136f9 100644 --- a/extlib/HTTP/Request2/Adapter/Socket.php +++ b/extlib/HTTP/Request2/Adapter/Socket.php @@ -1,971 +1,971 @@ - - * 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. - * * The names of the authors may not 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 HTTP - * @package HTTP_Request2 - * @author Alexey Borzov - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Socket.php 279760 2009-05-03 10:46:42Z avb $ - * @link http://pear.php.net/package/HTTP_Request2 - */ - -/** - * Base class for HTTP_Request2 adapters - */ -require_once 'HTTP/Request2/Adapter.php'; - -/** - * Socket-based adapter for HTTP_Request2 - * - * This adapter uses only PHP sockets and will work on almost any PHP - * environment. Code is based on original HTTP_Request PEAR package. - * - * @category HTTP - * @package HTTP_Request2 - * @author Alexey Borzov - * @version Release: 0.4.1 - */ -class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter -{ - /** - * Regular expression for 'token' rule from RFC 2616 - */ - const REGEXP_TOKEN = '[^\x00-\x1f\x7f-\xff()<>@,;:\\\\"/\[\]?={}\s]+'; - - /** - * Regular expression for 'quoted-string' rule from RFC 2616 - */ - const REGEXP_QUOTED_STRING = '"(?:\\\\.|[^\\\\"])*"'; - - /** - * Connected sockets, needed for Keep-Alive support - * @var array - * @see connect() - */ - protected static $sockets = array(); - - /** - * Data for digest authentication scheme - * - * The keys for the array are URL prefixes. - * - * The values are associative arrays with data (realm, nonce, nonce-count, - * opaque...) needed for digest authentication. Stored here to prevent making - * duplicate requests to digest-protected resources after we have already - * received the challenge. - * - * @var array - */ - protected static $challenges = array(); - - /** - * Connected socket - * @var resource - * @see connect() - */ - protected $socket; - - /** - * Challenge used for server digest authentication - * @var array - */ - protected $serverChallenge; - - /** - * Challenge used for proxy digest authentication - * @var array - */ - protected $proxyChallenge; - - /** - * Global timeout, exception will be raised if request continues past this time - * @var integer - */ - protected $timeout = null; - - /** - * Remaining length of the current chunk, when reading chunked response - * @var integer - * @see readChunked() - */ - protected $chunkLength = 0; - - /** - * Sends request to the remote server and returns its response - * - * @param HTTP_Request2 - * @return HTTP_Request2_Response - * @throws HTTP_Request2_Exception - */ - public function sendRequest(HTTP_Request2 $request) - { - $this->request = $request; - $keepAlive = $this->connect(); - $headers = $this->prepareHeaders(); - - // Use global request timeout if given, see feature requests #5735, #8964 - if ($timeout = $request->getConfig('timeout')) { - $this->timeout = time() + $timeout; - } else { - $this->timeout = null; - } - - try { - if (false === @fwrite($this->socket, $headers, strlen($headers))) { - throw new HTTP_Request2_Exception('Error writing request'); - } - // provide request headers to the observer, see request #7633 - $this->request->setLastEvent('sentHeaders', $headers); - $this->writeBody(); - - if ($this->timeout && time() > $this->timeout) { - throw new HTTP_Request2_Exception( - 'Request timed out after ' . - $request->getConfig('timeout') . ' second(s)' - ); - } - - $response = $this->readResponse(); - - if (!$this->canKeepAlive($keepAlive, $response)) { - $this->disconnect(); - } - - if ($this->shouldUseProxyDigestAuth($response)) { - return $this->sendRequest($request); - } - if ($this->shouldUseServerDigestAuth($response)) { - return $this->sendRequest($request); - } - if ($authInfo = $response->getHeader('authentication-info')) { - $this->updateChallenge($this->serverChallenge, $authInfo); - } - if ($proxyInfo = $response->getHeader('proxy-authentication-info')) { - $this->updateChallenge($this->proxyChallenge, $proxyInfo); - } - - } catch (Exception $e) { - $this->disconnect(); - throw $e; - } - - return $response; - } - - /** - * Connects to the remote server - * - * @return bool whether the connection can be persistent - * @throws HTTP_Request2_Exception - */ - protected function connect() - { - $secure = 0 == strcasecmp($this->request->getUrl()->getScheme(), 'https'); - $tunnel = HTTP_Request2::METHOD_CONNECT == $this->request->getMethod(); - $headers = $this->request->getHeaders(); - $reqHost = $this->request->getUrl()->getHost(); - if (!($reqPort = $this->request->getUrl()->getPort())) { - $reqPort = $secure? 443: 80; - } - - if ($host = $this->request->getConfig('proxy_host')) { - if (!($port = $this->request->getConfig('proxy_port'))) { - throw new HTTP_Request2_Exception('Proxy port not provided'); - } - $proxy = true; - } else { - $host = $reqHost; - $port = $reqPort; - $proxy = false; - } - - if ($tunnel && !$proxy) { - throw new HTTP_Request2_Exception( - "Trying to perform CONNECT request without proxy" - ); - } - if ($secure && !in_array('ssl', stream_get_transports())) { - throw new HTTP_Request2_Exception( - 'Need OpenSSL support for https:// requests' - ); - } - - // RFC 2068, section 19.7.1: A client MUST NOT send the Keep-Alive - // connection token to a proxy server... - if ($proxy && !$secure && - !empty($headers['connection']) && 'Keep-Alive' == $headers['connection'] - ) { - $this->request->setHeader('connection'); - } - - $keepAlive = ('1.1' == $this->request->getConfig('protocol_version') && - empty($headers['connection'])) || - (!empty($headers['connection']) && - 'Keep-Alive' == $headers['connection']); - $host = ((!$secure || $proxy)? 'tcp://': 'ssl://') . $host; - - $options = array(); - if ($secure || $tunnel) { - foreach ($this->request->getConfig() as $name => $value) { - if ('ssl_' == substr($name, 0, 4) && null !== $value) { - if ('ssl_verify_host' == $name) { - if ($value) { - $options['CN_match'] = $reqHost; - } - } else { - $options[substr($name, 4)] = $value; - } - } - } - ksort($options); - } - - // Changing SSL context options after connection is established does *not* - // work, we need a new connection if options change - $remote = $host . ':' . $port; - $socketKey = $remote . (($secure && $proxy)? "->{$reqHost}:{$reqPort}": '') . - (empty($options)? '': ':' . serialize($options)); - unset($this->socket); - - // We use persistent connections and have a connected socket? - // Ensure that the socket is still connected, see bug #16149 - if ($keepAlive && !empty(self::$sockets[$socketKey]) && - !feof(self::$sockets[$socketKey]) - ) { - $this->socket =& self::$sockets[$socketKey]; - - } elseif ($secure && $proxy && !$tunnel) { - $this->establishTunnel(); - $this->request->setLastEvent( - 'connect', "ssl://{$reqHost}:{$reqPort} via {$host}:{$port}" - ); - self::$sockets[$socketKey] =& $this->socket; - - } else { - // Set SSL context options if doing HTTPS request or creating a tunnel - $context = stream_context_create(); - foreach ($options as $name => $value) { - if (!stream_context_set_option($context, 'ssl', $name, $value)) { - throw new HTTP_Request2_Exception( - "Error setting SSL context option '{$name}'" - ); - } - } - $this->socket = @stream_socket_client( - $remote, $errno, $errstr, - $this->request->getConfig('connect_timeout'), - STREAM_CLIENT_CONNECT, $context - ); - if (!$this->socket) { - throw new HTTP_Request2_Exception( - "Unable to connect to {$remote}. Error #{$errno}: {$errstr}" - ); - } - $this->request->setLastEvent('connect', $remote); - self::$sockets[$socketKey] =& $this->socket; - } - return $keepAlive; - } - - /** - * Establishes a tunnel to a secure remote server via HTTP CONNECT request - * - * This method will fail if 'ssl_verify_peer' is enabled. Probably because PHP - * sees that we are connected to a proxy server (duh!) rather than the server - * that presents its certificate. - * - * @link http://tools.ietf.org/html/rfc2817#section-5.2 - * @throws HTTP_Request2_Exception - */ - protected function establishTunnel() - { - $donor = new self; - $connect = new HTTP_Request2( - $this->request->getUrl(), HTTP_Request2::METHOD_CONNECT, - array_merge($this->request->getConfig(), - array('adapter' => $donor)) - ); - $response = $connect->send(); - // Need any successful (2XX) response - if (200 > $response->getStatus() || 300 <= $response->getStatus()) { - throw new HTTP_Request2_Exception( - 'Failed to connect via HTTPS proxy. Proxy response: ' . - $response->getStatus() . ' ' . $response->getReasonPhrase() - ); - } - $this->socket = $donor->socket; - - $modes = array( - STREAM_CRYPTO_METHOD_TLS_CLIENT, - STREAM_CRYPTO_METHOD_SSLv3_CLIENT, - STREAM_CRYPTO_METHOD_SSLv23_CLIENT, - STREAM_CRYPTO_METHOD_SSLv2_CLIENT - ); - - foreach ($modes as $mode) { - if (stream_socket_enable_crypto($this->socket, true, $mode)) { - return; - } - } - throw new HTTP_Request2_Exception( - 'Failed to enable secure connection when connecting through proxy' - ); - } - - /** - * Checks whether current connection may be reused or should be closed - * - * @param boolean whether connection could be persistent - * in the first place - * @param HTTP_Request2_Response response object to check - * @return boolean - */ - protected function canKeepAlive($requestKeepAlive, HTTP_Request2_Response $response) - { - // Do not close socket on successful CONNECT request - if (HTTP_Request2::METHOD_CONNECT == $this->request->getMethod() && - 200 <= $response->getStatus() && 300 > $response->getStatus() - ) { - return true; - } - - $lengthKnown = 'chunked' == strtolower($response->getHeader('transfer-encoding')) || - null !== $response->getHeader('content-length'); - $persistent = 'keep-alive' == strtolower($response->getHeader('connection')) || - (null === $response->getHeader('connection') && - '1.1' == $response->getVersion()); - return $requestKeepAlive && $lengthKnown && $persistent; - } - - /** - * Disconnects from the remote server - */ - protected function disconnect() - { - if (is_resource($this->socket)) { - fclose($this->socket); - $this->socket = null; - $this->request->setLastEvent('disconnect'); - } - } - - /** - * Checks whether another request should be performed with server digest auth - * - * Several conditions should be satisfied for it to return true: - * - response status should be 401 - * - auth credentials should be set in the request object - * - response should contain WWW-Authenticate header with digest challenge - * - there is either no challenge stored for this URL or new challenge - * contains stale=true parameter (in other case we probably just failed - * due to invalid username / password) - * - * The method stores challenge values in $challenges static property - * - * @param HTTP_Request2_Response response to check - * @return boolean whether another request should be performed - * @throws HTTP_Request2_Exception in case of unsupported challenge parameters - */ - protected function shouldUseServerDigestAuth(HTTP_Request2_Response $response) - { - // no sense repeating a request if we don't have credentials - if (401 != $response->getStatus() || !$this->request->getAuth()) { - return false; - } - if (!$challenge = $this->parseDigestChallenge($response->getHeader('www-authenticate'))) { - return false; - } - - $url = $this->request->getUrl(); - $scheme = $url->getScheme(); - $host = $scheme . '://' . $url->getHost(); - if ($port = $url->getPort()) { - if ((0 == strcasecmp($scheme, 'http') && 80 != $port) || - (0 == strcasecmp($scheme, 'https') && 443 != $port) - ) { - $host .= ':' . $port; - } - } - - if (!empty($challenge['domain'])) { - $prefixes = array(); - foreach (preg_split('/\\s+/', $challenge['domain']) as $prefix) { - // don't bother with different servers - if ('/' == substr($prefix, 0, 1)) { - $prefixes[] = $host . $prefix; - } - } - } - if (empty($prefixes)) { - $prefixes = array($host . '/'); - } - - $ret = true; - foreach ($prefixes as $prefix) { - if (!empty(self::$challenges[$prefix]) && - (empty($challenge['stale']) || strcasecmp('true', $challenge['stale'])) - ) { - // probably credentials are invalid - $ret = false; - } - self::$challenges[$prefix] =& $challenge; - } - return $ret; - } - - /** - * Checks whether another request should be performed with proxy digest auth - * - * Several conditions should be satisfied for it to return true: - * - response status should be 407 - * - proxy auth credentials should be set in the request object - * - response should contain Proxy-Authenticate header with digest challenge - * - there is either no challenge stored for this proxy or new challenge - * contains stale=true parameter (in other case we probably just failed - * due to invalid username / password) - * - * The method stores challenge values in $challenges static property - * - * @param HTTP_Request2_Response response to check - * @return boolean whether another request should be performed - * @throws HTTP_Request2_Exception in case of unsupported challenge parameters - */ - protected function shouldUseProxyDigestAuth(HTTP_Request2_Response $response) - { - if (407 != $response->getStatus() || !$this->request->getConfig('proxy_user')) { - return false; - } - if (!($challenge = $this->parseDigestChallenge($response->getHeader('proxy-authenticate')))) { - return false; - } - - $key = 'proxy://' . $this->request->getConfig('proxy_host') . - ':' . $this->request->getConfig('proxy_port'); - - if (!empty(self::$challenges[$key]) && - (empty($challenge['stale']) || strcasecmp('true', $challenge['stale'])) - ) { - $ret = false; - } else { - $ret = true; - } - self::$challenges[$key] = $challenge; - return $ret; - } - - /** - * Extracts digest method challenge from (WWW|Proxy)-Authenticate header value - * - * There is a problem with implementation of RFC 2617: several of the parameters - * here are defined as quoted-string and thus may contain backslash escaped - * double quotes (RFC 2616, section 2.2). However, RFC 2617 defines unq(X) as - * just value of quoted-string X without surrounding quotes, it doesn't speak - * about removing backslash escaping. - * - * Now realm parameter is user-defined and human-readable, strange things - * happen when it contains quotes: - * - Apache allows quotes in realm, but apparently uses realm value without - * backslashes for digest computation - * - Squid allows (manually escaped) quotes there, but it is impossible to - * authorize with either escaped or unescaped quotes used in digest, - * probably it can't parse the response (?) - * - Both IE and Firefox display realm value with backslashes in - * the password popup and apparently use the same value for digest - * - * HTTP_Request2 follows IE and Firefox (and hopefully RFC 2617) in - * quoted-string handling, unfortunately that means failure to authorize - * sometimes - * - * @param string value of WWW-Authenticate or Proxy-Authenticate header - * @return mixed associative array with challenge parameters, false if - * no challenge is present in header value - * @throws HTTP_Request2_Exception in case of unsupported challenge parameters - */ - protected function parseDigestChallenge($headerValue) - { - $authParam = '(' . self::REGEXP_TOKEN . ')\\s*=\\s*(' . - self::REGEXP_TOKEN . '|' . self::REGEXP_QUOTED_STRING . ')'; - $challenge = "!(?<=^|\\s|,)Digest ({$authParam}\\s*(,\\s*|$))+!"; - if (!preg_match($challenge, $headerValue, $matches)) { - return false; - } - - preg_match_all('!' . $authParam . '!', $matches[0], $params); - $paramsAry = array(); - $knownParams = array('realm', 'domain', 'nonce', 'opaque', 'stale', - 'algorithm', 'qop'); - for ($i = 0; $i < count($params[0]); $i++) { - // section 3.2.1: Any unrecognized directive MUST be ignored. - if (in_array($params[1][$i], $knownParams)) { - if ('"' == substr($params[2][$i], 0, 1)) { - $paramsAry[$params[1][$i]] = substr($params[2][$i], 1, -1); - } else { - $paramsAry[$params[1][$i]] = $params[2][$i]; - } - } - } - // we only support qop=auth - if (!empty($paramsAry['qop']) && - !in_array('auth', array_map('trim', explode(',', $paramsAry['qop']))) - ) { - throw new HTTP_Request2_Exception( - "Only 'auth' qop is currently supported in digest authentication, " . - "server requested '{$paramsAry['qop']}'" - ); - } - // we only support algorithm=MD5 - if (!empty($paramsAry['algorithm']) && 'MD5' != $paramsAry['algorithm']) { - throw new HTTP_Request2_Exception( - "Only 'MD5' algorithm is currently supported in digest authentication, " . - "server requested '{$paramsAry['algorithm']}'" - ); - } - - return $paramsAry; - } - - /** - * Parses [Proxy-]Authentication-Info header value and updates challenge - * - * @param array challenge to update - * @param string value of [Proxy-]Authentication-Info header - * @todo validate server rspauth response - */ - protected function updateChallenge(&$challenge, $headerValue) - { - $authParam = '!(' . self::REGEXP_TOKEN . ')\\s*=\\s*(' . - self::REGEXP_TOKEN . '|' . self::REGEXP_QUOTED_STRING . ')!'; - $paramsAry = array(); - - preg_match_all($authParam, $headerValue, $params); - for ($i = 0; $i < count($params[0]); $i++) { - if ('"' == substr($params[2][$i], 0, 1)) { - $paramsAry[$params[1][$i]] = substr($params[2][$i], 1, -1); - } else { - $paramsAry[$params[1][$i]] = $params[2][$i]; - } - } - // for now, just update the nonce value - if (!empty($paramsAry['nextnonce'])) { - $challenge['nonce'] = $paramsAry['nextnonce']; - $challenge['nc'] = 1; - } - } - - /** - * Creates a value for [Proxy-]Authorization header when using digest authentication - * - * @param string user name - * @param string password - * @param string request URL - * @param array digest challenge parameters - * @return string value of [Proxy-]Authorization request header - * @link http://tools.ietf.org/html/rfc2617#section-3.2.2 - */ - protected function createDigestResponse($user, $password, $url, &$challenge) - { - if (false !== ($q = strpos($url, '?')) && - $this->request->getConfig('digest_compat_ie') - ) { - $url = substr($url, 0, $q); - } - - $a1 = md5($user . ':' . $challenge['realm'] . ':' . $password); - $a2 = md5($this->request->getMethod() . ':' . $url); - - if (empty($challenge['qop'])) { - $digest = md5($a1 . ':' . $challenge['nonce'] . ':' . $a2); - } else { - $challenge['cnonce'] = 'Req2.' . rand(); - if (empty($challenge['nc'])) { - $challenge['nc'] = 1; - } - $nc = sprintf('%08x', $challenge['nc']++); - $digest = md5($a1 . ':' . $challenge['nonce'] . ':' . $nc . ':' . - $challenge['cnonce'] . ':auth:' . $a2); - } - return 'Digest username="' . str_replace(array('\\', '"'), array('\\\\', '\\"'), $user) . '", ' . - 'realm="' . $challenge['realm'] . '", ' . - 'nonce="' . $challenge['nonce'] . '", ' . - 'uri="' . $url . '", ' . - 'response="' . $digest . '"' . - (!empty($challenge['opaque'])? - ', opaque="' . $challenge['opaque'] . '"': - '') . - (!empty($challenge['qop'])? - ', qop="auth", nc=' . $nc . ', cnonce="' . $challenge['cnonce'] . '"': - ''); - } - - /** - * Adds 'Authorization' header (if needed) to request headers array - * - * @param array request headers - * @param string request host (needed for digest authentication) - * @param string request URL (needed for digest authentication) - * @throws HTTP_Request2_Exception - */ - protected function addAuthorizationHeader(&$headers, $requestHost, $requestUrl) - { - if (!($auth = $this->request->getAuth())) { - return; - } - switch ($auth['scheme']) { - case HTTP_Request2::AUTH_BASIC: - $headers['authorization'] = - 'Basic ' . base64_encode($auth['user'] . ':' . $auth['password']); - break; - - case HTTP_Request2::AUTH_DIGEST: - unset($this->serverChallenge); - $fullUrl = ('/' == $requestUrl[0])? - $this->request->getUrl()->getScheme() . '://' . - $requestHost . $requestUrl: - $requestUrl; - foreach (array_keys(self::$challenges) as $key) { - if ($key == substr($fullUrl, 0, strlen($key))) { - $headers['authorization'] = $this->createDigestResponse( - $auth['user'], $auth['password'], - $requestUrl, self::$challenges[$key] - ); - $this->serverChallenge =& self::$challenges[$key]; - break; - } - } - break; - - default: - throw new HTTP_Request2_Exception( - "Unknown HTTP authentication scheme '{$auth['scheme']}'" - ); - } - } - - /** - * Adds 'Proxy-Authorization' header (if needed) to request headers array - * - * @param array request headers - * @param string request URL (needed for digest authentication) - * @throws HTTP_Request2_Exception - */ - protected function addProxyAuthorizationHeader(&$headers, $requestUrl) - { - if (!$this->request->getConfig('proxy_host') || - !($user = $this->request->getConfig('proxy_user')) || - (0 == strcasecmp('https', $this->request->getUrl()->getScheme()) && - HTTP_Request2::METHOD_CONNECT != $this->request->getMethod()) - ) { - return; - } - - $password = $this->request->getConfig('proxy_password'); - switch ($this->request->getConfig('proxy_auth_scheme')) { - case HTTP_Request2::AUTH_BASIC: - $headers['proxy-authorization'] = - 'Basic ' . base64_encode($user . ':' . $password); - break; - - case HTTP_Request2::AUTH_DIGEST: - unset($this->proxyChallenge); - $proxyUrl = 'proxy://' . $this->request->getConfig('proxy_host') . - ':' . $this->request->getConfig('proxy_port'); - if (!empty(self::$challenges[$proxyUrl])) { - $headers['proxy-authorization'] = $this->createDigestResponse( - $user, $password, - $requestUrl, self::$challenges[$proxyUrl] - ); - $this->proxyChallenge =& self::$challenges[$proxyUrl]; - } - break; - - default: - throw new HTTP_Request2_Exception( - "Unknown HTTP authentication scheme '" . - $this->request->getConfig('proxy_auth_scheme') . "'" - ); - } - } - - - /** - * Creates the string with the Request-Line and request headers - * - * @return string - * @throws HTTP_Request2_Exception - */ - protected function prepareHeaders() - { - $headers = $this->request->getHeaders(); - $url = $this->request->getUrl(); - $connect = HTTP_Request2::METHOD_CONNECT == $this->request->getMethod(); - $host = $url->getHost(); - - $defaultPort = 0 == strcasecmp($url->getScheme(), 'https')? 443: 80; - if (($port = $url->getPort()) && $port != $defaultPort || $connect) { - $host .= ':' . (empty($port)? $defaultPort: $port); - } - // Do not overwrite explicitly set 'Host' header, see bug #16146 - if (!isset($headers['host'])) { - $headers['host'] = $host; - } - - if ($connect) { - $requestUrl = $host; - - } else { - if (!$this->request->getConfig('proxy_host') || - 0 == strcasecmp($url->getScheme(), 'https') - ) { - $requestUrl = ''; - } else { - $requestUrl = $url->getScheme() . '://' . $host; - } - $path = $url->getPath(); - $query = $url->getQuery(); - $requestUrl .= (empty($path)? '/': $path) . (empty($query)? '': '?' . $query); - } - - if ('1.1' == $this->request->getConfig('protocol_version') && - extension_loaded('zlib') && !isset($headers['accept-encoding']) - ) { - $headers['accept-encoding'] = 'gzip, deflate'; - } - - $this->addAuthorizationHeader($headers, $host, $requestUrl); - $this->addProxyAuthorizationHeader($headers, $requestUrl); - $this->calculateRequestLength($headers); - - $headersStr = $this->request->getMethod() . ' ' . $requestUrl . ' HTTP/' . - $this->request->getConfig('protocol_version') . "\r\n"; - foreach ($headers as $name => $value) { - $canonicalName = implode('-', array_map('ucfirst', explode('-', $name))); - $headersStr .= $canonicalName . ': ' . $value . "\r\n"; - } - return $headersStr . "\r\n"; - } - - /** - * Sends the request body - * - * @throws HTTP_Request2_Exception - */ - protected function writeBody() - { - if (in_array($this->request->getMethod(), self::$bodyDisallowed) || - 0 == $this->contentLength - ) { - return; - } - - $position = 0; - $bufferSize = $this->request->getConfig('buffer_size'); - while ($position < $this->contentLength) { - if (is_string($this->requestBody)) { - $str = substr($this->requestBody, $position, $bufferSize); - } elseif (is_resource($this->requestBody)) { - $str = fread($this->requestBody, $bufferSize); - } else { - $str = $this->requestBody->read($bufferSize); - } - if (false === @fwrite($this->socket, $str, strlen($str))) { - throw new HTTP_Request2_Exception('Error writing request'); - } - // Provide the length of written string to the observer, request #7630 - $this->request->setLastEvent('sentBodyPart', strlen($str)); - $position += strlen($str); - } - } - - /** - * Reads the remote server's response - * - * @return HTTP_Request2_Response - * @throws HTTP_Request2_Exception - */ - protected function readResponse() - { - $bufferSize = $this->request->getConfig('buffer_size'); - - do { - $response = new HTTP_Request2_Response($this->readLine($bufferSize), true); - do { - $headerLine = $this->readLine($bufferSize); - $response->parseHeaderLine($headerLine); - } while ('' != $headerLine); - } while (in_array($response->getStatus(), array(100, 101))); - - $this->request->setLastEvent('receivedHeaders', $response); - - // No body possible in such responses - if (HTTP_Request2::METHOD_HEAD == $this->request->getMethod() || - (HTTP_Request2::METHOD_CONNECT == $this->request->getMethod() && - 200 <= $response->getStatus() && 300 > $response->getStatus()) || - in_array($response->getStatus(), array(204, 304)) - ) { - return $response; - } - - $chunked = 'chunked' == $response->getHeader('transfer-encoding'); - $length = $response->getHeader('content-length'); - $hasBody = false; - if ($chunked || null === $length || 0 < intval($length)) { - // RFC 2616, section 4.4: - // 3. ... If a message is received with both a - // Transfer-Encoding header field and a Content-Length header field, - // the latter MUST be ignored. - $toRead = ($chunked || null === $length)? null: $length; - $this->chunkLength = 0; - - while (!feof($this->socket) && (is_null($toRead) || 0 < $toRead)) { - if ($chunked) { - $data = $this->readChunked($bufferSize); - } elseif (is_null($toRead)) { - $data = $this->fread($bufferSize); - } else { - $data = $this->fread(min($toRead, $bufferSize)); - $toRead -= strlen($data); - } - if ('' == $data && (!$this->chunkLength || feof($this->socket))) { - break; - } - - $hasBody = true; - if ($this->request->getConfig('store_body')) { - $response->appendBody($data); - } - if (!in_array($response->getHeader('content-encoding'), array('identity', null))) { - $this->request->setLastEvent('receivedEncodedBodyPart', $data); - } else { - $this->request->setLastEvent('receivedBodyPart', $data); - } - } - } - - if ($hasBody) { - $this->request->setLastEvent('receivedBody', $response); - } - return $response; - } - - /** - * Reads until either the end of the socket or a newline, whichever comes first - * - * Strips the trailing newline from the returned data, handles global - * request timeout. Method idea borrowed from Net_Socket PEAR package. - * - * @param int buffer size to use for reading - * @return Available data up to the newline (not including newline) - * @throws HTTP_Request2_Exception In case of timeout - */ - protected function readLine($bufferSize) - { - $line = ''; - while (!feof($this->socket)) { - if ($this->timeout) { - stream_set_timeout($this->socket, max($this->timeout - time(), 1)); - } - $line .= @fgets($this->socket, $bufferSize); - $info = stream_get_meta_data($this->socket); - if ($info['timed_out'] || $this->timeout && time() > $this->timeout) { - throw new HTTP_Request2_Exception( - 'Request timed out after ' . - $this->request->getConfig('timeout') . ' second(s)' - ); - } - if (substr($line, -1) == "\n") { - return rtrim($line, "\r\n"); - } - } - return $line; - } - - /** - * Wrapper around fread(), handles global request timeout - * - * @param int Reads up to this number of bytes - * @return Data read from socket - * @throws HTTP_Request2_Exception In case of timeout - */ - protected function fread($length) - { - if ($this->timeout) { - stream_set_timeout($this->socket, max($this->timeout - time(), 1)); - } - $data = fread($this->socket, $length); - $info = stream_get_meta_data($this->socket); - if ($info['timed_out'] || $this->timeout && time() > $this->timeout) { - throw new HTTP_Request2_Exception( - 'Request timed out after ' . - $this->request->getConfig('timeout') . ' second(s)' - ); - } - return $data; - } - - /** - * Reads a part of response body encoded with chunked Transfer-Encoding - * - * @param int buffer size to use for reading - * @return string - * @throws HTTP_Request2_Exception - */ - protected function readChunked($bufferSize) - { - // at start of the next chunk? - if (0 == $this->chunkLength) { - $line = $this->readLine($bufferSize); - if (!preg_match('/^([0-9a-f]+)/i', $line, $matches)) { - throw new HTTP_Request2_Exception( - "Cannot decode chunked response, invalid chunk length '{$line}'" - ); - } else { - $this->chunkLength = hexdec($matches[1]); - // Chunk with zero length indicates the end - if (0 == $this->chunkLength) { - $this->readLine($bufferSize); - return ''; - } - } - } - $data = $this->fread(min($this->chunkLength, $bufferSize)); - $this->chunkLength -= strlen($data); - if (0 == $this->chunkLength) { - $this->readLine($bufferSize); // Trailing CRLF - } - return $data; - } -} - + + * 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. + * * The names of the authors may not 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 HTTP + * @package HTTP_Request2 + * @author Alexey Borzov + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Socket.php 279760 2009-05-03 10:46:42Z avb $ + * @link http://pear.php.net/package/HTTP_Request2 + */ + +/** + * Base class for HTTP_Request2 adapters + */ +require_once 'HTTP/Request2/Adapter.php'; + +/** + * Socket-based adapter for HTTP_Request2 + * + * This adapter uses only PHP sockets and will work on almost any PHP + * environment. Code is based on original HTTP_Request PEAR package. + * + * @category HTTP + * @package HTTP_Request2 + * @author Alexey Borzov + * @version Release: 0.4.1 + */ +class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter +{ + /** + * Regular expression for 'token' rule from RFC 2616 + */ + const REGEXP_TOKEN = '[^\x00-\x1f\x7f-\xff()<>@,;:\\\\"/\[\]?={}\s]+'; + + /** + * Regular expression for 'quoted-string' rule from RFC 2616 + */ + const REGEXP_QUOTED_STRING = '"(?:\\\\.|[^\\\\"])*"'; + + /** + * Connected sockets, needed for Keep-Alive support + * @var array + * @see connect() + */ + protected static $sockets = array(); + + /** + * Data for digest authentication scheme + * + * The keys for the array are URL prefixes. + * + * The values are associative arrays with data (realm, nonce, nonce-count, + * opaque...) needed for digest authentication. Stored here to prevent making + * duplicate requests to digest-protected resources after we have already + * received the challenge. + * + * @var array + */ + protected static $challenges = array(); + + /** + * Connected socket + * @var resource + * @see connect() + */ + protected $socket; + + /** + * Challenge used for server digest authentication + * @var array + */ + protected $serverChallenge; + + /** + * Challenge used for proxy digest authentication + * @var array + */ + protected $proxyChallenge; + + /** + * Global timeout, exception will be raised if request continues past this time + * @var integer + */ + protected $timeout = null; + + /** + * Remaining length of the current chunk, when reading chunked response + * @var integer + * @see readChunked() + */ + protected $chunkLength = 0; + + /** + * Sends request to the remote server and returns its response + * + * @param HTTP_Request2 + * @return HTTP_Request2_Response + * @throws HTTP_Request2_Exception + */ + public function sendRequest(HTTP_Request2 $request) + { + $this->request = $request; + $keepAlive = $this->connect(); + $headers = $this->prepareHeaders(); + + // Use global request timeout if given, see feature requests #5735, #8964 + if ($timeout = $request->getConfig('timeout')) { + $this->timeout = time() + $timeout; + } else { + $this->timeout = null; + } + + try { + if (false === @fwrite($this->socket, $headers, strlen($headers))) { + throw new HTTP_Request2_Exception('Error writing request'); + } + // provide request headers to the observer, see request #7633 + $this->request->setLastEvent('sentHeaders', $headers); + $this->writeBody(); + + if ($this->timeout && time() > $this->timeout) { + throw new HTTP_Request2_Exception( + 'Request timed out after ' . + $request->getConfig('timeout') . ' second(s)' + ); + } + + $response = $this->readResponse(); + + if (!$this->canKeepAlive($keepAlive, $response)) { + $this->disconnect(); + } + + if ($this->shouldUseProxyDigestAuth($response)) { + return $this->sendRequest($request); + } + if ($this->shouldUseServerDigestAuth($response)) { + return $this->sendRequest($request); + } + if ($authInfo = $response->getHeader('authentication-info')) { + $this->updateChallenge($this->serverChallenge, $authInfo); + } + if ($proxyInfo = $response->getHeader('proxy-authentication-info')) { + $this->updateChallenge($this->proxyChallenge, $proxyInfo); + } + + } catch (Exception $e) { + $this->disconnect(); + throw $e; + } + + return $response; + } + + /** + * Connects to the remote server + * + * @return bool whether the connection can be persistent + * @throws HTTP_Request2_Exception + */ + protected function connect() + { + $secure = 0 == strcasecmp($this->request->getUrl()->getScheme(), 'https'); + $tunnel = HTTP_Request2::METHOD_CONNECT == $this->request->getMethod(); + $headers = $this->request->getHeaders(); + $reqHost = $this->request->getUrl()->getHost(); + if (!($reqPort = $this->request->getUrl()->getPort())) { + $reqPort = $secure? 443: 80; + } + + if ($host = $this->request->getConfig('proxy_host')) { + if (!($port = $this->request->getConfig('proxy_port'))) { + throw new HTTP_Request2_Exception('Proxy port not provided'); + } + $proxy = true; + } else { + $host = $reqHost; + $port = $reqPort; + $proxy = false; + } + + if ($tunnel && !$proxy) { + throw new HTTP_Request2_Exception( + "Trying to perform CONNECT request without proxy" + ); + } + if ($secure && !in_array('ssl', stream_get_transports())) { + throw new HTTP_Request2_Exception( + 'Need OpenSSL support for https:// requests' + ); + } + + // RFC 2068, section 19.7.1: A client MUST NOT send the Keep-Alive + // connection token to a proxy server... + if ($proxy && !$secure && + !empty($headers['connection']) && 'Keep-Alive' == $headers['connection'] + ) { + $this->request->setHeader('connection'); + } + + $keepAlive = ('1.1' == $this->request->getConfig('protocol_version') && + empty($headers['connection'])) || + (!empty($headers['connection']) && + 'Keep-Alive' == $headers['connection']); + $host = ((!$secure || $proxy)? 'tcp://': 'ssl://') . $host; + + $options = array(); + if ($secure || $tunnel) { + foreach ($this->request->getConfig() as $name => $value) { + if ('ssl_' == substr($name, 0, 4) && null !== $value) { + if ('ssl_verify_host' == $name) { + if ($value) { + $options['CN_match'] = $reqHost; + } + } else { + $options[substr($name, 4)] = $value; + } + } + } + ksort($options); + } + + // Changing SSL context options after connection is established does *not* + // work, we need a new connection if options change + $remote = $host . ':' . $port; + $socketKey = $remote . (($secure && $proxy)? "->{$reqHost}:{$reqPort}": '') . + (empty($options)? '': ':' . serialize($options)); + unset($this->socket); + + // We use persistent connections and have a connected socket? + // Ensure that the socket is still connected, see bug #16149 + if ($keepAlive && !empty(self::$sockets[$socketKey]) && + !feof(self::$sockets[$socketKey]) + ) { + $this->socket =& self::$sockets[$socketKey]; + + } elseif ($secure && $proxy && !$tunnel) { + $this->establishTunnel(); + $this->request->setLastEvent( + 'connect', "ssl://{$reqHost}:{$reqPort} via {$host}:{$port}" + ); + self::$sockets[$socketKey] =& $this->socket; + + } else { + // Set SSL context options if doing HTTPS request or creating a tunnel + $context = stream_context_create(); + foreach ($options as $name => $value) { + if (!stream_context_set_option($context, 'ssl', $name, $value)) { + throw new HTTP_Request2_Exception( + "Error setting SSL context option '{$name}'" + ); + } + } + $this->socket = @stream_socket_client( + $remote, $errno, $errstr, + $this->request->getConfig('connect_timeout'), + STREAM_CLIENT_CONNECT, $context + ); + if (!$this->socket) { + throw new HTTP_Request2_Exception( + "Unable to connect to {$remote}. Error #{$errno}: {$errstr}" + ); + } + $this->request->setLastEvent('connect', $remote); + self::$sockets[$socketKey] =& $this->socket; + } + return $keepAlive; + } + + /** + * Establishes a tunnel to a secure remote server via HTTP CONNECT request + * + * This method will fail if 'ssl_verify_peer' is enabled. Probably because PHP + * sees that we are connected to a proxy server (duh!) rather than the server + * that presents its certificate. + * + * @link http://tools.ietf.org/html/rfc2817#section-5.2 + * @throws HTTP_Request2_Exception + */ + protected function establishTunnel() + { + $donor = new self; + $connect = new HTTP_Request2( + $this->request->getUrl(), HTTP_Request2::METHOD_CONNECT, + array_merge($this->request->getConfig(), + array('adapter' => $donor)) + ); + $response = $connect->send(); + // Need any successful (2XX) response + if (200 > $response->getStatus() || 300 <= $response->getStatus()) { + throw new HTTP_Request2_Exception( + 'Failed to connect via HTTPS proxy. Proxy response: ' . + $response->getStatus() . ' ' . $response->getReasonPhrase() + ); + } + $this->socket = $donor->socket; + + $modes = array( + STREAM_CRYPTO_METHOD_TLS_CLIENT, + STREAM_CRYPTO_METHOD_SSLv3_CLIENT, + STREAM_CRYPTO_METHOD_SSLv23_CLIENT, + STREAM_CRYPTO_METHOD_SSLv2_CLIENT + ); + + foreach ($modes as $mode) { + if (stream_socket_enable_crypto($this->socket, true, $mode)) { + return; + } + } + throw new HTTP_Request2_Exception( + 'Failed to enable secure connection when connecting through proxy' + ); + } + + /** + * Checks whether current connection may be reused or should be closed + * + * @param boolean whether connection could be persistent + * in the first place + * @param HTTP_Request2_Response response object to check + * @return boolean + */ + protected function canKeepAlive($requestKeepAlive, HTTP_Request2_Response $response) + { + // Do not close socket on successful CONNECT request + if (HTTP_Request2::METHOD_CONNECT == $this->request->getMethod() && + 200 <= $response->getStatus() && 300 > $response->getStatus() + ) { + return true; + } + + $lengthKnown = 'chunked' == strtolower($response->getHeader('transfer-encoding')) || + null !== $response->getHeader('content-length'); + $persistent = 'keep-alive' == strtolower($response->getHeader('connection')) || + (null === $response->getHeader('connection') && + '1.1' == $response->getVersion()); + return $requestKeepAlive && $lengthKnown && $persistent; + } + + /** + * Disconnects from the remote server + */ + protected function disconnect() + { + if (is_resource($this->socket)) { + fclose($this->socket); + $this->socket = null; + $this->request->setLastEvent('disconnect'); + } + } + + /** + * Checks whether another request should be performed with server digest auth + * + * Several conditions should be satisfied for it to return true: + * - response status should be 401 + * - auth credentials should be set in the request object + * - response should contain WWW-Authenticate header with digest challenge + * - there is either no challenge stored for this URL or new challenge + * contains stale=true parameter (in other case we probably just failed + * due to invalid username / password) + * + * The method stores challenge values in $challenges static property + * + * @param HTTP_Request2_Response response to check + * @return boolean whether another request should be performed + * @throws HTTP_Request2_Exception in case of unsupported challenge parameters + */ + protected function shouldUseServerDigestAuth(HTTP_Request2_Response $response) + { + // no sense repeating a request if we don't have credentials + if (401 != $response->getStatus() || !$this->request->getAuth()) { + return false; + } + if (!$challenge = $this->parseDigestChallenge($response->getHeader('www-authenticate'))) { + return false; + } + + $url = $this->request->getUrl(); + $scheme = $url->getScheme(); + $host = $scheme . '://' . $url->getHost(); + if ($port = $url->getPort()) { + if ((0 == strcasecmp($scheme, 'http') && 80 != $port) || + (0 == strcasecmp($scheme, 'https') && 443 != $port) + ) { + $host .= ':' . $port; + } + } + + if (!empty($challenge['domain'])) { + $prefixes = array(); + foreach (preg_split('/\\s+/', $challenge['domain']) as $prefix) { + // don't bother with different servers + if ('/' == substr($prefix, 0, 1)) { + $prefixes[] = $host . $prefix; + } + } + } + if (empty($prefixes)) { + $prefixes = array($host . '/'); + } + + $ret = true; + foreach ($prefixes as $prefix) { + if (!empty(self::$challenges[$prefix]) && + (empty($challenge['stale']) || strcasecmp('true', $challenge['stale'])) + ) { + // probably credentials are invalid + $ret = false; + } + self::$challenges[$prefix] =& $challenge; + } + return $ret; + } + + /** + * Checks whether another request should be performed with proxy digest auth + * + * Several conditions should be satisfied for it to return true: + * - response status should be 407 + * - proxy auth credentials should be set in the request object + * - response should contain Proxy-Authenticate header with digest challenge + * - there is either no challenge stored for this proxy or new challenge + * contains stale=true parameter (in other case we probably just failed + * due to invalid username / password) + * + * The method stores challenge values in $challenges static property + * + * @param HTTP_Request2_Response response to check + * @return boolean whether another request should be performed + * @throws HTTP_Request2_Exception in case of unsupported challenge parameters + */ + protected function shouldUseProxyDigestAuth(HTTP_Request2_Response $response) + { + if (407 != $response->getStatus() || !$this->request->getConfig('proxy_user')) { + return false; + } + if (!($challenge = $this->parseDigestChallenge($response->getHeader('proxy-authenticate')))) { + return false; + } + + $key = 'proxy://' . $this->request->getConfig('proxy_host') . + ':' . $this->request->getConfig('proxy_port'); + + if (!empty(self::$challenges[$key]) && + (empty($challenge['stale']) || strcasecmp('true', $challenge['stale'])) + ) { + $ret = false; + } else { + $ret = true; + } + self::$challenges[$key] = $challenge; + return $ret; + } + + /** + * Extracts digest method challenge from (WWW|Proxy)-Authenticate header value + * + * There is a problem with implementation of RFC 2617: several of the parameters + * here are defined as quoted-string and thus may contain backslash escaped + * double quotes (RFC 2616, section 2.2). However, RFC 2617 defines unq(X) as + * just value of quoted-string X without surrounding quotes, it doesn't speak + * about removing backslash escaping. + * + * Now realm parameter is user-defined and human-readable, strange things + * happen when it contains quotes: + * - Apache allows quotes in realm, but apparently uses realm value without + * backslashes for digest computation + * - Squid allows (manually escaped) quotes there, but it is impossible to + * authorize with either escaped or unescaped quotes used in digest, + * probably it cannot parse the response (?) + * - Both IE and Firefox display realm value with backslashes in + * the password popup and apparently use the same value for digest + * + * HTTP_Request2 follows IE and Firefox (and hopefully RFC 2617) in + * quoted-string handling, unfortunately that means failure to authorize + * sometimes + * + * @param string value of WWW-Authenticate or Proxy-Authenticate header + * @return mixed associative array with challenge parameters, false if + * no challenge is present in header value + * @throws HTTP_Request2_Exception in case of unsupported challenge parameters + */ + protected function parseDigestChallenge($headerValue) + { + $authParam = '(' . self::REGEXP_TOKEN . ')\\s*=\\s*(' . + self::REGEXP_TOKEN . '|' . self::REGEXP_QUOTED_STRING . ')'; + $challenge = "!(?<=^|\\s|,)Digest ({$authParam}\\s*(,\\s*|$))+!"; + if (!preg_match($challenge, $headerValue, $matches)) { + return false; + } + + preg_match_all('!' . $authParam . '!', $matches[0], $params); + $paramsAry = array(); + $knownParams = array('realm', 'domain', 'nonce', 'opaque', 'stale', + 'algorithm', 'qop'); + for ($i = 0; $i < count($params[0]); $i++) { + // section 3.2.1: Any unrecognized directive MUST be ignored. + if (in_array($params[1][$i], $knownParams)) { + if ('"' == substr($params[2][$i], 0, 1)) { + $paramsAry[$params[1][$i]] = substr($params[2][$i], 1, -1); + } else { + $paramsAry[$params[1][$i]] = $params[2][$i]; + } + } + } + // we only support qop=auth + if (!empty($paramsAry['qop']) && + !in_array('auth', array_map('trim', explode(',', $paramsAry['qop']))) + ) { + throw new HTTP_Request2_Exception( + "Only 'auth' qop is currently supported in digest authentication, " . + "server requested '{$paramsAry['qop']}'" + ); + } + // we only support algorithm=MD5 + if (!empty($paramsAry['algorithm']) && 'MD5' != $paramsAry['algorithm']) { + throw new HTTP_Request2_Exception( + "Only 'MD5' algorithm is currently supported in digest authentication, " . + "server requested '{$paramsAry['algorithm']}'" + ); + } + + return $paramsAry; + } + + /** + * Parses [Proxy-]Authentication-Info header value and updates challenge + * + * @param array challenge to update + * @param string value of [Proxy-]Authentication-Info header + * @todo validate server rspauth response + */ + protected function updateChallenge(&$challenge, $headerValue) + { + $authParam = '!(' . self::REGEXP_TOKEN . ')\\s*=\\s*(' . + self::REGEXP_TOKEN . '|' . self::REGEXP_QUOTED_STRING . ')!'; + $paramsAry = array(); + + preg_match_all($authParam, $headerValue, $params); + for ($i = 0; $i < count($params[0]); $i++) { + if ('"' == substr($params[2][$i], 0, 1)) { + $paramsAry[$params[1][$i]] = substr($params[2][$i], 1, -1); + } else { + $paramsAry[$params[1][$i]] = $params[2][$i]; + } + } + // for now, just update the nonce value + if (!empty($paramsAry['nextnonce'])) { + $challenge['nonce'] = $paramsAry['nextnonce']; + $challenge['nc'] = 1; + } + } + + /** + * Creates a value for [Proxy-]Authorization header when using digest authentication + * + * @param string user name + * @param string password + * @param string request URL + * @param array digest challenge parameters + * @return string value of [Proxy-]Authorization request header + * @link http://tools.ietf.org/html/rfc2617#section-3.2.2 + */ + protected function createDigestResponse($user, $password, $url, &$challenge) + { + if (false !== ($q = strpos($url, '?')) && + $this->request->getConfig('digest_compat_ie') + ) { + $url = substr($url, 0, $q); + } + + $a1 = md5($user . ':' . $challenge['realm'] . ':' . $password); + $a2 = md5($this->request->getMethod() . ':' . $url); + + if (empty($challenge['qop'])) { + $digest = md5($a1 . ':' . $challenge['nonce'] . ':' . $a2); + } else { + $challenge['cnonce'] = 'Req2.' . rand(); + if (empty($challenge['nc'])) { + $challenge['nc'] = 1; + } + $nc = sprintf('%08x', $challenge['nc']++); + $digest = md5($a1 . ':' . $challenge['nonce'] . ':' . $nc . ':' . + $challenge['cnonce'] . ':auth:' . $a2); + } + return 'Digest username="' . str_replace(array('\\', '"'), array('\\\\', '\\"'), $user) . '", ' . + 'realm="' . $challenge['realm'] . '", ' . + 'nonce="' . $challenge['nonce'] . '", ' . + 'uri="' . $url . '", ' . + 'response="' . $digest . '"' . + (!empty($challenge['opaque'])? + ', opaque="' . $challenge['opaque'] . '"': + '') . + (!empty($challenge['qop'])? + ', qop="auth", nc=' . $nc . ', cnonce="' . $challenge['cnonce'] . '"': + ''); + } + + /** + * Adds 'Authorization' header (if needed) to request headers array + * + * @param array request headers + * @param string request host (needed for digest authentication) + * @param string request URL (needed for digest authentication) + * @throws HTTP_Request2_Exception + */ + protected function addAuthorizationHeader(&$headers, $requestHost, $requestUrl) + { + if (!($auth = $this->request->getAuth())) { + return; + } + switch ($auth['scheme']) { + case HTTP_Request2::AUTH_BASIC: + $headers['authorization'] = + 'Basic ' . base64_encode($auth['user'] . ':' . $auth['password']); + break; + + case HTTP_Request2::AUTH_DIGEST: + unset($this->serverChallenge); + $fullUrl = ('/' == $requestUrl[0])? + $this->request->getUrl()->getScheme() . '://' . + $requestHost . $requestUrl: + $requestUrl; + foreach (array_keys(self::$challenges) as $key) { + if ($key == substr($fullUrl, 0, strlen($key))) { + $headers['authorization'] = $this->createDigestResponse( + $auth['user'], $auth['password'], + $requestUrl, self::$challenges[$key] + ); + $this->serverChallenge =& self::$challenges[$key]; + break; + } + } + break; + + default: + throw new HTTP_Request2_Exception( + "Unknown HTTP authentication scheme '{$auth['scheme']}'" + ); + } + } + + /** + * Adds 'Proxy-Authorization' header (if needed) to request headers array + * + * @param array request headers + * @param string request URL (needed for digest authentication) + * @throws HTTP_Request2_Exception + */ + protected function addProxyAuthorizationHeader(&$headers, $requestUrl) + { + if (!$this->request->getConfig('proxy_host') || + !($user = $this->request->getConfig('proxy_user')) || + (0 == strcasecmp('https', $this->request->getUrl()->getScheme()) && + HTTP_Request2::METHOD_CONNECT != $this->request->getMethod()) + ) { + return; + } + + $password = $this->request->getConfig('proxy_password'); + switch ($this->request->getConfig('proxy_auth_scheme')) { + case HTTP_Request2::AUTH_BASIC: + $headers['proxy-authorization'] = + 'Basic ' . base64_encode($user . ':' . $password); + break; + + case HTTP_Request2::AUTH_DIGEST: + unset($this->proxyChallenge); + $proxyUrl = 'proxy://' . $this->request->getConfig('proxy_host') . + ':' . $this->request->getConfig('proxy_port'); + if (!empty(self::$challenges[$proxyUrl])) { + $headers['proxy-authorization'] = $this->createDigestResponse( + $user, $password, + $requestUrl, self::$challenges[$proxyUrl] + ); + $this->proxyChallenge =& self::$challenges[$proxyUrl]; + } + break; + + default: + throw new HTTP_Request2_Exception( + "Unknown HTTP authentication scheme '" . + $this->request->getConfig('proxy_auth_scheme') . "'" + ); + } + } + + + /** + * Creates the string with the Request-Line and request headers + * + * @return string + * @throws HTTP_Request2_Exception + */ + protected function prepareHeaders() + { + $headers = $this->request->getHeaders(); + $url = $this->request->getUrl(); + $connect = HTTP_Request2::METHOD_CONNECT == $this->request->getMethod(); + $host = $url->getHost(); + + $defaultPort = 0 == strcasecmp($url->getScheme(), 'https')? 443: 80; + if (($port = $url->getPort()) && $port != $defaultPort || $connect) { + $host .= ':' . (empty($port)? $defaultPort: $port); + } + // Do not overwrite explicitly set 'Host' header, see bug #16146 + if (!isset($headers['host'])) { + $headers['host'] = $host; + } + + if ($connect) { + $requestUrl = $host; + + } else { + if (!$this->request->getConfig('proxy_host') || + 0 == strcasecmp($url->getScheme(), 'https') + ) { + $requestUrl = ''; + } else { + $requestUrl = $url->getScheme() . '://' . $host; + } + $path = $url->getPath(); + $query = $url->getQuery(); + $requestUrl .= (empty($path)? '/': $path) . (empty($query)? '': '?' . $query); + } + + if ('1.1' == $this->request->getConfig('protocol_version') && + extension_loaded('zlib') && !isset($headers['accept-encoding']) + ) { + $headers['accept-encoding'] = 'gzip, deflate'; + } + + $this->addAuthorizationHeader($headers, $host, $requestUrl); + $this->addProxyAuthorizationHeader($headers, $requestUrl); + $this->calculateRequestLength($headers); + + $headersStr = $this->request->getMethod() . ' ' . $requestUrl . ' HTTP/' . + $this->request->getConfig('protocol_version') . "\r\n"; + foreach ($headers as $name => $value) { + $canonicalName = implode('-', array_map('ucfirst', explode('-', $name))); + $headersStr .= $canonicalName . ': ' . $value . "\r\n"; + } + return $headersStr . "\r\n"; + } + + /** + * Sends the request body + * + * @throws HTTP_Request2_Exception + */ + protected function writeBody() + { + if (in_array($this->request->getMethod(), self::$bodyDisallowed) || + 0 == $this->contentLength + ) { + return; + } + + $position = 0; + $bufferSize = $this->request->getConfig('buffer_size'); + while ($position < $this->contentLength) { + if (is_string($this->requestBody)) { + $str = substr($this->requestBody, $position, $bufferSize); + } elseif (is_resource($this->requestBody)) { + $str = fread($this->requestBody, $bufferSize); + } else { + $str = $this->requestBody->read($bufferSize); + } + if (false === @fwrite($this->socket, $str, strlen($str))) { + throw new HTTP_Request2_Exception('Error writing request'); + } + // Provide the length of written string to the observer, request #7630 + $this->request->setLastEvent('sentBodyPart', strlen($str)); + $position += strlen($str); + } + } + + /** + * Reads the remote server's response + * + * @return HTTP_Request2_Response + * @throws HTTP_Request2_Exception + */ + protected function readResponse() + { + $bufferSize = $this->request->getConfig('buffer_size'); + + do { + $response = new HTTP_Request2_Response($this->readLine($bufferSize), true); + do { + $headerLine = $this->readLine($bufferSize); + $response->parseHeaderLine($headerLine); + } while ('' != $headerLine); + } while (in_array($response->getStatus(), array(100, 101))); + + $this->request->setLastEvent('receivedHeaders', $response); + + // No body possible in such responses + if (HTTP_Request2::METHOD_HEAD == $this->request->getMethod() || + (HTTP_Request2::METHOD_CONNECT == $this->request->getMethod() && + 200 <= $response->getStatus() && 300 > $response->getStatus()) || + in_array($response->getStatus(), array(204, 304)) + ) { + return $response; + } + + $chunked = 'chunked' == $response->getHeader('transfer-encoding'); + $length = $response->getHeader('content-length'); + $hasBody = false; + if ($chunked || null === $length || 0 < intval($length)) { + // RFC 2616, section 4.4: + // 3. ... If a message is received with both a + // Transfer-Encoding header field and a Content-Length header field, + // the latter MUST be ignored. + $toRead = ($chunked || null === $length)? null: $length; + $this->chunkLength = 0; + + while (!feof($this->socket) && (is_null($toRead) || 0 < $toRead)) { + if ($chunked) { + $data = $this->readChunked($bufferSize); + } elseif (is_null($toRead)) { + $data = $this->fread($bufferSize); + } else { + $data = $this->fread(min($toRead, $bufferSize)); + $toRead -= strlen($data); + } + if ('' == $data && (!$this->chunkLength || feof($this->socket))) { + break; + } + + $hasBody = true; + if ($this->request->getConfig('store_body')) { + $response->appendBody($data); + } + if (!in_array($response->getHeader('content-encoding'), array('identity', null))) { + $this->request->setLastEvent('receivedEncodedBodyPart', $data); + } else { + $this->request->setLastEvent('receivedBodyPart', $data); + } + } + } + + if ($hasBody) { + $this->request->setLastEvent('receivedBody', $response); + } + return $response; + } + + /** + * Reads until either the end of the socket or a newline, whichever comes first + * + * Strips the trailing newline from the returned data, handles global + * request timeout. Method idea borrowed from Net_Socket PEAR package. + * + * @param int buffer size to use for reading + * @return Available data up to the newline (not including newline) + * @throws HTTP_Request2_Exception In case of timeout + */ + protected function readLine($bufferSize) + { + $line = ''; + while (!feof($this->socket)) { + if ($this->timeout) { + stream_set_timeout($this->socket, max($this->timeout - time(), 1)); + } + $line .= @fgets($this->socket, $bufferSize); + $info = stream_get_meta_data($this->socket); + if ($info['timed_out'] || $this->timeout && time() > $this->timeout) { + throw new HTTP_Request2_Exception( + 'Request timed out after ' . + $this->request->getConfig('timeout') . ' second(s)' + ); + } + if (substr($line, -1) == "\n") { + return rtrim($line, "\r\n"); + } + } + return $line; + } + + /** + * Wrapper around fread(), handles global request timeout + * + * @param int Reads up to this number of bytes + * @return Data read from socket + * @throws HTTP_Request2_Exception In case of timeout + */ + protected function fread($length) + { + if ($this->timeout) { + stream_set_timeout($this->socket, max($this->timeout - time(), 1)); + } + $data = fread($this->socket, $length); + $info = stream_get_meta_data($this->socket); + if ($info['timed_out'] || $this->timeout && time() > $this->timeout) { + throw new HTTP_Request2_Exception( + 'Request timed out after ' . + $this->request->getConfig('timeout') . ' second(s)' + ); + } + return $data; + } + + /** + * Reads a part of response body encoded with chunked Transfer-Encoding + * + * @param int buffer size to use for reading + * @return string + * @throws HTTP_Request2_Exception + */ + protected function readChunked($bufferSize) + { + // at start of the next chunk? + if (0 == $this->chunkLength) { + $line = $this->readLine($bufferSize); + if (!preg_match('/^([0-9a-f]+)/i', $line, $matches)) { + throw new HTTP_Request2_Exception( + "Cannot decode chunked response, invalid chunk length '{$line}'" + ); + } else { + $this->chunkLength = hexdec($matches[1]); + // Chunk with zero length indicates the end + if (0 == $this->chunkLength) { + $this->readLine($bufferSize); + return ''; + } + } + } + $data = $this->fread(min($this->chunkLength, $bufferSize)); + $this->chunkLength -= strlen($data); + if (0 == $this->chunkLength) { + $this->readLine($bufferSize); // Trailing CRLF + } + return $data; + } +} + ?> \ No newline at end of file diff --git a/extlib/MIME/Type.php b/extlib/MIME/Type.php index c335f8d92d..8653362d39 100644 --- a/extlib/MIME/Type.php +++ b/extlib/MIME/Type.php @@ -478,7 +478,7 @@ class MIME_Type // Don't return an empty string if (!$type || !strlen($type)) { - return PEAR::raiseError("Sorry, couldn't determine file type."); + return PEAR::raiseError("Sorry. Could not determine file type."); } // Strip parameters if present & requested @@ -510,7 +510,7 @@ class MIME_Type $fileCmd = PEAR::getStaticProperty('MIME_Type', 'fileCmd'); if (!$cmd->which($fileCmd)) { unset($cmd); - return PEAR::raiseError("Can't find file command \"{$fileCmd}\""); + return PEAR::raiseError("Cannot find file command \"{$fileCmd}\""); } $cmd->pushCommand($fileCmd, "-bi " . escapeshellarg($file)); diff --git a/extlib/MIME/Type/Extension.php b/extlib/MIME/Type/Extension.php index 1987e2a10e..2ffdee9a91 100644 --- a/extlib/MIME/Type/Extension.php +++ b/extlib/MIME/Type/Extension.php @@ -265,7 +265,7 @@ class MIME_Type_Extension } if (!isset($this->extensionToType[$extension])) { - return PEAR::raiseError("Sorry, couldn't determine file type."); + return PEAR::raiseError("Sorry. Could not determine file type."); } return $this->extensionToType[$extension]; @@ -288,7 +288,7 @@ class MIME_Type_Extension $extension = array_search($type, $this->extensionToType); if ($extension === false) { - return PEAR::raiseError("Sorry, couldn't determine extension."); + return PEAR::raiseError("Sorry. Could not determine extension."); } return $extension; } diff --git a/extlib/Mail/mail.php b/extlib/Mail/mail.php index b13d695656..112ff940c7 100644 --- a/extlib/Mail/mail.php +++ b/extlib/Mail/mail.php @@ -51,7 +51,7 @@ class Mail_mail extends Mail { } /* Because the mail() function may pass headers as command - * line arguments, we can't guarantee the use of the standard + * line arguments, we cannot guarantee the use of the standard * "\r\n" separator. Instead, we use the system's native line * separator. */ if (defined('PHP_EOL')) { diff --git a/extlib/Mail/sendmail.php b/extlib/Mail/sendmail.php index cd248e61d2..aea52081a5 100644 --- a/extlib/Mail/sendmail.php +++ b/extlib/Mail/sendmail.php @@ -67,7 +67,7 @@ class Mail_sendmail extends Mail { /* * Because we need to pass message headers to the sendmail program on - * the commandline, we can't guarantee the use of the standard "\r\n" + * the commandline, we cannot guarantee the use of the standard "\r\n" * separator. Instead, we use the system's native line separator. */ if (defined('PHP_EOL')) { diff --git a/extlib/Net/LDAP2/Entry.php b/extlib/Net/LDAP2/Entry.php index 66de966780..5531bfa13d 100644 --- a/extlib/Net/LDAP2/Entry.php +++ b/extlib/Net/LDAP2/Entry.php @@ -665,7 +665,7 @@ class Net_LDAP2_Entry extends PEAR * To force replace mode instead of add, you can set $force to true. * * @param array $attr Attributes to replace - * @param bool $force Force replacing mode in case we can't read the attr value but are allowed to replace it + * @param bool $force Force replacing mode in case we cannot read the attr value but are allowed to replace it * * @access public * @return true|Net_LDAP2_Error diff --git a/extlib/Net/LDAP2/Filter.php b/extlib/Net/LDAP2/Filter.php index 0723edab2b..bd13d1ee4f 100644 --- a/extlib/Net/LDAP2/Filter.php +++ b/extlib/Net/LDAP2/Filter.php @@ -439,7 +439,7 @@ class Net_LDAP2_Filter extends PEAR * * This method is only for compatibility to the perl interface. * However, the original method was called "print" but due to PHP language restrictions, - * we can't have a print() method. + * we cannot have a print() method. * * @param resource $FH (optional) A filehandle resource * diff --git a/extlib/System/Command.php b/extlib/System/Command.php index f5c3ec6b92..d2001a975f 100644 --- a/extlib/System/Command.php +++ b/extlib/System/Command.php @@ -376,7 +376,7 @@ class System_Command { return $this->_initError; } - // if the command is empty or if the last element was a control operator, we can't continue + // if the command is empty or if the last element was a control operator, we cannot continue if (is_null($this->previousElement) || $this->commandStatus == -1 || in_array($this->previousElement, $this->controlOperators)) { return PEAR::raiseError(null, SYSTEM_COMMAND_INVALID_COMMAND, null, E_USER_WARNING, $this->systemCommand, 'System_Command_Error', true); } diff --git a/extlib/markdown.php b/extlib/markdown.php index 8179b568b8..1bb1b6ce43 100644 --- a/extlib/markdown.php +++ b/extlib/markdown.php @@ -1348,7 +1348,7 @@ class Markdown_Parser { // { // list(, $div_open, , $div_content, $div_close) = $matches; // -// # We can't call Markdown(), because that resets the hash; +// # We cannot call Markdown(), because that resets the hash; // # that initialization code should be pulled into its own sub, though. // $div_content = $this->hashHTMLBlocks($div_content); // diff --git a/install.php b/install.php index e7f7cf3187..78a4b87636 100644 --- a/install.php +++ b/install.php @@ -391,7 +391,7 @@ function showLibs() libraries instead, as they tend to provide security updates faster, and may offer improved performance.

On Debian based distributions, such as Ubuntu, use a package manager (such as "aptitude", "apt-get", and "synaptic") to install the package listed.

On RPM based distributions, such as Red Hat, Fedora, CentOS, Scientific Linux, Yellow Dog Linux and Oracle Enterprise Linux, use a package manager (such as "yum", "apt-rpm", and "up2date") to install the package listed.

-

On servers without a package manager (such as Windows), or if the library is not packaged for your distribution, you can use PHP's PEAR to install the library. Simply run "pear install <name>".

+

On servers without a package manager (such as Windows), or if the library is not packaged for your distribution, you can use PHP PEAR to install the library. Simply run "pear install <name>".

Absent Libraries