str_replace() function and multiple variables? - php

This is going to be pretty hard to explain, so I'll try to make it as much of a chronological story as possible and end with the question, so that anyone who needs a relatively in-depth idea of what I'm talking about has one :).
I have a theme template with four text containers named primary_headline, primary_subline, secondary_headline and secondary_subtext. The content for each container comes from echo($container_name).
Each container has it's own variable, $container_name, which posts user created content to from a form, contents which sometimes contains the variables $city_name and $ref_name as raw data (i.e. "Hello, I'm from $city_name"), as $city_name and $ref_name has assigned values, for arguments sake let's just say $city_name= Dallas and $ref_name = Facebook.
Originally, I believed that I only wanted the user to be able to use $city_name and $ref_name within the secondary_subtext container, and I was also going to make the option to use $city_name OR $ref_name the choice of the user in the first place (they'd have to select one, or the other, or none - but couldn't select both.
However, I now want to allow $city_name AND $ref_name across all four container variables ($secondary_subtext for example).
So, my question is, how do I go about doing that in the easiest possible fashion?
Here's my old code for good measure:
if($geo_text == "enable") {
$geo_init = include("inc/geo_text.php");
$secondary_headline = str_replace('$city_name', $city_name, $_POST['secondary_headline']); // $_POST data from user
} else($ref_text == "enable") {
$ref_init = include("inc/ref_text.php");
$secondary_headline = str_replace('$ref_name', $ref_name, $_POST['secondary_headline']); // $_POST data from user
} else { $secondary_headline = $_POST['secondary_headline']; }
Any comments/answers etc will be very greatly appreciated :)!!

$placeholders = array('city_name','ref_name');
$include_mapper('geo_text' => 'inc/geo_text.php','ref_text'=>'inc/ref_text.php');
$containers = array('first_headline','scondary_headline');
$found = 0;
foreach ($include_mapper as $map => $include){
if ($$map == "enable"){
include ($include_mapper[$map]);
foreach ($container as $container){
foreach ($placeholders as $placeholder){
$$container = str_replace('$'.$placeholder, $$placeholder, $_POST[$container];
}
}
$found = 1;
break;
}
}
if (!$found){
foreach ($container as $container){
$$container = $_POST[$container];
}
}

Related

Woocommerce Order / AFC get_sub_field / get_sub_field_object (array)

Have setup ACF repeater field that stores various amount of tracking numbers in the order. Having 0 success with retrieving this information so need some advice.
Am using this to put information in subfields and it does the job
foreach ($base->DocumentLines->DocumentLine as $item) {
foreach ($item->MiscData as $misc) {
foreach ($misc->PackageNo as $package) {
$trackno = (string)$package->TrackingNo;
update_post_meta("$order_id", $field_rep, $count);
$sub = $count +1;
update_sub_field(array($field_key_rep, $sub, $field_key_sub), $trackno, "$order_id");
$count = $count + 1;
update_field($field_key, $trackno, "$order_id");
}
}
}
This works well, but then i need to retrieve this numbers and write em out. They are getting included in an email so need to retrieve the data outside of order.
Before rebuilding the function to be able to handle multiple numbers i did use a single field and could retrieve the information with
get_post_meta($order_id, 'tracking', true);
Feels like i have been trying everything now but got absolutely nothing.
Image from one of the orders, in this one it’s 10 tracking numbers but it varies from 1 to 20 if it's to any help.
The feeling when you realize after 10 hours that your missed a capital letter in sub field name.
Just wanted to submit my solution and hopefully it can help someone else having issues with ACF Repeater fields + Woocommerce
For my specific case i did make a function that could extract all the tracking numbers my function above did add from XML files.
$function trackingNo($postID) {
$field_rep = 'trackingNo';
$field_sub = 'no';
if (have_rows($field_rep, $postID)) {
$trackingNo = array();
// loop through the rows of data
while (have_rows($field_rep, $postID)):
the_row();
// Add to array
$trackingNo[] = get_sub_field($field_sub);
endwhile;
$foo = implode('&consignmentId=', $trackingNo);
$bar = 'urlzz/tracktrace/TrackConsignments_do.jsp?&consignmentId=';
$value = $bar . $foo;
return $value;
}
}
Any advice for improvement is always welcome, my PHP is so'n'so :)

