Project

General

Profile

« Previous | Next » 

Revision 1351

Added by Dietmar almost 14 years ago

XHTML output fixed in show_menu2

View differences:

branches/2.8.x/CHANGELOG
11 11
! = Update/Change
12 12

  
13 13
------------------------------------- 2.8.2 -------------------------------------
14
21 Dec-2010 Dietmar Woellbrink (Luisehahne)
15
# XHTML output fixed in show_menu2
14 16
20 Dec-2010 Dietmar Woellbrink (Luisehahne)
15 17
# syntaxfix in initialize.php
16 18
19 Dec-2010 Dietmar Woellbrink (Luisehahne)
branches/2.8.x/wb/admin/interface/version.php
52 52

  
53 53
// check if defined to avoid errors during installation (redirect to admin panel fails if PHP error/warnings are enabled)
54 54
if(!defined('VERSION')) define('VERSION', '2.8.2.RC1');
55
if(!defined('REVISION')) define('REVISION', '1350');
55
if(!defined('REVISION')) define('REVISION', '1351');
56 56

  
57 57
?>
branches/2.8.x/wb/modules/show_menu2/info.php
1
<?php
2
/**
3
 *
4
 * @category        module
5
 * @package         show_menu2
6
 * @author          WebsiteBaker Project
7
 * @copyright       2004-2009, Ryan Djurovich
8
 * @copyright       2009-2011, Website Baker Org. e.V.
9
 * @link			http://www.websitebaker2.org/
10
 * @license         http://www.gnu.org/licenses/gpl.html
11
 * @platform        WebsiteBaker 2.7.0 | 2.8.x
12
 * @requirements    PHP 5.2.2 and higher
13
 * @version         $Id$
14
 * @filesource		$HeadURL$
15
 * @lastmodified    $Date$
16
 *
17
 */
18

  
19
$module_directory = 'show_menu2';
20
$module_name = 'show_menu2';
21
$module_function = 'snippet';
22
$module_version = '4.9.1';
23
$module_platform = '2.7 | 2.8.x';
24
$module_author = 'Brodie Thiesfield';
25
$module_license = 'GNU General Public License';
26
$module_description = 'A code snippet for the Website Baker CMS providing a complete replacement for the builtin menu functions. See <a href="http://code.jellycan.com/show_menu2/" target="_blank">http://code.jellycan.com/show_menu2/</a> for details or view the <a href="' .WB_URL .'/modules/show_menu2/README.en.txt" target="_blank">readme</a> file.';
27
?>
1
<?php
2
/**
3
 *
4
 * @category        module
5
 * @package         show_menu2
6
 * @author          WebsiteBaker Project
7
 * @copyright       2004-2009, Ryan Djurovich
8
 * @copyright       2009-2011, Website Baker Org. e.V.
9
 * @link			http://www.websitebaker2.org/
10
 * @license         http://www.gnu.org/licenses/gpl.html
11
 * @platform        WebsiteBaker 2.8.x
12
 * @requirements    PHP 5.2.2 and higher
13
 * @version         $Id$
14
 * @filesource		$HeadURL$
15
 * @lastmodified    $Date$
16
 *
17
 */
