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