Efficient way to make a (PHP) redirection functionality for multiple (128) database values

Currently I am working on a webpage where certain data from a database is being fetched and displayed to the user. This information is about certain project information and the lead partners of those projects. I want to implement a functionality where the user can click on a lead partner (link) and the link will redirect this user to another page (where the database information of all the organisations is on) BUT with a predefined search for only the organisations that are equal to the clicked lead partner link.
I found a solution on how to do this but the problem is that the solution (which i describe further below) isn't that good/efficient for multiple (128) organisations.. So the question is, do you know a better/more efficient solution to achieve this. To answer this question you probably also need some background information:
BACKGROUND INFORMATION
In the outputted database information (which is done in a table) there are several information columns/titles such as:
Project name
Organisations involved
Leader partner
Project website
And so on...
The fetching of the data is being done with a simple query where certain database columns have a specific identifier. For example, the project website columns is obviously a link, so in the query it is being done as follows: $SomeQueryVar = ("SELECT project_website as LINK FROM xxxx WHERE project_website ('$some_website') "); -- Just a short example to clarify things.
For the displaying, the data is being 'catched' like so:
if(count($SomeQueryVar)>0){
for($i=0;$i<count($SomeQueryVar);$i++){
echo "<tr>";
foreach($SomeQueryVar[$i] as $key=>$value){
echo "<td>";
$b=unserialize($value);
if($key =='LINK' && $value != NULL){
$first = true;
array_filter($b);
foreach($b as $y){
echo ''."Project website".'';
$first = false;
if(!$first) break;
}
} else {
echo $value;
}
echo "</td>";
}
echo "</tr>";
}
}
As you can see in the above code, certain database columns need other displaying as the rest. For example, links must be clickable instead of just being plain text. These 'exceptions' are being catched with the if $key ==, for the data that just needs regular displaying (plain text) there is the last else inserted that just echo's the $value.
MY FOUND SOLUTION
So regarding the question, i found out that i can create redirection links using the ?SomePage on the projects page and using this 'added link value' on the organisations page to compare it. If the link is equal, then do the specific query. But it is probably easier to paste the code here:
The 'CATCHING' part
To catch a specific lead partner is also used an identifier in my query called ORG (which stands for organisation). So here is the code where i catch the organisations table:
if($key =='ORG' && $value != NULL){
$needle = array('Brainport','Development','BRAINPORT',
'brainport','DEVELOPMENT','development');
$needle2 = array('Casa','CASA', 'casa');
if (strpos_arr($value,$needle) !== false) {
echo '<a href="http://portal.e-ucare.eu/database/organisations/?a=brainport" >'.$value.'</a>';
}
if (strpos_arr($value,$needle2) !== false) {
echo '<a href="http://portal.e-ucare.eu/database/organisations/?a=casa" >'.$value.'</a>';
}
}
In the above code i just created it for 2 organisations (brainport and casa). For this solution i used a function called strpos_arr which searches for the needle in the haystack;) So in the code above i set the needles to the names in the database where it has to create a link for. So if for example a company with the word Brainport exists in the database, this 'catcher' will see this and display the organisation and make the name clickable.
The strpos_arr function for the $needle is as follows:
function strpos_arr($value, $needle) {
if(!is_array($needle)) $needle = array($needle);
foreach($needle as $what) {
if(($pos = strpos($value, $what))!==false) return $pos;
}
return false;
}
In the redirection page the code will also catch certain links to make queries for that link -- so for the brainport link this is http://portal.e-ucare.eu/database/organisations/?a=brainport -- in the second page code this link is catched like so:
$host = $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
if($host == 'portal.e-ucare.eu/database/organisations/?a=brainport')
{
$link_word = "Brainport";
$tmp = $wpdb->get_results("
SELECT
name_of_company__organization, company_location,
company_website as LINK, organisation_type,
organisation_active_in_, organisation_scope,
organisation_files as DOC
FROM
wp_participants_database
WHERE
name_of_company__organization REGEXP ('$link_word')
ORDER BY
name_of_company__organization ASC
");
}
With this solution i can do what i want, BUT like i said in the beginning, i need this for not just 2 organisations but 128!! This would mean i have to copy the catching code blocks on both pages 128 times!! This is obviously not very efficient..
So is there any more efficient way to achieve this? Sorry if it is a bit unclear but i found it quite hard to easily wright this down;)
Anyway, thank you in advance!
The firts part you can rewrite to
if($key =='ORG' && $value != NULL){
$needles = array(
'brainport'=>array('Brainport','Development','BRAINPORT','brainport','DEVELOPMENT','development'),
'casa'=>array('Casa','CASA', 'casa')
);
foreach($needles AS $nkey => $needle){
if(strpos_arr($value,$needle) !== false) {
echo "<a href='http://portal.e-ucare.eu/database/organisations/?a={$nkey}' >{$value}</a>";
}
}
}
For the second part make an array like
[EDIT]
$link_words = array(
'portal.e-ucare.eu/database/organisations/?a=brainport'=>'Brainport',
'portal.e-ucare.eu/database/organisations/?a=casa'=>'Casa',
);
then you can use
$host = $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
if(!empty($link_words[$host])){
$link_word = $link_words[$host];
$tmp = $wpdb->get_results("
SELECT
name_of_company__organization, company_location, company_website as LINK, organisation_type, organisation_active_in_, organisation_scope, organisation_files as DOC
FROM
wp_participants_database
WHERE
name_of_company__organization REGEXP ('$link_word')
ORDER BY
name_of_company__organization ASC
");
}

PHP - Display results from this 'Detect' array?

re: Home Site = http://mobiledetect.net/
re: this script = Mobile_Detect.php
Download script here: https://github.com/serbanghita/Mobile-Detect
This script functions perfectly detecting the different parameters of a user's device.
However, this is how I am currently detecting these parameters:
// each part of the IF statement is hard-coded = not the way to do this
if($detect->isiOS()){
$usingOS = 'iOS';
}
if($detect->isAndroidOS()){
$usingOS = 'Android';
}
echo 'Your OS is: '.$usingOS;
My goal is to use a FOREACH to iterate thru the various arrays in this script to determine a user's device's parameters. I would need to have the "($detect->isXXXXOS())" be dynamic... (which, would be based upon the KEY). The results would display the KEY. But the detection would be based upon the VALUE.
Also, since my web page uses a REQUIRE to access this script... in the Mobile_Script.php script, the arrays are "protected." I think this is also causing me problems (but I don't know for sure).
Any help is appreciated.
In foreach loop you can call dynamic method look like this :
$array = array('Android','Windows','Linux','Mac');
foreach( $array as $value) {
$method = "is{$value}OS";
if($detect->$method()) {
$os = $value;
echo "Your OS is : {$os}";
}
}
Please rearrange your code what you want. I give you an example.
you can try to use somethin like this:
$OSList = $detect->getOperatingSystems();// will give array of operating system name => match params
foreach($OSList as $os_name=>$os_params/*unused*/)
{
$method = 'is'.$os_name;
if($detect->$method())
{
$usingOS = $os_name;
}
}

Need better structure of my code

this is my front controller
$pages = array("matches", "boards", "search", "articles", "interviews", "userlist", "teams", "servers", "awards", "gallery", "qids");
if (!$_SERVER['QUERY_STRING']) include('home_en.php');
elseif (isset($_GET['matchid'])) include('matchid.php');
elseif (isset($_GET['boardid'])) include('boardid.php');
elseif (isset($_GET['articleid'])) include('articleid.php');
elseif (isset($_GET['interviewid'])) include('interviewid.php');
elseif (isset($_GET['userid'])) include('profi.php');
elseif (isset($_GET['teamid'])) include('teamid.php');
elseif (isset($_GET['serverid'])) include('serverid.php');
elseif (isset($_GET['awardid'])) include('awardid.php');
elseif (isset($_GET['galleryid'])) include('galleryid.php');
elseif (isset($_GET['threadid'])) include('threadid.php');
elseif (isset($_GET['blogid'])) include('blogid.php');
..
elseif (in_array($_GET['content'], $pages)) include($_GET['content']);
else echo "File not found =(";
could i somehow add the identifiers to the array too? but i want the pages as index.php?matchid=9438 and for regular pages: index.php?content=matches
would really aprricate some ideas
thanks!
My Suggestion, From My Comment is this:
In order to check what type of id it is, you should use two $_GET parameters. One is the type (match, award, server, etc), one is the ID. That way you don't have to check for 500 different $_GET parameters, just the value of 2. Much more standardized.
Second, you want to make all of it under 1 file for the ID showing.
In the spirit of writing less code, not more, it would be relatively easy to change the SQL statement to grab the record based on if $_GET['type'] was match, award, team, etc. This is of course given that they will probably look the same. If they don't, instead of writing new code to grab each type, instead write code to display it differently
All Variables in this code much be validated/sanatized beforehand.
// First Get the Type
$type = $_GET['type'];
// Then the ID
$id = $_GET['id'];
// SANITIZE YOUR DATA. Replace this with your sanitization.
die("SANITIZE YOUR DATA HERE");
// Get Data Here
$sql = "SELECT * FROM table WHERE type=".$type." AND id=".$id;
$data = mysql_query($sql);
// Next, Include a template based on the data.
// Global the variable so it can be used in the file
Global $data;
include($type."-template.php");
I agree with Tom -- you should look into using a framework such as Zend, Cake, Symfony, Kohana, CodeIgniter, ez-Components, or Seagull. The advantage of using a framework is that they have already solved a lot of issues for you, including:
1) How to structure your code
2) How to interpret pretty urls (i.e. /x/1/y/2 instead of ?x=1&y=2)
3) Where to put certain types of code (html, php, configs, etc)
4) How to fix something you can't figure out (because these frameworks have communities)
and much much more...
That being said, maybe you don't want all the overhead of using a framework (it does require you to learn a lot). In that case, I recommend Rasmus Lerdorf's "No Framework PHP Framework". Rasmus is the creator of PHP, so you know he knows his stuff.
Lastly, to answer your actual question, here's how I would do it:
could i somehow add the identifiers to the array too?
i want the pages as index.php?matchid=9438
and for regular pages: index.php?content=matches
Sure, but yes, as Chacha102 said, you will need 2 parameters: $area (page) and $id.
Example: index.php?area=articles&id=2345
Then you can re-organize & simplify your 'front controller' this way:
/index.php
/areas/articles.php
/areas/boards.php
etc.
Instead of naming the templates articleid.php, just call it articles.php -- this way your area name also tells you which template to use.
$valid_areas = array("matches", "boards", "search", "articles",
"interviews", "userlist", "teams", "servers",
"awards", "gallery", "qids");
$area = strtolower(trim($_REQUEST['area'])); //if you are not posting any forms, use $_GET instead
$id = (int)$_REQUEST['id']; //if you are not posting any forms, use $_GET instead
if(!$id)
{
include('home_en.php');
}
if(!in_array($area), $valid_areas))
{
echo 'Sorry, the area you have requested does not exist: '.$area;
exit();
}
else
{
$template = '/templates/'.$area.'.php';
if(!file_exists($template))
{
echo 'Sorry, the file you have requested does not exist: '.$area.' '.$id);
}
else
{
include($template);
}
}
It might help to go ahead and use a framework such as Zend:
http://framework.zend.com/
You could do this:
<?php
$controllerDefault = 'home';
function sanitize($str)
{
return str_replace(array('.', '/', '\\'), '', $str);
}
//Prevent of Remote File Inclusion
$controller = sanitize($_GET['controller']);
$id = intval($_GET['id']);
if (empty($controller))
{
$controller = $controllerDefault;
}
if (!empty($id))
{
$controller .= 'id';
}
$controllerFile = $controller . '.php';
if (!file_exists($controllerFile)
|| $controller == 'index') //for not recursive index.php include :)
{
exit('Controller "'.$controllerFile.'" not exists');
}
include($controllerFile);
?>
Using this code you can use your application like:
http://yoursite.com/index.php //include('home.php')
http://yoursite.com/index.php?id=285230 //include('homeid.php')
http://yoursite.com/index.php?controller=matches //include('matches.php')
http://yoursite.com/index.php?controller=matches&id=28410 //include('matchesid.php')
http://yoursite.com/index.php?controller=notexists //ERROR! Controller "notexists" not exists
http://yoursite.com/index.php?controller=../../etc/passwd //ERROR! Controller "etcpasswd" not exists
I hope you like it
PD: the code is not tested, but I hope you catch my idea

