]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Merge branch 'testing' of git@gitorious.org:statusnet/mainline into 0.9.x
authorBrion Vibber <brion@pobox.com>
Tue, 23 Mar 2010 21:20:14 +0000 (14:20 -0700)
committerBrion Vibber <brion@pobox.com>
Tue, 23 Mar 2010 21:20:14 +0000 (14:20 -0700)
actions/foaf.php
plugins/OStatus/lib/xrd.php
plugins/OStatus/tests/remote-tests.php
plugins/OpenID/OpenIDPlugin.php

index fc2ec9b12f20c9b0ac93d95c100e8bc200ef1ba4..fc56e19b4f5c4dbb37a37e4e7a9e1262fefcdbe9 100644 (file)
@@ -162,40 +162,29 @@ class FoafAction extends Action
 
         if ($sub->find()) {
             while ($sub->fetch()) {
-                if ($sub->token) {
-                    $other = Remote_profile::staticGet('id', $sub->subscriber);
-                    $profile = Profile::staticGet('id', $sub->subscriber);
-                } else {
-                    $other = User::staticGet('id', $sub->subscriber);
-                    $profile = Profile::staticGet('id', $sub->subscriber);
-                }
-                if (!$other) {
+                $profile = Profile::staticGet('id', $sub->subscriber);
+                if (empty($profile)) {
                     common_debug('Got a bad subscription: '.print_r($sub,true));
                     continue;
                 }
-                if (array_key_exists($other->uri, $person)) {
-                    $person[$other->uri][0] = BOTH;
+                $user = $profile->getUser();
+                $other_uri = $profile->getUri();
+                if (array_key_exists($other_uri, $person)) {
+                    $person[$other_uri][0] = BOTH;
                 } else {
-                    $person[$other->uri] = array(LISTENER,
-                                                 $other->id,
-                                                 $profile->nickname,
-                                                 (empty($sub->token)) ? 'User' : 'Remote_profile');
+                    $person[$other_uri] = array(LISTENER,
+                                                $profile->id,
+                                                $profile->nickname,
+                                                $user ? 'local' : 'remote');
                 }
-                $other->free();
-                $other = null;
-                unset($other);
-                $profile->free();
-                $profile = null;
                 unset($profile);
             }
         }
 
-        $sub->free();
-        $sub = null;
         unset($sub);
 
         foreach ($person as $uri => $p) {
-            list($type, $id, $nickname, $cls) = $p;
+            list($type, $id, $nickname, $local) = $p;
             if ($type == BOTH) {
                 $this->element('knows', array('rdf:resource' => $uri));
             }
@@ -206,8 +195,8 @@ class FoafAction extends Action
 
         foreach ($person as $uri => $p) {
             $foaf_url = null;
-            list($type, $id, $nickname, $cls) = $p;
-            if ($cls == 'User') {
+            list($type, $id, $nickname, $local) = $p;
+            if ($local == 'local') {
                 $foaf_url = common_local_url('foaf', array('nickname' => $nickname));
             }
             $profile = Profile::staticGet($id);
@@ -216,7 +205,7 @@ class FoafAction extends Action
                 $this->element('knows', array('rdf:resource' => $this->user->uri));
             }
             $this->showMicrobloggingAccount($profile,
-                                   ($cls == 'User') ? common_root_url() : null,
+                                   ($local == 'local') ? common_root_url() : null,
                                    $uri,
                                    true);
             if ($foaf_url) {
@@ -275,33 +264,22 @@ class FoafAction extends Action
 
             if ($sub->find()) {
                 while ($sub->fetch()) {
-                    if (!empty($sub->token)) {
-                        $other = Remote_profile::staticGet('id', $sub->subscribed);
-                        $profile = Profile::staticGet('id', $sub->subscribed);
-                    } else {
-                        $other = User::staticGet('id', $sub->subscribed);
-                        $profile = Profile::staticGet('id', $sub->subscribed);
-                    }
-                    if (empty($other)) {
+                    $profile = Profile::staticGet('id', $sub->subscribed);
+                    if (empty($profile)) {
                         common_debug('Got a bad subscription: '.print_r($sub,true));
                         continue;
                     }
-                    $this->element('sioc:follows', array('rdf:resource' => $other->uri.'#acct'));
-                    $person[$other->uri] = array(LISTENEE,
-                                                 $other->id,
-                                                 $profile->nickname,
-                                                 (empty($sub->token)) ? 'User' : 'Remote_profile');
-                    $other->free();
-                    $other = null;
-                    unset($other);
-                    $profile->free();
-                    $profile = null;
+                    $user = $profile->getUser();
+                    $other_uri = $profile->getUri();
+                    $this->element('sioc:follows', array('rdf:resource' => $other_uri.'#acct'));
+                    $person[$other_uri] = array(LISTENEE,
+                                                $profile->id,
+                                                $profile->nickname,
+                                                $user ? 'local' : 'remote');
                     unset($profile);
                 }
             }
 
-            $sub->free();
-            $sub = null;
             unset($sub);
         }
 
index aa13ef02428faf623b5c128e0c5e38e47fdfeeab..34b28790b7452b9bea3e74e70ed2425e8f80c4fe 100644 (file)
@@ -53,7 +53,14 @@ class XRD
         $xrd = new XRD();
 
         $dom = new DOMDocument();
-        if (!$dom->loadXML($xml)) {
+
+        // Don't spew XML warnings to output
+        $old = error_reporting();
+        error_reporting($old & ~E_WARNING);
+        $ok = $dom->loadXML($xml);
+        error_reporting($old);
+
+        if (!$ok) {
             throw new Exception("Invalid XML");
         }
         $xrd_element = $dom->getElementsByTagName('XRD')->item(0);
index 103ca066c05bd86a42dcda62c96b1df02afca19d..b064114911212580df7cece401e451c70e7d99b2 100644 (file)
@@ -40,6 +40,20 @@ class TestBase
         }
         return true;
     }
+
+    function assertTrue($a)
+    {
+        if (!$a) {
+            throw new Exception("Failed to assert true: got false");
+        }
+    }
+
+    function assertFalse($a)
+    {
+        if ($a) {
+            throw new Exception("Failed to assert false: got true");
+        }
+    }
 }
 
 class OStatusTester extends TestBase
@@ -60,8 +74,12 @@ class OStatusTester extends TestBase
     function run()
     {
         $this->setup();
+
         $this->testLocalPost();
         $this->testMentionUrl();
+        $this->testSubscribe();
+        $this->testUnsubscribe();
+
         $this->log("DONE!");
     }
 
@@ -98,6 +116,25 @@ class OStatusTester extends TestBase
         $post = $this->pub->post("@$base/$name should have this in home and replies");
         $this->sub->assertReceived($post);
     }
+
+    function testSubscribe()
+    {
+        $this->assertFalse($this->sub->hasSubscription($this->pub->getProfileUri()));
+        $this->assertFalse($this->pub->hasSubscriber($this->sub->getProfileUri()));
+        $this->sub->subscribe($this->pub->getProfileLink());
+        $this->assertTrue($this->sub->hasSubscription($this->pub->getProfileUri()));
+        $this->assertTrue($this->pub->hasSubscriber($this->sub->getProfileUri()));
+    }
+
+    function testUnsubscribe()
+    {
+        $this->assertTrue($this->sub->hasSubscription($this->pub->getProfileUri()));
+        $this->assertTrue($this->pub->hasSubscriber($this->sub->getProfileUri()));
+        $this->sub->unsubscribe($this->pub->getProfileLink());
+        $this->assertFalse($this->sub->hasSubscription($this->pub->getProfileUri()));
+        $this->assertFalse($this->pub->hasSubscriber($this->sub->getProfileUri()));
+    }
+
 }
 
 class SNTestClient extends TestBase
@@ -202,6 +239,43 @@ class SNTestClient extends TestBase
         return $dom;
     }
 
