forked from GNUsocial/gnu-social
		
	Merge branch 'testing' of git@gitorious.org:statusnet/mainline into testing
This commit is contained in:
		| @@ -294,6 +294,9 @@ class NewnoticeAction extends Action | ||||
|             if ($profile) { | ||||
|                 $content = '@' . $profile->nickname . ' '; | ||||
|             } | ||||
|         } else { | ||||
|             // @fixme most of these bits above aren't being passed on above | ||||
|             $inreplyto = null; | ||||
|         } | ||||
|  | ||||
|         $notice_form = new NoticeForm($this, '', $content, null, $inreplyto); | ||||
|   | ||||
| @@ -425,8 +425,6 @@ class Action extends HTMLOutputter // lawsuit | ||||
|             $connect = 'imsettings'; | ||||
|         } else if (common_config('sms', 'enabled')) { | ||||
|             $connect = 'smssettings'; | ||||
|         } else if (common_config('twitter', 'enabled')) { | ||||
|             $connect = 'twittersettings'; | ||||
|         } | ||||
|  | ||||
|         $this->elementStart('dl', array('id' => 'site_nav_global_primary')); | ||||
|   | ||||
| @@ -177,8 +177,8 @@ $default = | ||||
|         array('source' => 'StatusNet', # source attribute for Twitter | ||||
|               'taguri' => null), # base for tag URIs | ||||
|         'twitter' => | ||||
|         array('enabled'       => true, | ||||
|               'consumer_key'    => null, | ||||
|         array('signin' => true, | ||||
|               'consumer_key' => null, | ||||
|               'consumer_secret' => null), | ||||
|         'cache' => | ||||
|         array('base' => null), | ||||
|   | ||||
							
								
								
									
										24
									
								
								lib/util.php
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								lib/util.php
									
									
									
									
									
								
							| @@ -809,8 +809,28 @@ function common_shorten_links($text) | ||||
|  | ||||
| function common_xml_safe_str($str) | ||||
| { | ||||
|     // Neutralize control codes and surrogates | ||||
| 	return preg_replace('/[\p{Cc}\p{Cs}]/u', '*', $str); | ||||
|     // Replace common eol and extra whitespace input chars | ||||
|     $unWelcome = array( | ||||
|         "\t",  // tab | ||||
|         "\n",  // newline | ||||
|         "\r",  // cr | ||||
|         "\0",  // null byte eos | ||||
|         "\x0B" // vertical tab | ||||
|     ); | ||||
|  | ||||
|     $replacement = array( | ||||
|         ' ', // single space | ||||
|         ' ', | ||||
|         '',  // nothing | ||||
|         '', | ||||
|         ' ' | ||||
|     ); | ||||
|  | ||||
|     $str = str_replace($unWelcome, $replacement, $str); | ||||
|  | ||||
|     // Neutralize any additional control codes and UTF-16 surrogates | ||||
|     // (Twitter uses '*') | ||||
|     return preg_replace('/[\p{Cc}\p{Cs}]/u', '*', $str); | ||||
| } | ||||
|  | ||||
| function common_tag_link($tag) | ||||
|   | ||||
| @@ -22,7 +22,7 @@ | ||||
|  * @category  Plugin | ||||
|  * @package   StatusNet | ||||
|  * @author    Zach Copley <zach@status.net> | ||||
|  * @copyright 2009 StatusNet, Inc. | ||||
|  * @copyright 2009-2010 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/ | ||||
|  */ | ||||
| @@ -32,12 +32,12 @@ if (!defined('STATUSNET')) { | ||||
| } | ||||
|  | ||||
| define("FACEBOOK_CONNECT_SERVICE", 3); | ||||
| define('FACEBOOKPLUGIN_VERSION', '0.9'); | ||||
|  | ||||
| require_once INSTALLDIR . '/plugins/Facebook/facebookutil.php'; | ||||
|  | ||||
| /** | ||||
|  * Facebook plugin to add a StatusNet Facebook application | ||||
|  * Facebook plugin to add a StatusNet Facebook canvas application | ||||
|  * and allow registration and authentication via Facebook Connect | ||||
|  * | ||||
|  * @category Plugin | ||||
|  * @package  StatusNet | ||||
| @@ -49,6 +49,36 @@ require_once INSTALLDIR . '/plugins/Facebook/facebookutil.php'; | ||||
| class FacebookPlugin extends Plugin | ||||
| { | ||||
|  | ||||
|     const VERSION = STATUSNET_VERSION; | ||||
|  | ||||
|     /** | ||||
|      * Initializer for the plugin. | ||||
|      */ | ||||
|  | ||||
|     function initialize() | ||||
|     { | ||||
|         // Allow the key and secret to be passed in | ||||
|         // Control panel will override | ||||
|  | ||||
|         if (isset($this->apikey)) { | ||||
|             $key = common_config('facebook', 'apikey'); | ||||
|             if (empty($key)) { | ||||
|                 Config::save('facebook', 'apikey', $this->apikey); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (isset($this->secret)) { | ||||
|             $secret = common_config('facebook', 'secret'); | ||||
|             if (empty($secret)) { | ||||
|                 Config::save( | ||||
|                     'facebook', | ||||
|                     'secret', | ||||
|                     $this->secret | ||||
|                 ); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Add Facebook app actions to the router table | ||||
|      * | ||||
| @@ -70,6 +100,7 @@ class FacebookPlugin extends Plugin | ||||
|                     array('action' => 'facebooksettings')); | ||||
|         $m->connect('facebook/app/invite.php', array('action' => 'facebookinvite')); | ||||
|         $m->connect('facebook/app/remove', array('action' => 'facebookremove')); | ||||
|         $m->connect('admin/facebook', array('action' => 'facebookadminpanel')); | ||||
|  | ||||
|         // Facebook Connect stuff | ||||
|  | ||||
| @@ -98,6 +129,7 @@ class FacebookPlugin extends Plugin | ||||
|         case 'FacebookinviteAction': | ||||
|         case 'FacebookremoveAction': | ||||
|         case 'FacebooksettingsAction': | ||||
|         case 'FacebookadminpanelAction': | ||||
|             include_once INSTALLDIR . '/plugins/Facebook/' . | ||||
|               strtolower(mb_substr($cls, 0, -6)) . '.php'; | ||||
|             return false; | ||||
| @@ -122,6 +154,32 @@ class FacebookPlugin extends Plugin | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Add a Facebook tab to the admin panels | ||||
|      * | ||||
|      * @param Widget $nav Admin panel nav | ||||
|      * | ||||
|      * @return boolean hook value | ||||
|      */ | ||||
|  | ||||
|     function onEndAdminPanelNav($nav) | ||||
|     { | ||||
|         if (AdminPanelAction::canAdmin('facebook')) { | ||||
|  | ||||
|             $action_name = $nav->action->trimmed('action'); | ||||
|  | ||||
|             $nav->out->menuItem( | ||||
|                 common_local_url('facebookadminpanel'), | ||||
|                 _m('Facebook'), | ||||
|                 _m('Facebook integration configuration'), | ||||
|                 $action_name == 'facebookadminpanel', | ||||
|                 'nav_facebook_admin_panel' | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Override normal HTML output to force the content type to | ||||
|      * text/html and add in xmlns:fb | ||||
| @@ -359,8 +417,6 @@ class FacebookPlugin extends Plugin | ||||
|             $connect = 'imsettings'; | ||||
|         } else if (common_config('sms', 'enabled')) { | ||||
|             $connect = 'smssettings'; | ||||
|         } else if (common_config('twitter', 'enabled')) { | ||||
|             $connect = 'twittersettings'; | ||||
|         } | ||||
|  | ||||
|         if (!empty($user)) { | ||||
| @@ -525,15 +581,18 @@ class FacebookPlugin extends Plugin | ||||
|  | ||||
|     function onPluginVersion(&$versions) | ||||
|     { | ||||
|         $versions[] = array('name' => 'Facebook', | ||||
|                             'version' => FACEBOOKPLUGIN_VERSION, | ||||
|                             'author' => 'Zach Copley', | ||||
|                             'homepage' => 'http://status.net/wiki/Plugin:Facebook', | ||||
|                             'rawdescription' => | ||||
|                             _m('The Facebook plugin allows you to integrate ' . | ||||
|                                'your StatusNet instance with ' . | ||||
|                                '<a href="http://facebook.com/">Facebook</a> ' . | ||||
|                                'and Facebook Connect.')); | ||||
|         $versions[] = array( | ||||
|             'name' => 'Facebook', | ||||
|             'version' => self::VERSION, | ||||
|             'author' => 'Zach Copley', | ||||
|             'homepage' => 'http://status.net/wiki/Plugin:Facebook', | ||||
|             'rawdescription' => _m( | ||||
|                 'The Facebook plugin allows you to integrate ' . | ||||
|                 'your StatusNet instance with ' . | ||||
|                 '<a href="http://facebook.com/">Facebook</a> ' . | ||||
|                 'and Facebook Connect.' | ||||
|             ) | ||||
|         ); | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|   | ||||
							
								
								
									
										223
									
								
								plugins/Facebook/facebookadminpanel.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										223
									
								
								plugins/Facebook/facebookadminpanel.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,223 @@ | ||||
| <?php | ||||
| /** | ||||
|  * StatusNet, the distributed open-source microblogging tool | ||||
|  * | ||||
|  * Facebook integration administration panel | ||||
|  * | ||||
|  * PHP version 5 | ||||
|  * | ||||
|  * LICENCE: This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU Affero General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU Affero General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Affero General Public License | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * @category  Settings | ||||
|  * @package   StatusNet | ||||
|  * @author    Zach Copley <zach@status.net> | ||||
|  * @copyright 2010 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/ | ||||
|  */ | ||||
|  | ||||
| if (!defined('STATUSNET')) { | ||||
|     exit(1); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Administer global Facebook integration settings | ||||
|  * | ||||
|  * @category Admin | ||||
|  * @package  StatusNet | ||||
|  * @author   Zach Copley <zach@status.net> | ||||
|  * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 | ||||
|  * @link     http://status.net/ | ||||
|  */ | ||||
|  | ||||
| class FacebookadminpanelAction extends AdminPanelAction | ||||
| { | ||||
|     /** | ||||
|      * Returns the page title | ||||
|      * | ||||
|      * @return string page title | ||||
|      */ | ||||
|  | ||||
|     function title() | ||||
|     { | ||||
|         return _m('Facebook'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Instructions for using this form. | ||||
|      * | ||||
|      * @return string instructions | ||||
|      */ | ||||
|  | ||||
|     function getInstructions() | ||||
|     { | ||||
|         return _m('Facebook integration settings'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Show the Facebook admin panel form | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|  | ||||
|     function showForm() | ||||
|     { | ||||
|         $form = new FacebookAdminPanelForm($this); | ||||
|         $form->show(); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Save settings from the form | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|  | ||||
|     function saveSettings() | ||||
|     { | ||||
|         static $settings = array( | ||||
|             'facebook'     => array('apikey', 'secret'), | ||||
|         ); | ||||
|  | ||||
|         $values = array(); | ||||
|  | ||||
|         foreach ($settings as $section => $parts) { | ||||
|             foreach ($parts as $setting) { | ||||
|                 $values[$section][$setting] | ||||
|                     = $this->trimmed($setting); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // This throws an exception on validation errors | ||||
|  | ||||
|         $this->validate($values); | ||||
|  | ||||
|         // assert(all values are valid); | ||||
|  | ||||
|         $config = new Config(); | ||||
|  | ||||
|         $config->query('BEGIN'); | ||||
|  | ||||
|         foreach ($settings as $section => $parts) { | ||||
|             foreach ($parts as $setting) { | ||||
|                 Config::save($section, $setting, $values[$section][$setting]); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $config->query('COMMIT'); | ||||
|  | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     function validate(&$values) | ||||
|     { | ||||
|         // Validate consumer key and secret (can't be too long) | ||||
|  | ||||
|         if (mb_strlen($values['facebook']['apikey']) > 255) { | ||||
|             $this->clientError( | ||||
|                 _m("Invalid Facebook API key. Max length is 255 characters.") | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         if (mb_strlen($values['facebook']['secret']) > 255) { | ||||
|             $this->clientError( | ||||
|                 _m("Invalid Facebook API secret. Max length is 255 characters.") | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| class FacebookAdminPanelForm extends AdminForm | ||||
| { | ||||
|     /** | ||||
|      * ID of the form | ||||
|      * | ||||
|      * @return int ID of the form | ||||
|      */ | ||||
|  | ||||
|     function id() | ||||
|     { | ||||
|         return 'facebookadminpanel'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * class of the form | ||||
|      * | ||||
|      * @return string class of the form | ||||
|      */ | ||||
|  | ||||
|     function formClass() | ||||
|     { | ||||
|         return 'form_settings'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Action of the form | ||||
|      * | ||||
|      * @return string URL of the action | ||||
|      */ | ||||
|  | ||||
|     function action() | ||||
|     { | ||||
|         return common_local_url('facebookadminpanel'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Data elements of the form | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|  | ||||
|     function formData() | ||||
|     { | ||||
|         $this->out->elementStart( | ||||
|             'fieldset', | ||||
|             array('id' => 'settings_facebook-application') | ||||
|         ); | ||||
|         $this->out->element('legend', null, _m('Facebook application settings')); | ||||
|         $this->out->elementStart('ul', 'form_data'); | ||||
|  | ||||
|         $this->li(); | ||||
|         $this->input( | ||||
|             'apikey', | ||||
|             _m('API key'), | ||||
|             _m('API key provided by Facebook'), | ||||
|             'facebook' | ||||
|         ); | ||||
|         $this->unli(); | ||||
|  | ||||
|         $this->li(); | ||||
|         $this->input( | ||||
|             'secret', | ||||
|              _m('Secret'), | ||||
|             _m('API secret provided by Facebook'), | ||||
|             'facebook' | ||||
|         ); | ||||
|         $this->unli(); | ||||
|  | ||||
|         $this->out->elementEnd('ul'); | ||||
|         $this->out->elementEnd('fieldset'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Action elements | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|  | ||||
|     function formActions() | ||||
|     { | ||||
|         $this->out->submit('submit', _('Save'), 'submit', null, _('Save Facebook settings')); | ||||
|     } | ||||
| } | ||||
| @@ -312,8 +312,6 @@ class MobileProfilePlugin extends WAP20Plugin | ||||
|             $connect = 'imsettings'; | ||||
|         } else if (common_config('sms', 'enabled')) { | ||||
|             $connect = 'smssettings'; | ||||
|         } else if (common_config('twitter', 'enabled')) { | ||||
|             $connect = 'twittersettings'; | ||||
|         } | ||||
|  | ||||
|         $action->elementStart('ul', array('id' => 'site_nav_global_primary')); | ||||
|   | ||||
| @@ -222,31 +222,62 @@ class OStatusPlugin extends Plugin | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      * Find any explicit remote mentions. Accepted forms: | ||||
|      *   Webfinger: @user@example.com | ||||
|      *   Profile link: @example.com/mublog/user | ||||
|      * @param Profile $sender (os user?) | ||||
|      * @param string $text input markup text | ||||
|      * @param array &$mention in/out param: set of found mentions | ||||
|      * @return boolean hook return value | ||||
|      */ | ||||
|  | ||||
|     function onEndFindMentions($sender, $text, &$mentions) | ||||
|     { | ||||
|         preg_match_all('/(?:^|\s+)@((?:\w+\.)*\w+@(?:\w+\.)*\w+(?:\w+\-\w+)*\.\w+)/', | ||||
|         preg_match_all('!(?:^|\s+) | ||||
|                         @(                                # Webfinger: | ||||
|                           (?:\w+\.)*\w+                   #   user | ||||
|                           @                               #   @ | ||||
|                           (?:\w+\.)*\w+(?:\w+\-\w+)*\.\w+ #   domain | ||||
|                          |                                # Profile: | ||||
|                           (?:\w+\.)*\w+(?:\w+\-\w+)*\.\w+ #   domain | ||||
|                           (?:/\w+)+                       #   /path1(/path2...) | ||||
|                          )!x', | ||||
|                        $text, | ||||
|                        $wmatches, | ||||
|                        PREG_OFFSET_CAPTURE); | ||||
|  | ||||
|         foreach ($wmatches[1] as $wmatch) { | ||||
|             $target = $wmatch[0]; | ||||
|             $oprofile = null; | ||||
|  | ||||
|             $webfinger = $wmatch[0]; | ||||
|  | ||||
|             $this->log(LOG_INFO, "Checking Webfinger for address '$webfinger'"); | ||||
|  | ||||
|             $oprofile = Ostatus_profile::ensureWebfinger($webfinger); | ||||
|             if (strpos($target, '/') === false) { | ||||
|                 $this->log(LOG_INFO, "Checking Webfinger for address '$target'"); | ||||
|                 try { | ||||
|                     $oprofile = Ostatus_profile::ensureWebfinger($target); | ||||
|                 } catch (Exception $e) { | ||||
|                     $this->log(LOG_ERR, "Webfinger check failed: " . $e->getMessage()); | ||||
|                 } | ||||
|             } else { | ||||
|                 $schemes = array('https', 'http'); | ||||
|                 foreach ($schemes as $scheme) { | ||||
|                     $url = "$scheme://$target"; | ||||
|                     $this->log(LOG_INFO, "Checking profile address '$url'"); | ||||
|                     try { | ||||
|                         $oprofile = Ostatus_profile::ensureProfile($url); | ||||
|                         if ($oprofile) { | ||||
|                             continue; | ||||
|                         } | ||||
|                     } catch (Exception $e) { | ||||
|                         $this->log(LOG_ERR, "Profile check failed: " . $e->getMessage()); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if (empty($oprofile)) { | ||||
|  | ||||
|                 $this->log(LOG_INFO, "No Ostatus_profile found for address '$webfinger'"); | ||||
|  | ||||
|                 $this->log(LOG_INFO, "No Ostatus_profile found for address '$target'"); | ||||
|             } else { | ||||
|  | ||||
|                 $this->log(LOG_INFO, "Ostatus_profile found for address '$webfinger'"); | ||||
|                 $this->log(LOG_INFO, "Ostatus_profile found for address '$target'"); | ||||
|  | ||||
|                 if ($oprofile->isGroup()) { | ||||
|                     continue; | ||||
| @@ -261,7 +292,7 @@ class OStatusPlugin extends Plugin | ||||
|                     } | ||||
|                 } | ||||
|                 $mentions[] = array('mentioned' => array($profile), | ||||
|                                     'text' => $wmatch[0], | ||||
|                                     'text' => $target, | ||||
|                                     'position' => $pos, | ||||
|                                     'url' => $profile->profileurl); | ||||
|             } | ||||
|   | ||||
| @@ -104,7 +104,7 @@ class PushHubAction extends Action | ||||
|             throw new ClientException("Invalid hub.secret $secret; must be under 200 bytes."); | ||||
|         } | ||||
|  | ||||
|         $sub = HubSub::staticGet($sub->topic, $sub->callback); | ||||
|         $sub = HubSub::staticGet($topic, $callback); | ||||
|         if (!$sub) { | ||||
|             // Creating a new one! | ||||
|             $sub = new HubSub(); | ||||
|   | ||||
| @@ -260,9 +260,15 @@ class HubSub extends Memcached_DataObject | ||||
|             $retries = intval(common_config('ostatus', 'hub_retries')); | ||||
|         } | ||||
|  | ||||
|         $data = array('sub' => clone($this), | ||||
|         // We dare not clone() as when the clone is discarded it'll | ||||
|         // destroy the result data for the parent query. | ||||
|         // @fixme use clone() again when it's safe to copy an | ||||
|         // individual item from a multi-item query again. | ||||
|         $sub = HubSub::staticGet($this->topic, $this->callback); | ||||
|         $data = array('sub' => $sub, | ||||
|                       'atom' => $atom, | ||||
|                       'retries' => $retries); | ||||
|         common_log(LOG_INFO, "Queuing PuSH: $this->topic to $this->callback"); | ||||
|         $qm = QueueManager::get(); | ||||
|         $qm->enqueue($data, 'hubout'); | ||||
|     } | ||||
|   | ||||
| @@ -146,8 +146,10 @@ class Magicsig extends Memcached_DataObject | ||||
|          | ||||
|         $mod = base64_url_decode($matches[1]); | ||||
|         $exp = base64_url_decode($matches[2]); | ||||
|         if ($matches[4]) { | ||||
|         if (!empty($matches[4])) { | ||||
|             $private_exp = base64_url_decode($matches[4]); | ||||
|         } else { | ||||
|             $private_exp = false; | ||||
|         } | ||||
|  | ||||
|         $params['public_key'] = new Crypt_RSA_KEY($mod, $exp, 'public'); | ||||
|   | ||||
| @@ -698,7 +698,7 @@ class Ostatus_profile extends Memcached_DataObject | ||||
|     { | ||||
|         // Get the canonical feed URI and check it | ||||
|         $discover = new FeedDiscovery(); | ||||
|         if ($hints['feedurl']) { | ||||
|         if (isset($hints['feedurl'])) { | ||||
|             $feeduri = $hints['feedurl']; | ||||
|             $feeduri = $discover->discoverFromFeedURL($feeduri); | ||||
|         } else { | ||||
| @@ -1145,7 +1145,7 @@ class Ostatus_profile extends Memcached_DataObject | ||||
|  | ||||
|         if (!empty($poco)) { | ||||
|             $url = $poco->getPrimaryURL(); | ||||
|             if ($url->type == 'homepage') { | ||||
|             if ($url && $url->type == 'homepage') { | ||||
|                 $homepage = $url->value; | ||||
|             } | ||||
|         } | ||||
|   | ||||
| @@ -94,7 +94,7 @@ class Discovery | ||||
|             $links = call_user_func(array($class, 'discover'), $uri); | ||||
|             if ($link = Discovery::getService($links, Discovery::LRDD_REL)) { | ||||
|                 // Load the LRDD XRD | ||||
|                 if ($link['template']) { | ||||
|                 if (!empty($link['template'])) { | ||||
|                     $xrd_uri = Discovery::applyTemplate($link['template'], $uri); | ||||
|                 } else { | ||||
|                     $xrd_uri = $link['href']; | ||||
|   | ||||
| @@ -53,17 +53,22 @@ class XRD | ||||
|         $xrd = new XRD(); | ||||
|  | ||||
|         $dom = new DOMDocument(); | ||||
|         $dom->loadXML($xml); | ||||
|         if (!$dom->loadXML($xml)) { | ||||
|             throw new Exception("Invalid XML"); | ||||
|         } | ||||
|         $xrd_element = $dom->getElementsByTagName('XRD')->item(0); | ||||
|  | ||||
|         // Check for host-meta host | ||||
|         $host = $xrd_element->getElementsByTagName('Host')->item(0)->nodeValue; | ||||
|         $host = $xrd_element->getElementsByTagName('Host')->item(0); | ||||
|         if ($host) { | ||||
|             $xrd->host = $host; | ||||
|             $xrd->host = $host->nodeValue; | ||||
|         } | ||||
|  | ||||
|         // Loop through other elements | ||||
|         foreach ($xrd_element->childNodes as $node) { | ||||
|             if (!($node instanceof DOMElement)) { | ||||
|                 continue; | ||||
|             } | ||||
|             switch ($node->tagName) { | ||||
|             case 'Expires': | ||||
|                 $xrd->expires = $node->nodeValue; | ||||
| @@ -156,20 +161,20 @@ class XRD | ||||
|     function saveLink($doc, $link) | ||||
|     { | ||||
|         $link_element = $doc->createElement('Link'); | ||||
|         if ($link['rel']) { | ||||
|         if (!empty($link['rel'])) { | ||||
|             $link_element->setAttribute('rel', $link['rel']); | ||||
|         } | ||||
|         if ($link['type']) { | ||||
|         if (!empty($link['type'])) { | ||||
|             $link_element->setAttribute('type', $link['type']); | ||||
|         } | ||||
|         if ($link['href']) { | ||||
|         if (!empty($link['href'])) { | ||||
|             $link_element->setAttribute('href', $link['href']); | ||||
|         } | ||||
|         if ($link['template']) { | ||||
|         if (!empty($link['template'])) { | ||||
|             $link_element->setAttribute('template', $link['template']); | ||||
|         } | ||||
|  | ||||
|         if (is_array($link['title'])) { | ||||
|         if (!empty($link['title']) && is_array($link['title'])) { | ||||
|             foreach($link['title'] as $title) { | ||||
|                 $title = $doc->createElement('Title', $title); | ||||
|                 $link_element->appendChild($title); | ||||
|   | ||||
| @@ -1,47 +1,89 @@ | ||||
| Twitter Bridge Plugin | ||||
| ===================== | ||||
|  | ||||
| This Twitter "bridge" plugin allows you to integrate your StatusNet | ||||
| instance with Twitter.  Installing it will allow your users to: | ||||
|  | ||||
|     - automatically post notices to thier Twitter accounts | ||||
|     - automatically post notices to their Twitter accounts | ||||
|     - automatically subscribe to other Twitter users who are also using | ||||
|       your StatusNet install, if possible (requires running a daemon) | ||||
|     - import their Twitter friends' tweets (requires running a daemon) | ||||
|     - allow users to authenticate using Twitter ('Sign in with Twitter') | ||||
|  | ||||
| Installation | ||||
| ------------ | ||||
|  | ||||
| To enable the plugin, add the following to your config.php: | ||||
|  | ||||
|     addPlugin("TwitterBridge"); | ||||
|  | ||||
| OAuth is used to to access protected resources on Twitter (as opposed to | ||||
| HTTP Basic Auth)*.  To use Twitter bridging you will need to register | ||||
| your instance of StatusNet as an application on Twitter | ||||
| (http://twitter.com/apps), and update the following variables in your | ||||
| config.php with the consumer key and secret Twitter generates for you: | ||||
|  | ||||
|     $config['twitter']['consumer_key']    = 'YOURKEY'; | ||||
|     $config['twitter']['consumer_secret'] = 'YOURSECRET'; | ||||
| OAuth 1.0a (http://oauth.net) is used to to access protected resources | ||||
| on Twitter (as opposed to HTTP Basic Auth)*.  To use Twitter bridging | ||||
| you will need to register your instance of StatusNet as an application | ||||
| on Twitter (http://twitter.com/apps).  During the application | ||||
| registration process your application will be assigned a "consumer" key | ||||
| and secret, which the plugin will use to make OAuth requests to Twitter. | ||||
| You can either pass the consumer key and secret in when you enable the | ||||
| plugin, or set it using the Twitter administration panel. | ||||
|  | ||||
| When registering your application with Twitter set the type to "Browser" | ||||
| and your Callback URL to: | ||||
|  | ||||
|     http://example.org/mublog/twitter/authorization | ||||
|  | ||||
| The default access type should be, "Read & Write". | ||||
| (Change "example.org" to your site domain and "mublog" to your site | ||||
| path.) | ||||
|  | ||||
| The default access type should be "Read & Write". | ||||
|  | ||||
| To enable the plugin, add the following to your config.php: | ||||
|  | ||||
|     addPlugin( | ||||
|         'TwitterBridge', | ||||
|         array( | ||||
|             'consumer_key'    => 'YOUR_CONSUMER_KEY', | ||||
|             'consumer_secret' => 'YOUR_CONSUMER_SECRET' | ||||
|         ) | ||||
|     ); | ||||
|  | ||||
| * Note: The plugin will still push notices to Twitter for users who | ||||
|   have previously setup the Twitter bridge using their Twitter name and | ||||
|   password under an older versions of StatusNet, but all new Twitter | ||||
|   have previously set up the Twitter bridge using their Twitter name and | ||||
|   password under an older version of StatusNet, but all new Twitter | ||||
|   bridge connections will use OAuth. | ||||
|  | ||||
| Deamons | ||||
| Administration panel | ||||
| -------------------- | ||||
|  | ||||
| As of StatusNet 0.9.0 there is a new administration panel that allows | ||||
| you to configure Twitter bridge settings within StatusNet itself, | ||||
| instead of having to specify them manually in your config.php.  To enable | ||||
| the administration panel, you will need to add it to the list of active | ||||
| administration panels.  You can do this via your config.php. E.g.: | ||||
|  | ||||
|     $config['admin']['panels'][] = 'twitter'; | ||||
|  | ||||
| And to access it, you'll need to use a user with the "administrator" | ||||
| role (see: scripts/userrole.php). | ||||
|  | ||||
| Sign in with Twitter | ||||
| -------------------- | ||||
|  | ||||
| With 0.9.0, StatusNet optionally allows users to register and | ||||
| authenticate using their Twitter credentials via the "Sign in with | ||||
| Twitter" pattern described here: | ||||
|  | ||||
|     http://apiwiki.twitter.com/Sign-in-with-Twitter | ||||
|  | ||||
| The option is _on_ by default when you install the plugin, but it can | ||||
| disabled via the Twitter bridge administration panel, or by adding the | ||||
| following line to your config.php: | ||||
|  | ||||
|     $config['twitter']['signin'] = false; | ||||
|  | ||||
| Daemons | ||||
| ------- | ||||
|  | ||||
| For friend syncing and importing notices running two additional daemon | ||||
| scripts is necessary (synctwitterfriends.php and | ||||
| twitterstatusfetcher.php). | ||||
| For friend syncing and importing Twitter tweets, running two | ||||
| additional daemon scripts is necessary: synctwitterfriends.php and | ||||
| twitterstatusfetcher.php. | ||||
|  | ||||
| In the daemons subidrectory of the plugin are three scripts: | ||||
| In the daemons subdirectory of the plugin are three scripts: | ||||
|  | ||||
| * Twitter Friends Syncing (daemons/synctwitterfriends.php) | ||||
|  | ||||
| @@ -51,13 +93,13 @@ subscribe to "friends" (people they "follow") on Twitter who also have | ||||
| accounts on your StatusNet system, and who have previously set up a link | ||||
| for automatically posting notices to Twitter. | ||||
|  | ||||
| The plugin will try to start this daemon when you run | ||||
| scripts/startdaemons.sh. | ||||
| The plugin will start this daemon when you run scripts/startdaemons.sh. | ||||
|  | ||||
| * Importing statuses from Twitter (daemons/twitterstatusfetcher.php) | ||||
|  | ||||
| To allow your users to import their friends' Twitter statuses, you will | ||||
| need to enable the bidirectional Twitter bridge in your config.php: | ||||
| You can allow uses to enable importing of your friends' Twitter | ||||
| timelines either in the Twitter bridge administration panel or in your | ||||
| config.php using the following configuration line: | ||||
|  | ||||
|     $config['twitterimport']['enabled'] = true; | ||||
|  | ||||
| @@ -66,8 +108,9 @@ other daemons when you run scripts/startdaemons.sh. | ||||
|  | ||||
| Additionally, you will want to set the integration source variable, | ||||
| which will keep notices posted to Twitter via StatusNet from looping | ||||
| back.  The integration source should be set to the name of your | ||||
| application, exactly as you specified it on the settings page for your | ||||
| back.  You can do this in the Twitter bridge administration panel, or | ||||
| via config.php. The integration source should be set to the name of your | ||||
| application _exactly_ as you specified it on the settings page for your | ||||
| StatusNet application on Twitter, e.g.: | ||||
|  | ||||
|     $config['integration']['source'] = 'YourApp'; | ||||
| @@ -79,7 +122,9 @@ set up Twitter bridging. | ||||
|  | ||||
| It's not strictly necessary to run this queue handler, and sites that | ||||
| haven't enabled queuing are still able to push notices to Twitter, but | ||||
| for larger sites and sites that wish to improve performance, this | ||||
| script allows notices to be sent "offline" via a separate process. | ||||
| for larger sites and sites that wish to improve performance the script | ||||
| allows notices to be sent "offline" via a separate process. | ||||
|  | ||||
| The plugin will start this script when you run scripts/startdaemons.sh. | ||||
| StatusNet will automatically use the TwitterQueueHandler if you have | ||||
| enabled the queuing subsystem.  See the "Queues and daemons" section of | ||||
| the main README file for more information about how to do that. | ||||
|   | ||||
| @@ -23,7 +23,7 @@ | ||||
|  * @author    Julien C <chaumond@gmail.com> | ||||
|  * @copyright 2009-2010 Control Yourself, Inc. | ||||
|  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 | ||||
|  * @link      http://laconi.ca/ | ||||
|  * @link      http://status.net/ | ||||
|  */ | ||||
|  | ||||
| if (!defined('STATUSNET')) { | ||||
| @@ -32,8 +32,6 @@ if (!defined('STATUSNET')) { | ||||
|  | ||||
| require_once INSTALLDIR . '/plugins/TwitterBridge/twitter.php'; | ||||
|  | ||||
| define('TWITTERBRIDGEPLUGIN_VERSION', '0.9'); | ||||
|  | ||||
| /** | ||||
|  * Plugin for sending and importing Twitter statuses | ||||
|  * | ||||
| @@ -44,19 +42,41 @@ define('TWITTERBRIDGEPLUGIN_VERSION', '0.9'); | ||||
|  * @author   Zach Copley <zach@status.net> | ||||
|  * @author   Julien C <chaumond@gmail.com> | ||||
|  * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 | ||||
|  * @link     http://laconi.ca/ | ||||
|  * @link     http://status.net/ | ||||
|  * @link     http://twitter.com/ | ||||
|  */ | ||||
|  | ||||
| class TwitterBridgePlugin extends Plugin | ||||
| { | ||||
|  | ||||
|     const VERSION = STATUSNET_VERSION; | ||||
|  | ||||
|     /** | ||||
|      * Initializer for the plugin. | ||||
|      */ | ||||
|  | ||||
|     function __construct() | ||||
|     function initialize() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         // Allow the key and secret to be passed in | ||||
|         // Control panel will override | ||||
|  | ||||
|         if (isset($this->consumer_key)) { | ||||
|             $key = common_config('twitter', 'consumer_key'); | ||||
|             if (empty($key)) { | ||||
|                 Config::save('twitter', 'consumer_key', $this->consumer_key); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (isset($this->consumer_secret)) { | ||||
|             $secret = common_config('twitter', 'consumer_secret'); | ||||
|             if (empty($secret)) { | ||||
|                 Config::save( | ||||
|                     'twitter', | ||||
|                     'consumer_secret', | ||||
|                     $this->consumer_secret | ||||
|                 ); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -71,10 +91,17 @@ class TwitterBridgePlugin extends Plugin | ||||
|  | ||||
|     function onRouterInitialized($m) | ||||
|     { | ||||
|         $m->connect('twitter/authorization', | ||||
|                     array('action' => 'twitterauthorization')); | ||||
|         $m->connect( | ||||
|             'twitter/authorization', | ||||
|             array('action' => 'twitterauthorization') | ||||
|         ); | ||||
|         $m->connect('settings/twitter', array('action' => 'twittersettings')); | ||||
|         $m->connect('main/twitterlogin', array('action' => 'twitterlogin')); | ||||
|  | ||||
|         if (common_config('twitter', 'signin')) { | ||||
|             $m->connect('main/twitterlogin', array('action' => 'twitterlogin')); | ||||
|         } | ||||
|  | ||||
|         $m->connect('admin/twitter', array('action' => 'twitteradminpanel')); | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
| @@ -88,13 +115,16 @@ class TwitterBridgePlugin extends Plugin | ||||
|      */ | ||||
|     function onEndLoginGroupNav(&$action) | ||||
|     { | ||||
|  | ||||
|         $action_name = $action->trimmed('action'); | ||||
|  | ||||
|         $action->menuItem(common_local_url('twitterlogin'), | ||||
|                                            _('Twitter'), | ||||
|                                            _('Login or register using Twitter'), | ||||
|                                              'twitterlogin' === $action_name); | ||||
|         if (common_config('twitter', 'signin')) { | ||||
|             $action->menuItem( | ||||
|                 common_local_url('twitterlogin'), | ||||
|                 _m('Twitter'), | ||||
|                 _m('Login or register using Twitter'), | ||||
|                 'twitterlogin' === $action_name | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
| @@ -110,10 +140,12 @@ class TwitterBridgePlugin extends Plugin | ||||
|     { | ||||
|         $action_name = $action->trimmed('action'); | ||||
|  | ||||
|         $action->menuItem(common_local_url('twittersettings'), | ||||
|                           _m('Twitter'), | ||||
|                           _m('Twitter integration options'), | ||||
|                           $action_name === 'twittersettings'); | ||||
|         $action->menuItem( | ||||
|             common_local_url('twittersettings'), | ||||
|             _m('Twitter'), | ||||
|             _m('Twitter integration options'), | ||||
|             $action_name === 'twittersettings' | ||||
|         ); | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
| @@ -132,6 +164,7 @@ class TwitterBridgePlugin extends Plugin | ||||
|         case 'TwittersettingsAction': | ||||
|         case 'TwitterauthorizationAction': | ||||
|         case 'TwitterloginAction': | ||||
|         case 'TwitteradminpanelAction': | ||||
|             include_once INSTALLDIR . '/plugins/TwitterBridge/' . | ||||
|               strtolower(mb_substr($cls, 0, -6)) . '.php'; | ||||
|             return false; | ||||
| @@ -173,12 +206,18 @@ class TwitterBridgePlugin extends Plugin | ||||
|      */ | ||||
|     function onGetValidDaemons($daemons) | ||||
|     { | ||||
|         array_push($daemons, INSTALLDIR . | ||||
|                    '/plugins/TwitterBridge/daemons/synctwitterfriends.php'); | ||||
|         array_push( | ||||
|             $daemons, | ||||
|             INSTALLDIR | ||||
|             . '/plugins/TwitterBridge/daemons/synctwitterfriends.php' | ||||
|         ); | ||||
|  | ||||
|         if (common_config('twitterimport', 'enabled')) { | ||||
|             array_push($daemons, INSTALLDIR | ||||
|                 . '/plugins/TwitterBridge/daemons/twitterstatusfetcher.php'); | ||||
|             array_push( | ||||
|                 $daemons, | ||||
|                 INSTALLDIR | ||||
|                 . '/plugins/TwitterBridge/daemons/twitterstatusfetcher.php' | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
| @@ -197,17 +236,55 @@ class TwitterBridgePlugin extends Plugin | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Add a Twitter tab to the admin panel | ||||
|      * | ||||
|      * @param Widget $nav Admin panel nav | ||||
|      * | ||||
|      * @return boolean hook value | ||||
|      */ | ||||
|  | ||||
|     function onEndAdminPanelNav($nav) | ||||
|     { | ||||
|         if (AdminPanelAction::canAdmin('twitter')) { | ||||
|  | ||||
|             $action_name = $nav->action->trimmed('action'); | ||||
|  | ||||
|             $nav->out->menuItem( | ||||
|                 common_local_url('twitteradminpanel'), | ||||
|                 _m('Twitter'), | ||||
|                 _m('Twitter bridge configuration'), | ||||
|                 $action_name == 'twitteradminpanel', | ||||
|                 'nav_twitter_admin_panel' | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Plugin version data | ||||
|      * | ||||
|      * @param array &$versions array of version blocks | ||||
|      * | ||||
|      * @return boolean hook value | ||||
|      */ | ||||
|  | ||||
|     function onPluginVersion(&$versions) | ||||
|     { | ||||
|         $versions[] = array('name' => 'TwitterBridge', | ||||
|                             'version' => TWITTERBRIDGEPLUGIN_VERSION, | ||||
|                             'author' => 'Zach Copley', | ||||
|                             'homepage' => 'http://status.net/wiki/Plugin:TwitterBridge', | ||||
|                             'rawdescription' => | ||||
|                             _m('The Twitter "bridge" plugin allows you to integrate ' . | ||||
|                                'your StatusNet instance with ' . | ||||
|                                '<a href="http://twitter.com/">Twitter</a>.')); | ||||
|         $versions[] = array( | ||||
|             'name' => 'TwitterBridge', | ||||
|             'version' => self::VERSION, | ||||
|             'author' => 'Zach Copley, Julien C', | ||||
|             'homepage' => 'http://status.net/wiki/Plugin:TwitterBridge', | ||||
|             'rawdescription' => _m( | ||||
|                 'The Twitter "bridge" plugin allows you to integrate ' . | ||||
|                 'your StatusNet instance with ' . | ||||
|                 '<a href="http://twitter.com/">Twitter</a>.' | ||||
|             ) | ||||
|         ); | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										280
									
								
								plugins/TwitterBridge/twitteradminpanel.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										280
									
								
								plugins/TwitterBridge/twitteradminpanel.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,280 @@ | ||||
| <?php | ||||
| /** | ||||
|  * StatusNet, the distributed open-source microblogging tool | ||||
|  * | ||||
|  * Twitter bridge administration panel | ||||
|  * | ||||
|  * PHP version 5 | ||||
|  * | ||||
|  * LICENCE: This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU Affero General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU Affero General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Affero General Public License | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  * @category  Settings | ||||
|  * @package   StatusNet | ||||
|  * @author    Zach Copley <zach@status.net> | ||||
|  * @copyright 2010 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/ | ||||
|  */ | ||||
|  | ||||
| if (!defined('STATUSNET')) { | ||||
|     exit(1); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Administer global Twitter bridge settings | ||||
|  * | ||||
|  * @category Admin | ||||
|  * @package  StatusNet | ||||
|  * @author   Zach Copley <zach@status.net> | ||||
|  * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 | ||||
|  * @link     http://status.net/ | ||||
|  */ | ||||
|  | ||||
| class TwitteradminpanelAction extends AdminPanelAction | ||||
| { | ||||
|     /** | ||||
|      * Returns the page title | ||||
|      * | ||||
|      * @return string page title | ||||
|      */ | ||||
|  | ||||
|     function title() | ||||
|     { | ||||
|         return _m('Twitter'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Instructions for using this form. | ||||
|      * | ||||
|      * @return string instructions | ||||
|      */ | ||||
|  | ||||
|     function getInstructions() | ||||
|     { | ||||
|         return _m('Twitter bridge settings'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Show the Twitter admin panel form | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|  | ||||
|     function showForm() | ||||
|     { | ||||
|         $form = new TwitterAdminPanelForm($this); | ||||
|         $form->show(); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Save settings from the form | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|  | ||||
|     function saveSettings() | ||||
|     { | ||||
|         static $settings = array( | ||||
|             'twitter'     => array('consumer_key', 'consumer_secret'), | ||||
|             'integration' => array('source') | ||||
|         ); | ||||
|  | ||||
|         static $booleans = array( | ||||
|             'twitter'       => array('signin'), | ||||
|             'twitterimport' => array('enabled') | ||||
|         ); | ||||
|  | ||||
|         $values = array(); | ||||
|  | ||||
|         foreach ($settings as $section => $parts) { | ||||
|             foreach ($parts as $setting) { | ||||
|                 $values[$section][$setting] | ||||
|                     = $this->trimmed($setting); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         foreach ($booleans as $section => $parts) { | ||||
|             foreach ($parts as $setting) { | ||||
|                 $values[$section][$setting] | ||||
|                     = ($this->boolean($setting)) ? 1 : 0; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // This throws an exception on validation errors | ||||
|  | ||||
|         $this->validate($values); | ||||
|  | ||||
|         // assert(all values are valid); | ||||
|  | ||||
|         $config = new Config(); | ||||
|  | ||||
|         $config->query('BEGIN'); | ||||
|  | ||||
|         foreach ($settings as $section => $parts) { | ||||
|             foreach ($parts as $setting) { | ||||
|                 Config::save($section, $setting, $values[$section][$setting]); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         foreach ($booleans as $section => $parts) { | ||||
|             foreach ($parts as $setting) { | ||||
|                 Config::save($section, $setting, $values[$section][$setting]); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $config->query('COMMIT'); | ||||
|  | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     function validate(&$values) | ||||
|     { | ||||
|         // Validate consumer key and secret (can't be too long) | ||||
|  | ||||
|         if (mb_strlen($values['twitter']['consumer_key']) > 255) { | ||||
|             $this->clientError( | ||||
|                 _m("Invalid consumer key. Max length is 255 characters.") | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         if (mb_strlen($values['twitter']['consumer_secret']) > 255) { | ||||
|             $this->clientError( | ||||
|                 _m("Invalid consumer secret. Max length is 255 characters.") | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| class TwitterAdminPanelForm extends AdminForm | ||||
| { | ||||
|     /** | ||||
|      * ID of the form | ||||
|      * | ||||
|      * @return int ID of the form | ||||
|      */ | ||||
|  | ||||
|     function id() | ||||
|     { | ||||
|         return 'twitteradminpanel'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * class of the form | ||||
|      * | ||||
|      * @return string class of the form | ||||
|      */ | ||||
|  | ||||
|     function formClass() | ||||
|     { | ||||
|         return 'form_settings'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Action of the form | ||||
|      * | ||||
|      * @return string URL of the action | ||||
|      */ | ||||
|  | ||||
|     function action() | ||||
|     { | ||||
|         return common_local_url('twitteradminpanel'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Data elements of the form | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|  | ||||
|     function formData() | ||||
|     { | ||||
|         $this->out->elementStart( | ||||
|             'fieldset', | ||||
|             array('id' => 'settings_twitter-application') | ||||
|         ); | ||||
|         $this->out->element('legend', null, _m('Twitter application settings')); | ||||
|         $this->out->elementStart('ul', 'form_data'); | ||||
|  | ||||
|         $this->li(); | ||||
|         $this->input( | ||||
|             'consumer_key', | ||||
|             _m('Consumer key'), | ||||
|             _m('Consumer key assigned by Twitter'), | ||||
|             'twitter' | ||||
|         ); | ||||
|         $this->unli(); | ||||
|  | ||||
|         $this->li(); | ||||
|         $this->input( | ||||
|             'consumer_secret', | ||||
|              _m('Consumer secret'), | ||||
|             _m('Consumer secret assigned by Twitter'), | ||||
|             'twitter' | ||||
|         ); | ||||
|         $this->unli(); | ||||
|  | ||||
|         $this->li(); | ||||
|         $this->input( | ||||
|             'source', | ||||
|              _m('Integration source'), | ||||
|             _m('Name of your Twitter application'), | ||||
|             'integration' | ||||
|         ); | ||||
|         $this->unli(); | ||||
|  | ||||
|         $this->out->elementEnd('ul'); | ||||
|         $this->out->elementEnd('fieldset'); | ||||
|  | ||||
|         $this->out->elementStart( | ||||
|             'fieldset', | ||||
|             array('id' => 'settings_twitter-options') | ||||
|         ); | ||||
|         $this->out->element('legend', null, _m('Options')); | ||||
|  | ||||
|         $this->out->elementStart('ul', 'form_data'); | ||||
|  | ||||
|         $this->li(); | ||||
|  | ||||
|         $this->out->checkbox( | ||||
|             'signin', _m('Enable "Sign-in with Twitter"'), | ||||
|             (bool) $this->value('signin', 'twitter'), | ||||
|             _m('Allow users to login with their Twitter credentials') | ||||
|         ); | ||||
|         $this->unli(); | ||||
|  | ||||
|         $this->li(); | ||||
|         $this->out->checkbox( | ||||
|             'enabled', _m('Enable Twitter import'), | ||||
|             (bool) $this->value('enabled', 'twitterimport'), | ||||
|             _m('Allow users to import their Twitter friends\' timelines') | ||||
|         ); | ||||
|         $this->unli(); | ||||
|  | ||||
|         $this->out->elementEnd('ul'); | ||||
|  | ||||
|         $this->out->elementEnd('fieldset'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Action elements | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|  | ||||
|     function formActions() | ||||
|     { | ||||
|         $this->out->submit('submit', _('Save'), 'submit', null, _('Save Twitter settings')); | ||||
|     } | ||||
| } | ||||
| @@ -47,7 +47,7 @@ require_once INSTALLDIR . '/plugins/TwitterBridge/twitter.php'; | ||||
|  * @author   Zach Copley <zach@status.net> | ||||
|  * @author   Julien C <chaumond@gmail.com> | ||||
|  * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 | ||||
|  * @link     http://laconi.ca/ | ||||
|  * @link     http://status.net/ | ||||
|  * | ||||
|  */ | ||||
| class TwitterauthorizationAction extends Action | ||||
|   | ||||
		Reference in New Issue
	
	Block a user