Persistent HTTP GET variables in PHP

Let's say I have some code like this
if(isset($_GET['foo']))
//do something
if(isset($_GET['bar']))
//do something else
If a user is at example.com/?foo=abc and clicks on a link to set bar=xyz, I want to easily take them to example.com/?foo=abc&bar=xyz, rather than example.com/?bar=xyz.
I can think of a few very messy ways to do this, but I'm sure there's something cleaner that I don't know about and haven't been able to track down via Google.
Here's one way....
//get passed params
//(you might do some sanitizing at this point)
$params=$_GET;
//morph the params with new values
$params['bar']='xyz';
//build new query string
$query='';
$sep='?';
foreach($params as $name=>$value)
{
$query.=$sep.$name.'='.urlencode($value);
$sep='&';
}
If you are updating the query string you need ot make sure you don't do something like
$qs="a=1&b=2";
$href="$qs&b=4";
$href contains "a=1&b=2&b=4"
What you really want to do is overwrite the current key if you need to .
You can use a function like this. (disclaimer: Off the top of my head, maybe slightly bugged)
function getUpdateQS($key,$value)
{
foreach ($_GET as $k => $v)
{
if ($k != $key)
{
$qs .= "$k=".urlencode($v)."&"
}
else
{
$qs .= "$key=".urlencode($value)."&";
}
}
return $qs
}
View report
Just set the link that changes bar to xyz to also have foo=abc if foo is already set.
$link = ($_GET['foo'] == 'abc') ? 'foo=abc&bar=xyz' : 'bar=xyz';
?>
Click Me
You would have to render out the links with the proper URL querystring to make that happen. This is a design decision that you would need to make on your end depending on how your system is setup.
I have some sites that have this issue, and what I do is setup a querystring global variable that sets the current page data the top of the page request.
Then when I am rendering the page, if I need to make use of the current query string I do something like:
echo '<a href="myurl.php' . querystring . '&bar=foo';
It's not the cleanest, but it all depends on how your system works.
Save some code and use the built-in http_build_query. I use this wrapper in one of my projects:
function to_query_string($array) {
if(is_scalar($array)) $query = trim($array, '? \t\n\r\0\x0B'); // I could split on "&" and "=" do some urlencode-ing here
else $query = http_build_query($array);
return '?'.$query;
}
Also, though it isn't often used, you can have $_GET on the left-hand side of an assignment:
$_GET['overriden_or_new'] = 'new_value';
echo 'Yeah!';
Other than that, just do what Paul Dixon said.

Categories