Finally I wrote a UserFunction that fulfills my needs. In this function I extend the given lookuptable function from realURL and fetch me the values yourself.
The model has been renamed in the meantime to activity.
I do now save the detail pid for the show action and the storage pid in the sport model so I can search the whole URL path to find place name and lookup the storage pid. With the storage pid of the place I can find the right activity. And with a correct lookup in the database I can return a valid ID.
For SEO reasons I added a new field URL to the model that contains the string in the URL path. In the id2alias method I return the url value of the activity with the given ID.
I noticed one behavior that realURL doesn't find the correct entry in the caching table once all the parameters are hashed, so I had to exclude the activity GETvar from cHash generation.
$GLOBALS['TYPO3_CONF_VARS']['FE']['cHashExcludedParameters'] = tx_myext_activity[activity]
After all this is my working setup :-)
RealURL config:
'GETvar' => 'tx_myext_activity[activity]',
'type' => 'user',
'languageGetVar' => 'L',
'languageField' => 'sys_language_uid',
'useUniqueCache' => 0,
'userFunc' => 'EXT:MyUserFunc.php:&MyUserFunc->main'
The UserFunction handles now the URL generation.
<?php
class MyUserFunc
{
protected $sys_language_uid;
protected $params;
protected $localizedStrings;
public function main($params, $ref)
{
if ($params) {
$this->params = $params;
$dirParts = $this->params['pObj']->dirParts;
//language
$this->sys_language_uid = 0;
//is realUrl in encode or decode
if ($this->params['decodeAlias']) {
return $this->alias2id($this->params['value']);
} else {
return $this->id2alias($this->params['value']);
}
}
}
/*
* Generate URL param
*/
protected function id2alias($value)
{
$sysLanguageToBuild = $this->params['pathParts'][0];
//if not default, use l10n_parent with sysuid
if ($sysLanguageToBuild > 0) {
$additionalWhere = ' AND l10n_parent = ' . (int)$value;
$additionalWhere .= ' AND sys_language_uid = ' . (int)$sysLanguageToBuild;
} else {
$additionalWhere = ' AND uid = ' . (int)$value;
}
$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
'url',
'tx_myext_domain_model_activity',
'deleted = 0 AND hidden = 0' . $additionalWhere
);
$activityRow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
if (is_array($activityRow)) {
return $activityRow['url'];
}
return 'undefined';
}
/**
* Decode string to uid
* respect activities with different pid
*
* @param $value
* @return int
*/
protected function alias2id($value)
{
$dirParts = $this->params['pObj']->dirParts; //get array of complete path
$place = htmlspecialchars($this->params['pObj']->dirParts[2]); //get place
//transform place string
$place = strtolower($place);
$place = preg_replace("/[^A-Za-z0-9\s-._\/]/", "", $place);
$place = trim(preg_replace("/[\s-]+/", " ", $place));
//Query Place
$placeRes = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
'uid, activity_storage_page',
'tx_myext_domain_model_place',
'deleted = 0 AND hidden = 0 AND sys_language_uid = '. $this->sys_language_uid .
' AND LOWER(name) = "' . $place . '"'
);
$placeRow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($placeRes);
//Query Activity
if (is_array($placeRow)) {
$additionalWhere .= " AND tx_myext_domain_model_activity.pid = '" . (int)$placeRow['activity_storage_page'] . "'";
}
$additionalWhere = " AND tx_myext_domain_model_activity.sys_language_uid = " . $this->sys_language_uid;
$additionalWhere .= " AND tx_myext_domain_model_activity.url = '" . $value . "'";
$additionalWhere .= " AND tx_myext_domain_model_activity.pid = '" . $pid . "'";
$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
'tx_myext_domain_model_activity.uid',
'tx_myext_domain_model_activity',
'deleted = 0 AND hidden = 0' . $additionalWhere
);
while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
return (int)$row['uid'];
}
//catch old URLs and return uid
$additionalWhere = " AND tx_myext_domain_model_activity.sys_language_uid = " . $this->sys_language_uid;
$additionalWhere .= " AND tx_myext_domain_model_activity.name = '" . $value . "'";
$resElse = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
'tx_myext_domain_model_activity.uid',
'tx_myext_domain_model_activity',
'deleted = 0 AND hidden = 0' . $additionalWhere
);
while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($resElse)) {
return (int)$row['uid'];
}
return false;
}
}