The question is kind of similar to randomize default products in opencart, but simpler. I am trying to have my products listed by newest first. I made the following change in catalog/model/catalog/product.php:
if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
if ($data['sort'] == 'pd.name' || $data['sort'] == 'p.model') {
$sql .= " ORDER BY LCASE(" . $data['sort'] . ")";
} else {
$sql .= " ORDER BY " . $data['sort'];
}
} else {
$sql .= " ORDER BY p.date_added";
}
But I don't see this having any effect to the default sort.
I don't know which version of OC do You have, but You should also consider modifying the order part. In OC 1.5.5 it is like this:
if (isset($data['order']) && ($data['order'] == 'DESC')) {
$sql .= " DESC, LCASE(pd.name) DESC";
} else {
$sql .= " ASC, LCASE(pd.name) ASC";
}
In this case, with Your change and if no sort nor order data is provided the products will be sorted from the oldest to newest (oldest first). I recommend changing the order part to something like this:
if (isset($data['order']) && ($data['order'] == 'ASC')) {
$sql .= " ASC, LCASE(pd.name) ASC";
} else {
$sql .= " DESC, LCASE(pd.name) DESC";
}
If You are saying that there is no change also try to delete Your browser session as the sorting, filtering and other options are stored there.
Related
I'm trying to filter through my database according to filters done by visitors.
$query = "select * from Sheet1 where";
//filter query start
if (!empty($brand)) {
$branddata = implode("','", $brand);
//testing removing query
$query .= " Brand in('$branddata') and";
}
if (!empty($model)) {
$modeldata = implode("','", $model);
//testing removing query
$query .= " Model in('$modeldata') and";
}
/* if(!empty($model) && empty($brand)){
} */
if (!empty($spower) && !empty($epower)) {
$query .= " Power>='$spower' and Power<='$epower' and";
}
if (!empty($sprice) && !empty($eprice)) {
$query .= " Doors>='$sprice' and Doors<='$eprice'";
}
$rs = mysqli_query($conn, $query) or die("Error : " . mysqli_error($conn));
The result I wish to get is a sql query that works and has correct syntax. Such as select * from Sheet1 where Doors>='$sprice' and Doors<='$eprice', if the visitor is filtering by price.
Currently, my code is made so that it simply adds a certain string to the variable. This means that if you don't filter by model, it skips model, because the model variable is empty. The problem comes to if you filter by power, the SQL will become select * from Sheet1 where Power>='$spower' and Power<='$epower' and. Obviously this doesn't work, so I need help in making the code make sure it works for every combination of filters.
Append $query .= " 1 = 1"; at the end. I did some modification in your given code. Have a look.
<?php
$query = "SELECT * FROM `Sheet1` WHERE";
//filter query start
if(!empty($brand)){
$branddata = implode("','",$brand);
$query .= " (Brand in('$branddata')) AND";
}
if(!empty($model)){
$modeldata = implode("','",$model);
$query .= " (Model in('$modeldata')) AND";
}
if(!empty($spower) && !empty($epower)){
$query .= " (Power>='$spower' AND Power<='$epower') AND";
}
if(!empty($sprice) && !empty($eprice)){
$query .= " (Doors>='$sprice' AND Doors<='$eprice') AND"; //Added 'AND'
}
$query .= " 1 = 1"; //Added new line
$rs = mysqli_query($conn,$query) or die("Error : ".mysqli_error($conn));
?>
Add AND on each query appended in if conditions. Then, at last add $query .= " 1 = 1";. Which will save you from extra AND coming at the end. If none of the conditions satisfy, then your query will be SELECT * FROM Sheet1 WHERE 1 = 1. Simple. And, don't forget to differentiate between conditions in query. Differentiate your conditions like how I did by opening and closing brackets.
I would do it this way
$filters=array();
if(!empty($brand)){
$branddata =implode("','",$brand);
//testing removing query
$filters[]= " Brand in('$branddata')";
}
if(!empty($model)){
$modeldata =implode("','",$model);
//testing removing query
$filters[]= " Model in('$modeldata') and";
}
if(!empty($spower) && !empty($epower)){
$filters[]= " Power>='$spower' and Power<='$epower' and";
}
if(!empty($sprice) && !empty($eprice)){
$filters[]= " Doors>='$sprice' and Doors<='$eprice'";
}
$query = "select * from Sheet1 where";
foreach ($filters as $filter) {
$query.=' AND '.$filter;
}
$rs = mysqli_query($conn,$query) or die("Error : ".mysqli_error($conn));
I want to show database records ordered by Datetime or Price when users click on links sort by Datetime or sort by Price. Should I add a condition into the query ?
$sql = "SELECT p.title AS Title, p.date_published) AS Datetime , p.price AS Price, c.name AS Category FROM products p
INNER JOIN categories c
ON c.id = p.category
INNER JOIN brands b
ON b.id = p.brand
.
.
.
";
if (isset($_GET['search'])){
$locations = array();
$getters = array();
$queries = array();
foreach($_GET as $key => $value) {
.
.
.
}
if (!empty($brands)) {
$brd_q = implode(",",$brands);
}
if(!empty($getters)) {
foreach($getters as $key => $value){
${$key} = $value;
switch($key) {
case 'search':
array_push($queries, "(p.title LIKE '%$search%' || p.description LIKE '%$search%' || p.number LIKE '%$search%')");
break;
case 'scategory':
array_push($queries, "p.category = $scategory");
break;
case 'sbrands':
array_push($queries, "p_brd.brand_id IN ($brd_q)");
break;
.
.
.
}
}
}
if(!empty($queries)) {
$sql .= " WHERE ";
$i=1;
foreach($queries as $query) {
if ($i < count($queries)) {
$sql .= $query." AND ";
}else{
$sql .= $query;
}
$i++;
}
}
$sql .= " ORDER BY Datetime DESC";
}
You already have this clause:
$sql .= " ORDER BY Datetime DESC";
All you need, is to add ordering parameter to your query, say $_GET['order'] as integer index(1-based) in your whitelist orders where sign points to order direction.
$orders = ['Datetime', 'Price'];
if (empty($_GET['order'])) $_GET['order'] = -1; // set default order
$index = abs($_GET['order'])-1;
$ord = isset($orders[$index]) ? $orders[$index] : $orders[0];
$direction = $_GET['order'] > 0 ? 'ASC' : 'DESC';
$sql .= " ORDER BY {$ord} {$direction}";
In simple way you can use if else condition for sort query only. According to your condition like this.
$sql = "Rest of the Query..";
if($_GET['order'] == 'price') {
$sql .= " ORDER BY Price DESC";
} else {
$sql .= " ORDER BY Datetime DESC";
}
When user click Sort by Price or Datetime then query will executed as per the condition.
(Or)
You can update query case condition like below example.
ORDER BY
CASE WHEN "price" = $_GET['order'] THEN price END DESC,
CASE WHEN "datetime" = $_GET['order'] THEN datetime END DESC
(or)
ORDER BY
CASE $_GET['order']
WHEN "price" THEN price END DESC,
WHEN "datetime" THEN datetime END DESC
etc...
Whatever you choose booth will be same performance and efficiency.
I have latest MySQL version (5.5) and this is the screenshot of groupid field
I didn't touch anything yet, but some cells are not ordered correctly like this
But if I click groupid name in the top, it will ordered correctly like this:
Below PHP code output is like first screenshot above, that are not ordered correctly. Please help how to make the output ordered correctly, like it is displayed in the second screenshot above,
Maybe add code like this : order by id asc, but which is the right place to add it below?
$group_ids = explode(" ", $options['groupchoice_ids']);
$groupsql = "SELECT id, title FROM " . TABLE_PREFIX . "thegroup WHERE";
$first = true;
foreach($group_ids as $value)
{
if (!$first)
{
$groupsql = $groupsql . " OR ";
}
else
{
$first = false;
}
$groupsql = $groupsql . " id = '" . $value . "' ";
}
$kh_optionsgroup = '<select name = "accounttype">';
$checksec = $db->query_read($groupsql);
if ($db->num_rows($checksec))
{
while ($lboard = $db->fetch_array($checksec))
{
$kh_optionsgroup = $kh_optionsgroup . "<option value
='" . $lboard['id'] . "'>" . $lboard['title'] . "</option>";
}
}
$verifystring = '$human_verify';
$kh_optionsgroup = $kh_optionsgroup . "</select>";
At the end of your query, you need to set an order, like so:
$groupsql="SELECT id, title FROM " . TABLE_PREFIX . "thegroup WHERE";
$first=true;
foreach($group_ids as $value){
if(!$first){
$groupsql = $groupsql." OR ";
}else{
$first = false;
}
$groupsql = $groupsql." id = '".$value."' ORDER BY groupid ASC";
}
ORDER BY id ASC
This will make the query return its results in ascending order from the groupid column. Simply change ASC to DESC if you want it to go descendinng (high->low).
I'm having a little trouble with a search form I've been creating the functionality for. I basically want a form (on whatever page) to go to this page then list the relevant rows from my database. My problem is that the form has both a text field and a select field (for name and categories) and I've been unable to create the functionality for having these two values search the database together.
So heres what I want to happen: When you only type in the name and not the category, it will display from just the name, vise versa for the category and no name; then when both together it only displays rows with both of them in.
Heres what I have so far:
// 2. Create variables to store values
if(!$_GET['search-category'] == "") {
$searchName = $_GET['search-name'];
}
if(!$_GET['search-category'] == "select-your-category") {
$searchCat = $_GET['search-category'];
}
// 2. Create the query for the stored value. Matching it against the name, summary and sub type of my item.
$mainSearch = "SELECT attraction.*, type.type_name, sub_type.sub_type_name ";
$mainSearch .= "FROM attraction ";
$mainSearch .= "INNER JOIN sub_type ON attraction.sub_type = sub_type.sub_type_id ";
$mainSearch .= "INNER JOIN type ON attraction.type = type.type_id ";
$mainSearch .= "WHERE attraction.name LIKE '%" . $searchName . "%' AND (sub_type.sub_type_name LIKE '%" . $searchCat . "%' )";
$mainSearch .= "ORDER BY sub_type_name ASC";
// 2. run query
$result2 = $con->query($mainSearch);
if (!$result2) {
die('Query error: ' . mysqli_error($result2));
}
I'd refactor the code to something like -
foreach( $_GET['filters'] as $fname => $fval ) {
if( !$fval ) continue;
$where[] = "$fname LIKE '%{$fval}%'";
}
You need to include only those inputs that are non-empty in the query. Also you will need to address security issues like escaping inputs etc.
What you can do is that declare a variable called $search_condition and based on whether $searchName or $searchCat is null or not assign value to $search_condition
For e.g.
if (isset($searchName ) || !is_empty($searchName ))
{
$search_condition = "WHERE attraction.name LIKE '%" . $searchName;
}
if (isset($searchCat ) || !is_empty($searchCat ))
{
$search_condition = "sub_type.sub_type_name LIKE '%" . $searchCat . "%'";
}
if ((isset($searchName ) || !is_empty($searchName )) && (isset($searchCat ) || !is_empty($searchCat )))
{
$search_condition = "WHERE attraction.name LIKE '%" . $searchName . "%' AND (sub_type.sub_type_name LIKE '%" . $searchCat . "%' )";
}
Hope this might help you
Thanks
This is a comment, but I want to take advantage of formatting options...
You know, you can rewrite that this way...
// 2. Create the query for the stored value. Matching it against the name, summary and sub type of my item.
$mainSearch = "
SELECT a.*
, t.type_name
, s.sub_type_name
FROM attraction a
JOIN sub_type s
ON a.sub_type = s.sub_type_id
JOIN type t
ON a.type = t.type_id
WHERE a.name LIKE '%$searchName%'
AND s.sub_type_name LIKE '%$searchCat%'
ORDER
BY s.sub_type_name ASC;
";
You can just check that the relevant values aren't empty:
// 2. Create the query for the stored value.
// Matching it against the name, summary and sub type of my item.
$mainSearch = "SELECT attraction.*, type.type_name, sub_type.sub_type_name ";
$mainSearch .= "FROM attraction ";
$mainSearch .= "INNER JOIN sub_type ON attraction.sub_type = sub_type.sub_type_id ";
$mainSearch .= "INNER JOIN type ON attraction.type = type.type_id ";
$mainSearch .= "WHERE ";
if ($searchName) {
$mainSearch .= "attraction.name LIKE '%" . $searchName . "%'";
if ($searchCat) {
$mainSearch .= " AND ";
}
}
if ($searchCat) {
$mainSearch .= "sub_type.sub_type_name LIKE '%" . $searchCat . "%'"
}
$mainSearch .= "ORDER BY sub_type_name ASC";
// Double check that at least one of the search criteria is filled:
if (!$searchName && !$searchCat) {
die("Must supply either name search or category search");
}
I wrote a custom query to use in CakePHP 1.3 The query is as follows:
SELECT artists.id, artists.name, artists.image_id, genres.genre
FROM artists
LEFT JOIN coupling_artist_genre
ON artists.id = coupling_artist_genre.id_in
LEFT JOIN genres
ON coupling_artist_genre.id_out = genres.id
WHERE artists.name LIKE '%tee%'
AND genres.id IN (12,14)
ORDER BY artists.name ASC
LIMIT 0,25
When I call this like this:
$this -> Artist -> query ($sql);
I get this error:
1064: You have an error in your SQL syntax; check the manual that corresponds
to your MySQL server version for the right syntax to use near '
However, when I copy the generated query and paste it into PHPMyAdmin it works fine. No warnings, no errors, and most importantly: the result I expect.
Does anyone know what could cause this difference between Cake and PMA?
Edit: This is how the query is generated:
$query = "SELECT artists.id, artists.name, artists.image_id";
if ($genres != ' ' && strlen ($genres) > 0)
{
$query .= ", genres.genre";
}
$query .= " FROM artists";
if ($genres != ' ' && strlen ($genres) > 0)
{
$query .= " LEFT JOIN coupling_artist_genre ON artists.id = coupling_artist_genre.id_in";
$query .= " LEFT JOIN genres ON coupling_artist_genre.id_out = genres.id";
}
$query .= " WHERE";
if ($searchString != '' && strlen ($searchString) > 0)
{
$searchString = $searchString == ' ' ? '' : $searchString;
$query .= " artists.name LIKE '%".$searchString."%'";
}
if ($searchString != ' ' && strlen ($searchString) > 0 && $genres != ' ' && strlen ($genres) > 0)
{
$query .= " AND";
}
if ($genres != ' ' && strlen ($genres) > 0)
{
$query .= " genres.id IN (".$genres.")";
}
$query .= " ORDER BY artists.name ASC LIMIT " . ($page - 1) * 25 . ",25";
$this -> set ('artists', $this -> Artist -> query ($query));
I think there are case when your queries end up like this:
" ...
WHERE
ORDER BY ... "
or
" ...
WHERE artists.name LIKE '%tee%'
AND
ORDER BY ... "
Try this:
$query .= " WHERE True ";
if ($searchString != '' && strlen ($searchString) > 0)
{
$searchString = $searchString == ' ' ? '' : $searchString;
$query .= " AND artists.name LIKE '%".$searchString."%'";
}
if ($genres != ' ' && strlen ($genres) > 0)
{
$query .= " AND genres.id IN (".$genres.")";
}
$query .= " ORDER BY artists.name ASC LIMIT " . ($page - 1) * 25 . ",25";
$this -> set ('artists', $this -> Artist -> query ($query));
Tried to post this earlier, but I couldn't without 100 reputation. Anyway here's the answer I tried to post earlier:
Dear visitors of this question. I am terribly sorry (especially for you ypercube because you took the time to think about AND answer my question!).
I just discovered that I made a very stupid mistake. Down in my controller, in a totally different method that shouldn't even be executed I had another query in a die() call. That was the query MySQL was complaining about. I never expected it to be executed but alas, it was the query causing my error. Seeing as I didn't need it anymore I deleted it and my error was gone.
Once again, I'm sorry for all of you that put time in this question. I shall try to be more careful in the future!