[TASK] Remove function index
[Packages/TYPO3.CMS.git] / typo3 / sysext / cms / tslib / media / scripts / wapversionLib.inc
1 <?php
2 /***************************************************************
3 *  Copyright notice
4 *
5 *  (c) 1999-2009 Kasper Skårhøj (kasperYYYY@typo3.com)
6 *  All rights reserved
7 *
8 *  This script is part of the TYPO3 project. The TYPO3 project is
9 *  free software; you can redistribute it and/or modify
10 *  it under the terms of the GNU General Public License as published by
11 *  the Free Software Foundation; either version 2 of the License, or
12 *  (at your option) any later version.
13 *
14 *  The GNU General Public License can be found at
15 *  http://www.gnu.org/copyleft/gpl.html.
16 *  A copy is found in the textfile GPL.txt and important notices to the license
17 *  from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 *  This script is distributed in the hope that it will be useful,
21 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
22 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23 *  GNU General Public License for more details.
24 *
25 *  This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27 /**
28  * Contains class for creating WAP pages for TYPO3
29  *
30  * Revised for TYPO3 3.6 June/2003 by Kasper Skårhøj
31  *
32  * @author      Kasper Skårhøj <kasperYYYY@typo3.com>
33  */
34 /**
35  * Class that creates the current page and content element records as an WML structure using the library "t3lib_xml"
36  * It is demonstrated in use in the testsite package on page "59"
37  * The static template "plugin.alt.wap" is used to trigger this WML creation as well. That template contains this set of TypoScript lines which triggers the WML creation and disables all regular HTML headers
38  *
39  * ## Set up page/type:
40  * alt_wap >
41  * alt_wap = PAGE
42  * alt_wap {
43  *   typeNum=97
44  *   config.disableAllHeaderCode = 1
45  *   config.additionalHeaders = Content-type: text/vnd.wap.wml
46  *
47  *   ## Includes the newsLib:
48  *   includeLibs.alt_wap = media/scripts/wapversionLib.inc
49  *
50  *   ## Inserting the USER cObject for WAP/XML rendering
51  *   10 = USER
52  *   10 {
53  *     userFunc = user_wapversion->main_wapversion
54  *     debug=0
55  *     preTitle = T3WAP
56  *     navLabels.prev = Prev
57  *     navLabels.next = Next
58  *     navLabels.up = Up
59  *   }
60  * }
61  *
62  * NOTICE:
63  *
64  * In the static template "plugin.alt.wap" there is a part in the end looking like this:
65  *
66  * ## If the browser is a WAP-device,
67  * [device=wap]
68  * alt_wap.typeNum=0
69  * [global]
70  *
71  * This means that IF the device coming to the URL is a WAP device they will get wap content even if they don't specify "&type=97" since the typeNum is changed to zero here!
72  * In fact they CANNOT get any wap-content at "&type=97" anymore! This has been a source of error and confusion for many people
73  *
74  * @package TYPO3
75  * @subpackage tslib
76  * @author      Kasper Skårhøj <kasperYYYY@typo3.com>
77  */
78 class user_wapversion {
79         var $cObj;              // The backReference to the mother cObj object set at call time
80
81         var $idx=0;
82
83         /**
84          * Main function, called from TypoScript
85          *
86          * @param       string          Empty, ignore.
87          * @param       array           TypoScript properties for this content object/function call
88          * @return      string          WML content
89          */
90         function main_wapversion($content,$conf)        {
91                 $GLOBALS['TSFE']->set_no_cache();
92
93                 $xmlObj = t3lib_div::makeInstance('t3lib_xml', 'wml');
94                 $xmlObj->XMLdebug=$conf['debug'];
95
96                         // Creating top level object
97                 $xmlObj->WAPHeader();
98
99                         // Creating back button:
100                 $xmlObj->WAPback();
101
102                 $pageRec = $GLOBALS['TSFE']->page;
103                 if ($GLOBALS['TSFE']->idParts[1])       {
104                                 // Creating content card:
105                         $xmlObj->newLevel('card',1,array(
106                                 'id' => 'content',
107                                 'title' => ($conf['preTitle']?$conf['preTitle'].': ':'').$pageRec['title']
108                         ));
109
110                         $cParts = $this->contentAll();
111                         $pointer = t3lib_div::intInRange($GLOBALS['TSFE']->idParts[1],1,10000);
112
113                         $msg='';
114                         if ($pointer-1) {$msg.=$this->navLink(htmlspecialchars($conf['navLabels.']['prev']),$pointer-1).' ';}
115                         $msg.=$this->navLink(htmlspecialchars($conf['navLabels.']['up']),0).' ';
116                         if ($pointer<count($cParts))    {$msg.=$this->navLink(htmlspecialchars($conf['navLabels.']['next']),$pointer+1).' ';}
117                         $msg.= '['.$pointer.'/'.count($cParts).']<br/>';
118
119                         $xmlObj->lines[] = $this->paragraph($msg);
120                         $xmlObj->lines[] = $this->paragraph($cParts[$pointer-1]);
121                         $xmlObj->lines[] = $this->paragraph('<br/>'.$msg);
122
123                         $xmlObj->newLevel('card',0);
124                 } else {
125                                 // Creating menu card:
126                         $xmlObj->newLevel('card',1,array(
127                                 'id' => 'menu',
128                                 'title' => ($conf['preTitle']?$conf['preTitle'].': ':'').$pageRec['title']
129                         ));
130                         $xmlObj->lines[] = $this->contentAbstract();
131                         $xmlObj->lines[] = '<p><br/>'.$this->bold('Menu:').'</p>';
132                         $xmlObj->lines[] = $this->menuCurrentLevel($xmlObj->Icode);
133                         $xmlObj->newLevel('card',0);
134                 }
135
136                         // Footer
137                 $xmlObj->renderFooter();
138                 return $xmlObj->getResult();
139
140         }
141
142         /**
143          * Getting abstract of the first content elements header and bodytext for the menu
144          *
145          * @return      string          WML string
146          */
147         function contentAbstract()      {
148                 $res = $this->getContentResult('tt_content');
149                 $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
150                 $out = $this->bold(t3lib_div::fixed_lgd_cs(htmlspecialchars($row['header']),20)).'<br/>';
151                 $out.= t3lib_div::fixed_lgd_cs(htmlspecialchars($row['bodytext']),50);
152                 $out = '<p>'.$out.' <a href="'.htmlspecialchars('?id='.$GLOBALS['TSFE']->id.',1.'.$GLOBALS['TSFE']->type).'">[more]</a></p>';
153                 return $out;
154         }
155
156         /**
157          * Returns all page content, but in an array where the content is divided into chunks or a max length (for WAP clients with limited memory capabilities)
158          * Content is then displayed using the pointer value found in $GLOBALS['TSFE']->idParts[1], see main_wapversion()
159          *
160          * @param       integer         Max length of each content chunk
161          * @return      array           Array with the page content divided into chucks WML code (default length equals $chunkLgd; 850)
162          * @see main_wapversion()
163          */
164         function contentAll($chunkLgd=850)      {
165                 $res = $this->getContentResult('tt_content');
166                 $overlap=5;
167                 $idx=0;
168                 $out=array();
169                 while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))       {
170                                 // Header:
171                         $get = '<br/>'.$this->cHeader($row['header']).'<br/>';
172                         if (strlen($out[$idx].$get)>$chunkLgd)  {
173                                 $idx++;
174                         }
175                         $out[$idx].=$get;
176
177                         switch($row['CType'])   {
178                                 case 'text':
179                                 case 'bullets':
180                                 case 'table':
181                                         $bodyText = $row['bodytext'];
182                                 break;
183                                 case 'textpic':
184                                 case 'image':
185                                         if ($row['CType']!='image')             {$bodyText = $row['bodytext'];}
186                                         $bodyText.= chr(10).'['.count(explode(',',$row['image'])).'images, caption: '.$row['imagecaption'].']';
187                                 break;
188                                 case 'header':
189                                         $bodyText=$row['subheader'];
190                                 break;
191                                 default:
192                                         $bodyText = '[Un-rendered element, '.$row['CType'].']';
193                                 break;
194                         }
195
196                                 // Bodytext:
197                         $get = $this->cBodytext($bodyText).'<br/>';
198                         $diff = $chunkLgd - strlen($out[$idx]);
199
200                         if ($diff>strlen($get)) {
201                                 $out[$idx].=$get;
202                         } else {
203                                 $out[$idx].=$this->cBodytext($bodyText,0,$diff+$overlap).'<br/>';
204
205                                 $safe=0;
206                                 do {
207                                         $idx++;
208                                         $out[$idx].=$this->cBodytext($bodyText,$diff+($safe*$chunkLgd)-$overlap,$chunkLgd+$overlap).'<br/>';
209                                         $safe++;
210                                         if ($safe>100) break;
211                                 } while (strlen($out[$idx])>$chunkLgd);
212                         }
213                 }
214                 return $out;
215         }
216
217         /**
218          * Formats the header for a content element
219          *
220          * @param       string          Header value to format
221          * @return      string          Returns the formatted version, stripped from tags and htmlspecialchar()'ed
222          * @see contentAll()
223          */
224         function cHeader($str)  {
225                 $out = $this->bold(htmlspecialchars(strip_tags($str)));
226                 return $out;
227         }
228
229         /**
230          * Formats the bodytext for a content element
231          *
232          * @param       string          The bodytext content
233          * @param       integer         Position where to start in the bodytext stream. If larger than zero a prefix, "...", is prepended.
234          * @param       integer         Max length
235          * @return      string          Prepared content
236          * @see contentAll()
237          */
238         function cBodytext($str,$start=0,$max=0)        {
239                 $out = t3lib_div::fixed_lgd_cs(($start?'...':'').substr($this->nl2br(htmlspecialchars(strip_tags($str))),$start),($max?$max:100000));
240                 $out = str_replace('&','',$out);        // No & in WAP docs??? --> or maybe just htmlspecialchar() things as the LAST thing instead!)
241                 return $out;
242         }
243
244         /**
245          * Local version of ml2br(). Replaces linebreaks with <br/> tags.
246          *
247          * @param       string          The input string to process
248          * @return      string          The processed value returned.
249          */
250         function nl2br($str)    {
251                 return str_replace(chr(10),'<br/>',$str);
252         }
253
254         /**
255          * Selects all records from $table having the current page id as PID (records belonging to that page)
256          * Used to select content elements from "tt_content"
257          *
258          * @param       string          A tablename found in $GLOBALS['TCA']
259          * @return      pointer         A database resource pointer
260          */
261         function getContentResult($table) {
262                 if ($GLOBALS['TCA'][$table])    {
263                         $orderBy = ($GLOBALS['TCA'][$table]['ctrl']['sortby']
264                                 ? 'ORDER BY '.$GLOBALS['TCA'][$table]['ctrl']['sortby']
265                                 : $GLOBALS['TCA'][$table]['ctrl']['default_sortby']);
266                         $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $table, 'pid='.intval($GLOBALS['TSFE']->id).$this->cObj->enableFields($table), '', $GLOBALS['TYPO3_DB']->stripOrderBy($orderBy));
267                         return $res;
268                 }
269         }
270
271         /**
272          * Simulates bold type - basically setting it in uppercase
273          *
274          * @param       string          The string for format in "bold" (uppercase)
275          * @return      string          Processed output.
276          */
277         function bold($str)     {
278                 return strtoupper($str);
279         }
280
281         /**
282          * Wraps a string in <p>...</p> tags
283          *
284          * @param       string          The input string
285          * @return      string          The wrapped string
286          */
287         function paragraph($str)        {
288                 return '<p>'.$str.'</p>';
289         }
290
291         /**
292          * Adds a linebreak character to the end of $str
293          *
294          * @param       string          The string/line
295          * @return      string          The input string with '<br/>' prepended
296          */
297         function line($str)     {
298                 return $str.'<br/>';
299         }
300
301         /**
302          * Creates a navigation link to the next part of the page content!
303          *
304          * @param       string          The link text
305          * @param       integer         The pointer value
306          * @return      string          The input string, linked with the pointer value to the current page.
307          */
308         function navLink($str,$pointer) {
309                 return '<a href="'.htmlspecialchars('?id='.$GLOBALS['TSFE']->id.','.$pointer.'.'.$GLOBALS['TSFE']->type).'">'.$str.'</a>';
310         }
311
312         /**
313          * Creates a menu for the current pagelevel. Navigation is both a path-menu (rootline) and a menu of current page subpages.
314          *
315          * @param       string          Indentation prefix string per menu item.
316          * @return      string          A paragraph with the menu items inside.
317          */
318         function menuCurrentLevel($indent)      {
319                 $rL = $GLOBALS['TSFE']->config['rootLine'];
320                 $preSpace='';
321                 $out=array();
322                         // Hierarchy menu
323                 foreach ($rL as $level => $data) {
324                         $preSign = count($rL)-1 > $level ? '-' : '>';
325                         $menuItem = htmlspecialchars($preSign.' '.$data['title']);
326                         $menuItem = $this->link($preSpace.$menuItem,$data['uid']);
327                         $out[]=$indent.$this->line($menuItem);
328                         $preSpace.='..';
329                 }
330                         // Current page menu:
331                 $menu = $this->cleanMenuArray($GLOBALS['TSFE']->sys_page->getMenu($GLOBALS['TSFE']->id));
332                 foreach ($menu as $data) {
333                         $preSign = count($this->cleanMenuArray($GLOBALS['TSFE']->sys_page->getMenu($data['uid']))) ? '+' : '*';
334                         $menuItem = htmlspecialchars($preSign.' '.$data['title']);
335                         $menuItem = $this->link($preSpace.$menuItem,$data['uid']);
336                         $out[]=$indent.$this->line($menuItem);
337                 }
338                 return $this->paragraph(implode(chr(10),$out));
339         }
340
341         /**
342          * Creates a link around the input string to another page/deck
343          * Used to create menus
344          *
345          * @param       string          The string to be wrapped in <a> tags
346          * @param       integer         The page id to link to
347          * @param       string          The deck name, if any
348          * @return      string          String wrapped in <a> tags
349          * @see menuCurrentLevel()
350          */
351         function link($str,$id,$deck='')        {
352                 if ($GLOBALS['TSFE']->id==$id && $deck) {
353                         $out = '<a href="#'.$deck.'">'.$str.'</a>';
354                 } else {
355                         $type = $GLOBALS['TSFE']->type;
356                         $out = '<a href="'.htmlspecialchars('?id='.$id.','.($GLOBALS['TSFE']->id==$id?1:$this->idx).'.'.$type).'">'.$str.'</a>';
357                 }
358                 return $out;
359         }
360
361         /**
362          * Cleaning up the menu array returned from sys_page->getMenu(). Removing page types with doktype "5" (not in menu)
363          *
364          * @param       array           Menu item array
365          * @return      array           New menu item array with doktype-5 elements removed.
366          */
367         function cleanMenuArray($menu)  {
368                 reset($menu);
369                 $newMenu=array();
370                 while(list(,$data)=each($menu)) {
371                         if ($data['doktype'] != t3lib_pageSelect::DOKTYPE_HIDE_IN_MENU && !$data['nav_hide']) {
372                                 $newMenu[]=$data;
373                         }
374                 }
375                 return $newMenu;
376         }
377 }
378
379
380 // AND HERE just some debugging content: Basically a valid WML deck.
381
382                 /*
383 switch($id)     {
384         case 1:
385                 <wml>
386                         <card id="Hallo" ontimer="#Login" title="wapportal.dk">
387                                 <timer value="35"/>
388                                 <p>
389                                         <img src="/images/logo.wbmp" alt="WAPPORTAL"/>
390                                         asf asdf asdf
391                                 </p>
392                         </card>
393                         <card id="Login" title="wapportal.dk" newcontext="true">
394                                 <p>Mobil nr:
395                                         <input name="Login" title="Mobil nr:" value="" format="*N" size="15"/>Kodeord:
396                                         <input name="Passwd" title="Kodeord:" value="" type="password" format="*N" size="12"/>
397                                         <anchor>Login !<go href="/wap/portal/DeckPortal/menu.wml?sid=FGBNRru&amp;rnd=107915&amp;login=$(Login:u)&amp;pwd=$(Passwd:u)"/></anchor>
398                                         <br/>
399                                         <anchor>G&#xe6;st<go href="/wap/portal/DeckPortal/menu.wml?sid=FGBNRru&amp;rnd=107916&amp;login=visitor&amp;pwd=visitor"></go></anchor>
400                                 </p>
401                         </card>
402                 </wml>
403         break;
404         default:
405                 <wml>
406                 <template>
407                         <do type="accept" label="Back"><prev/></do>
408                 </template>
409                 <card id="index1" title="Hovedside">
410                         <p>Hej Kasper.
411                         Dette er noget
412                         <img src="/images/logo.wbmp" alt="WAPPORTAL"/>
413                          tekst.</p>
414
415                 </card>
416                 </wml>
417         break;
418 }
419 */
420
421
422
423
424 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['media/scripts/wapversionLib.inc'])) {
425         include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['media/scripts/wapversionLib.inc']);
426 }
427
428
429 ?>