]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - plugins/Facebook/facebookaction.php
Just a label change. Since the user already went ahead with
[quix0rs-gnu-social.git] / plugins / Facebook / facebookaction.php
1 <?php
2 /**
3  * StatusNet, the distributed open-source microblogging tool
4  *
5  * Base Facebook Action
6  *
7  * PHP version 5
8  *
9  * LICENCE: This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU Affero General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU Affero General Public License for more details.
18  *
19  * You should have received a copy of the GNU Affero General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  * @category  Faceboook
23  * @package   StatusNet
24  * @author    Zach Copley <zach@status.net>
25  * @copyright 2008-2009 StatusNet, Inc.
26  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
27  * @link      http://status.net/
28  */
29
30 if (!defined('STATUSNET') && !defined('LACONICA')) {
31     exit(1);
32 }
33
34 require_once INSTALLDIR . '/plugins/Facebook/facebookutil.php';
35 require_once INSTALLDIR . '/plugins/Facebook/facebooknoticeform.php';
36
37 class FacebookAction extends Action
38 {
39
40     var $facebook = null;
41     var $fbuid    = null;
42     var $flink    = null;
43     var $action   = null;
44     var $app_uri  = null;
45     var $app_name = null;
46
47     function __construct($output='php://output', $indent=null, $facebook=null, $flink=null)
48     {
49         parent::__construct($output, $indent);
50
51         $this->facebook = $facebook;
52         $this->flink = $flink;
53
54         if ($this->flink) {
55             $this->fbuid = $flink->foreign_id;
56             $this->user = $flink->getUser();
57         }
58
59         $this->args = array();
60     }
61
62     function prepare($argarray)
63     {
64         parent::prepare($argarray);
65
66         $this->facebook = getFacebook();
67         $this->fbuid = $this->facebook->require_login();
68
69         $this->action = $this->trimmed('action');
70
71         $app_props = $this->facebook->api_client->Admin_getAppProperties(
72                 array('canvas_name', 'application_name'));
73
74         $this->app_uri = 'http://apps.facebook.com/' . $app_props['canvas_name'];
75         $this->app_name = $app_props['application_name'];
76
77         $this->flink = Foreign_link::getByForeignID($this->fbuid, FACEBOOK_SERVICE);
78
79         return true;
80
81     }
82
83     function showStylesheets()
84     {
85         $this->cssLink('css/display.css', 'base');
86         $this->cssLink('css/display.css', null, 'screen, projection, tv');
87         $this->cssLink('plugins/Facebook/facebookapp.css');
88     }
89
90     function showScripts()
91     {
92         $this->script(common_path('plugins/Facebook/facebookapp.js'));
93     }
94
95     /**
96      * Start an Facebook ready HTML document
97      *
98      * For Facebook we don't want to actually output any headers,
99      * DTD info, etc.  Just Stylesheet and JavaScript links.
100      *
101      * @param string $type MIME type to use; default is to do negotation.
102      *
103      * @return void
104      */
105
106     function startHTML($type=null)
107     {
108         $this->showStylesheets();
109         $this->showScripts();
110
111         $this->elementStart('div', array('class' => 'facebook-page'));
112     }
113
114     /**
115     *  Ends a Facebook ready HTML document
116     *
117     *  @return void
118     */
119     function endHTML()
120     {
121         $this->elementEnd('div');
122         $this->endXML();
123     }
124
125     /**
126      * Show notice form.
127      *
128      * @return nothing
129      */
130     function showNoticeForm()
131     {
132         // don't do it for most of the Facebook pages
133     }
134
135     function showBody()
136     {
137         $this->elementStart('div', array('id' => 'wrap'));
138         $this->showHeader();
139         $this->showCore();
140         $this->showFooter();
141         $this->elementEnd('div');
142     }
143
144     function showHead($error, $success)
145     {
146
147         if ($error) {
148             $this->element("h1", null, $error);
149         }
150
151         if ($success) {
152             $this->element("h1", null, $success);
153         }
154
155         $this->elementStart('fb:if-section-not-added', array('section' => 'profile'));
156         $this->elementStart('span', array('id' => 'add_to_profile'));
157         $this->element('fb:add-section-button', array('section' => 'profile'));
158         $this->elementEnd('span');
159         $this->elementEnd('fb:if-section-not-added');
160
161     }
162
163     // Make this into a widget later
164     function showLocalNav()
165     {
166         $this->elementStart('ul', array('class' => 'nav'));
167
168         $this->elementStart('li', array('class' =>
169             ($this->action == 'facebookhome') ? 'current' : 'facebook_home'));
170         $this->element('a',
171             array('href' => 'index.php', 'title' => _m('Home')), _m('Home'));
172         $this->elementEnd('li');
173
174         if (common_config('invite', 'enabled')) {
175             $this->elementStart('li',
176                 array('class' =>
177                     ($this->action == 'facebookinvite') ? 'current' : 'facebook_invite'));
178             $this->element('a',
179                 array('href' => 'invite.php', 'title' => _m('Invite')), _m('Invite'));
180             $this->elementEnd('li');
181         }
182
183         $this->elementStart('li',
184             array('class' =>
185                 ($this->action == 'facebooksettings') ? 'current' : 'facebook_settings'));
186         $this->element('a',
187             array('href' => 'settings.php',
188                 'title' => _m('Settings')), _m('Settings'));
189         $this->elementEnd('li');
190
191         $this->elementEnd('ul');
192     }
193
194     /**
195      * Show header of the page.
196      *
197      * @return nothing
198      */
199     function showHeader()
200     {
201         $this->elementStart('div', array('id' => 'header'));
202         $this->showLogo();
203         $this->showNoticeForm();
204         $this->elementEnd('div');
205     }
206
207     /**
208      * Show page, a template method.
209      *
210      * @return nothing
211      */
212     function showPage($error = null, $success = null)
213     {
214         $this->startHTML();
215         $this->showHead($error, $success);
216         $this->showBody();
217         $this->endHTML();
218     }
219
220     function showInstructions()
221     {
222
223         $this->elementStart('div', array('class' => 'facebook_guide'));
224
225         $this->elementStart('dl', array('class' => 'system_notice'));
226         $this->element('dt', null, 'Page Notice');
227
228         $loginmsg_part1 = _m('To use the %s Facebook Application you need to login ' .
229             'with your username and password. Don\'t have a username yet? ');
230         $loginmsg_part2 = _m(' a new account.');
231
232         $this->elementStart('dd');
233         $this->elementStart('p');
234         $this->text(sprintf($loginmsg_part1, common_config('site', 'name')));
235         $this->element('a',
236             array('href' => common_local_url('register')), _m('Register'));
237         $this->text($loginmsg_part2);
238         $this->elementEnd('p');
239         $this->elementEnd('dd');
240
241         $this->elementEnd('dl');
242         $this->elementEnd('div');
243     }
244
245     function showLoginForm($msg = null)
246     {
247
248         $this->elementStart('div', array('id' => 'content'));
249         $this->element('h1', null, _m('Login'));
250
251         if ($msg) {
252              $this->element('fb:error', array('message' => $msg));
253         }
254
255         $this->showInstructions();
256
257         $this->elementStart('div', array('id' => 'content_inner'));
258
259         $this->elementStart('form', array('method' => 'post',
260                                                'class' => 'form_settings',
261                                                'id' => 'login',
262                                                'action' => 'index.php'));
263
264         $this->elementStart('fieldset');
265
266         $this->elementStart('ul', array('class' => 'form_datas'));
267         $this->elementStart('li');
268         $this->input('nickname', _m('Nickname'));
269         $this->elementEnd('li');
270         $this->elementStart('li');
271         $this->password('password', _m('Password'));
272         $this->elementEnd('li');
273         $this->elementEnd('ul');
274
275         $this->submit('submit', _m('Login'));
276         $this->elementEnd('fieldset');
277         $this->elementEnd('form');
278
279         $this->elementStart('p');
280         $this->element('a', array('href' => common_local_url('recoverpassword')),
281                        _m('Lost or forgotten password?'));
282         $this->elementEnd('p');
283
284         $this->elementEnd('div');
285         $this->elementEnd('div');
286
287     }
288
289     function updateProfileBox($notice)
290     {
291
292         // Need to include inline CSS for styling the Profile box
293
294         $app_props = $this->facebook->api_client->Admin_getAppProperties(array('icon_url'));
295         $icon_url = $app_props['icon_url'];
296
297         $style = '<style> .entry-title *, .entry-content * { font-size:14px; font-family:"Lucida Sans Unicode", "Lucida Grande", sans-serif; } .entry-title a, .entry-content a { color:#002E6E; } .entry-title .vcard .photo { float:left; display:inline; margin-right:11px; margin-bottom:11px } .entry-title { margin-bottom:11px; } .entry-title p.entry-content { display:inline; margin-left:5px; } div.entry-content { clear:both; } div.entry-content dl, div.entry-content dt, div.entry-content dd { display:inline; text-transform:lowercase; } div.entry-content dd, div.entry-content .device dt { margin-left:0; margin-right:5px; } div.entry-content dl.timestamp dt, div.entry-content dl.response dt { display:none; } div.entry-content dd a { display:inline-block; } #facebook_statusnet_app { text-indent:-9999px; height:16px; width:16px; display:block; background:url('.$icon_url.') no-repeat 0 0; float:right; } </style>';
298
299         $this->xw->openMemory();
300
301         $item = new FacebookProfileBoxNotice($notice, $this);
302         $item->show();
303
304         $fbml = "<fb:wide>$style " . $this->xw->outputMemory(false) . "</fb:wide>";
305         $fbml .= "<fb:narrow>$style " . $this->xw->outputMemory(false) . "</fb:narrow>";
306
307         $fbml_main = "<fb:narrow>$style " . $this->xw->outputMemory(false) . "</fb:narrow>";
308
309         $this->facebook->api_client->profile_setFBML(null, $this->fbuid, $fbml, null, null, $fbml_main);
310
311         $this->xw->openURI('php://output');
312     }
313
314     /**
315      * Generate pagination links
316      *
317      * @param boolean $have_before is there something before?
318      * @param boolean $have_after  is there something after?
319      * @param integer $page        current page
320      * @param string  $action      current action
321      * @param array   $args        rest of query arguments
322      *
323      * @return nothing
324      */
325     function pagination($have_before, $have_after, $page, $action, $args=null)
326     {
327         // Does a little before-after block for next/prev page
328         if ($have_before || $have_after) {
329             $this->elementStart('dl', 'pagination');
330             $this->element('dt', null, _m('Pagination'));
331             $this->elementStart('dd', null);
332             $this->elementStart('ul', array('class' => 'nav'));
333         }
334         if ($have_before) {
335             $pargs   = array('page' => $page-1);
336             $newargs = $args ? array_merge($args, $pargs) : $pargs;
337             $this->elementStart('li', array('class' => 'nav_prev'));
338             $this->element('a', array('href' => "$this->app_uri/$action?page=$newargs[page]", 'rel' => 'prev'),
339                            _m('After'));
340             $this->elementEnd('li');
341         }
342         if ($have_after) {
343             $pargs   = array('page' => $page+1);
344             $newargs = $args ? array_merge($args, $pargs) : $pargs;
345             $this->elementStart('li', array('class' => 'nav_next'));
346             $this->element('a', array('href' => "$this->app_uri/$action?page=$newargs[page]", 'rel' => 'next'),
347                            _m('Before'));
348             $this->elementEnd('li');
349         }
350         if ($have_before || $have_after) {
351             $this->elementEnd('ul');
352             $this->elementEnd('dd');
353             $this->elementEnd('dl');
354         }
355     }
356
357     function saveNewNotice()
358     {
359
360         $user = $this->flink->getUser();
361
362         $content = $this->trimmed('status_textarea');
363
364         if (!$content) {
365             $this->showPage(_m('No notice content!'));
366             return;
367         } else {
368             $content_shortened = common_shorten_links($content);
369
370             if (Notice::contentTooLong($content_shortened)) {
371                 $this->showPage(sprintf(_m('That\'s too long. Max notice size is %d chars.'),
372                                         Notice::maxContent()));
373                 return;
374             }
375         }
376
377         $inter = new CommandInterpreter();
378
379         $cmd = $inter->handle_command($user, $content_shortened);
380
381         if ($cmd) {
382
383             // XXX fix this
384
385             $cmd->execute(new WebChannel());
386             return;
387         }
388
389         $replyto = $this->trimmed('inreplyto');
390
391         try {
392             $notice = Notice::saveNew($user->id, $content, 'web',
393                                       array('reply_to' => ($replyto == 'false') ? null : $replyto));
394
395         } catch (Exception $e) {
396             $this->showPage($e->getMessage());
397             return;
398         }
399
400     }
401
402 }
403
404 class FacebookNoticeList extends NoticeList
405 {
406
407     /**
408      * constructor
409      *
410      * @param Notice $notice stream of notices from DB_DataObject
411      */
412
413     function __construct($notice, $out=null)
414     {
415         parent::__construct($notice, $out);
416     }
417
418     /**
419      * show the list of notices
420      *
421      * "Uses up" the stream by looping through it. So, probably can't
422      * be called twice on the same list.
423      *
424      * @return int count of notices listed.
425      */
426
427     function show()
428     {
429         $this->out->elementStart('div', array('id' =>'notices_primary'));
430         $this->out->element('h2', null, _m('Notices'));
431         $this->out->elementStart('ul', array('class' => 'notices'));
432
433         $cnt = 0;
434
435         while ($this->notice->fetch() && $cnt <= NOTICES_PER_PAGE) {
436             $cnt++;
437
438             if ($cnt > NOTICES_PER_PAGE) {
439                 break;
440             }
441
442             $item = $this->newListItem($this->notice);
443             $item->show();
444         }
445
446         $this->out->elementEnd('ul');
447         $this->out->elementEnd('div');
448
449         return $cnt;
450     }
451
452     /**
453      * returns a new list item for the current notice
454      *
455      * Overridden to return a Facebook specific list item.
456      *
457      * @param Notice $notice the current notice
458      *
459      * @return FacebookNoticeListItem a list item for displaying the notice
460      * formatted for display in the Facebook App.
461      */
462
463     function newListItem($notice)
464     {
465         return new FacebookNoticeListItem($notice, $this);
466     }
467
468 }
469
470 class FacebookNoticeListItem extends NoticeListItem
471 {
472
473     /**
474      * constructor
475      *
476      * Also initializes the profile attribute.
477      *
478      * @param Notice $notice The notice we'll display
479      */
480
481     function __construct($notice, $out=null)
482     {
483         parent::__construct($notice, $out);
484     }
485
486     /**
487      * recipe function for displaying a single notice in the Facebook App.
488      *
489      * Overridden to strip out some of the controls that we don't
490      * want to be available.
491      *
492      * @return void
493      */
494
495     function show()
496     {
497         $this->showStart();
498         $this->showNotice();
499         $this->showNoticeInfo();
500
501         // XXX: Need to update to show attachements and controls
502
503         $this->showEnd();
504     }
505
506 }
507
508 class FacebookProfileBoxNotice extends FacebookNoticeListItem
509 {
510
511     /**
512      * constructor
513      *
514      * Also initializes the profile attribute.
515      *
516      * @param Notice $notice The notice we'll display
517      */
518
519     function __construct($notice, $out=null)
520     {
521         parent::__construct($notice, $out);
522     }
523
524     /**
525      * Recipe function for displaying a single notice in the
526      * Facebook App profile notice box
527      *
528      * @return void
529      */
530
531     function show()
532     {
533         $this->showNotice();
534         $this->showNoticeInfo();
535         $this->showAppLink();
536     }
537
538     function showAppLink()
539     {
540
541         $this->facebook = getFacebook();
542
543         $app_props = $this->facebook->api_client->Admin_getAppProperties(
544                 array('canvas_name', 'application_name'));
545
546         $this->app_uri = 'http://apps.facebook.com/' . $app_props['canvas_name'];
547         $this->app_name = $app_props['application_name'];
548
549         $this->out->elementStart('a', array('id' => 'facebook_statusnet_app',
550                                             'href' => $this->app_uri));
551         $this->out->text($this->app_name);
552         $this->out->elementEnd('a');
553     }
554
555 }