+    protected function parseXml($path, $body)
+    {
+        $dom = new DOMDocument();
+        if ($dom->loadXML($body)) {
+            return $dom;
+        } else {
+            throw new Exception("Bogus XML data from $path:\n$body");
+        }
+    }
+
+    /**
+     * Make a hit to a REST-y XML page on the site, without authentication.
+     * @param string $path URL fragment for something relative to base
+     * @param array $params POST parameters to send
+     * @return DOMDocument
+     * @throws Exception on low-level error conditions
+     */
+    protected function xml($path, $params=array())
+    {
+        $response = $this->hit($path, $params, true);
+        $body = $response->getBody();
+        return $this->parseXml($path, $body);
+    }
+
+    protected function parseJson($path, $body)
+    {
+        $data = json_decode($body, true);
+        if ($data !== null) {
+            if (!empty($data['error'])) {
+                throw new Exception("JSON API returned error: " . $data['error']);
+            }
+            return $data;
+        } else {
+            throw new Exception("Bogus JSON data from $path:\n$body");
+        }
+    }
+
     /**
      * Make an API hit to this site, with authentication.
      * @param string $path URL fragment for something under 'api' folder
@@ -215,22 +289,9 @@ class SNTestClient extends TestBase
         $response = $this->hit("api/$path.$style", $params, true);
         $body = $response->getBody();
         if ($style == 'json') {
-            $data = json_decode($body, true);
-            if ($data !== null) {
-                if (!empty($data['error'])) {
-                    throw new Exception("JSON API returned error: " . $data['error']);
-                }
-                return $data;
-            } else {
-                throw new Exception("Bogus JSON data from $path:\n$body");
-            }
+            return $this->parseJson($path, $body);
         } else if ($style == 'xml' || $style == 'atom') {
-            $dom = new DOMDocument();
-            if ($dom->loadXML($body)) {
-                return $dom;
-            } else {
-                throw new Exception("Bogus XML data from $path:\n$body");
-            }
+            return $this->parseXml($path, $body);
         } else {
             throw new Exception("API needs to be JSON, XML, or Atom");
         }
@@ -257,6 +318,24 @@ class SNTestClient extends TestBase
                   'submit' => 'Register'));
     }
 
+    /**
+     * @return string canonical URI/URL to profile page
+     */
+    function getProfileUri()
+    {
+        $data = $this->api('account/verify_credentials', 'json');
+        $id = $data['id'];
+        return $this->basepath . '/user/' . $id;
+    }
+
+    /**
+     * @return string human-friendly URL to profile page
+     */
+    function getProfileLink()
+    {
+        return $this->basepath . '/' . $this->username;
+    }
+
     /**
      * Check that the account has been registered and can be used.
      * On failure, throws a test failure exception.
@@ -349,22 +428,81 @@ class SNTestClient extends TestBase
         return false;
     }
 
+    /**
+     * @param string $profile user page link or webfinger
+     */
+    function subscribe($profile)
+    {
+        // This uses the command interface, since there's not currently
+        // a friendly Twit-API way to do a fresh remote subscription and
+        // the web form's a pain to use.
+        $this->post('follow ' . $profile);
+    }
+
+    /**
+     * @param string $profile user page link or webfinger
+     */
+    function unsubscribe($profile)
+    {
+        // This uses the command interface, since there's not currently
+        // a friendly Twit-API way to do a fresh remote subscription and
+        // the web form's a pain to use.
+        $this->post('leave ' . $profile);
+    }
+
     /**
      * Check that this account is subscribed to the given profile.
      * @param string $profile_uri URI for the profile to check for
+     * @return boolean
      */
