18.10.2011

Typo3 Extbase Workspaces Preview

Problem: In Extbase werden Datensätze im Preview manchmal nicht richtig angezeigt. Das betrifft Typo3-Datensätze, die in Relation (n-m) zum eigentlichen Haupt-Datensatz stehen und zusammen mit diesem im Frontend dargestellt werden sollen. Der Hauptdatensatz wird als Preview-Version angezeigt, die relationalen Datensätze werden aber aus dem Live-Workspace genommen.

Als Beispiel: Wenn ein (in Extbase selbst programmierter) Newsartikel zum seinem Thema verwandte Artikel als Teaser anzeigen soll, tritt dieses Problem auf. Der Newsartikel kommt aus dem Preview-Workspace, die Teaser der verwandten Artikel kommen aus dem Live-Workspace.

Wenn man im Preview jetzt aber alles so anzeigen möchte wie im Preview zugewiesen, hilft vielleicht dieser Workaround:

Die relationalen Datensätze werden über ihr eigenes Repository an das übergeordnete Model ausgeliefert. Deshalb könnte man innerhalb des Repositorys eine Funktion definieren, die die Objekte aus dem jeweiligen Preview-Workspace zurückliefert anstelle der Live-Daten. Ich hab also eine Klasse Baserepository geschrieben, von der alle meine anderen Repositories erben. In den Querys muss dann noch respectEnableFields auf false gesetzt werden.

<?php

/**
 * Description of BaseRepository
 *
 * @author tim schenk http://www.tim-schenk.de
 */
class Tx_MyExtension_Domain_Repository_BaseRepository extends Tx_Extbase_Persistence_Repository
{
    /**
     * static table->uid array
     * @var array array('Table'=>array('PlaceholderUid'=>'WorkspaceUid'),'nextTable'=>array(...),...);
     */
    private static $idsInWorkspace = array();
    /**
     * table name for this repository
     * @var string
     */
    protected $table = "";
    /**
     * Gets the Workspace ID
     * @return string Workspace ID (default 0 = Live)
     */
    protected function getWsId()
    {
        //if both fails return zero
        $wsId = 0;
        //Backend
        if (!empty($GLOBALS['BE_USER']->workspace))
        {
            $wsId = $GLOBALS['BE_USER']->workspace;
        }
        //Frontend
        elseif (!empty($GLOBALS['TSFE']->sys_page->versioningWorkspaceId))
        {
            $wsId = $GLOBALS['TSFE']->sys_page->versioningWorkspaceId;
        }

        return $wsId;
    }

    /**
     * If its a preview the integer should be greater zero
     * @return integer Workspace ID (default 0 = Live)
     */
    public function isPreview()
    {
        return $this->getWsId();
    }

    /**
     * there might be a standard typo3 function for that
     * @param string $table name of table
     * @return string delete clause sql
     */
    protected function getDeletedClause($table)
    {
        return "$table.deleted=0";
    }

    /**
     * there might be a standard typo3 function for that
     * @param string $table name of table
     * @return string hidden clause sql
     */
    protected function getHiddenClause($table)
    {
        $where = $this->getDeletedClause($table);
        $where .= " AND $table.hidden=0";
        if (!$this->isPreview())
        {
            $where .= " AND ( $table.starttime=0 OR $table.starttime<=" . time() . " )";
            $where .= " AND ( $table.endtime=0 OR $table.endtime>=" . time() . " )";
        }
        return $where;
    }

