Archiv der Kategorie: TYPO3 CMS

Rechteverwaltung im TYPO3-Backend

Die Rechte der Benutzer des TYPO3-BE können über Zugriffslisten (Access Lists) bis ins Kleinste definiert werden.

Wenn z.B. folgende Meldung beim Bearbeiten eines Seiteninhaltselements erscheint, ist die Darstellung der Dateilinks (File Links) untersagt:

Sie haben nicht die nötigen Rechte, um diese Änderung durchzuführen.
Reason: ERROR: authMode „explicitDeny“ failed for field „CType“ with value „uploads“ evaluated

Standardmäßig ist $TYPO3_CONF_VARS[‘BE’][‘explicitADmode’] auf den Wert ‚explicitDeny‘ eingestellt, wodurch alle Zugriffe erlaubt sind und Verbote ausdrücklich (explizit) gesetzt werden müssen. Entfernt man nun die Markierung von „[Deny] File Links“ und speichert die Einstellungen, kann die jeweilige Benutzergruppe auch auf das Inhaltselement vom Typ Dateilinks zugreifen.

TYPO3-Rechteverwaltung
Explicitly allow/deny field values

Dateien in FAL ersetzen

Wer unter TYPO3 CMS die Extension DAM (Digital Asset Management) einsetzte, weis die Vorteile der Funktion „Datei ersetzen“ zu schätzen. Zum jetzigen Zeitpunkt gibt es eine analoge Funktion unter FAL bzw. TYPO3 CMS 6.2 jedoch nicht.

Ein Trick, um die Funktionalität beizubehalten, ist es, eine Datei mit gleichem Namen in das Verzeichnis hochzuladen und eine bestehende Datei somit zu überschreiben. Die Datei-Referenz bleibt bestehen und somit ist das Ziel erreicht. Nach dem Hochladen kann die (neue) Datei natürlich umbenannt werden.

Gefunden im TYPO-Forum.

Call to undefined method getCharset() in LocallangXmlParser.php

Nach einem erfolgreichen TYPO3-Update von 4.5 auf 6.2 lief alles soweit. Bis zu dem Zeitpunkt, als im Backend ein neuer Datensatz per Web | Seite erstellt werden sollte (Wizard zum Erstellen neuer Inhaltselemente). Es erschien die Fehlermeldung

Fatal error: Call to undefined method tx_wtdirectory_pi1_wizicon::getCharset() in xxx/typo3_src-6.2.5/typo3/sysext/core/Classes/Localization/Parser/LocallangXmlParser.php on line 41

Nach einer kurzen Suche fand ich die Ursache: der statische Aufruf der Funktion getParsedData().

$LOCAL_LANG = t3lib_l10n_parser_Llxml::getParsedData($llFile, $GLOBALS['LANG']->lang);

Beheben liess sich der Bug folgendermaßen, wie auf TYPO3 Forge nachgelesen werden kann:

$version = class_exists('t3lib_utility_VersionNumber')
 ? t3lib_utility_VersionNumber::convertVersionNumberToInteger(TYPO3_version)
 : t3lib_div::int_from_ver(TYPO3_version);
if ($version >= 4007000) {
 $object = t3lib_div::makeInstance('t3lib_l10n_parser_Llxml');
 $LOCAL_LANG = $object->getParsedData($llFile, $GLOBALS['LANG']->lang);
} else {
 $LOCAL_LANG = t3lib_div::readLLXMLfile($llFile, $GLOBALS['LANG']->lang);
}

Auch Powermail lieferte unter Version 1.6.11 eine ähnliche Fehlermeldung:

Fatal error: Call to undefined method TYPO3\CMS\Core\Utility\GeneralUtility::readLLXMLfile() in xxx/typo3conf/ext/powermail/pi1/class.tx_powermail_pi1_wizicon.php on line 79

Hier lag es aber nicht an der statischen Einbindung, sondern noch an einer Versions-Unverträglichkeit:

$LOCAL_LANG = t3lib_div::readLLXMLfile($llFile, $GLOBALS['LANG']->lang);

 

Akkordeon mit TYPO3

Akkordeons eignen sich als Design- bzw. UI-Elemente, um den Benutzer auf wichtige Inhalte zu lenken, ohne beschreibende oder weiterführende Inhalte sofort zur Verfügung zu stellen, aber diese dennoch mit wenig (Zeit-)Aufwand bereitzustellen.

Akkordeon

Zur Umsetzung als Inline-Akkordeon (im Fließtext einzubauen) müssen bspw. folgende Stellen erweitert werden:

  • Template
  • Javascript
  • CSS

Generiert wird das Akkordeon im Typoscript des Main-Templates:

lib.stdheader {
    ...
    # Vererbung von H3:
    91 < .3
    91.fontTag = <h3 class="inlineAccordionToggler">|</h3><div class="inlineAccordionElement">
    ...
}
tt_content.stdWrap {
    ...
    outerWrap = |</div>
    outerWrap.stdWrap.if.equals = 91
    outerWrap.stdWrap.if.value.field = header_layout
}

Dadurch werden Inhaltselemente vom Überschriften-Typ 91 mit einer CSS-Klasse und einem umhüllenden DIV ausgestattet. Die CSS-Klasse hinterlegen wir im eingebundenen Stylesheet:

.inlineAccordionToggler {
    color:#ff7713;
    padding:8px 0;
    margin:0;
    cursor:pointer;
    font-weight: normal;
}
.inlineAccordionActiveToggler {
    font-weight: bold !important;
}
.inlineAccordion {
    border:1px solid #e4e4e4;
    border-width:1px 0;
    margin-bottom:-1px;
    font-size:1em;
}

Momentan kann das Akkordeon aber noch nicht verwendet werden. Dafür muss der Überschriften-Typ 91 per TCEFORM definiert werden:

Web | List | Home => bearbeiten
Ressourcen-Tab => TypoScript-Konfiguration:
TCEFORM.tt_content.header_layout.addItems {
    91 = Inline-Akkordeon
}

Nun kann als Überschriften-Typ Inline-Akkordeon gewählt werden.

tceform

Jetzt fehlt lediglich noch die Javascript-Funktionalität, um das Auf- bzw. Zuklappen bereitzustellen. Bei Verwendung von jQuery könnte das dann so aussehen:

jQuery(document).ready(function(){
    ...
    init_inlineAccordion();
    ...
}
function init_inlineAccordion() {
    var togglers = $('.inlineAccordionToggler');
    if (togglers.length > 0) {
        /**
         * neues Div mit class="inlineAccord" erstellen ..
         * .. und um toggler herum in DOM einfuegen
         */
        $('.inlineAccordionToggler, .inlineAccordionElement').wrapAll('<div class="inlineAccordion"></div>');
        var allPanels = $('.inlineAccordionToggler + .inlineAccordionElement').hide();

        $('.inlineAccordion > .inlineAccordionToggler').click(function() {
            var $this = $(this),
                contentItem = $this.next();
            allPanels.slideUp();
            togglers.removeClass('inlineAccordionActiveToggler');
            if (contentItem.css('display')==='none') {
                // Inhalt einblenden:
                contentItem.slideDown();
                $this.addClass('inlineAccordionActiveToggler');
            }
              return false;
        });
    }
}

Unter Prototype hilft folgendes Snippet:

window.IBSEfehse = {
    inlineAccordion_currentItem: false,
    inlineAccordion_init: function() {
        var togglers = $$('.inlineAccordionToggler'),
            myAccordion = this;
        if (togglers.length > 0) {
            togglers.each(function(toggler,idx){
            myAccordion.inlineAccordion_hideContent(toggler);
                toggler.on('click', function(evt){
                    if (myAccordion.inlineAccordion_currentItem!==false) {
                        if (myAccordion.inlineAccordion_currentItem!==toggler) {
                            myAccordion.inlineAccordion_hideContent(myAccordion.inlineAccordion_currentItem);
                            myAccordion.inlineAccordion_showContent(toggler);
                            myAccordion.inlineAccordion_currentItem = toggler;
                        } else {
                            myAccordion.inlineAccordion_hideContent(toggler);
                            myAccordion.inlineAccordion_currentItem = false;
                        }
                    } else {
                        myAccordion.inlineAccordion_showContent(toggler);
                        myAccordion.inlineAccordion_currentItem = toggler;
                    }
                });
            });
        }
    },
    inlineAccordion_hideContent: function(link){
        var container = link.up(0);
        container.childElements().invoke('hide');
        link.show();
    },
    inlineAccordion_showContent: function(link){
        var container = link.up(0);
        container.childElements().invoke('show');
        this.inlineAccordion_currentItem = link;
    }
};
Event.observe(window, 'load', function() { IBSEfehse.inlineAccordion_init(); });

Das kann in einer bestehenden js-Datei eingearbeitet werden oder separat mittels page.includeJS im TypoScript:

page.includeJs {
    file = xyz.js
}

Domain-Umzug unter TYPO3 CMS

Nach einer Aktualisierung sollte ein TYPO3-CMS-Update praktischerweise per Subdomain umgestellt werden. Beispielsweise sollte ein Update mittels t3update.domain.tld und separatem Verzeichnis (an einer Kopie) durchgeführt werden und nach Abschluss der Aktualisierung müsste lediglich das „Startverzeichnis“ der Domain domain.tld bzw. der Subdomain www.domain.tld auf das „neue“ Verzeichnis umbiegen. Das klappt ohne weitere Probleme und Fallstricke ..

Leider ist dies nicht immer möglich, da entweder kein Zugriff auf die Konfiguration möglich oder der Domain-Administrator nicht greifbar ist. Mit folgenden Schritten klappt auch ein Umzug, ohne an der Konfiguration rumzuspielen:

$ rm -rI typo3temp/
$ rm typo3conf/temp_CACHED_*

Diese zwei Schritte löschen die temporären Dateien physisch. Jedoch reicht dies noch nicht. Nun muss per InstallTool unter „Clear Cache“ noch nachgearbeitet werden: Die Verzeichnisse compressor und _processed_ müssen noch geleert werden (nach Update auf TYPO3 CMS 6.x). Nun können die Verzeichnisse umgezogen werden:

$ mv domainFolder folder-alt
$ mv t3updateFolder domainFolder

Damit sollte im Browser nach Aufruf von domain.tld die aktualisierte TYPO3-Seite zu sehen sein.

Debugging in TYPO3 CMS

Extension debuggen

Auf something.php gibt es zwar schon einen sehr interessanten Artikel zu diesem Thema, aber ich möchte das noch einmal für mich auf die Schnelle zusammenfassen.

Für die TYPO3 CMS 4.x-Ära half u.a. zum Debugging einer Extension:

$content .= t3lib_utility_Debug::viewArray($this->piVars);
return $this->pi_wrapInBaseClass($content);

Unter zuhilfenahme der Namespaces unter TYPO3 CMS 6.x hilft folgendes:

\TYPO3\CMS\Core\Utility\DebugUtility::debug($var, 'Title', 'Group');

oder

 \TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($var, 'Title');

Um das Frontend-Debugging zu aktivieren, muss per InstallTool die Eigenschaft $TYPO3CONF[‚FE‘][‚debug‘] auf 1 gesetzt sein!

TypoScript debuggen

Um beispilesweise die Inhalte eines HMENU darzustellen, hilft folgender Code:

xxx = HMENU
xxx {
  entryLevel = 1
  1 = TMENU
  1 {
    debugItemConf = 1
    NO {
      # hier sonstige Angaben zur Darstellung des Listenpunktes
      stdWrap.debugData = 1
    }
  }
}

debugData stellt dabei den jeweiligen Datensatz im Frontend dar ($cObj->data), debugItemConf zeigt das Konfigurations-Array. Diese Optionen können natürlich auch unabhängig voneinander Verwendung finden.

Dazu gibt es weitere Informationen auf wiki.typo3.org.

Extension auf FAL umstellen

TYPO3 CMS ab Version 6.x setzt auf FAL (File Abstraction Layer) zur Dateireferenzierung. Dies hat einige Vorteile, z.B. kann eine Datei mehrmals verknüpft werden, ohne dass Kopien erstellt werden müssten, wie es vorher der Fall war.

Im Umkehrschluss heißt das allerdings, dass der Dateizugriff im PHP-Quellcode der TYPO3-Erweiterungen angepasst werden muss, wenn bspw. Bilder dargestellt werden. Hier ein kurzes Beispiel zur Umstellung.

In einer Extension in TYPO3 CMS 4.7 zur Darstellung als Template-Marker sah es noch so aus:

# $this->cObj->data => vollstaendiger darszustellender Datensatz
$tmp = explode(',', $this->cObj->data['image']);
if (count($tmp)>0){
  foreach ($tmp as $key=>$value){
    $markerArray['###MY_IMAGE###'] = $this->cObj->IMG_RESOURCE( array( 'file'=>'uploads/pics/' . $value, 'file.'=>array( 'width'=>'199m', 'height'=>'165' )) );
    $this->cObj->substituteMarkerArrayCached($subparts['template_alt_image'], $markerArray);
  }
}

Nach der Umstellung auf TYPO3 CMS 6.2 sieht obiger Code dann so aus:

if (intval($this->cObj->data['image'])>0){ # $this->cObj->data['image'] enthaelt nun die Anzahl der referenzierten Dateien
  $fileRepository = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\FileRepository');
  $fileObjects = $fileRepository->findByRelation('tt_content', 'image', $this->cObj->data['uid']);
  foreach ($fileObjects as $key=>$value){
    $markerArray['###MY_IMAGE###'] = $this->cObj->IMG_RESOURCE( array(
'file.'=>array('treatAsReference'=>1, 'width'=>'199m', 'height'=>'165', ),
'file' => $value->getOriginalFile()->getProperties()['uid'],
'params'=>'',
'altText'=>'',
) );
  $this->cObj->substituteMarkerArrayCached($subparts['template_alt_image'], $markerArray);
  }
}

Eine sehr hilfreiche Dokumentationen dazu ist das TYPO3Wiki.