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