    /**
     * createQuery overrides parent function
     * @return Tx_Extbase_Persistence_QueryInterface $q
     */
    public function createQuery()
    {
        $q = parent::createQuery();
        // show also hidden fields etc...
        $q->getQuerySettings()->getRespectEnableFields(false);
        return $q;
    }
/**
 * returns the sql string for the actual workspace
 * @param string $table
 * @return string workspace sql clause
 */
    public function getWsClause($table)
    {
        //get workspace id
        $wsId = $this->getWsId();
        $where = "";

        if ($wsId == 0)
        {//Live workspace
            $where .= " $table.pid<>-1 ";
            $where .= " AND $table.t3ver_wsid=0 ";
            if (TYPO3_MODE == 'FE')
            {
                //includes deleted and startime / endtime
                $where .= " AND " . $this->getHiddenClause($table);
            }
            else
            {
                // dont return any deleted stuff
                $where .= " AND $table.deleted=0";
            }
        }
        else
        {//preview workspace
            $stageWhere = $this->getPrewiewStageClause($table);
            if (!empty($stageWhere))
            {
                $where .= " $stageWhere";
            }
            else
            {
                $where .= " $table.pid<>-1";
            }
            // return both, workspace and preview items
            $where .= " AND $table.t3ver_wsid IN (0,$wsId)";
            $where .= " AND $table.deleted=0";

            if (TYPO3_MODE == 'FE')
            {
                $where .= " AND $table.hidden=0";
            }
        }
        return $where;
    }
    /**
     * gets an array of the uid in actual workspace
     * http://www.schmutt.de/303/eigene-extension-mit-workspace-versionierung/
     * http://www.ausgebloggt.de/2011/02/10/typo3-extbase-workspace-vorschau/
     * http://typo3.org/documentation/document-library/core-documentation/doc_core_api/4.1.0/view/3/2/
     *
     * @param string $table
     * @param bool $returnPlaceholderUids default = false
     * @return array of integers -> uids in workspace
     *     Array keys are the original uids
     *     Array Values are the workspace uids
     */
    protected function getWorkspaceConstraint($table, $returnPlaceholderUids = false)
    {
        $queryString = array();
        $wsId = $this->getWsId();
        // do this search only one time per process
        if (empty(self::$idsInWorkspace[$table]))
        {//static
            $ids = array();
            //deleted,hidden,sichtbare version, workspace
            $where = $this->getWsClause($table);
            $queryResult = $GLOBALS['TYPO3_DB']->exec_SELECTquery("*", $table, $where);
            while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($queryResult))
            {
                // deletes row if it is no valid version
                if (TYPO3_MODE == 'BE')
                {
                    t3lib_BEfunc::workspaceOL($table, $row);
                }
                else
                {
                    $GLOBALS['TSFE']->sys_page->versionOL($table, $row, true);
                }
                if (is_array($row))
                { //get uid of workspace version
                    $ids[$row['uid']] = $row['uid'];
                }
            }
            self::$idsInWorkspace[$table] = $ids;
        }
        $idArray = self::$idsInWorkspace[$table];
        if (!$returnPlaceholderUids)
        {
            foreach ($idArray as $key => $value)
            {
                $idArray[$key] = $this->getWsUid($table, $value);
            }
        }
        if (!count($idArray))
        {
            $idArray = array(0);
        }
        return $idArray;
    }
    /**
     * returns uid of actual workspace
     * @param string $table
     * @param integer $uid
     * @param string $mode BE or FE
     * @return integer $uid
     */
    public function getWsUid($table, $uid, $mode = 'FE')
    {
        if ($this->isPreview() && TYPO3_MODE == $mode)
        {
            return t3lib_BEfunc::wsMapId($table, $uid);
        }
        return $uid;
    }
}
?>


Im erbenden Objekt können dann nach bedarf die entsprechenden uids geholt werden. Zum Beispiel:

function getMyrelation(){
  $q = $this->createQuery();
  $wsConstraint = $this->getWorkspaceConstraint('tx_myextension_domain_model_mymodelclass');
  if(!empty($wsConstraint)){
     $q->matching($q->in('uid',$wsConstraint));
  }
  return $q->execute();
}


Das sollte so gehen...







28.08.2011

Kleine Catering Seite für Mecklenburg-Vorpommern

Catering Mecklenburg-Vorpommern zu finden ist relativ einfach, ob das dann jedoch der jeweils beste Anbieter ist? Diese Seite verlinkt zwei Caterer aus Rostock, die meines Erachtens auch am leckersten sind. Der eine bietet Gourmet-Catering, der andere  mehr so die günstige und schnelle Partyservice-Variante für den schmalen Geldbeutel. Satt wird man allemal und das ganz ohne selbst zu kochen...


26.06.2011

Typo3 Zertifizierung

trotz Krankheit hab ich mich heute zur Prüfung für die Typo3 Zertifizierung geschleppt. War schon etwas aufregend alles, besonders weil ich mich vor Schnupfen und Husten kaum konzentrieren konnte. Nach dem Unterschreiben des NDA rund 90 min schwitzen das war alles und jetzt auf das Ergebnis warten. Der Prüfer meinte es dauert 'ewig' bis die Ergebnisse da sein werden, na hoffentlich leb ich dann noch :-) Ich kann nur jedem empfehlen, doch mal einen Blick vorher in das offizielle Buch für die Prüfung zu werfen. Ich war doch etwas erstaunt was da zum Teil für Fragen auftauchen...

27.02.2011

04.02.2011

Relaunch der Webseite ISS-Hamburg.de

Ein aktuelles Typo3-Projekt im etwas gößeren Umfang ist der Relaunch der Webseite iss-hamburg.de. Neben der Übernahme der Daten der alten Seite wurde das HTML bereinigt, so dass jetzt valides HTML und valides CSS zum Vorschein kommt. Auch kleinere Verbesserungen zur Suchmaschinen Optimierung (SEO) kamen zum Einsatz. Die Seite sollte demnächst besser in den Suchmaschinen ranken, mal schauen.



10.01.2011

Betreuung der Typo3 Seite von Essential Agency Models Berlin

Seit kurzem betreue ich die Typo3 Seite der Model- und Hostess Agentur Essential Agency. Die Seite ist recht schlicht vom Design und hat kleinere Spielereien mit Javascript und JQuery, wie z.B. das Bewerbungsformular zum Model Casting in der Berliner Agentur. Hauptaufgaben sind momentan die suchmaschinenfreundliche Umgestaltung (SEO) der Seite...

Technorati-Tags: , ,

06.01.2011

Powermail Error (No Rendering Definition)

Bei Typo3 & Powermail 1.5.7 wird ein Error angezeigt. Workaround / Bugfix:

Bei Powermail wird nur eine Fehlermeldung angezeigt:
ERROR: Content Element type "powermail_pi1" has no rendering definition!



Im Typoscript Template einfach die Zeile hinzufügen... Müsste so gehen.

tt_content.powermail_pi1 < plugin.tx_powermail_pi1

Siehe auch: Tim Schenk - Typo3 Programmierer Berlin - Powermail Bugfix

Technorati-Tags: ,