Project

General

Profile

Actions

Bug #15752

closed

Faster "substituteConstants"

Added by old_hkdennis2k over 18 years ago. Updated over 18 years ago.

Status:
Closed
Priority:
Should have
Category:
Communication
Target version:
-
Start date:
2006-03-02
Due date:
% Done:

0%

Estimated time:
TYPO3 Version:
4.0
PHP Version:
5
Tags:
Complexity:
Is Regression:
Sprint Focus:

Description

"substituteConstants" for typoscript is using loop and str_replace, which has a poor performance. O(M x N).
Neither longer typoscript setup or one more constants(even not used) will increase processing time a lot.

By replacing it into preg_replace_callback, it can finish the job with only 20% of time.

class.t3lib_TStemplate.php
---- 1.27.2.1 on CVS ----
function substituteConstants($all) {
if ($this->tt_track) $GLOBALS['TT']->setTSlogMessage('Constants to substitute: '.count($this->flatSetup));
reset($this->flatSetup);
while (list($const,$val)=each($this->flatSetup)) {
if (!is_array($val)) {
$all = str_replace('{$'.$const.'}',$val,$all);
}
}
return $all;
}
---- modified ----
function substituteConstantsCallBack($matches) {
return isset ($this->flatSetup[$matches1]) ? $this->flatSetup[$matches1] : $matches0;
}
function substituteConstants($all) {
if ($this->tt_track)
$GLOBALS['TT']->setTSlogMessage('Constants to substitute: '.count($this->flatSetup));
return preg_replace_callback('/\{\$(.+?)\}/', array ($this, 'substituteConstantsCallBack'), $all);
}

(issue imported from #M2743)


Files

bug2743_followup.diff (967 Bytes) bug2743_followup.diff Administrator Admin, 2006-03-11 13:30

Related issues 1 (0 open1 closed)

Related to TYPO3 Core - Bug #72413: constants replacing in TSOBRejected2015-12-23

Actions
Actions #1

Updated by Wolfgang Klinger over 18 years ago

That's true for this method but not for the similar method in tsparser_ext (you didn't mention here), so I will only change the method in t3lib_tstemplate

