Counting database entries that are the same/mysqli_num_rows - count

There doesn't seem to be a similar question anywhere. I need this to just loop through each unique value, and then kick out how many are the same but, somehow I'm using mysqli_num_rows wrong. Thank you in advance.
//This portion fetches unique entries that aren't empty
$query = "SELECT DISTINCT burger ";
$query .= "FROM newbob ";
$query .= "WHERE burger != '' ";
$query .= "ORDER BY burger ASC ";
$result = mysqli_query($dbc, $query);
if (!$result){
die ("Database query failed.");
}
//and I want this portion to count how many there are that are the same, and
//just add it next to it.
while($entries = mysqli_fetch_assoc($result)) {
echo $entries["burger"];
$query2 = "SELECT burger ";
$query2 .= "FROM newbob ";
$query2 .= "WHERE burger = '$entries[burger]'";
$result2 = mysqli_query($dbc, $query2);
$rowcount = mysqli_num_rows($result2);
echo "( " . $rowcount . " )<br>";
}
Edit: my query is failing somehow, I fixed the spaces in the query but, I'm wondering if I'm doing something wrong with the $entries[burger] part of the query.
Edit2: Might sit here and type myself through it! I just needed some single quotes around it. Now I'm failing when it hit's an apostrophe though. Any ideas?

Yup, just worked my way right through it. It's not necessarily beautiful but, I'm not sure how to do it better. The new bottom portion is
//and I want this portion to count how many there are that are the same, and
//just add it next to it.
while($entries = mysqli_fetch_assoc($result)) {
echo stripslashes($entries["burger"]);
foreach ($entries as $entries) {
$entries2 = mysqli_real_escape_string($dbc,$entries); }
$query2 = "SELECT burger ";
$query2 .= "FROM newbob ";
$query2 .= "WHERE burger = '$entries2'";
$result2 = mysqli_query($dbc, $query2);
if (!$result2){
die ("<br>Database query failed.");
}
$rowcount = mysqli_num_rows($result2);
echo "( " . $rowcount . " )<br>";
}

Related

Wordpress, search in post's categories description too (OR term_taxonomy.description LIKE %A%)

I'm struggling with finding a simple way for wordpress search to also search in post's categories description.
I found few topics but no real anwser.
The thing is, that the user might be typing what they search for + category name too (for example, "Mario Nintendo 64", where "Nintendo 64" is the category name. As of right now, it would return no results, which doesn't feel right).
I need to search in term_taxonomy.description, as categories have aliases, which I enter in this field (for instance: "Nintendo 64, N64 etc...")
Here what I came up with.
function custom_posts_join ($a) {
global $wpdb;
return $a . " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id)
INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_id) ";
}
function custom_posts_where ($a) {
global $wpdb;
return $a . " AND $wpdb->term_taxonomy.taxonomy = 'category'";
}
add_filter('posts_join', custom_posts_join );
add_filter('posts_where', custom_posts_where );
Still, I need to be able to integrate OR (term_taxonomy.description LIKE '%A%')in the search
as of right now the sql request only search for
(posts.post_title LIKE '%A%')
OR (posts.post_excerpt LIKE '%A%')
OR (posts.post_content LIKE '%A%')
Also, would it be possible to add DISTINCT, so it does not return the same post multiple times, based on the fact that posts can belong to multiple categories.
I really don't know if I'm on the right path here, but I'm stuck.
Also I am wondering how heavy, what may have seemed like a little adjustment, this will turn out to be on the server?
I haven't been developping for years, and now I'm back to it, and I'm not sure if this will make the search too heavy. Is INNER JOIN the best way?
Is there another way I could handle the search to search in the categories description of the posts.
After hours of research, I finally made progress, and everything works perfectly!
Here what it looks like now:
function custom_posts_join ( $join ) {
global $wpdb;
if ( is_search() ) {
$join .= " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id)
INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_id) ";
}
return $join;
}
function custom_posts_where ( $where ) {
global $wpdb;
if ( is_search() ) {
$where = preg_replace(
"/\(\s*".$wpdb->posts.".post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",
"(".$wpdb->posts.".post_title LIKE $1) OR (".$wpdb->term_taxonomy.".description LIKE $1)", $a );
$where .= " AND $wpdb->term_taxonomy.taxonomy='category'";
}
return $where;
}
add_filter('posts_join', custom_posts_join );
add_filter('posts_where', custom_posts_where );
And to add DISTINCT:
function custom_posts_distinct ( $distinct ) {
global $wpdb;
if ( is_search() ) {
return "DISTINCT";
}
return $distinct;
}
add_filter( 'posts_distinct', 'custom_posts_distinct' );
Still, how about performance, doing 2 INNER JOIN every research?
Anyway, here is a full solution, I hope this will help someone.

Query with join not work

