php mysql and in_array performance - php

Is there anything to get more performance? Because it tooks about 8 secs. car_models database has over 100.000 records, cars database has over 20.000 records and finaly car_parts has over 20.000 records. I could do for that a database something like keywords. But the problem is the databases are dynamic. I mean the records adding everyday by editors. And I can't touch the part of the software because it is not open source...
$news = dbquery("SELECT * FROM " . DB_NEWS . " ORDER BY news_id DESC LIMIT 0,1");
while ($news_data = dbarray($news))
{
echo $news_data['news_subject'];
$news_first_part = str_replace("\\", "", $news_data['news_news']);
$news_first_part = explode('.', $news_first_part); //first phrase
$news_first_part = $news_first_part[0];
$news_second_part = str_replace("\\", "", $news_data['news_extended']);
$find = array();
$keywords = dbquery("SELECT name FROM cars GROUP BY name");
while ($keywords_data = dbarray($keywords))
{
$my_keyword = $keywords_data['name'];
$news_first_part = str_replace($my_keyword, "<a href='keyword.php?keyword=$my_keyword' title='$my_keyword'>$my_keyword</a>", $news_first_part);
$news_second_part = str_replace($my_keyword, "<a href='keyword.php?keyword=$my_keyword' title='$my_keyword'>$my_keyword</a>", $news_second_part);
if ($news_first_part OR $news_second_part AND !in_array($my_keyword, $find,true))
{
array_push($find, $my_keyword);
}
}
$my_keyword="";
$keywords = dbquery("SELECT name FROM car_models GROUP BY name");
while ($keywords_data = dbarray($keywords))
{
$my_keyword = $keywords_data['name'];
if (strlen($my_keyword) > 10 && !in_array($my_keyword, $find, true))
{
$news_first_part = str_replace($my_keyword, "<a href='keyword.php?keyword=$my_keyword' title='$my_keyword'>$my_keyword</a>", $news_first_part);
$news_second_part = str_replace($my_keyword, "<a href='keyword.php?keyword=$my_keyword' title='$my_keyword'>$my_keyword</a>", $news_second_part);
}
}
$keywords = dbquery("SELECT name FROM car_parts GROUP BY name");
while ($keywords_data = dbarray($keywords))
{
$my_keyword = $keywords_data['name'];
if (strlen($my_keyword) > 10)
{
$news_first_part = str_replace($my_keyword, "<a href='keyword.php?keyword=$my_keyword' title='$my_keyword'>$my_keyword</a>", $news_first_part);
$news_second_part = str_replace($my_keyword, "<a href='keyword.php?keyword=$my_keyword' title='$my_keyword'>$my_keyword</a>", $news_second_part);
}
}
$my_keyword="";
echo $news_first_part . '.'; //note I added the final ponctuation
$news_first_part .= ".";
$news_second_part = str_replace($news_first_part, "", $news_second_part);
echo nl2br($news_second_part);
}