(don't ask me why)

Actions #2

Updated by old_hkdennis2k over 18 years ago

I think the same logic can be apply into substituteConstants in tsparser_ext
You just have to wrote two more different callback.

Beside, Why put the switch in the loop??
put it outside the loop can be faster.
(i.e. It still do loop on the flatSetup even "untouched")
----
function substituteConstantsConstCallBack($matches) {
if(isset ($this->flatSetup[$matches1])){
return '##'.$this->Cmarker.'_B##{$'.$matches0.'}##'.$this->Cmarker.'_E##';
}else{
return $matches0;
}
}
function substituteConstantsSubstCallBack($matches) {
if(isset ($this->flatSetup[$matches1])){
return '##'.$this->Cmarker.'_B##{$'.$this->flatSetup[$matches1].'}##'.$this->Cmarker.'_E##';
}else{
return $matches0;
}
}
function substituteConstantsCallBack($matches) {
return isset ($this->flatSetup[$matches1]) ? $this->flatSetup[$matches1] : $matches0;
}
function substituteConstants($all) {
switch($this->constantMode) {
case 'untouched':
return all;
case 'const':
$this->Cmarker=substr(md5(uniqid("")),0,6);
return preg_replace_callback('/\{\$(.+?)\}/', array ($this, 'substituteConstantsConstCallBack'), $all);
case 'subst':
$this->Cmarker=substr(md5(uniqid("")),0,6);
return preg_replace_callback('/\{\$(.+?)\}/', array ($this, 'substituteConstantsSubstCallBack'), $all);
default:
return preg_replace_callback('/\{\$(.+?)\}/', array ($this, 'substituteConstantsCallBack'), $all);
}
}

function substituteCMarkers($all)    {
switch($this->constantMode) {
case 'const':
case 'subst':
$all = str_replace(
array('##'.$this->Cmarker.'_B##','##'.$this->Cmarker.'_E##'),
array('<font color="green"><B>','</b></font>'),
$all);
default:
}
return $all;
}
Actions #3

Updated by Wolfgang Klinger over 18 years ago

I found a bug in my test code, sorry, I'll post it ASAP to the core list.

Actions #4

Updated by Wolfgang Klinger over 18 years ago

fixed in CVS

Actions #5

Updated by Stanislas Rolland over 18 years ago

When CVS version 1.27.2.2 is used as in TYPO3 4.0RC1, constants are not correctly replaced.

In the case I encountered, constants assigned to other constants are not correctly replaced.

Reverting to 1.27.2.1 corrects the problem.

Actions #6

Updated by old_hkdennis2k over 18 years ago

In the case I encountered, constants assigned to other constants are not correctly replaced.

In fact, the old substituteConstants was not correctly replaced too.

The "constants assigned to other constants" should be resloved and report error for any recursive loop.

I forget I did modified some where else, and make it reslove "constants assigned to other constants" at constant parse time. ( It does make sense and faster)

-----
What SHOULD the ideal final value in the folloing example?

$abc=abc
$useabc={$abc}
$abc=def

$x=x
$y=y
$xyz=${x}${y}${z}
$z=z

$inner=inner
$inner2=inner2
$outer={${$inner}2}

Actions #7

Updated by Wolfgang Klinger over 18 years ago

I'll take a look at it asap

Actions #8

Updated by Wolfgang Klinger over 18 years ago

Please test the attached patch (bug2743_followup.diff), this should fix the issue with constants in constants.

I'll commit it to CVS if no one complains.

Actions #9

Updated by Michael Stucki over 18 years ago

Patch looks good to me, but please add some comments that explain why you are going three times over the loop (I suppose this is just an assumption?)

Actions #10

Updated by Wolfgang Klinger over 18 years ago

That's just a reasonable value, I don't think that anybody out there will ever cascade more than 3 levels of constants;
this is possible now:

TEST4 = Kaviar
TEST3 = Bananen, aber keinen {$TEST4}
TEST1 = Affen {$TEST2}
TEST2 = essen gerne {$TEST3}

this will output

Affen essen gerne Bananen, aber keinen {$TEST4}

We can easily increase to let's say 5 as the loop will end if there's no further substitution possible anyway...

btw: prior to this patch the following is not possible:

TEST2 = Test
TEST1 = das ist ein {$TEST2}

this will output
das ist ein {$TEST2}

while this:

TEST1 = das ist ein {$TEST2}
TEST2 = Test

gives the correct result:
das ist ein Test

so this "issue" is gone now too!

Actions #11

Updated by Wolfgang Klinger over 18 years ago

@hkdennis2k:

-------------------------
abc=abc
useabc={$abc}
abc=def

page.500 = TEXT
page.500.value = {$useabc} 

Output: def
-------------------------
x=x
y=y
xyz={$x}{$y}{$z}
z=z

page.500 = TEXT
page.500.value = {$xyz} 

Output: xyz
-------------------------
inner=inner
inner2=inner2
outer={${$inner}2}

page.500 = TEXT
page.500.value = {$outer} 

Output: {${$inner}2}
-------------------------

so the last one will not work (and did not before)

Actions #12

Updated by Michael Stucki over 18 years ago

I suggest you set the loop limit to 99 then so we will definitely never have any problems.

Please commit the patch to CVS so it is fixed there, but send a copy of the patch to the core list for information.

Thanks for providing a solution so quickly!

Actions #13

Updated by Wolfgang Klinger over 18 years ago

fixed in CVS, please update,

I set the limit to 10, that should really be enough and make no problems if there's a hidden recursion somewhere
(e.g.

TEST2 = Hello {$TEST2}
)

Actions

Also available in: Atom PDF