Ergebnis 1 bis 40 von 40

Thema: lightbox mit catalog geht nicht mehr

  1. #1
    Contao-Fan
    Registriert seit
    29.07.2011.
    Beiträge
    411

    Standard lightbox mit catalog geht nicht mehr

    Hallo zusammen,

    lightbox mit dem Catalog funktioniert seit dem update auf 2.11 nicht mehr.
    Jetzt habe ich schon contao 2.11.2, lightbox mit dem normalen Bildergalerie oder einzelne Bilder geht gut, mit dem catalog immer noch nicht. es werden die Bilder in gleichem Fenster geöffnet.

    Catalog aus dem SVN
    Contao 2.11.2

    bin ich der einzige der das problem hat?

  2. #2
    Contao-Nutzer Avatar von florilein
    Registriert seit
    12.01.2012.
    Ort
    Spanien
    Beiträge
    64

    Standard

    Hallo


    vielleicht hilft dir das hier weiter:
    Replaced the `rel="lightbox"` attribute with `data-lightbox=""` in all HTML5
    templates, because `rel="lightbox"` is not a valid attribute actually.

  3. #3
    Contao-Fan
    Registriert seit
    29.07.2011.
    Beiträge
    411

    Standard

    aktuell in modulcatalog.php ist es schon geändert:
    Code:
    if(version_compare(TL_VERSION, '2.11', '>='))
    {
    $tmpFile = '<a data-lightbox="lb' . $this->strTable . $strId . '" href="'.$file.'" title="'.$alt.'">'.$tmpFile.'</a>';
    } else {
    $tmpFile = '<a rel="lightbox[lb' . $this->strTable . $strId . ']" href="'.$file.'" title="'.$alt.'">'.$tmpFile.'</a>';
    }

  4. #4
    Contao-Nutzer Avatar von florilein
    Registriert seit
    12.01.2012.
    Ort
    Spanien
    Beiträge
    64

    Standard

    du hast da noch ein rel-lightbox drin

    PHP-Code:
    if(version_compare(TL_VERSION'2.11''>='))
    {

    $tmpFile '<a rel="lightbox[lb' $this->strTable $strId ']" href="'.$file.'" title="'.$alt.'">'.$tmpFile.'</a>';


  5. #5
    Contao-Fan
    Registriert seit
    29.07.2011.
    Beiträge
    411

    Standard

    ja, jetzt geht's
    vielen dank!

  6. #6
    Contao-Yoda Avatar von MacKP
    Registriert seit
    15.06.2009.
    Ort
    Duisburg
    Beiträge
    13.292
    User beschenken
    Wunschliste
    Contao-Projekt unterstützen

    Support Contao

    Standard

    Bitte dazu ein Ticket beim Catalog-TIcket System machen (contao-forge).

    Viele Grüße
    Contao Pool | C-C-A | MetaModels | [Internetseite -> Mediendepot Ruhr]
    [Arbeitet bei -> Paus Design & Medien]
    "I can EXPLAIN it to you, but I can't UNDERSTAND it for you."

  7. #7
    Contao-Fan
    Registriert seit
    29.07.2011.
    Beiträge
    411

  8. #8
    Contao-Fan
    Registriert seit
    29.07.2011.
    Beiträge
    411

    Standard

    also die richtige Version ist so:
    Code:
    if(version_compare(VERSION, '2.11', '>='))
    {
    $tmpFile = '<a data-lightbox="lb' . $this->strTable . $strId . '" href="'.$file.'" title="'.$alt.'">'.$tmpFile.'</a>';
    } else {
    $tmpFile = '<a rel="lightbox[lb' . $this->strTable . $strId . ']" href="'.$file.'" title="'.$alt.'">'.$tmpFile.'</a>';
    }
    VERSION, '2.11' statt TL-VERSION, '2.11'. rel="lightbox war richtig

    danke an Andy Pillip

  9. #9
    Contao-Nutzer Avatar von jabadoo
    Registriert seit
    15.08.2009.
    Beiträge
    63

    Standard

    Also ich konnte das Problem nur mit folgendem Code in 2.11.2 lösen:
    Code:
    if(version_compare(VERSION, '2.11', '>='))
    {
    $tmpFile = '<a data-lightbox="lb' . $this->strTable . $strId . '" href="'.$file . '/' . $subfile.'" title="'.$alt.'">'.$tmpFile.'</a>';
    } else {
    $tmpFile = '<a rel="lightbox[lb' . $this->strTable . $strId . ']" href="'.$file . '/' . $subfile.'" title="'.$alt.'">'.$tmpFile.'</a>';
    }

  10. #10
    Maintainer Avatar von xtra
    Registriert seit
    02.07.2009.
    Ort
    Tuebingen
    Beiträge
    2.007
    User beschenken
    Wunschliste

    Standard

    In dem check ist noch ein Problem, es wird noch nicht gecheckt, ob auch das html5 Format ausgewaehlt wurde und nicht xhtml.

    Somit funktioniert es nun unter 2.11 & xhtml nicht mehr.

    Patch is underway.
    Bedenke stets: Wenn Du ungenaue oder unzureichende Angaben machst, so koennte dies die Bearbeitung deiner Frage endlos verzoegern (oder sogar dazu fyhren, dass ich zu viel nachdenken muss und die Antwort vergesse!). Kein Support per PN.

  11. #11
    Contao-Nutzer
    Registriert seit
    23.06.2010.
    Ort
    Bremen
    Beiträge
    112

    Standard

    Hallo,

    ich würde hier gern nochmal nachhaken.
    Ich verwende den Catalog 2.0.0 beta2 mit Contao 2.11.2 und hatte auch das Problem, dass die Bilder im Catalog sich nicht in einer Lightbox (egal ob Slimbox, Mediabox oder Lightbox4ward) öffnen ließen.
    Dann habe ich - nach Anleitung in diesem Thread - die passenden Zeilen in der ModulCatalog.php gesucht, aber nicht gefunden.

    Stattdessen musste ich in den Zeilen 2558 und 2665 jeweils folgende Anpassung vornehmen:

    PHP-Code:
    $tmpFile '<a rel="lightbox[lb' $this->strTable $id ']" title="'.$alt.'" href="'.$file '/' $subfile.'">'.$tmpFile.'</a>'
    wird zu

    PHP-Code:
    $tmpFile '<a data-lightbox=[lb' $this->strTable $id ']" title="'.$alt.'" href="'.$file '/' $subfile.'">'.$tmpFile.'</a>'
    Und jetzt klappt das.
    Geändert von Freeflow (11.05.2012 um 08:50 Uhr)

  12. #12
    AG CMS-Garden
    Contao-Urgestein
    Avatar von lindesbs
    Registriert seit
    05.06.2009.
    Ort
    Oer-Erkenschwick
    Beiträge
    4.154
    Partner-ID
    keine
    User beschenken
    Wunschliste

    Standard

    Obiger Kontext bezog sich auch auf den Catalog aus dem SVN.
    Da koennen Zeilenbezuege anders sein.
    von Willi Voltz aus PR 500: Henry George sagte einmal: »Kultur ist Zusammenarbeit.«


    Contao-Hosting: begeisterter Uberspace-Nutzer

  13. #13
    Contao-Nutzer
    Registriert seit
    23.06.2010.
    Ort
    Bremen
    Beiträge
    112

    Standard

    Hallo lindesb,

    danke für den Hinweis.
    Ich dachte nur, dass vielleicht andere, die auch die 2.0.0 beta verwenden, sich dann die Suche im Code ersparen können. ;-)

  14. #14
    Contao-Nutzer
    Registriert seit
    30.07.2009.
    Ort
    Hessen
    Beiträge
    147

    Standard

    Hi, möchte das Thema auch nochmal hoch holen. Habe gemäß der Änderungen hier im Thread den Link angepasst, danach das Feld Bilder nochmal neu gespeichert, damit die Änderung im Template greif, im Code ist es auch geändert, aber die Lightbox funktioniert nicht. Den Catalog hab ich auf die neuste Version aus dem Repository geupdated. (catalog 2.0.0 beta2 61)

    HTML-Code:
    <a rel="lightbox[lbcat_einsaetzecatalogreader0]" title="Bildname" href="tl_files/Bilder/12_01_01-3_01.jpg"><img src="system/html/12_01_01-3_01-7b06e3ff.jpg" alt="01 01-3 01" width="171" height="120"></a>
    Im entsprechenden Seitenlayout ist "moo_slimbox" ausgewählt.

    Hab ich noch was übersehen ?

  15. #15
    Contao-Yoda Avatar von MacKP
    Registriert seit
    15.06.2009.
    Ort
    Duisburg
    Beiträge
    13.292
    User beschenken
    Wunschliste
    Contao-Projekt unterstützen

    Support Contao

    Standard

    Hallo zonk,
    ich glaub du hast vergessen die Anpassung für 2.11 zu machen XD

    Da sollte im Quellcode dann sowas stehen: <a data-lightbox=[lb

    So ist das ja auch ein paar Threads weiter oben beschrieben...

    Viele Grüße
    Contao Pool | C-C-A | MetaModels | [Internetseite -> Mediendepot Ruhr]
    [Arbeitet bei -> Paus Design & Medien]
    "I can EXPLAIN it to you, but I can't UNDERSTAND it for you."

  16. #16
    Contao-Nutzer
    Registriert seit
    30.07.2009.
    Ort
    Hessen
    Beiträge
    147

    Standard

    Moin, danke für die schnelle Antwort, du hast recht mein Post war Banane.. ABER

    Ich hab die Änderungen durchgeführt: -> $tmpFile = '<a data-lightbox=[lb' . $this->strTable . $id . ']" title="'.$alt.'" href="'.$file . '/' . $subfile.'">'.$tmpFile.'</a>';

    In der ModulCatalog.php .. aber im Quelltext steht immer noch der alte Code. Am Cache liegt es definitiv nicht.. wie gesagt in der ModulCatalog.php steht:

    HTML-Code:
    $tmpFile = '<img src="'.$src.'" alt="'.$alt.'" '.$size[3].' />';
    						if ($showLink)	
    						{
    							// $tmpFile = '<a rel="lightbox[lb'.$id.']" href="'.$file.'" title="'.$alt.'">'.$tmpFile.'</a>';
    							// we have to supply the catalog id here as we might have more than one catalog with a field with the same name 
    							// which will cause the lightbox to display the images for items with the same id in both.
    							/*  tmpFile = '<a rel="lightbox[lb' . $this->strTable . $id . ']" href="'.$file.'" title="'.$alt.'">'.$tmpFile.'</a>'; */
    						  $tmpFile = '<a data-lightbox=[lb' . $this->strTable . $id . ']" title="'.$alt.'" href="'.$file . '/' . $subfile.'">'.$tmpFile.'</a>';
                }

  17. #17
    Contao-Yoda Avatar von MacKP
    Registriert seit
    15.06.2009.
    Ort
    Duisburg
    Beiträge
    13.292
    User beschenken
    Wunschliste
    Contao-Projekt unterstützen

    Support Contao

    Standard

    Hallo zonk,
    am Cache kanns nicht liegen? Hast du denn denn mal komplett gelöscht in der Systemwartung?

    Als Notnagel: bau den Link per Hand im Template zusammen.. die raw Daten sollten ja passen und die kann man wunderbar in nem img-Inserttag einsetzen.

    Viele Grüße
    Contao Pool | C-C-A | MetaModels | [Internetseite -> Mediendepot Ruhr]
    [Arbeitet bei -> Paus Design & Medien]
    "I can EXPLAIN it to you, but I can't UNDERSTAND it for you."

  18. #18
    Contao-Nutzer
    Registriert seit
    30.07.2009.
    Ort
    Hessen
    Beiträge
    147

    Standard

    Hm, kannst du mir bzgl des Einbaus noch nen Tip geben ? Hab ja nicht immer Bilder mit dran.
    Cache kann ich ausschließen, eben an drei verschiedenen Rechnern getestet, wo die Seite noch nie geöffnet war.
    Was ich nicht verstehe, wenn es richtig im Code steht, wieso dann im Quelltext noch der alte Inhalt steht ?

  19. #19
    Contao-Yoda Avatar von MacKP
    Registriert seit
    15.06.2009.
    Ort
    Duisburg
    Beiträge
    13.292
    User beschenken
    Wunschliste
    Contao-Projekt unterstützen

    Support Contao

    Standard

    Dann kannst du den Cache eben doch nicht ausschließen. Zumindest nicht den Contao eigenen.
    Geh mal auf Systemwartung und lösche system/html system/scripts system/tmp
    Erst dann kannst du sicher sein, das es nicht daran liegt.

    Für Template: steht eigentlich alles im Wiki. Nur ne if-Abfrage drum herum, das es nur ausgegeben wird, wenn überhaupt ein Bild im Array ist (steht auch im Wiki).

    Viele Grüße
    Contao Pool | C-C-A | MetaModels | [Internetseite -> Mediendepot Ruhr]
    [Arbeitet bei -> Paus Design & Medien]
    "I can EXPLAIN it to you, but I can't UNDERSTAND it for you."

  20. #20
    Contao-Nutzer
    Registriert seit
    30.07.2009.
    Ort
    Hessen
    Beiträge
    147

    Standard

    Also auch dieser Cache wurde mehrfach geleert, im Quelltext steht weiterhin der alte Code:

    rel="lightbox[lbcat_einsaetzecatalogreader0]"><img alt="06 22 01" src="system/html/12_06_22_01-5effb8f4.jpg" width="171" height="120">

    Warum übernimmt er das denn nicht aus der ModulCatalog.php ??

    Wiki schau ich nach, Danke für den Tipp..

  21. #21
    Contao-Yoda Avatar von MacKP
    Registriert seit
    15.06.2009.
    Ort
    Duisburg
    Beiträge
    13.292
    User beschenken
    Wunschliste
    Contao-Projekt unterstützen

    Support Contao

    Standard

    Hallo zonk,
    ich kann dir gerade nicht sagen, warum der das nicht übernimmt.
    Eventuell hast du nicht die richtige Stelle erwischt?

    Viele Grüße
    Contao Pool | C-C-A | MetaModels | [Internetseite -> Mediendepot Ruhr]
    [Arbeitet bei -> Paus Design & Medien]
    "I can EXPLAIN it to you, but I can't UNDERSTAND it for you."

  22. #22
    Contao-Nutzer
    Registriert seit
    30.07.2009.
    Ort
    Hessen
    Beiträge
    147

    Standard

    ModuleCatalog.php

    Zeilen 2574-2582, letzte Version aus dem Repository

    HTML-Code:
    $tmpFile = '<img src="'.$src.'" alt="'.$alt.'" '.$size[3].' />';
    						
    if ($showLink)	
    						
    {
    // $tmpFile = '<a rel="lightbox[lb'.$id.']" href="'.$file.'" title="'.$alt.'">'.$tmpFile.'</a>';
    // we have to supply the catalog id here as we might have more than one catalog with a field with the same name 
    // which will cause the lightbox to display the images for items with the same id in both.
    // tmpFile = '<a rel="lightbox[lb' . $this->strTable . $id . ']" href="'.$file.'" title="'.$alt.'">'.$tmpFile.'</a>';
    
    $tmpFile = '<a data-lightbox=[lb' . $this->strTable . $id . ']" title="'.$alt.'" href="'.$file . '/' . $subfile.'">'.$tmpFile.'</a>';
    }
    So bin auch noch in der Zeile 2666 fündig geworden. NARF .. Nun stimmt es im Quelltext schon einmal
    HTML-Code:
    <a data-lightbox="[lbcat_einsaetzecatalogreader0]&quot;" title="06 22 01" href="tl_files/...
    aber die Bilder werden trotzdem nicht in der Lightbox angezeigt. Was könnte jetzt noch fehlen ?
    Geändert von zonk (09.07.2012 um 10:39 Uhr)

  23. #23
    Contao-Yoda Avatar von MacKP
    Registriert seit
    15.06.2009.
    Ort
    Duisburg
    Beiträge
    13.292
    User beschenken
    Wunschliste
    Contao-Projekt unterstützen

    Support Contao

    Standard

    Hallo zonk,
    such mal in der Datei nach 'lightbox' es gibt da soweit ich weiß noch ne andere Stelle wo das gesetzt wird.
    Ansonsten guck im SVN, da sind die Anpassungen schon gemacht (auch einfach suchen und kopieren).

    Viele Grüße

    Edit: da hat sich das anscheinend überschnitte...
    Wird die Lightbox denn auf 'normalen' Seiten angezeigt? Oder überall nicht?
    Contao Pool | C-C-A | MetaModels | [Internetseite -> Mediendepot Ruhr]
    [Arbeitet bei -> Paus Design & Medien]
    "I can EXPLAIN it to you, but I can't UNDERSTAND it for you."

  24. #24
    Contao-Nutzer
    Registriert seit
    30.07.2009.
    Ort
    Hessen
    Beiträge
    147

    Standard

    Auf normalen Seiten ohne Probleme, mit den gleichen Einstellungen im Seitenlayout, nur im Catalog nicht.

  25. #25
    Contao-Yoda Avatar von MacKP
    Registriert seit
    15.06.2009.
    Ort
    Duisburg
    Beiträge
    13.292
    User beschenken
    Wunschliste
    Contao-Projekt unterstützen

    Support Contao

    Standard

    Und der Quellcode sieht jetzt genau gleich aus?
    Ist auch 100% das JavaScript eingebunden? Guck mal in den Quellcode ganz am Ende der Seite, ob da der passende Aufruf ist.

    Viele Grüße
    Contao Pool | C-C-A | MetaModels | [Internetseite -> Mediendepot Ruhr]
    [Arbeitet bei -> Paus Design & Medien]
    "I can EXPLAIN it to you, but I can't UNDERSTAND it for you."

  26. #26
    Contao-Nutzer
    Registriert seit
    30.07.2009.
    Ort
    Hessen
    Beiträge
    147

    Standard

    Also ich habe gerade mal den Code verglichen von Seiten wo es geht, und im Catalog, ist eigentlich bis auf Reihenfolge der Attribute gleich.

    Code im Catalog:
    HTML-Code:
    <a data-lightbox="cat_einsaetzecatalogreader0" title="06 22 01" href="tl_files/Bilder/[...].jpg">
    <img src="system/html/12_06_22_01-5effb8f4.jpg" alt="06 22 01" width="171" height="120">
    </a>
    Code auf normalen Seiten (Newsreader)
    HTML-Code:
    <a href="tl_files/Bilder/[...].jpg" data-lightbox="lb1047" title="05 04 01">
    <img src="system/html/12_05_04_01-b4b8852c.jpg" width="165" height="120" alt="05 04 01">
    </a>

    Das Javascript am Ende ist auf beiden Seiten identisch:
    Code:
    <script>
    Slimbox.scanPage = function() {
      $$(document.links).filter(function(el) {
        return el.getAttribute('data-lightbox') != null;
      }).slimbox({
        // Put custom options here
      }, null, function(el) {
        return (this == el) || el.getAttribute('data-lightbox').match(this.getAttribute('data-lightbox'));
      });
    };
    window.addEvent('domready', Slimbox.scanPage);
    </script>
    
    <script>
    new Request({
      url:'system/html/cron.txt',
      onComplete: function(txt) {
        if (!txt) txt = 0;
        if (parseInt(txt) < (Math.round(+new Date()/1000) - 300)) {
          new Request({url:'cron.php'}).get();
        }
      }
    }).get();
    </script>

  27. #27
    Contao-Yoda Avatar von MacKP
    Registriert seit
    15.06.2009.
    Ort
    Duisburg
    Beiträge
    13.292
    User beschenken
    Wunschliste
    Contao-Projekt unterstützen

    Support Contao

    Standard

    Hallo zonk,
    dann weiß ich da gerade auch nicht weiter.. tut mir leid. Hast du vllt mal ne URL wo man sich das live anschauen kann?

    Viele Grüße
    Contao Pool | C-C-A | MetaModels | [Internetseite -> Mediendepot Ruhr]
    [Arbeitet bei -> Paus Design & Medien]
    "I can EXPLAIN it to you, but I can't UNDERSTAND it for you."

  28. #28
    Contao-Yoda Avatar von MacKP
    Registriert seit
    15.06.2009.
    Ort
    Duisburg
    Beiträge
    13.292
    User beschenken
    Wunschliste
    Contao-Projekt unterstützen

    Support Contao

    Standard

    Hallo zonk,
    leider kann ich immer noch nicht sagen, was genau das Problem ist. Eventuell liegt es an den Leerzeichen vom Ordnernamen? Die sollten eigenltich mit %20 ersetzt werden, was in dem Fall irgendwie nicht passiert. Oder es liegt daran, das du jquery nutzt?

    So oder so wäre es vllt praktischer, wenn du die URL hier postest, damit da vllt noch jemand anders drüber gucken kann.

    Viele Grüße
    Contao Pool | C-C-A | MetaModels | [Internetseite -> Mediendepot Ruhr]
    [Arbeitet bei -> Paus Design & Medien]
    "I can EXPLAIN it to you, but I can't UNDERSTAND it for you."

  29. #29
    Contao-Nutzer
    Registriert seit
    30.07.2009.
    Ort
    Hessen
    Beiträge
    147

    Standard

    OKay das mit den Ordnernamen teste ich.
    Und jQuery werde ich mal abschalten.
    Wenn das nicht hilft, poste ich die URL mal.

    Trotzdem viele Dank bis hier.

  30. #30
    Contao-Nutzer
    Registriert seit
    30.07.2009.
    Ort
    Hessen
    Beiträge
    147

    Standard

    So .. jQuery hab ich abgeschaltet. Leerzeichen in Ordnern habe ich entfernt und getestet, alles ohne Erfolg.

    Hier also die URL, vll. hat noch jemand eine Idee.

    News, hier geht die Lightbox;
    http://2012.feuerwehr-nauheim.de/nac...hsengrund.html

    Catalog, hier geht Sie nicht:
    http://2012.feuerwehr-nauheim.de/cat.../items/63.html

    In den beiden Seitenlayouts sind identische Einstellungen. Habe auch einen Backend-Account, falls jemand helfen kann. Bin echt ratlos ..

  31. #31
    Contao-Nutzer
    Registriert seit
    30.07.2009.
    Ort
    Hessen
    Beiträge
    147

    Standard

    Okay hab es durch Zufall gelöst..

    -jQeruy aus
    - moo_slimbox UND moo_accodion an, dann geht es ..

  32. #32
    Contao-Nutzer
    Registriert seit
    13.07.2009.
    Beiträge
    135

    Standard

    Ist jemand so nett und postet die letzte und funktionierende Version von ModuleCatalog.php ?
    Inzwischen gibt es hier so viele Varianten und Versionen.

    Danke!

  33. #33
    Contao-Nutzer
    Registriert seit
    30.07.2009.
    Ort
    Hessen
    Beiträge
    147

    Standard

    Zitat Zitat von valentin Beitrag anzeigen
    Ist jemand so nett und postet die letzte und funktionierende Version von ModuleCatalog.php ?
    Inzwischen gibt es hier so viele Varianten und Versionen.

    Danke!
    Geht es da nur um die Funktionalität der Lightbox ? Wenn ja, kann ich gerne meine Version einstellen, hier wurde nur angepasst um die Lightbox zum Laufen zu bringen.

  34. #34
    Contao-Nutzer
    Registriert seit
    13.07.2009.
    Beiträge
    135

    Standard

    Ja, ich habe gestern eine aktuelle Contao Version mit Catalog installiert und habe gerade festgestellt, dass die Lightbox nicht mehr funktioniert.
    Wenn du eine funktionierende Version hast, wäre das super!

    LG,
    V

  35. #35
    Contao-Nutzer
    Registriert seit
    30.07.2009.
    Ort
    Hessen
    Beiträge
    147

    Standard

    Nur zwei Zeilen verändert für Lightbox:
    PHP-Code:
    <?php if (!defined('TL_ROOT')) die('You can not access this file directly!');

    /**
     * TYPOlight webCMS
     *
     * The TYPOlight webCMS is an accessible web content management system that 
     * specializes in accessibility and generates W3C-compliant HTML code. It 
     * provides a wide range of functionality to develop professional websites 
     * including a built-in search engine, form generator, file and user manager, 
     * CSS engine, multi-language support and many more. For more information and 
     * additional TYPOlight applications like the TYPOlight MVC Framework please 
     * visit the project website https://contao.org.
     * 
     * The Catalog extension allows the creation of multiple catalogs of custom items,
     * each with its own unique set of selectable field types, with field extendability.
     * The Front-End modules allow you to build powerful listing and filtering of the 
     * data in each catalog.
     * 
     * PHP version 5
     * @copyright    Martin Komara, Thyon Design, CyberSpectrum 2007-2009
     * @author        Martin Komara, 
     *                 John Brand <john.brand@thyon.com>,
     *                 Christian Schiffler <c.schiffler@cyberspectrum.de>
     * @package        Catalog
     * @license        LGPL 
     * @filesource
     */


    /**
     * Class ModuleCatalog
     *
     * @copyright    Martin Komara, Thyon Design, CyberSpectrum 2007-2009
     * @author        Martin Komara, 
     *                 John Brand <john.brand@thyon.com>,
     *                 Christian Schiffler <c.schiffler@cyberspectrum.de>
     * @package        Controller
     *
     */
    abstract class ModuleCatalog extends Module
    {


        
    /**
         * Tablename String
         * @var string
         */
        
    protected    $strTable;

        
    /**
         * Name of the alias field
         * @var string
         */
        
    protected    $strAliasField;

        
    /**
         * Search String
         * @var string
         */
        
    protected    $strSearch     'search';

        
    /**
         * Sort String
         * @var string
         */
        
    protected    $strSort         'sort';

        
    /**
         * OrderBy String
         * @var string
         */
        
    protected    $strOrderBy    'orderby';


        protected 
    $systemColumns = array('id''pid''sorting''tstamp');


        protected    
    $arrTree;    

        protected    
    $cacheJumpTo;    

        public function 
    generate()
        {
            if (!
    strlen($this->catalog))
            {
                return 
    '';
            }

            
    // get DCA
            
    $objCatalog $this->Database->prepare('SELECT * FROM tl_catalog_types WHERE id=?')
                    ->
    limit(1)
                    ->
    execute($this->catalog);
            
            if (
    $objCatalog->numRows && $objCatalog->tableName)
            {
                
    $this->strTable $objCatalog->tableName;
                
    $this->strAliasField=$objCatalog->aliasField;
                
    $this->publishField=$objCatalog->publishField;

                
    // dynamically load dca for catalog operations
                
    $this->Import('Catalog');
                if(!
    $GLOBALS['TL_DCA'][$objCatalog->tableName]['Cataloggenerated'])
                {
                    
    // load language files and DC.
                    
    $this->loadLanguageFile($objCatalog->tableName);
                    
    $this->loadDataContainer($objCatalog->tableName);
                    
                    
    // load default language
                    
    $GLOBALS['TL_LANG'][$objType->tableName] = is_array($GLOBALS['TL_LANG'][$objType->tableName])
                                                         ? 
    Catalog::array_replace_recursive($GLOBALS['TL_LANG']['tl_catalog_items'], $GLOBALS['TL_LANG'][$objType->tableName])
                                                         : 
    $GLOBALS['TL_LANG']['tl_catalog_items'];
                    
    // load dca
                    
    $GLOBALS['TL_DCA'][$objCatalog->tableName] = 
                        
    is_array($GLOBALS['TL_DCA'][$objCatalog->tableName])
                            ? 
    Catalog::array_replace_recursive($this->Catalog->getCatalogDca($this->catalog), $GLOBALS['TL_DCA'][$objCatalog->tableName])
                            : 
    $this->Catalog->getCatalogDca($this->catalog);
                    
    $GLOBALS['TL_DCA'][$objCatalog->tableName]['Cataloggenerated'] = true;
                }
            }

            
    // Send file to the browser
            
    $blnDownload = ($this instanceof ModuleCatalogList || $this instanceof ModuleCatalogFeatured || $this instanceof ModuleCatalogRelated || $this instanceof ModuleCatalogReference || $this instanceof ModuleCatalogReader); 
            if (
    $blnDownload && strlen($this->Input->get('file')) && $this->catalog_visible)
            {
                foreach (
    $this->catalog_visible as $k)
                {
                    
    $fieldConf = &$GLOBALS['TL_DCA'][$this->strTable]['fields'][$k];
                    if (
    $fieldConf['eval']['catalog']['type'] == 'file' && !$fieldConf['eval']['catalog']['showImage'])
                    {
                        
    // check file in Catalog
                        
    $objDownload $this->Database->prepare('SELECT id FROM '.$this->strTable.' WHERE '.(!BE_USER_LOGGED_IN && $this->publishField $this->publishField.'=1 AND ' '').'(LOCATE(?,'.$k.')>0 OR LOCATE(?,'.$k.')>0)')
                                ->
    limit(1)
                                ->
    execute($this->Input->get('file'), dirname($this->Input->get('file')));
                        
                        if (
    $objDownload->numRows)
                        {
                            
    $this->sendFileToBrowser($this->Input->get('file'));
                        }
                    }
                }
            }

            return 
    parent::generate();
        }

        protected function 
    getModulesForThisPage()
        {
            if(
    $this->cachePageModules)
                return 
    $this->cachePageModules;
            global 
    $objPage;
            if(
    $objPage->layout)
                
    $objLayout $this->Database->prepare('SELECT id,modules FROM tl_layout WHERE id=?')
                                    ->
    limit(1)
                                    ->
    execute($objPage->layout);
            
    // Fallback layout
            
    if (!$objPage->layout || $objLayout->numRows == 0)
            {
                
    $objLayout $this->Database->prepare('SELECT id, modules FROM tl_layout WHERE fallback=?')
                                            ->
    limit(1)
                                            ->
    execute(1);
            }
            
    // check if there is a layout and fetch modules if so.
            
    if ($objLayout->numRows)
            {
                
    $arrModules deserialize($objLayout->modules);
            } else {
                
    $arrModules = array();
            }
            
    // fetch all content element modules from this page.
            
    $objContent $this->Database->prepare('SELECT module FROM tl_content WHERE pid IN (SELECT id FROM tl_article WHERE pid=?) AND type="module"')
                                        ->
    execute($objPage->id);
            while(
    $objContent->next())
            {
                
    $arrModules[] = array('mod' => $objContent->module);
            
            }
            
    $ids=array();
            foreach (
    $arrModules as $arrModule)
            {
                
    $ids[] = $arrModule['mod'];
            }
            
    $this->cachePageModules=$ids;
            return 
    $this->cachePageModules;
        }

        protected function 
    getCatalogFields($arrTypes=false)
        {
            if(!
    $arrTypes)
                
    $arrTypes=$GLOBALS['BE_MOD']['content']['catalog']['typesCatalogFields'];
            
    $fields = array();
            
    $objFields $this->Database->prepare("SELECT * FROM tl_catalog_fields WHERE pid=? ORDER BY sorting")
                                ->
    execute($this->catalog);

            while (
    $objFields->next())
            {
                if(!
    in_array($objFields->type$arrTypes))
                    continue;
                
    $fields[$objFields->colName] = array 
                (
                    
    'label' => $objFields->name,
                    
    'type' => $objFields->type,
                );

            }
            return 
    $fields;
        }

        protected function 
    getTree()
        {
            if (
    $this->type != 'catalogfilter' || !$this->catalog_filter_enable)
            {
                return array();
            }
            
    $tree = array();
            if(
    $this->catalog_filters) {
                
    $arrFilters deserialize($this->catalog_filterstrue);
                foreach (
    $arrFilters as $key=>$fieldconfig)
                {
                    list(
    $field$config) = each($fieldconfig);
                    if (
    $config['checkbox'] == 'tree')
                    {
                        
    $tree[] = $field;
                    }
                }
            }
            return 
    $tree;
        }


        protected function 
    parseFilterUrl($searchFields=NULL)
        {
            
    $arrTree $this->getTree();
            
    $blnTree = (count($arrTree)>0);

            
    $current $this->convertAliasInput();
            
    $searchFields deserialize($searchFields);

            
    // Setup Fields
            
    $fields $this->getCatalogFields();

            if (!
    strlen($this->catalog_tags_mode))
            {
                
    $this->catalog_tags_mode 'AND';
            }

            
    // Process POST redirect() settings
            
    $doPost false;
            if (
    $this->Input->post('FORM_SUBMIT') == $this->strTable)
            {
                
    // search string POST
                
    if (array_key_exists($this->strSearch$_POST))
                {
                    
    $doPost true;

                    if (
    $this->Input->post($this->strSearch))
                    {
                        
    $current[$this->strSearch] = $this->Input->post($this->strSearch);
                    } 
                    else
                    {
                        unset(
    $current[$this->strSearch]);
                    } 
                }

                
    // filters POST
                
    foreach ($fields as $field=>$data)
                {
                    
    // check if this is a filter
                    
    if (array_key_exists($field$_POST))
                    {
                        
    $doPost true;
                        
    $fieldConf = &$GLOBALS['TL_DCA'][$this->strTable]['fields'][$field];
                        
    // check if array posted (range and dates)
                        
    if (is_array($this->Input->post($field)))
                        {
                            
    $range $this->Input->post($field);
                            
    $min strlen($fieldConf['eval']['catalog']['minValue']) ? 
                                        
    max(min($range), $fieldConf['eval']['catalog']['minValue']) : min($range);
                            
    $max strlen($fieldConf['eval']['catalog']['maxValue']) ? 
                                        
    min(max($range), $fieldConf['eval']['catalog']['maxValue']) : max($range);
                            if (
    strlen($max) && strlen($min))
                            {
                                
    $current[$field] = $min.'__'.$max;
                            }
                            if (
    in_array($fieldConf['eval']['catalog']['type'],array('number''decimal''date')))
                            {
                                
    $min='';
                                
    $max='';
                                if(
    $fieldConf['eval']['catalog']['type'] == 'date')
                                {
                                    if(
    $range[0] && !is_numeric($range[0]))
                                        
    $range[0] = strtotime($range[0]);
                                    if(
    $range[1] && !is_numeric($range[1]))
                                        
    $range[1] = strtotime($range[1]);
                                }
                                if (
    strlen($range[0]))                            
                                    
    $min=$range[0];
                                if (
    strlen($range[1]))
                                    
    $max=$range[1];
                                if (
    strlen($max) || strlen($min))
                                {
                                    
    $current[$field] = $min.'__'.$max;
                                }
                            }
                        }
                        
    // regular filter value
                        
    else 
                        {
                            
    // use TL safe function
                            
    $v $this->Input->post($field);
                            
    $fieldConf = &$GLOBALS['TL_DCA'][$this->strTable]['fields'][$field];
                            if (
    strlen($v) && $this->getAliasFieldConf($fieldConf) != 'id')
                            {
                                
    $arrAlias array_flip($this->getAliasOptionList($fieldConf));
                                switch (
    $fieldConf['eval']['catalog']['type'])
                                {
                                    case 
    'tags':
                                        
    $tags explode(','$v);
                                        
    $newtags = array();
                                        foreach(
    $tags as $tag)
                                        {
                                            
    $newtags[] = $arrAlias[$tag];
                                        }
                                        
    $v implode(','$newtags);
                                        break;
                                        
                                    case 
    'select':
                                        
    $v $arrAlias[$v]; 
                                        break;
                                        
                                    default:;
                                }
                            }
                            
    $current[$field] = $v;
                        }            
                    }
                }
                
    // Redirect POST variables to GET, for [search] and [ranges]
                
    if ($doPost)
                {
                    
    $this->redirect($this->generateFilterUrl($currentfalsefalse));
                }
            }

            
    // return if no filter parameters in URL
            
    if (!is_array($current) && !count($current))
            {
                return array();
            }

            
    // Setup Variables
            
    $baseurl $this->generateFilterUrl();
            
    $procedure = array();
            
    $values = array();


            
    $procedure['search'] = null;
            
    $values['search'] = null;

            foreach (
    $fields as $field=>$data)
            {
                
    $fieldConf = &$GLOBALS['TL_DCA'][$this->strTable]['fields'][$field];

                
    // GET search value
                
    if ($this->Input->get($this->strSearch) && strlen($fieldConf['eval']['catalog']['type']))
                {
                    if (
    is_array($searchFields) && !in_array($field$searchFields))
                    {
                        continue;
                    }

                    switch (
    $fieldConf['eval']['catalog']['type'])
                    {
                        case 
    'text':
                        case 
    'longtext':
                                
    // explode the search by spaces and add the result to the query.
                                // this allows us to search for multiple words which do not have to be in the same order as searched by.
                                // Drawback is, we now can not search for exact phrases anymore (which is less required than searching for
                                // multiple words IMO).
                                // TODO: make this configable so users can decide which search algorithm to use.
                                
    $words=explode(' '$this->Input->get($this->strSearch));
                                
    $proc=array();
                                
    $vals=array();
                                if(
    count($words))
                                {
                                    
    $values['search'][$field]=array();
                                    foreach(
    $words as $word)
                                    {
                                        
    $proc[] = '('.$field.' LIKE ?)';
                                        
    $values['search'][$field][] =  '%'.$word.'%';
                                    }
                                    
    $procedure['search'][$field] = '('.implode(' AND '$proc).')';
                                }
                                break;
                        case 
    'number':
                        case 
    'decimal':
                                
    $procedure['search'][$field] = '('.$field.' LIKE ?)';
                                
    $values['search'][$field] = '%'.$this->Input->get($this->strSearch).'%';
                                break;

                        case 
    'file':
                        case 
    'url':
                                
    $procedure['search'][$field] = '('.$field.' LIKE ?)';
    //                            $values['search'][$field] = '%'.urldecode($this->Input->get($this->strSearch)).'%';
                                
    $values['search'][$field] = '%'.($this->Input->get($this->strSearch)).'%';
                                break;

                        case 
    'date':
                                
    // add month only search
                                
    if (!is_numeric($this->Input->get($this->strSearch)))
                                {
                                    
    $procedure['search'][$field] = "CAST(MONTHNAME(FROM_UNIXTIME(".$field.")) AS CHAR) LIKE ?";
                                    
    $values['search'][$field] = '%'.$this->Input->get($this->strSearch).'%';
                                }
                                
    // add numeric day, month, year search
                                
    else
                                {
                                    foreach (array(
    'YEAR','MONTH','DAY') as $function
                                    {
                                        
    $tmpDate[] = "CAST(".$function."(FROM_UNIXTIME(".$field.")) AS CHAR) LIKE ?";
                                        
    $values['search'][$field][] = '%'.$this->Input->get($this->strSearch).'%';
                                    }
                                    
    $procedure['search'][$field] = '('.implode(' OR ',$tmpDate).')';
                                }
                                
                                break;

                        case 
    'checkbox' :
                                
    // search only if true
                                
    if (substr_count(strtolower($fieldConf['label']['0']),strtolower($this->Input->get($this->strSearch))))
                                {
                                    
    $procedure['search'][$field] = '('.$field.'=?)';
                                    
    $values['search'][$field] = '1';
                                }
                                break;

                        case 
    'select' :
                                list(
    $itemTable$valueCol) = explode('.'$fieldConf['eval']['catalog']['foreignKey']);
                                
    $procedure['search'][$field] = '('.$field.' IN (SELECT id FROM '.$itemTable.' WHERE '.$valueCol.' LIKE ?'.($fieldConf['options']? ' AND id IN ('.implode(',',array_keys($fieldConf['options'])).')':'').'))';
                                
    $values['search'][$field] = '%'.$this->Input->get($this->strSearch).'%';
                                break;
                                    
                        case 
    'tags' :

                                list(
    $itemTable$valueCol) = explode('.'$fieldConf['eval']['catalog']['foreignKey']);
                                
    // perform search by using a subselect over the tables.
                                
    $tagQuery $this->Database->prepare(sprintf('SELECT DISTINCT(itemid) as id FROM tl_catalog_tag_rel WHERE fieldid=%s AND valueid IN (SELECT id FROM %s WHERE %s LIKE ? %s)',
                                                                        
    $fieldConf['eval']['catalog']['fieldId'],
                                                                        
    $itemTable,
                                                                        
    $valueCol,
                                                                        (
    $fieldConf['options']? ' AND id IN ('.implode(',',array_keys($fieldConf['options'])).')':'')
                                                                        ))
                                        ->
    execute('%'.$this->Input->get($this->strSearch).'%');
                                if (
    $tagQuery->numRows)
                                {
                                    
    $procedure['search'][$field] = 'id IN('.implode(','$tagQuery->fetchEach('id')).')';
                                }
                                break;

                        default:;
                            
    // HOOK: Might be a custom field type, check if that one has registered a hook.
                            
    $fieldType=$GLOBALS['BE_MOD']['content']['catalog']['fieldTypes'][$fieldConf['eval']['catalog']['type']];
                            if(
    array_key_exists('generateFilter'$fieldType) && is_array($fieldType['generateFilter']))
                            {
                                foreach (
    $fieldType['generateFilter'] as $callback)
                                {
                                    
    $this->import($callback[0]);
                                    
    $tmp=$this->$callback[0]->$callback[1]($field$fieldConf$this->Input->get($this->strSearch));
                                    
    $procedure['search'][$field] = $tmp['procedure'];
                                    if(
    is_array($tmp['search']))
                                    {
                                        if(isset(
    $values['search'][$field]))
                                            
    $values['search'][$field]=array_merge($values['search'][$field], $tmp['search']);
                                        else
                                            
    $values['search'][$field]=$tmp['search'];
                                    }
                                    else
                                        
    $values['search'][$field]=$tmp['search'];
                                }
                            }
                    }
                } 
    // of search

                // GET range values
                
    if (substr_count($this->Input->get($field),'__'))
                {
                    
    $rangeValues trimsplit('__'$this->Input->get($field), 2);
                    
    $rangeOptions[$field]['label'] = $fieldConf['label'][0];
                    
    $rangeOptions[$field]['min'] =     $rangeValues[0];
                    
    $rangeOptions[$field]['max'] = $rangeValues[1];
                    
    $minValue =    $rangeValues[0];
                    
    $maxValue $rangeValues[1];
                    
    //$procedure['where'][] = '('.$field.' BETWEEN ? AND ?)';
                    
    $strSqlWhereClause '('.$field.' BETWEEN ? AND ?)';
                    switch (
    $fieldConf['eval']['catalog']['type'])
                    {
                        case 
    'number':
                            
    $rangeValues[0] = intval($rangeValues[0]);
                            
    $rangeValues[1] = intval($rangeValues[1]);
                            break;
                        case 
    'decimal':
                            
    $rangeValues[0] = floatval($rangeValues[0]);
                            
    $rangeValues[1] = floatval($rangeValues[1]);
                            break;
                        case 
    'date':
                            
    $rangeValues[0] = strtotime($rangeValues[0]);
                            
    $rangeValues[1] = strtotime($rangeValues[1]);
                            break;
                        default:
                    }
                    if (
    $minValue!='')
                        
    $values['where'][] = $rangeValues[0];
                    else
                        
    $strSqlWhereClause '('.$field.' < ?)';
                    if (
    $maxValue!='')
                        
    $values['where'][] = $rangeValues[1];
                    else
                        
    $strSqlWhereClause '('.$field.' > ?)';
                    
    $procedure['where'][] = $strSqlWhereClause;
                    
    $current[$field] = $this->Input->get($field);
                }
                
    //GET filter values
                
    elseif (strlen($this->Input->get($field)))
                {
                    switch (
    $fieldConf['eval']['catalog']['type'])
                    {
                        case 
    'tags':
                            list(
    $itemTable$valueCol) = explode('.'$fieldConf['eval']['catalog']['foreignKey']);
                            
    // TODO: add support for string values here and get rid of the convertAliasInput call on the beginning.
                            
    foreach(explode(','$current[$field]) as $tag)
                                
    $tags[] = (int)$tag;
                            if(
    $this->catalog_tags_mode == 'AND')
                            {
                                
    $sql sprintf('SELECT itemid FROM tl_catalog_tag_rel WHERE fieldid=%s AND valueid=%s'
                                                 
    $fieldConf['eval']['catalog']['fieldId'], 
                                                 
    $tag);
                                foreach(
    $tags as $tag)
                                    
    $sql sprintf('SELECT itemid FROM tl_catalog_tag_rel WHERE fieldid=%s AND valueid=%s AND itemid IN(%s)'
                                                     
    $fieldConf['eval']['catalog']['fieldId'], 
                                                     
    $tag,
                                                     
    $sql);
                                
    $sql sprintf('id IN (SELECT DISTINCT(itemid) FROM tl_catalog_tag_rel WHERE fieldid=%s AND itemid IN (%s) AND valueid IN (%s))',
                                                
    $fieldConf['eval']['catalog']['fieldId'], 
                                                
    $sql,
                                                
    implode(','array_intersect($tags, ($fieldConf['options']?array_keys($fieldConf['options']):array())))
                                                );
                                
    $tagQuery $sql;
                            } else {
                                
    // perform search by using a subselect over the tables.
                                
    $tagQuery 'id IN(SELECT DISTINCT(itemid) as id FROM tl_catalog_tag_rel WHERE fieldid='.$fieldConf['eval']['catalog']['fieldId'].' AND valueid IN ('.implode(','array_intersect($tags, ($fieldConf['options']?array_keys($fieldConf['options']):array()))).'))';
                            }
                            
    $procedure['tags'][] = $tagQuery;
                            if (
    $blnTree && in_array($field$arrTree))
                            {
                                
    $procedure['tree'][] = $tagQuery;
                            }
                            break;
                        case 
    'checkbox':
                            
    $procedure['where'][] = $field."=?";
                            
    $values['where'][] = ($this->Input->get($field) == 'true' 0);
                            
    //$current[$field] = $this->Input->get($field);
                            
    if ($blnTree && in_array($field$arrTree)) 
                            {
                                
    $procedure['tree'][$field] = $field."=?";
                                
    $values['tree'][$field] = ($this->Input->get($field) == 'true' 0);
                            }
                            break;
                        case 
    'text':
                        case 
    'longtext':
                        case 
    'number':
                        case 
    'decimal':
                        case 
    'select':
                            
    $value $current[$field];
                            if(
    $value!==NULL)
                            {
                                
    $procedure['where'][] = $field."=?";
                                
    $values['where'][] = $value;
                                if (
    $blnTree && in_array($field$arrTree)) 
                                {
                                    
    $procedure['tree'][$field] = $field."=?";
                                    
    $values['tree'][$field] = $value;
                                }
                            }
                            break;
                        case 
    'date':
                            
    $procedure['where'][] = $field."=?";
                            
    $values['where'][] = strtotime($this->Input->get($field));
                            
    //$current[$field] = $this->Input->get($field);

                            
    if ($blnTree && in_array($field$arrTree)) 
                            {
                                
    $procedure['tree'][$field] = $field."=?";
                                
    $values['tree'][$field] = strtotime($this->Input->get($field));
                            }
                            break;
                        case 
    'file':
                        case 
    'url':
                            
    $procedure['where'][] = $field."=?";
                            
    $values['where'][] = urldecode($this->Input->get($field));
                            
    $current[$field] = $this->Input->get($field);

                            if (
    $blnTree && in_array($field$arrTree)) 
                            {
                                
    $procedure['tree'][$field] = $field."=?";
                                
    $values['tree'][$field] = urldecode($this->Input->get($field));
                            }
                            break;
                    }
                } 
    // filter

                // GET sort values
                
    if ($this->Input->get($this->strOrderBy) == $field && in_array($this->Input->get($this->strSort), array('asc','desc')))
                {
                    switch (
    $fieldConf['eval']['catalog']['type'])
                    {
                        case 
    'select':
                            list(
    $itemTable$valueCol) = explode('.'$fieldConf['eval']['catalog']['foreignKey']);
                            
    $procedure['orderby'] = '(SELECT '.$valueCol.' from '.$itemTable.' WHERE id='.$field.') '.$this->Input->get($this->strSort);
                            break;
                        default:
                            
    $procedure['orderby'] = $field.' '.$this->Input->get($this->strSort);
                    }
                    
    $current[$this->strOrderBy] = $this->Input->get($this->strOrderBy);
                    
    $current[$this->strSort] = $this->Input->get($this->strSort);
                } 
    //sort

            
    // foreach $filter
            

            
    $settings = array 
                (
                    
    'current'     => $current,
                    
    'procedure' => $procedure,
                    
    'values'         => $values,
                );
            
    // HOOK: allow other extensions to manipulate the filter settings before passing it to the template
            
    if(is_array($GLOBALS['TL_HOOKS']['filterCatalog']))
            {
                foreach (
    $GLOBALS['TL_HOOKS']['filterCatalog'] as $callback)
                {
                    
    $this->import($callback[0]);
                    
    $settings $this->$callback[0]->$callback[1]($settings);
                }
            }
            return 
    $settings;
        }

        
    /**
         * Retrieve Alias field from table, checks if catalog
         * @param string
         * @return string
         */

        
    public function getAliasField($sourceTable)
        {
            
    // check alias field
            
    $objAlias $this->Database->prepare("SELECT aliasField FROM tl_catalog_types WHERE tableName=?")
                                            ->
    execute($sourceTable);
            
    $aliasField = ($objAlias->numRows && strlen($objAlias->aliasField)) ? $objAlias->aliasField 'alias';

            return (
    $this->Database->fieldExists($aliasField$sourceTable) && !$GLOBALS['TL_CONFIG']['disableAlias']) ? $aliasField 'id';
        }

        
    /**
         * Retrieve alias field for current catalog field configuration
         * @param array
         * @return string
         */

        
    private function getAliasFieldConf($fieldConf)
        {
            if (!
    $fieldConf['eval']['catalog']['foreignKey'])
            {
                return 
    'id';
            }
            
            
    // get alias column
            
    list($itemTable$valueCol) = explode('.'$fieldConf['eval']['catalog']['foreignKey']);

            return 
    $this->getAliasField($itemTable);
        }


        
    /**
         * Retrieve alias values with id as index
         * @param array
         * @return array
         */

        
    private function getAliasOptionList(&$fieldConf)
        {
            if(
    $fieldConf['optionslist'])
                return 
    $fieldConf['optionslist'];

            
    // get alias column
            
    list($itemTable$valueCol) = explode('.'$fieldConf['eval']['catalog']['foreignKey']);
            
    $aliasField $this->getAliasField($itemTable);

            
    // determine item sorting.
            
    $strSorting=($fieldConf['eval']['catalog']['sortCol']
                        ?
    ' ORDER BY '.$fieldConf['eval']['catalog']['sortCol']
                        :(
    $this->Database->fieldExists('sorting'$itemTable)?' ORDER BY sorting':''));
            
    // get existing alias values of options in DB
            
    $objList $this->Database->prepare('SELECT id,'.$aliasField.' FROM '.$itemTable 
                            (
    $fieldConf['options'] ? ' WHERE id IN ('.implode(',',array_keys($fieldConf['options'])).')':'') . $strSorting)
                    ->
    execute();
            
            
    $return = array();
            while (
    $objList->next())
            {
                
    // check if this is still ok to use id if alias is empty
                
    $return[$objList->id] = strlen($objList->$aliasField) ? $objList->$aliasField $objList->id;
            }
            
    $fieldConf['optionslist'] = $return;
            return 
    $return;
        }

        
    /**
         * Detect input $_GET variables and convert alias values to id's, if table supports it
         * @return array
         */

        
    protected function convertAliasInput()
        {

            
    $return = array();

            
    // convert $_GET filter parameters in Url
            
    foreach ($_GET as $k=>$v)
            {
                
    // exclude page parameter
                
    if (!in_array($k, array('page')))
                {
                    
    $_GET[$k] = str_replace($GLOBALS['TL_CONFIG']['catalog']['safeReplace'], $GLOBALS['TL_CONFIG']['catalog']['safeCheck'], $v);
                    
                    
    // use TL safe function
                    
    $v $this->Input->get($k);

                    
    $fieldConf = &$GLOBALS['TL_DCA'][$this->strTable]['fields'][$k];
                    if (
    strlen($v) && $this->getAliasFieldConf($fieldConf) != 'id')
                    {
                        
    $arrAlias array_flip($this->getAliasOptionList($fieldConf));
                        switch (
    $fieldConf['eval']['catalog']['type'])
                        {
                            case 
    'tags':
                                
    $tags explode(','$v);
                                
    $newtags = array();
                                foreach(
    $tags as $tag)
                                {
                                    
    $newtags[] = $arrAlias[$tag];
                                }
                                
    $v implode(','$newtags);
                                break;
                                
                            case 
    'select':
                                
    $v $arrAlias[$v]; 
                                break;
                                
                            default:;
                        }
                    }
                    
                    
    $return[$k] = $v
                }
            }
            
            return 
    $return;
        }


        protected function 
    lastInTree($field$current$tree)
        {
            return (!
    count($tree) || in_array($field$tree) && array_search($field$tree)==(count($tree)-1));
        }


        protected function 
    hideTree($field$current$tree)
        {
            if (
    $this->catalog_filter_hide && in_array($field$tree))
            {
                
    $pos array_search($field$tree);
                for (
    $i=0,$total=0;$i<=$pos;$i++)
                {
                    
    $total += array_key_exists($tree[$i], $current);
                }
                return (
    $total<$pos);
            }
            return 
    false;
        }

        protected function 
    buildTreeQuery($field$filterurl$tree)
        {
            if (
    count($tree) && is_array($filterurl['procedure']['tree']))
            {
                
    $pos array_search($field$tree);
                for (
    $i=0;$i<$pos;$i++)
                {
                    if (
    strlen($filterurl['procedure']['tree'][$tree[$i]]))
                        
    $query[] = $filterurl['procedure']['tree'][$tree[$i]];
                    if (
    strlen($filterurl['values']['tree'][$tree[$i]]))
                        
    $params[] = $filterurl['values']['tree'][$tree[$i]];
                }
            }
            return array (
                
    'query' => (is_array($query) ? implode(' AND '$query) : ''),
                
    'params' => (is_array($params) ? $params : array()),
            );
        }


        protected function 
    clearTree($field, &$newcurrent$tree)
        {
            if (
    in_array($field$tree))
            {
                
    $pos = (array_search($field$tree)+1);
                for (
    $i=$pos;$i<=count($tree);$i++)
                {
                    unset(
    $newcurrent[$tree[$i]]);
                }
            }
        }

        protected function 
    makeAllLabel($input$label$multi=false)
        {
            if (
    $input=='select' && !$multi)
            {
                return 
    sprintf($GLOBALS['TL_LANG']['MSC']['selectNone'], $label);
            }
            return 
    sprintf($GLOBALS['TL_LANG']['MSC']['clearAll'], $label);
        }


        protected function 
    generateFilter()
        {
            
    $filterurl $this->parseFilterUrl();        
            
    $current     $filterurl['current'];

            
    $arrFilters deserialize($this->catalog_filterstrue);
            if (
    $this->catalog_filter_enable && count($arrFilters))
            {
                
    // Get Tree View
                
    $tree $this->getTree();

                
    // Setup filters and option values
                
    $filterOptions = array();
                foreach (
    $arrFilters as $fieldconfig)
                {
                    list(
    $field$config) = each($fieldconfig);
                    
    $input $config['radio'];
                    
    $blnTree = ($config['checkbox'] == 'tree');
                    
                    if (
    $input == 'none' || $this->hideTree($field$current$tree))
                    {
                        continue;
                    }
                    
    $blnLast $this->lastInTree($field$current$tree);

                    
    $query $this->buildTreeQuery($field$filterurl$tree);
                    if(!
    BE_USER_LOGGED_IN && $this->publishField)
                    {
                        if(
    strlen($query['query']))
                        {
                            
    $query['query'].=' AND '.$this->publishField.'=1 ';
                        } else {
                            
    $query['query']=$this->publishField.'=1 ';
                        }
                    }

                    
    $fieldConf = &$GLOBALS['TL_DCA'][$this->strTable]['fields'][$field];

                    
    $fieldType $fieldConf['eval']['catalog']['type'];
                    
    // HOOK: let custom fields mimic another fieldtype to generate a filter
                    
    if(array_key_exists($fieldType$GLOBALS['BE_MOD']['content']['catalog']['fieldTypes']))
                    {
                        
    $fieldTypeArr=$GLOBALS['BE_MOD']['content']['catalog']['fieldTypes'][$fieldType];
                        if(
    array_key_exists('generateFilterWidget'$fieldTypeArr) && is_array($fieldTypeArr['generateFilterWidget']))
                        {
                            foreach (
    $fieldTypeArr['generateFilterWidget'] as $callback)
                            {
                                
    $this->import($callback[0]);
                                
    $tmp=$this->$callback[0]->$callback[1]($fieldType$field$config$fieldConf$filterurl$query$tree);
                                if(
    $tmp)
                                {
                                    
    $fieldType $tmp;
                                }
                            }
                        }
                    }

                    
    $options = array();
                    switch (
    $fieldType)
                    {
                        case 
    'checkbox':
                            
    // Build Widget Options
                            
    $labels = array
                            (
                                
    'none'     => $this->makeAllLabel($input$fieldConf['label'][0]),
                                
    'true'     => $GLOBALS['TL_LANG']['MSC']['true'],
                                
    'false'    => $GLOBALS['TL_LANG']['MSC']['false'],
                            );
                            foreach (
    $labels as $key=>$label)
                            {
                                
    $newcurrent $current;
                                
    $newcurrent[$field] = ($key == 'none' '' $key);
                                
    $selected $current[$field] == $newcurrent[$field];
                                
    $this->clearTree($field$newcurrent$tree);
                                
    $url $this->generateFilterUrl($newcurrenttrue$blnLast);
                                
                                
    $addOption = array();
                                
    $addOption['value'] = $url;
                                
    $addOption['label'] = $label;
                                
    $addOption['id'] = ($key == 'none' '' $key);
                                if (
    $selected)
                                {
                                    
    $addOption['selected'] = true;
                                }
                                
    array_push($options$addOption);

                            }
                            
    $widget = array
                            (
                                
    'name'            => $field,
                                
    'id'                => 'filter_field_'.$field,
                                
    'label'            => $fieldConf['label'][0],
                                
    'options'        => serialize($options),
                                
    'value'         => htmlentities($this->generateFilterUrl($currenttrue$blnLast)),
                                
    'tableless'    => true,
                                
    'inputType' => $input,
                            );

                            
    // parse Widget
                            
    $settings['filter'][] =  $this->parseWidget($widgetfalse);
                            
    $widgets['filter'][] = $widget;

                            break;


                        case 
    'select':
                            if((
    $this instanceof ModuleCatalogFilter) && $this->catalog_filter_cond_from_lister)
                            {
                                
    $ids=$this->getModulesForThisPage();
                                
    $objModules $this->Database->prepare('SELECT * FROM tl_module WHERE id IN (' implode(', '$ids) . ') AND deny_catalog_filter_cond_from_lister=0 AND type=\'cataloglist\' AND catalog='.$this->catalog)
                                        ->
    execute();
                                while(
    $objModules->next())
                                {
                                    
    $objModules->catalog_search=deserialize($objModules->catalog_search);
                                    
    $moduleFilterUrl $this->parseFilterUrl($objModules->catalog_search);
                                    if (
    is_array($objModules->catalog_search) && strlen($objModules->catalog_search[0]) && is_array($moduleFilterUrl['procedure']['search']))
                                    {
                                        
    // reset arrays
                                        
    $searchProcedure = array();
                                        
    $searchValues = array();
                                        foreach(
    $objModules->catalog_search as $searchfield)
                                        {
                                            if ((
    $searchfield != $field)
                                                && 
    array_key_exists($searchfield$moduleFilterUrl['current'])
                                                && 
    array_key_exists($searchfield$moduleFilterUrl['procedure']['search']))
                                            {
                                                
    $searchProcedure[] = $moduleFilterUrl['procedure']['search'][$searchfield];
                                                if (
    is_array($moduleFilterUrl['values']['search'][$searchfield]))
                                                {
                                                    foreach(
    $moduleFilterUrl['values']['search'][$searchfield] as $item)
                                                    {
                                                        
    $searchValues[] = $item;
                                                    }
                                                }
                                                else
                                                {
                                                    
    $searchValues[] = $moduleFilterUrl['values']['search'][$searchfield];
                                                }
                                            }
                                        }
                                        if(
    count($searchProcedure))
                                        {
                                            
    $moduleFilterUrl['procedure']['where'][] = ' ('.implode(' OR '$searchProcedure).')';
                                            
    $moduleFilterUrl['values']['where'] = is_array($moduleFilterUrl['values']['where']) ? (array_merge($moduleFilterUrl['values']['where'],$searchValues)) : $searchValues;
                                        }
                                    }
                                    if(
    is_array($moduleFilterUrl['procedure']['where']))
                                    {
                                        foreach(
    $moduleFilterUrl['procedure']['where'] as $key=>$value)
                                        {
                                            if(
    strpos($value$field) !== false)
                                            {
                                                unset(
    $moduleFilterUrl['procedure']['where'][$key]);
                                                unset(
    $moduleFilterUrl['values']['where'][$key]);
                                            }
                                        }
                                    }
                                    if(
    is_array($moduleFilterUrl['procedure']['tags']))
                                    {
                                        foreach(
    $moduleFilterUrl['procedure']['tags'] as $key=>$value)
                                        {
                                            if(
    strpos($value$field) !== false)
                                            {
                                                unset(
    $moduleFilterUrl['procedure']['tags'][$key]);
                                                unset(
    $moduleFilterUrl['values']['tags'][$key]);
                                            }
                                        }
                                    }
                                    if (
    is_array($moduleFilterUrl['values']['where'])) {
                                        
    $query['params'] = array_merge($query['params'], $moduleFilterUrl['values']['where']);
                                    }
                            
                                    if (
    is_array($moduleFilterUrl['values']['tags'])) {
                                        
    $query['params'] = array_merge($query['params'], $moduleFilterUrl['values']['tags']);
                                    }

                                    if(
    $objModules->catalog_where)
                                    {
                                        
    $strCondition $this->replaceInsertTags($objModules->catalog_where);
                                        if(
    strlen($strCondition))
                                            
    $query['query'] .= (strlen($query['query'])?' AND ':'').$strCondition;
                                    }
                                    if(
    count($moduleFilterUrl['procedure']['where']))
                                        
    $query['query'] .=(strlen($query['query'])?' AND ':'').implode(' '.$objModules->catalog_query_mode.' '$moduleFilterUrl['procedure']['where']);
                                    if(
    count($moduleFilterUrl['procedure']['tags']))
                                        
    $query['query'] .=(strlen($query['query'])?' AND ':'').implode(' '.$objModules->catalog_tags_mode.' '$moduleFilterUrl['procedure']['tags']);
                                }
                            }
                            
    // get existing options in DB
                            
    $objFilter $this->Database->prepare('SELECT DISTINCT('.$field.') FROM '.$this->strTable . ($query['query'] ? ' WHERE '.$query['query'] : '') )
                                    ->
    execute($query['params']);

                            if (
    $objFilter->numRows
                            {
                                
    $selected = !strlen($current[$field]);
                                
    $newcurrent $current;
                                unset(
    $newcurrent[$field]);
                                
    $this->clearTree($field$newcurrent$tree);
                                
    $url $this->generateFilterUrl($newcurrenttrue$blnLast);
                                
                                
    $addOption = array();
                                
    $addOption['value'] = $url;
                                
    $addOption['label'] = $this->makeAllLabel($input$fieldConf['label'][0]);
                                
    $addOption['id'] = '';
                                if (
    $selected)
                                {
                                    
    $addOption['selected'] = true;
                                }
                                
    array_push($options$addOption);
                                
                                
    // get all rows
                                
    $rows $objFilter->fetchEach($field);

                                if(
    $fieldConf['options'])
                                {
                                    
    $tmpTags = array();
                                    foreach (
    $fieldConf['options'] as $id=>$option)
                                    {
                                        
    $tmpTags[] = 'SUM(FIND_IN_SET('.$id.','.$field.')) AS '.$field.$id;
                                    }
                                    
    $objResultCount $this->Database->prepare('SELECT '.implode(', ',$tmpTags).' FROM '.$this->strTable. ($query['query'] ? ' WHERE '$query['query'] : ''))
                                                                    ->
    execute($query['params']);
                                    
    $arrResultCount $objResultCount->row();

                                    foreach (
    $fieldConf['options'] as $id=>$option)
                                    {
                                        if (
    in_array($id$rows))
                                        {
                                            
    $selected = ($current[$field] == $id);
                                            
    $newcurrent $current;
                                            
    $newcurrent[$field] = $id;
                                            
    $this->clearTree($field$newcurrent$tree);
                                            
    $url $this->generateFilterUrl($newcurrenttrue$blnLast);
                                            
    $addOption = array();
                                            
    $addOption['value'] = $url;
                                            
    $addOption['label'] = $option;
                                            
    $addOption['id'] = $id;
                                            
    $addOption['alias'] = $id;
                                            
    $addOption['resultcount'] = $arrResultCount[$field.$id];
                                            if (
    $selected)
                                            {
                                                
    $addOption['selected'] = true;
                                            }
                                            
    array_push($options$addOption);
                                        }
                                    }
                                }

                                
    $widget = array
                                (
                                    
    'name'            => $field,
                                    
    'id'                => 'filter_field_'.$field,
                                    
    'label'            => $fieldConf['label'][0],
                                    
    'value'         => $this->generateFilterUrl($currenttrue$blnLast),
                                    
    'options'        => serialize($options),
                                    
    'tableless'    => true,
                                    
    'inputType' => $input,
                                );
        
                                
    // parse Widget
                                
    $settings['filter'][] =  $this->parseWidget($widgetfalse);
                                
    $widgets['filter'][] = $widget;

                            }
                            break;
        
                        case 
    'tags' :
                            
    $query['query'] = '';
                            
    $query['params'] = is_array($filterurl['values']['where'])? $filterurl['values']['where'] : array();
                            if (
    is_array($filterurl['values']['tags']))
                                
    $query['params'] = array_merge($query['params'], $filterurl['values']['tags']);
                            if(
    count($filterurl['procedure']['where']))
                                
    $query['query'] .=(strlen($query['query'])?' AND ':'').implode(' AND '$filterurl['procedure']['where']);
                            
    // TODO: we have a problem here if more than one tag field exists - we simply ignore the other one in here.
    //                        if(count($filterurl['procedure']['tags']))
    //                            $query['query'] .=(strlen($query['query'])?' AND ':'').implode(' AND ', $filterurl['procedure']['tags']);

                            // clear option
                            
    $selected = !strlen($current[$field]);
                            
    $newcurrent $current;
                            unset(
    $newcurrent[$field]);
                            
    $this->clearTree($field$newcurrent$tree);
                            
    $url $this->generateFilterUrl($newcurrenttrue$blnLast);

                            
    $addOption = array();
                            
    $addOption['value'] = $url;
                            
    $addOption['label'] = $this->makeAllLabel($input$fieldConf['label'][0], $this->catalog_tags_multi);
                            
    $addOption['id'] = $id;
                            if (
    $selected)
                            {
                                
    $addOption['selected'] = true;
                            }
                            
    array_push($options$addOption);

                            
    $tmpTags = array();
                            
    // get ids of matches according to all other filters.
                            
    if($query['query'])
                            {
                                
    $objFilter $this->Database->prepare('SELECT id FROM '.$this->strTable.' WHERE '.$query['query'])
                                                            ->
    execute($query['params']);
                                
    $itemIds implode(',',$objFilter->fetchEach('id'));
                            }
                            foreach (
    $fieldConf['options'] as $id=>$option)
                            {
                                
    $tmpTags[] = '(SELECT COUNT(itemid) FROM tl_catalog_tag_rel WHERE valueid='.$id.' AND fieldid='.$fieldConf['eval']['catalog']['fieldId'].($query['query'] && $itemIds?' AND itemid IN('.$itemIds.')':'').') AS '.$field.$id;
                            }
                            if(
    count($tmpTags)==0)
                                
    $tmpTags = array($field);
                            
    $objFilter $this->Database->prepare('SELECT '.implode(', ',$tmpTags))
                                                        ->
    execute($query['params']);
                            if (
    $objFilter->numRows)
                            {
                                
    $row $objFilter->row();

                                foreach (
    $fieldConf['options'] as $id=>$option)
                                {
                                    if (
    $row[$field.$id])
                                    {
                                        
    $selected in_array($idexplode(',',$current[$field]));
                                        
    $newcurrent $current;
                                        
    $newids strlen($current[$field]) ? explode(','$current[$field]) : array();
                                        
    $newids array_unique(!$selected array_merge($newids, array($id)) : array_diff($newids, array($id)));
                                        
    $newcurrent[$field] = ($this->catalog_tags_multi implode(',',$newids) : $id);
                                        
    $this->clearTree($field$newcurrent$tree);
                                        
    $url $this->generateFilterUrl($newcurrenttrue$blnLast);

                                        
    $blnList = ($selected && $input=='list');

                                        
    $addOption = array();
                                        
    $addOption['value'] = $url;
                                        
    $addOption['label'] = $blnList sprintf($GLOBALS['TL_LANG']['MSC']['optionselected'], $option) : $option;
                                        
    $addOption['id'] = $id;
                                        
    $addOption['resultcount'] = $row[$field.$id];
                                        
    $addOption['selected'] = $selected;
                                        
    array_push($options$addOption);
                                    }
                                }
                            }

                            
    $widget = array
                            (
                                
    'name'            => $field,
                                
    'id'                => 'filter_field_'.$field,
                                
    'label'            => $fieldConf['label'][0],
                                
    'value'         => $this->generateFilterUrl($currenttrue$blnLast),
                                
    'options'        => serialize($options),
                                
    'tableless'    => true,
                                
    'inputType' => ($this->catalog_tags_multi && $input=='radio' 'checkbox' $input),
                            );


                            if (
    $this->catalog_tags_multi && $input=='select'
                            {
                                
    $widget array_merge($widget, array('multiple'=>true));
                            }
                            
                            
    $settings['filter'][] = $this->parseWidget($widgetfalse);
                            
    $widgets['filter'][] = $widget;

                            break;
        
                        case 
    'text':
                        case 
    'file':
                        case 
    'url':
                        case 
    'number':
                        case 
    'decimal':
                        case 
    'date':
                            
    $query['query'] = '';
                            
    // TODO: this is an evil hack - we DEFINATELY have to rewrite this lookup mechanism.
                            
    if(count($filterurl['procedure']['where']))
                            foreach(
    $filterurl['procedure']['where'] as $k=>$v)
                            {
                                if(
    strpos($v$field) !== false)
                                {
                                    unset(
    $filterurl['procedure']['where'][$k]);
                                    unset(
    $filterurl['values']['where'][$k]);
                                }
                            }
                            
                            
    $query['params'] = is_array($filterurl['values']['where'])? $filterurl['values']['where'] : array();
                            if (
    is_array($filterurl['values']['tags']))
                                
    $query['params'] = array_merge($query['params'], $filterurl['values']['tags']);
                            if(
    count($filterurl['procedure']['where']))
                                
    $query['query'] .=(strlen($query['query'])?' AND ':'').implode(' AND '$filterurl['procedure']['where']);
                            if(
    count($filterurl['procedure']['tags']))
                                
    $query['query'] .=(strlen($query['query'])?' AND ':'').implode(' AND '$filterurl['procedure']['tags']);
                            
    // get existing options in DB
                            
    $options = array();
                            
    $objFilter $this->Database->prepare("SELECT DISTINCT ".$field." FROM ".$this->strTable . ($query['query'] ? " WHERE ".$query['query'] : '') . " ORDER BY ".$field)
                                    ->
    execute($query['params']);

                            if (
    $objFilter->numRows)
                            {
                                
    // setup ALL option
                                
    $selected = !strlen($current[$field]);
                                
    $newcurrent $current;
                                unset(
    $newcurrent[$field]);    
                                
    $this->clearTree($field$newcurrent$tree);
                                
    $url $this->generateFilterUrl($newcurrenttrue$blnLast);

                                
    $addOption = array();
                                
    $addOption['value'] = $url;
                                
    $addOption['label'] = $this->makeAllLabel($input$fieldConf['label'][0]);
                                
    $addOption['id'] = '';
                                if (
    $selected)
                                {
                                    
    $addOption['selected'] = true;
                                }
                                
    array_push($options$addOption);

                                while (
    $objFilter->next())
                                {
                                    
    $row $objFilter->row();
                                    if (!
    strlen(trim($row[$field])))
                                    {
                                        continue;
                                    }
                                    
    $label $this->formatValue(0$field$row[$field], false);
                                    switch (
    $fieldConf['eval']['catalog']['type'])
                                    {
                                        case 
    'url':
                                            
    $label $row[$field];
                                            
    $row[$field] = urlencode(urlencode($row[$field]));
                                            break;

                                        case 
    'file':
                                            
    $label implode(',',deserialize($row[$field],true));
                                            
    $row[$field] = urlencode(urlencode($row[$field]));
                                            break;

                                        case 
    'date':
                                            
    $row[$field] = $label;
                                            break;

                                        default:;

                                    }

                                    
    $newcurrent $current;
                                    
    $newcurrent[$field] = htmlspecialchars($row[$field]);
                                    
    $selected $current[$field] == $newcurrent[$field];
                                    
    $this->clearTree($field$newcurrent$tree);
                                    
    $url $this->generateFilterUrl($newcurrenttrue$blnLast);

                                    
    $addOption = array();
                                    
    $addOption['value'] = $url;
                                    
    $addOption['label'] = $label;
                                    
    $addOption['id'] = $row[$field];
                                    if (
    $selected)
                                    {
                                        
    $addOption['selected'] = true;
                                    }
                                    
    array_push($options$addOption);

                                }
                                
                                
    $widget = array
                                (
                                    
    'name'            => $field,
                                    
    'id'                => 'filter_field_'.$field,
                                    
    'label'            => $fieldConf['label'][0],
                                    
    'options'        => serialize($options),
                                    
    'value'         => htmlentities($this->generateFilterUrl($currenttrue$blnLast)),
                                    
    'tableless'    => true,
                                    
    'inputType'    => $input,
                                );

                                
    // parse Widget
                                
    $settings['filter'][] =  $this->parseWidget($widgetfalse);
                                
    $widgets['filter'][] = $widget;
                                
                            }
                            
                            break;

                        case 
    'longtext':
                            
    $options[] = array 
                            (
                                
    'label' => &$GLOBALS['TL_LANG']['MSC']['invalidFilter'],
                                
    'value' => '',
                            );
                            
    $widget = array
                            (
                                
    'name'            => $field,
                                
    'id'                => 'filter_field_'.$field,
                                
    'label'            => $fieldConf['label'][0],
                                
    'options'        => serialize($options),
                                
    'value'         => '',
                                
    'tableless'    => true,
                                
    'inputType'    => 'list',
                            );
                            
    // parse Widget
                            
    $settings['filter'][] =  $this->parseWidget($widgettrue);
                            
    $widgets['filter'][] = $widget;

                            break;
                        
                        default:
                            
    // HOOK: let custom fields generate a filter widget
                            
    if($fieldType && array_key_exists($fieldType$GLOBALS['BE_MOD']['content']['catalog']['fieldTypes']))
                            {
                                
    $fieldType=$GLOBALS['BE_MOD']['content']['catalog']['fieldTypes'][$fieldType];
                                if(
    array_key_exists('generateFilterForField'$fieldType) && is_array($fieldType['generateFilterForField']))
                                {
                                    
    $callback $fieldType['generateFilterForField'];
                                    
    $tmp=$this->$callback[0]->$callback[1]($fieldType$field$config$fieldConf$filterurl$query$tree);
                                    if(
    $tmp)
                                    {
                                        
    $settings['filter'][] = $tmp['settings'];
                                        
    $widgets['filter'][] = $tmp['widget'];
                                    }
                                }
                            }
                    }
                }
            }
            
    $arrRange deserialize($this->catalog_range,true);
            if (
    $this->catalog_range_enable && count($arrRange) && strlen($arrRange[0]))
            {
                
    // GET range values
                
    $rangeOptions = array();
                foreach (
    $arrRange as $field
                {
                    
    $fieldConf = &$GLOBALS['TL_DCA'][$this->strTable]['fields'][$field];
                    switch (
    $fieldConf['eval']['catalog']['type'])
                    {
                        case 
    'text':
                        case 
    'longtext':
                        case 
    'number':
                        case 
    'decimal':
                        case 
    'date':
                        
                            
    $rangeValues substr_count($this->Input->get($field),'__') ? trimsplit('__'$this->Input->get($field)) : array('','');
                            
    $current[$field] = $this->Input->get($field);

                            
    $widget = array
                            (
                                
    'name'            => $field,
                                
    'id'                => 'filter_range_'.$field,
                                
    'label'            => ($i==$fieldConf['label'][0]:''),
                                
    'inputType' => 'range',
                                
    'value'         => serialize($rangeValues),
                                
    'multiple'    => true,
                                
    'size'            => 2,
                                
    'tableless' => true,
                                
    'addSubmit' => true,
                                
    'slabel'         => $GLOBALS['TL_LANG']['MSC']['catalogSearch'],
                            );


                            if (
    $fieldConf['eval']['catalog']['type'] == 'date')
                            {
                                
    $date = array
                                (
                                    
    'maxlength' => 10,
                                    
    'rgxp'             => 'date'
                                
    );
                                
    // date picker was changed in 2.10
                                
    if (version_compare(VERSION'2.10''>='))
                                    
    $date['datepicker'] = true;
                                else
                                    
    $date['datepicker'] = $this->getDatePickerString();
                                
    $widget array_merge($widget$date);
                            }

                            
    $settings['range'][] = $this->parseWidget($widgettrue);
                            
    $widgets['range'][] = $widget;

                            break;
        
                        default :;
                    }
                }
            }
            

            
    // Setup date values
            
    $arrDates deserialize($this->catalog_dates,true);

            
    $arrRanges deserialize($this->catalog_date_ranges,true);
            if (
    $this->catalog_date_enable && count($arrDates))
            {
                foreach (
    $arrDates as $fieldconfig)
                {
                    list(
    $field$config) = each($fieldconfig);
                    
    $input $config['radio'];

                    
    $fieldConf = &$GLOBALS['TL_DCA'][$this->strTable]['fields'][$field];
                    
    $options = array();

                    
    $selected = !strlen($current[$field]);
                    
    $newcurrent $current;
                    unset(
    $newcurrent[$field]);
                    
    $url $this->generateFilterUrl($newcurrenttrue);

                    
    $addOption = array();
                    
    $addOption['value'] = $url;
                    
    $addOption['label'] = $this->makeAllLabel($input$fieldConf['label'][0]);
                    
    $addOption['id'] = '';
                    if (
    $selected)
                    {
                        
    $addOption['selected'] = true;
                    }
                    
    array_push($options$addOption);

                    foreach (
    $arrRanges as $id=>$range
                    {
                        
    $now = new Date();
                        
    $strToday '';
                        
    $strYesterday date($now->format, (strtotime('-1 days'$now->dayBegin) + 1));
                        
    $strTomorrow date($now->format, (strtotime('+1 days'$now->dayBegin) + 1));
                        
    $strPast '';
                        
    $strFuture '';
                        switch (
    $range)
                        {
                            case 
    'd':
                                
    //$strPast = date($now->format, $now->dayEnd);
                                
    $strPast date($now->format, (strtotime('-1 days'$now->dayBegin) + 1));
                                break;

                            case 
    'w':
                                
    $strPast date($now->format, (strtotime('-7 days'$now->dayBegin) + 1));
                                break;

                            case 
    'm':
                                
    $strPast date($now->format, (strtotime('-1 month'$now->dayBegin) + 1));
                                break;

                            case 
    'h':
                                
    $strPast date($now->format, (strtotime('-6 month'$now->dayBegin) + 1));
                                break;

                            case 
    'y':
                                
    $strPast date($now->format, (strtotime('-1 year'$now->dayBegin) + 1));
                                break;

                            case 
    't':
                                
    $strToday date($now->format$now->dayBegin);
                                break;

                            case 
    'df':
                                
    $strFuture date($now->format, (strtotime('+1 days'$now->dayBegin) + 1));
                                break;

                            case 
    'wf':
                                
    $strFuture date($now->format, (strtotime('+7 days'$now->dayBegin) + 1));
                                break;

                            case 
    'mf':
                                
    $strFuture date($now->format, (strtotime('+1 month'$now->dayBegin) + 1));
                                break;

                            case 
    'hf':
                                
    $strFuture date($now->format, (strtotime('+6 month'$now->dayBegin) + 1));
                                break;

                            case 
    'yf':
                                
    $strFuture date($now->format, (strtotime('+1 year'$now->dayBegin) + 1));
                                break;

                        }
                        
    $newcurrent $current;
                        
    $newcurrent[$field] = ($strPast $strPast '__' .$strYesterday '') . $strToday . ($strFuture $strTomorrow '__' $strFuture '');
                        
    $selected = ($current[$field] == $newcurrent[$field]);
                        
    $url $this->generateFilterUrl($newcurrenttrue);

                        
    $addOption = array();
                        
    $addOption['value'] = $url;
                        
    $addOption['label'] = &$GLOBALS['TL_LANG']['MSC']['daterange'][$range];
                        
    $addOption['id'] = $range;
                        if (
    $selected)
                        {
                            
    $addOption['selected'] = true;
                        }
                        
    array_push($options$addOption);

                    }
                    
    $widget = array
                    (
                        
    'name' => $field,
                        
    'id' => 'filter_date_'.$field,
                        
    'label' => $fieldConf['label'][0],
                        
    'value' =>  $this->generateFilterUrl($currenttrue),
                        
    'tableless' => true,
                        
    'options' => serialize($options),
                        
    'inputType' => $input,
                    );
                    
                    
    $settings['date'][] = $this->parseWidget($widgetfalse);            
                    
    $widgets['date'][] = $widget;
                }
            }



            
    $arrSort deserialize($this->catalog_sort,true);
            if (
    $this->catalog_sort_enable && count($arrSort))
            {
                
    // Setup sort values
                
    $options = array();
                if (
    count($arrSort) && $this->catalog_sort_type!='list')
                {
                    
    $selected = !strlen($current[$field]);
                    
    $newcurrent $current;
                    unset(
    $newcurrent[$this->strOrderBy]);
                    unset(
    $newcurrent[$this->strSort]);
                    
    $url $this->generateFilterUrl($newcurrenttrue);

                    
    $addOption = array();
                    
    $addOption['value'] = $url;
                    
    $addOption['label'] = $GLOBALS['TL_LANG']['MSC']['unsorted'];
                    
    $addOption['id'] = '';
                    if (
    $selected)
                    {
                        
    $addOption['selected'] = true;
                    }
                    
    array_push($options$addOption);

                }
                foreach (
    $arrSort as $id=>$field
                {
                    
    $fieldConf = &$GLOBALS['TL_DCA'][$this->strTable]['fields'][$field];
                    
    $newcurrent $current;
                    
    $newcurrent[$this->strOrderBy] = $field;
                    foreach (array(
    'asc','desc') as $order)
                    {
                        
    $newcurrent[$this->strSort] = $order;
                        
    $selected = ($current[$this->strSort] == $newcurrent[$this->strSort] && $current[$this->strOrderBy] == $newcurrent[$this->strOrderBy]);
                        
    $url $this->generateFilterUrl($newcurrenttrue);

                        
    $addOption = array();
                        
    $addOption['value'] = $url;
                        
    $addOption['label'] = $fieldConf['label'][0] . ' ' $this->selectSortLabel($fieldConf['eval']['catalog']['type'], ($order=='asc'));
                        
    $addOption['id'] = $field.'__'.$order;
                        if (
    $selected)
                        {
                            
    $addOption['selected'] = true;
                        }
                        
    array_push($options$addOption);

                    }
                }
                
    $widget = array
                (
                    
    'name'             => $this->strSort,
                    
    'id'                 => 'filter_'.$this->strSort,
                    
    'value'         =>  $this->generateFilterUrl($currenttrue),
                    
    'tableless'    => true,
                    
    'options'     => serialize($options),
                    
    'inputType' => $this->catalog_sort_type,
                );
                
                
    $settings['sort'] = $this->parseWidget($widgetfalse);            
                
    $widgets['sort'] = $widget;
            }


            if (
    $this->catalog_search_enable)
            {

                
    $widget = array
                (
                    
    'name' => $this->strSearch,
                    
    'id' => 'filter_'.$this->strSearch,
                    
    'inputType' => 'text',
                    
    'value' =>  $this->Input->get($this->strSearch),
                    
    'tableless' => true,
                    
    'addSubmit' => true,
                    
    'slabel' => $GLOBALS['TL_LANG']['MSC']['catalogSearch'],
                );
                
    $settings['search'] =  $this->parseWidget($widget);
                
    $widgets['search'] = $widget;
            }


            
    $settings['url']         =    $this->generateFilterUrl();
            
    $settings['action'] =    $this->generateFilterUrl($current);
            
    $settings['widgets'] = $widgets;

            if(
    is_array($GLOBALS['TL_HOOKS']['generateFilterCatalog']))
            {
                foreach (
    $GLOBALS['TL_HOOKS']['generateFilterCatalog'] as $callback)
                {
                    
    $this->import($callback[0]);
                    
    $settings $this->$callback[0]->$callback[1]($this,$settings);
                }
            }
            return 
    $settings
        }



        public function 
    parseWidget(&$widget)
        {
            
    $this->addWidgetAttributes($widget);

            
    $class $widget['inputType'];
            
    $options deserialize($widget['options']);
            
    $return '';

            
    $label $widget['label'] ? sprintf(
    '<h3><label for="%s">%s</label></h3>
    '
    ,
                                
    'ctrl_'.$widget['id'], 
                                
    $widget['label'])
                                : 
    '';

        
            switch (
    $widget['inputType'])
            {
                case 
    'list':        
                    
    $return sprintf(
    '%s<div id="%s" class="list_container">
        <ul class="list%s">'

                                
    $label,
                                
    'ctrl_'.$widget['id'], 
                                (
    strlen($widget['class']) ? ' ' $widget['class'] : '')
                        );
                    foreach (
    $options as $id=>$option)
                    {
                        
    $class standardize($option['id']);
                        
    $class = ($class == '' 'none' $class);
                        
                        
    $selected $option['selected'];
                        
    $return .= sprintf('
            <li class="option%s%s"><a href="%s" title="%s">%s</a></li>'
    ,
                            
    ' list_'.$class,
                            (
    $selected ' active' ''),
                            
    $option['value'],
                            
    $option['label'],
                            
    $option['label']
                        );
                    }
                    
    $return .= '
        </ul></div>'
    ;
                    break;
                                


                case 
    'range':
                    
    $widget['value'] = deserialize($widget['value'], true);
                    
    $arrFields = array();
                    for (
    $i=0$i<2$i++)
                    {
                        
    $datepicker = ($widget['datepicker'] ? '
                        <script type="text/javascript"><!--//--><![CDATA[//><!--
                        window.addEvent(\'domready\', function() { ' 
    sprintf($widget['datepicker'], 'ctrl_' $widget['id'] .'_'.$i) . ' });
                        //--><!]]></script>'
                        
    '');
                        
                        
    // adding a <label for=""> to the inputs
                        
    $strLabel = ($i == 0) ? $GLOBALS['TL_LANG']['MSC']['rangeFrom'] : $GLOBALS['TL_LANG']['MSC']['rangeTo'];
            
                        
    $arrFields[] = sprintf('%s<input type="text" name="%s[]" id="ctrl_%s" class="text%s" value="%s"%s />',
                                (
    strlen($strLabel)) ? '<label for="ctrl_' $widget['id'].'_'.$i '">' $strLabel '</label>' '',
                                
    $widget['name'],
                                
    $widget['id'].'_'.$i,
                                (
    strlen($widget['class']) ? ' ' $widget['class'] : ''),
                                
    specialchars($widget['value'][$i]),
                                
    $widget['attributes'])
                                . 
    $datepicker . ($i==$this->addSubmit($widget) : '');
                                    
                    }

                    
    $return sprintf('%s<div id="ctrl_%s"%s>%s</div>',
                            
    $label,
                            
    $widget['id'],
                            (
    strlen($widget['class']) ? ' class="' $widget['class'] . '"' ''),
                            
    implode(($widget['separator'] ? $widget['separator'] : ' '), $arrFields));
                    
                    break;

                case 
    'text':
                    
    $return sprintf('<input type="text" name="%s" id="ctrl_%s" class="text%s" value="%s"%s />',
                                    
    $widget['name'],
                                    
    $widget['id'],
                                    (
    strlen($widget['class']) ? ' ' $widget['class'] : ''),
                                    
    specialchars($widget['value']),
                                    
    $widget['attributes']) 
                                    . 
    $this->addSubmit($widget);
                    break;    


                case 
    'radio':
                
                    
    $arrOptions = array();
                    foreach (
    $options as $i=>$option)
                    {
                        
    $arrOptions[] = sprintf('<input type="radio" name="%s" id="opt_%s" class="radio%s" value="%s"%s%s /> <label for="opt_%s">%s</label>',
                                                
    $widget['name'],
                                                
    $widget['id'].'_'.$option['id'],
                                                (
    strlen($widget['class']) ? ' ' $widget['class'] : ''),
                                                
    specialchars($option['value']),
                                                (
    $option['selected'] ? ' checked="checked"' ''),
                                                
    $widget['attributes'],
                                                
    // $widget['id'].'_'.$i,
                                                
    $widget['id'].'_'.$option['id'], // we have to use the proper ID otherwise the label won't be attached to the input.
                                                
    $option['label']);
                    }
            
                    
    // Add a "no entries found" message if there are no options
                    
    if (!count($options))
                    {
                        
    $arrOptions[]= '<p class="tl_noopt">'.$GLOBALS['TL_LANG']['MSC']['noResult'].'</p>';
                    }
            
                    
    $return sprintf('%s<div id="ctrl_%s" class="radio_container%s">%s</div>',
                                
    $label,
                                
    $widget['id'],
                                (
    strlen($widget['class']) ? ' ' $widget['class'] : ''),
                                
    implode(($widget['separator'] ? $widget['separator'] : '<br />'), $arrOptions));

                    break;

            
                case 
    'checkbox':
                
                    
    $arrOptions = array();
                    foreach (
    $options as $i=>$option)
                    {
                        
    $arrOptions[] = sprintf('<span><input type="checkbox" name="%s" id="opt_%s" class="checkbox%s" value="%s"%s%s /> <label for="opt_%s">%s</label></span>',
                            
    $widget['name'] . ($widget['multiple'] ? '[]' ''), // name
                            
    $widget['id'].'_'.$option['id'], // id
                            
    (strlen($widget['class']) ? ' ' $widget['class'] : ''), // class
                            
    ($widget['multiple'] ? specialchars($option['value']) : 1), // value
                            
    ($option['selected'] ? ' checked="checked"' ''), // state
                            
    $widget['attributes'], // more attributes
    //                        $widget['id'].'_'.$i, // the id again
                            
    $widget['id'].'_'.$option['id'], // the id again
                            
    $option['label']); // and the label
                    
    }
        
                    
    // Add a "no entries found" message if there are no options
                    
    if (!count($options))
                    {
                        
    $arrOptions[]= '<p class="noopt">'.$GLOBALS['TL_LANG']['MSC']['noResult'].'</p>';
                    }

            
    $return sprintf('%s<div id="ctrl_%s" class="%s%s">%s</div>',
                            
    $label,
                            
    $widget['id'],
                            (
    $widget['multiple'] ? 'checkbox_container' 'checkbox_single_container'),
                            (
    strlen($widget['class']) ? ' ' $widget['class'] : ''),
    //                        implode(($widget['separator'] ? $widget['separator'] : '<br />'), $arrOptions));
                            // c.schiffler - removed the separator as if none specified, we do not want one. <br /> is evil IMO.
                            
    implode(($widget['separator'] ? $widget['separator'] : ''), $arrOptions));
                    break;


        
                case 
    'select':
                    
    // Add empty option (XHTML) if there are none
                    
    if (!count($options))
                    {
                        
    $options = array(array('value'=>'''label'=>'-'));
                    }
                    foreach (
    $options as $option)
                    {
                        
    $strOptions .= sprintf('<option value="%s"%s>%s</option>',
                                        
    $option['value'],
                                        (
    $option['selected'] ? ' selected="selected"' ''),
                                        
    $option['label']);
                    }
                    
                    
    $return sprintf('%s<select name="%s" id="ctrl_%s" class="%s%s"%s%s>%s</select>',
                            
    $label,
                            
    $widget['name'] . ($widget['multiple'] ? '[]' ''),
                            
    $widget['id'],
                            (
    $widget['multiple'] ? 'multi'.$class $class),
                            (
    strlen($widget['class']) ? ' ' $widget['class'] : ''),
                            (
    $widget['multiple'] ? ' multiple="multiple"' ''),
                            
    $widget['attributes'],
                            
    $strOptions);
                
                    break;
        
            
            
                default:;
            }        
            return 
    '<div class="widget'.(strlen($widget['id']) ? ' ' $widget['id'] : '').'">
    '
    .$return.'
    </div>
    '
    ;
        }



        protected function 
    addSubmit($widget)
        {
            return (
    strlen($widget['slabel']) ? sprintf(' <input type="submit" id="ctrl_%s_submit" class="submit" value="%s" />',
                            
    $widget['id'],
                            
    specialchars($widget['slabel']))
                            : 
    '');
        }


        private function 
    addWidgetAttributes(&$widget)
        {
            switch (
    $widget['inputType'])
            {
                case 
    'radio':
                    
    $types = array
                    (
                        
    'attributes'    => ' onclick="window.location=this.value"',
                    );
                    break;

                case 
    'checkbox':
                    
    $types = array
                    (
                        
    'multiple'        => true,
                        
    'attributes'    => ' onclick="window.location=this.value"',
                    );
                    break;

                case 
    'select':
                    
    $types = array
                    (
                        
    'attributes'        => $widget['multiple'
                                        ? 
    ' onclick="window.location=this.options[this.selectedIndex].value"' 
                                        
    ' onchange="window.location=this.options[this.selectedIndex].value"',
                    );

                    break;
                default:;
            }
            if (
    is_array($types)) 
            {
                
    $widget array_merge($widget$types);
            }
        }
        


        private function 
    checkArray($arrInput
        {
            return 
    is_array($arrInput) ? $arrInput : array();
        }



        protected function 
    selectSortLabel($inputType$blnAsc=true)
        {
            
    $labelSuffix '';
            switch (
    $inputType)
            {
                case 
    'text':
                case 
    'longtext':
                case 
    'select':
                case 
    'tags':
                case 
    'url':
                case 
    'file':
                    
    $labelSuffix $blnAsc $GLOBALS['TL_LANG']['MSC']['AtoZ']: $GLOBALS['TL_LANG']['MSC']['ZtoA'];
                    break;
                
                case 
    'number':
                case 
    'decimal':
                    
    $labelSuffix $blnAsc $GLOBALS['TL_LANG']['MSC']['lowhigh']: $GLOBALS['TL_LANG']['MSC']['highlow'];
                    break;
                
                case 
    'checkbox':
                    
    $labelSuffix $blnAsc $GLOBALS['TL_LANG']['MSC']['falsetrue']: $GLOBALS['TL_LANG']['MSC']['truefalse'];
                    break;
                
                case 
    'date':
                    
    $labelSuffix $blnAsc $GLOBALS['TL_LANG']['MSC']['dateasc']: $GLOBALS['TL_LANG']['MSC']['datedesc'];
                    break;
                    
                default:
                    if(
    $blnAsc)
                    {
                        if(
    $GLOBALS['TL_LANG']['MSC'][$inputType.'asc'])
                            
    $labelSuffix=$GLOBALS['TL_LANG']['MSC'][$inputType.'asc'];
                    } else {
                        if(
    $GLOBALS['TL_LANG']['MSC'][$inputType.'desc'])
                            
    $labelSuffix=$GLOBALS['TL_LANG']['MSC'][$inputType.'desc'];
                    }
            }        
            return 
    $labelSuffix;
        }



        private function 
    getJumpTo($catalogJump$blnJumpTo=true)
        {
            global 
    $objPage;
            if(!
    $blnJumpTo)
                return 
    $objPage->row();

            if (
    $this->cacheJumpTo[$catalogJump])
            {
                return 
    $this->cacheJumpTo[$catalogJump];
            }
            else
            {
                if (
    $catalogJump && $blnJumpTo)
                {
                    
    // Get current "jumpTo" page
                    
    $objJump $this->Database->prepare("SELECT * FROM tl_page WHERE id=?")
                                            ->
    execute($catalogJump);
                    if (
    $objJump->numRows)
                    {
                        
    $pageRow $objJump->row();
                    }
                } 
                else
                {
                    
    $pageRow $objPage->row();
                }
                
    // cacheJumpTo
                
    $this->cacheJumpTo[$pageRow['id']] = $pageRow;
                return 
    $pageRow;
            }
        }



        public function 
    generateFilterUrl($arrGet = array(), $blnRoot=false$blnJumpTo=true)
        {
            
    $arrPage=$this->getJumpTo($this->catalog_jumpTo$blnJumpTo);
            
    $strParams '';
            if (
    is_array($arrGet) && ($arrGet))
            {
                foreach (
    $arrGet as $k=>$v)
                {
                    if (
    strlen($v)) 
                    {
                        
    $fieldConf = &$GLOBALS['TL_DCA'][$this->strTable]['fields'][$k];
                        if (
    in_array($fieldConf['eval']['catalog']['type'], array('select''tags')) 
                                && 
    $this->getAliasFieldConf($fieldConf) != 'id')
                        {
                            
    $arrAlias $this->getAliasOptionList($fieldConf);
                            if (
    $fieldConf['eval']['catalog']['type'] == 'tags')
                            {
                                
    $tags explode(','$v);
                                
    $newtags = array();
                                foreach(
    $tags as $tag)
                                {
                                    
    $newtags[] = $arrAlias[$tag];
                                }
                                
    $v implode(','$newtags);
                            }
                            else
                            {
                                
    $v $arrAlias[$v]; 
                            }
                        }
                        
    $v str_replace($GLOBALS['TL_CONFIG']['catalog']['safeCheck'], $GLOBALS['TL_CONFIG']['catalog']['safeReplace'], $v);
        
                        
    $strParams .= $GLOBALS['TL_CONFIG']['disableAlias'] ? '&amp;' $k '=' $v  '/' $k '/' $v;
                    }
                }
            }
            return (
    $blnRoot $this->Environment->base '') . $this->generateFrontEndUrl($arrPage$strParams);        
        }

        
    /**
         * Translate SQL if needed (needed for calculated fields)
         * @param array
         * @return array
         */

        
    protected function processFieldSQL($arrVisible)
        {
            
    $arrConverted = array();

            
    // iterate all catalog fields
            
    $objFields $this->Database->prepare("SELECT * FROM tl_catalog_fields f WHERE f.pid=(SELECT c.id FROM tl_catalog_types c WHERE c.tableName=?)")
                                       ->
    execute($this->strTable);

            
    $arrFields = array();
            if (
    $objFields->numRows)
            {
                while (
    $objFields->next())
                {
                    
    $row $objFields->row();            
                    
    $arrFields[$row['colName']] = $row;
                }

                foreach (
    $arrVisible as $id=>$field)
                {
                    if (
    array_key_exists($field$arrFields))
                    {
                        switch (
    $arrFields[$field]['type'])
                        {
                            case 
    'calc':
                                
    // set query value to forumla
                                
    $value '('.$arrFields[$field]['calcValue'].') AS '.$field//.'_calc';
                                
    $arrConverted[$id] = $value;
                                break;

                            default:
                                
    $arrConverted[$id] = $field;
                        }

                    }

                    
    // HOOK: allow third party extension developers to prepare the SQL data
                    
    if(is_array($GLOBALS['TL_HOOKS']['processFieldSQL']) && count($GLOBALS['TL_HOOKS']['processFieldSQL']))
                    {
                        foreach(
    $GLOBALS['TL_HOOKS']['processFieldSQL'] as $callback)
                        {
                            
    $this->import($callback[0]);
                            
    $this->$callback[0]->$callback[1]($this->catalog$id$field$arrFields$arrConverted$this->strTable);
                        }
                    }    
                }    
            }

            return 
    $arrConverted;
        }

        
    /**
         * Generate one or more items and return them as array
         * @param object
         * @param boolean
         * @return array
         */
        
    protected function generateCatalog(Database_Result $objCatalog$blnLink=true$visible=null$blnImageLink=false)
        {
            
    $i=0;
            
    $arrCatalog = array();

            
    $objCatalog->reset();        
            while (
    $objCatalog->next())
            {
                
    $arrCatalog[$i]['id'] = $objCatalog->id;
                
    $arrCatalog[$i]['catalog_name'] = $objCatalog->catalog_name;
                
    $arrCatalog[$i]['parentJumpTo'] = $objCatalog->parentJumpTo;
                
    $arrCatalog[$i]['tablename'] = $this->strTable;
                
    $arrCatalog[$i]['showLink'] = (!$this->catalog_link_override);

                
    // get alias field WARNING -- check if blnLink is needed for edit mode where alias is also used
                
    if ($i==&& $blnLink)
                {
                    
    $objArchive $this->Database->prepare("SELECT aliasField FROM tl_catalog_types where id=?")
                                             ->
    limit(1)
                                             ->
    execute($objCatalog->pid);

        
                    
    $aliasField $objArchive->numRows $objArchive->aliasField 'alias';
                }
                
                
    $class = (($i == 0) ? ' first' '') . ((($i 1) == $objCatalog->numRows) ? ' last' '') . ((($i 2) == 0) ? ' even' ' odd');
                
    $arrCatalog[$i]['class'] = $class;

                if (
    $blnLink
                {
                    
    $arrCatalog[$i]['link'] = $this->generateLink($objCatalog$aliasField$this->strTable$this->catalog_link_window);
                    
    $arrCatalog[$i]['url'] = $this->generateCatalogUrl($objCatalog$aliasField$this->strTable);
                }


                
    $arrData $objCatalog->row();
                
    // check if editing of this record is disabled for frontend.
                
    $editingallowedByFields=true;
                foreach (
    $GLOBALS['TL_DCA'][$this->strTable]['fields'] as $fieldname=>$field)
                {
                    if(
    is_array($visible) && !in_array($fieldname$visible))
                        continue;
                    
    // HOOK: additional permission checks if this field allows editing of this record (for the current user).
                    
    $fieldType $GLOBALS['BE_MOD']['content']['catalog']['fieldTypes'][$field['eval']['catalog']['type']];
                    if(
    is_array($fieldType) && array_key_exists('checkPermissionFERecordEdit'$fieldType) && is_array($fieldType['checkPermissionFERecordEdit']))
                    {
                        foreach (
    $fieldType['checkPermissionFERecordEdit'] as $callback)
                        {
                            
    $this->import($callback[0]);
                            
    // TODO: Do we need more parameters here?
                            
    if(!($this->$callback[0]->$callback[1]($this->strTable$fieldname$arrData)))
                            {
                                
    $editingallowedByFields=false;
                                break;
                            }
                        }
                    }
                }

                if (
    $this->catalog_edit_enable && $editingallowedByFields)
                {
                    
    $arrCatalog[$i]['linkEdit'] = $this->generateLink($objCatalog$aliasField$this->strTable$this->catalog_link_windowtrue);
                    
    $arrCatalog[$i]['urlEdit'] = $this->generateCatalogEditUrl($objCatalog$aliasField$this->strTable);
                }

                if (
    is_array($visible))
                {
                    foreach(
    $visible as $field)
                    {
                        
    $tmpData[$field] = $arrData[$field];
                    }
                    
    $arrData $tmpData;
                }
                

                foreach (
    $arrData as $k=>$v)
                {
                
                    
    $fieldConf = &$GLOBALS['TL_DCA'][$this->strTable]['fields'][$k];
                    
                    
    $blnParentCheckbox $fieldConf['eval']['catalog']['parentCheckbox'] && !$arrData[$fieldConf['eval']['catalog']['parentCheckbox']];
                    
                    if (
    in_array($k, array('id','pid','sorting','tstamp')) || $fieldConf['inputType'] == 'password' || $blnParentCheckbox)
                        continue;

                    
    $strLabel strlen($label $fieldConf['label'][0]) ? $label $k;
                    
    $strType $fieldConf['eval']['catalog']['type'];

                    
    $arrValues $this->parseValue($this->type.$i$k$v$blnImageLink$objCatalog);
                    
                    
    $linked deserialize($this->catalog_islinktrue);
                    if (
    $this->catalog_link_override && is_array($linked) && in_array($k$linked))
                    {
                        
    $arrValues['html'] = $this->generateLink($objCatalog$aliasField$this->strTable$this->catalog_link_windowfalse$arrValues['html']);
                    }

                    
    $arrCatalog[$i]['data'][$k] = array
                    (
                        
    'label' => $strLabel,
                        
    'type'    => $strType,
                        
    'raw' => $v,
                        
    'value' => ($arrValues['html'] ? $arrValues['html'] : '')
                    );

                    switch (
    $strType)
                    {
                        case 
    'select':
                        case 
    'tags':
                            list(
    $refTable$valueCol) = explode('.'$fieldConf['eval']['catalog']['foreignKey']);

                            if (
    strlen(trim($v)))
                            {
                                
    // set sort order
                                
    $sortCol =    $fieldConf['eval']['catalog']['sortCol'];
                                if (!
    strlen($sortCol)) 
                                {
                                    
    $sortCol 'sorting';
                                }
                                        
                                
    $sortOrder $this->Database->fieldExists($sortCol$refTable) ? $sortCol $refCol;

                                
    // Get referenced fields
                                
    $objRef $this->Database->prepare('SELECT * FROM '.$refTable.' WHERE id IN ('.trim($v).')'.(strlen($sortOrder)?' ORDER BY '.$sortOrder:''))
                                                        ->
    execute();

                                if (
    $objRef->numRows)
                                {
                                    
    // Get Ref Catalog JumpTo
                                    
    $objJump $this->Database->prepare("SELECT tableName, aliasField, jumpTo FROM tl_catalog_types WHERE tableName=?")
                                                            ->
    limit(1)
                                                            ->
    execute($refTable);
                                                            
                                    
    // Add Ref Catalog Links
                                    
    if ($objJump->numRows)
                                    {
                                        while (
    $objRef->next())
                                        {
                                                
    $objRef->parentJumpTo $objJump->jumpTo;
                                                
    $objRef->parentLink $this->generateLink($objRef$objJump->aliasField$objJump->tableName$this->catalog_link_window);
                                                
    $objRef->parentUrl $this->generateCatalogUrl($objRef$objJump->aliasField$objJump->tableName);
                                        }
                                    }

                                    
    // add to reference array
                                    
    $arrCatalog[$i]['data'][$k]['ref'] = $objRef->fetchAllAssoc();                                
                                }
                            }
                            break;

                        case 
    'file':
                        case 
    'image':
                            
    // add file and image information
                            
    $arrCatalog[$i]['data'][$k]['files'] = $arrValues['items'];
                            
    $arrCatalog[$i]['data'][$k]['meta'] = $arrValues['values'];

                            break;

                        default:
                            
    // per default we deliver all other keys aswell to allow custom field types to transport custom data.
                            
    foreach($arrValues as $kk => $vv)
                            {
                                if(
    $kk != 'html')
                                    
    $arrCatalog[$i]['data'][$k][$kk] = $vv;
                            }
                    }

                }
                
    // HOOK: allow other extensions to manipulate the item before returning them in the array
                
    if(is_array($GLOBALS['TL_HOOKS']['generateCatalogItem']))
                {
                    foreach (
    $GLOBALS['TL_HOOKS']['generateCatalogItem'] as $callback)
                    {
                        
    $this->import($callback[0]);
                        
    $arrCatalog[$i] = $this->$callback[0]->$callback[1]($arrCatalog[$i], $arrData$this);
                    }
                }
                
    $i++;
            }
            return 
    $arrCatalog;
        }

        
    /**
         * Parse one or more items and pipe them through the given template
         * @param object
         * @param boolean
         * @return array
         */
        
    protected function parseCatalog(Database_Result $objCatalog$blnLink=true$template='catalog_full'$visible=null$blnImageLink=false)
        {
            
    $objTemplate = new FrontendTemplate($template);
            
    $arrCatalog $this->generateCatalog($objCatalog$blnLink$visible$blnImageLink);

            
    // HOOK: allow other extensions to manipulate the items before passing it to the template
            
    if(is_array($GLOBALS['TL_HOOKS']['parseCatalog']))
            {
                foreach (
    $GLOBALS['TL_HOOKS']['parseCatalog'] as $callback)
                {
                    
    $this->import($callback[0]);
                    
    $arrCatalog $this->$callback[0]->$callback[1]($arrCatalog$objTemplate$this);
                }
            }
            
    $objTemplate->entries         $arrCatalog;
            
    $objTemplate->moduleTemplate  $this->Template;
            
    $objTemplate->noItemsMsg      $GLOBALS['TL_LANG']['MSC']['noItemsMsg'];

            return 
    $objTemplate->parse();
        }


        protected function 
    generateCatalogUrl(Database_Result $objCatalog$aliasField='alias'$strTable$strPrependParams='')
        {

            if (!
    strlen($aliasField))
            {
                
    $aliasField 'alias';
            }

            
    $useJump = ($this instanceof ModuleCatalogList || $this instanceof ModuleCatalogFeatured || $this instanceof ModuleCatalogRelated || $this instanceof ModuleCatalogReference || $this instanceof ModuleCatalogNavigation); 

            
    $jumpTo = ($useJump && $this->jumpTo) ? $this->jumpTo $objCatalog->parentJumpTo;
            
    $arrPage=$this->getJumpTo($jumpTotrue);
            return 
    ampersand($this->generateFrontendUrl($arrPage$strPrependParams '/items/' . (($this->Database->fieldExists($aliasField$strTable) && strlen($objCatalog->$aliasField) && !$GLOBALS['TL_CONFIG']['disableAlias']) ? $objCatalog->$aliasField $objCatalog->id)));
            
        }

        private function 
    generateCatalogEditUrl(Database_Result $objCatalog$aliasField='alias'$strTable)
        {

            if (!
    strlen($aliasField))
            {
                
    $aliasField 'alias';
            }

            
    $arrPage=$this->getJumpTo($this->catalog_editJumpTotrue);

            
    // Link to catalog edit
            
    return ampersand($this->generateFrontendUrl($arrPage'/items/' . (($this->Database->fieldExists($aliasField$strTable) && strlen($objCatalog->$aliasField) && !$GLOBALS['TL_CONFIG']['disableAlias']) ? $objCatalog->$aliasField $objCatalog->id)));
            
        }


        
    /**
         * Generate a link and return it as string
         * @param string
         * @param object
         * @param boolean
         * @return string
         */
        
    protected function generateLink(Database_Result $objCatalog$aliasField$strTable$blnWindow$blnEdit=false$strLink='')
        {
            
    $linkUrl = (!$blnEdit $this->generateCatalogUrl($objCatalog$aliasField$strTable) : $this->generateCatalogEditUrl($objCatalog$aliasField$strTable));
            
    $strLink strlen($strLink) ? $strLink : (!$blnEdit $GLOBALS['TL_LANG']['MSC']['viewCatalog'] : $GLOBALS['TL_LANG']['MSC']['editCatalog']);
            
    $strTitle = (!$blnEdit $GLOBALS['TL_LANG']['MSC']['viewCatalog'] : $GLOBALS['TL_LANG']['MSC']['editCatalog']);

            return 
    sprintf('<a href="%s" title="%s"%s>%s</a>',
                            
    $linkUrl,
                            
    $strTitle,
                            
    $blnWindow ' onclick="this.blur(); window.open(this.href); return false;"' '',
                            
    $strLink
                            
    );
        }


         
    /**
         * Format the catalog value according to its settings and return it as HTML string
         * @param integer
         * @param string
         * @param variable
         * @param boolean
         * @return string
         */

        
    protected function formatValue($id$k$value$blnImageLink=true$objCatalog=array())
        {
            
    $arrFormat $this->parseValue($id$k$value$blnImageLink$objCatalog);
            return 
    $arrFormat['html'];
        }
        

         
    /**
         * parse the catalog values and return information as an array
         * @param integer
         * @param string
         * @param variable
         * @param boolean
         * @return array
         */
      
        
    protected function parseValue($id$k$value$blnImageLink=true$objCatalog=array())
        {
            
    $raw $value;
            
    $arrItems deserialize($valuetrue);
            
    $arrValues deserialize($valuetrue);
            
    $strHtml $value;
            
    $fieldConf = &$GLOBALS['TL_DCA'][$this->strTable]['fields'][$k];

            if((
    version_compare(VERSION'2.10''>=')) && $fieldConf['eval']['rte'] && $GLOBALS['TL_CONFIG']['useRTE'])
            {
                global 
    $objPage;
                
    $this->import('String');
                
    // reformat the RTE output to the proper format
                
    if($objPage->outputFormat == 'xhtml')
                {
                    
    $strHtml $this->String->toXhtml($strHtml);
                }
                if(
    $objPage->outputFormat == 'html5')
                {
                    
    $strHtml $this->String->toHtml5($strHtml);
                }
            }

            switch (
    $fieldConf['eval']['catalog']['type'])
            {
                case 
    'select':
                case 
    'tags':
                    if (
    $fieldConf['options'])
                    {
                        
    $arrItems trimsplit(',',$raw);
                        
    $selectedValues array_intersect_key($fieldConf['options'], array_flip($arrItems));
                        
    $arrValues $selectedValues;
                        
    $strHtml implode(', '$arrValues);
                    }
                    break;

                case 
    'file':
                    
    $files $this->parseFiles($id$k$raw);
                    
    $arrItems $files['files'];
                    
    $arrValues $files['src'];
                    
    $strHtml implode(''$files['html']);
                    break;


                case 
    'url':
                    if (
    strlen($raw))
                    {
                        
    // E-mail addresses
                        
    if (preg_match_all('/^(mailto:)?(\w+([_\.-]*\w+)*@\w+([_\.-]*\w+)*\.[a-z]{2,6})$/i'$value$matches))
                        {
                            
    $this->import('String');
                            
    $emailencode $this->String->encodeEmail($matches[2][0]);
                            
    $arrValues[0] = $emailencode;
                            
    $strHtml '<a href="mailto:' $emailencode '">' $emailencode '</a>';
                        }
                        elseif (
    preg_match_all('@^(https?://|ftp://)(\w+([_\.-]*\w+)*\.[a-z]{2,6})(/?)@i'$value$matches))
                        {
                            
    $arrValues[0] = $raw;
                            
    $website $matches[2][0];
                            
    $strHtml '<a href="'.ampersand($raw).'"'.(preg_match('@^(https?://|ftp://)@i'$value) ? ' onclick="window.open(this.href); return false;"' '').'>'.$website.'</a>';
                        }
                    
                    }
                    break;
            
                
    // allow custom fields.
                
    default:
                    if(
    array_key_exists($fieldConf['eval']['catalog']['type'], $GLOBALS['BE_MOD']['content']['catalog']['fieldTypes']))
                    {
                        
    // HOOK: try to format the fieldtype as it is a custom added one.
                        
    $fieldType=$GLOBALS['BE_MOD']['content']['catalog']['fieldTypes'][$fieldConf['eval']['catalog']['type']];
                        if(
    array_key_exists('parseValue'$fieldType) && is_array($fieldType['parseValue']))
                        {
                            foreach (
    $fieldType['parseValue'] as $callback)
                            {
                                
    $this->import($callback[0]);
                                
    $ret=$this->$callback[0]->$callback[1]($id$k$value$blnImageLink$objCatalog$this$fieldConf);
                                
    $arrItems $ret['items'];
                                
    $arrValues $ret['values'];
                                
    $strHtml $ret['html'];
                            }
                        }
                    }
            }        

            
    // special formatting 
            
    $formatStr $fieldConf['eval']['catalog']['formatStr'];
            if (
    strlen($formatStr))
            {
                
    //$formatStr = htmlspecialchars_decode($fieldConf['eval']['catalog']['formatStr']);
                
    $value $arrValues[0];
                switch (
    $fieldConf['eval']['catalog']['formatFunction'])
                {
                    case 
    'string':
                            
    $value sprintf($formatStr$value);
                            break;
                    case 
    'number':
                            
    $decimalPlaces is_numeric($formatStr) ? intval($formatStr) : 0;
                            
    $value number_format($value$decimalPlaces
                                    
    $GLOBALS['TL_LANG']['MSC']['decimalSeparator'],
                                    
    $GLOBALS['TL_LANG']['MSC']['thousandsSeparator']);
                            break;
                    case 
    'date':
                            if (
    strlen($raw) && $raw !== 0)
                            {
                                
    $date = new Date($raw);
                                
    $value $this->parseDate((strlen($formatStr) ? $formatStr $GLOBALS['TL_CONFIG']['dateFormat']), $date->tstamp);
                            }
                            else
                            {
                                
    $value '';
                            }
                            break;
                    default:;
                }
                
    $arrValues[0] = $value;
                
    $strHtml $value;
            }

            
    // add prefix and suffix format strings
            
    if (is_array($fieldConf['eval']['catalog']['formatPrePost']) && count($fieldConf['eval']['catalog']['formatPrePost'])>0)
            {
                
    $strHtml $fieldConf['eval']['catalog']['formatPrePost'][0].$strHtml.$fieldConf['eval']['catalog']['formatPrePost'][1];
                
    // no $this->restoreBasicEntities() as this is done in the OutputTemplate
            
    }

            
    $return['items'] = $arrItems;
            
    $return['values'] = $arrValues;
            
    $return['html'] = $strHtml;

            return 
    $return;
        }


         
    /**
         * parse files into HTML and other information and return as an array
         * @param integer
         * @param string
         * @param variable
         * @return array
         */

        
    public function parseFiles($id$k$files)
        {    
            
    $fieldConf = &$GLOBALS['TL_DCA'][$this->strTable]['fields'][$k];

            
    $blnThumnailOverride $this->catalog_thumbnails_override && ($this instanceof ModuleCatalogList || $this instanceof ModuleCatalogFeatured || $this instanceof ModuleCatalogRelated || $this instanceof ModuleCatalogReference);

            
    // setup standard linking
            
    $showLink $fieldConf['eval']['catalog']['showLink'];
            
            
    // image override 
            
    if ($blnThumnailOverride)
            {
                
    $showLink $this->catalog_imagemain_field == $k $this->catalog_imagemain_fullsize 
                        (
    $this->catalog_imagegallery_field == $k $this->catalog_imagegallery_fullsize ''); // override default
            
    }

            
    $sortBy $blnThumnailOverride $this->sortBy $fieldConf['eval']['catalog']['sortBy'];
            
            
    $files deserialize($files,true);
            
    $countFiles count($files);
            if (!
    is_array($files) || $countFiles 1)
            {
                return array(
    'files'=>array(),'src'=>array(),'html'=>array());
            }    

            
    // required for parseMetaFile function (in FrontEnd)
            
    $this->multiSRC $files;
            
    $this->arrAux = array();
            
    // TODO: we also have to clean the array of already processed files here as otherwise $arrAux will not get populated again.
            // We might find some better approach to this in the future rather than cleaning the cache arrays.
            
    $this->arrProcessed=array();

            
    $arrFiles = array();
            
    $arrSource = array();
            
    $arrValues = array();
            
    $auxDate = array();

            
    $counter 0
            
    $allowedDownload trimsplit(','strtolower($GLOBALS['TL_CONFIG']['allowedDownload']));
            if (
    strlen($fieldConf['eval']['extensions']))
            {
                
    $extensions trimsplit(','strtolower($fieldConf['eval']['extensions']));
                
    $allowedDownload array_intersect($allowedDownload$extensions);
            }

            foreach (
    $files as $file)
            {
                if (!
    file_exists(TL_ROOT '/' $file))
                {
                    continue;
                }

                if (
    is_file(TL_ROOT '/' $file))
                {
                    
    $objFile = new File($file);

                    
    $showImage $objFile->isGdImage && $fieldConf['eval']['catalog']['showImage'];
                    if (!
    $showImage && in_array($objFile->extension$allowedDownload) || $showImage
                    {
                        
    $class = (($counter == 0) ? ' first' '') . (($counter == ($countFiles -)) ? ' last' '') . ((($counter 2) == 0) ? ' even' ' odd');

                        
    $this->parseMetaFile(dirname($file), true);
                        
    $strBasename strlen($this->arrMeta[$objFile->basename][0]) ? $this->arrMeta[$objFile->basename][0] : specialchars($objFile->basename);
                        
    $alt = (strlen($this->arrMeta[$objFile->basename][0]) ? $this->arrMeta[$objFile->basename][0] : ucfirst(str_replace('_'' 'preg_replace('/^[0-9]+_/'''$objFile->filename))));

                        
    $auxDate[] = $objFile->mtime;
                        
                        
    // images
                        
    if ($showImage)
                        {
                            
    $w $fieldConf['eval']['catalog']['imageSize'][0] ? $fieldConf['eval']['catalog']['imageSize'][0] : '';
                            
    $h $fieldConf['eval']['catalog']['imageSize'][1] ? $fieldConf['eval']['catalog']['imageSize'][1] : '';
                            if (
    $blnThumnailOverride)
                            {
                                
    $newsize =  deserialize($this->catalog_imagemain_field == $k $this->catalog_imagemain_size 
                                    
    : ($this->catalog_imagegallery_field == $k $this->catalog_imagegallery_size : array()) );
                                
    $w = ($newsize[0] ? $newsize[0] : '');
                                
    $h = ($newsize[1] ? $newsize[1] : '');
                            }
                            
    $src $this->getImage($this->urlEncode($file), $w$h$fieldConf['eval']['catalog']['imageSize'][2]);
                            
    $size getimagesize(TL_ROOT '/' $src);
                            
    $arrSource[$file] = array
                            (
                                
    'src'    => $src,
                                
    'alt'    => $alt,
                                
    'lb'    => 'lb'.$id,
                                
    'w'     => $size[0],
                                
    'h'     => $size[1],
                                
    'wh'    => $size[3],
                                
    'caption' => (strlen($this->arrMeta[$objFile->basename][2]) ? $this->arrMeta[$objFile->basename][2] : ''),
                                
    'metafile' => $this->arrMeta[$objFile->basename],
                            );
                            
    $tmpFile '<img src="'.$src.'" alt="'.$alt.'" '.$size[3].' />';
                            if (
    $showLink)    
                            {
                                
    // $tmpFile = '<a rel="lightbox[lb'.$id.']" href="'.$file.'" title="'.$alt.'">'.$tmpFile.'</a>';
                                // we have to supply the catalog id here as we might have more than one catalog with a field with the same name 
                                // which will cause the lightbox to display the images for items with the same id in both.
                              
    $tmpFile '<a data-lightbox="'$this->strTable $id '" title="'.$alt.'" href="'.$file '/' $subfile.'">'.$tmpFile.'</a>';
                   
                }
                        }
                        
    // files
                        
    elseif ($showLink)
                        {
                            
    $text $strBasename;
                            
    $url $this->Environment->request . (($GLOBALS['TL_CONFIG']['disableAlias'] || strpos($this->Environment->request'?') !== false) ? '&amp;' '?') . 'file=' $this->urlEncode($file);
                            
    $icon 'system/themes/' $this->getTheme() . '/images/' $objFile->icon;
                            
    $sizetext '('.$this->getReadableSize($objFile->filesize1).')';
                            
    $arrSource[$file] = array
                            (
                                
    'title' => $strBasename,
                                
    'url' => $url,
                                
    'alt'    => $alt,
                                
    'caption' => (strlen($this->arrMeta[$objFile->basename][2]) ? $this->arrMeta[$objFile->basename][2] : ''),
                                
    'size' => $objFile->filesize,
                                
    'sizetext' => $sizetext,
                                
    'icon' => $icon,
                                
    'metafile' => $this->arrMeta[$objFile->basename],
                            );
                            
    $iconfile '<img src="'.$icon.'" alt="'.$alt.'" />';
                            
    $tmpFile $iconfile.' <a href="'.$url.'" title="'.$alt.'">'.$text.' '.$sizetext.'</a>';
                        }

                        
    $arrFiles[$file] = $file;
                        
    $arrValues[$file] = '<span class="'.($showImage 'image' 'file').$class.'">'.$tmpFile.'</span>';
                        
    $counter ++;
                    }
                    continue;
                }
                else if (
    is_dir(TL_ROOT '/' $file))
                {
                    
    // Folders

                    
    $subfiles scan(TL_ROOT '/' $file);
                    
    $this->parseMetaFile($file);
            
                    foreach (
    $subfiles as $subfile)
                    {
                        if (
    is_file(TL_ROOT '/' $file '/' $subfile))
                        {    
                            
    $objFile = new File($file '/' $subfile);

                            
    $showImage $objFile->isGdImage && $fieldConf['eval']['catalog']['showImage'];
                            if (!
    $showImage && in_array($objFile->extension$allowedDownload) || $showImage
                            {
                                
    $class = (($counter == 0) ? ' first' '') . ((($counter 2) == 0) ? ' even' ' odd');        

                                
    $strBasename strlen($this->arrMeta[$objFile->basename][0]) ? $this->arrMeta[$objFile->basename][0] : specialchars($objFile->basename);
                                
    $alt = (strlen($this->arrMeta[$objFile->basename][0]) ? $this->arrMeta[$objFile->basename][0] : ucfirst(str_replace('_'' 'preg_replace('/^[0-9]+_/'''$objFile->filename))));

                                
    $auxDate[] = $objFile->mtime;
                
                                if (
    $showImage)
                                {
                                    
    $w $fieldConf['eval']['catalog']['imageSize'][0] ? $fieldConf['eval']['catalog']['imageSize'][0] : '';
                                    
    $h $fieldConf['eval']['catalog']['imageSize'][1] ? $fieldConf['eval']['catalog']['imageSize'][1] : '';
                                    if (
    $blnThumnailOverride)
                                    {
                                        
    $newsize =  deserialize($this->catalog_imagemain_field == $k $this->catalog_imagemain_size 
                                            
    : ($this->catalog_imagegallery_field == $k $this->catalog_imagegallery_size : array()) );
                                        
    $w = ($newsize[0] ? $newsize[0] : '');
                                        
    $h = ($newsize[1] ? $newsize[1] : '');
                                    }
                                    
    $src $this->getImage($this->urlEncode($file '/' $subfile), $w$h$fieldConf['eval']['catalog']['imageSize'][2]);
                                    
    $size getimagesize(TL_ROOT '/' $src);

                                    
    $arrSource[$file '/' $subfile] = array
                                    (
                                        
    'src'    => $src,
                                        
    'alt'    => $alt,
                                        
    'lb'    => 'lb'.$id,
                                        
    'w'     => $size[0],
                                        
    'h'     => $size[1],
                                        
    'wh'    => $size[3],
                                        
    'caption' => (strlen($this->arrMeta[$objFile->basename][2]) ? $this->arrMeta[$objFile->basename][2] : ''),
                                        
    'metafile' => $this->arrMeta[$objFile->basename],
                                    );

                                    
    $tmpFile '<img src="'.$src.'" alt="'.$alt.'" '.$size[3].' />';
                                    if (
    $showLink)    
                                    {
                                        
    // $tmpFile = '<a rel="lightbox[lb'.$id.']" title="'.$alt.'" href="'.$file . '/' . $subfile.'">'.$tmpFile.'</a>';
                                        // we have to supply the catalog id here as we might have more than one catalog with a field with the same name here.
                                        
    $tmpFile '<a data-lightbox="'$this->strTable $id '" title="'.$alt.'" href="'.$file '/' $subfile.'">'.$tmpFile.'</a>';
                                    }

                                }
                                
    // files
                                
    elseif ($showLink)
                                {
                                    
    $text $strBasename;
                                    
    $url $this->Environment->request . (($GLOBALS['TL_CONFIG']['disableAlias'] || !$GLOBALS['TL_CONFIG']['rewriteURL']
    && 
    count($_GET) || strlen($_GET['page'])) ? '&amp;' '?'). 'file=' $this->urlEncode($file '/' $subfile);
                                    
    $icon 'system/themes/' $this->getTheme() . '/images/' $objFile->icon;
                                    
    $sizetext '('.number_format(($objFile->filesize/1024), 1$GLOBALS['TL_LANG']['MSC']['decimalSeparator'], $GLOBALS['TL_LANG']['MSC']['thousandsSeparator']).' kB)';
                                    
                                    
    $arrSource[$file '/' $subfile] = array
                                    (
                                        
    'title' => $strBasename,
                                        
    'url' => $url,
                                        
    'alt'    => $alt,
                                        
    'caption' => (strlen($this->arrMeta[$objFile->basename][2]) ? $this->arrMeta[$objFile->basename][2] : ''),
                                        
    'size' => $objFile->filesize,
                                        
    'sizetext' => $sizetext,
                                        
    'icon' => $icon,
                                        
    'metafile' => $this->arrMeta[$objFile->basename],
                                    );
                                    
    $iconfile '<img src="'.$icon.'" alt="'.$alt.'" />';
                                    
    $tmpFile $iconfile.' <a href="'.$url.'" title="'.$alt.'">'.$text.' '.$sizetext.'</a>';
                                }
                                
                                
    $arrFiles[$file '/' $subfile] = $file '/' $subfile;
                                
    $arrValues[$file '/' $subfile] = '<span class="'.($showImage 'image' 'file').$class.'">'.$tmpFile.'</span>';
                                
    $counter ++;
                            }
                        }
                    }
                }
            }

            
    // Sort array
            
    $files = array();
            
    $source = array();
            
    $values = array();

            switch (
    $sortBy)
            {
                default:
                case 
    'name_asc':
                    
    uksort($arrFiles'basename_natcasecmp');
                    break;

                case 
    'name_desc':
                    
    uksort($arrFiles'basename_natcasercmp');
                    break;

                case 
    'date_asc':
                    
    array_multisort($arrFilesSORT_NUMERIC$auxDateSORT_ASC);
                    break;

                case 
    'date_desc':
                    
    array_multisort($arrFilesSORT_NUMERIC$auxDateSORT_DESC);
                    break;

                case 
    'meta':
                    foreach (
    $this->arrAux as $aux)
                    {
                        
    $k array_search($aux$arrFiles);
                        if (
    $k !== false)
                        {
                            
    $files[] = $arrFiles[$k];
                            
    $source[] = $arrSource[$k];
                            
    $values[] = $arrValues[$k];
                        }
                    }
                    break;

                case 
    'random':
                    
    $keys array_keys($arrFiles);
                    
    shuffle($keys);
                    foreach(
    $keys as $key)
                    {
                        
    $files[$key] = $arrFiles[$key];
                    }
                    
    $arrFiles $files;
                    break;
            }
            if (
    $sortBy != 'meta')
            {
                
    // re-sort the values
                
    foreach($arrFiles as $k=>$v)
                {
                    
    $files[] = $arrFiles[$k];
                    
    $source[] = $arrSource[$k];
                    
    $values[] = $arrValues[$k];
                }
            }

            
    $return['files']    = $files;
            
    $return['src']         = $source;
            
    $return['html']        = $values;


            return 
    $return;
        }


        
    /**
         * Replace Catalog InsertTags including TL InsertTags
         * @param string
         * @param array
         * @return string
         */

        
    protected function replaceCatalogTags($strValue$arrCatalog)
        {
            
    $strValue trim($strValue);

            
    // search for catalog tags
            
    $tags = array();
            
    preg_match_all('/{{[^}]+}}/i'$strValue$tags);

            
    // Replace tags of type {{catalog::fieldname}}
            
    foreach ($tags[0] as $tag)
            {
                
    $elements explode('::'trim(str_replace(array('{{''}}'), array(''''), $tag)));

                
    // {{catalog::fieldname}}
                
    if (strtolower($elements[0]) == 'catalog')
                {
                    
    $key $elements[1];
                    if (
    array_key_exists($key$arrCatalog))
                    {
                        
    $strValue str_replace($tagstr_replace("\n""<br>"$arrCatalog[$key]), $strValue);
                    }
                }
            }
            
            
    // Replace standard insert tags
            
    if (strlen($strValue))
            {
                
    $strValue $this->replaceInsertTags($strValue);
            }

            return 
    $strValue;
        } 



        
    /**
         * Generate Front-end Url with only catalog ID as parameter
         * @param integer
         * @param integer
         * @return string
         */

        
    public function generateCatalogNavigationUrl($field=false$value=false)
        {
            
    $jumpTo$this->catalog_jumpTo?$this->catalog_jumpTo:$this->jumpTo;
            
    $pageRow=$this->getJumpTo($jumpTotrue);

            if (!
    $pageRow)
            {
                return 
    ampersand($this->Environment->requestENCODE_AMPERSANDS);
            }

            if(
    $field)
            {
                
    $strParams $GLOBALS['TL_CONFIG']['disableAlias'] ? '&amp;' $field '=' $value  '/' $field '/' $value;
            } else {
                
    $strParams '';
            }

            
    // Return link to catalog reader page with item alias
            
    return ampersand($this->generateFrontendUrl($pageRow$strParams));
            
        }


        protected function 
    renderCatalogNavigationItems($id$level=1$blnTags=false$value='')
        {
            
    $aliasField $this->getAliasField($this->strTable);

            
    $strWhere $blnTags $this->strTable.'.id=tl_catalog_tag_rel.itemid AND fieldid='.$GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->catalog_navigation]['eval']['catalog']['fieldId'].' AND valueid='.$id.'' $this->catalog_navigation."=?";
            
    // TODO: add the parsed filter URL here.
            
    if(!BE_USER_LOGGED_IN && $this->publishField)
            {
                
    $strWhere .=' AND '.$this->publishField.'=1';
            }
            
    // query database
            
    $objNodes $this->Database->prepare('SELECT DISTINCT '.$this->strTable.'.*, tl_catalog_types.jumpTo AS parentJumpTo FROM '.$this->strTable.($blnTags?', tl_catalog_tag_rel':'').', tl_catalog_types WHERE tl_catalog_types.id='.$this->strTable.'.pid AND '.$strWhere)
                                            ->
    execute($id);
            if (
    $objNodes->numRows 1)
            {
                return 
    '';
            }
            
            
    $items = array();

            
    // Determine the layout template
            
    if (!strlen($this->navigationTpl))
            {
                
    $this->navigationTpl 'nav_default';
            }

            
    // Overwrite template
            
    $objTemplate = new FrontendTemplate($this->navigationTpl);

            
    $objTemplate->type get_class($this);
            
    $objTemplate->level 'level_' $level++;

            
    // Get page object
            
    global $objPage;

            
    $showField $this->catalog_show_field;

            
    // Browse items
            
    while($objNodes->next())
            {
                
    $href $this->generateCatalogUrl($objNodes$aliasField$this->strTablesprintf('/%s/%s'$this->catalog_navigation$value?$value:$id));
                
                
    // Active field
                
    if ($this->Input->get('items') == $objNodes->id || $this->Input->get('items') == $objNodes->$aliasField)
                {
                    
    $strClass =  trim('item' . (strlen($objJump->cssClass) ? ' ' $objJump->cssClass ''));

                    
    $items[] = array
                    (
                        
    'isActive' => true,
                        
    'subitems' => $subitems,
                        
    'class' => (strlen($strClass) ? $strClass ''),
    //                    'pageTitle' => specialchars($objJump->pageTitle),
                        
    'title' => specialchars($objNodes->$showField),
                        
    'link' => $objNodes->$showField,
                        
    'href' => $href,
    //                    'alias' => $objJump->alias,
    //                    'target' => (($objJump->type == 'redirect' && $objJump->target) ? ' window.open(this.href); return false;' : ''),
    //                    'description' => str_replace(array("\n", "\r"), array(' ' , ''), $objJump->description),
    //                    'accesskey' => $objJump->accesskey,
    //                    'tabindex' => $objJump->tabindex
                    
    );

                    continue;
                }

                
    $strClass trim('item' . (strlen($objJump->cssClass) ? ' ' $objJump->cssClass ''));

                
    $items[] = array
                (
                    
    'isActive' => false,
                    
    'subitems' => $subitems,
                    
    'class' => (strlen($strClass) ? $strClass ''),
    //                'pageTitle' => specialchars($objJump->pageTitle),
                    
    'title' => specialchars($objNodes->$showField),
                    
    'link' => $objNodes->$showField,
                    
    'href' => $href,
    //                'alias' => $objJump->alias,
    //                'target' => (($objJump->type == 'redirect' && $objJump->target) ? ' window.open(this.href); return false;' : ''),
    //                'description' => str_replace(array("\n", "\r"), array(' ' , ''), $objJump->description),
    //                'accesskey' => $objJump->accesskey,
    //                'tabindex' => $objJump->tabindex
                
    );

            }

            
    // Add classes first and last
            
    if (count($items))
            {
                
    $last count($items) - 1;

                
    $items[0]['class'] = trim($items[0]['class'] . ' first');
                
    $items[$last]['class'] = trim($items[$last]['class'] . ' last');
            }

            
    $objTemplate->items $items;
            return 
    count($items) ? $objTemplate->parse() : '';
            
        }


        protected 
    $arrTrail=array();
        protected 
    $objNavField=NULL;

        
    /**
         * Recursively compile the catalog navigation menu and return it as HTML string
         * @param integer
         * @param integer
         * @return string
         */
        
    protected function internalRenderCatalogNavigation($pid$level$strActive=NULL)
        {
            
    // Get internal page (from parent catalog)
            
    $arrJump $this->getJumpTo($this->jumpTofalse);
            
    $ids = ($pid == 0) ? ($this->objNavField->limitItems && $this->objNavField->items $this->objNavField->items : array(0)) : array($pid);
            
    $strRoot = ((!$this->objNavField->blnChildren && $level == 1) ? 'id' 'pid');
            if (
    $this->objNavField->treeView)
            {
                if(
    $this->objNavField->type == 'tags')
                {
                    
    $strItemCount '(SELECT COUNT(t.id) AS count FROM tl_catalog_tag_rel AS t RIGHT JOIN ' $this->strTable ' AS c ON (t.itemid=c.id) WHERE t.valueid=o.id AND t.fieldid=' $this->objNavField->id . (!BE_USER_LOGGED_IN && $this->publishField ' AND c.' $this->publishField.'=1' '') . ') AS itemCount';
                } else {
                    
    $strItemCount '(SELECT COUNT(t.id) AS count FROM ' $this->strTable ' AS t WHERE ' 
                    (!
    BE_USER_LOGGED_IN && $this->publishField 't.'.$this->publishField.'=1 AND ' '') . 
                    
    $this->catalog_navigation ' IN (SELECT id FROM  ' $this->objNavField->sourceTable ' AS t WHERE pid=o.id) OR '.$this->catalog_navigation.'=o.id) AS itemCount';
                }
                
    $objNodes $this->Database->execute('SELECT '.$strRoot.', id, ' $this->objNavField->valueField 
                                                
    ', (SELECT COUNT(*) FROM '$this->objNavField->sourceTable .' i WHERE i.pid=o.id) AS childCount, ' 
                                                
    $this->objNavField->sourceColumn ' AS name, ' .
                                                
    $strItemCount .
                                                
    ' FROM '$this->objNavField->sourceTable' o WHERE '.$strRoot.' IN ('.implode(',',$ids).') ORDER BY '$this->objNavField->sort);
            }
            if (!
    $this->objNavField->treeView || ($objNodes->numRows == && $level == 1))
            {
                
    $objNodes $this->Database->execute('SELECT id, '.$this->objNavField->valueField.', 0 AS childCount, '$this->objNavField->sourceColumn .' AS name, 0 AS itemCount FROM '$this->objNavField->sourceTable .' ORDER BY '.$this->objNavField->sort);
            }
            
    // no entries for the given pid
            
    if (!$objNodes->numRows)
                return 
    '';

            
    $valueField=$this->objNavField->valueField;

            
    $items = array();
            
    // Overwrite template
            
    $objTemplate = new FrontendTemplate($this->navigationTpl);
            
    $objTemplate->type get_class($this);
            
    $objTemplate->level 'level_' $level++;
            
    // Browse field nodes

            
    while($objNodes->next())
            {
                
    $subitems '';
                
    $strClass '';
                
    // setup field and value
                
    $field $this->catalog_navigation;
                
    $value $objNodes->$valueField;
                
    $isTrail in_array($objNodes->id$this->arrTrail);
                
    $href $this->generateCatalogNavigationUrl($field$valuesprintf('/%s/%s'$field$value));

                 if (!
    $this->showLevel || $this->showLevel >= $level || (!$this->hardLimit && $isTrail))
                {
                    
    // if current field value is selected, display children
                    
    if ($this->catalog_show_items && $strActive == $objNodes->$valueField)
                    {
                        
    $subitems .= $this->renderCatalogNavigationItems($objNodes->id$level, ($this->objNavField->type == 'tags'), $value);
                    }
                    if (
    count($objNodes->childCount) && $this->objNavField->blnChildren
                    {
                        
    $subitems .= $this->internalRenderCatalogNavigation($objNodes->id$level$strActive);
                    }
                }

                
    $strClass .= trim((strlen($subitems) ? 'submenu' ''
                                . (
    strlen($arrJump['cssClass']) ? ' ' $arrJump['cssClass'] : '')
                                . (
    $isTrail ' trail' '')
                                . 
    ' ' . (count($items)%'odd' 'even')
                                );
                
    // Active field
                
    if ($strActive == $value)
                {
                    
    $items[] = array
                    (
                        
    'isActive' => !strlen($this->Input->get('items')),
                        
    'subitems' => $subitems,
                        
    'subitemcount' => $objNodes->itemCount,
                        
    'class' => (strlen($strClass) ? $strClass ''),
                        
    'pageTitle' => specialchars($arrJump['pageTitle']),
                        
    'title' => specialchars($objNodes->name),
                        
    'link' => $objNodes->name,
                        
    'href' => $href,
                        
    'alias' => $arrJump['alias'],
                        
    'target' => (($arrJump['type'] == 'redirect' && $arrJump['target']) ? ' window.open(this.href); return false;' ''),
                        
    'description' => str_replace(array("\n""\r"), array(' ' ''), $arrJump['description']),
                        
    'accesskey' => $arrJump['accesskey'],
                        
    'tabindex' => $arrJump['tabindex'],
                        
    'itemAlias' => $value
                    
    );
                    
    // move on to next childnode
                    
    continue;
                }

                if(!
    $this->objNavField->treeView || ($objNodes->itemCount || $objNodes->childCount))
                {
                    
    $items[] = array
                    (
                        
    'isActive' => false,
                        
    'subitems' => $isTrail?$subitems:'',
                        
    'subitemcount' => $objNodes->itemCount,
                        
    'class' => (strlen($strClass) ? $strClass ''),
                        
    'pageTitle' => specialchars($arrJump['pageTitle']),
                        
    'title' => specialchars($objNodes->name),
                        
    'link' => specialchars($objNodes->name),
                        
    'href' => $href,
                        
    'alias' => $arrJump['alias'],
                        
    'target' => (($arrJump['type'] == 'redirect' && $arrJump['target']) ? ' window.open(this.href); return false;' ''),
                        
    'description' => str_replace(array("\n""\r"), array(' ' ''), $arrJump['description']),
                        
    'accesskey' => $arrJump['accesskey'],
                        
    'tabindex' => $arrJump['tabindex'],
                        
    'itemAlias' => $value
                    
    );
                }
            }

            
    // Add classes first and last
            
    if (count($items))
            {
                
    $last count($items) - 1;

                
    $items[0]['class'] = trim($items[0]['class'] . ' first');
                
    $items[$last]['class'] = trim($items[$last]['class'] . ' last');
            }
            
    $objTemplate->items $items;
            return 
    count($items) ? $objTemplate->parse() : '';
        }

        protected function 
    determineNavRootFromReferer($strNavField$skipRawReferer=false)
        {
            
    $HTTPReferer = (!$skipRawReferer) ? $this->Environment->httpReferer $this->getReferer();

            
    // We check the real HTTP referer first, as we might have multiple tabs open in 
            // this environment and therefore want to use the "real" referer.
            
    if((!$skipRawReferer) && preg_match('#[\/?&]'.$strNavField.'#'$HTTPReferer))
            {
                
    $strRequest str_replace($this->Environment->base''$HTTPReferer);
                if(!
    $GLOBALS['TL_CONFIG']['disableAlias'])
                {
                    
    $strRequest preg_replace('/\?.*$/i'''$strRequest);
                    
    $strRequest preg_replace('/' preg_quote($GLOBALS['TL_CONFIG']['urlSuffix'], '/') . '$/i'''$strRequest);
                    
    $arrFragments explode('/'$strRequest);
                    
    // Skip index.php
                    
    if (strtolower($arrFragments[0]) == 'index.php')
                    {
                        
    array_shift($arrFragments);
                    }
                } else {
                    
    // TODO: handle disabled aliases here.
                    
    $arrFragments = array();
                }
                
    // skip page and search for our param.
                
    for($i=1;$i<count($arrFragments);$i+=2)
                {
                    if(
    $arrFragments[$i]==$strNavField)
                    {
                        return 
    $arrFragments[$i+1];
                    }
                }
            }
            if(!
    $skipRawReferer)
            {
                return 
    $this->determineNavRootFromReferer($strNavFieldtrue);
            }
        }

        
    /**
         * Look up all needed stuff and then call the recursive function internalRenderCatalogNavigation
         * @param integer
         * @return string
         */
        
    protected function renderCatalogNavigation($pid)
        {
            
    $this->arrTrail=array();
            
    // get reference table and column        
            
    $objFields $this->Database->prepare('SELECT * FROM tl_catalog_fields WHERE pid=? AND colName=?')
                                                ->
    limit(1)
                                                ->
    execute($this->catalog$this->catalog_navigation);
            if (!
    $objFields->numRows)
                return 
    '';
            
    $this->objNavField = new stdClass();
            
    $this->objNavField->id $objFields->id;
            
    $this->objNavField->sourceTable $objFields->itemTable;
            
    $this->objNavField->sourceColumn $objFields->itemTableValueCol;
            
    $this->objNavField->blnChildren $objFields->childrenSelMode;
            
    $this->objNavField->limitItems $objFields->limitItems;
            
    $this->objNavField->items deserialize($objFields->items);
            
    $this->objNavField->valueField $this->getAliasField($this->objNavField->sourceTable);
            
    $this->objNavField->type $objFields->type;
            
    // check if this tree has a pid or a flat table
            
    $this->objNavField->treeView $this->Database->fieldExists('pid'$this->objNavField->sourceTable);
            
    $this->objNavField->sort $this->Database->fieldExists('sorting'$this->objNavField->sourceTable) ? 'sorting' $this->objNavField->sourceColumn;
            
    // Determine the layout template
            
    if (!strlen($this->navigationTpl))
            {
                
    $this->navigationTpl 'nav_default';
            }

            
    // root is given via URL
            
    if($this->Input->get($this->catalog_navigation))
            {
                
    $root=$this->Input->get($this->catalog_navigation);
            }
            
    // root not given via URL but we have an select field and an item is being requested.
            
    else if($this->Input->get('items') && ($this->objNavField->type == 'select'))
            {
                
    // SELECT fields
                
    $value=$this->Input->get('items');
                
    $strAlias $this->strAliasField $this->strAliasField : (is_numeric($value) ? 'id' '');
                if(
    strlen($strAlias))
                {
                    
    $objItem $this->Database->prepare('SELECT '.$this->objNavField->valueField.' AS alias FROM '$this->objNavField->sourceTable' WHERE id=(SELECT '.$this->catalog_navigation.' FROM '.$this->strTable.' WHERE '.(!BE_USER_LOGGED_IN && $this->publishField $this->publishField.'=1 AND ' ''). $strAlias '=?)')
                                                ->
    limit(1)
                                                ->
    execute($value);
                    if (
    $objItem->numRows)
                    {
                        
    $root=$objItem->alias;
                    }
                }
            }
            
    // no root via URL but an item requested, let's try to get the root from the referer.
            
    else if($this->Input->get('items') && !$this->Input->get($this->catalog_navigation))
            {
                
    // check if in referer is something mentioned.
                
    if(preg_match('#[\/?&]'.$this->catalog_navigation.'#'$this->Environment->httpReferer))
                {
                    
    $root $this->determineNavRootFromReferer($this->catalog_navigation);
                }
            }
            if (
    $this->objNavField->treeView && $root)
            {
                
    // determine all parents
                
    $objRoot $this->Database->prepare('SELECT id,pid FROM '$this->objNavField->sourceTable' WHERE '.$this->objNavField->valueField.'=?')
                                                    ->
    limit(1)
                                                    ->
    execute($root);
                
    $parents=array($objRoot->id);
                
    // root found, we can now find the parents.
                
    while($objRoot->numRows && $objRoot->pid)
                {
                    
    $parents[]=$objRoot->pid;
                    
    $objRoot $this->Database->prepare('SELECT pid FROM '$this->objNavField->sourceTable' WHERE id='.$objRoot->pid)
                                                        ->
    limit(1)
                                                        ->
    execute();
                }
                foreach(
    array_reverse($parents) as $k=>$v)
                    
    $this->arrTrail[$k+1]=$v;
            }
            if(
    $this->levelOffset)
            {
                
    // start level specified but not in trail -> do not output
                
    if(!$this->arrTrail[$this->levelOffset])
                    return 
    '';
                
    $pid $this->arrTrail[$this->levelOffset];
            }
            return 
    $this->internalRenderCatalogNavigation($pid1$root);
        }
        
        
    /**
         * List and generate comment form
         * @param object
         */
        
    public function processComments(Database_Result $objCatalog)
        {
            
    // Comments
            
    $objArchive $this->Database->prepare('SELECT * FROM tl_catalog_types WHERE id=?')
                                         ->
    limit(1)
                                         ->
    execute($objCatalog->pid);

            if (
    $objArchive->numRows || !$objArchive->allowComments || !in_array('comments'$this->Config->getActiveModules()))
            {
                
    $this->Template->allowComments false;
                return;
            }

            
    $this->Template->allowComments true;
            
    $this->import('Comments');
            
    $objConfig = new stdClass();
            
    $objConfig->perPage $objArchive->perPage;
            
    $objConfig->order $objArchive->sortOrder;
            
    $objConfig->template $objArchive->template;
            
    $objConfig->requireLogin $objArchive->requireLogin;
            
    $objConfig->disableCaptcha $objArchive->disableCaptcha;
            
    $objConfig->bbcode $objArchive->bbcode;
            
    $objConfig->moderate $objArchive->moderate;
            
    // TODO: add notifies here.
            
    $arrNotifies=array($GLOBALS['TL_ADMIN_EMAIL']);

            
    // issue #1690 hide member details not working anymore.
            
    if($objArchive->hideMember && ($this->Input->post('FORM_SUBMIT')=='com_'$this->strTable .'_'$objCatalog->id))
            {
                
    // we have to trick the comments module into beliving that the user inserted his name and email as those are hardcoded mandatory.
                
    $this->import('FrontendUser''Member');
                
    $this->Input->setPost('name'trim($this->Member->firstname ' ' $this->Member->lastname));
                
    $this->Input->setPost('email'trim($this->Member->email));
            }
            
    $this->Comments->addCommentsToTemplate($this->Template$objConfig$this->strTable$objCatalog->id$arrNotifies);

            if(
    $objArchive->hideMember)
            {
                
    $fields $this->Template->fields;
                unset(
    $fields['name']);
                unset(
    $fields['email']);
                
    $this->Template->fields=$fields;
            }
            if(
    $objArchive->disableWebsite)
            {
                
    $fields $this->Template->fields;
                unset(
    $fields['website']);
                
    $this->Template->fields=$fields;
            }
        }
    }

    ?>
    Noch ein Hinweis, wenn in den Ordnernamen wo die Bilder liegen Leerzeichen sind, verträgt es sich auch nicht mit dem Catalog.

  36. #36
    Contao-Nutzer
    Registriert seit
    30.07.2009.
    Ort
    Hessen
    Beiträge
    147

    Standard

    Wenn man einzelne Bilder in einem Ordner anklickt, und nicht den gesamten Ordner anhakt, kommt es ebenfalls zu Problemen. @Mack schon bekannt ?

  37. #37
    Contao-Nutzer
    Registriert seit
    13.07.2009.
    Beiträge
    135

    Standard

    Danke dir!
    Ich hab das gerade eingebaut aber einen seltsamen Fehler entdeckt:

    Wenn ich mehrere Bilder ausgewählt habe, funktioniert die Mediabox.
    Wenn ich nur ein Bild über den Katalog eingefügt habe, dann öffnet sich das Pop-Up aber das Bild lädt nicht.

    Der Link der erzeugt wird, heißt auch www.domain.com/tl_files/mein_ordner/bild.jpg/ (mit Schrägstrich am Ende der URL)
    Liegt das vielleicht an dem Script? Mein PHP reicht da leider nicht aus...
    Geändert von valentin (10.07.2012 um 12:09 Uhr)

  38. #38
    Contao-Nutzer
    Registriert seit
    13.07.2009.
    Beiträge
    135

    Standard

    Okay, ich hab jetzt mal auf Verdacht aus der Zeile 2580 den Schrägstrich entfernt.

    PHP-Code:
    $tmpFile '<a data-lightbox="'$this->strTable $id '" title="'.$alt.'" href="'.$file '/' $subfile.'">'.$tmpFile.'</a>'
    Zeile 2580 neu:

    PHP-Code:
    $tmpFile '<a data-lightbox="'$this->strTable $id '" title="'.$alt.'" href="'.$file '' $subfile.'">'.$tmpFile.'</a>'

    Hat funktioniert - hoffe, es hat keine anderen Einschränkungen.

    Das NEUE ModuleCatalog.php habe ich als ZIP angehängt.
    Angehängte Dateien Angehängte Dateien
    Geändert von valentin (10.07.2012 um 12:11 Uhr)

  39. #39
    Contao-Yoda Avatar von MacKP
    Registriert seit
    15.06.2009.
    Ort
    Duisburg
    Beiträge
    13.292
    User beschenken
    Wunschliste
    Contao-Projekt unterstützen

    Support Contao

    Standard

    Zitat Zitat von zonk Beitrag anzeigen
    Wenn man einzelne Bilder in einem Ordner anklickt, und nicht den gesamten Ordner anhakt, kommt es ebenfalls zu Problemen. @Mack schon bekannt ?
    Ich meine das ist noch nciht bekannt. Bitte ein Ticket machen

    Viele Grüße
    Contao Pool | C-C-A | MetaModels | [Internetseite -> Mediendepot Ruhr]
    [Arbeitet bei -> Paus Design & Medien]
    "I can EXPLAIN it to you, but I can't UNDERSTAND it for you."

  40. #40
    Contao-Nutzer
    Registriert seit
    30.07.2009.
    Ort
    Hessen
    Beiträge
    147

    Standard

    Zitat Zitat von MacKP Beitrag anzeigen
    Ich meine das ist noch nciht bekannt. Bitte ein Ticket machen

    Viele Grüße
    Das Entfernen wie von valentin beschrieben des Slash "/" behebt den Ordner-Fehler..

Aktive Benutzer

Aktive Benutzer

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)

Lesezeichen

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •