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