-    function assertHasSubscription($profile_uri)
+    function hasSubscription($profile_uri)
     {
-        throw new Exception('tbi');
+        $this->log("Checking if $this->username has a subscription to $profile_uri");
+
+        $me = $this->getProfileUri();
+        return $this->checkSubscription($me, $profile_uri);
     }
 
     /**
      * Check that this account is subscribed to by the given profile.
      * @param string $profile_uri URI for the profile to check for
+     * @return boolean
      */
-    function assertHasSubscriber($profile_uri)
+    function hasSubscriber($profile_uri)
+    {
+        $this->log("Checking if $this->username is subscribed to by $profile_uri");
+
+        $me = $this->getProfileUri();
+        return $this->checkSubscription($profile_uri, $me);
+    }
+    
+    protected function checkSubscription($subscriber, $subscribed)
     {
-        throw new Exception('tbi');
+        // Using FOAF as the API methods for checking the social graph
+        // currently are unfriendly to remote profiles
+        $ns_foaf = 'http://xmlns.com/foaf/0.1/';
+        $ns_sioc = 'http://rdfs.org/sioc/ns#';
+        $ns_rdf = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
+
+        $dom = $this->xml($this->username . '/foaf');
+        $agents = $dom->getElementsByTagNameNS($ns_foaf, 'Agent');
+        foreach ($agents as $agent) {
+            $agent_uri = $agent->getAttributeNS($ns_rdf, 'about');
+            if ($agent_uri == $subscriber) {
+                $follows = $agent->getElementsByTagNameNS($ns_sioc, 'follows');
+                foreach ($follows as $follow) {
+                    $target = $follow->getAttributeNS($ns_rdf, 'resource');
+                    if ($target == ($subscribed . '#acct')) {
+                        $this->log("Confirmed $subscriber subscribed to $subscribed");
+                        return true;
+                    }
+                }
+                $this->log("We found $subscriber but they don't follow $subscribed");
+                return false;
+            }
+        }
+        $this->log("Can't find $subscriber in {$this->username}'s social graph.");
+        return false;
     }
 
 }
