/** * Returns true if the specified Facebook user (default to current one) can * edit properties for the application. The user must be an administrator * or developer of the app and must also be an administrator of the wiki. */ function canEdit($fbUser = NULL) { global $facebook, $wgUser; if (!$fbUser instanceof FacebookUser) { $fbUser = new FacebookUser(); } // First, check MediaWiki permissions. Then check with Facebook if ($fbUser->getMWUser()->getId() == 0 || $fbUser->getMWUser()->getId() != $wgUser->getId()) { return false; } // If $wgFbUserRightsFromGroups is set, this should trigger a group check $groups = $fbUser->getMWUser()->getEffectiveGroups(); if (!in_array('sysop', $groups) && !in_array('fb-admin', $groups)) { return false; } // Check that the Facebook user has a development role with the application $roles = $this->getRoles(); if (!in_array($fbUser->getId(), $roles['administrators']) && !in_array($fbUser->getId(), $roles['developers'])) { return false; } return true; }
/** * If $wgFbDisableLogin is set, make sure the user gets logged out if their * Facebook session is destroyed. * * This hook was added in MediaWiki 1.14. */ static function UserLoadAfterLoadFromSession($user) { global $wgFbDisableLogin; // Don't mess with authentication on Special:Connect $title = $user->getSkin()->getTitle(); if (!empty($wgFbDisableLogin) && $user->isLoggedIn() && $title instanceof Title && !$title->isSpecial('Connect')) { $fbUser = new FacebookUser(); // If possible, force a preemptive ping to Facebook's servers. Otherwise, we // must wait until the next page view to pick up the user's Facebook login status #$fbUser->isLoggedIn($ping = true); if (!$fbUser->isLoggedIn() || $user->getId() != $fbUser->getMWUser()->getId()) { $user->logout(); } } return true; }
/** * Remove the watch action from the user's Timeline when they unwatch an * article. */ public static function UnwatchArticleComplete(&$user, &$article) { global $facebook; if (self::getAction('watch')) { $fbUser = new FacebookUser(); if ($fbUser->getMWUser()->getId() == $user->getId()) { $object = FacebookOpenGraph::newObjectFromTitle($article->getTitle()); try { self::removeAction('watch', $object); } catch (FacebookApiException $e) { // echo $e->getType() . ": " . $e->getMessage() . "<br/>\n"; } } } return true; }
public function execute() { global $wgFbStreamlineLogin; if (!empty($wgFbStreamlineLogin)) { $params = $this->extractRequestParams(); $fbUser = new FacebookUser($params['id']); $id = $fbUser->getMWUser()->getId(); if ($id) { //wfLoadExtensionMessages('Facebook'); // Deprecated since 1.16 $specialConnect = new SpecialConnect(); $this->getResult()->addValue(null, null, $specialConnect->getLogoutAndContinueForm($params, $id)); } else { // TODO: Add a LogoutAndCreateNewUser form to SpecialConnect.php. For // now, return an empty response to send user to Special:Connect // (which displays an error message). } } }
/** * Special:Connect/Debug * * This is the only subpage that can be called directly. It allows an admin * to verify that the app is set up correctly inside Facebook, and offers * to automatically fix some of the problems it detects. */ private function debugView() { global $wgRequest, $wgOut, $wgFbNamespace, $wgFbLogo, $wgEmergencyContact, $wgStylePath, $wgVersion; // "Enter a page name to view it as an object in the Open Graph." Render a button that // submits the wpPageName field to Special:Connect/Debug and handle the submission here. // TODO: handle the redirect in execute() maybe // The following code is untested $pageName = $wgRequest->getText('wpPageName'); if ($pageName != '') { $title = Title::newFromText($pageName); if (!$title instanceof Title) { $title = Title::newMainPage(); } $url = 'https://developers.facebook.com/tools/debug/og/object?q=' . urlencode($title->getFullURL()); $wgOut->redirect($url); return; } $wgOut->setPageTitle(wfMsg('facebook-debug-title')); // Include the JavaScript that lets us change the application properties if (version_compare($wgVersion, '1.17', '>=')) { $wgOut->addModules('ext.facebook.application'); } $app = new FacebookApplication(); $info = $app->getInfo(); // If the request failed, 'id' will be the only field $id = $info['id']; unset($info['id']); if (empty($info)) { $wgOut->addHTML("No application information could be retrieved from Facebook."); return; } $server = ''; // Lookup the server name if (isset($_SERVER['SERVER_NAME'])) { $server = $_SERVER['SERVER_NAME']; } elseif (isset($_SERVER['HOSTNAME'])) { $server = $_SERVER['HOSTNAME']; } elseif (isset($_SERVER['HTTP_HOST'])) { $server = $_SERVER['HTTP_HOST']; } elseif (isset($_SERVER['SERVER_ADDR'])) { $server = $_SERVER['SERVER_ADDR']; } // Might as well not show a blank logo if (!$info['icon_url'] && !empty($wgFbLogo)) { $info['icon_url'] = $wgFbLogo; } // Get a link to the creator's wiki page or Facebook profile page $creatorLink = ''; if ($info['creator_uid']) { $creator = new FacebookUser($info['creator_uid']); if ($creator->getMWUser()->getId()) { $creatorLink = '<a href="' . $creator->getMWUser()->getUserPage()->getFullURL() . '">' . $creator->getMWUser()->getName() . '</a>'; } else { $creatorLink = '<span class="mw-facebook-logo"><a ' . 'href="https://www.facebook.com/profile.php?id=' . $info['creator_uid'] . '">' . $info['creator_uid'] . '</a></span>'; } } // The values of these fields are pulled from the extension messages $fields_with_msgs = array('privacy_policy_url' => 'privacypage', 'terms_of_service_url' => 'facebook-termsofservicepage', 'auth_dialog_headline' => 'facebook-auth-dialog-headline', 'auth_dialog_description' => 'facebook-auth-dialog-description', 'auth_dialog_perms_explanation' => 'facebook-auth-dialog-explanation'); // Format is: (field_name, Display name, Description, Suggested value) $field_array = array(array('namespace', 'Namespace', 'Namespace your app uses for Open Graph', FacebookAPI::isNamespaceSetup() ? $wgFbNamespace : ''), array('website_url', 'Website URL', 'URL of the Main Page', Title::newMainPage()->getFullURL()), array('deauth_callback_url', 'Deauthorize URL', 'Set this to Special:Connect/Deauth', self::getTitleFor('Connect', 'Deauth')->getFullURL()), array('privacy_policy_url', 'Privacy policy URL', 'The Facebook Platform Terms of Service require a privacy policy URL', Title::newFromText(wfMsg($fields_with_msgs['privacy_policy_url']))->getFullURL()), array('terms_of_service_url', 'Terms of service URL', '', Title::newFromText(wfMsg($fields_with_msgs['terms_of_service_url']))->getFullURL()), array('app_domains', 'App domains', 'Domains and subdomains this app can use (e.g., "example.com" will enable *.example.com)', $server), array('contact_email', 'Contact email', 'Primary email used for important communication related to your app ($wgEmergencyContact)', !empty($wgEmergencyContact) ? $wgEmergencyContact : ''), array('user_support_email', 'User support email', 'Required by Facebook: Main contact email for this app ($wgEmergencyContact)', !empty($wgEmergencyContact) ? $wgEmergencyContact : ''), array('auth_dialog_headline', 'Auth dialog headline', 'Description that appears in the Auth Dialog (30 characters or less)', $this->trimPTags(wfMsgWikiHtml($fields_with_msgs['auth_dialog_headline']))), array('auth_dialog_description', 'Auth dialog description', 'Description that appears in the Auth Dialog (140 characters or less)', $this->trimPTags(wfMsgWikiHtml($fields_with_msgs['auth_dialog_description']))), array('auth_dialog_perms_explanation', 'Explanation for permissions', 'Provide an explanation for how your app plans to use extended permissions, if any (140 characters or less)', $this->trimPTags(wfMsgWikiHtml($fields_with_msgs['auth_dialog_perms_explanation']))), array('daily_active_users', 'Daily active users', '', ''), array('weekly_active_users', 'Weekly active users', '', ''), array('monthly_active_users', 'Monthly active users', '', '')); // Build the html $html = ' <table> <tr> <td> <a href="' . $info['link'] . '"> <img src="' . $info['logo_url'] . '" style="width:75px; height:75px; margin-right:8px;"> </a> </td> <td><div> <h3 style="float:left;padding:0 !important;"> <span style="padding-left: 22px; background:url(\'' . $info['icon_url'] . '\') no-repeat left center;"> ' . $info['name'] . ' </span> </h3> <div style="font-size:0.9em;"><table cellpadding="0" cellspacing="0"> <tr> <td><b>App ID:</b></td> <td style="padding:0 14px;"><a href="' . $info['link'] . '">' . $id . '</a></td> </tr> <tr> <td><b>App creator:</b></td> <td style="padding:0 14px;">' . $creatorLink . '</td> </td> <tr> <td colspan="2" style="font-size:0.95em"> <a href="https://developers.facebook.com/apps/' . $id . '/summary">(Edit settings)</a> </td> </tr> </table></div> </div></td> </tr> </table> ' . wfMsgWikiHtml('facebook-debug-msg') . '<br/> <table>'; // The icons we use are included in MW 1.17 (use bits.wikimedia.org if not available) if (version_compare($wgVersion, '1.17', '>=')) { $icon_base = $wgStylePath; } else { $icon_base = 'http://bits.wikimedia.org/skins-1.18'; } $icons = array('ok' => array('tooltip' => 'OK', 'src' => $icon_base . '/common/images/tick-32.png'), 'warning' => array('tooltip' => 'Click to update', 'src' => $icon_base . '/common/images/warning-32.png'), 'error' => array('tooltip' => 'Click to update', 'src' => $icon_base . '/common/images/critical-32.png')); // Render each setting field of the application as a table row foreach ($field_array as $item) { $field = $item[0]; // field_name $title = $item[1]; // Display name $tip = $item[2]; // Description $correct = $item[3]; // Suggested value if ($field == 'app_domains') { continue; } // TODO: $field is an array and involves wildcards $icon = false; if ($correct != '') { if ($info[$field] == $correct) { $icon = 'ok'; } else { switch ($field) { // Critical errors case 'namespace': case 'deauth_callback_url': case 'privacy_policy_url': // Necessary per Facebook's TOS // Necessary per Facebook's TOS case 'user_support_email': // Required: https://developers.facebook.com/blog/post/630/ $icon = 'error'; break; default: $icon = 'warning'; } } } // If the field's value came from a message, link to the message in NS_MEDIAWIKI foreach ($fields_with_msgs as $field_name => $msg_name) { if ($field == $field_name) { $title = '<a href="' . Title::newFromText($fields_with_msgs[$field], NS_MEDIAWIKI)->getFullURL() . '">' . $title . '</a>'; break; } } // Also, if the message is a page name, link to the page (in red) if it doesn't exist if ($field == 'privacy_policy_url' || $field == 'terms_of_service_url') { $titleObj = Title::newFromText(wfMsg($fields_with_msgs[$field])); // Don't add a link to an empty $info[$field] if (!$titleObj->exists() && $info[$field] != '') { $info[$field] = '<a href="' . $titleObj->getFullURL() . '" class="new">' . $info[$field] . '</a>'; } } // Placeholder indicating particular field is empty if ($info[$field] == '') { $info[$field] = '<em>empty</em>'; } // Generate the html for the row $html .= ' <tr> <td style="text-align:right; padding:0;"> ' . ($tip == '' ? '' : '<img class="mw-facebook-tip" id="facebook-tip-' . $field . '" src="' . $wgStylePath . '/common/images/tooltip_icon.png" title="' . $tip . '" /> ') . ' <b>' . $title . ':</b> </td> <td class="facebook-field" id="facebook-field-' . $field . '" style="padding:0 0 0 16px; height:22px;"> <div class="facebook-field-current"> <span>' . $info[$field] . '</span> ' . ($icon ? ' ' . ($icon != 'ok' ? '<a href="#">' : '') . '<img src="' . $icons[$icon]['src'] . '" style="width:22px; height:22px;" title="' . $icons[$icon]['tooltip'] . '" />' . ($icon != 'ok' ? '</a>' : '') : '') . ' </div>' . ($icon ? ' <div class="facebook-field-' . $icon . '" style="display:none;"> <span>' . $correct . '</span> <img src="' . $icons['ok']['src'] . '" style="width:22px; height:22px;" title="' . $icons['ok']['tooltip'] . ' " /> </div>' : '') . ' </td> </tr>'; } $html .= ' </table><br/>'; // Add an option to debug Open Graph objects $html .= ' <form action="' . $this->getTitle('Debug')->getLocalUrl() . '" method="POST" style="padding-left:14px;"> <h3>' . wfMsg('facebook-object-debug-title') . '</h3> <label for="wpPageName"><p>' . wfMsg('facebook-object-debug') . '</p></label> <input name="wpPageName" id="wpPageName" size="42" value="" style="font-size:1.75em;" /> <input type="submit" value="' . wfMsg('facebook-debug') . '" name="Debug" /> </form>'; $html .= "\n<br/><br/>\n"; $wgOut->addHTML($html); }