i am doing a query in my controller like this:
$aviso = $em->getRepository("FabricacionBundle:Aviso")->findBy(array("fecha" => $fecha));
$dql = "SELECT a FROM PedidosBundle:Articulo a WHERE a.aviso = :aviso";
if(isset($_GET['filterField']) && isset($_GET['filterValue'])){
$dql = "SELECT a FROM PedidosBundle:Articulo a JOIN ProductosBundle:Producto p WHERE a.aviso = :aviso";
$dql .= " AND " . $_GET['filterField'] . " LIKE '%" . $_GET['filterValue'] . "%'";
}
$query = $em->createQuery($dql)
->setParameter("aviso", $aviso[0]->getId());
//dump($query);die();
$paginator = $this->get('knp_paginator');
$articulos = $paginator->paginate(
$query,
$request->query->get('page', 1),
25
);
When i dont use the filter, this work, but when i use the filter i get the next error:
Cannot count query which selects two FROM components, cannot make distinction
Where is the problem? Thanks!
What SQL engine are you running ?
Note, that it's usually a very bad practice to insert anything directly from your $_GET variable into your SQL query, as this can lead to SQL injection.
Imagine, that someone sends \'; DROP TABLE something; -- in your $_GET['filterField'] - everything is gone.
From the top of my head, there is a lacking JOINing condition.

Create a Query using QueryBuilder with two Many-to-Many relation in Symfony2

