Zum Inhalt springen

Extension => TCA-Konfiguration => m:n-Beziehung => foreign_table_where => PID setzen

Erstellt am 13. Juni 2016 · 1 Antwort · letzte Antwort am 16. Juni 2016

Tags: TCA, tx_news, Frage

Typolisten ·

Hallo TYPO3-Extension-Entwickler,

aktuell arbeite ich an der Entwicklung einer Autoren-Extension (Extbase/Fluid), welche die news-Extension (G. Ringer) erweitert (die TYPO3-pages später auch). In einem TYPO3-Ordner (authors) können Autoren-Datensätze angelegt werden (Tabelle tx_authors_domain_model_author) sowie auch, wie bekannt, in einem Ordner die news-Datensätze (Tabelle tx_news_domain_model_news).

Durch eine Zwischentabelle (m:n-Beziehung) können auf beiden Seiten (news <=> authors) Datensätze zugeordnet, bearbeitet, erstellt und auch wieder gelöscht werden.

Einzelnen news können also ein oder mehrere Autoren-Datensätze zugeordnet werden, wie auch einzelne Autoren mit ein oder mehreren news-Datensätzen verbunden werden können. Die Autoren können dann dem/den news-Template/s hinzugefügt und formatiert ausgegeben werden. Zudem ist eine List- sowie Single-Ansicht der Autoren angedacht (sowie eine g**gle-Maps-Ansicht mit den einzelnen Standorten ...).

Zwei Screenshots zum besseren Verständnis:
Autoren
Bild: typolisten.de/…/beziehung_authors_news.jpg
(Grafik 1)

News
Bild: typolisten.de/…/beziehung_news_authors.jpg
(Grafik2)

Mein Problem:
In der TCA-Konfiguration (Feld related_news) für die tx_authors_domain_model_author-Tabelle:

...