You could build some kind of array tree-structure, to limit the size of the sub-arrays. The array would then become:
$arr['a']['apple'];
$arr['a']['anna'];
$arr['a']['awesome'];
$arr['b']['bread'];
$arr['b']['beer'];
$arr['c']['cucumber'];
Instead of
$arr['apple'];
$arr['anna'];
$arr['awesome'];
$arr['bread'];
$arr['beer'];
$arr['cucumber'];
As you can see, an in_array would become lots faster.
If we would like to check "php", there is no array for the first-letter "p": nothing has to be walked through again
If we would like to check "ananas", we would have to lookup 3 items, instead of 6!
Note: the "outer" array could consist of the 1st letter (or 2, 3, 4, etc.) depending on the size of your set.
In PHP code you would get something like
$word = "ananas";
$arr = array();
if (!isset($arr[$word{0}]) || !in_array($word, $arr[$word{0})) {
// New word
if (!isset($arr[$word{0}])) {
$arr[$word{0}] = array($word);
} else {
$arr[$word{0}][] = $word;
}
}

Try it this way, it is much faster.
if ($news_first_part OR $news_second_part AND !isset($find[$my_keyword]))
{
$find[$my_keyword] = 1;
}
Update the rest of the code correspondingly. Actually, you do not need to use a !isset($find[$my_keyword]) check here.

Related

Select where to display values from MySQL DB in CodeIgniter

I want to display the values from MySQL database using CodeIgniter. Here, I am using SELECT to query to compare the multiple values using the WHERE condition.
I want to display the checked rows values from one page to another. I am passing the the checked value via URL. In the second page, I am getting the value from the URL, and using the explode() function to split the value and display using a for loop. Here, values are displaying correctly. But, when passing the array values to the SELECT query, it displays only the last rows.
I want to display all checked rows from the database.
For example, sample code:
<?php
$id = $this->uri->segment(4);
$arr = explode(',', $id);
for ($kk = 0; $kk < count($arr); $kk++) {
echo $id_val13 = $arr[$kk];
$basicUrl = $this->config->item("basicUrl");
$basicUrl['bread_crumb'] = $this->breadcrumb();
$query = $this->db->query("SELECT aa.id as id,customer_type_id,start_time,close_time,dd.name as customer_name,bb.name as vehicle_name,cc.name as driver_name,other_expensive,depature_city,destination_city,journey_status,payment,tour_file,DATE_FORMAT(aa.created_date, '%d/%m/%Y') as created_date FROM " . $this->tbl . " as aa
left join vehicle as bb on aa.vehicle_id=bb.id
left join driver as cc on aa.driver_id=cc.id
left join tbl_customer as dd on aa.customer_id=dd.id
WHERE aa.id = $id_val13");
$result = array();
if ($query->num_rows()) {
$i = 1;
foreach ($query->result() as $row) {
$result_row = array();
$result_row[] = '<input type="checkbox" name="chk_id" id="chk_id" value="' . $row->id . '" />';
$result_row[] = $row->id;
$result_row[] = $row->customer_name;
if ($row->customer_type_id == "1")
$result_row[] = "Tour";
else if ($row->customer_type_id == "2")
$result_row[] = "Company";
else if ($row->customer_type_id == "3")
$result_row[] = "Guest";
$result_row[] = $row->driver_name;
$result_row[] = $row->vehicle_name;
$result_row[] = $row->destination_city;
$result_row[] = $row->start_time;
$result_row[] = $row->close_time;
$result_row[] = $row->payment;
$result_row[] = $row->other_expensive;
$result_row[] = $row->journey_status == "1" ? "Complete" : "On Progress";
if ($row->tour_file != "") {
$result_row[] = '' . $row->tour_file . '';
} else {
$result_row[] = "No File";
}
$result_row[] = $row->created_date;
$action_btn = action_button("Edit", $row->id) . action_button("Delete", $row->id) . action_button("Select", $row->id);
$result_row[] = $action_btn;
$result[] = $result_row;
$i++;
}
}
}
$tbl_header = array(
"",
"S NO",
"Customer Name",
"Type",
"Driver Name",
'Vehicle Name',
"Destination City",
"Start Time",
"Close Time",
"Rupee",
"Other Expensive",
"Journey Status",
"Itinerary",
"Created Date",
array(
"Edit",
"Delete"
)
);
$basicUrl['table'] = $this->makeTable($result, $tbl_header, $bool = TRUE);
$this->parser->parse("admin/center", $basicUrl);
?>
For example:
$array = array("1","2","6");
Normally using explode() and for loop, it display all the values. When I use select query using CodeIgniter, it displays the last row only.
Try this (I have defined $result before for loop) Also this is not a good practice to use your code like this use controller and models to do all the logical and database work....
<?php
$id = $this->uri->segment(4);
$arr = explode(',', $id);
$result=array();
for ($kk = 0; $kk < count($arr); $kk++)
{
echo $id_val13 = $arr[$kk];
$basicUrl = $this->config->item("basicUrl");
$basicUrl['bread_crumb'] = $this->breadcrumb();
$query=$this->db->query("SELECT aa.id as id,customer_type_id,start_time,close_time,dd.name as customer_name,bb.name as vehicle_name,cc.name as driver_name,other_expensive,depature_city,destination_city,journey_status,payment,tour_file,DATE_FORMAT(aa.created_date, '%d/%m/%Y') as created_date FROM ".$this->tbl." as aa
left join vehicle as bb on aa.vehicle_id=bb.id
left join driver as cc on aa.driver_id=cc.id
left join tbl_customer as dd on aa.customer_id=dd.id
WHERE aa.id = $id_val13");
if($query->num_rows()){
$i=1;
foreach($query->result() as $row){
$result_row=array();
$result_row[]='<input type="checkbox" name="chk_id" id="chk_id" value="'.$row->id.'" />';
$result_row[]=$row->id;
$result_row[]=$row->customer_name;
if($row->customer_type_id=="1")
$result_row[]="Tour";
else if($row->customer_type_id=="2")
$result_row[]="Company";
else if($row->customer_type_id=="3")
$result_row[]="Guest";
$result_row[]=$row->driver_name;
$result_row[]=$row->vehicle_name;
$result_row[]=$row->destination_city;
$result_row[]=$row->start_time;
$result_row[]=$row->close_time;
$result_row[]=$row->payment;
$result_row[]=$row->other_expensive;
$result_row[]=$row->journey_status=="1" ? "Complete" : "On Progress";
if($row->tour_file!="")
{
$result_row[]=''.$row->tour_file.'';
}
else
{
$result_row[]="No File";
}
$result_row[]=$row->created_date;
$action_btn=action_button("Edit",$row->id).action_button("Delete",$row->id).action_button("Select",$row->id);
$result_row[]=$action_btn;
$result[]=$result_row;
$i++;
}
}
}
$tbl_header=array("","S NO","Customer Name","Type","Driver Name",'Vehicle Name',"Destination City","Start Time","Close Time","Rupee","Other Expensive","Journey Status","Itinerary","Created Date",array("Edit","Delete"));
$basicUrl['table']=$this->makeTable($result,$tbl_header,$bool=TRUE);
$this->parser->parse("admin/center",$basicUrl);
?>

Eliminating HTML escape sequences from string with PHP

I am working on a php script to pull quest data from wowhead, particularly what starts and ends the quest, whether it is an item or a npc, and what its id or name is, respectively. This is the relevant portion of the whole script, with the rest involving database insertion. This is the completed snippet of code I came up with if anyone is interested. Also, seeing as this will run about 15,000 times, is this the best method of obtaining/storing the data?
<?php
$quests = array();
//$questlimit = 14987;
$questlimit = 5;
$currentquest = 1;
$questsprocessed = 0;
while($questsprocessed != $questlimit)
{
echo "<br>";
echo " Start of iteration: ".$questsprocessed." ";
echo "<br>";
echo " Attempting to process quest: ".$currentquest." ";
echo "<br>";
$quests[$currentquest] = array();
$baseurl = 'http://wowhead.com/quest=';
$fullurl = $baseurl.$currentquest;
$data = drupal_http_request($fullurl);
$queststartloc1 = strpos($data->data, 'quest_start');
$queststartloc2 = strpos($data->data, 'quest_end');
if($queststartloc1==false)
{$currentquest++; echo "No data for this quest"; echo "<br>"; continue;}
$questendloc1 = strpos($data->data, 'quest_end');
$questendloc2 = strpos($data->data, 'x5DDifficulty');
$startcaptureLength = $queststartloc2 - $queststartloc1;
$endcaptureLength = $questendloc2 - $questendloc1;
$quest_start_raw = substr($data->data,$queststartloc1, $startcaptureLength);
$quest_end_raw = substr($data->data, $questendloc1, $endcaptureLength);
$startDecoded = preg_replace('~\\\\x([A-Fa-f0-9]{2})~e', 'chr("0x$1")', $quest_start_raw);
$endDecoded = preg_replace('~\\\\x([A-Fa-f0-9]{2})~e', 'chr("0x$1")', $quest_end_raw);
$quests[$currentquest]['Start'] = array();
$quests[$currentquest]['End'] = array();
if(strstr($startDecoded, 'npc'))
{
$quests[$currentquest]['Start']['Type'] = "npc";
preg_match('~npc=(\d+)~', $startDecoded, $startmatch);
}
else
{
$quests[$currentquest]['Start']['Type'] = "item";
preg_match('~item=(\d+)~', $startDecoded, $startmatch);
}
$quests[$currentquest]['Start']['ID'] = $startmatch[1];
if(strstr($endDecoded, 'npc'))
{
$quests[$currentquest]['End']['Type'] = "npc";
preg_match('~npc=(\d+)~', $endDecoded, $endmatch);
}
else
{
$quests[$currentquest]['End']['Type'] = "item";
preg_match('~item=(\d+)~', $endDecoded, $endmatch);
}
$quests[$currentquest]['End']['ID'] = $endmatch[1];
//var_dump($quests[$currentquest]);
echo " End of iteration: ".$questsprocessed." ";
echo "<br>";
echo " Processed quest: ".$currentquest." ";
echo "<br>";
$currentquest++;
$questsprocessed++;
}
?>
These are called "escape sequences". Normally, they're used to represent characters not printable otherwise, but can encode any character. In php, you can decode them like this:
$text = '
quest_start\\x5DStart\\x3A\\x20\\x5Bitem\\x3D16305\\x5D\\x5B\\x2Ficon\\x5D\\x5B\\x2Fli\\x5D\\x5Bli\\x5D\\x5Bicon\\x20name\\x3Dquest_end\\x5DEnd\\x3A\\x20\\x5Burl\\x3D\\x2Fnpc\\x3D12696\\x5DSenani\\x20Thunderheart\\x5B\\x2Furl\\x5D\\x5B\\x2Ficon\\x5D\\x5B\\x2Fli\\x5D\\x5Bli\\x5DNot\\x20sharable\\x5B\\x2Fli\\x5D\\x5Bli
';
$decoded = preg_replace('~\\\\x([A-Fa-f0-9]{2})~e', 'chr("0x$1")', $text);
Which gives you a string similar to this:
quest_start]Start: [item=16305][/icon][/li][li][icon name=quest_end]End: [url=/npc=12696]Senani Thunderheart[/url][/icon][/li][li]Not sharable[/li][li
(obviously, some kind of BB-code). To remove all bbcodes, yet one replacement is necessary:
$clean = preg_replace('~(\[.+?\])+~', ' ', $decoded);

PHP while loop within a while loop works once

I have two queries sent to a database bring back posts (op_ideas 16 cols) followed by another which holds the votes per post (op_idea_vote cols 4) with matching idea_id's
Example of Data:
Query: op_ideas:
[{"idea_id":"2211","author_id":"100000", "date":"2012-09-06
10:02:28","idea_title":"Another test","4" etc etc
Query: op_idea_votes:
idea_id = 2211, agree=3, disagree=1, abstain=0
The code below ought to look at op_ideas, and then cycle over op_ideas_vote until it finds a match under 'idea_id'. Then it goes to the next record under op_ideas, and again using that idea_id search for it within the op_idea_vote list, find a match, and add it to the array.
This works for only the first record, not for the other three. I am testing, so I have 3 rows in each that match idea_id with different results in the op_idea_vote.
$votes = mysql_query($commentVotes);
$result = mysql_query($gl_query);
while ($gce_result = mysql_fetch_array($result)) {
$voteid = $gce_result['idea_id'];
while($allvotes= mysql_fetch_array($votes)) {
if($voteid = $allvotes['idea_id'])
{
//echo $voteid . " main idea and the votes: " . $allvotes;
$gce_result["agree"] = $allvotes['agree'];
$gce_result["disagree"] = $allvotes['disagree'];
$gce_result["abstain"] = $allvotes['obstain'];
}
else
{
$gce_result["agree"] = 0;
$gce_result["disagree"] = 0;
$gce_result["abstain"] = 0;
}
//print_r($gce_result);
}
$data_result[] = $gce_result;
}
echo json_encode($data_result);
If I use print_f(&gce_result) it works fine in phpfiddle. But when i use the code above, it works for the first record, but it's complete missing the second two. It seems to be missing the second while, as it does not even give me the 0 0 0 results.
Query for op_ideas:
$gl_query = "SELECT DISTINCT * FROM heroku_056eb661631f253.op_ideas INNER JOIN op_organs ORDER BY date ASC;";
if (!mysql_query($gl_query)) {
die('Error: ' . $gl_query . " " . mysql_error());
}
$result = mysql_query($gl_query);
Query For op_idea_vote :
$commentVotes = "SELECT v.idea_id, COUNT(v.agree = 1 or null) as agree, COUNT(v.disagree = 1 or null) as disagree, COUNT(v.obstain = 1 or null) as obstain FROM op_idea_vote v GROUP BY v.idea_id";
if (!mysql_query($commentVotes)) {
die('Error: ' . $commentVotes . " " . mysql_error());
}
$votes = mysql_query($commentVotes);
You can scan a resource only once.
So the inner while will be run only one time.
use == instead of = for checking condition of if & while
in the while loop ,you have to assign the value of $allvotes ,but you never assigned,
while ($gce_result == mysql_fetch_array($result)) {
$voteid = $gce_result['idea_id'];
while($allvotes== mysql_fetch_array($votes)) {
if($voteid == $allvotes['idea_id'])
{
//echo $voteid . " main idea and the votes: " . $allvotes;
$gce_result["agree"] = $allvotes['agree'];
$gce_result["disagree"] = $allvotes['disagree'];
$gce_result["abstain"] = $allvotes['obstain'];
}
else
{
$gce_result["agree"] = 0;
$gce_result["disagree"] = 0;
$gce_result["abstain"] = 0;
}
$data_result[] = $gce_result;
}
}
Your problem is trying to scan over the $votes result more than once.
You should store the result of that query first.
Eg.
while ($vote = mysql_fetch_array($votes)) {
$allvotes['idea_id'] = $vote;
}
while ($gce_result = mysql_fetch_array($result)) {
$voteid = $gce_result['idea_id'];
if (array_key_exists[$voteid, $allvotes]) {
//assign results
} else {
//default
}
}
Another option would be to do the query with a join, so you can do everything in one query. Then just loop over that result.

Handling a bunch of various requests into the database

I currently have a php page that grabs information from a database and produces HTML with data attributes that are filled in by from the MySQL query. The database is going to be used to search, with many different options for searches.
What I need help with is knowing a way so to organize how the many variables are handled. It's a really big mess of code, and even with all the comments I put it gives me a headache trying to figure out how to add another variable to the search.
All the variables, except for the LIMIT to which row and how many results, are optional. So if someone leaves everything except that blank, I still want it to function as well as if they meticulously filled in all the fields.
Here's what I have, with 6 variables.
<?php
$product_size = "(".$_GET['size']." BETWEEN productsizeDOWN AND productsizeUP)"; // This code sets the variable to input into the MySQL string based on the URL
$product_size_check = $_GET['size']; // the _checks check are used to see if the value is or isn't empty using if statements below
$manufacturer = $_GET['manufacturer'];
$product_manufacterer_check = $_GET['manufacturer']; // _check
$product_invisible = "(hideproduct = '".$_GET['invisible']."')"; // Checks if product is hidden
$product_invisible_check = $_GET['invisible']; // _check
$product_instock_check = $_GET['instock']; // _check
$product_limit0 = $_GET['startat']; // This is the first number after LIMIT; the row to start in.
$product_limit1 = $_GET['results']; // This is how many results to load.
$manufacturer_array = explode(",", $manufacturer); // The manufacturer comes in as "Nike,Addidas,Rebok" and is turned into an array
$manufacturer_imploded = implode("' OR productmanufacturer = '", $manufacturer_array); // Puts it back together with "OR productmanufacturer =" between each name.
$product_manufacterer = ("(productmanufacturer = '".$manufacturer_imploded."')"); // formats it so it can be directly inserted into MySQL string with a WHERE in front.
if($product_invisible_check == ""){
$product_invisible = "";
}else{$where = "WHERE ";}; //Useless code that I havn't deleted that I tried to use when I searched the entire database
if($product_size_check == ""){
$product_size = "";
}else{$where = "WHERE ";};
if($product_manufacterer_check == ""){
$product_manufacterer = "";
}else{$where = "WHERE ";};
if($product_instock_check == "N"){
$product_instock = "(stockstatus <= '0' AND donotallowbackorders = 'Y') AND "; // Checks if product is in stock (Allowing backordering OR stock >1)
$where = "WHERE ";
}
elseif($product_instock_check == "Y") {
$product_instock = "(stockstatus > '0' OR donotallowbackorders = 'N') AND ";
$where = "WHERE ";
}
else {
$product_instock = "";
};
$sql="Select * FROM ioa7pd_Products WHERE ".$product_instock.$product_size."AND".$product_manufacterer_and.$product_manufacterer."".$product_invisible." LIMIT ".$product_limit0.", ".$product_limit1; // The end result of it all.
echo $sql;
?>
When the URL is
test.php?size=5&manufacturer=Nike,Addidas,Rebok&invisible=N&instock=Y&startat=0&results=30
the resulting SQL query is
Select * FROM ioa7pd_Products WHERE (stockstatus > '0' OR donotallowbackorders = 'N') AND (5 BETWEEN productsizeDOWN AND productsizeUP)AND(productmanufacturer = 'Nike' OR productmanufacturer = 'Addidas' OR productmanufacturer = 'Rebok')(hideproduct = 'N') LIMIT 0, 30
But I plan to add more options to the search.
My main question is simply: What way can I organize this to make it simple to add more variables? Tiered if statements?
Travesty has been helping me with my code and has really been great in organizing it.
Here is the current code. It needs to be secure to prevent injection.
// Database connection
$con = mysql_connect("[CENSORED]","[CENSORED]","[CENSORED]")
or die("Could not connect: " . mysql_error());
mysql_select_db("[CENSORED]") or die('Could not select database');
// Begin organization of URL variables into MYSQL Query
$get_size = $_GET['size'];
$get_manufacturer = $_GET['manufacturer'];
$get_invisible = $_GET['invisible'];
$get_instock = $_GET['instock'];
$get_sex = $_GET['sex'];
$get_startat = $_GET['startat'];
$get_results = $_GET['results'];
if ($get_size != ""){
$all_selectors[] = "(".$get_size." BETWEEN productsizeDOWN AND productsizeUP)"; // Add to array if size is not blank.
};
if ($get_manufacturer != ""){
$manufacturer_exploded = explode(",", $get_manufacturer);
$manufacturer_imploded = implode("' OR productmanufacturer = '", $manufacturer_exploded);
$all_selectors[] = ("(productmanufacturer = '".$manufacturer_imploded."')");
};
if ($get_invisible != ""){
$all_selectors[] = "(hideproduct = '".$get_invisible."')";
};
if($get_instock == "N" or $get_instock == "n"){
$all_selectors[] = "(stockstatus <= '0' AND donotallowbackorders = 'Y')";
}elseif($get_instock == "Y" or $get_instock == "y") {
$all_selectors[] = "(stockstatus > '0' OR donotallowbackorders = 'N')";
};
if ($get_startat != "" or $get_results != ""){
$number_results = "LIMIT ".$get_startat.", ".$get_results;
} else {
$number_results = "LIMIT 0, 15";
};
// All variables are now in an array, except "startat" and "results"
$all_selectors0 = "WHERE ".implode(" AND ", $all_selectors);
// Create SQL query
$sql="Select * FROM sadsads_Products ".$all_selectors0." ".$number_results;
I would do something more like this. It's not tested and probably not 100% complete...you may need to do some further customization, particularly with adding more special cases to the switch statement, but this will make adding more variables much easier:
REMOVED OLD EXAMPLE, SEE UPDATED EXAMPLE BELOW
One key thing to note is that you aren't sanitizing your database inputs. Your code is vulnerable to SQL injection. My example above helps to solve that, but this code isn't fully tested, so you should ensure that all user input is sanitized before using it in any query.
If your field names don't match up with your MySQL columns (which it looks like they don't), then you can fix them with an associative array:
$columns = array(
// [form field] => [mysql column]
'size' => 'product_size',
'manufacturer' => 'product_manufacturer',
'invisible' => 'hideproduct'
// ...
);
And then in your switch statement, do something more like this:
$whereClause[] = "{$columns[$key]} = '{$value}'";
FINAL UPDATE:
DOCUMENTED SAMPLE - has plenty of comments and extra stuff to make it work on Codepad
EXACT WORKING CODE - you should be able to copy and paste this (and add your DB credentials) and it should work:
$con = mysqli_connect("[CENSORED]", "[CENSORED]", "[CENSORED]") or die("Could not connect: ". mysqli_error());
mysqli_select_db("[CENSORED]") or die("Could not select database");
$columns = array(
'size' => 'product_size',
'manufacturer' => 'product_manufacturer',
'invisible' => 'hideproduct'
);
$whereClause = array();
$limit = array("startat" => 0, "results" => 15);
foreach ($_GET as $key=>$value) {
$key = mysqli_real_escape_string($key);
if (is_array($value)) {
for ($i = 0; $i < count($value); $i++) {
$value[$i] = mysqli_real_escape_string($value[$i]);
}
} else {
$value = mysqli_real_escape_string($value);
}
switch ($key) {
case 'size':
$whereClause[] = "({$value} BETWEEN productsizeDOWN AND productsizeUP)";
break;
case 'startat':
case 'results':
$limit[$key] = $value;
break;
case 'instock':
$whereClause[] = "(stockstatus ". ($value == 'N' ? "<=" : ">") ." '0' ". ($value == 'N' ? "AND" : "OR") ." donotallowbackorders = '". ($value == 'N' ? "Y" : "N") ."')";
break;
default: {
if (is_array($value)) {
$whereClause[] = "{$columns[$key]} IN ('". implode("', '", $value) ."')";
} else {
$whereClause[] = "{$columns[$key]} = '{$value}'";
}
}
}
}
$sql = "SELECT * FROM ioa7pd_Products". (empty($whereClause) ? "" : " WHERE ". implode(" AND ", $whereClause)) ." LIMIT {$limit['startat']}, {$limit['results']}";
echo $sql;
after
else {
$product_instock = "";
};
do:
$limit = '';
if( !empty($product_limit0) && !empty($product_limit1) )
$limit = " LIMIT $product_limit0, $product_limit1";
$sql="Select * FROM ioa7pd_Products WHERE ".$product_instock.$product_size."AND".$product_manufacterer_and.$product_manufacterer."".$product_invisible." $limit"; // The end result of it all.
echo $sql;
If you have separate params in $_GET, you would have to traverse with multiple if statements. you can pass the params as an array into $_GET, with numeric keys, that would help a bunch.

How can I load the title of parent item in Drupal

I want to extend Nodes with the title of the parentnode so I can display a hierarchy link.
I have a solution that sometimes works:
function modulename_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL)
{
switch ($op)
{
case 'view':
loadParentTitle($node);
break;
}
}
function loadParentTitle(&$node)
{
$title = $node->title;
$query = "SELECT mlid, p1, p2,p4,p5,p6,p7,p8,p9 FROM menu_links WHERE link_title like '%%%s%%'";
$data = db_fetch_array(db_query($query, $title));
$mlid = $data["mlid"];
$i = 9;
while (($data["p". $i] == 0 || $data["p". $i] == $mlid) && $i >= 0)
{
$i--;
}
if ($i > 0)
{
$query = "SELECT `link_title` as parentTitle from `menu_links` WHERE mlid = " . $data["p" . $i];
$data = db_fetch_array(db_query($query));
$parentTitle = ($data["parentTitle"]);
}
else
{
$parentTitle = $title;
}
$node->content['#parentTitle'] = $parentTitle;
}
This works as long as the title of the item is the same as the Menu Title. However i'm looking for a solution that will work all the time. Any ideas?
You did not specify really what do you mean by 'parent node' but the mlid of the parent of a menu link is stored in menu_links.plid. Now, the link_path is going to be node/nid and you can fetch the title from there.
$mlid = db_result(db_query("SELECT plid FROM {menu_links} WHERE link_path = 'node/%d'", $node->nid));
$link_path = db_result(db_query("SELECT link_path FROM {menu_links} WHERE mlid = %d", $mlid));
$title = db_result(db_query("SELECT title FROM {node} WHERE nid = %d", substr($link_path, 5));
The first two queries can be unified by a JOIN but I strongly recommend against getting the third in there too (you can with CONCAT('node/', nid) = parent.link_path) because that is not going to be indexable. These three queries should be practically instant.
P.S. You won't forget to check_plain($title) before printing, would you? :)

Categories