Jump to content

string replacement - on a complex scale (apparently?)


jamesmpollard
Go to solution Solved by QuickOldCar,

Recommended Posts

Hi Ladies & Gent's

 

I was wondering if someone could help. Basically I have built a small script that will take a template file - like this one:

<html>
    <head>
        <title>Test</title>
    </head>
    <body>
        <ul>
            <li>settings{name} - settings{value}</li>
            <li>settings{id} - settings{value} - settings{name}</li>
            <li>settings{value} - settings{name}</li>
            <li>members{name} - members{email}</li>
            <li>data{name} - data{email}</li>
            <li>data{test1} - data{test2}</li>
        </ul>
    </body>
</html>

And replace the tags. "data" stands is replaced with basic data tags and the rest are SQL tags, so settings{name} would indicate to ouput the column "name" from settings.

 

All is working except on thing that I have been trying everything to fix....

 

On line one we have this:

<li>settings{name} - settings{value}</li>

and on line two we have

<li>settings{id} - settings{value} - settings{name}</li>

All ouputs fine, except that because there isn't a request for an ID column on line one (which the ID would in this instance be 1 as it's the first row request), it places the ID in line two's ID column. So on the second row, for ID, it displays 1, when it should display 2.

 

Here is my source:

 

<?phpif (!defined('ND')) {    exit('Direct access to this file is not permitted.');} $template_name = 'template'; class template {     private $Contents;    private $DBTags;    private $DTTags;    private $TemplateName;     public function __construct() {            }     public function init($TemplateName) {        $this->TemplateName = $TemplateName;        $this->setTemplate();    }     public function addTag($key, $data) {        if ($key === 'data') {            $this->DTTags[$key] = $data;        } else {            $this->DBTags[$key] = $data;        }    }     private function setTemplate() {        if (file_exists('skins/default/templates/' . $this->TemplateName . '.tpl.php')) {            $this->Contents = file_get_contents('skins/default/templates/' . $this->TemplateName . '.tpl.php');        } else {            // ERROR HERE        }    }     private function replaceTags() {        foreach ($this->DBTags as $TagKey => $TagValue) {            for ($i = 0; $i < FrameworkRegistry::getObject('db')->SQLCacheResultCount($TagValue[1]); $i++) {                $Value = FrameworkRegistry::getObject('db')->resultsFromCache($TagValue[1]);                if (!empty($Value)) {                    $this->DBTags[$TagKey]['RESULTS'][] = $Value;                }            }        }         foreach ($this->DTTags as $DTagKey => $DTagValue) {            for ($e = 0; $e < FrameworkRegistry::getObject('db')->DataCacheResultCount(); $e++) {                $Value = FrameworkRegistry::getObject('db')->dataFromCache($e);                if (!empty($Value)) {                    $this->DTTags[$DTagKey]['RESULTS'][] = $Value;                }            }        }         $this->replaceDBTags();        $this->replaceDataTags();    }        private function RemoveCacheItem($Tag, $ID, $Item) {        unset($this->DBTags[$Tag]['RESULTS'][$ID][$Item]);    }     private function replaceDBTags() {        foreach ($this->DBTags as $DBKey => $DBValue) {            foreach ($DBValue['RESULTS'] as $DBVK => $DBVV) {                foreach ($DBVV as $NK => $NV) {                    $this->Contents = $this->str_replace_first($DBKey . '{' . $NK . '}', (string)$NV);                    $this->RemoveCacheItem($DBKey, $DBVK, $NK);                }            }        }    }     private function replaceDataTags() {        foreach($this->DTTags['data']['RESULTS'] as $DTKey => $DTValue) {            foreach($DTValue as $TK => $TV) {                $this->Contents = $this->str_replace_first('data{' . $TK . '}', $TV);            }        }    }     private function str_replace_first($search, $replace) {        $pos = strpos($this->Contents, $search);        if ($pos !== false) {            $this->Contents = substr_replace($this->Contents, $replace, $pos, strlen($search));        }        return $this->Contents;    }     public function Output() {        $this->replaceTags();         //echo '<pre>' . print_r($this->DTTags, true) . '</pre>';        return $this->Contents;    }     public function __destruct() {            } }

 
Is there anything I can do to stop this? As you can see I've tried writing a function to remove the result set after use so that it will allow it to move to the next one but this doesn't seem to work! All get's removed, but it still doesn't output right!
 
Any help appreciated here.
 
Many thanks
James
Link to comment
Share on other sites

Sorry, forgot to add. This is the output once ran:

				<html>
				<head>
				<title>Test</title>
				</head>
				<body>
				<ul>
				<li>skin - default</li>
				<li>1 - ATestSite - sitename</li>
				<li>test - atest</li>
				<li>James - test@test.test</li>
				<li>jamess - hi</li>
				<li>test11 - test22</li>
				</ul>
				</body>
				</html>

This is what it should be

<html>
                <head>
                <title>Test</title>
                </head>
                <body>
                <ul>
                <li>skin - default</li>
                <li>2 - ATestSite - sitename</li>
                <li>test - atest</li>
                <li>James - test@test.test</li>
                <li>jamess - hi</li>
                <li>test11 - test22</li>
                </ul>
                </body>
                </html>
Edited by jamesmpollard
Link to comment
Share on other sites

After reading this many times, it seems you have to check if id exists and handle it.

So pass an id tag and a value of 1 if not there or -1 the rest of id's

 

That last line confused me a bit lol.

 

This is a print out of my example array:

 

 

Array
(
[members] => Array
(
[0] => SQL
[1] => 0
[RESULTS] => Array
(
[0] => Array
(
[id] => 1
[name] => James
[email] => test@test.test
)

)

)

[settings] => Array
(
[0] => SQL
[1] => 1
[RESULTS] => Array
(
[0] => Array
(
[id] => 1
[name] => skin
[value] => default
)

[1] => Array
(
[id] => 2
[name] => sitename
[value] => ATestSite
)

[2] => Array
(
[id] => 3
[name] => atest
[value] => test
)

)

)

)
Link to comment
Share on other sites

Using the "settings" key as an example here.

 

What's happening is as it loop's through the system, on the first hit it find's settings{id} and replaces it with the first result set ID. When - if working right, it should be replacing it on the second hit because it's the second "request/line". I've tried making it so that the whole html is broken down line by line and processed that way but that's a massive nightmare and a benchmarking disaster

Link to comment
Share on other sites

  • Solution

Just an idea, instead of parsing line by line can't you do something like named blocks in your templates and let your code fill in the correct data as needed?

 

Is a matter of adding the data versus editing them.

Can do defines for included scripts or values, or add some unique naming to replace as doing now.

<html>
<head>
<title><?php echo TPL_TITLE;?></title>
</head>
<body>
<div>
<?php echo TPL_HEADER;?>
</div>
<div>
<?php echo TPL_CONTENT;?>
</div>
<div>
<?php echo TPL_SIDEBAR;?>
</div>
<div>
<?php echo TPL_FOOTER;?>
</div>
</body>
</html>
  • Like 1
Link to comment
Share on other sites

 

Just an idea, instead of parsing line by line can't you do something like named blocks in your templates and let your code fill in the correct data as needed?

 

Is a matter of adding the data versus editing them.

Can do defines for included scripts or values, or add some unique naming to replace as doing now.

<html>
<head>
<title><?php echo TPL_TITLE;?></title>
</head>
<body>
<div>
<?php echo TPL_HEADER;?>
</div>
<div>
<?php echo TPL_CONTENT;?>
</div>
<div>
<?php echo TPL_SIDEBAR;?>
</div>
<div>
<?php echo TPL_FOOTER;?>
</div>
</body>
</html>

That's almost what it's going to do when I'm finished, it will have a separate TPL for the header and footer and only really change the body TPL. But for ease of development, I'm trying to get it to parse all the data passed through it correctly which apparently is harder than I thought lol.

 

Basically once the first line (settings{name} & settings{value}) has been parsed, I need it to unset the first result set, then the second and so on. But because everything is dynamic (the results, the requests, etc) I can't set in stone the order, so it's a numbers game. So in essence I need to find a way for the script to go 

 

On this line - I need to replace 2 items for the first result set. 

Then the line after - I need to replace 3 items from the second result set and so on.

 

I was thinking about making it run through every line, gathering a list of replacements needed per line, then sorting them to the results set and str_replace'ing them all using arrays but that didn't seem to work well lol

Link to comment
Share on other sites

 

Just an idea, instead of parsing line by line can't you do something like named blocks in your templates and let your code fill in the correct data as needed?

 

Is a matter of adding the data versus editing them.

Can do defines for included scripts or values, or add some unique naming to replace as doing now.

<html>
<head>
<title><?php echo TPL_TITLE;?></title>
</head>
<body>
<div>
<?php echo TPL_HEADER;?>
</div>
<div>
<?php echo TPL_CONTENT;?>
</div>
<div>
<?php echo TPL_SIDEBAR;?>
</div>
<div>
<?php echo TPL_FOOTER;?>
</div>
</body>
</html>

Thank you for your help! I'm going to hit the reset button and start over!

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.