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