gijew Posted June 8, 2009 Share Posted June 8, 2009 I'm writing a class to help automate all of the cron jobs I run at work and integrated a small template system. It worked well until I tried to integrate a few "other" features, this happens. The template variables are formatted like Smarty (because I already use Smarty so I figured it would be easier for me to remember). Ex: {$variable|capitalize} Now, since I don't feel like typing out a bunch of database fields and assigning them like Smarty ($smarty->assign('name', $var) - which I would have to do the Smarty way) it loops through an array of database fields. What I'm thinking it should be doing (which it does not do) is replace the variable {$loan_type} with the database field `loan_type`. It would also parse the template variable to see if there is any special formatting or instructions like in this example {$loan_type|capitalize} and capitalize it. So, an example of what it actually does... Example (using 3 records) Database rows `loan_type | data: purchase` `loan_amount | data: 850000` `cltv | data: 88` Template `{$loan_type|capitalize}` `{$loan_amount|currency}` `{$cltv|percentage}` Expected output `Purchase` `$850,000` `88%` Here's a bit of code to work with (only throwing this one out because it was much simplier approach than my first time out). This one is totally broken and I'm at my wits end here so sorry if it's effed up. <?php /* Example of what is being returned from mysql - (mysql): SELECT loan_type,loan_amount,cltv FROM form_loan_scenarios WHERE emailed = 0 ORDER BY date_submitted desc */ public function process_cronjob() { $sql = $this->db->GetAll(" SELECT " . $this->db_rows . " FROM " . $this->db_table . " " . $this->db_join_table . " " . $this->db_join_table_on . " " . $this->db_criteria . " " . $this->db_sort . " " . $this->db_limit . " "); if (count($sql) != 0) { $counter = -1; $db_rows = explode(',', $this->db_rows); $mailer_template = file_get_contents($this->mailer_template); foreach ($sql as $r) { $counter++; for ($f = 0; $f <= $this->db_row_count - 1; $f++) { $output = $this->helpers(str_replace($db_rows[$f], $r[$f], $mailer_template)); } echo $output; echo '<hr />'; } } } private function helpers($t) { if (preg_match('/({\$)([a-z0-9_]+)[(|)]?([a-z]+)(})/', $t, $matches)) { $split_matches = explode('|', $matches[0]); $data = $split_matches[0]; $format = $split_matches[1]; switch ($format) { case 'capitalize'; if (!empty($data)) $replace = ucwords(strtolower($data)); break; case 'percentage'; if (!empty($data)) $replace = number_format($data, 0) . '%'; break; case 'currency'; if (!empty($data)) $replace = $this->readable_number($data); break; } return str_replace($matches[0], $replace, $t } } /* Outputs: Loan Type [nothing] Loan amount {$loan_amount|currency} CLTV {$cltv|percentage} */ ?> Quote Link to comment https://forums.phpfreaks.com/topic/161422-solved-oo-template-variables-whelpers/ Share on other sites More sharing options...
RussellReal Posted June 8, 2009 Share Posted June 8, 2009 just use str replace foreach ($row as $k => $v) { str_replace('{'.$k.'}',$v,$data); } if you want to add those 'flags' in you might want to use substr and strpos to look for { and then get the rest to } remove the { } in the variable and then explode by | and then loop thru the parameters, or just pass it to a function which expects the parameters ion the order they were expecting them, either way its doable. Quote Link to comment https://forums.phpfreaks.com/topic/161422-solved-oo-template-variables-whelpers/#findComment-851948 Share on other sites More sharing options...
gijew Posted June 8, 2009 Author Share Posted June 8, 2009 I thought about the str_replace, strpos and what not but I was having trouble coming up with a solution that would allow me to wildcard the string (like regex allows for). Using the approach you suggested (albeit probably not the best implementation on my part) only lets me retrieve / match the first part but I have no other way of knowing ahead of time what the format type should be as it's stored in the template, which I must read first. I think I just went cross-eyed. <?php foreach ($sql as $k => $v) { for ($f = 0; $f <= $this->db_row_count - 1; $f++) { if (!empty($v[$f])) { $string1 = $db_rows[$f]; $pos1 = stripos($mailer_template, $string1); if ($pos1 !== false) { $word = substr($mailer_template, $pos1, strlen($string1)); echo str_replace($word, $v[$f], $word) . '<br />'; } } else { echo 'empty <br>'; } } echo '<hr />'; } ?> Quote Link to comment https://forums.phpfreaks.com/topic/161422-solved-oo-template-variables-whelpers/#findComment-851969 Share on other sites More sharing options...
gevans Posted June 9, 2009 Share Posted June 9, 2009 Dunno if this is exactly what you want, but I fancied playing anyway; <?php /** * The functions you want to use * I've made three cheap and chearful ones * To fit your OP */ function capitalize($value) { return ucfirst($value); } function currency($value) { return '$' . number_format($value); } function percentage($value) { return $value."%"; } /** * Emulate your sql results * Should make sense */ $data = array( "loan_type" => "purchase", "loan_amount" => "850000", "cltv" => "88" ); /** * Test Content * This would be your template */ $content = 'The details<br /> Loan Type: {$loan_type|capitalize}<br /> Loam Amount: {$loan_amount|currency}<br /> CLTV: {$cltv|percentage}'; //Loop through each field of the returned table (array for me) foreach($data as $k => $v) { //regex pattern to find the temp string $pattern = '#{\$'.$k.'\|[a-z]+}#'; preg_match($pattern, $content, $matches); $match = $matches[0]; //get just the function you want to run $func_array = explode("|", $match); $func = str_replace("}", "", $func_array[1]); //run the function on the data (if it exists) if(function_exists($func)) { $value = $func($v); }//you may want a fallback here //replace the temp string with your formatted content $content = str_replace($match, $value, $content); } echo $content; Quote Link to comment https://forums.phpfreaks.com/topic/161422-solved-oo-template-variables-whelpers/#findComment-851989 Share on other sites More sharing options...
gijew Posted June 9, 2009 Author Share Posted June 9, 2009 SO CLOSE! That's almost exactly right except... Now all the variables are switching out correctly and the helpers are being applied BUT now they aren't switching out with the template. Example time... <?php if (count($sql) != 0) { $counter = -1; $db_rows = explode(',', $this->db_rows); $mailer_template = file_get_contents($this->mailer_template); foreach($sql as $k => $v) { for ($f = 0; $f <= $this->db_row_count - 1; $f++) { $pattern = '#{\$' . $db_rows[$f] . '\|[a-zA-Z0-9\=\-\_\: ]+}#'; preg_match($pattern, $mailer_template, $matches); $match = $matches[0]; if (!empty($match)) { $split = explode('|', $match); $data = str_replace('{$', '', $split[0]); $format = str_replace('}', '', $split[1]); $helper = $this->helpers($v[$f], $format); echo $data . ' | ' . $format . ' | ' . $helper . '<br />'; $content = str_replace($match, $helper, $mailer_template); } } echo $content; echo '<hr />'; } } ?> That outputs the following: loan_type | capitalize | Purchase loan_amount | currency | 612,000 cltv | percentage | 80% The template however still outputs Loan Type {$loan_type|capitalize} Loan amount {$loan_amount|currency} CLTV {$cltv|percentage} Quote Link to comment https://forums.phpfreaks.com/topic/161422-solved-oo-template-variables-whelpers/#findComment-852475 Share on other sites More sharing options...
gevans Posted June 9, 2009 Share Posted June 9, 2009 change; $content = str_replace($match, $helper, $mailer_template); } } echo $content; to $mailer_template = str_replace($match, $helper, $mailer_template); } } echo $mailer_template; Quote Link to comment https://forums.phpfreaks.com/topic/161422-solved-oo-template-variables-whelpers/#findComment-852480 Share on other sites More sharing options...
gijew Posted June 9, 2009 Author Share Posted June 9, 2009 Pfft, you're smart'n me...today (probably tomorrow too but I'm not keeping track) I hate to be a PITA but this script has broken me. Any suggestions on why it keeps outputting the same record? Just for fun I opened up 3, 4 records to see how it would perform and they are all the same one. I tried unsetting the $mailer_template variable but nuttin. Quote Link to comment https://forums.phpfreaks.com/topic/161422-solved-oo-template-variables-whelpers/#findComment-852487 Share on other sites More sharing options...
gevans Posted June 9, 2009 Share Posted June 9, 2009 Without seeing the whole script, and the class that your using I can't comment on more than is on the screen. Feel free to add more script if you fancy. I've been thinking about building a simple template system for a framework, this is good practice With more time there might be a more efficient way to do it, though I think my first post is pretty decent Quote Link to comment https://forums.phpfreaks.com/topic/161422-solved-oo-template-variables-whelpers/#findComment-852498 Share on other sites More sharing options...
gijew Posted June 9, 2009 Author Share Posted June 9, 2009 Actually all of the magic is happening in that method because I ripped out everything else to try and get it to output the right data. I'm glad I can help you practice hehe. Anyhoo, here is the entire guy in all it's barebones glory (not much has changed besides the template processing). Now, what I've found is that if I comment out the line: $mailer_template = str_replace($match, $helper, $mailer_template); And print out the data directly: echo $data . ' | ' . $format . ' | ' . $helper . '<br />'; It displays all of the records. As soon as I try and output the $mailer_template again it just uses the same record again and again. <?php public function process_cronjob() { $sql = $this->db->GetAll(" SELECT " . $this->db_rows . " FROM " . $this->db_table . " " . $this->db_join_table . " " . $this->db_join_table_on . " " . $this->db_criteria . " " . $this->db_sort . " " . $this->db_limit . " "); if (count($sql) != 0) { $counter = -1; $db_rows = explode(',', $this->db_rows); $mailer_template = file_get_contents($this->mailer_template); foreach($sql as $k => $v) { for ($f = 0; $f <= $this->db_row_count - 1; $f++) { $pattern = '#{\$' . $db_rows[$f] . '\|[a-zA-Z0-9\=\-\_\: ]+}#'; preg_match($pattern, $mailer_template, $matches); $match = $matches[0]; if (!empty($match)) { $split = explode('|', $match); $data = str_replace('{$', '', $split[0]); $format = str_replace('}', '', $split[1]); $helper = $this->helpers($v[$f], $format); echo $data . ' | ' . $format . ' | ' . $helper . '<br />'; //$mailer_template = str_replace($match, $helper, $mailer_template); } } echo $mailer_template; echo '<hr />'; } } } ?> Quote Link to comment https://forums.phpfreaks.com/topic/161422-solved-oo-template-variables-whelpers/#findComment-852507 Share on other sites More sharing options...
gevans Posted June 9, 2009 Share Posted June 9, 2009 I'm can't really get my head around it, without seeing the methods working on db_rows, what is set in $sql etc... Can you give me an example of the output without the final string replace (as your code is above), so; first iteration echo $data . ' | ' . $format . ' | ' . $helper . '<br />'; echo $data . ' | ' . $format . ' | ' . $helper . '<br />'; echo $data . ' | ' . $format . ' | ' . $helper . '<br />'; second iteration echo $data . ' | ' . $format . ' | ' . $helper . '<br />'; echo $data . ' | ' . $format . ' | ' . $helper . '<br />'; echo $data . ' | ' . $format . ' | ' . $helper . '<br />'; If you're figuring it out yourself don't worry Quote Link to comment https://forums.phpfreaks.com/topic/161422-solved-oo-template-variables-whelpers/#findComment-852515 Share on other sites More sharing options...
gijew Posted June 9, 2009 Author Share Posted June 9, 2009 I attached all files associated (except configs, adodb libs, etc). It's pretty raw so please don't beat me I know the database structure blows but I'm not allowed to change it. I included: The class The page used to call it The mail template Sample db structure with 2 test records Sample output I really can't thank you enough for taking as much time as you have already. I guess it pays to be part of a good community And FYI: I'm still working on getting this resolved myself but I figured I put what I had out there in case you're quicker hehe. [attachment deleted by admin] Quote Link to comment https://forums.phpfreaks.com/topic/161422-solved-oo-template-variables-whelpers/#findComment-852545 Share on other sites More sharing options...
gevans Posted June 9, 2009 Share Posted June 9, 2009 Well, I've got it working, but I substituted all your db stuff for my own, so I've changed a load of variables and may make no sense. can you do this; echo '<pre>'; var_dump($sql); echo '</pre>' straight after $sql is set. So I can just duplicate your db result and try and get you something. Quote Link to comment https://forums.phpfreaks.com/topic/161422-solved-oo-template-variables-whelpers/#findComment-852571 Share on other sites More sharing options...
gevans Posted June 9, 2009 Share Posted June 9, 2009 Though on a quick though try this; change $mailer_template = file_get_contents($this->mailer_template); to $template = file_get_contents($this->mailer_template); and.... change foreach($sql as $k => $v) { for ($f = 0; $f <= $this->db_row_count - 1; $f++) { to foreach($sql as $k => $v) { $mailer_template = $template; for ($f = 0; $f <= $this->db_row_count - 1; $f++) { Quote Link to comment https://forums.phpfreaks.com/topic/161422-solved-oo-template-variables-whelpers/#findComment-852576 Share on other sites More sharing options...
gijew Posted June 9, 2009 Author Share Posted June 9, 2009 Hmm, no dice. I'm playing around with it now. It's going back to displaying the template without replacing the vars. Quote Link to comment https://forums.phpfreaks.com/topic/161422-solved-oo-template-variables-whelpers/#findComment-852587 Share on other sites More sharing options...
gevans Posted June 9, 2009 Share Posted June 9, 2009 If you follow the steps I followed in this post, http://www.phpfreaks.com/forums/index.php/topic,255764.msg1203504.html#msg1203504 I think I can crack it Quote Link to comment https://forums.phpfreaks.com/topic/161422-solved-oo-template-variables-whelpers/#findComment-852591 Share on other sites More sharing options...
gijew Posted June 9, 2009 Author Share Posted June 9, 2009 Holy crap. It works. To be honest, I was just throwing a few variables around and don't even know what did it to make it work but it works lol. This was the final go. I'll have to compare the last try to this one. Maybe the browser cached something, dunno. Either way, I can't thank you enough for the time you spent helping me along with this. It is VERY much appreciated! If you're ever in Southern California, expect to get free beer! <?php public function process_cronjob() { $sql = $this->db->GetAll(" SELECT " . $this->db_rows . " FROM " . $this->db_table . " " . $this->db_join_table . " " . $this->db_join_table_on . " " . $this->db_criteria . " " . $this->db_sort . " " . $this->db_limit . " "); if (count($sql) != 0) { $counter = -1; $db_rows = explode(',', $this->db_rows); $template = file_get_contents($this->mailer_template); foreach($sql as $k => $v) { $mailer_template = $template; for ($f = 0; $f <= $this->db_row_count - 1; $f++) { $pattern = '#{\$' . $db_rows[$f] . '\|[a-zA-Z0-9\=\-\_\: ]+}#'; preg_match($pattern, $mailer_template, $matches); $match = $matches[0]; if (!empty($match)) { $split = explode('|', $match); $data = str_replace('{$', '', $split[0]); $format = str_replace('}', '', $split[1]); $helper = $this->helpers($v[$f], $format); $mailer_template = str_replace($match, $helper, $mailer_template); } } echo $mailer_template; echo '<hr />'; } } } ?> Quote Link to comment https://forums.phpfreaks.com/topic/161422-solved-oo-template-variables-whelpers/#findComment-852612 Share on other sites More sharing options...
gevans Posted June 9, 2009 Share Posted June 9, 2009 Glad it's sorted, I think I might make a similar version to this soon (all from scratch though ) I'll take you up on that beer...... Next time I'm in california :s lol Quote Link to comment https://forums.phpfreaks.com/topic/161422-solved-oo-template-variables-whelpers/#findComment-852620 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.