index 6b35ec3e142f2f1503f7df6476e94691fb1d1d2f..1724b5f7be769b01ce9fb9648d07837b172954b4 100644 (file)
@@ -59,6 +59,8 @@ class OpenIDPlugin extends Plugin
      *
      * Hook for RouterInitialized event.
      *
+     * @param Net_URL_Mapper $m URL mapper
+     *
      * @return boolean hook return
      */
 
@@ -67,54 +69,87 @@ class OpenIDPlugin extends Plugin
         $m->connect('main/openid', array('action' => 'openidlogin'));
         $m->connect('main/openidtrust', array('action' => 'openidtrust'));
         $m->connect('settings/openid', array('action' => 'openidsettings'));
-        $m->connect('index.php?action=finishopenidlogin', array('action' => 'finishopenidlogin'));
-        $m->connect('index.php?action=finishaddopenid', array('action' => 'finishaddopenid'));
+        $m->connect('index.php?action=finishopenidlogin',
+                    array('action' => 'finishopenidlogin'));
+        $m->connect('index.php?action=finishaddopenid',
+                    array('action' => 'finishaddopenid'));
         $m->connect('main/openidserver', array('action' => 'openidserver'));
 
         return true;
     }
 
+    /**
+     * Public XRDS output hook
+     *
+     * Puts the bits of code needed by some OpenID providers to show
+     * we're good citizens.
+     *
+     * @param Action       $action         Action being executed
+     * @param XMLOutputter &$xrdsOutputter Output channel
+     *
+     * @return boolean hook return
+     */
+
     function onEndPublicXRDS($action, &$xrdsOutputter)
     {
         $xrdsOutputter->elementStart('XRD', array('xmlns' => 'xri://$xrd*($v*2.0)',
-                                          'xmlns:simple' => 'http://xrds-simple.net/core/1.0',
-                                          'version' => '2.0'));
+                                                  'xmlns:simple' => 'http://xrds-simple.net/core/1.0',
+                                                  'version' => '2.0'));
         $xrdsOutputter->element('Type', null, 'xri://$xrds*simple');
         //consumer
         foreach (array('finishopenidlogin', 'finishaddopenid') as $finish) {
             $xrdsOutputter->showXrdsService(Auth_OpenID_RP_RETURN_TO_URL_TYPE,
-                                common_local_url($finish));
+                                            common_local_url($finish));
         }
         //provider
         $xrdsOutputter->showXrdsService('http://specs.openid.net/auth/2.0/server',
-                            common_local_url('openidserver'),
-                            null,
-                            null,
-                            'http://specs.openid.net/auth/2.0/identifier_select');
+                                        common_local_url('openidserver'),
+                                        null,
+                                        null,
+                                        'http://specs.openid.net/auth/2.0/identifier_select');
         $xrdsOutputter->elementEnd('XRD');
     }
 
+    /**
+     * User XRDS output hook
+     *
+     * Puts the bits of code needed to discover OpenID endpoints.
+     *
+     * @param Action       $action         Action being executed
+     * @param XMLOutputter &$xrdsOutputter Output channel
+     *
+     * @return boolean hook return
+     */
+
     function onEndUserXRDS($action, &$xrdsOutputter)
     {
         $xrdsOutputter->elementStart('XRD', array('xmlns' => 'xri://$xrd*($v*2.0)',
-                                          'xml:id' => 'openid',
-                                          'xmlns:simple' => 'http://xrds-simple.net/core/1.0',
-                                          'version' => '2.0'));
+                                                  'xml:id' => 'openid',
+                                                  'xmlns:simple' => 'http://xrds-simple.net/core/1.0',
+                                                  'version' => '2.0'));
         $xrdsOutputter->element('Type', null, 'xri://$xrds*simple');
 
         //consumer
         $xrdsOutputter->showXrdsService('http://specs.openid.net/auth/2.0/return_to',
-                            common_local_url('finishopenidlogin'));
+                                        common_local_url('finishopenidlogin'));
 
         //provider
         $xrdsOutputter->showXrdsService('http://specs.openid.net/auth/2.0/signon',
-                            common_local_url('openidserver'),
-                            null,
-                            null,
-                            common_profile_url($action->user->nickname));
+                                        common_local_url('openidserver'),
+                                        null,
+                                        null,
+                                        common_profile_url($action->user->nickname));
         $xrdsOutputter->elementEnd('XRD');
     }
 