18

  
19
$module_directory = 'show_menu2';
20
$module_name = 'show_menu2';
21
$module_function = 'snippet';
22
$module_version = '4.9.3';
23
$module_platform = '2.7 | 2.8.2';
24
$module_author = 'Brodie Thiesfield';
25
$module_license = 'GNU General Public License';
26
$module_description = 'A code snippet for the Website Baker CMS providing a complete replacement for the builtin menu functions. See <a href="http://code.jellycan.com/show_menu2/" target="_blank">http://code.jellycan.com/show_menu2/</a> for details or view the <a href="' .WB_URL .'/modules/show_menu2/README.en.txt" target="_blank">readme</a> file.';
27
?>
branches/2.8.x/wb/modules/show_menu2/README.de.txt
1 1
show_menu2, version 4.9
2 2
=======================
3
Ist ein Code-Snippet für das CMS Website Baker. Es stellt einen kompletten 
4
Ersatz für die eingebaute Menüfuntionalität zur Verfügung. Alle, für die 
5
Erzeugung des Menüs erforderlichen Daten, werden durch eine einzige 
6
Datenbankabfrage erzeugt. Durch umfangreiche Anpassungsmöglichkeiten des 
7
erzeugten HTML-Code können alle möglichen Menüarten (Listen, Breadcrumbs, 
3
Ist ein Code-Snippet für das CMS Website Baker. Es stellt einen kompletten 

4
Ersatz für die eingebaute Menüfuntionalität zur Verfügung. Alle, für die 

5
Erzeugung des Menüs erforderlichen Daten, werden durch eine einzige 

6
Datenbankabfrage erzeugt. Durch umfangreiche Anpassungsmöglichkeiten des 

7
erzeugten HTML-Code können alle möglichen Menüarten (Listen, Breadcrumbs, 

8 8
Sitemaps, usw.) erzeugt werden.
9 9

  
10 10
---
11
Deutsche Übersetzung von BerndJM. Dies ist eine weitgehend direkte Übersetzung 
12
des englischen Originals. Bei Übersetzungs- oder Interpretationsfehlern, bitte 
11
Deutsche Übersetzung von BerndJM. Dies ist eine weitgehend direkte Übersetzung 

12
des englischen Originals. Bei Übersetzungs- oder Interpretationsfehlern, bitte 

13 13
eine Email an bjm@wwnw.de.
14 14
---
15 15

  
......
20 20
1. Die aktuelle Version von http://code.jellycan.com/show_menu2/ herunterladen.
21 21
2. In das Admin-Backend der Website Baker Installation einlogen.
22 22
3. Erweiterungen -> Module aufrufen.
23
4. Wenn bereits eine frühere Version von show_menu2 installiert ist, diese über
23
4. Wenn bereits eine frühere Version von show_menu2 installiert ist, diese über

24 24
   "Modul deinstallieren" auswählen und deinstallieren.
25
5. Im Abschnitt "Modul installieren" das im Schritt 1 heruntergeladene zip-File
25
5. Im Abschnitt "Modul installieren" das im Schritt 1 heruntergeladene zip-File

26 26
   auswählen und installieren.
27 27

  
28 28
   
29 29
   
30 30
BENUTZUNG VON SHOW_MENU2
31 31
========================
32
Um show_menu2 zu benutzen muss das verwendete Template an den Stellen 
33
modifiziert werden, an denen das Menü erscheinen soll. Bitte beachten: Wenn alte 
34
Menüaufrufe ersetzt werden, müssen unbedingt auch die entsprechenden neuen 
32
Um show_menu2 zu benutzen muss das verwendete Template an den Stellen 

33
modifiziert werden, an denen das Menü erscheinen soll. Bitte beachten: Wenn alte 

34
Menüaufrufe ersetzt werden, müssen unbedingt auch die entsprechenden neuen 

35 35
Parameter verwendet werden die show_menu2 benötigt.
36 36

  
37
In den meisten Fällen genügt bereits der Standardaufruf ohne weitere Parameter 
38
von show_menu2. In diesem Fall werden die Vorgabewerte verwendet, dies erzeugt 
37
In den meisten Fällen genügt bereits der Standardaufruf ohne weitere Parameter 

38
von show_menu2. In diesem Fall werden die Vorgabewerte verwendet, dies erzeugt 

39 39
ein Menü das die aktuelle Seite und die Unterseiten der aktuellen Seite anzeigt:
40 40
    
41 41
    show_menu2();
42 42
    
43
Bitte beachten: der Aufruf von show_menu2 ist PHP und muss normalerweise in PHP-
44
Codezeichen eingeschlossen werden (ausser der Aufruf erfolgt bereits innerhalb 
43
Bitte beachten: der Aufruf von show_menu2 ist PHP und muss normalerweise in PHP-

44
Codezeichen eingeschlossen werden (ausser der Aufruf erfolgt bereits innerhalb 

45 45
von PHP Code):
46 46

  
47 47
    <?php show_menu2(); ?>
48 48

  
49
Dieses Vorgabe Menü erzeugt bereits ein komplettes Menü auf Listenbasis mit 
50
etlichen Klassen, die eine leichte Formatierung mittels CSS ermöglichen. Es wird 
51
z.B. die Klasse "menu-current" zu dem <li> tag des aktuellen Menüpunktes 
52
hinzugefügt. Zusätzlich erhält jeder Menüpunkt der Unterpunkte enthält die 
53
Klasse "menu-expand". Das erlaubt es sehr differenzierte CSS Regeln für die 
49
Dieses Vorgabe Menü erzeugt bereits ein komplettes Menü auf Listenbasis mit 

50
etlichen Klassen, die eine leichte Formatierung mittels CSS ermöglichen. Es wird 

51
z.B. die Klasse "menu-current" zu dem <li> tag des aktuellen Menüpunktes 

52
hinzugefügt. Zusätzlich erhält jeder Menüpunkt der Unterpunkte enthält die 

53
Klasse "menu-expand". Das erlaubt es sehr differenzierte CSS Regeln für die 

54 54
einzelnen Menüpunkte aufzustellen.
55 55
Zum Beispiel:
56 56

  
57 57
    li.menu-expand  { font-weight: bold; }
58 58
    li.menu-current { background: red; }
59 59

  
60
Im Abschnitt "HTML-Ausgabe" findet sich eine detaillierte Beschreibung welche 
61
Klassen welchem Element zugeordnet werden. Durch die Verwendung von 
62
verschiedenen Parametern bei dem show_menu2 Funktionsaufruf lassen sich auch 
63
recht umfangreiche und unterschiedliche Menüstrukturen erzeugen. Um 
64
beispielsweise nur Menüpunkte aus der obersten Ebene der Menüstruktur 
60
Im Abschnitt "HTML-Ausgabe" findet sich eine detaillierte Beschreibung welche 

61
Klassen welchem Element zugeordnet werden. Durch die Verwendung von 

62
verschiedenen Parametern bei dem show_menu2 Funktionsaufruf lassen sich auch 

63
recht umfangreiche und unterschiedliche Menüstrukturen erzeugen. Um 

64
beispielsweise nur Menüpunkte aus der obersten Ebene der Menüstruktur 

65 65
darzustellen, könnte man folgenden Aufruf verwenden:
66 66

  
67 67
    show_menu2(0, SM2_ROOT, SM2_START);
......
70 70

  
71 71
    show_menu2(0, SM2_CURR+1, SM2_CURR+2);
72 72

  
73
Es gibt jede Menge Möglichkeiten, um die unterschiedlichsten Menüstrukturen zu 
74
erzeugen. Zahlreiche Beispiele dazu findet man auf der Demo-Website: http://
73
Es gibt jede Menge Möglichkeiten, um die unterschiedlichsten Menüstrukturen zu 

74
erzeugen. Zahlreiche Beispiele dazu findet man auf der Demo-Website: http://

75 75
code.jellycan.com/sm2test/
76 76

  
77 77

  
......
84 84

  
85 85

  
86 86
Q:  Wie kann ich ein sogenanntes Drop-Down Menü erstellen?
87
A:  Dies hat nichts mit show_menu2 zu tun. Um ein Drop-Down Menü zu erzeugen muß
88
    lediglich der CSS-Code des jeweiligen Templates angepaßt werden. Die nötigen 
89
    Anpassungen findet man z.B. im "allcss2" Template aus dem WB Addon     
87
A:  Dies hat nichts mit show_menu2 zu tun. Um ein Drop-Down Menü zu erzeugen muß

88
    lediglich der CSS-Code des jeweiligen Templates angepaßt werden. Die nötigen 

89
    Anpassungen findet man z.B. im "allcss2" Template aus dem WB Addon     

90 90
    Repository -> http://addons.websitebaker.org/pages/templates.php
91 91

  
92 92

  
93
Q:  Warum verschwindet das Menü nachdem ich in einer mehrsprachigen WB-Site die 
93
Q:  Warum verschwindet das Menü nachdem ich in einer mehrsprachigen WB-Site die 

94 94
    Suchfunktion benutzt habe?
95
A:  Im verwendeten Template fehlen die notwendigen Zeilen:
96

  
97
    1.  Im WB Admin Backend: Optionen -> Erweiterte Optionen anzeigen ->        
98
        Suchoptionen -> Kopfzeile - hier direkt nach dem öffnenden <form> tag 
99
        folgende Zeile einfügen:
100
       
+A:  Im verwendeten Template fehlen die notwendigen Zeilen:
95

  
96
    1.  Im WB Admin Backend: Optionen -> Erweiterte Optionen anzeigen ->        
97
        Suchoptionen -> Kopfzeile - hier direkt nach dem öffnenden <form> tag 
98
        folgende Zeile einfügen:
99
       
101 100
        <input type="hidden" name="referrer" value="[REFERRER_ID]" />
102 101

  
103
    2.  In der index.php des verwendeten Templates folgende Zeile unmittelbar   
104
        nach dem öffnenden <form> tag der Suche einfügen:
105

  
102
    2.  In der index.php des verwendeten Templates folgende Zeile unmittelbar   

103
        nach dem öffnenden <form> tag der Suche einfügen:

104

  
106 105
        <input type="hidden" name="referrer" value="<?php echo defined('REFERRER_ID')?REFERRER_ID:PAGE_ID;?>" />
107 106

  
108 107

  
......
112 112

  
113 113
Q:  Jedesmal wenn eine Seite aufgerufen wird, erzeugt SM2 folgende Warnmeldung:
114 114
    "show_menu2 error: $aOptions is invalid. No flags from group 1 supplied!"
115
A:  Der Funktion wurden die falschen Werte oder eine falsche Anzahl an 
116
    Werten übergeben.
117
    Siehe den Abschnitt PARAMETER für die korrekten Flag Werte die dem 
115
A:  Der Funktion wurden die falschen Werte oder eine falsche Anzahl an 

116
    Werten übergeben.

117
    Siehe den Abschnitt PARAMETER für die korrekten Flag Werte die dem 

118 118
    $aOptions Parameter zu übergeben sind.    
119 119

  
120 120

  
......
169 169
        $aTopMenuOpen   = false
170 170
        )
171 171

  
172
Im Abschnitt "Parameter" findet sich eine detaillierte Beschreibung jedes 
173
einzelnen Parameters.
174
Jeder Parameter muß absolut korrekt verwendet werden. Folgende Regeln können 
172
Im Abschnitt "Parameter" findet sich eine detaillierte Beschreibung jedes 

173
einzelnen Parameters.

174
Jeder Parameter muß absolut korrekt verwendet werden. Folgende Regeln können 

175 175
dabei helfen:
176 176

  
177 177
    $aMenu = 0 ist in den meisten Anwendungsfällen der beste Wert.
......
180 180
    
181 181
    $aMaxLevel kann nur Werte erhalten, die mit "SM2_" beginnen.
182 182
    
183
    $aOptions bis auf einige wenige Spezialfälle sind hier nur Werte die mit 
183
    $aOptions bis auf einige wenige Spezialfälle sind hier nur Werte die mit 

184 184
    "SM2_" beginnen zulässig.
185 185
    
186
    Alle weiteren Parameter enthalten die (HTML)Tags die die Ausgabe des Menüs 
186
    Alle weiteren Parameter enthalten die (HTML)Tags die die Ausgabe des Menüs 

187 187
    steuern.
188 188
    
189
    Ab $aItemOpen kann jedem Parameter der Wert false übergeben werden um den 
189
    Ab $aItemOpen kann jedem Parameter der Wert false übergeben werden um den 

190 190
    jeweiligen Vorgabewert zu erhalten.
191 191

  
192
    Dies kann beispielsweise verwendet werden um eine nummerierte Liste zu 
193
    erzeugen, während für die einzelnen Menüpunkte trotzdem die Vorgabewerte 
192
    Dies kann beispielsweise verwendet werden um eine nummerierte Liste zu 

193
    erzeugen, während für die einzelnen Menüpunkte trotzdem die Vorgabewerte 

194 194
    Verwendung finden:
195 195

  
196 196
        show_menu2(0, SM2_ROOT, SM2_ALL, SM2_ALL, false, false, '<ol>', '</ol>');
......
215 215
    menu-first      Der erste Punkt eines jeden Menüs oder Untermenüs.
216 216
    menu-last       Der letzte Punkt eines jeden Menüs oder Untermenüs.
217 217

  
218
    Folgende Klassen werden nur hinzugefügt, wenn das SM2_NUMCLASS Flag gesetzt 
218
    Folgende Klassen werden nur hinzugefügt, wenn das SM2_NUMCLASS Flag gesetzt 

219 219
    ist:
220 220

  
221 221
    menu-N          Jeder Menüpunkt, wobei das N für die ABSOLUTE Menütiefe, 
......
268 268
PARAMETER
269 269
=========
270 270
$aMenu      
271
    Nummer des Menüs. Diese ist nützlich um mehrere Menüs auf einer Seite zu    
271
    Nummer des Menüs. Diese ist nützlich um mehrere Menüs auf einer Seite zu    

272 272
    verwenden.
273 273
    Menü Nummer 0 ist das Vorgabemenü der aktuellen Seite, SM2_ALLMENU gibt alle
274 274
    im System verwendeten Menüs zurück.
275 275

  
276 276
$aStart  
277
    Gibt an, ab welcher Ebene die Erzeugung des Menüs beginnen soll. In den     
278
    meisten Fällen wird dies die oberste Ebene des anzuzeigenden Menüs sein. Es 
277
    Gibt an, ab welcher Ebene die Erzeugung des Menüs beginnen soll. In den     

278
    meisten Fällen wird dies die oberste Ebene des anzuzeigenden Menüs sein. Es 

279 279
    kann einer der folgenden Werte verwendet werden:
280 280

  
281 281
        SM2_ROOT+N  Beginnt N Ebenen unterhalb der obersten Ebene, z.B.:
......
290 290
                                  mit allen Unterebenen
291 291

  
292 292
        page_id     Verwendet die Seite mit der angegebenen page id als Elternelement.
293
                    Alle Untermenüs dieser Seite werden angezeigt. 
294
                    (Die page id kann ermittelt werden, wenn man die Seite im 
295
                    Admin-Backend editiert, sie steht dann in der Adresszeile des      
293
                    Alle Untermenüs dieser Seite werden angezeigt. 

294
                    (Die page id kann ermittelt werden, wenn man die Seite im 

295
                    Admin-Backend editiert, sie steht dann in der Adresszeile des      

296 296
                    Browsers: http://SITE/admin/pages/modify.php?page_id=35
297 297

  
298 298
$aMaxLevel   
......
379 379
                    mit SM2_NOCACHE, sonst zeigt es keine Wirkung.
380 380
    
381 381
    SM2_NOCACHE     Die aus der Datenbank gelesenen Daten werden bei erneutem Aufruf von
382
                    show_menu2 nicht wiederverwendet sondern erneut aus der Datenbank 
382
                    show_menu2 nicht wiederverwendet sondern erneut aus der Datenbank 

383 383
                    gelesen.
384 384
    
385 385
    SM2_PRETTY      Bringt die HTML-Ausgabe des Menüs mittels Leerzeichen und
386
                    Zeilenumbrüchen in eine gut lesbare Form. Das ist besonders 
386
                    Zeilenumbrüchen in eine gut lesbare Form. Das ist besonders 

387 387
                    nützlich beim Debuggen der Menüausgabe.
388 388
    
389 389
    SM2_BUFFER      Gibt den HTML-Code nicht direkt aus, sondern speichert ihn intern
......
405 405
                    release 4.8, supply this flag to enable hidden pages to
406 406
                    become visible when they are active.
407 407

  
408
    Für diesen Parameter gibt es auch einen erweiterten Modus, bei dem die Optionen
409
    als assoziatives Array übergeben werden. Näheres dazu im Abschnitt ERWEITERTE
410
    OPTIONEN. Für die meisten Anwendungsfälle wird dies jedoch NICHT benötigt.
408
    SM2_XHTML_STRICT	Stellt die XHTML-Kompatibilität der Links sicher indem
409
					in per [a] oder [ac] formatierten Links die Targetangabe
410
					entfernt und das Argument title="[page_titel]" eingefügt
411
					wird. Bei manuell zusammengestellten Links ist der Designer
412
					selbst für die XHTML-Konformität zuständig.
413

  
414
	SM2_NO_TITLE	Unterdrückt die Ausgabe des Inhaltes des Title-Attributes
415
					bei [a] oder [ac] formatierten links.
416

  
417
    Für diesen Parameter gibt es auch einen erweiterten Modus, bei dem die Optionen
418
    als assoziatives Array übergeben werden. Näheres dazu im Abschnitt ERWEITERTE
419
    OPTIONEN. Für die meisten Anwendungsfälle wird dies jedoch NICHT benötigt.
411 420
    
412 421
$aItemOpen
413 422
    Dies legt den Formatstring fest, mit dem jeder einzelne Menüeintrag begonnen
......
421 430
    verwenden: '<li>[ac][menu_title]</a>'.
422 431
    
423 432
    Dieser Parameter kann auch als Instanz eine Formatierungklasse für das Menü
424
    verwendet werden. Die nähere Beschreibung dazu findet sich im Abschnitt FORMATTER. 
433
    verwendet werden. Die nähere Beschreibung dazu findet sich im Abschnitt FORMATTER. 

425 434
    Wenn hier ein Formatter angegeben wird, werden alle Argumente
426 435
    nach $aItemOpen ignoriert.
427 436

  
......
455 464
    
456 465

  
457 466
ERWEITERTE OPTIONEN
458
===================
459
Der Parameter $aOptions kann auf zweierlei Arten verwendet werden. Zum einen, wie oben 
460
im Abschnitt PARAMETER beschrieben, diese Art sollte für die allermeisten 
461
Anwendungsfälle ausreichen. Um allerdings in speziellen Fällen die Sonderoptionen 
462
ansprechen zu können, müssen die erforderlichen Werte als assoziatives Array 
463
bereitgestellt werden.
464
Bitte beachten: Die SM2_* Flags sind auch hierbei erforderlich und müßen als 'flags' 
465
übergeben werden.
467
===================

468
Der Parameter $aOptions kann auf zweierlei Arten verwendet werden. Zum einen, wie oben 

469
im Abschnitt PARAMETER beschrieben, diese Art sollte für die allermeisten 

470
Anwendungsfälle ausreichen. Um allerdings in speziellen Fällen die Sonderoptionen 

471
ansprechen zu können, müssen die erforderlichen Werte als assoziatives Array 

472
bereitgestellt werden.

473
Bitte beachten: Die SM2_* Flags sind auch hierbei erforderlich und müßen als 'flags' 

474
übergeben werden.

466 475

  
467
    'flags'     **ZWINGEND ERFORDELICH** Dies sind die Flags die oben im Abschnitt 
476
    'flags'     **ZWINGEND ERFORDELICH** Dies sind die Flags die oben im Abschnitt 

468 477
                PARAMETER unter $aOptions beschrieben wurden.
469 478

  
470
    'notrim'    Hiermit wird eine Anzahl von Ebenen festegelegt, die relativ bezogen 
471
                auf die in $aStart festgelegte Menüebene, immer angezeigt werden. Dies 
472
                bewirkt, daß für diese Ebenen das SM2_TRIM Flag ignoriert wird.
473

  
474
Um dieses Array zu verwenden, empfiehlt es sich es erst anzulegen und dann den 
479
    'notrim'    Hiermit wird eine Anzahl von Ebenen festegelegt, die relativ bezogen 

480
                auf die in $aStart festgelegte Menüebene, immer angezeigt werden. Dies 

481
                bewirkt, daß für diese Ebenen das SM2_TRIM Flag ignoriert wird.

482

  
483
Um dieses Array zu verwenden, empfiehlt es sich es erst anzulegen und dann den 

475 484
$aOptions parameter mit dem angelegten Array zu beliefern:
476 485

  
477 486
    $options = array('flags' => (SM2_TRIM|...), 'notrim' => 1);
......
489 498
[li]            <li> tag mit Klasse:   '<li class="[class]">'
490 499
[ul]            <ul> tag mit Klasse:   '<ul class="[class]">'
491 500
[class]         Liste der Klassen für diese Seite
492
[menu_title]    Text des Menütitel 
501
[menu_title]    Text des Menütitel 

493 502
                (HTML entity escaped ausser das SM2_NOESCAPE Flag ist gesetzt)
494
[page_title]    text des Seitentitel 
503
[menu_icon_0]	die URL zu einer Bilddatei mit normal - Darstellung (ab WB2.9.0)
504
[menu_icon_1]	die URL zu einer Bilddatei mit active/hover - Darstellung (ab WB2.9.0)
505
[page_title]    text des Seitentitel 
495 506
                (HTML entity escaped ausser das SM2_NOESCAPE Flag ist gesetzt)
507
[page_icon]		die URL zu einer seitenbezogenen Bilddatei (ab WB2.9.0)
496 508
[url]           die URL der Seiten für den <a> tag
497 509
[target]        das Seitenziel für den <a> tag
498 510
[page_id]       die Page ID des aktuellen Menüpunktes.
499 511
[parent]        die Page ID des übergeordneten Menüpunktes.
500
[level]         die Seitenebene, 
512
[level]         die Seitenebene, 

501 513
                dies ist die gleiche Zahl die im "menu-N" CSS tag verwendet wird.
502 514
[sib]           Anzahl der Geschwister des aktuellen Menüpunktes.
503 515
[sibCount]      Anzahl aller Geschwister in diesem Menü.
......
535 547
Wenn mehr als ein Vergleich erforderlich ist, so muss dieser mit den anderen Vergleichen
536 548
mittels || (boolsches oder - OR) oder && (boolsches und - AND) verknüpft werden.    
537 549

  
538
Ein einzelner Vergleich besteht aus dem linken Operanden, dem Operator und dem rechten 
550
Ein einzelner Vergleich besteht aus dem linken Operanden, dem Operator und dem rechten 

539 551
Operanden.
540 552
z.B. X == Y  - hierbei ist X der linke Operand, == der Operator und Y der rechte Operand.
541 553
    
......
548 560
        sib         Überprüfung der Geschwisteranzahl der aktuellen Seite.
549 561
        sibCount    Überprüfung der Geamtanzahl der Geschwister im aktuellen Menü.
550 562
        id          Überprüfung der page id.
563
		target		Überprüfung der Target-Angabe
551 564
    
552 565
    Operator. Muss einer der folgenden sein:
553 566
        <           Kleiner als
......
575 588
        sib         Eine positive Integerzahl, oder "sibCount" um die Anzahl der
576 589
                    Geschwister in diesem Menü zu überprüfen
577 590
        sibCount    Eine positive Integerzahl
591
		target		Ein String, der eine mögliche Targetangabe darstellt
578 592
        
579 593
Folgende Beispiele ergeben "wahr" und der Ausdruck {exp} wird ausgeführt, wenn zutrifft:
580 594
    
......
587 601
    [if(sib==2){exp}]               ist der zweite Eintrag in einem Menü
588 602
    [if(sibCount>1){exp}]           ist in einem Menü mit mehr als einem Eintrag
589 603
    [if(sibCount!=2){exp}]          ist in einem Menü, das nicht genau 2 Einträge hat
590
    [if(level>parent){exp}]         ist in einem Geschwistermenü oder dem Untermenü eines      
604
    [if(level>parent){exp}]         ist in einem Geschwistermenü oder dem Untermenü eines      

591 605
                                    Geschwistermenüs
592 606
    [if(id==parent){exp}]           ist der übergeordnete Punkt der aktuellen id
607
	[if(target==_self){exp}]		im Target-Attribut ist der String '_self' enthalten
593 608

  
594
Wenn eine sonst-Klausel (else) hinzugefügt wird, so wird diese in allen anderen Fällen 
609
Wenn eine sonst-Klausel (else) hinzugefügt wird, so wird diese in allen anderen Fällen 

595 610
ausgeführt.
596 611
Zum Beispiel wird "foo" immer dann ausgeführt, wenn die if Überprüfung falsch ergibt, also:
597 612

  
......
600 615

  
601 616
Bei mehrfach Vergleichen wird der Ausdruck "exp" nur ausgeführt, wenn:
602 617

  
603
    [if(sib == 1 || sib > 3){exp}]  ist der erste Eintrag ODER ist der vierte oder höhere   
618
    [if(sib == 1 || sib > 3){exp}]  ist der erste Eintrag ODER ist der vierte oder höhere   

604 619
    Eintrag im Menü    
605 620
               
606
    [if(id == current && class == menu-expand){exp}  ist der aktuelle Eintrag UND hat 
621
    [if(id == current && class == menu-expand){exp}  ist der aktuelle Eintrag UND hat 

607 622
    Untermenüs
608 623
        
609 624
Bitte beachten:
branches/2.8.x/wb/modules/show_menu2/include.php
1
<?php
2
/**
3
 *
4
 * @category        module
5
 * @package         show_menu2
6
 * @author          WebsiteBaker Project
7
 * @copyright       2004-2009, Ryan Djurovich
8
 * @copyright       2009-2011, Website Baker Org. e.V.
9
 * @link			http://www.websitebaker2.org/
10
 * @license         http://www.gnu.org/licenses/gpl.html
11
 * @platform        WebsiteBaker 2.7.0 | 2.8.x
12
 * @requirements    PHP 5.2.2 and higher
13
 * @version         $Id$
14
 * @filesource		$HeadURL$
15
 * @lastmodified    $Date$
16
 *
17
 */
18

  
19
define('SM2_ROOT',       -1000);
20
define('SM2_CURR',       -2000);
21
define('SM2_ALLMENU',       -1);
22
define('SM2_START',       1000);
23
define('SM2_MAX',         2000);
24
define('SM2_ALL',       0x0001); // bit 0 (group 1) (Note: also used for max level!)
25
define('SM2_TRIM',      0x0002); // bit 1 (group 1)
26
define('SM2_CRUMB',     0x0004); // bit 2 (group 1)
27
define('SM2_SIBLING',   0x0008); // bit 3 (group 1)
28
define('SM2_NUMCLASS',  0x0010); // bit 4
29
define('SM2_ALLINFO',   0x0020); // bit 5
30
define('SM2_NOCACHE',   0x0040); // bit 6
31
define('SM2_PRETTY',    0x0080); // bit 7
32
define('SM2_ESCAPE',    0x0100); // bit 8
33
define('SM2_NOESCAPE',       0); // NOOP, unnecessary with WB 2.6.7+
34
define('SM2_BUFFER',    0x0200); // bit 9
35
define('SM2_CURRTREE',  0x0400); // bit 10
36
define('SM2_SHOWHIDDEN', 0x0800); // bit 11
37

  
38
define('_SM2_GROUP_1',  0x000F); // exactly one flag from group 1 is required
39

  
40

  
41
// Implement support for page_menu and show_menu using show_menu2. If you remove
42
// the comments characters from the beginning of the following include, all menu
43
// functions in Website Baker will be implemented using show_menu2. While it is
44
// commented out, the original WB functions will be used.
45
//include('legacy.php');
46

  
47
// This class is the default menu formatter for sm2. If desired, you can 
48
// create your own formatter class and pass the object into show_menu2 
49
// as $aItemFormat.
50
define('SM2_CONDITIONAL','if\s*\(([^\)]+)\)\s*{([^}]*)}\s*(?:else\s*{([^}]*)}\s*)?');
51
define('SM2_COND_TERM','\s*(\w+)\s*(<|<=|==|=|=>|>|!=)\s*([\w\-]+)\s*');
52
class SM2_Formatter
53
{
54
    var $output;
55
    var $flags;
56
    var $itemOpen;
57
    var $itemClose;
58
    var $menuOpen;
59
    var $menuClose;
60
    var $topItemOpen;
61
    var $topMenuOpen;
62
    
63
    var $isFirst;
64
    var $page;
65
    var $url;
66
    var $currSib;
67
    var $sibCount;
68
    var $currClass;
69
    var $prettyLevel;
70

  
71
    // output the data
72
    function output($aString) {
73
        if ($this->flags & SM2_BUFFER) {
74
            $this->output .= $aString;
75
        }
76
        else {
77
            echo $aString;
78
        }
79
    }
80
    
81
    // set the default values for all of our formatting items
82
    function set($aFlags, $aItemOpen, $aItemClose, $aMenuOpen, $aMenuClose, $aTopItemOpen, $aTopMenuOpen) {
83
        $this->flags        = $aFlags;
84
        $this->itemOpen     = is_string($aItemOpen)    ? $aItemOpen    : '[li][a][menu_title]</a>';
85
        $this->itemClose    = is_string($aItemClose)   ? $aItemClose   : '</li>';
86
        $this->menuOpen     = is_string($aMenuOpen)    ? $aMenuOpen    : '[ul]';
87
        $this->menuClose    = is_string($aMenuClose)   ? $aMenuClose   : '</ul>';
88
        $this->topItemOpen  = is_string($aTopItemOpen) ? $aTopItemOpen : $this->itemOpen;
89
        $this->topMenuOpen  = is_string($aTopMenuOpen) ? $aTopMenuOpen : $this->menuOpen;
90
    }
91

  
92
    // initialize the state of the formatter before anything is output
93
    function initialize() {
94
        $this->output = '';
95
        $this->prettyLevel = 0;
96
        if ($this->flags & SM2_PRETTY) {
97
            $this->output("\n<!-- show_menu2 -->");
98
        }
99
    }
100

  
101
    // start a menu     
102
    function startList(&$aPage, &$aUrl) {
103
        $currClass = '';
104
        $currItem = $this->menuOpen;
105
        
106
        // use the top level menu open if this is the first menu
107
        if ($this->topMenuOpen) {
108
            $currItem = $this->topMenuOpen;
109
            $currClass .= ' menu-top';
110
            $this->topMenuOpen = false;
111
        }
112
        
113
        // add the numbered menu class only if requested
114
        if (($this->flags & SM2_NUMCLASS) == SM2_NUMCLASS) {
115
            $currClass .= ' menu-'.$aPage['level'];
116
        }
117
        
118
        $this->prettyLevel += 1;
119
        
120
        // replace all keywords in the output
121
        if ($this->flags & SM2_PRETTY) {
122
            $this->output("\n".str_repeat(' ',$this->prettyLevel).
123
                $this->format($aPage, $aUrl, $currItem, $currClass));
124
        }
125
        else {
126
            $this->output($this->format($aPage, $aUrl, $currItem, $currClass));
127
        }
128
        
129
        $this->prettyLevel += 3;
130
    }
131
    
132
    // start an item within the menu
133
    function startItem(&$aPage, &$aUrl, $aCurrSib, $aSibCount) {
134
        // generate our class list
135
        $currClass = '';
136
        if (($this->flags & SM2_NUMCLASS) == SM2_NUMCLASS) {
137
            $currClass .= ' menu-'.$aPage['level'];
138
        }
139
        if (array_key_exists('sm2_has_child', $aPage)) {
140
            // not set if false, so existence = true
141
            $currClass .= ' menu-expand';
142
        }
143
        if (array_key_exists('sm2_is_curr', $aPage)) { 
144
            $currClass .= ' menu-current';
145
        }
146
        elseif (array_key_exists('sm2_is_parent', $aPage)) { 
147
            // not set if false, so existence = true
148
            $currClass .= ' menu-parent';
149
        }
150
        elseif (array_key_exists('sm2_is_sibling', $aPage)) {
151
            // not set if false, so existence = true
152
            $currClass .= ' menu-sibling';
153
        }
154
        elseif (array_key_exists('sm2_child_level',$aPage)) {
155
            // not set if not a child
156
            $currClass .= ' menu-child';
157
            if (($this->flags & SM2_NUMCLASS) == SM2_NUMCLASS) {
158
                $currClass .= ' menu-child-'.($aPage['sm2_child_level']-1);
159
            }
160
        }
161
        if ($aCurrSib == 1) {
162
            $currClass .= ' menu-first';
163
        }
164
        if ($aCurrSib == $aSibCount) {
165
            $currClass .= ' menu-last';
166
        }
167

  
168
        // use the top level item if this is the first item
169
        $currItem = $this->itemOpen;
170
        if ($this->topItemOpen) {
171
            $currItem = $this->topItemOpen;
172
            $this->topItemOpen = false;
173
        }
174

  
175
        // replace all keywords in the output
176
        if ($this->flags & SM2_PRETTY) {
177
            $this->output("\n".str_repeat(' ',$this->prettyLevel));
178
        }
179
        $this->output($this->format($aPage, $aUrl, $currItem, $currClass, $aCurrSib, $aSibCount));
180
    }
181
    
182
    // find and replace all keywords, setting the state variables first
183
    function format(&$aPage, &$aUrl, &$aCurrItem, &$aCurrClass, 
184
        $aCurrSib = 0, $aSibCount = 0) 
185
    {
186
        $this->page      = &$aPage;
187
        $this->url       = &$aUrl;
188
        $this->currClass = trim($aCurrClass);
189
        $this->currSib   = $aCurrSib;
190
        $this->sibCount  = $aSibCount;
191
        
192
        $item = $this->format2($aCurrItem);
193
        
194
        unset($this->page);
195
        unset($this->url);
196
        unset($this->currClass);
197
        
198
        return $item;
199
    }
200
    
201
    // find and replace all keywords
202
    function format2(&$aCurrItem) {
203
        if (!is_string($aCurrItem)) return '';
204
        return preg_replace(
205
            '@\[('.
206
                'a|ac|/a|li|/li|ul|/ul|menu_title|page_title|url|target|page_id|'.
207
                'parent|level|sib|sibCount|class|description|keywords|'.
208
                SM2_CONDITIONAL.
209
            ')\]@e', 
210
            '$this->replace("\1")', $aCurrItem);
211
    }
212
    
213
    // replace the keywords
214
    function replace($aMatch) {
215
        switch ($aMatch) {
216
        case 'a':
217
            return '<a href="'.$this->url.'" target="'.$this->page['target'].'">';
218
        case 'ac':
219
            return '<a href="'.$this->url.'" target="'.$this->page['target'].'" class="'.$this->currClass.'">';
220
        case '/a':
221
            return '</a>';
222
        case 'li':
223
            return '<li class="'.$this->currClass.'">';
224
        case '/li':
225
            return '</li>';
226
        case 'ul':
227
            return '<ul class="'.$this->currClass.'">';
228
        case '/ul':
229
            return '</ul>';
230
        case 'url':
231
            return $this->url;
232
        case 'sib':
233
            return $this->currSib;
234
        case 'sibCount':
235
            return $this->sibCount;
236
        case 'class':
237
            return $this->currClass;
238
        default:
239
            if (array_key_exists($aMatch, $this->page)) {
240
                if ($this->flags & SM2_ESCAPE) {
241
                    return htmlspecialchars($this->page[$aMatch], ENT_QUOTES);
242
                }
243
                else {
244
                    return $this->page[$aMatch];
245
                }
246
            }
247
            if (preg_match('/'.SM2_CONDITIONAL.'/', $aMatch, $rgMatches)) {
248
                return $this->replaceIf($rgMatches[1], $rgMatches[2], $rgMatches[3]);
249
            }
250
        }
251
        return "[$aMatch=UNKNOWN]";
252
    }
253
    
254
    // conditional replacement
255
    function replaceIf(&$aExpression, &$aIfValue, &$aElseValue) {
256
        // evaluate all of the tests in the conditional (we don't do short-circuit
257
        // evaluation) and replace the string test with the boolean result
258
        $rgTests = preg_split('/(\|\||\&\&)/', $aExpression, -1, PREG_SPLIT_DELIM_CAPTURE);
259
        for ($n = 0; $n < count($rgTests); $n += 2) {
260
            if (preg_match('/'.SM2_COND_TERM.'/', $rgTests[$n], $rgMatches)) {
261
                $rgTests[$n] = $this->ifTest($rgMatches[1], $rgMatches[2], $rgMatches[3]);
262
            }
263
            else {
264
                @error_logs("show_menu2 error: conditional expression is invalid!");
265
                $rgTests[$n] = false;
266
            }
267
        }
268

  
269
        // combine all test results for a final result
270
        $ok = $rgTests[0];
271
        for ($n = 1; $n+1 < count($rgTests); $n += 2) {
272
            if ($rgTests[$n] == '||') {
273
                $ok = $ok || $rgTests[$n+1];
274
            }
275
            else {
276
                $ok = $ok && $rgTests[$n+1];
277
            }
278
        }
279
        
280
        // return the formatted expression if the test succeeded
281
        return $ok ? $this->format2($aIfValue) : $this->format2($aElseValue);
282
    }
283

  
284
    // conditional test
285
    function ifTest(&$aKey, &$aOperator, &$aValue) {
286
        global $wb;
287
        
288
        // find the correct operand
289
        $operand = false;
290
        switch($aKey) {
291
        case 'class':
292
            // we need to wrap the class names in spaces so we can test for a unique
293
            // class name that will not match prefixes or suffixes. Same must be done
294
            // for the value we are testing.
295
            $operand = " $this->currClass "; 
296
            break;
297
        case 'sib':
298
            $operand = $this->currSib;
299
            if ($aValue == 'sibCount') {
300
                $aValue = $this->sibCount;
301
            }
302
            break;
303
        case 'sibCount':
304
            $operand = $this->sibCount;
305
            break;
306
        case 'level':
307
            $operand = $this->page['level'];
308
            switch ($aValue) {
309
            case 'root':    $aValue = 0; break;
310
            case 'granny':  $aValue = $wb->page['level']-2; break;
311
            case 'parent':  $aValue = $wb->page['level']-1; break;
312
            case 'current': $aValue = $wb->page['level'];   break;
313
            case 'child':   $aValue = $wb->page['level']+1; break;
314
            }
315
            if ($aValue < 0) $aValue = 0;
316
            break;
317
        case 'id':
318
            $operand = $this->page['page_id'];
319
            switch ($aValue) {
320
            case 'parent':  $aValue = $wb->page['parent'];  break;
321
            case 'current': $aValue = $wb->page['page_id']; break;
322
            }
323
            break;
324
        default:
325
            return '';
326
        }
327

  
328
        // do the test        
329
        $ok = false;
330
        switch ($aOperator) { 
331
        case '<':
332
            $ok = ($operand < $aValue); 
333
            break;
334
        case '<=':
335
            $ok = ($operand <= $aValue); 
336
            break;
337
        case '=':
338
        case '==':
339
        case '!=':
340
            if ($aKey == 'class') {
341
                $ok = strstr($operand, " $aValue ") !== FALSE;
342
            }
343
            else {
344
                $ok = ($operand == $aValue); 
345
            }
346
            if ($aOperator == '!=') {
347
                $ok = !$ok;
348
            }
349
            break;
350
        case '>=':
351
            $ok = ($operand >= $aValue); 
352
        case '>':
353
            $ok = ($operand > $aValue); 
354
        }
355
        
356
        return $ok;
357
    }
358
    
359
    // finish the current menu item
360
    function finishItem() {
361
        if ($this->flags & SM2_PRETTY) {
362
            $this->output(str_repeat(' ',$this->prettyLevel).$this->itemClose);
363
        }
364
        else {
365
            $this->output($this->itemClose);
366
        }
367
    }
368

  
369
    // finish the current menu
370
    function finishList() {
371
        $this->prettyLevel -= 3;
372
        
373
        if ($this->flags & SM2_PRETTY) {
374
            $this->output("\n".str_repeat(' ',$this->prettyLevel).$this->menuClose."\n");
375
        }
376
        else {
377
            $this->output($this->menuClose);
378
        }
379
        
380
        $this->prettyLevel -= 1;
381
    }
382
    
383
    // cleanup the state of the formatter after everything has been output
384
    function finalize() {
385
        if ($this->flags & SM2_PRETTY) {
386
            $this->output("\n");
387
        }
388
    }
389

  
390
    // return the output
391
    function getOutput() {
392
        return $this->output;
393
    }
394
};
395

  
396
function error_logs($error_str)
397
{
398
                $log_error = true;
399
                if ( ! function_exists('error_log') )
400
                        $log_error = false;
401

  
402
                $log_file = @ini_get('error_log');
403
                if ( !empty($log_file) && ('syslog' != $log_file) && !@is_writable($log_file) )
404
                        $log_error = false;
405

  
406
                if ( $log_error )
407
                        @error_log($error_str, 0);
408
}
409

  
410
function show_menu2(
411
    $aMenu          = 0,
412
    $aStart         = SM2_ROOT,
413
    $aMaxLevel      = -1999, // SM2_CURR+1
414
    $aOptions       = SM2_TRIM,
415
    $aItemOpen      = false,
416
    $aItemClose     = false,
417
    $aMenuOpen      = false,
418
    $aMenuClose     = false,
419
    $aTopItemOpen   = false,
420
    $aTopMenuOpen   = false
421
    )
422
{
423
    global $wb;
424

  
425
    // extract the flags and set $aOptions to an array
426
    $flags = 0;
427
    if (is_int($aOptions)) {
428
        $flags = $aOptions;
429
        $aOptions = array();
430
    }
431
    else if (isset($aOptions['flags'])) {
432
        $flags = $aOptions['flags'];
433
    }
434
    else {
435
        $flags = SM2_TRIM;
436
        $aOptions = array();
437
        @error_logs('show_menu2 error: $aOptions is invalid. No flags supplied!');
438
    }
439
    
440
    // ensure we have our group 1 flag, we don't check for the "exactly 1" part, but
441
    // we do ensure that they provide at least one.
442
    if (0 == ($flags & _SM2_GROUP_1)) {
443
        @error_logs('show_menu2 error: $aOptions is invalid. No flags from group 1 supplied!');
444
        $flags |= SM2_TRIM; // default to TRIM
445
    }
446
    
447
    // search page results don't have any of the page data loaded by WB, so we load it 
448
    // ourselves using the referrer ID as the current page
449
    $CURR_PAGE_ID = defined('REFERRER_ID') ? REFERRER_ID : PAGE_ID;
450
    if (count($wb->page) == 0 && defined('REFERRER_ID') && REFERRER_ID > 0) {
451
        global $database;
452
        $sql = 'SELECT * FROM `'.TABLE_PREFIX.'pages` WHERE `page_id` = '.REFERRER_ID.'';
453
        $result = $database->query($sql);
454
        if ($result->numRows() == 1) {
455
            $wb->page = $result->fetchRow();
456
        }
457
        unset($result);
458
    }
459
    
460
    // fix up the menu number to default to the menu number
461
    // of the current page if no menu has been supplied
462
    if ($aMenu == 0) {
463
        $aMenu = $wb->page['menu'] == '' ? 1 : $wb->page['menu'];
464
    } 
465

  
466
    // Set some of the $wb->page[] settings to defaults if not set
467
    $pageLevel  = $wb->page['level']  == '' ? 0 : $wb->page['level'];
468
    $pageParent = $wb->page['parent'] == '' ? 0 : $wb->page['parent'];
469
    
470
    // adjust the start level and start page ID as necessary to
471
    // handle the special values that can be passed in as $aStart
472
    $aStartLevel = 0;
473
    if ($aStart < SM2_ROOT) {   // SM2_CURR+N
474
        if ($aStart == SM2_CURR) {
475
            $aStartLevel = $pageLevel;
476
            $aStart = $pageParent;
477
        }
478
        else {
479
            $aStartLevel = $pageLevel + $aStart - SM2_CURR;
480
            $aStart = $CURR_PAGE_ID; 
481
        }
482
    }
483
    elseif ($aStart < 0) {   // SM2_ROOT+N
484
        $aStartLevel = $aStart - SM2_ROOT;
485
        $aStart = 0;
486
    }
487

  
488
    // we get the menu data once and store it in a global variable. This allows 
489
    // multiple calls to show_menu2 in a single page with only a single call to 
490
    // the database. If this variable exists, then we have already retrieved all
491
    // of the information and processed it, so we don't need to do it again.
492
    if (($flags & SM2_NOCACHE) != 0
493
        || !array_key_exists('show_menu2_data', $GLOBALS)
494
        || !array_key_exists($aMenu, $GLOBALS['show_menu2_data'])) 
495
    {
496
        global $database;
497

  
498
        // create an array of all parents of the current page. As the page_trail
499
        // doesn't include the theoretical root element 0, we add it ourselves.
500
        $rgCurrParents = explode(",", '0,'.$wb->page['page_trail']);
501
        array_pop($rgCurrParents); // remove the current page
502
        $rgParent = array();
503

  
504
        // if the caller wants all menus gathered together (e.g. for a sitemap)
505
        // then we don't limit our SQL query
506
        $menuLimitSql = ' AND menu = ' .$aMenu;
507
        if ($aMenu == SM2_ALLMENU) {
508
            $menuLimitSql = '';
509
        }
510

  
511
        // we only load the description and keywords if we have been told to,
512
        // this cuts the memory load for pages that don't use them. Note that if
513
        // we haven't been told to load these fields the *FIRST TIME* show_menu2
514
        // is called (i.e. where the database is loaded) then the info won't
515
        // exist anyhow.
516
        $fields = 'parent,page_id,menu_title,page_title,link,target,level,visibility,viewing_groups';
517
        if (version_compare(WB_VERSION, '2.7', '>=')) { // WB 2.7+
518
            $fields .= ',viewing_users';
519
        }
520
        if ($flags & SM2_ALLINFO) {
521
            $fields = '*';
522
        }
523

  
524
        // we request all matching rows from the database for the menu that we
525
        // are about to create it is cheaper for us to get everything we need
526
        // from the database once and create the menu from memory then make 
527
        // multiple calls to the database. 
528
        $sql = "SELECT $fields FROM ".TABLE_PREFIX.
529
               "pages WHERE $wb->extra_where_sql $menuLimitSql ".
530
               'ORDER BY level ASC, position ASC';
531
        $sql = str_replace('hidden', 'IGNOREME', $sql); // we want the hidden pages
532
        $oRowset = $database->query($sql);
533
        if (is_object($oRowset) && $oRowset->numRows() > 0) {
534
            // create an in memory array of the database data based on the item's parent. 
535
            // The array stores all elements in the correct display order.
536
            while ($page = $oRowset->fetchRow()) {
537
                // ignore all pages that the current user is not permitted to view
538
                if(version_compare(WB_VERSION, '2.7', '>=')) { // WB >= 2.7
539
                    // 1. hidden pages aren't shown unless they are on the current page
540
                    if ($page['visibility'] == 'hidden') {
541
                        $page['sm2_hide'] = true;
542
                    }
543
                    
544
                    // 2. all pages with no active sections (unless it is the top page) are ignored
545
                    else if (!$wb->page_is_active($page) && $page['link'] != $wb->default_link && !INTRO_PAGE) {
546
                        continue;
547
                    }
548

  
549
                    // 3. all pages not visible to this user (unless always visible to registered users) are ignored
550
                    else if (!$wb->page_is_visible($page) && $page['visibility'] != 'registered') {
551
                        continue;
552
                    }
553
                }
554

  
555
                // ensure that we have an array entry in the table to add this to
556
                $idx = $page['parent'];
557
                if (!array_key_exists($idx, $rgParent)) {
558
                    $rgParent[$idx] = array();
559
                }
560

  
561
                // mark our current page as being on the current path
562
                if ($page['page_id'] == $CURR_PAGE_ID) {
563
                    $page['sm2_is_curr'] = true;
564
                    $page['sm2_on_curr_path'] = true;
565
                    if ($flags & SM2_SHOWHIDDEN) 
566
					{ 
567
                        // show hidden pages if active and SHOWHIDDEN flag supplied
568
                        unset($page['sm2_hide']); 
569
                    }
570
                }
571

  
572
                // mark parents of the current page as such
573
                if (in_array($page['page_id'], $rgCurrParents)) {
574
                    $page['sm2_is_parent'] = true;
575
                    $page['sm2_on_curr_path'] = true;
576
                    if ($flags & SM2_SHOWHIDDEN) 
577
					{
578
                        // show hidden pages if active and SHOWHIDDEN flag supplied
579
						unset($page['sm2_hide']); // don't hide a parent page                
580
                    }
581
                }
582
                
583
                // add the entry to the array                
584
                $rgParent[$idx][] = $page;
585
            }
586
        }    
587
        unset($oRowset);
588

  
589
        // mark all elements that are siblings of any element on the current path
590
        foreach ($rgCurrParents as $x) {
591
            if (array_key_exists($x, $rgParent)) {
592
                foreach (array_keys($rgParent[$x]) as $y) {
593
                    $mark =& $rgParent[$x][$y];
594
                    $mark['sm2_path_sibling'] = true;
595
                    unset($mark);
596
                }
597
            }
598
        }
599

  
600
        // mark all elements that have children and are siblings of the current page
601
        $parentId = $pageParent;
602
        foreach (array_keys($rgParent) as $x) {
603
            $childSet =& $rgParent[$x];
604
            foreach (array_keys($childSet) as $y) {
605
                $mark =& $childSet[$y];
606
                if (array_key_exists($mark['page_id'], $rgParent)) {
607
                    $mark['sm2_has_child'] = true;
608
                }
609
                if ($mark['parent'] == $parentId && $mark['page_id'] != $CURR_PAGE_ID) {
610
                    $mark['sm2_is_sibling'] = true;
611
                }
612
                unset($mark);
613
            }
614
            unset($childSet);
615
        }
616
        
617
        // mark all children of the current page. We don't do this when 
618
        // $CURR_PAGE_ID is 0, as 0 is the parent of everything. 
619
        // $CURR_PAGE_ID == 0 occurs on special pages like search results
620
        // when no referrer is available.s
621
        if ($CURR_PAGE_ID != 0) {
622
            sm2_mark_children($rgParent, $CURR_PAGE_ID, 1);
623
        }
624
        
625
        // store the complete processed menu data as a global. We don't 
626
        // need to read this from the database anymore regardless of how 
627
        // many menus are displayed on the same page.
628
        if (!array_key_exists('show_menu2_data', $GLOBALS)) {
629
            $GLOBALS['show_menu2_data'] = array();
630
        }
631
        $GLOBALS['show_menu2_data'][$aMenu] =& $rgParent;
632
        unset($rgParent);
633
    }
634

  
635
    // adjust $aMaxLevel to the level number of the final level that 
636
    // will be displayed. That is, we display all levels <= aMaxLevel.
637
    if ($aMaxLevel == SM2_ALL) {
638
        $aMaxLevel = 1000;
639
    }
640
    elseif ($aMaxLevel < 0) {   // SM2_CURR+N
641
        $aMaxLevel += $pageLevel - SM2_CURR;
642
    }
643
    elseif ($aMaxLevel >= SM2_MAX) { // SM2_MAX+N
644
        $aMaxLevel += $aStartLevel - SM2_MAX;
645
        if ($aMaxLevel > $pageLevel) {
646
            $aMaxLevel = $pageLevel;
647
        }
648
    }
649
    else {  // SM2_START+N
650
        $aMaxLevel += $aStartLevel - SM2_START;
651
    }
652

  
653
    // generate the menu
654
    $retval = false;
655
    if (array_key_exists($aStart, $GLOBALS['show_menu2_data'][$aMenu])) {
656
        $formatter = $aItemOpen;
657
        if (!is_object($aItemOpen)) {
658
            static $sm2formatter;
659
            if (!isset($sm2formatter)) {
660
                $sm2formatter = new SM2_Formatter;
661
            }
662
            $formatter = $sm2formatter;
663
            $formatter->set($flags, $aItemOpen, $aItemClose, 
664
                $aMenuOpen, $aMenuClose, $aTopItemOpen, $aTopMenuOpen);
665
        }
666
        
667
        // adjust the level until we show everything and ignore the SM2_TRIM flag.
668
        // Usually this will be less than the start level to disable it.
669
        $showAllLevel = $aStartLevel - 1;
670
        if (isset($aOptions['notrim'])) {
671
            $showAllLevel = $aStartLevel + $aOptions['notrim'];
672
        }
673
        
674
        // display the menu
675
        $formatter->initialize();
676
        sm2_recurse(
677
            $GLOBALS['show_menu2_data'][$aMenu],
678
            $aStart,    // parent id to start displaying sub-menus
679
            $aStartLevel, $showAllLevel, $aMaxLevel, $flags, 
680
            $formatter);
681
        $formatter->finalize();
682
        
683
        // if we are returning something, get the data
684
        if (($flags & SM2_BUFFER) != 0) {
685
            $retval = $formatter->getOutput();
686
        }
687
    }
688

  
689
    // clear the data if we aren't caching it
690
    if (($flags & SM2_NOCACHE) != 0) {
691
        unset($GLOBALS['show_menu2_data'][$aMenu]);
692
    }
693
    
694
    return $retval;
695
}
696

  
697
function sm2_mark_children(&$rgParent, $aStart, $aChildLevel)
698
{
699
    if (array_key_exists($aStart, $rgParent)) {
700
        foreach (array_keys($rgParent[$aStart]) as $y) {
701
            $mark =& $rgParent[$aStart][$y];
702
            $mark['sm2_child_level'] = $aChildLevel;
703
            $mark['sm2_on_curr_path'] = true;
704
            sm2_mark_children($rgParent, $mark['page_id'], $aChildLevel+1);
705
        }
706
    }
707
}
708

  
709
function sm2_recurse(
710
    &$rgParent, $aStart, 
711
    $aStartLevel, $aShowAllLevel, $aMaxLevel, $aFlags, 
712
    &$aFormatter
713
    )
714
{
715
    global $wb;
716

  
717
    // on entry to this function we know that there are entries for this 
718
    // parent and all entries for that parent are being displayed. We also 
719
    // need to check if any of the children need to be displayed too.
720
    $isListOpen = false;
721
    $currentLevel = $wb->page['level'] == '' ? 0 : $wb->page['level'];
722

  
723
    // get the number of siblings skipping the hidden pages so we can pass 
724
    // this in and check if the item is first or last
725
    $sibCount = 0;
726
    foreach ($rgParent[$aStart] as $page) {
727
        if (!array_key_exists('sm2_hide', $page)) $sibCount++;
728
    }
729
    
730
    $currSib = 0;
731
    foreach ($rgParent[$aStart] as $page) {
732
        // skip all hidden pages 
733
        if (array_key_exists('sm2_hide', $page)) { // not set if false, so existence = true
734
            continue;
735
        }
736
        
737
        $currSib++;
738

  
739
        // skip any elements that are lower than the maximum level
740
        $pageLevel = $page['level'];
741
        if ($pageLevel > $aMaxLevel) {
742
            continue;
743
        }
744
        
745
        // this affects ONLY the top level
746
        if ($aStart == 0 && ($aFlags & SM2_CURRTREE)) {
747
            if (!array_key_exists('sm2_on_curr_path', $page)) { // not set if false, so existence = true
748
                continue;
749
            }
750
            $sibCount = 1;
751
        }
752
        
753
        // trim the tree as appropriate
754
        if ($aFlags & SM2_SIBLING) {
755
            // parents, and siblings and children of current only
756
            if (!array_key_exists('sm2_on_curr_path', $page)      // not set if false, so existence = true
757
                && !array_key_exists('sm2_is_sibling', $page)     // not set if false, so existence = true
758
                && !array_key_exists('sm2_child_level', $page)) { // not set if false, so existence = true
759
                continue;
760
            }
761
        }
762
        else if ($aFlags & SM2_TRIM) {
763
            // parents and siblings of parents
764
            if ($pageLevel > $aShowAllLevel  // permit all levels to be shown
765
                && !array_key_exists('sm2_on_curr_path', $page)    // not set if false, so existence = true
766
                && !array_key_exists('sm2_path_sibling', $page)) {  // not set if false, so existence = true
767
                continue;
768
            }
769
        }
770
        elseif ($aFlags & SM2_CRUMB) {
771
            // parents only
772
            if (!array_key_exists('sm2_on_curr_path', $page)    // not set if false, so existence = true
773
                || array_key_exists('sm2_child_level', $page)) {  // not set if false, so existence = true
774
                continue;
775
            }
776
        }
777

  
778
        // depth first traverse
779
        $nextParent = $page['page_id'];
780

  
781
        // display the current element if we have reached the start level
782
        if ($pageLevel >= $aStartLevel) {
783
            // massage the link into the correct form
784
            if(!INTRO_PAGE && $page['link'] == $wb->default_link) {
785
                $url = WB_URL;
786
            }
787
            else {
788
                $url = $wb->page_link($page['link']);
789
            }
790
                    
791
            // we open the list only when we absolutely need to
792
            if (!$isListOpen) {
793
                $aFormatter->startList($page, $url);
794
                $isListOpen = true;
795
            }
796

  
797
            $aFormatter->startItem($page, $url, $currSib, $sibCount);
798
        }
799
        
800
        // display children as appropriate
801
        if ($pageLevel + 1 <= $aMaxLevel 
802
            && array_key_exists('sm2_has_child', $page)) {  // not set if false, so existence = true
803
            sm2_recurse(
804
                $rgParent, $nextParent, // parent id to start displaying sub-menus
805
                $aStartLevel, $aShowAllLevel, $aMaxLevel, $aFlags, 
806
                $aFormatter);
807
        }
808
        
809
        // close the current element if appropriate
810
        if ($pageLevel >= $aStartLevel) {
811
            $aFormatter->finishItem($pageLevel, $page);
812
        }
813
    }
814

  
815
    // close the list if we opened one
816
    if ($isListOpen) {
817
        $aFormatter->finishList();
818
    }
819
}
820

  
821
?>
1
<?php
2
/**
3
 *
4
 * @category        module
5
 * @package         show_menu2
6
 * @author          WebsiteBaker Project
7
 * @copyright       2004-2009, Ryan Djurovich
8
 * @copyright       2009-2010, Website Baker Org. e.V.
9
 * @link			http://www.websitebaker2.org/
10
 * @license         http://www.gnu.org/licenses/gpl.html
11
 * @platform        WebsiteBaker 2.7.0 | 2.8.x
12
 * @requirements    PHP 4.4.9 and higher
13
 * @version         $Id$
14
 * @filesource		$HeadURL$
15
 * @lastmodified    $Date$
16
 *
17
 */
18

  
19
define('SM2_ROOT',          -1000);
20
define('SM2_CURR',          -2000);
21
define('SM2_ALLMENU',          -1);
22
define('SM2_START',          1000);
23
define('SM2_MAX',            2000);
24
define('SM2_ALL',          0x0001); // bit 0 (group 1) (Note: also used for max level!)
25
define('SM2_TRIM',         0x0002); // bit 1 (group 1)
26
define('SM2_CRUMB',        0x0004); // bit 2 (group 1)
27
define('SM2_SIBLING',      0x0008); // bit 3 (group 1)
28
define('SM2_NUMCLASS',     0x0010); // bit 4
29
define('SM2_ALLINFO',      0x0020); // bit 5
30
define('SM2_NOCACHE',      0x0040); // bit 6
31
define('SM2_PRETTY',       0x0080); // bit 7
32
define('SM2_ESCAPE',       0x0100); // bit 8
33
define('SM2_NOESCAPE',          0); // NOOP, unnecessary with WB 2.6.7+
34
define('SM2_BUFFER',       0x0200); // bit 9
35
define('SM2_CURRTREE',     0x0400); // bit 10
36
define('SM2_SHOWHIDDEN',   0x0800); // bit 11
37
define('SM2_XHTML_STRICT', 0x1000); // bit 12
38
define('SM2_NO_TITLE',     0x1001); // bit 13
39

  
40
define('_SM2_GROUP_1',  0x000F); // exactly one flag from group 1 is required
41

  
42

  
43
// Implement support for page_menu and show_menu using show_menu2. If you remove
44
// the comments characters from the beginning of the following include, all menu
45
// functions in Website Baker will be implemented using show_menu2. While it is
46
// commented out, the original WB functions will be used.
47
//include('legacy.php');
48

  
49
// This class is the default menu formatter for sm2. If desired, you can 
50
// create your own formatter class and pass the object into show_menu2 
51
// as $aItemFormat.
52
define('SM2_CONDITIONAL','if\s*\(([^\)]+)\)\s*{([^}]*)}\s*(?:else\s*{([^}]*)}\s*)?');
53
define('SM2_COND_TERM','\s*(\w+)\s*(<|<=|==|=|=>|>|!=)\s*([\w\-]+)\s*');
54
class SM2_Formatter
55
{
56
    var $output;
57
    var $flags;
58
    var $itemOpen;
59
    var $itemClose;
60
    var $menuOpen;
61
    var $menuClose;
62
    var $topItemOpen;
63
    var $topMenuOpen;
64
    
65
    var $isFirst;
66
    var $page;
67
    var $url;
68
    var $currSib;
69
    var $sibCount;
70
    var $currClass;
71
    var $prettyLevel;
72

  
73
    // output the data
74
    function output($aString) {
75
        if ($this->flags & SM2_BUFFER) {
76
            $this->output .= $aString;
77
        }
78
        else {
79
            echo $aString;
80
        }
81
    }
82
    
83
    // set the default values for all of our formatting items
84
    function set($aFlags, $aItemOpen, $aItemClose, $aMenuOpen, $aMenuClose, $aTopItemOpen, $aTopMenuOpen) {
85
        $this->flags        = $aFlags;
86
        $this->itemOpen     = is_string($aItemOpen)    ? $aItemOpen    : '[li][a][menu_title]</a>';
87
        $this->itemClose    = is_string($aItemClose)   ? $aItemClose   : '</li>';
88
        $this->menuOpen     = is_string($aMenuOpen)    ? $aMenuOpen    : '[ul]';
89
        $this->menuClose    = is_string($aMenuClose)   ? $aMenuClose   : '</ul>';
90
        $this->topItemOpen  = is_string($aTopItemOpen) ? $aTopItemOpen : $this->itemOpen;
91
        $this->topMenuOpen  = is_string($aTopMenuOpen) ? $aTopMenuOpen : $this->menuOpen;
92
    }
93

  
94
    // initialize the state of the formatter before anything is output
95
    function initialize() {
96
        $this->output = '';
97
        $this->prettyLevel = 0;
98
        if ($this->flags & SM2_PRETTY) {
99
            $this->output("\n<!-- show_menu2 -->");
100
        }
101
    }
102

  
103
    // start a menu     
104
    function startList(&$aPage, &$aUrl) {
105
        $currClass = '';
106
        $currItem = $this->menuOpen;
107
        
108
        // use the top level menu open if this is the first menu
109
        if ($this->topMenuOpen) {
110
            $currItem = $this->topMenuOpen;
111
            $currClass .= ' menu-top';
112
            $this->topMenuOpen = false;
113
        }
114
        
115
        // add the numbered menu class only if requested
116
        if (($this->flags & SM2_NUMCLASS) == SM2_NUMCLASS) {
117
            $currClass .= ' menu-'.$aPage['level'];
118
        }
119
        
120
        $this->prettyLevel += 1;
121
        
122
        // replace all keywords in the output
123
        if ($this->flags & SM2_PRETTY) {
124
            $this->output("\n".str_repeat(' ',$this->prettyLevel).
125
                $this->format($aPage, $aUrl, $currItem, $currClass));
126
        }
127
        else {
128
            $this->output($this->format($aPage, $aUrl, $currItem, $currClass));
129
        }
130
        
131
        $this->prettyLevel += 3;
132
    }
133
    
134
    // start an item within the menu
135
    function startItem(&$aPage, &$aUrl, $aCurrSib, $aSibCount) {
136
        // generate our class list
137
        $currClass = '';
138
        if (($this->flags & SM2_NUMCLASS) == SM2_NUMCLASS) {
139
            $currClass .= ' menu-'.$aPage['level'];
140
        }
141
        if (array_key_exists('sm2_has_child', $aPage)) {
142
            // not set if false, so existence = true
143
            $currClass .= ' menu-expand';
144
        }
145
        if (array_key_exists('sm2_is_curr', $aPage)) { 
146
            $currClass .= ' menu-current';
147
        }
148
        elseif (array_key_exists('sm2_is_parent', $aPage)) { 
149
            // not set if false, so existence = true
150
            $currClass .= ' menu-parent';
151
        }
152
        elseif (array_key_exists('sm2_is_sibling', $aPage)) {
153
            // not set if false, so existence = true
154
            $currClass .= ' menu-sibling';
155
        }
156
        elseif (array_key_exists('sm2_child_level',$aPage)) {
157
            // not set if not a child
158
            $currClass .= ' menu-child';
159
            if (($this->flags & SM2_NUMCLASS) == SM2_NUMCLASS) {
160
                $currClass .= ' menu-child-'.($aPage['sm2_child_level']-1);
161
            }
162
        }
163
        if ($aCurrSib == 1) {
164
            $currClass .= ' menu-first';
165
        }
166
        if ($aCurrSib == $aSibCount) {
167
            $currClass .= ' menu-last';
168
        }
169

  
170
        // use the top level item if this is the first item
171
        $currItem = $this->itemOpen;
172
        if ($this->topItemOpen) {
173
            $currItem = $this->topItemOpen;
174
            $this->topItemOpen = false;
175
        }
176

  
177
        // replace all keywords in the output
178
        if ($this->flags & SM2_PRETTY) {
179
            $this->output("\n".str_repeat(' ',$this->prettyLevel));
180
        }
181
        $this->output($this->format($aPage, $aUrl, $currItem, $currClass, $aCurrSib, $aSibCount));
182
    }
183
    
184
    // find and replace all keywords, setting the state variables first
185
    function format(&$aPage, &$aUrl, &$aCurrItem, &$aCurrClass, 
186
        $aCurrSib = 0, $aSibCount = 0) 
187
    {
188
        $this->page      = &$aPage;
189
        $this->url       = &$aUrl;
190
        $this->currClass = trim($aCurrClass);
191
        $this->currSib   = $aCurrSib;
192
        $this->sibCount  = $aSibCount;
193
        
194
        $item = $this->format2($aCurrItem);
195
        
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff