Smarty replace and array - php

I'm working on a site for some apartments.
I have some data getting assigned to Smarty in a foreach loop.
$i = 0;
foreach ($obj2 as $array) {
$smarty->assign('name'.$i, $obj2[$i]['name']);
$smarty->assign('numbedrooms'.$i, $obj2[$i]['number_of_bedrooms']);
$smarty->assign('numbathrooms'.$i, $obj2[$i]['number_of_bathrooms']);
$smarty->assign('sqfeet'.$i, $obj2[$i]['square_feet']);
$smarty->assign('deposit'.$i, $obj2[$i]['deposit']);
$smarty->assign('rent'.$i, $obj2[$i]['rent']);
$smarty->assign('vacantunits'.$i, $obj2[$i]['vacant_units']);
$i++;
}
When the template is loaded ($smarty->display('template.tpl');) I want all of the data to be available via replace(like replace:'[[lowestrate]]':{$lowestrate} (example from another block of code)).
However, because the number of items in $obj2 could change (it's currently 3), I can't just say replace:'[[name1]]':{$name1}. (Not to mention how long that would take)
Also, the reason replacement is required is that the page content is managed from a CMS system with a WYSIWYG editor, where the editor can type [[lowestrate]] to have it replaced with the lowest cost apartment. They should be able to type [[name1]] to have it replaced with the name of the first apartment, or [[numberbedrooms1]] to be replaced with the number of bedrooms apartment 1 has.
Does anyone have any idea as to how I should go about doing this?

This sounds like a job you should be doing in the PHP level, not the smarty level. I suggest that you do the replacements before the assignment to smarty, and then send the transformed array, it will be much easier (and cleaner imho)

Related

Importing PHP string with quotes

So I'm importing ExpressionEngine fields into a php array. I want to display one field, called {gearboxx_body}, unless that field has more then 300 characters, in which case I want to display a field called {article_blurb}. I'm pretty sure there isn't a way to do this just in ExpressionEngine fields and conditionals, so I tried some PHP, which I'm just starting to learn:
<?php
$info = array('{gearboxx_body}','{article_blurb}');
if(mb_strlen($info[0]) <= 300)
echo($info[0]);
}
else {
echo($info[1]);
}
?>
So that works well, but there's a problem. If the tag includes any apostrophes or quote marks, it ends the string and the page won't load. So what can I do about this? I've tried to replace the quote marks in the string, but I have to have loaded the string from the fields first, and as soon as I do that the page is already broken.
Hopefully that made sense. Any suggestions?
I would recommend you handle this in an EE plugin rather than in the template:
Faster to render (because you don't need the overhead of PHP in the templates)
More secure and reliable
Faster to develop once you get the basics of EE development down which is a useful life skill
All around best-practice
The plugin I have in mind takes three parameters:
body, blurb and character limit.
Let's say you call your plugin "Blurby". In the template you would just have this:
{exp:blurby body="{gearboxx_body}" blurb="{article_blurb}" char_limit="300"}
It variably returns either of your fields based on the logic you define in the plugin itself.
See plugin developer documentation.
Alternatively you could use the dreaded HEREDOC syntax to set variables before passing them into your array:
$body = <<<EOT
{gearboxx_body}
EOT;
$blurb = <<<EOT
{article_blurb}
EOT;

WordPress PHP htmlspecialchars(get_field... cannot read arrays?

I am working on a WordPress Website/Blog with two main functions.
Create reports.
Compile final report.
People can write reports, selecting the fields they need and publish it. Then at the end of the day, they can "compile" a final report from all of the reports (it concatenate the fields of all reports).
The theme is twentyten (in case it might be useful).
In my function.php file, I concatenate everthing for the final report using a foreach and lines like that:
$Urgences_Environnementales .= htmlspecialchars("<br/>".get_field('Urgences_Environnementales', $idnumber->ID));
$avezvous_regardé_des_indices_de_temps_violent_aujourdhui .= htmlspecialchars(get_field('avezvous_regardé_des_indices_de_temps_violent_aujourdhui', $idnumber->ID));
$quelle_est_cette_raison .= htmlspecialchars(get_field('quelle_est_cette_raison', $idnumber->ID));
One line per field, all the same way. After the loop is done, I update the fields:
update_field('Urgences_Environnementales',preg_replace('/(<br[\s]?[\/]?>[\s]*){2,}/', '<br/><br/>', htmlspecialchars_decode($Urgences_Environnementales)), $identificationRapport);
update_field('avezvous_regardé_des_indices_de_temps_violent_aujourdhui',preg_replace('/(<br[\s]?[\/]?>[\s]*){2,}/', '<br/><br/>', htmlspecialchars_decode($avezvous_regardé_des_indices_de_temps_violent_aujourdhui)), $identificationRapport);
update_field('quelle_est_cette_raison',preg_replace('/(<br[\s]?[\/]?>[\s]*){2,}/', '<br/><br/>', htmlspecialchars_decode($quelle_est_cette_raison)), $identificationRapport);
Then it's printed for the final report like this (this is a single field):
if(strip_tags(html_entity_decode(get_field('Urgences_Environnementales')))!=''){
simplebox(strip_tags(html_entity_decode(get_field('Urgences_Environnementales')))!='', get_field('Urgences_Environnementales'));
}
And for those fields it works perfectly.
My problem is that all my fields composed of arrays (checkboxes that people can select multiple choices using the ACF plugin) are empty in my databse... They appear perfectly in the single reports, but they appear blank in the final report.
As an exemple, this is what I see in my database for a single report for one of my arrays:
a:4:{i:0;s:49:"L’indice d’intensité d’orage violent (STI)";i:1;s:35:"L’indice d’orage violent (TMPV)";i:2;s:34:"Potential Severe Storm Environment";i:3;s:6:"Autres";}
The corresponding field in my final report is empty.
Would someone have an idea on how to read those arrays and record them correctly in my databse? Could I transform them in strings in my foreach loop? Should I do something differently?
If you need more code don't hesitate to ask. I didn't put all my 3 functions (functions.php, report.php, finalreport.php) that I have in my WordPress theme as it would take tons of lines and I'm pretty sure the most important ones are right here. If I'm wrong, I could post the functions.
I searched and searched, but I can't seem to find the answer by myself, so I'm searching for help here.
PS: This is my 1st post, if you have any reccomandations, you can send them to me and I will change my post.
Thank you very much for your help!
PPS: I'm sorry for my english, I'm french, from Montreal, Qc, Canada.
Advanced Custom Fields stores some values as serialized arrays (checkboxes, repeaters, etc). Your code is assuming that you will be getting a string back. As you suggested in your answer, the easiest way to account for this in your current code would be to use the is_array() method to check the type of the returned value, and then another inner loop to handle the summary. This code assumes you just want to concatenate all the values, you could just as easily use another array to make sure they are unique, etc.
// get the value from acf
$value = get_field( 'Urgences_Environnementales', $idnumber->ID );
// if it's already an array, use that, if not make it into an array with a single element
$value_arr = ( is_array( $value ) )? $value : array( $value );
$text = ""; // reset since this is in a loop
// concatenate each checkbox value
foreach ( $value_arr as $val ){
$text .= $val . ', ';
}
// append it to the main summary
$Urgences_Environnementales .= htmlspecialchars( "<br/>". $text );

Smarty dynamic variable issue

Unfortunately, in my current workplace, I have to use Smarty on a project they had before i was employed.
Anyway, I am trying to call in a Dynamic html title for each category in the app.
So for example, the title used to be pageTitle="{$category} in {$areaname}".
However I now want it to be: pageTitle="{html_title}". Within html_title (from db), is a string, for example: "Monkeys in the {areaname}" Where {areaname} could be "jungle".
When I output the result, I get:
"Monkeys in {areaname}".
So to cut a long story short, its not recognizing the variable. It is treating it as a string. I have googled my head off and can't find an answer. I hate smarty!
Please help!
Couldn't you just do something like
$html_title = preg_replace("/{areaname}/", "jungle", $html_title);
after fetching the title from the database?

Assistance with building an inverted-index

It's part of an information retrieval thing I'm doing for school. The plan is to create a hashmap of words using the the first two letters of the word as a key and any words with the two letters saved as a string value. So,
hashmap["ba"] = "bad barley base"
Once I'm done tokenizing a line I take that hashmap, serialize it, and append it to the text file named after the key.
The idea is that if I take my data and spread it over hundreds of files I'll lessen the time it takes to fulfill a search by lessening the density of each file. The problem I am running into is when I'm making 100+ files in each run it happens to choke on creating a few files for whatever reason and so those entries are empty. Is there any way to make this more efficient? Is it worth continuing this, or should I abandon it?
I'd like to mention I'm using PHP. The two languages I know relatively intimately are PHP and Java. I chose PHP because the front end will be very simple to do and I will be able to add features like autocompletion/suggested search without a problem. I also see no benefit in using Java. Any help is appreciated, thanks.
I would use a single file to get and put the serialized string. I would also use json as the serialization.
Put the data
$string = "bad barley base";
$data = explode(" ",$string);
$hashmap["ba"] = $data;
$jsonContent = json_encode($hashmap);
file_put_contents("a-z.txt",$jsonContent);
Get the data
$jsonContent = file_get_contents("a-z.txt");
$hashmap = json_decode($jsonContent);
foreach($hashmap as $firstTwoCharacters => $value) {
if ($firstTwoCharacters == 'ba') {
$wordCount = count($value);
}
}
You didn't explain the problem you are trying to solve. I'm guessing you are trying to make a full text search engine, but you don't have document ids in your hashmap so I'm not sure how you are using the hashmap to find matching documents.
Assuming you want a full text search engine, I would look into using a trie for the data structure. You should be able to fit everything in it without it growing too large. Nodes that match a word you want to index would contain the ids of the documents containing that word.

PHP equivalent for RoR template partials/collections

I'm trying to figure out the most efficient way to implement RoR-style partials/collections for a PHP template class that I'm writing. For those who aren't familiar with rails, I want to iterate over a template fragment (say a table row or list item) located in a separate file. I want to do this without resorting to eval or placing an include within the loop.
I've seen a similar post that addresses single partials, which are trivial, but nothing that covers implementing partials in a collection. I've been thinking about this so long my head hurts and I'm afraid I'm overlooking an obvious solution. I'm hoping someone here can suggest an elegant solution that, again, doesn't require eval or include within the loop. TIA.
You need a templating engine with that can process includes on its own and then eval the whole thing at once. Much like c preprocessor works.
Step 1 (source template):
$template = '
foreach($bigarray as $record)
#include "template_for_record.php"
'
Step 2 (after preprocessing):
$template = '
foreach($bigarray as $record)
// include statement replaced with file contents
echo $record['name'] etc
'
Step 3 (final rendering)
// eval() only once
eval($template);
In this way you can avoid the overhead of evaling/including subtemplate on every loop step.
You're asking how to do something without resorting to the solution.
Any template system you use is going to use an eval or an include within the loop, even if it's buried in abstraction 1000 layers deep.
That's just how it's done.

Categories