+    /**
+     * Menu item for login
+     *
+     * @param Action &$action Action being executed
+     *
+     * @return boolean hook return
+     */
+
     function onEndLoginGroupNav(&$action)
     {
         $action_name = $action->trimmed('action');
@@ -127,6 +162,14 @@ class OpenIDPlugin extends Plugin
         return true;
     }
 
+    /**
+     * Menu item for OpenID admin
+     *
+     * @param Action &$action Action being executed
+     *
+     * @return boolean hook return
+     */
+
     function onEndAccountSettingsNav(&$action)
     {
         $action_name = $action->trimmed('action');
@@ -139,68 +182,102 @@ class OpenIDPlugin extends Plugin
         return true;
     }
 
+    /**
+     * Autoloader
+     *
+     * Loads our classes if they're requested.
+     *
+     * @param string $cls Class requested
+     *
+     * @return boolean hook return
+     */
+
     function onAutoload($cls)
     {
         switch ($cls)
         {
-         case 'OpenidloginAction':
-         case 'FinishopenidloginAction':
-         case 'FinishaddopenidAction':
-         case 'XrdsAction':
-         case 'PublicxrdsAction':
-         case 'OpenidsettingsAction':
-         case 'OpenidserverAction':
-         case 'OpenidtrustAction':
-            require_once(INSTALLDIR.'/plugins/OpenID/' . strtolower(mb_substr($cls, 0, -6)) . '.php');
+        case 'OpenidloginAction':
+        case 'FinishopenidloginAction':
+        case 'FinishaddopenidAction':
+        case 'XrdsAction':
+        case 'PublicxrdsAction':
+        case 'OpenidsettingsAction':
+        case 'OpenidserverAction':
+        case 'OpenidtrustAction':
+            require_once INSTALLDIR.'/plugins/OpenID/' . strtolower(mb_substr($cls, 0, -6)) . '.php';
             return false;
-         case 'User_openid':
-            require_once(INSTALLDIR.'/plugins/OpenID/User_openid.php');
+        case 'User_openid':
+            require_once INSTALLDIR.'/plugins/OpenID/User_openid.php';
             return false;
-         case 'User_openid_trustroot':
-            require_once(INSTALLDIR.'/plugins/OpenID/User_openid_trustroot.php');
+        case 'User_openid_trustroot':
+            require_once INSTALLDIR.'/plugins/OpenID/User_openid_trustroot.php';
             return false;
-         default:
+        default:
             return true;
         }
     }
 
+    /**
+     * Sensitive actions
+     *
+     * These actions should use https when SSL support is 'sometimes'
+     *
+     * @param Action  $action Action to form an URL for
+     * @param boolean &$ssl   Whether to mark it for SSL
+     *
+     * @return boolean hook return
+     */
+
     function onSensitiveAction($action, &$ssl)
     {
         switch ($action)
         {
-         case 'finishopenidlogin':
-         case 'finishaddopenid':
+        case 'finishopenidlogin':
+        case 'finishaddopenid':
             $ssl = true;
             return false;
-         default:
+        default:
             return true;
         }
     }
 
