]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - lib/facebookaction.php
Merge branch 'master' of /var/www/trunk
[quix0rs-gnu-social.git] / lib / facebookaction.php
1 <?php
2 /**
3  * Laconica, the distributed open-source microblogging tool
4  *
5  * Low-level generator for HTML
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   Laconica
24  * @author    Zach Copley <zach@controlyourself.ca>
25  * @copyright 2008 Control Yourself, Inc.
26  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
27  * @link      http://laconi.ca/
28  */
29
30 if (!defined('LACONICA'))
31 {
32     exit(1);
33 }
34
35 require_once INSTALLDIR.'/lib/facebookutil.php';
36 require_once INSTALLDIR.'/lib/noticeform.php';
37
38
39 class FacebookAction extends Action
40 {
41     
42     var $facebook = null;
43     var $fbuid    = null;
44     var $flink    = null;
45     var $action   = null;
46     var $app_uri  = null;
47     var $app_name = null;
48   
49     function prepare($argarray)
50     {        
51         parent::prepare($argarray);
52         
53         common_debug("Facebookaction::prepare");
54   
55         $this->facebook = get_facebook();
56         $this->fbuid = $this->facebook->require_login();
57         
58         $this->action = $this->trimmed('action');
59         
60         $app_props = $this->facebook->api_client->Admin_getAppProperties(
61                 array('canvas_name', 'application_name'));
62         
63         $this->app_uri = 'http://apps.facebook.com/' . $app_props['canvas_name'];
64         $this->app_name = $app_props['application_name'];
65
66         $this->flink = Foreign_link::getByForeignID($this->fbuid, FACEBOOK_SERVICE);
67         
68         return true;
69         
70     }
71   
72     function showStylesheets()
73     {
74         
75         $this->element('link', array('rel' => 'stylesheet',
76                                      'type' => 'text/css',
77                                      'href' => getFacebookBaseCSS()));
78
79         $this->element('link', array('rel' => 'stylesheet',
80                                      'type' => 'text/css',
81                                      'href' => getFacebookThemeCSS()));
82     }
83   
84     function showScripts()
85     {
86         $this->element('script', array('type' => 'text/javascript',
87                                        'src' => getFacebookJS()),
88                        ' ');
89     }
90     
91     /**
92      * Start an Facebook ready HTML document
93      *
94      *  For Facebook we don't want to actually output any headers,
95      *  DTD info, etc.
96      *
97      * If $type isn't specified, will attempt to do content negotiation.
98      *
99      * @param string $type MIME type to use; default is to do negotation.
100      *
101      * @return void
102      */
103
104     function startHTML($type=null) 
105     {          
106         $this->elementStart('div', array('class' => 'facebook-page'));
107     }
108
109     /**
110     *  Ends a Facebook ready HTML document
111     *
112     *  @return void
113     */
114     function endHTML()
115     {
116         $this->elementEnd('div');
117         $this->endXML();
118     }
119
120     /**
121      * Show notice form.
122      *
123      * MAY overload if no notice form needed... or direct message box????
124      *
125      * @return nothing
126      */
127     function showNoticeForm()
128     {
129         // don't do it for most of the Facebook pages
130     }
131
132     function showBody()
133     {
134         $this->elementStart('div', 'wrap');
135         $this->showHeader();
136         $this->showCore();
137         $this->showFooter();
138         $this->elementEnd('div');
139     }
140       
141     function showAside()
142     {
143     }
144
145     function showHead($error, $success)
146     {
147         $this->showStylesheets();
148         $this->showScripts();
149         
150         if ($error) {
151             $this->element("h1", null, $error);
152         }
153         
154         if ($success) {
155             $this->element("h1", null, $success);
156         }
157
158         $this->elementStart('fb:if-section-not-added', array('section' => 'profile'));
159         $this->elementStart('span', array('id' => 'add_to_profile'));
160         $this->element('fb:add-section-button', array('section' => 'profile'));
161         $this->elementEnd('span');
162         $this->elementEnd('fb:if-section-not-added');
163         
164     }
165
166     
167     // Make this into a widget later
168     function showLocalNav()
169     {
170                 
171         $this->elementStart('ul', array('class' => 'nav'));
172
173         $this->elementStart('li', array('class' =>
174             ($this->action == 'facebookhome') ? 'current' : 'facebook_home'));
175         $this->element('a',
176             array('href' => 'index.php', 'title' => _('Home')), _('Home'));
177         $this->elementEnd('li');
178
179         $this->elementStart('li',
180             array('class' =>
181                 ($this->action == 'facebookinvite') ? 'current' : 'facebook_invite'));
182         $this->element('a',
183             array('href' => 'invite.php', 'title' => _('Invite')), _('Invite'));
184         $this->elementEnd('li');
185
186         $this->elementStart('li',
187             array('class' =>
188                 ($this->action == 'facebooksettings') ? 'current' : 'facebook_settings'));
189         $this->element('a',
190             array('href' => 'settings.php',
191                 'title' => _('Settings')), _('Settings'));
192         $this->elementEnd('li');
193
194         $this->elementEnd('ul');
195
196     }     
197
198     /**
199      * Show primary navigation.
200      *
201      * @return nothing
202      */
203     function showPrimaryNav()
204     {
205         // we don't want to show anything for this
206     }
207     
208     /**
209      * Show header of the page.
210      *
211      * Calls template methods
212      *
213      * @return nothing
214      */
215     function showHeader()
216     {
217         $this->elementStart('div', array('id' => 'header'));
218         $this->showLogo();
219         $this->showNoticeForm();
220         $this->showPrimaryNav();
221         $this->elementEnd('div');
222     }
223     
224     /**
225      * Show page, a template method.
226      *
227      * @return nothing
228      */
229     function showPage($error = null, $success = null)
230     {
231         $this->startHTML();
232         $this->showHead($error, $success);
233         $this->showBody();
234         $this->endHTML();
235     }
236     
237
238     function showInstructions()
239     {
240         global $xw;
241
242         $this->elementStart('dl', array('class' => 'system_notice'));
243         $this->element('dt', null, 'Page Notice');
244
245         $loginmsg_part1 = _('To use the %s Facebook Application you need to login ' .
246             'with your username and password. Don\'t have a username yet? ');
247
248         $loginmsg_part2 = _(' a new account.');
249
250         $this->elementStart('dd');
251         $this->elementStart('p');
252         $this->text(sprintf($loginmsg_part1, common_config('site', 'name')));
253         $this->element('a',
254             array('href' => common_local_url('register')), _('Register'));
255         $this->text($loginmsg_part2);
256         $this->elementEnd('dd');
257         $this->elementEnd('dl');
258     }
259
260
261     function showLoginForm($msg = null)
262     {
263
264         $this->elementStart('div', array('class' => 'content'));
265         $this->element('h1', null, _('Login'));
266
267         if ($msg) {
268              $this->element('fb:error', array('message' => $msg));
269         }
270
271         $this->showInstructions();
272
273         $this->elementStart('div', array('id' => 'content_inner'));
274
275         $this->elementStart('form', array('method' => 'post',
276                                                'class' => 'form_settings',
277                                                'id' => 'login',
278                                                'action' => 'index.php'));
279
280         $this->elementStart('fieldset');
281         $this->element('legend', null, _('Login to site'));
282
283         $this->elementStart('ul', array('class' => 'form_datas'));
284         $this->elementStart('li');
285         $this->input('nickname', _('Nickname'));
286         $this->elementEnd('li');
287         $this->elementStart('li');
288         $this->password('password', _('Password'));
289         $this->elementEnd('li');
290         $this->elementEnd('ul');
291
292         $this->submit('submit', _('Login'));
293         $this->elementEnd('form');
294
295         $this->elementStart('p');
296         $this->element('a', array('href' => common_local_url('recoverpassword')),
297                        _('Lost or forgotten password?'));
298         $this->elementEnd('p');
299
300         $this->elementEnd('div');
301
302     }
303     
304     
305     function updateProfileBox($notice)
306     {
307
308         // Need to include inline CSS for styling the Profile box
309
310         $style = '<style>
311          #notices {
312              clear: both;
313              margin: 0 auto;
314              padding: 0;
315              list-style-type: none;
316              width: 600px;
317              border-top: 1px solid #dec5b5;
318          }
319          #notices a:hover {
320              text-decoration: underline;
321          }
322          .notice_single {
323              clear: both;
324              display: block;
325              margin: 0;
326              padding: 5px 5px 5px 0;
327              min-height: 48px;
328              font-family: Georgia, "Times New Roman", Times, serif;
329              font-size: 13px;
330              line-height: 16px;
331              border-bottom: 1px solid #dec5b5;
332              background-color:#FCFFF5;
333              opacity:1;
334          }
335          .notice_single:hover {
336              background-color: #f7ebcc;
337          }
338          .notice_single p {
339              display: inline;
340              margin: 0;
341              padding: 0;
342          }
343          </style>';        
344
345         $this->xw->openMemory();
346
347         $item = new FacebookNoticeListItem($notice, $this);
348         $item->show();
349
350         $fbml = "<fb:wide>$style " . $this->xw->outputMemory(false) . "</fb:wide>";
351         $fbml .= "<fb:narrow>$style " . $this->xw->outputMemory(false) . "</fb:narrow>";
352
353         $fbml_main = "<fb:narrow>$style " . $this->xw->outputMemory(false) . "</fb:narrow>";
354
355         $this->facebook->api_client->profile_setFBML(null, $this->fbuid, $fbml, null, null, $fbml_main);  
356
357         $this->xw->openURI('php://output');
358     }
359     
360     
361     /**
362      * Generate pagination links
363      *
364      * @param boolean $have_before is there something before?
365      * @param boolean $have_after  is there something after?
366      * @param integer $page        current page
367      * @param string  $action      current action
368      * @param array   $args        rest of query arguments
369      *
370      * @return nothing
371      */
372     function pagination($have_before, $have_after, $page, $action, $args=null)
373     {
374         // Does a little before-after block for next/prev page
375         if ($have_before || $have_after) {
376             $this->elementStart('div', array('class' => 'pagination'));
377             $this->elementStart('dl', null);
378             $this->element('dt', null, _('Pagination'));
379             $this->elementStart('dd', null);
380             $this->elementStart('ul', array('class' => 'nav'));
381         }
382         if ($have_before) {
383             $pargs   = array('page' => $page-1);
384             $newargs = $args ? array_merge($args, $pargs) : $pargs;
385             $this->elementStart('li', array('class' => 'nav_prev'));
386             $this->element('a', array('href' => "$this->app_uri/$action?page=$newargs[page]", 'rel' => 'prev'),
387                            _('After'));
388             $this->elementEnd('li');
389         }
390         if ($have_after) {
391             $pargs   = array('page' => $page+1);
392             $newargs = $args ? array_merge($args, $pargs) : $pargs;
393             $this->elementStart('li', array('class' => 'nav_next'));
394             $this->element('a', array('href' => "$this->app_uri/$action?page=$newargs[page]", 'rel' => 'next'),
395                            _('Before'));
396             $this->elementEnd('li');
397         }
398         if ($have_before || $have_after) {
399             $this->elementEnd('ul');
400             $this->elementEnd('dd');
401             $this->elementEnd('dl');
402             $this->elementEnd('div');
403         }
404     }
405     
406
407 }
408
409 class FacebookNoticeForm extends NoticeForm 
410 {
411     
412     var $post_action = null;
413     
414     /**
415      * Constructor
416      *
417      * @param HTMLOutputter $out     output channel
418      * @param string        $action  action to return to, if any
419      * @param string        $content content to pre-fill
420      */
421
422     function __construct($out=null, $action=null, $content=null, 
423         $post_action=null, $user=null)
424     {
425         parent::__construct($out, $action, $content, $user);
426         $this->post_action = $post_action;
427     }
428     
429     /**
430      * Action of the form
431      *
432      * @return string URL of the action
433      */
434
435     function action()
436     {
437         return $this->post_action;
438     }
439
440 }
441
442 class FacebookNoticeList extends NoticeList
443 {
444     /**
445      * show the list of notices
446      *
447      * "Uses up" the stream by looping through it. So, probably can't
448      * be called twice on the same list.
449      *
450      * @return int count of notices listed.
451      */
452
453     function show()
454     {
455         $this->out->elementStart('div', array('id' =>'notices_primary'));
456         $this->out->element('h2', null, _('Notices'));
457         $this->out->elementStart('ul', array('class' => 'notices'));
458
459         $cnt = 0;
460
461         while ($this->notice->fetch() && $cnt <= NOTICES_PER_PAGE) {
462             $cnt++;
463
464             if ($cnt > NOTICES_PER_PAGE) {
465                 break;
466             }
467
468             $item = $this->newListItem($this->notice);
469             $item->show();
470         }
471
472         $this->out->elementEnd('ul');
473         $this->out->elementEnd('div');
474
475         return $cnt;
476     }
477
478     /**
479      * returns a new list item for the current notice
480      *
481      * Overridden to return a Facebook specific list item.
482      *
483      * @param Notice $notice the current notice
484      *
485      * @return FacebookNoticeListItem a list item for displaying the notice
486      * formatted for display in the Facebook App.
487      */
488
489     function newListItem($notice)
490     {
491         return new FacebookNoticeListItem($notice, $this);
492     }
493
494 }
495
496 class FacebookNoticeListItem extends NoticeListItem
497 {    
498     /**
499      * recipe function for displaying a single notice in the Facebook App.
500      *
501      * Overridden to strip out some of the controls that we don't
502      * want to be available.
503      *
504      * @return void
505      */
506
507     function show()
508     {
509         $this->showStart();
510
511         $this->out->elementStart('div', 'entry-title');
512         $this->showAuthor();
513         $this->showContent();
514         $this->out->elementEnd('div');
515
516         $this->out->elementStart('div', 'entry-content');
517         $this->showNoticeLink();
518         $this->showNoticeSource();
519         $this->showReplyTo();
520         $this->out->elementEnd('div');
521
522         $this->showEnd();
523     }
524
525     function showNoticeLink()
526     {
527         $noticeurl = common_local_url('shownotice',
528                                       array('notice' => $this->notice->id));
529         // XXX: we need to figure this out better. Is this right?
530         if (strcmp($this->notice->uri, $noticeurl) != 0 &&
531             preg_match('/^http/', $this->notice->uri)) {
532             $noticeurl = $this->notice->uri;
533         }
534
535         $this->out->elementStart('dl', 'timestamp');
536         $this->out->element('dt', null, _('Published'));
537         $this->out->elementStart('dd', null);
538         $this->out->elementStart('a', array('rel' => 'bookmark',
539                                         'href' => $noticeurl));
540         $dt = common_date_iso8601($this->notice->created);
541         $this->out->element('abbr', array('class' => 'published',
542                                      'title' => $dt),
543         common_date_string($this->notice->created));
544         $this->out->elementEnd('a');
545         $this->out->elementEnd('dd');
546         $this->out->elementEnd('dl');
547     }
548
549 }