TYPO3 8.7.27
RealURL 2.5.0
English (id-0) and French (id=1) Multi Language Site
No matter what I do, RealURL keeps adding ?L=0 or ?L=1 to the end of every URL instead of actually creating real URLs. That is, I'm getting
www.domain.com/page1/?L=0
instead of
www.domain.com/en/page1
I've tried turning autoconf on and off, and I've read every piece of documentation out there, specifically Dmitry's own https://github.com/dmitryd/typo3-realurl/wiki/Notes-for-Integrators#configuring-languages
Here is the entire contents of /typo3conf/realurl_conf.php:
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['realurl']['_DEFAULT']['preVars'] => array(
array(
'GETvar' => 'L',
'valueMap' => array(
'en' => 0,
'fr' => 1,
),
'valueDefault' => 'en',
'noMatch' => 'bypass',
),
);
... and here is the relevent TypoScript:
config {
baseURL = {$BASE_URL}
absRefPrefix = {$BASE_URL}
tx_realurl_enable = 1
simulateStaticDocuments = 0
#linkVars = L(int)
sys_language_uid = 0
language = en
locale_all = en_US.UTF-8
htmlTag_langKey = en
#htmlTag_setParams = lang="en" dir="ltr" class="no-js"
linkVars = L
uniqueLinkVars=1
sys_language_mode = content_fallback
sys_language_overlay = 1
defaultGetVars {
L = 0
}
}
[globalVar = GP:L = 1]
config {
sys_language_uid = 1
language = fr
locale_all = fr_FR.UTF-8
htmlTag_langKey = fr
#htmlTag_setParams = lang="fr" dir="ltr" class="no-js"
}
[global]
page.19.variables.LANGUAGE = HMENU
page.19.variables.LANGUAGE {
special = language
special.value = 1,0
1 = TMENU
1 {
wrap = <ul id="language"> | </ul>
NO = 1
NO {
wrapItemAndSub = <li> | </li>
stdWrap.override = FR || EN
}
ACT < .NO
ACT {
ATagParams = class="active"
}
}
}
As an examnple, if I click on "page1" in the menu, I'm taken to:
www.domain.com/page1/?L=0 (which confirms that realURL is working, but also indicates something is wrong)
I'm expecting, when I click on "page1" in the menu, I get taken to:
www.domain.com/en/page1
Can anyone help me turn the "stuck" postVar into a proper preVar?
Thank you very much in advance for any help you can provide!!!
EDIT/UPDATE 1: Thanks to Heinz, I now have www.domain.com/fr/page1 but ONLY if I manually enter it - it doesn't work automatically through menus, etc.
EDIT/UPDATE 2: I modified realurl_conf.php as follows (added the full code + encode at bottom) to get auto generation (see below) but now it's always adding ?L to the end. That is, result is always www.domain.com/fr/page1/?L=1 when it should be www.domain.com/fr/page1
<?php
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['realurl']['_DEFAULT']= array (
'fixedPostVars' => array (
),
'pagePath' => array (
'type' => 'user',
'userFunc' => 'EXT:realurl/class.tx_realurl_advanced.php:&tx_realurl_advanced->main',
'spaceCharacter' => '-',
'languageGetVar' => 'L',
'rootpage_id' => '1'
),
'init' =>
array (
'appendMissingSlash' => 'ifNotFile,redirect',
'emptyUrlReturnValue' => '/',
),
'pagePath' =>
array (
'rootpage_id' => '1',
),
'fileName' =>
array (
'defaultToHTMLsuffixOnPrev' => 0,
'acceptHTMLsuffix' => 1,
'index' =>
array (
'print' =>
array (
'keyValues' =>
array (
'type' => 98,
),
),
),
),
'preVars' =>
array (
0 =>
array (
'GETvar' => 'L',
'valueMap' =>
array (
'en' => '0',
'fr' => '1',
),
/*'valueDefault' => 'en',
'noMatch' => 'bypass',*/
),
),
'postVarSets' =>
array (
'_DEFAULT' =>
array (
'news' =>
array (
0 =>
array (
'GETvar' => 'tx_news_pi1[news]',
'lookUpTable' =>
array (
'table' => 'tx_news_domain_model_news',
'id_field' => 'uid',
'alias_field' => 'IF(path_segment!="",path_segment,title)',
'addWhereClause' => ' AND NOT deleted',
'useUniqueCache' => 1,
'expireDays' => 180,
'enable404forInvalidAlias' => true,
),
),
),
),
),
);
$TYPO3_CONF_VARS['EXTCONF']['realurl']['_DOMAINS'] = array(
'encode' => array(
array(
'GETvar' => 'L',
'value' => '0', // en
'useConfiguration' => '_DEFAULT',
'urlPrepend' => '/en/'
),
array(
'GETvar' => 'L',
'value' => '1', // fr
'useConfiguration' => '_DEFAULT',
'urlPrepend' => '/fr/'
),
),
);
EDIT/UPDATE 3: If I do an .htaccess hack, I can get /en and /fr ... but it's ugly:
# Remove trailing ?L GET parameter from RealURL
RewriteCond %{QUERY_STRING} ^L=0$ [NC]
RewriteRule ^(.*)$ https://cmhw.stormiscoming.ca/en/$1? [R=301,L]
RewriteCond %{QUERY_STRING} ^L=1$ [NC]
RewriteRule ^(.*)$ https://cmhw.stormiscoming.ca/fr/$1? [R=301,L]
Some of your config are not needed anymore or does nothing. This should work:
<?php
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['realurl']['_DEFAULT'] = array (
'init' => array (
'appendMissingSlash' => 'ifNotFile,redirect',
'emptyUrlReturnValue' => 1,
),
'preVars' => array (
array (
'GETvar' => 'L',
'valueMap' => array (
'en' => '0',
'fr' => '1',
),
),
),
'pagePath' => array (
'rootpage_id' => '1'
),
'fixedPostVars' => array (
),
'fileName' => array(),
'postVarSets' => array(
'_DEFAULT' => array (
'news' => array (
array (
'GETvar' => 'tx_news_pi1[news]',
'lookUpTable' => array (
'table' => 'tx_news_domain_model_news',
'id_field' => 'uid',
'alias_field' => 'IF(path_segment!="",path_segment,title)',
'addWhereClause' => ' AND NOT deleted',
'useUniqueCache' => 1,
'expireDays' => 180,
'enable404forInvalidAlias' => true,
),
),
),
),
),
);
I'm trying to get videos from my channel using search function. Response include only nextPageToken, but no prevPageToken. prevPageToken is null always, even if I'm listing other pages using nextPageToken. I use an access_token param from Google Oauth.
My request:
$searchResponse = $youtube->search->listSearch('snippet', array(
'forMine' => 'true',
'order' => 'date',
'pageToken' => $pageToken,
'type'=>'video',
'maxResults' => '10',
'q' => $searchQuery,
));
Result:
Google_Service_YouTube_SearchListResponse Object
(
[collection_key:protected] => items
[etag] => "XXX"
[eventId] =>
[itemsType:protected] => Google_Service_YouTube_SearchResult
[itemsDataType:protected] => array
[kind] => youtube#searchListResponse
[nextPageToken] => Cib3-ZrgSf____9uWHdEYVNIVnlOVQD_Af_-blh3RGFTSFZ5TlUAARAPIbmtEhE6-iWlOQAAAAC2H2UGSAFQAFoLCdIYcGeU2-YsEAJgyOjNygE=
[pageInfoType:protected] => Google_Service_YouTube_PageInfo
[pageInfoDataType:protected] =>
[prevPageToken] =>
[regionCode] =>
[tokenPaginationType:protected] => Google_Service_YouTube_TokenPagination
[tokenPaginationDataType:protected] =>
[visitorId] =>
[internal_gapi_mappings:protected] => Array
(
)
[modelData:protected] => Array
(
)
[processed:protected] => Array
(
)
[pageInfo] => Google_Service_YouTube_PageInfo Object
(
[resultsPerPage] => 5
[totalResults] => 55
[internal_gapi_mappings:protected] => Array
(
)
[modelData:protected] => Array
(
)
[processed:protected] => Array
(
)
)
Thank you for your ideas!
Petr
UPDATE
This problem is only if is set param forMine. But I need show only my videos...
I am getting array data from a function ReportsController::getStudentYearwiseAvgHeightsProvince() in the below format:
Array ( [0] => Array ( [name] => Baluchistan [data] => Array ( [0] => 0 [1] => 0 [2] => 0 [3] => 0 [4] => 0 [5] => 0 [6] => 0 ) ) [1] => Array ( [name] => KPK [data] => Array ( [0] => 56 [1] => 58 [2] => 58 [3] => 0 [4] => 0 [5] => 0 [6] => 60 ) ) [2] => Array ( [name] => Punjab [data] => Array ( [0] => 0 [1] => 0 [2] => 0 [3] => 78 [4] => 90 [5] => 90 [6] => 0 ) ) [3] => Array ( [name] => Sindh [data] => Array ( [0] => 0 [1] => 0 [2] => 0 [3] => 0 [4] => 0 [5] => 0 [6] => 0 ) ) )
ReportsController::getStudentYearwiseAvgHeightsProvince() function is:
public function getStudentYearwiseAvgHeightsProvince() {
$result = Yii::$app->db->createCommand ( '
SELECT temp.name AS name,
GROUP_CONCAT(IFNULL(temp.height,0) order by year) AS data
FROM ( SELECT years.year AS year, p.name AS NAME, FLOOR(AVG(sd.height)) AS height
FROM (
SELECT DISTINCT year FROM student_detail ORDER BY year
) years
cross join province p
left join student_detail sd on years.year = sd.year and sd.province_id = p.id
GROUP BY years.year, p.name
ORDER BY years.year )
AS temp
GROUP BY name; ' )->queryAll ();
$i = 0;
foreach ($result as $innerArray) {
$result[$i]['data'] = explode(",", $result[$i]['data']);
//$result[$i]['name'] = $innerArray['name'];
$i++;
}
//$result = array_map(function($var){ return (int) $var['data']; }, $result); // extraction from 2 level associative arry to 1-d associative array
print_r ( $result );
return $result;
}
and I am setting highcharts component as follows:
echo Highcharts::widget([
'scripts' => [
'modules/exporting',
'themes/grid-light',
],
'options' => [
'title' => ['text' => 'Student Province-wise Yearly Avg Heights'],
'plotOptions' => [
'column' => [
'depth' => 25
]
],
'xAxis' => [
'categories' => ReportsController::getDistinctCols("student_detail", "year")
],
'yAxis' => [
'min' => 0,
'title' => ['text' => 'Avg Height']
],
'series' =>
ReportsController::getStudentYearwiseAvgHeightsProvince()
]
]);
No graph is generated :(
I fixed the graph not showing issue by just converting the STRING ARRAY to INTEGER ARRAY which is returned by EXPLODE in my function getStudentYearwiseAvgHeightsProvince()
by editing the code inside FOREACH LOOP as:
foreach ($result as $innerArray) {
$result[$i]['data'] = explode(",", $result[$i]['data']);
$temp = array();
foreach ($result[$i]['data'] AS $index => $value)
$temp[$index] = (int)$value;
$result[$i]['data'] = $temp;
$i++;
}
I've changed around the path structure for HybridAuth quite a bit, all of the HybridAuth files are in a login directory.
require_once('login/Auth.php');
$auth = new Hybrid_Auth(self::$settings['auth']);
Where self::$settings['auth'] is this json file
{
"debug": 1,
"database": {
"driver": "mysql",
"host": "localhost",
"port": 3306,
"name": "ws_db",
"username": "root",
"password": "",
"charset": "utf8"
},
"auth": {
"base_url": "http://localhost/login/process",
"providers": {
"Twitter": {
"enabled": true
},
"Google": {
"enabled": true,
"keys": {
"id": "",
"secret": ""
}
},
"Facebook": {
"enabled": true,
"keys": {
"id": "",
"secret": ""
},
"trustForwarded": false
},
"Steam": {
"enabled": true
}
},
"debug_mode": true,
"debug_file": "auth.txt"
}
}
I have not yet acquired keys for the providers I intended to use (is that possibly why this is happening?). I tried to login with Steam to test that it was working since it was the only provider that didn't require me to get keys.
$_SESSION['user'] = $auth->authenticate('Steam');
I was correctly redirected to a Steam login page however upon clicking Login I received the above error.
Fatal error: Uncaught exception 'Exception' with message 'Serialization of 'SimpleXMLElement' is not allowed' in login\Auth.php:153 Stack trace: #0 login\Auth.php(39): Hybrid_Auth::initialize(Array) #1 index.php(83): Hybrid_Auth->__construct(Array) #2 index.php(6): Site::main() #3 {main} thrown in login\Auth.php on line 153
I thought it possibly had something to do with this line:
Hybrid_Logger::debug( "Hybrid_Auth initialize. dump used config: ", serialize( $config ) );
because that is the only line that I see serializing something but commenting that out didn't seem to work. Line 83 in my index.php is the initialization of Hybrid_Auth.
$auth = new Hybrid_Auth(self::$settings['auth']);
I can't seem to figure out what is going wrong with this though. Since that line of code is run when attempting to login and only causes a problem when returning from the Steam authorization page.
Here is the information that was output into auth.txt, I removed some information.
(
[message:protected] => Serialization of 'SimpleXMLElement' is not allowed
[string:Exception:private] =>
[code:protected] => 0
[file:protected] => login\Storage.php
[line:protected] => 73
[trace:Exception:private] => Array
(
[0] => Array
(
[file] => login\Storage.php
[line] => 73
[function] => serialize
[args] => Array
(
[0] => Hybrid_User Object
(
[providerId] => Steam
[timestamp] => 1431707732
[profile] => Hybrid_User_Profile Object
(
[identifier] => ***************
[webSiteURL] =>
[profileURL] => http://steamcommunity.com/id/******/
[photoURL] =>
[displayName] => Renari
[description] => <span>profile information was here</span>
[firstName] => SimpleXMLElement Object
(
[0] => SimpleXMLElement Object
(
)
)
[lastName] =>
[gender] =>
[language] =>
[age] =>
[birthDay] =>
[birthMonth] =>
[birthYear] =>
[email] =>
[emailVerified] =>
[phone] =>
[address] =>
[country] =>
[region] => location information was here
[city] =>
[zip] =>
)
)
)
)
[1] => Array
(
[file] => login\Providers\Steam.php
[line] => 37
[function] => set
[class] => Hybrid_Storage
[type] => ->
[args] => Array
(
[0] => hauth_session.Steam.user
[1] => Hybrid_User Object
(
[providerId] => Steam
[timestamp] => 1431707732
[profile] => Hybrid_User_Profile Object
(
[identifier] => ***************
[webSiteURL] =>
[profileURL] => http://steamcommunity.com/id/******/
[photoURL] =>
[displayName] => ******
[description] => <span>profile information was here</span>
[firstName] => SimpleXMLElement Object
(
[0] => SimpleXMLElement Object
(
)
)
[lastName] =>
[gender] =>
[language] =>
[age] =>
[birthDay] =>
[birthMonth] =>
[birthYear] =>
[email] =>
[emailVerified] =>
[phone] =>
[address] =>
[country] =>
[region] => location information was here
[city] =>
[zip] =>
)
)
)
)
[2] => Array
(
[file] => login\Endpoint.php
[line] => 182
[function] => loginFinish
[class] => Hybrid_Providers_Steam
[type] => ->
[args] => Array
(
)
)
[3] => Array
(
[file] => login\Endpoint.php
[line] => 55
[function] => processAuthDone
[class] => Hybrid_Endpoint
[type] => ->
[args] => Array
(
)
)
[4] => Array
(
[file] => login\Endpoint.php
[line] => 71
[function] => __construct
[class] => Hybrid_Endpoint
[type] => ->
[args] => Array
(
[0] =>
)
)
[5] => Array
(
[file] => index.php
[line] => 90
[function] => process
[class] => Hybrid_Endpoint
[type] => ::
[args] => Array
(
)
)
[6] => Array
(
[file] => index.php
[line] => 6
[function] => main
[class] => Site
[type] => ::
[args] => Array
(
)
)
)
[previous:Exception:private] =>
)
This was an issue with the Steam provider and was fixed in a commit you can download the fixed steam provider from the github repo.
Below is the data I'm getting from wsdl response... I need to get the separate value for example how to get the firstname from this array...Please anyone help me...
GetReportResponse Object ( [GetReportResult] => MBPeopleSearchRs_Type Object ( [MsgRsHdr] => MsgRsHdr_Type Object ( [RqUID] => {4DB2AD23-228A-465F-938D-BE072CED61C4} [Status] => Status_Type Object ( [StatusCode] => 0 [ServerStatusCode] => [Severity] => Info [StatusDesc] => OK [AdditionalStatus] => ) ) [Subject] => Subject Object ( [RefNum] => [PersonInfo] => PersonInfo_Type Object ( [PersonName] => PersonName_Type Object ( [LastName] => JANARDHANAN [FirstName] => SENTHINBABU [FullName] => [MiddleName] => [TitlePrefix] => [NameSuffix] => [Nickname] => [LegalName] => [MaidenName] => [OfficialTitle] => [Source] => MB [EffDt] => 2013-05-24 ) [ContactInfo] => ContactInfo_Type Object ( [ContactPref] => [PhoneNum] => [ContactName] => [EmailAddr] => [URL] => [PostAddr] => PostAddr_Type Object ( [PreDirection] => [Addr2] => [PostDirection] => N [Addr3] => [StreetType] => AVE [Addr4] => [StreetName] => LEXINGTON [Apt] => APT 4203 [StreetNum] => 4150 [Addr1] => [City] => SAINT PAUL [StateProv] => MN [PostalCode] => 55126-6131 [County] => RAMSEY
I suggest using a framework for this. CXF is a good choice if you write Java.
http://cxf.apache.org/
edit: since you work with php, take a look here: PHP SOAP client Tutorial/Recommendation?