+    /**
+     * Login actions
+     *
+     * These actions should be visible even when the site is marked private
+     *
+     * @param Action  $action Action to show
+     * @param boolean &$login Whether it's a login action
+     *
+     * @return boolean hook return
+     */
+
     function onLoginAction($action, &$login)
     {
         switch ($action)
         {
-         case 'openidlogin':
-         case 'finishopenidlogin':
-         case 'openidserver':
+        case 'openidlogin':
+        case 'finishopenidlogin':
+        case 'openidserver':
             $login = true;
             return false;
-         default:
+        default:
             return true;
         }
     }
 
     /**
-     * We include a <meta> element linking to the publicxrds page, for OpenID
+     * We include a <meta> element linking to the userxrds page, for OpenID
      * client-side authentication.
      *
+     * @param Action $action Action being shown
+     *
      * @return void
      */
 
     function onEndShowHeadElements($action)
     {
-        if($action instanceof ShowstreamAction){
+        if ($action instanceof ShowstreamAction) {
             $action->element('link', array('rel' => 'openid2.provider',
                                            'href' => common_local_url('openidserver')));
             $action->element('link', array('rel' => 'openid2.local_id',
@@ -216,6 +293,9 @@ class OpenIDPlugin extends Plugin
     /**
      * Redirect to OpenID login if they have an OpenID
      *
+     * @param Action $action Action being executed
+     * @param User   $user   User doing the action
+     *
      * @return boolean whether to continue
      */
 
@@ -228,13 +308,21 @@ class OpenIDPlugin extends Plugin
         return true;
     }
 
+    /**
+     * Show some extra instructions for using OpenID
+     *
+     * @param Action $action Action being executed
+     *
+     * @return boolean hook value
+     */
+
     function onEndShowPageNotice($action)
     {
         $name = $action->trimmed('action');
 
         switch ($name)
         {
-         case 'register':
+        case 'register':
             if (common_logged_in()) {
                 $instr = '(Have an [OpenID](http://openid.net/)? ' .
                   '[Add an OpenID to your account](%%action.openidsettings%%)!';
@@ -244,12 +332,12 @@ class OpenIDPlugin extends Plugin
                   '(%%action.openidlogin%%)!)';
             }
             break;
-         case 'login':
+        case 'login':
             $instr = '(Have an [OpenID](http://openid.net/)? ' .
               'Try our [OpenID login]'.
               '(%%action.openidlogin%%)!)';
             break;
-         default:
+        default:
             return true;
         }
 
@@ -258,13 +346,21 @@ class OpenIDPlugin extends Plugin
         return true;
     }
 
+    /**
+     * Load our document if requested
+     *
+     * @param string &$title  Title to fetch
+     * @param string &$output HTML to output
+     *
+     * @return boolean hook value
+     */
+
     function onStartLoadDoc(&$title, &$output)
     {
-        if ($title == 'openid')
-        {
+        if ($title == 'openid') {
             $filename = INSTALLDIR.'/plugins/OpenID/doc-src/openid';
 
-            $c = file_get_contents($filename);
+            $c      = file_get_contents($filename);
             $output = common_markup_to_html($c);
             return false; // success!
         }
@@ -272,10 +368,18 @@ class OpenIDPlugin extends Plugin
         return true;
     }
 
+    /**
+     * Add our document to the global menu
+     *
+     * @param string $title   Title being fetched
+     * @param string &$output HTML being output
+     *
+     * @return boolean hook value
+     */
+
     function onEndLoadDoc($title, &$output)
     {
-        if ($title == 'help')
-        {
+        if ($title == 'help') {
             $menuitem = '* [OpenID](%%doc.openid%%) - what OpenID is and how to use it with this service';
 
             $output .= common_markup_to_html($menuitem);
@@ -284,7 +388,16 @@ class OpenIDPlugin extends Plugin
         return true;
     }
 
-    function onCheckSchema() {
+    /**
+     * Data definitions
+     *
+     * Assure that our data objects are available in the DB
+     *
+     * @return boolean hook value
+     */
+
+    function onCheckSchema()
+    {
         $schema = Schema::get();
         $schema->ensureTable('user_openid',
                              array(new ColumnDef('canonical', 'varchar',
@@ -307,6 +420,15 @@ class OpenIDPlugin extends Plugin
         return true;
     }
 
+    /**
+     * Add our tables to be deleted when a user is deleted
+     *
+     * @param User  $user    User being deleted
+     * @param array &$tables Array of table names
+     *
+     * @return boolean hook value
+     */
+
     function onUserDeleteRelated($user, &$tables)
     {
         $tables[] = 'User_openid';
@@ -314,6 +436,14 @@ class OpenIDPlugin extends Plugin
         return true;
     }
 
+    /**
+     * Add our version information to output
+     *
+     * @param array &$versions Array of version-data arrays
+     *
+     * @return boolean hook value
+     */
+
     function onPluginVersion(&$versions)
     {
         $versions[] = array('name' => 'OpenID',