Good evening everybody!
I have got a problem with the QueryBuilder in Symfony2.
A USER can be part of some GROUPS. Each GROUP can access to CATEGORIES. Here is a little database diagram.
Now, I would like to retrieve Categories for a User with the QueryBuilder in order to put the result in a form thanks to my CategoryRepository. Here is the corresponding SQL Statement (in the example I put 1 for the user_id but it is provided by $user->getId() in the CategoryRepository.
SELECT theCategoryObject
FROM category C, category_group CG, group G, user_group UG, user U
WHERE FU.id = 1
AND U.user_id = UG.user_id
AND UG.group_id = G.group_id
AND CG.group_id = G.group_id
AND CG.category_id = C.category_id
I tried to use EXISTS and MEMBER OF but it does not filter anything.
public function findByUserQueryBuilder(User $user)
{
$qb = $this->createQueryBuilder('c');
$qb->where('c.isSelectionable = true');
foreach ($user->getGroups() as $group)
{
$qb->andWhere('EXISTS (SELECT ' . $group->getId() . ' FROM ISIMA\Bundle\UserBundle\Entity\Group g' . $group->getId() . ' WHERE g' . $group->getId() . ' MEMBER OF c.groups)');
}
return $qb;
}
Thanks for your future answers !
Finally, I found the solution ! I forgot to define the group Id and place an Or condition in case of the User is part of several groups.
public function findByUserQueryBuilder(User $user)
{
$qb = $this->createQueryBuilder('c');
$qb->where('c.isSelectionable = true')
$i = 0;
foreach ($user->getGroups() as $group)
{
$query = 'EXISTS (SELECT 1 FROM ISIMA\Bundle\UserBundle\Entity\Group g' . $group->getId() . ' WHERE g' . $group->getId() . '.id = ' . $group->getId() . ' AND g' . $group->getId() . ' MEMBER OF c.groups)';
if($i == 0)
{
$qb->andWhere($query);
$i = 1;
}
else
{
$qb->orWhere($query);
}
}
return $qb;
}

how to search array words with Doctrine DQL using bucle

i'm trying to search words stored in array in this way:
$dql_cat =' SELECT c
FROM FrontendBundle:Categoria c
WHERE';
foreach ($palabras as $palabra){
if ($palabra === reset($palabras)){
$dql_cat .= ' c.nombre LIKE %'.$palabra.'%';
}
else{
$dql_cat .= ' OR c.nombre LIKE %'.$palabra.'%';
}
}
$dql_cat .= ' ORDER BY c.nombre';
$query = $em->createQuery($dql_cat);
$resultados['categorias'] = $query->getResult();
But i get an exception with the query.
Query result:
SELECT c
FROM FrontendBundle:Categoria c
WHERE c.nombre LIKE %carpinteria% OR c.nombre LIKE %aluminio% ORDER BY c.nombre
Query exception:
QueryException: [Syntax Error] line 0, col 98: Error: Expected StateFieldPathExpression | string | InputParameter | FunctionsReturningStrings | AggregateExpression, got '%'
I think that is more proper to use queryBuilder to avoid mistakes but i don't know how to use it with a parameters array.
I need a solution with or without queryBuilder.
Thanks.
queryBuilder would be as follows:
$qb = $em->createQueryBuilder();
$qb->select('c')
->from('FrontendBundle:Categoria', 'c');
foreach ($palabras as $palabra){
if ($palabra === reset($palabras)){
$qb->where($qb->expr()->like('c.nombre', $qb->expr()->literal('%' . $palabra . '%')));
}
$qb->orWhere($qb->expr()->like('c.nombre', $qb->expr()->literal('%' . $palabra . '%')));
}
$query = $qb->orderBy('c.nombre', 'ASC')
->getQuery();
$resultados['categorias'] = $query->getResult();
To begin with %$palabra% should be quoted, right?:
foreach ($palabras as $palabra){
if ($palabra === reset($palabras)){
$dql_cat .= " c.nombre LIKE '%".$palabra."%'";
}
else{
$dql_cat .= " OR c.nombre LIKE '%".$palabra."%'";
}
}

How to prevent `out of stock` items to show as a filter option in the sidebar (layered nav widget ) in WooCommerce?

I have 'hide out of stock' checked in the settings, however when using the layered navigation widget to filter results by shoe size, it is returning products which have that size listed as an attribute, but the size is out of stock. Is there a fix to this?
WordPress version 3.9.1, WooCommerce version 2.1.7
http://www.foten.se
He means not showing the products in the filter results. If a user filters by size M, he wants to see available size M products in the results, not All products that used to have a size M but dont anymore...
This is something woocommerce has not solved in years! and something that anyone opening a woocommerce store should know. I am sure most of them wont use woocommerce because of this issue alone.
I solve it by running the following script every night
$dir = dirname(__FILE__);
include_once($dir . '/../../../../wp-load.php');
$currentCount = 0;
$pageSize = 10;
global $wpdb;
$run = true;
while ($run) {
// select all variation of products with stock == 0
$sql = "SELECT * FROM `wpmf_postmeta` as pm
LEFT JOIN wpmf_posts as p on p.ID = pm.post_id
WHERE
meta_key = '_stock' and meta_value = 0
and p.post_parent <> 0 LIMIT $currentCount," . ($currentCount + $pageSize);
// var_dump($sql);die;
$res = $wpdb->get_results($sql, ARRAY_A);
if (!$res) { //|| $currentCount > 20
$run = false;
break;
}
foreach ($res as $r) {
$post_parent = $r['post_parent'];
$post_excerpt = $r['post_excerpt'];
$size = preg_replace('/[^0-9.]/', '', $post_excerpt);
// echo($post_parent . ", $size" . '<br>');
if ($size && $size != '') {
// find the term ID and delete it from parent product
$res_term = $wpdb->get_results("SELECT * FROM `wpmf_term_relationships` as tr
LEFT JOIN wpmf_terms as t on t.term_id = tr.term_taxonomy_id
where `object_id` = $post_parent and name = $size", ARRAY_A);
// var_dump($terms_rel);
if ($res_term) {
$query = "
DELETE FROM wpmf_term_relationships
WHERE term_taxonomy_id = " . $res_term[0]['term_id'] . "
AND object_id = " . $post_parent . "
";
$res_query = $wpdb->query(
$query);
echo($post_parent . ", $size, $res_query" . '<br>');
}
}
$currentCount++;
}
}
wp_cache_flush();
echo 'done! ' . $currentCount;
The problem this script fixes is: the sidebar filters the product by attribute but the stock is manage by product variation (child post).
The DB doesn't have a way to link the 2 fields, therefore it is not possible to create a query that filters attributes that has a matching variation with stock == 0.
Therefore this script solve the problem by deleting products attributes that have stock == 0
here is a opposite script to set an attribute for a product with stock > 0 and a missing attr:
$dir = dirname(__FILE__);
include_once($dir . '/../../../../wp-load.php');
$currentCount = 0;
$pageSize = 10;
global $wpdb;
$run = true;
while ($run) {
// select all varaition of a prod with stock > 0
$sql = "SELECT * FROM `wpmf_postmeta` as pm
LEFT JOIN wpmf_posts as p on p.ID = pm.post_id
WHERE
meta_key = '_stock' and meta_value <> 0
and p.post_parent <> 0 LIMIT $currentCount," . ($currentCount + $pageSize);
// var_dump($sql);die;
$res = $wpdb->get_results($sql, ARRAY_A);
if (!$res) { //|| $currentCount > 20
$run = false;
break;
}
foreach ($res as $r) {
$post_parent = $r['post_parent'];
$post_excerpt = $r['post_excerpt'];
$size = preg_replace('/[^0-9.]/', '', $post_excerpt);
if ($size && $size != '') {
// find the relevant term
$res_parent = $wpdb->get_results("SELECT * FROM `wpmf_term_relationships` as tr
LEFT JOIN wpmf_terms as t on t.term_id = tr.term_taxonomy_id
where `object_id` = $post_parent and name = $size", ARRAY_A);
// var_dump($terms_rel);
// if term is missing, create it
if (!$res_parent) {
wp_set_object_terms($post_parent, $size, 'pa_size', true);
echo($post_parent . ", $size" . '<br>');
}
$currentCount++;
}
}
}
wp_cache_flush();
echo 'done! ' . $currentCount;
NOTE:
this is not a proper solution to the problem - a solution should be at the design level, i.e. finding a way to link the 2 fields with an SQL query, this solution is a temp by-pass until a real solution is available
I didn't fully tested this code, I will update the answer if necessary in the future
I'm not fully familiar with the DB structure of wordpress or woocommerce, and the result of this code might change depending on different plugins, using this code is at your own risk
In WooCommerce, the default option is that, it shows all products that are in stock and out of stock on search results and the product category pages. This is a WooCommerce default functionality
Link regarding this:
https://github.com/woothemes/woocommerce/issues/5840
Also, not showing these products on the contrary is a bad idea, as it is not as per the best SEO practices.

Resources