TYPO3 API  SVNRelease
wapversionLib.inc
Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 1999-2009 Kasper Skårhøj (kasperYYYY@typo3.com)
00006 *  All rights reserved
00007 *
00008 *  This script is part of the TYPO3 project. The TYPO3 project is
00009 *  free software; you can redistribute it and/or modify
00010 *  it under the terms of the GNU General Public License as published by
00011 *  the Free Software Foundation; either version 2 of the License, or
00012 *  (at your option) any later version.
00013 *
00014 *  The GNU General Public License can be found at
00015 *  http://www.gnu.org/copyleft/gpl.html.
00016 *  A copy is found in the textfile GPL.txt and important notices to the license
00017 *  from the author is found in LICENSE.txt distributed with these scripts.
00018 *
00019 *
00020 *  This script is distributed in the hope that it will be useful,
00021 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023 *  GNU General Public License for more details.
00024 *
00025 *  This copyright notice MUST APPEAR in all copies of the script!
00026 ***************************************************************/
00027 /**
00028  * Contains class for creating WAP pages for TYPO3
00029  *
00030  * $Id: wapversionLib.inc 5634 2009-06-26 13:25:08Z ohader $
00031  * Revised for TYPO3 3.6 June/2003 by Kasper Skårhøj
00032  *
00033  * @author  Kasper Skårhøj <kasperYYYY@typo3.com>
00034  */
00035 /**
00036  * [CLASS/FUNCTION INDEX of SCRIPT]
00037  *
00038  *
00039  *
00040  *  129: class user_wapversion
00041  *  141:     function main_wapversion($content,$conf)
00042  *  200:     function contentAbstract()
00043  *  217:     function contentAll($chunkLgd=850)
00044  *  277:     function cHeader($str)
00045  *  291:     function cBodytext($str,$start=0,$max=0)
00046  *  303:     function nl2br($str)
00047  *  314:     function getContentResult($table)
00048  *  329:     function bold($str)
00049  *  339:     function paragraph($str)
00050  *  349:     function line($str)
00051  *  360:     function navLink($str,$pointer)
00052  *  370:     function menuCurrentLevel($indent)
00053  *  405:     function link($str,$id,$deck='')
00054  *  421:     function cleanMenuArray($menu)
00055  *
00056  * TOTAL FUNCTIONS: 14
00057  * (This index is automatically created/updated by the extension "extdeveval")
00058  *
00059  */
00060 /**
00061  * Class that creates the current page and content element records as an WML structure using the library "t3lib_xml"
00062  * It is demonstrated in use in the testsite package on page "59"
00063  * 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
00064  *
00065  * ## Set up page/type:
00066  * alt_wap >
00067  * alt_wap = PAGE
00068  * alt_wap {
00069  *   typeNum=97
00070  *   config.disableAllHeaderCode = 1
00071  *   config.additionalHeaders = Content-type: text/vnd.wap.wml
00072  *
00073  *   ## Includes the newsLib:
00074  *   includeLibs.alt_wap = media/scripts/wapversionLib.inc
00075  *
00076  *   ## Inserting the USER cObject for WAP/XML rendering
00077  *   10 = USER
00078  *   10 {
00079  *     userFunc = user_wapversion->main_wapversion
00080  *     debug=0
00081  *     preTitle = T3WAP
00082  *     navLabels.prev = Prev
00083  *     navLabels.next = Next
00084  *     navLabels.up = Up
00085  *   }
00086  * }
00087  *
00088  * NOTICE:
00089  *
00090  * In the static template "plugin.alt.wap" there is a part in the end looking like this:
00091  *
00092  * ## If the browser is a WAP-device,
00093  * [device=wap]
00094  * alt_wap.typeNum=0
00095  * [global]
00096  *
00097  * 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!
00098  * In fact they CANNOT get any wap-content at "&type=97" anymore! This has been a source of error and confusion for many people
00099  *
00100  * @package TYPO3
00101  * @subpackage tslib
00102  * @author  Kasper Skårhøj <kasperYYYY@typo3.com>
00103  */
00104 class user_wapversion {
00105     var $cObj;      // The backReference to the mother cObj object set at call time
00106 
00107     var $idx=0;
00108 
00109     /**
00110      * Main function, called from TypoScript
00111      *
00112      * @param   string      Empty, ignore.
00113      * @param   array       TypoScript properties for this content object/function call
00114      * @return  string      WML content
00115      */
00116     function main_wapversion($content,$conf)    {
00117         $GLOBALS['TSFE']->set_no_cache();
00118 
00119         $xmlObj = t3lib_div::makeInstance('t3lib_xml', 'wml');
00120         $xmlObj->XMLdebug=$conf['debug'];
00121 
00122             // Creating top level object
00123         $xmlObj->WAPHeader();
00124 
00125             // Creating back button:
00126         $xmlObj->WAPback();
00127 
00128         $pageRec = $GLOBALS['TSFE']->page;
00129         if ($GLOBALS['TSFE']->idParts[1])   {
00130                 // Creating content card:
00131             $xmlObj->newLevel('card',1,array(
00132                 'id' => 'content',
00133                 'title' => ($conf['preTitle']?$conf['preTitle'].': ':'').$pageRec['title']
00134             ));
00135 
00136             $cParts = $this->contentAll();
00137             $pointer = t3lib_div::intInRange($GLOBALS['TSFE']->idParts[1],1,10000);
00138 
00139             $msg='';
00140             if ($pointer-1) {$msg.=$this->navLink(htmlspecialchars($conf['navLabels.']['prev']),$pointer-1).' ';}
00141             $msg.=$this->navLink(htmlspecialchars($conf['navLabels.']['up']),0).' ';
00142             if ($pointer<count($cParts))    {$msg.=$this->navLink(htmlspecialchars($conf['navLabels.']['next']),$pointer+1).' ';}
00143             $msg.= '['.$pointer.'/'.count($cParts).']<br/>';
00144 
00145             $xmlObj->lines[] = $this->paragraph($msg);
00146             $xmlObj->lines[] = $this->paragraph($cParts[$pointer-1]);
00147             $xmlObj->lines[] = $this->paragraph('<br/>'.$msg);
00148 
00149             $xmlObj->newLevel('card',0);
00150         } else {
00151                 // Creating menu card:
00152             $xmlObj->newLevel('card',1,array(
00153                 'id' => 'menu',
00154                 'title' => ($conf['preTitle']?$conf['preTitle'].': ':'').$pageRec['title']
00155             ));
00156             $xmlObj->lines[] = $this->contentAbstract();
00157             $xmlObj->lines[] = '<p><br/>'.$this->bold('Menu:').'</p>';
00158             $xmlObj->lines[] = $this->menuCurrentLevel($xmlObj->Icode);
00159             $xmlObj->newLevel('card',0);
00160         }
00161 
00162             // Footer
00163         $xmlObj->renderFooter();
00164         return $xmlObj->getResult();
00165 
00166     }
00167 
00168     /**
00169      * Getting abstract of the first content elements header and bodytext for the menu
00170      *
00171      * @return  string      WML string
00172      */
00173     function contentAbstract()  {
00174         $res = $this->getContentResult('tt_content');
00175         $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
00176         $out = $this->bold(t3lib_div::fixed_lgd_cs(htmlspecialchars($row['header']),20)).'<br/>';
00177         $out.= t3lib_div::fixed_lgd_cs(htmlspecialchars($row['bodytext']),50);
00178         $out = '<p>'.$out.' <a href="'.htmlspecialchars('?id='.$GLOBALS['TSFE']->id.',1.'.$GLOBALS['TSFE']->type).'">[more]</a></p>';
00179         return $out;
00180     }
00181 
00182     /**
00183      * 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)
00184      * Content is then displayed using the pointer value found in $GLOBALS['TSFE']->idParts[1], see main_wapversion()
00185      *
00186      * @param   integer     Max length of each content chunk
00187      * @return  array       Array with the page content divided into chucks WML code (default length equals $chunkLgd; 850)
00188      * @see main_wapversion()
00189      */
00190     function contentAll($chunkLgd=850)  {
00191         $res = $this->getContentResult('tt_content');
00192         $overlap=5;
00193         $idx=0;
00194         $out=array();
00195         while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))   {
00196                 // Header:
00197             $get = '<br/>'.$this->cHeader($row['header']).'<br/>';
00198             if (strlen($out[$idx].$get)>$chunkLgd)  {
00199                 $idx++;
00200             }
00201             $out[$idx].=$get;
00202 
00203             switch($row['CType'])   {
00204                 case 'text':
00205                 case 'bullets':
00206                 case 'table':
00207                     $bodyText = $row['bodytext'];
00208                 break;
00209                 case 'textpic':
00210                 case 'image':
00211                     if ($row['CType']!='image')     {$bodyText = $row['bodytext'];}
00212                     $bodyText.= chr(10).'['.count(explode(',',$row['image'])).'images, caption: '.$row['imagecaption'].']';
00213                 break;
00214                 case 'header':
00215                     $bodyText=$row['subheader'];
00216                 break;
00217                 default:
00218                     $bodyText = '[Un-rendered element, '.$row['CType'].']';
00219                 break;
00220             }
00221 
00222                 // Bodytext:
00223             $get = $this->cBodytext($bodyText).'<br/>';
00224             $diff = $chunkLgd - strlen($out[$idx]);
00225 
00226             if ($diff>strlen($get)) {
00227                 $out[$idx].=$get;
00228             } else {
00229                 $out[$idx].=$this->cBodytext($bodyText,0,$diff+$overlap).'<br/>';
00230 
00231                 $safe=0;
00232                 do {
00233                     $idx++;
00234                     $out[$idx].=$this->cBodytext($bodyText,$diff+($safe*$chunkLgd)-$overlap,$chunkLgd+$overlap).'<br/>';
00235                     $safe++;
00236                     if ($safe>100) break;
00237                 } while (strlen($out[$idx])>$chunkLgd);
00238             }
00239         }
00240         return $out;
00241     }
00242 
00243     /**
00244      * Formats the header for a content element
00245      *
00246      * @param   string      Header value to format
00247      * @return  string      Returns the formatted version, stripped from tags and htmlspecialchar()'ed
00248      * @see contentAll()
00249      */
00250     function cHeader($str)  {
00251         $out = $this->bold(htmlspecialchars(strip_tags($str)));
00252         return $out;
00253     }
00254 
00255     /**
00256      * Formats the bodytext for a content element
00257      *
00258      * @param   string      The bodytext content
00259      * @param   integer     Position where to start in the bodytext stream. If larger than zero a prefix, "...", is prepended.
00260      * @param   integer     Max length
00261      * @return  string      Prepared content
00262      * @see contentAll()
00263      */
00264     function cBodytext($str,$start=0,$max=0)    {
00265         $out = t3lib_div::fixed_lgd_cs(($start?'...':'').substr($this->nl2br(htmlspecialchars(strip_tags($str))),$start),($max?$max:100000));
00266         $out = str_replace('&','',$out);    // No & in WAP docs??? --> or maybe just htmlspecialchar() things as the LAST thing instead!)
00267         return $out;
00268     }
00269 
00270     /**
00271      * Local version of ml2br(). Replaces linebreaks with <br/> tags.
00272      *
00273      * @param   string      The input string to process
00274      * @return  string      The processed value returned.
00275      */
00276     function nl2br($str)    {
00277         return str_replace(chr(10),'<br/>',$str);
00278     }
00279 
00280     /**
00281      * Selects all records from $table having the current page id as PID (records belonging to that page)
00282      * Used to select content elements from "tt_content"
00283      *
00284      * @param   string      A tablename found in $TCA
00285      * @return  pointer     A database resource pointer
00286      */
00287     function getContentResult($table) {
00288         global $TCA;
00289         if ($TCA[$table])   {
00290             $orderBy = $TCA[$table]['ctrl']['sortby'] ? 'ORDER BY '.$TCA[$table]['ctrl']['sortby'] : $TCA[$table]['ctrl']['default_sortby'];
00291             $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $table, 'pid='.intval($GLOBALS['TSFE']->id).$this->cObj->enableFields($table), '', $GLOBALS['TYPO3_DB']->stripOrderBy($orderBy));
00292             return $res;
00293         }
00294     }
00295 
00296     /**
00297      * Simulates bold type - basically setting it in uppercase
00298      *
00299      * @param   string      The string for format in "bold" (uppercase)
00300      * @return  string      Processed output.
00301      */
00302     function bold($str) {
00303         return strtoupper($str);
00304     }
00305 
00306     /**
00307      * Wraps a string in <p>...</p> tags
00308      *
00309      * @param   string      The input string
00310      * @return  string      The wrapped string
00311      */
00312     function paragraph($str)    {
00313         return '<p>'.$str.'</p>';
00314     }
00315 
00316     /**
00317      * Adds a linebreak character to the end of $str
00318      *
00319      * @param   string      The string/line
00320      * @return  string      The input string with '<br/>' prepended
00321      */
00322     function line($str) {
00323         return $str.'<br/>';
00324     }
00325 
00326     /**
00327      * Creates a navigation link to the next part of the page content!
00328      *
00329      * @param   string      The link text
00330      * @param   integer     The pointer value
00331      * @return  string      The input string, linked with the pointer value to the current page.
00332      */
00333     function navLink($str,$pointer) {
00334         return '<a href="'.htmlspecialchars('?id='.$GLOBALS['TSFE']->id.','.$pointer.'.'.$GLOBALS['TSFE']->type).'">'.$str.'</a>';
00335     }
00336 
00337     /**
00338      * Creates a menu for the current pagelevel. Navigation is both a path-menu (rootline) and a menu of current page subpages.
00339      *
00340      * @param   string      Indentation prefix string per menu item.
00341      * @return  string      A paragraph with the menu items inside.
00342      */
00343     function menuCurrentLevel($indent)  {
00344         $rL = $GLOBALS['TSFE']->config['rootLine'];
00345         $preSpace='';
00346         $out=array();
00347             // Hierarchy menu
00348         foreach ($rL as $level => $data) {
00349             $preSign = count($rL)-1 > $level ? '-' : '>';
00350             $menuItem = htmlspecialchars($preSign.' '.$data['title']);
00351             $menuItem = $this->link($preSpace.$menuItem,$data['uid']);
00352             $out[]=$indent.$this->line($menuItem);
00353             $preSpace.='..';
00354         }
00355             // Current page menu:
00356         $menu = $this->cleanMenuArray($GLOBALS['TSFE']->sys_page->getMenu($GLOBALS['TSFE']->id));
00357         foreach ($menu as $data) {
00358             $preSign = count($this->cleanMenuArray($GLOBALS['TSFE']->sys_page->getMenu($data['uid']))) ? '+' : '*';
00359             $menuItem = htmlspecialchars($preSign.' '.$data['title']);
00360             $menuItem = $this->link($preSpace.$menuItem,$data['uid']);
00361             $out[]=$indent.$this->line($menuItem);
00362         }
00363         return $this->paragraph(implode(chr(10),$out));
00364     }
00365 
00366     /**
00367      * Creates a link around the input string to another page/deck
00368      * Used to create menus
00369      *
00370      * @param   string      The string to be wrapped in <a> tags
00371      * @param   integer     The page id to link to
00372      * @param   string      The deck name, if any
00373      * @return  string      String wrapped in <a> tags
00374      * @see menuCurrentLevel()
00375      */
00376     function link($str,$id,$deck='')    {
00377         if ($GLOBALS['TSFE']->id==$id && $deck) {
00378             $out = '<a href="#'.$deck.'">'.$str.'</a>';
00379         } else {
00380             $type = $GLOBALS['TSFE']->type;
00381             $out = '<a href="'.htmlspecialchars('?id='.$id.','.($GLOBALS['TSFE']->id==$id?1:$this->idx).'.'.$type).'">'.$str.'</a>';
00382         }
00383         return $out;
00384     }
00385 
00386     /**
00387      * Cleaning up the menu array returned from sys_page->getMenu(). Removing page types with doktype "5" (not in menu)
00388      *
00389      * @param   array       Menu item array
00390      * @return  array       New menu item array with doktype-5 elements removed.
00391      */
00392     function cleanMenuArray($menu)  {
00393         $newMenu=array();
00394         foreach ($menu as $data) {
00395             if ($data['doktype'] != t3lib_pageSelect::DOKTYPE_HIDE_IN_MENU && !$data['nav_hide']) {
00396                 $newMenu[]=$data;
00397             }
00398         }
00399         return $newMenu;
00400     }
00401 }
00402 
00403 
00404 // AND HERE just some debugging content: Basically a valid WML deck.
00405 
00406         /*
00407 switch($id) {
00408     case 1:
00409         <wml>
00410             <card id="Hallo" ontimer="#Login" title="wapportal.dk">
00411                 <timer value="35"/>
00412                 <p>
00413                     <img src="/images/logo.wbmp" alt="WAPPORTAL"/>
00414                     asf asdf asdf
00415                 </p>
00416             </card>
00417             <card id="Login" title="wapportal.dk" newcontext="true">
00418                 <p>Mobil nr:
00419                     <input name="Login" title="Mobil nr:" value="" format="*N" size="15"/>Kodeord:
00420                     <input name="Passwd" title="Kodeord:" value="" type="password" format="*N" size="12"/>
00421                     <anchor>Login !<go href="/wap/portal/DeckPortal/menu.wml?sid=FGBNRru&amp;rnd=107915&amp;login=$(Login:u)&amp;pwd=$(Passwd:u)"/></anchor>
00422                     <br/>
00423                     <anchor>G&#xe6;st<go href="/wap/portal/DeckPortal/menu.wml?sid=FGBNRru&amp;rnd=107916&amp;login=visitor&amp;pwd=visitor"></go></anchor>
00424                 </p>
00425             </card>
00426         </wml>
00427     break;
00428     default:
00429         <wml>
00430         <template>
00431             <do type="accept" label="Back"><prev/></do>
00432         </template>
00433         <card id="index1" title="Hovedside">
00434             <p>Hej Kasper.
00435             Dette er noget
00436             <img src="/images/logo.wbmp" alt="WAPPORTAL"/>
00437              tekst.</p>
00438 
00439         </card>
00440         </wml>
00441     break;
00442 }
00443 */
00444 
00445 
00446 
00447 
00448 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['media/scripts/wapversionLib.inc'])) {
00449     include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['media/scripts/wapversionLib.inc']);
00450 }
00451 
00452 
00453 ?>