'related_news' => array(
			'exclude' => 1,
			'l10n_mode' => 'mergeIfNotBlank',
			'label' => 'LLL:EXT:authors/Resources/Private/Language/locallang_db.xlf:tx_authors_domain_model_author.related_news',
			'config' => array(
				'type' => 'select',
				'renderType' => 'selectMultipleSideBySide',
				'foreign_table' => 'tx_news_domain_model_news',
				'MM' => 'tx_authors_author_news_mn',
				'foreign_table_where' => 'AND tx_news_domain_model_news.pid=78 ORDER BY tx_news_domain_model_news.title',
				'size' => 3,
				'autoSizeMax' => 30,
				'maxitems' => 99,
				'multiple' => 0,
				//'readOnly' => 1,
				'disableNoMatchingValueElement' => 1,

...

sowie die Override-TCA-Konfiguration (hinzugefügtes Feld tx_authors) für die tx_news_domain_model_news

...

$tempColumns = Array (
	'tx_authors' => array(
		'exclude' => 1,
		'l10n_mode' => 'mergeIfNotBlank',
		'label' => 'LLL:EXT:authors/Resources/Private/Language/locallang_db.xlf:tx_authors_domain_model_author.authors',
		'config' => array(
			'type' => 'select',
			'size' => 3,
			'autoSizeMax' => 10,
			'minitems' => 0,
			'maxitems' => 9999,
			'autoSizeMax' => 30,
			'multiple' => 0,
			'foreign_table' => 'tx_authors_domain_model_author',
			'MM' => 'tx_authors_author_news_mn',
			'MM_opposite_field' => 'related_news',
			'foreign_table_where' => 'AND tx_news_domain_model_news.pid=75 ORDER BY tx_authors_domain_model_author.last_name',

...

benötige ich einen Marker oder andere Möglichkeit (Globales Konfigurations-Array) um die PID (die 75 bzw. 78) in der 'foreign_table_where'-Klausel zu setzen, damit per typoscript-Konfiguration (Extension => setup.txt => settings) der jeweilige Ordner (PID) zugewiesen werden kann, wo sich die jeweiligen Datensätze befinden, die angezeigt werden sollen ... und nur die aus diesem Ordner. Ansonsten werden z.B. bei den news alle angezeigt, die sich in einer TYPO3-Installation befinden (da eine Tabelle ...).

Des Weiteren benötige ich diese PID-Zuweisung auch bei der Erstellung eines neuen Datensatzes. So kann z.B. in einem News-Datensatz direkt ein neuer Autoren-Datensatz angelegt werden (siehe Grafik 2 => +-Icon). Folgender, in der Override-TCA-Konfiguration hinzugefügte add-Code, ist dafür zuständig:

...

'add' => [
	'module' => [
		'name' => 'wizard_add',
	],
	'type' => 'script',
	'title' => 'Create new',
	'icon' => 'add.gif',
	'params' => [
		'table' => 'tx_authors_domain_model_author',
		'pid' => '###CURRENT_PID###',
		'setValue' => 'prepend'
	],
],
				

...

Hier sieht man sehr schön den Marker "###CURRENT_PID###", durch den die PID der aktuellen Seite bzw. des aktuellen Ordners hinzugefügt wird, in dem man sich gerade befindet. Dadurch würde aber ein im Ordner News erstellter Autor auch diesem Ordner zugeordnet werden bzw. dort gespeichert. Das möchte ich nicht, den alle Autoren haben ihren eigenen Ordner (als Workaround könnte ich durch einen Hook, der beim Speichern ausgeführt wird, in diesem Fall die per typoscript gesetzte PID umschreiben).

Bei dem zuvor aufgeführten Problem finde ich aktuell keine Lösung oder sehe den Wald vor Bäumen nicht.

Es gibt hier verschiedene Marker, die genutzt werden können (http://www.typo3lexikon.de/typo3-tutorials/core/tca/marker-in-flexforms.html), wobei es den ###STORAGE_PID###-Marker aktuell nicht mehr gibt (diesen hätte man schön in einem Zwischen-Template setzen können).

Kurz um: Ich möchte gerne in der TCA-Konfiguration einer Extension Werte aus den typoscript-settings einbringen.

Ich hoffe, ich habe mich einigermaßen verständlich ausgedrückt. Wie habt ihr dieses Problem gelöst bzw. wie würdet ihr die PID einfügen.

Vielen Dank im voraus!

TYPO3-Version: 7.6.4
(News-Version: 4.1.0)

Viele Grüße
Typolisten

Typolisten ·

Lösung:
Erstellung einer statischen Klasse (../Classes/Utility/ExtConfiguration.php) mit einer getSettings-Methode, wo die typoscript-Settings der Extension extrahiert werden.

use \TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;

/**
 * Typoscript configuration for authors extension
 */
class ExtConfiguration
{
	/**
     * Get authors extension typoscript settings and transfer to object (so we can work comfortable with getter)
     *
     * @return object
     */
    public static function getSettings()
    {
		// make instance ObjectManager
		$objectManager = GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
		
		// get ConfigurationManagerInterface
		$configurationManager = $objectManager->get('TYPO3\\CMS\\Extbase\\Configuration\\ConfigurationManagerInterface');
		
		// get typoscript configurations from all installed extensions
		$fullTyposcriptSettings = $configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT);	
		
		// extract authors' typoscript settings
		$txAuthorsTyposcriptSettings = $fullTyposcriptSettings['plugin.']['tx_authors.']['settings.'];		
		
		// include created DTO (data transfer object) model class (with getter for typoscript settings)
		GeneralUtility::requireOnce(ExtensionManagementUtility::extPath('authors') . 'Classes/Domain/Model/Dto/ExtConfiguration.php');	
		
		// create object with extracted settings from above
		$tsSettings = new \Typolisten\Authors\Domain\Model\Dto\ExtConfiguration($txAuthorsTyposcriptSettings);
		
		
		// return object with typoscript settings
        return $tsSettings;
	}
    
}

Erstellung eine Model-Klasse (DTO 0> data transfer object => ../Classes/Model/DTO/ExtConfiguration.php), die in der zuvor erstellten Klasse initialisiert wird und die extrahierten typoscript-Settings als Parameter übergeben bekommt, welche dann im Konstruktor der Klasse den Klassen-Attributen zugeführt wird.

/**
 * Typoscript configuration
 */
class ExtConfiguration
{

    /**
     * Fill the properties automatically
     *
     * @param array $configuration typoscript configuration
     */
    public function __construct(array $configuration)
    {
        foreach ($configuration as $key => $value) {
            if (property_exists(__CLASS__, $key)) {
                $this->$key = $value;
            }
        }
    }

    /**
     * @var int
     */
    protected $newsPid = 0;
   
    :::

    /**
     * @return int
     */
    public function getNewsPid()
    {
        return intVal($this->newsPid);
    }

    :::
}

Die getSettings-Methode der statischen Klasse gibt dieses Object dann als return-Wert zurück.

Die statische Klasse kann dann komfortabel im TCA aufgerufen werden:

// Extension typoscript configuration
$configuration = \Vendor\Name\Utility\ExtConfiguration::getSettings();

und die benötigten Werte stehen zur Verfügung (getter).

:::

'foreign_table_where' => 'AND tx_news_domain_model_news.pid='.$configuration->getNewsPid().' ORDER BY tx_news_domain_model_news.title',

:::

Ein Blick in die news-Extension erklärt alles. An dieser Stelle vielen Dank an Herrn Ringer!

Viele Grüße
Typolisten