Exemplo n.º 1
0
 /**
  * Backwards compatibility for MediaWiki < 1.17.
  * 
  * This hook was added in MediaWiki 1.14. If we are not 1.14 or later, this
  * function is called from BeforePageDisplay via MGVS_hack() to retain
  * backward compatibility.
  * 
  * And then this hook was deprecated in 1.17, so it calls the new hook.
  */
 public static function MakeGlobalVariablesScript(&$vars)
 {
     global $wgVersion, $wgUser;
     if (version_compare($wgVersion, '1.17', '<')) {
         self::ResourceLoaderGetConfigVars($vars);
         unset($vars['fbScript']);
         // Made obsolete by ResourceLoader
     }
     // We want fbAppAccessToken to be set here instead of loaded through
     // ResourceLoader. I forget why this is the case, unfortunately.
     global $wgFbAllowDebug;
     if (!empty($wgFbAllowDebug)) {
         $title = $wgUser->getSkin()->getTitle();
         if ($title instanceof Title && SpecialPage::getTitleFor('Connect', 'Debug')->equals($title)) {
             $app = new FacebookApplication();
             if ($app->canEdit()) {
                 global $wgFbAppId, $wgFbSecret;
                 $vars['fbAppAccessToken'] = $wgFbAppId . '|' . $wgFbSecret;
             }
         }
     }
     return true;
 }
 /**
  * Requests info about the application from Facebook.
  * 
  * The 'id' field will always be returned. If there was an error, this will
  * be the only field in the returned array.
  */
 public function getInfo()
 {
     if (empty(self::$info)) {
         global $facebook;
         // Generate an array of the fields we wish to fetch
         $fields = array('name', 'link', 'description', 'icon_url', 'logo_url', 'daily_active_users', 'weekly_active_users', 'monthly_active_users', 'namespace', 'app_domains', 'auth_dialog_description', 'auth_dialog_headline', 'auth_dialog_perms_explanation', 'contact_email', 'creator_uid', 'deauth_callback_url', 'privacy_policy_url', 'terms_of_service_url', 'user_support_email', 'website_url');
         // Calls to an app's properties must be made with an app access token
         // https://developers.facebook.com/docs/reference/api/application/#application_access_tokens
         $user_access_token = $facebook->getAccessToken();
         $facebook->setAccessToken($this->id . '|' . $this->secret);
         try {
             self::$info = $facebook->api("/{$this->id}?fields=" . implode(',', $fields));
             // Fill in missing fields with false values
             foreach ($fields as $field) {
                 if (!isset(self::$info[$field])) {
                     self::$info[$field] = false;
                 }
             }
         } catch (FacebookApiException $e) {
             error_log($e->getMessage());
             self::$info = array('id' => $this->id);
         }
         // Restore the user access_token
         $facebook->setAccessToken($user_access_token);
     }
     return self::$info;
 }
    /**
     * 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 . '" /> &nbsp;') . '
			<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 ? '&nbsp; ' . ($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>
				&nbsp; <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;" /> &nbsp;
	<input type="submit" value="' . wfMsg('facebook-debug') . '" name="Debug" />
</form>';
        $html .= "\n<br/><br/>\n";
        $wgOut->addHTML($html);
    }