]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - plugins/MobileProfile/MobileProfilePlugin.php
Added function to set a list of features the mobile device supports
[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         }
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             }
95             else {
96                 // If they are a mobile device that supports WAP 2.0, 
97                 // serve them MP
98
99                 // XXX: Browser sniffing sucks
100
101                 // I really don't like going through this every page, 
102                 // find a better way
103
104                 // May be better to categorize the devices in terms of 
105                 // low,mid,high-end
106
107                 // Or, detect the mobile devices based on their support for 
108                 // MP 1.0, 1.1, or 1.2 may be ideal. Possible?
109
110                 $this->mobiledevices = array(
111                     'alcatel',
112                     'android',
113                     'audiovox',
114                     'au-mic,',
115                     'avantgo',
116                     'blackberry',
117                     'blazer',
118                     'cldc-',
119                     'danger',
120                     'epoc',
121                     'ericsson',
122                     'ericy',
123                     'iphone',
124                     'ipaq',
125                     'ipod',
126                     'j2me',
127                     'lg',
128                     'midp-',
129                     'mobile',
130                     'mot',
131                     'netfront',
132                     'nitro',
133                     'nokia',
134                     'opera mini',
135                     'palm',
136                     'palmsource',
137                     'panasonic',
138                     'philips',
139                     'pocketpc',
140                     'portalmmm',
141                     'rover',
142                     'samsung',
143                     'sanyo',
144                     'series60',
145                     'sharp',
146                     'sie-',
147                     'smartphone',
148                     'sony',
149                     'symbian',
150                     'up.browser',
151                     'up.link',
152                     'up.link',
153                     'vodafone',
154                     'wap1',
155                     'wap2',
156                     'windows ce'
157                 );
158
159                 $httpuseragent = strtolower($_SERVER['HTTP_USER_AGENT']);
160
161                 foreach($this->mobiledevices as $md) {
162                     if (strstr($httpuseragent, $md) !== false) {
163                         setMobileFeatures($httpuseragent);
164
165                         $this->serveMobile = true;
166                         break;
167                     }
168                 }
169             }
170
171             // If they are okay with MP, and the site has a mobile server, 
172             // redirect there
173             if ($this->serveMobile && 
174                 common_config('site', 'mobileserver') !== false &&
175                 (common_config('site', 'mobileserver') != 
176                     common_config('site', 'server'))) {
177
178                 // FIXME: Redirect to equivalent page on mobile site instead
179                 header("Location: ".$this->_common_path(''));
180                 exit();
181             }
182         }
183
184         if (!$this->serveMobile) {
185             return true;
186         }
187
188         header('Content-Type: '.$type);
189
190         $action->extraHeaders();
191
192         $action->startXML('html',
193                         '-//WAPFORUM//DTD XHTML Mobile 1.0//EN',
194                         $this->DTD);
195
196         $language = $action->getLanguage();
197
198         $action->elementStart('html', array('xmlns' => 'http://www.w3.org/1999/xhtml',
199                                             'xml:lang' => $language));
200
201         return false;
202     }
203
204
205     function setMobileFeatures($useragent)
206     {
207         /* List of devices that support input type="file" */
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         }
247         else {
248             $action->element('link', array('rel' => 'stylesheet',
249                                          'type' => 'text/css',
250                                          'href' => common_path('plugins/MobileProfile/mp-screen.css') . '?version=' . STATUSNET_VERSION,
251                                          'media' => 'screen'));
252         }
253
254         if (file_exists(theme_file('css/mp-handheld.css'))) {
255             $action->cssLink('css/mp-handheld.css', null, 'handheld');
256         }
257         else {
258             $action->element('link', array('rel' => 'stylesheet',
259                                          'type' => 'text/css',
260                                          'href' => common_path('plugins/MobileProfile/mp-handheld.css') . '?version=' . STATUSNET_VERSION,
261                                          'media' => 'handheld'));
262         }
263
264         return false;
265     }
266
267
268     function onStartShowHeader($action)
269     {
270         if (!$this->serveMobile) {
271             return true;
272         }
273
274         $action->elementStart('div', array('id' => 'header'));
275         $this->_showLogo($action);
276         $this->_showPrimaryNav($action);
277         if (common_logged_in()) {
278             $action->showNoticeForm();
279         }
280         $action->elementEnd('div');
281
282         return false;
283     }
284
285
286     function _showLogo($action)
287     {
288         $action->elementStart('address', 'vcard');
289         $action->elementStart('a', array('class' => 'url home bookmark',
290                                        'href' => common_local_url('public')));
291         if (common_config('site', 'mobilelogo') || 
292             file_exists(theme_file('logo.png')) || 
293             file_exists(theme_file('mobilelogo.gif'))) {
294
295             $action->element('img', array('class' => 'photo',
296                 'src' => (common_config('site', 'mobilelogo')) ? common_config('site', 'mobilelogo') : 
297                             ((file_exists(theme_file('mobilelogo.png'))) ? (theme_path('mobilelogo.png')) : theme_path('logo.png')),
298                 'alt' => common_config('site', 'name')));
299         }
300         $action->element('span', array('class' => 'fn org'), common_config('site', 'name'));
301         $action->elementEnd('a');
302         $action->elementEnd('address');
303     }
304
305
306     function _showPrimaryNav($action) {
307         $user = common_current_user();
308         $connect = '';
309         if (common_config('xmpp', 'enabled')) {
310             $connect = 'imsettings';
311         } else if (common_config('sms', 'enabled')) {
312             $connect = 'smssettings';
313         } else if (common_config('twitter', 'enabled')) {
314             $connect = 'twittersettings';
315         }
316
317         $action->elementStart('ul', array('id' => 'site_nav_global_primary'));
318         if ($user) {
319             $action->menuItem(common_local_url('all', array('nickname' => $user->nickname)),
320                             _('Home'));
321             $action->menuItem(common_local_url('profilesettings'),
322                             _('Account'));
323             if ($connect) {
324                 $action->menuItem(common_local_url($connect),
325                                 _('Connect'));
326             }
327             if (common_config('invite', 'enabled')) {
328                 $action->menuItem(common_local_url('invite'),
329                                 _('Invite'));
330             }
331             $action->menuItem(common_local_url('logout'),
332                             _('Logout'));
333         }
334         else {
335             if (!common_config('site', 'closed')) {
336                 $action->menuItem(common_local_url('register'),
337                                 _('Register'));
338             }
339             $action->menuItem(common_local_url('login'),
340                             _('Login'));
341         }
342         if ($user || !common_config('site', 'private')) {
343             $action->menuItem(common_local_url('peoplesearch'),
344                             _('Search'));
345         }
346         $action->elementEnd('ul');
347     }
348
349
350     function onStartShowNoticeFormData($form)
351     {
352         if (!$this->serveMobile) {
353             return true;
354         }
355
356         $form->out->element('textarea', array('id' => 'notice_data-text',
357                                               'cols' => 35,
358                                               'rows' => 4,
359                                               'name' => 'status_textarea'),
360                             ($form->content) ? $form->content : '');
361
362         $contentLimit = Notice::maxContent();
363
364         $form->out->element('script', array('type' => 'text/javascript'),
365                             'maxLength = ' . $contentLimit . ';');
366
367         if ($contentLimit > 0) {
368             $form->out->element('div', array('id' => 'notice_text-count'),
369                                 $contentLimit);
370         }
371
372         if (common_config('attachments', 'uploads')) {
373             $form->out->element('label', array('for' => 'notice_data-attach'),_('Attach'));
374             $form->out->element('input', array('id' => 'notice_data-attach',
375                                                'type' => 'file',
376                                                'name' => 'attach',
377                                                'title' => _('Attach a file')));
378             $form->out->hidden('MAX_FILE_SIZE', common_config('attachments', 'file_quota'));
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 ?>