diff --git a/README b/README index 45b72e9acc..c5adda1776 100644 --- a/README +++ b/README @@ -137,7 +137,9 @@ run correctly. - PHP 5.2.3+. It may be possible to run this software on earlier versions of PHP, but many of the functions used are only available - in PHP 5.2 or above. + in PHP 5.2 or above. 5.2.6 or later is needed for XMPP background + daemons on 64-bit platforms. PHP 5.3.x should work but is known + to cause some failures for OpenID. - MySQL 5.x. The StatusNet database is stored, by default, in a MySQL server. It has been primarily tested on 5.x servers, although it may be possible to install on earlier (or later!) versions. The server diff --git a/classes/Foreign_user.php b/classes/Foreign_user.php index 8b3e03dfb3..0dd94ffb99 100644 --- a/classes/Foreign_user.php +++ b/classes/Foreign_user.php @@ -41,6 +41,7 @@ class Foreign_user extends Memcached_DataObject function updateKeys(&$orig) { + $this->_connect(); $parts = array(); foreach (array('id', 'service', 'uri', 'nickname') as $k) { if (strcmp($this->$k, $orig->$k) != 0) { diff --git a/classes/Subscription.php b/classes/Subscription.php index 9cef2df1ad..5ac95f9222 100644 --- a/classes/Subscription.php +++ b/classes/Subscription.php @@ -105,8 +105,8 @@ class Subscription extends Memcached_DataObject $auto = new Subscription(); - $auto->subscriber = $subscriber->id; - $auto->subscribed = $other->id; + $auto->subscriber = $other->id; + $auto->subscribed = $subscriber->id; $auto->created = common_sql_now(); $result = $auto->insert(); diff --git a/classes/User.php b/classes/User.php index 77091fad5d..16c256535b 100644 --- a/classes/User.php +++ b/classes/User.php @@ -75,7 +75,11 @@ class User extends Memcached_DataObject function getProfile() { - return Profile::staticGet('id', $this->id); + $profile = Profile::staticGet('id', $this->id); + if (empty($profile)) { + throw new UserNoProfileException($this); + } + return $profile; } function isSubscribed($other) @@ -87,6 +91,7 @@ class User extends Memcached_DataObject function updateKeys(&$orig) { + $this->_connect(); $parts = array(); foreach (array('nickname', 'email', 'jabber', 'incomingemail', 'sms', 'carrier', 'smsemail', 'language', 'timezone') as $k) { if (strcmp($this->$k, $orig->$k) != 0) { @@ -140,9 +145,6 @@ class User extends Memcached_DataObject function getCurrentNotice() { $profile = $this->getProfile(); - if (!$profile) { - return null; - } return $profile->getCurrentNotice(); } @@ -470,21 +472,13 @@ class User extends Memcached_DataObject function getTaggedNotices($tag, $offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0) { $profile = $this->getProfile(); - if (!$profile) { - return null; - } else { - return $profile->getTaggedNotices($tag, $offset, $limit, $since_id, $before_id); - } + return $profile->getTaggedNotices($tag, $offset, $limit, $since_id, $before_id); } function getNotices($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0) { $profile = $this->getProfile(); - if (!$profile) { - return null; - } else { - return $profile->getNotices($offset, $limit, $since_id, $before_id); - } + return $profile->getNotices($offset, $limit, $since_id, $before_id); } function favoriteNotices($offset=0, $limit=NOTICES_PER_PAGE, $own=false) @@ -625,14 +619,12 @@ class User extends Memcached_DataObject function getSubscriptions($offset=0, $limit=null) { $profile = $this->getProfile(); - assert(!empty($profile)); return $profile->getSubscriptions($offset, $limit); } function getSubscribers($offset=0, $limit=null) { $profile = $this->getProfile(); - assert(!empty($profile)); return $profile->getSubscribers($offset, $limit); } @@ -696,9 +688,7 @@ class User extends Memcached_DataObject function delete() { $profile = $this->getProfile(); - if ($profile) { - $profile->delete(); - } + $profile->delete(); $related = array('Fave', 'Confirm_address', diff --git a/htaccess.sample b/htaccess.sample index 37eb8e01ec..18a868698c 100644 --- a/htaccess.sample +++ b/htaccess.sample @@ -5,6 +5,11 @@ RewriteBase /mublog/ + ## Uncomment these if having trouble with API authentication + ## when PHP is running in CGI or FastCGI mode. + #RewriteCond %{HTTP:Authorization} ^(.*) + #RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1] + RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule (.*) index.php?p=$1 [L,QSA] diff --git a/lib/apiauth.php b/lib/apiauth.php index 32502399f9..17f803a1ca 100644 --- a/lib/apiauth.php +++ b/lib/apiauth.php @@ -294,11 +294,15 @@ class ApiAuthAction extends ApiAction function basicAuthProcessHeader() { - if (isset($_SERVER['AUTHORIZATION']) - || isset($_SERVER['HTTP_AUTHORIZATION']) - ) { - $authorization_header = isset($_SERVER['HTTP_AUTHORIZATION']) - ? $_SERVER['HTTP_AUTHORIZATION'] : $_SERVER['AUTHORIZATION']; + $authHeaders = array('AUTHORIZATION', + 'HTTP_AUTHORIZATION', + 'REDIRECT_HTTP_AUTHORIZATION'); // rewrite for CGI + $authorization_header = null; + foreach ($authHeaders as $header) { + if (isset($_SERVER[$header])) { + $authorization_header = $_SERVER[$header]; + break; + } } if (isset($_SERVER['PHP_AUTH_USER'])) { diff --git a/lib/usernoprofileexception.php b/lib/usernoprofileexception.php new file mode 100644 index 0000000000..6744d2529d --- /dev/null +++ b/lib/usernoprofileexception.php @@ -0,0 +1,74 @@ +. + * + * @category Exception + * @package StatusNet + * @author Evan Prodromou + * @copyright 2010 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3 + * @link http://status.net/ + */ + +if (!defined('STATUSNET')) { + exit(1); +} + +/** + * Class for an exception when the user profile is missing + * + * @category Exception + * @package StatusNet + * @author Evan Prodromou + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3 + * @link http://status.net/ + */ + +class UserNoProfileException extends ServerException +{ + var $user = null; + + /** + * constructor + * + * @param User $user User that's missing a profile + */ + + public function __construct($user) + { + $this->user = $user; + + $message = sprintf(_("User %s (%d) has no profile record."), + $user->nickname, $user->id); + + parent::__construct($message); + } + + /** + * Accessor for user + * + * @return User the user that triggered this exception + */ + + public function getUser() + { + return $this->user; + } +} diff --git a/plugins/OStatus/classes/Ostatus_profile.php b/plugins/OStatus/classes/Ostatus_profile.php index 73f5d23229..f8fda4162a 100644 --- a/plugins/OStatus/classes/Ostatus_profile.php +++ b/plugins/OStatus/classes/Ostatus_profile.php @@ -1464,7 +1464,7 @@ class Ostatus_profile extends Memcached_DataObject if (array_key_exists('profileurl', $hints)) { try { common_log(LOG_INFO, "Discovery on acct:$addr with profile URL $profileUrl"); - $oprofile = self::ensureProfile($hints['profileurl'], $hints); + $oprofile = self::ensureProfileURL($hints['profileurl'], $hints); self::cacheSet(sprintf('ostatus_profile:webfinger:%s', $addr), $oprofile->uri); return $oprofile; } catch (Exception $e) { diff --git a/plugins/OStatus/scripts/updateostatus.php b/plugins/OStatus/scripts/updateostatus.php index d553a7d625..622ded56ab 100644 --- a/plugins/OStatus/scripts/updateostatus.php +++ b/plugins/OStatus/scripts/updateostatus.php @@ -56,7 +56,12 @@ try { $user = new User(); if ($user->find()) { while ($user->fetch()) { - updateOStatus($user); + try { + updateOStatus($user); + } catch (Exception $e) { + common_log(LOG_NOTICE, "Couldn't convert OMB subscriptions ". + "for {$user->nickname} to OStatus: " . $e->getMessage()); + } } } } else { @@ -98,7 +103,7 @@ function updateOStatus($user) echo "Checking {$rp->nickname}..."; } - $op = Ostatus_profile::ensureProfile($rp->profileurl); + $op = Ostatus_profile::ensureProfileURL($rp->profileurl); if (empty($op)) { echo "can't convert.\n"; @@ -107,8 +112,8 @@ function updateOStatus($user) if (!have_option('q', 'quiet')) { echo "Converting..."; } - Subscription::cancel($up, $rp); Subscription::start($up, $op->localProfile()); + Subscription::cancel($up, $rp); if (!have_option('q', 'quiet')) { echo "done.\n"; } @@ -118,8 +123,7 @@ function updateOStatus($user) if (!have_option('q', 'quiet')) { echo "fail.\n"; } - continue; - common_log(LOG_WARNING, "Couldn't convert OMB subscription (" . $up->nickname . ", " . $rp->nickname . + common_log(LOG_NOTICE, "Couldn't convert OMB subscription (" . $up->nickname . ", " . $rp->nickname . ") to OStatus: " . $e->getMessage()); continue; } diff --git a/scripts/fixup_files.php b/scripts/fixup_files.php new file mode 100755 index 0000000000..18feaf2218 --- /dev/null +++ b/scripts/fixup_files.php @@ -0,0 +1,77 @@ +#!/usr/bin/env php +. + */ + +define('INSTALLDIR', realpath(dirname(__FILE__) . '/..')); + +$longoptions = array('dry-run'); + +$helptext = <<title = 'h'; +$f->mimetype = 'h'; +$f->size = 0; +$f->protected = 0; +$f->find(); +echo "Found $f->N bad items:\n"; + +while ($f->fetch()) { + echo "$f->id $f->url"; + + $data = File_redirection::lookupWhere($f->url); + if ($dry) { + if (is_array($data)) { + echo " (unchanged)\n"; + } else { + echo " (unchanged, but embedding lookup failed)\n"; + } + } else { + // NULL out the mime/title/size/protected fields + $sql = sprintf("UPDATE file " . + "SET mimetype=null,title=null,size=null,protected=null " . + "WHERE id=%d", + $f->id); + $f->query($sql); + $f->decache(); + + if (is_array($data)) { + if ($f->saveOembed($data, $f->url)) { + echo " (ok)\n"; + } else { + echo " (ok, no embedding data)\n"; + } + } else { + echo " (ok, but embedding lookup failed)\n"; + } + } +} + +echo "done.\n"; + diff --git a/scripts/xmppdaemon.php b/scripts/xmppdaemon.php index 26c7991b88..abd7cc22b4 100755 --- a/scripts/xmppdaemon.php +++ b/scripts/xmppdaemon.php @@ -98,7 +98,15 @@ class XmppMaster extends IoMaster // don't have to find an XMPP site to start up when using --all mode. if (common_config('xmpp','enabled')==false) { print "Aborting daemon - xmpp is disabled\n"; - exit(); + exit(1); +} + +if (version_compare(PHP_VERSION, '5.2.6', '<')) { + $arch = php_uname('m'); + if ($arch == 'x86_64' || $arch == 'amd64') { + print "Aborting daemon - 64-bit PHP prior to 5.2.6 has known bugs in stream_select; you are running " . PHP_VERSION . " on $arch.\n"; + exit(1); + } } if (have_option('i', 'id')) {