]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - plugins/MobileProfile/MobileProfilePlugin.php
fd60575507959310677c71264229f691cf95f71a
[quix0rs-gnu-social.git] / plugins / MobileProfile / MobileProfilePlugin.php
1 <?php
2 /**
3  * StatusNet, the distributed open-source microblogging tool
4  *
5  * XHTML Mobile Profile plugin that uses WAP 2.0 Plugin
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  Plugin
23  * @package   StatusNet
24  * @author    Sarven Capadisli <csarven@status.net>
25  * @copyright 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 define('PAGE_TYPE_PREFS',
35        'application/vnd.wap.xhtml+xml, application/xhtml+xml, text/html;q=0.9');
36
37 require_once INSTALLDIR.'/plugins/Mobile/WAP20Plugin.php';
38
39
40 /**
41  * Superclass for plugin to output XHTML Mobile Profile
42  *
43  * @category Plugin
44  * @package  StatusNet
45  * @author   Sarven Capadisli <csarven@status.net>
46  * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
47  * @link     http://status.net/
48  */
49
50 class MobileProfilePlugin extends WAP20Plugin
51 {
52     public $DTD            = null;
53     public $serveMobile    = false;
54     public $mobileFeatures = array();
55
56     function __construct($DTD='http://www.wapforum.org/DTD/xhtml-mobile10.dtd')
57     {
58         $this->DTD = $DTD;
59
60         parent::__construct();
61     }
62
63
64     function onStartShowHTML($action)
65     {
66         // XXX: This should probably graduate to WAP20Plugin
67
68         // If they are on the mobile site, serve them MP
69         if ((common_config('site', 'mobileserver').'/'.
70              common_config('site', 'path').'/' == 
71             $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'])) {
72
73             $this->serveMobile = true;
74         } else {
75             // If they like the WAP 2.0 mimetype, serve them MP
76             if (strstr('application/vnd.wap.xhtml+xml', $type) !== false) {
77                 $this->serveMobile = true;
78             } else {
79                 // If they are a mobile device that supports WAP 2.0, 
80                 // serve them MP
81
82                 // XXX: Browser sniffing sucks
83
84                 // I really don't like going through this every page, 
85                 // perhaps use $_SESSION or cookies
86
87                 // May be better to group the devices in terms of 
88                 // low,mid,high-end
89
90                 // Or, detect the mobile devices based on their support for 
91                 // MP 1.0, 1.1, or 1.2 may be ideal. Possible?
92
93                 $this->mobiledevices = array(
94                     'alcatel',
95                     'android',
96                     'audiovox',
97                     'au-mic,',
98                     'avantgo',
99                     'blackberry',
100                     'blazer',
101                     'cldc-',
102                     'danger',
103                     'epoc',
104                     'ericsson',
105                     'ericy',
106                     'iphone',
107                     'ipaq',
108                     'ipod',
109                     'j2me',
110                     'lg',
111                     'midp-',
112                     'mobile',
113                     'mot',
114                     'netfront',
115                     'nitro',
116                     'nokia',
117                     'opera mini',
118                     'palm',
119                     'palmsource',
120                     'panasonic',
121                     'philips',
122                     'pocketpc',
123                     'portalmmm',
124                     'rover',
125                     'samsung',
126                     'sanyo',
127                     'series60',
128                     'sharp',
129                     'sie-',
130                     'smartphone',
131                     'sony',
132                     'symbian',
133                     'up.browser',
134                     'up.link',
135                     'up.link',
136                     'vodafone',
137                     'wap1',
138                     'wap2',
139                     'windows ce'
140                 );
141
142                 $httpuseragent = strtolower($_SERVER['HTTP_USER_AGENT']);
143
144                 foreach ($this->mobiledevices as $md) {
145                     if (strstr($httpuseragent, $md) !== false) {
146                         $this->setMobileFeatures($httpuseragent);
147
148                         $this->serveMobile = true;
149                         break;
150                     }
151                 }
152             }
153
154             // If they are okay with MP, and the site has a mobile server, 
155             // redirect there
156             if ($this->serveMobile && 
157                 common_config('site', 'mobileserver') !== false &&
158                 (common_config('site', 'mobileserver') != 
159                     common_config('site', 'server'))) {
160
161                 // FIXME: Redirect to equivalent page on mobile site instead
162                 header("Location: ".$this->_common_path(''));
163                 exit();
164             }
165         }
166
167         if (!$this->serveMobile) {
168             return true;
169         }
170
171         if (!$type) {
172             $httpaccept = isset($_SERVER['HTTP_ACCEPT']) ?
173               $_SERVER['HTTP_ACCEPT'] : null;
174
175             $cp = common_accept_to_prefs($httpaccept);
176             $sp = common_accept_to_prefs(PAGE_TYPE_PREFS);
177
178             $type = common_negotiate_type($cp, $sp);
179
180             if (!$type) {
181                 throw new ClientException(_('This page is not available in a '.
182                                             'media type you accept'), 406);
183             }
184         }
185
186         header('Content-Type: '.$type);
187
188         $action->extraHeaders();
189         if (preg_match("/.*\/.*xml/", $type)) {
190             // Required for XML documents
191             $action->xw->startDocument('1.0', 'UTF-8');
192         }
193         $action->xw->writeDTD('html',
194                         '-//WAPFORUM//DTD XHTML Mobile 1.0//EN',
195                         $this->DTD);
196
197         $language = $action->getLanguage();
198
199         $action->elementStart('html', array('xmlns' => 'http://www.w3.org/1999/xhtml',
200                                             'xml:lang' => $language));
201
202         return false;
203     }
204
205
206     function setMobileFeatures($useragent)
207     {
208         $mobiledeviceInputFileType = array(
209             'nokia'
210         );
211
212         $this->mobileFeatures['inputfiletype'] = false;
213
214         foreach ($mobiledeviceInputFileType as $md) {
215             if (strstr($useragent, $md) !== false) {
216                 $this->mobileFeatures['inputfiletype'] = true;
217                 break;
218             }
219         }
220     }
221
222
223     function onStartShowHeadElements($action)
224     {
225         if (!$action->serveMobile) {
226             return true;
227         }
228
229         $action->showTitle();
230         $action->showShortcutIcon();
231         $action->showStylesheets();
232         $action->showFeeds();
233         $action->showDescription();
234         $action->extraHead();
235     }
236
237
238     function onStartShowStatusNetStyles($action)
239     {
240         if (!$this->serveMobile) {
241             return true;
242         }
243
244         if (file_exists(Theme::file('css/mp-screen.css'))) {
245             $action->cssLink('css/mp-screen.css', null, 'screen');
246         } else {
247             $action->element('link', array('rel' => 'stylesheet',
248                                          'type' => 'text/css',
249                                          'href' => common_path('plugins/MobileProfile/mp-screen.css') . '?version=' . STATUSNET_VERSION,
250                                          'media' => 'screen'));
251         }
252
253         if (file_exists(Theme::file('css/mp-handheld.css'))) {
254             $action->cssLink('css/mp-handheld.css', null, 'handheld');
255         } else {
256             $action->element('link', array('rel' => 'stylesheet',
257                                          'type' => 'text/css',
258                                          'href' => common_path('plugins/MobileProfile/mp-handheld.css') . '?version=' . STATUSNET_VERSION,
259                                          'media' => 'handheld'));
260         }
261
262         return false;
263     }
264
265
266     function onStartShowHeader($action)
267     {
268         if (!$this->serveMobile) {
269             return true;
270         }
271
272         $action->elementStart('div', array('id' => 'header'));
273         $this->_showLogo($action);
274         $this->_showPrimaryNav($action);
275         if (common_logged_in()) {
276             $action->showNoticeForm();
277         }
278         $action->elementEnd('div');
279
280         return false;
281     }
282
283
284     function _showLogo($action)
285     {
286         $action->elementStart('address', 'vcard');
287         $action->elementStart('a', array('class' => 'url home bookmark',
288                                        'href' => common_local_url('public')));
289         if (common_config('site', 'mobilelogo') || 
290             file_exists(Theme::file('logo.png')) || 
291             file_exists(Theme::file('mobilelogo.png'))) {
292
293             $action->element('img', array('class' => 'photo',
294                 'src' => (common_config('site', 'mobilelogo')) ? common_config('site', 'mobilelogo') : 
295                             ((file_exists(Theme::file('mobilelogo.png'))) ? (Theme::path('mobilelogo.png')) : Theme::path('logo.png')),
296                 'alt' => common_config('site', 'name')));
297         }
298         $action->element('span', array('class' => 'fn org'), common_config('site', 'name'));
299         $action->elementEnd('a');
300         $action->elementEnd('address');
301     }
302
303
304     function _showPrimaryNav($action)
305     {
306         $user    = common_current_user();
307         $connect = '';
308         if (common_config('xmpp', 'enabled')) {
309             $connect = 'imsettings';
310         } else if (common_config('sms', 'enabled')) {
311             $connect = 'smssettings';
312         } else if (common_config('twitter', 'enabled')) {
313             $connect = 'twittersettings';
314         }
315
316         $action->elementStart('ul', array('id' => 'site_nav_global_primary'));
317         if ($user) {
318             $action->menuItem(common_local_url('all', array('nickname' => $user->nickname)),
319                             _('Home'));
320             $action->menuItem(common_local_url('profilesettings'),
321                             _('Account'));
322             if ($connect) {
323                 $action->menuItem(common_local_url($connect),
324                                 _('Connect'));
325             }
326             if (common_config('invite', 'enabled')) {
327                 $action->menuItem(common_local_url('invite'),
328                                 _('Invite'));
329             }
330             $action->menuItem(common_local_url('logout'),
331                             _('Logout'));
332         } else {
333             if (!common_config('site', 'closed')) {
334                 $action->menuItem(common_local_url('register'),
335                                 _('Register'));
336             }
337             $action->menuItem(common_local_url('login'),
338                             _('Login'));
339         }
340         if ($user || !common_config('site', 'private')) {
341             $action->menuItem(common_local_url('peoplesearch'),
342                             _('Search'));
343         }
344         $action->elementEnd('ul');
345     }
346
347
348     function onStartShowNoticeFormData($form)
349     {
350         if (!$this->serveMobile) {
351             return true;
352         }
353
354         $form->out->element('textarea', array('id' => 'notice_data-text',
355                                               'cols' => 15,
356                                               'rows' => 4,
357                                               'name' => 'status_textarea'),
358                             ($form->content) ? $form->content : '');
359
360         $contentLimit = Notice::maxContent();
361
362         $form->out->element('script', array('type' => 'text/javascript'),
363                             'maxLength = ' . $contentLimit . ';');
364
365         if ($contentLimit > 0) {
366             $form->out->element('div', array('id' => 'notice_text-count'),
367                                 $contentLimit);
368         }
369
370         if (common_config('attachments', 'uploads')) {
371             if ($this->mobileFeatures['inputfiletype']) {
372                 $form->out->element('label', array('for' => 'notice_data-attach'), _('Attach'));
373                 $form->out->element('input', array('id' => 'notice_data-attach',
374                                                    'type' => 'file',
375                                                    'name' => 'attach',
376                                                    'title' => _('Attach a file')));
377                 $form->out->hidden('MAX_FILE_SIZE', common_config('attachments', 'file_quota'));
378             }
379         }
380         if ($form->action) {
381             $form->out->hidden('notice_return-to', $form->action, 'returnto');
382         }
383         $form->out->hidden('notice_in-reply-to', $form->inreplyto, 'inreplyto');
384
385         return false;
386     }
387
388
389     function onStartShowAside($action)
390     {
391         if ($this->serveMobile) {
392             return false;
393         }
394     }
395
396
397     function onStartShowScripts($action)
398     {
399
400     }
401
402
403     function _common_path($relative, $ssl=false)
404     {
405         $pathpart = (common_config('site', 'path')) ? common_config('site', 'path')."/" : '';
406
407         if (($ssl && (common_config('site', 'ssl') === 'sometimes'))
408             || common_config('site', 'ssl') === 'always') {
409             $proto = 'https';
410             if (is_string(common_config('site', 'sslserver')) &&
411                 mb_strlen(common_config('site', 'sslserver')) > 0) {
412                 $serverpart = common_config('site', 'sslserver');
413             } else {
414                 $serverpart = common_config('site', 'mobileserver');
415             }
416         } else {
417             $proto      = 'http';
418             $serverpart = common_config('site', 'mobileserver');
419         }
420
421         return $proto.'://'.$serverpart.'/'.$pathpart.$relative;
422     }
423 }
424
425
426 ?>