Prestashop module SQL Query to get id_products from a specific feature value - sql

I'm currently working with a module called "Leo Parts Filter" on prestashop, which sort id_products by make, model, year and device in a database "ps_leopartsfilter_product".
When i call a make, model, year a device that have an id_product in this table, prestashop show this id_product.
public static $definition = array(
'table' => 'leopartsfilter_product',
'primary' => 'id_product',
'multilang' => false,
$sql = 'SELECT * FROM `' . _DB_PREFIX_ . 'leopartsfilter_product` WHERE 1=1 ';
if ($id_product != null && (int) $id_product) {
$sql .= ' AND id_product =' . (int) id_product;
}
I would like to change the way id_product is called, instead of calling only this id_product according this way :
I would like to query all products where the feature_id = 212 and where the feature_value_lang = id_product.
I tried to adapt this query but i can't make it work correctly (no data showing)
SELECT id_product, fl.name, value, pf.id_feature
FROM '._DB_PREFIX_.'feature_product pf
LEFT JOIN '._DB_PREFIX_.'feature_lang fl ON (fl.id_feature =212 AND fl.id_lang = '.(int)$context->language->id.')
LEFT JOIN '._DB_PREFIX_.'feature_value_lang fvl ON (fvl.id_feature_value = pf.id_feature_value AND fvl.id_lang = '.(int)$context->language->id.')
LEFT JOIN '._DB_PREFIX_.'feature f ON (f.id_feature = pf.id_feature)
'.Shop::addSqlAssociation('feature', 'f').'
WHERE fvl.`value` = '['id_product']'
GROUP BY id_product
ORDER BY f.position ASC
';
I'm not good at SQL so don't blame me, i learned everything by my way and i try to build my own company website, this module is all i need to finish.
If someone want some money for help, i'm open to give rewards to make it work.
Thanks

Your second query has nothing to do with the Leo Parts Filter module, since it only queries native Prestashop feature tables and not those of the Leo module itself, so your request is not very clear.
If you need to rely on basic features, it must be clear to you that the relationship between id features / id feature values and id products is all in the ps_feature_product table, so if you want products that have id_feature_value = 212 you just need a simple
SELECT id_product FROM ps_feature_product WHERE id_feature_value = 212;

Related

Display Product Combinations in Prestashop Customer View

I am trying to get the product combinations displayed in Prestashop admin Customer detail view in addition to the products that are displayed for the customer.
This seems to be the relevant call from AdminCustomersController.php in public form renderForm():
$products = $customer->getBoughtProducts();
Then in the Customer class I found the method:
public function getBoughtProducts()
{
return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
SELECT * FROM `'._DB_PREFIX_.'orders` o
LEFT JOIN `'._DB_PREFIX_.'order_detail` od ON o.id_order = od.id_order
WHERE o.valid = 1 AND o.`id_customer` = '.(int)$this->id);
}
How can I modify this method to show the product combination alongside the product name?
I am using Prestashop version 1.6.0.9.
you can get it using 2 ways:
order_detail table already have field 'product_name' that contains value like 'Product Name - Combination', so you can use $products['product_name'] in that case.
or
if for some reason it is not good for you, same table contains also product_attribute_id field, it is combination id, so:
$combination = new Combination($product['product_attribute_id']);
$attributes = $combination->getAttributesName($id_lang);
var_dump($attributes);
will give you array of attributes that current combination contains.

Magento SQL Query to show product manufacturer

I am trying to query the Product Manufacturer in Magento 1.7.0.2 . I browse again and again all the table to where I can get the manufacturer table and connect it with product SKU.
I try this query to hope that I can get the manufacturers of the product:
SELECT
eav_attribute_option_value.value FROM
eav_attribute,
eav_attribute_option,
eav_attribute_option_value
WHERE
eav_attribute.attribute_code = 'manufacturer' AND
eav_attribute_option.attribute_id = eav_attribute.attribute_id AND
eav_attribute_option_value.option_id = eav_attribute_option.option_id
but it is not equal to the product manufacturer when I compare the result to my magento admin product manufacturer.
My question is that what should I do to query so that I can get the list of manufacturers of the product so that I can sql join in with catalog_product_enity's SKU.
Does anyone has an idea about my case? I am new with magento so please be gentle with me.
Any help will be appreciated, Thanks in advance
I hope I understood correctly.
If you want to get the manufacturer for a product, you don't need any query.
This should work. Let's assume that you already have the product in var $_product;
$_product->getAttributeText('manufacturer');//this gets you the label
$_product->getManufacturer(); //gets the manufacturer id
[EDIT]
To get this for all the products do this:
$collection = Mage::getModel('catalog/product')->getCollection()
->addAttributeToSelect('manufacturer');
$collection->addAttributeToFilter('status', 1);//optional for only enabled products
$collection->addAttributeToFilter('visibility', 4);//optional for products only visible in catalog and search
foreach ($collection as $product) {
$sku = $product->getSku();
$manufacturerId = $product->getManufacturer();
$manufacturerLabel = $product->getAttributeText('manufacturer');
//do something with the values above - like write them in a csv or excel
}
Little late, but this is what I came up with. Works like a charm.
SELECT cpe.sku, cpev.value, cpf1.manufacturer_value
FROM catalog_product_entity cpe
JOIN catalog_product_entity_varchar cpev ON cpev.entity_id = cpe.entity_id
JOIN catalog_product_flat_1 cpf1 ON cpf1.entity_id = cpe.entity_id
WHERE cpev.attribute_id = 191

Query that joins just a single row from a ForeignKey relationship

I have the following models (simplified):
class Category(models.model):
# ...
class Product(models.model):
# ...
class ProductCategory(models.Model):
product = models.ForeignKey(Product)
category = models.ForeignKey(Category)
# ...
class ProductImage(models.Model):
product = models.ForeignKey(Product)
image = models.ImageField(upload_to=product_image_path)
sort_order = models.PositiveIntegerField(default=100)
# ...
I want to construct a query that will get all the products associated with a particular category. I want to include just one of the many associated images--the image with the lowest sort_order--in the queryset so that a single query gets all of the data needed to show all products within a category.
In raw SQL I would might use a GROUP BY something like this:
SELECT * FROM catalog_product p
LEFT JOIN catalog_productcategory c ON (p.id = c.product_id)
LEFT JOIN catalog_productimage i ON (p.id = i.product_id)
WHERE c.category_id=2
GROUP BY p.id HAVING i.sort_order = MIN(sort_order)
Can this be done without using a raw query?
Edit - I should have noted what I've tried...
# inside Category model...
products = Product.objects.filter(productcategory__category=self) \
.annotate(Min('productimage__sort_order'))
While this query does GROUP BY, I do not see any way to (a) get the right ProductImage.image into the QuerySet eg. HAVING clause. I'm effectively trying to dynamically add a field to the Product instance (or the QuerySet) from a specific ProductImage instance. This may not be the way to do it with Django.
It isn't quite a raw query, but it isn't quite public api either.
You can add a group by clause to the queryset before it is evaluated:
qs = Product.objects.filter(some__foreign__key__join=something)
qs.group_by = 'some_field'
results = list(qs)
Word of caution, though: this behaves differently depending on the db backend.
catagory = Catagory.objects.get(get_your_catagory)
qs = Product.objects.annotate(Min('productimage__sortorder').filter(productcategory__category = catagory)
This should hit the DB only once, because querysets are lazy.

yii cdbcriteria: complex joins

I recently started a project using Yii and I'm trying to get used to the query builder. Now, I want to make a query using joins and access the joining tables' data in the query but I haven't been able to get the following to work:
My (simplified) db-tables:
customer(#id, name)
employee(#id, name)
customer_employee(#customerid, #employeeid)
accounting(#id, customerid, started_date, finished_date, month, year)
many-to-many relation between customer and employee
one-to-many relation between customer and accounting
I want to execute the following query, which would select all the customers associated with a certain employee and display their accounting status (started_date & finished_date) if applicable (otherwise null).
The following query works perfectly, it's just that I can't get it to work with the cdbcriteria and Yii query builder: (also, hardcoded id is just for this example)
SELECT name, started_date, finished_date
FROM customer
RIGHT JOIN customer_employee ON customer.id=customer_employee.customerid
LEFT JOIN accounting ON customer.id=accounting.customerid
WHERE customer_employee.employeeid=2';
Please help!
1.
createCommand
Yii::app()->db->createCommand()
->select('name, started_date, finished_date')
->from('customer c')
->rightJoin('customer_employee ce', 'c.id=ce.customerid')
->leftJoin('accounting a', 'c.id=a.customerid')
->where('ce.employeeid=:id', array(':id'=>2))
->queryRow();
2.
CdbCriteria
$criteria = new CDbCriteria;
$criteria->select = 'name, started_date, finished_date';
$criteria->join = 'RIGHT JOIN customer_employee ON customer.id=customer_employee.customerid ';
$criteria->join .= 'LEFT JOIN accounting ON customer.id=accounting.customerid';
$criteria->condition = 'customer_employee.employeeid=:id';
$criteria->params = array(':id'=>2);
$customers = Customers::model()->find($criteria);
*.
don't forget the rules: http://www.yiiframework.com/doc/guide/1.1/en/database.arr
I didn't tested your SQLs, but if worked for you, these should, also work in Yii.
$criteria = new CDbCriteria();
$criteria->select = "name, started_date, finished_date";
$criteria->join = "RIGHT JOIN customer_employee ON customer.id=customer_employee.customerid LEFT JOIN accounting ON customer.id=accounting.customerid";
$criteria->condition = "customer_employee.employeeid=2";
$models = Customer::model()->findAll($criteria);
This is how to get data with command for table customer_employee
foreach($model as $value)
{
}
A bit late in the day but see this post on my blog which addresses both parts of this difficult sub-query style SQL.
Firstly, to build a Search that relies on attributes from other models
Secondly, to use related models simply without using the full Yii AR model
http://sudwebdesign.com/yii-parameterising-a-sub-select-in-sql-builder/932
I have not run it but some thing like the following is what you need
$criteria = new CDbCriteria();
$criteria->select = "name, started_date, finished_date";
$criteria->join = "RIGHT JOIN customer_employee ON customer.id=customer_employee.customerid LEFT JOIN accounting ON customer.id=accounting.customerid";
$criteria->condition = "customer_employee.employeeid=2";
$models = Customer::model()->findAll($criteria);

How to Write a SQL Query to Display list of most used tags in the last 30 days in Wordpress website

I am looking for a way to display the most used tags over the last 30 days on my Baseball blog, built on Wordpress. I am no coder, but I have come up with this mashup to display a list of the most used 28 tags (preference to fit my theme). I cannot, for the life of me, figure out how to limit the tags to the most used in the last 30 days.
Here is what I have:
<ul id="footer-tags">
<?php
global $wpdb;
$term_ids = $wpdb->get_col("
SELECT DISTINCT term_taxonomy_id FROM $wpdb->term_relationships
INNER JOIN $wpdb->posts ON $wpdb->posts.ID = object_id
WHERE DATE_SUB(CURDATE(), INTERVAL 30 DAY) <= $wpdb->posts.post_date");
if(count($term_ids) > 0){
$tags = get_tags(array(
'orderby' => 'count',
'order' => 'DESC',
'number' => 28,
'include' => $term_ids,
));
foreach ( (array) $tags as $tag ) {
echo '<li>' . $tag->name . '</li>';
}
}
?>
</ul>
The website is slightly less than ~4 weeks old, so to test, I changed INTERVAL 30 DAY to INTERVAL 3 DAY and the tags being returned seem random and some haven't been used in 2+ weeks and have only been used a single time. As well, only 8 tags are being displayed, when more have been used.
To check that the correct number of days have been queried, I did the following:
Completely deleted all items in the trash for posts and pages, I don't have any custom post types.
Did the same with drafts.
Ran a query in phpmyadmin to delete all post revisions - DELETE FROM wp_posts WHERE post_type = "revision";
Ran a query in phpmyadmin to check if the results are the posts from the last 3 days - SELECT * from wp_posts WHERE DATE_SUB(CURDATE(), INTERVAL 3 DAY) <= post_date
The results from the phpmyadmin query were, in fact, the posts from the last 3 days, but the front-end display did not change.
UPDATE
Here are some screen shots. Maybe the screenshots can help find where my code is wrong.
Blog Post with Category and Tags
wp_posts table with the post ID of above post
wp_terms table with the term_id of the tags used
wp_term_taxonomy with the tags' term_id as term_taxonomy_id
wp_term_relationships with term_taxonomy_id assigned to post as object_id
UPDATE 2
I think I figured out the problem, but do not know how to fix it.
The SQL query gets the term_taxonomy_id, not the actual tag ID and get_tag_link uses term_id
UPDATE 3
I have recently created a plugin to display the most popular recently used tags - https://wordpress.org/plugins/recent-popular-tags/
The PHP variables you are inserting in your SQL string are the PHP objects that can be used to access WordPress tables from within PHP; whereas you are after the names of the tables and columns for accessing the data from within SQL.
You want instead:
"SELECT DISTINCT term_taxonomy_id FROM wp_term_relationships
INNER JOIN wp_posts ON wp_posts.ID = wp_term_relationships.object_id
WHERE DATE_SUB(CURDATE(), INTERVAL 30 DAY) <= wp_posts.post_date"
As an aside: should you ever need to insert the value of a PHP variable into a SQL statement, be very careful to escape it first in order to prevent any malicious code from being injected.
The problem was that the SQL query code was getting the term_taxonomy_id, not the actual tag ID.
I added an additional INNER JOIN using the term_taxonomy table to get the term_id. This seems to work, but if a mod can improve this, please do!
<ul id="footer-tags">
<?php $wpdb->show_errors(); ?>
<?php
global $wpdb;
$term_ids = $wpdb->get_col("
SELECT term_id FROM $wpdb->term_taxonomy
INNER JOIN $wpdb->term_relationships ON $wpdb->term_taxonomy.term_taxonomy_id=$wpdb->term_relationships.term_taxonomy_id
INNER JOIN $wpdb->posts ON $wpdb->posts.ID = $wpdb->term_relationships.object_id
WHERE DATE_SUB(CURDATE(), INTERVAL 30 DAY) <= $wpdb->posts.post_date");
if(count($term_ids) > 0){
$tags = get_tags(array(
'orderby' => 'count',
'order' => 'DESC',
'number' => 28,
'include' => $term_ids,
));
foreach ( (array) $tags as $tag ) {
echo '<li>' . $tag->name . '</li>';
}
}
?>
</ul>
UPDATE
I have recently created a plugin to display the most popular recently used tags - https://wordpress.org/plugins/recent-popular-tags/