Set Magento Product Group Permissions Programatically - php

When you edit a Product in Magento there is a Permissions tab with two multi-selects on it.
Disable product for
and
Hide product price for
We need to set the Disable product groups programatically by including 'Mage.php' and using a script to update the Disabled Groups.
For example we want to Disable a product for 10 specific groups for a product. We've been able to do pretty much everything else you can do in the Admin Interface in script so there should be a way to access this using Mage::getModel('catalog/product') or another Model. Call a function, pass in the group ID's you want to set the product to disabled for.
But can't seem to track it down.
Thanks!

Found where the data is stored in the database and just ended up modifying the database directly.
$groupsDisabledArray is an array that contains an ID for each group I want to disable product permissions for. The data in magento is simply stored as a comma separated list of Group ID's
Example:
1,2,3,4,5,6,7,8,9,10
So I implode my disabled group ID's array to get a comma separated list
$groupsList=implode(",", $groupsDisabledArray);
Then either insert or update the catalog_product_entity_text table which is where the value is stored.
The value is stored in catalog_product_entity_text where
entity_id = PRODUCT_ID
attribute_id = 155 (This corresponds to the table eav_attribute where attribute_code = 'aw_cp_disable_product')
entity_type_id = 4 (This corresponds to table eav_entity_type where entity_type_code = 'catalog_product')
store_id = STORE_ID (If you just have one store you should just be able to put 0 here for the Default Store)
Code to do the complete update below. May need to update the path to Mage.php depending where you put your script.
include("/app/Mage.php");
/* Get DB Connections */
$resource = Mage::getSingleton('core/resource');
$readConnection = $resource->getConnection('core_read');
$writeConnection = $resource->getConnection('core_write');
$tableName = $resource->getTableName('catalog_product_entity_text');
/* $groupsDisabledArray - Array of all of the Magento Group ID's I want to disable this product for */
$groupsList=implode(",", $groupsDisabledArray);
$sql="SELECT * FROM $tableName WHERE entity_id=$product_id AND attribute_id=155 and entity_type_id=4 AND store_id=0;";
$results = $readConnection->fetchAll($sql);
if (count($results) > 0) {
$sql="UPDATE $tableName SET value='$groupsList' WHERE entity_id=$product_id AND attribute_id=155 and entity_type_id=4 AND store_id=0;";
}
else
{
$sql="INSERT INTO $tableName (entity_id, entity_type_id, store_id, attribute_id, value) VALUES ($product_id, 4, 0, 155, '$groupsList')";
}
$writeConnection->query($sql);

Related

How can I change order values in a table when inserting a new row with a higher order value?

Using php and mysqli, I have a categories table that group products and control the order they are displayed in my catalog. The field "ord" is an int with the value that controls the order these product categories are displayed. When inserting a new category, I would like to reorder the remaining categories from the new category down and update the table then insert the new category without duplicating the "ord" value.
There are 11 categories. I want to insert my new category with it's "ord" value as 5. Clearly I need to add 1 to each "ord" values 6 - 11 to reorder my catalog. Not sure how to do this. I'm not good with arrays but I would think some sort of foreach array[$key][] + 1 with an UPDATE to the table would work. I'm not clear on how to create the array.
Don't really have any working ideas on this...
Category ord=1: Site Licensing
Category ord=2: PICC Insertion Training
Category ord=3: Ultrasound Training
New Category: ord 2: Membership Subscriptions
Category ord=1: Site Licensing
Category ord=2: Membership Subscriptions
Category ord=3: PICC Insertion Training
Category ord=4: Ultrasound Training
You can simply update the table before doing the INSERT. By updating the existing data first, you leave a space for your new entry.
$order = $_POST['order'];
$stmt = $mysqli->prepare("UPDATE `categories` set order = order + 1 where order >= ?"));
$stmt->bind_param("i", $order);
$stmt->execute();
/** Now perform INSERT statement */

Get values from CSV file and search MySQL database

I have a query a Wordpress include which does the following:
$sql = "SELECT DISTINCT meta_value FROM $wpdb->postmeta WHERE meta_key = 'merchant_id' LIMIT 6";
$results = $wpdb->get_results($sql);
foreach ($results as $row)
{
echo $row->meta_value . ",";
//sprintf("SELECT * FROM retailers WHERE advertiserId = '%s'", $row->meta_value);
}
//clean all results
$wpdb->flush();
It parses all pages custom fields (merchant ID numbers), and returns any unique distinct values, separated by a comma. This bit works great.
ie: The above may return: 1301,345,723,134,1435
What I also have is a separate MySQL table of about 20 fields, three of which are the MerchantID, programmeName, and commissionMax. Each value from the CSV correlates with the MerchantID in the database.
Regardless of the amount of merchant ID's that appear in the CSV - I need to parse them all, but show the three highest commission rates (commissionMax), as well as the programmeName.
I managed to get connected to my external database and retrieve the appropriate values (using the commented code above) however this showed all of the retailers information.
Any advice?
Use the following query with limit:
SELECT * // select all fields
FROM table_name // from your table
WHERE MerchantID IN (your_ids_here) // IDs received from previous query or wherever
ORDER BY commissionMax DESC // descending sort by commissionMax field
LIMIT 3 // take first 3 results

Checking for record in MySQL and create if not exist

When I click a buy now button I'm checking to see if the record (product id) exists in my mysql database table and if they don't create another one and if they do, just update the existing one.
It creates the first record fine and it even updates when I click it again without making another record, but when I click another product it creates another record and it never updates the following records.
In other words it just updates the first product id and it creates new records for the rest.
here is an image of my table
function add_to_cart(){
global $connection;
$ip = getIp();
if(isset($_GET['add'])) {
$product_id = $_GET['id'];
$product_price = get_item_price($product_id);
$query = "SELECT * FROM cart WHERE ip_address = '{$ip}' ";
$check_query = query($query);
confirm($check_query);
$row = fetch_array($check_query);
$db_product_id = $row['product_id'];
if(mysqli_num_rows($check_query) === 0 || $product_id != $db_product_id) {
$query = "INSERT INTO cart(product_id,ip_address,quantity,price_sum) VALUES('{$product_id}', '{$ip}' ,1, '{$product_price}')";
$send_query_cart = query($query);
confirm($send_query_cart);
redirect("index.php");
} else {
$query = "UPDATE cart SET quantity = quantity + 1, price_sum = price_sum + '{$product_price}' WHERE product_id = '{$product_id}' ";
$update_records = query($query);
confirm($update_records);
redirect("index.php");
}
}
}
Probably the best solution is to create a UNIQUE constraint on (I am assuming) product_id and ip_address.
ALTER TABLE `cart` ADD UNIQUE `unique_index`(`ip_address`, `product_id`);
Then, I would not store the price of items in the cart at all. The price of an item can be looked up in your items table. When an order is completed you can save the price of the individual item since it could change, but while it's in the cart you want the most recent price.
Once you have done that, your query can be simplified to
$query = "INSERT INTO cart(product_id,ip_address,quantity)
VALUES ('{$product_id}', '{$ip}', 1)
ON DUPLICATE KEY UPDATE
quantity = quantity+1";
and you don't even have to check it - the query will handle the update or insert automatically.
Also, I wouldn't rely on ip_address to identify users - if someone is shopping on their phone while riding in a car, it could easily change. Two people on the same router can appear to have the same ip address to your website. I would save something in the session or in a secure cookie and use that to identify them.
To get the totals, you would do something like:
$totals = "SELECT cart.product_id, cart.quantity * products.price as product_price_total
FROM cart
LEFT JOIN products USING(products.id = cart.product_id)
WHERE ip_address = '{$ip}'";

How to move comma seperated ids from one row to another row?

I have a database table like this
Id user_id folder product_ids
1 4 test1 2,3,4
2 4 test2 7,8,9
3 4 test3 10,11,12
Here I have saved product ids comma separated.Users have created their folders like this and wanted to move one or more products to another folder. Let say if user want he can select product id(8) and move it from test2 to test3 and the result set will look like this:
Id user_id folder product_ids
1 4 test1 2,3,4
2 4 test2 7,9
3 4 test3 10,11,12,8
How can I do it with sql and php?
Unfortunately, MySQL doesn't have a built-in REPLACE by REGEX :(
NOTE :
Please, update PRODUCT_TABLE by your Table Name
Here is a solution :
<?
/**
* #param String $folderSrc
* #param String $folderDst
* #param String $movedProductIds
* #param String $userId
* #return String Built SQL Query
*/
function buildSqlQueryMoveProductId ($folderSrc, $folderDst, $movedProductIds, $userId) {
return
"UPDATE PRODUCT_TABLE
SET PRODUCT_IDS =
CASE
WHEN FOLDER = '" . $folderSrc . "' THEN (REPLACE (REPLACE (REPLACE (PRODUCT_IDS, '," . $movedProductIds . "', ''), '" . $movedProductIds . ",', ''), '" . $movedProductIds . "', ''))
WHEN FOLDER = '" . $folderDst . "' THEN (CONCAT (IF (LENGTH(PRODUCT_IDS) > 0, CONCAT (PRODUCT_IDS, ','), '' ), '" . $movedProductIds . "'))
ELSE PRODUCT_IDS
END
WHERE USER_ID = " . $userId;
}
// Example
print moveProductId ('test1', 'test2', '3', 4);
Try not to store comma separated values in one column.
MySQL can perfectly handle large tables, so you could enter each product ID as a separate row.
You could also create multiple tables, say one holds the folder data.
Then another table could hold the primary keys of the folder table, along with the product IDs, and the user ID.
The more you store in a single table, the less organised it becomes.
I am not sure what's best performance-wise, but organisation is key, especially later on.
EDIT:
So let's say you create a table like this:
ID User_ID Folder Product_ID
1 4 test1 2
2 4 test2 7
3 4 test3 10
You could now simply look for the Product_ID, and UPDATE the folder name.
So when you pass the Product ID on to the update script, you could use a query somewhat like this:
UPDATE your_table_name SET Folder = :folder WHERE Product_ID = :pid
Then bind the folder name and product ID.
Please read this about PDO if you're unfamiliar with prepared statements.
I would recommend binding the values, as you're talking about user input, which can always be manipulated, causing a possible security breach.
<?php
/*Fetch your product ids and you will return sting of ids like "1,2,3,4,5,6,7"
*
*/
// product Ids. From where you want to remove id
$productOne="1,2,3,4,5";
// product Ids, From where you want to put id
$productTwo="6,7,8,9";
//product 1 array
$productOneArray=explode(",",$productOne);
//product 2 array
$productTwoArray=explode(",",$productTwo);
//Id which you want to change
$movingId = "5";
//Let's remove your product.
foreach ($productOneArray as $key=>$id){
if($id == $movingId){
unset($productOneArray[$key]);
}
}//BINGO !! you remove your id
//Add it to another product ids
array_push($productTwoArray,$movingId);
//Bingo You did it
//now turn both into string
$productOne=implode(",",$productOneArray);
$productTwo=implode(",",$productTwoArray);
//Update both the values in database
?>
If you need more help in hindi or gujrati, you can ask me.
If you want to move multiple ids
<?php
$name="parag";
if($name=="parag"){
echo uniqid().$name;
}
?>
<script>
$("div").css("width", "100px");
$("div").css("height", "100px");
</script>
<?php
echo "<pre>";
/*Fetch your product ids and you will return sting of ids like "1,2,3,4,5,6,7"
*
*/
// product Ids. From where you want to remove id
$productOne="1,2,3,4,5";
// product Ids, From where you want to put id
$productTwo="6,7,8,9";
//product 1 array
$productOneArray=explode(",",$productOne);
//product 2 array
$productTwoArray=explode(",",$productTwo);
//Id which you want to change
$movingId = "2,3,4";
$movingIdArray = explode(",", $movingId);
//Let's remove your product.
foreach($movingIdArray as $movingIds){
foreach ($productOneArray as $key=>$id){
if($id == $movingIds){
unset($productOneArray[$key]);
}
}//BINGO !! you remove your id
}
print_r($productOneArray);
//Add it to another product ids
array_push($productTwoArray,$movingId);
//Bingo You did it
//now turn both into string
$productOne=implode(",",$productOneArray);
$productTwo=implode(",",$productTwoArray);
//Update both the values in database
echo "productOne = ".$productOne."<br />";
echo "productTwo = ".$productTwo."<br />";
?>
Why don't you use json_encode() while adding product_ids.
When you insert product id just encode it and save. & while moving from folder read that json and decode it.
Add or remove respective ids from json then again save to database
You got answers on how to achieve this with php-code. But you really should normalize your database. A normalized database only contains tables where each table holds data describing a certain entity and relates to other entities through foreign-keys. You already did this by connecting your user-data through the foreign key "user_id", now move on and refactor your table to the other entities "folder" and "product".
Your final schema may look like this:
Table users
user_id
user_name
etc.
Table folders
folder_id
folder_name
user_id
etc.
Table products
product_id
folder_id
product_name
etc.
With this, to move a product from one folder to another, just change the folder_id of a record from products-table.
To fetch all products from one folder you use joins:
SELECT folders.*, products.* from products
JOIN folders on folders.folder_id = products.folder_id
WHERE folders.folder_id = your_desired_folder_id
Read more on database-normalization with lots of examples and reasons why to do this (despite the problems you are already facing) here:
http://www.dbnormalization.com/
Regards,
jojo

Insert Value From One Table to Another on Update MySql, PHP

I was wondering if there was a way to take one value from a column in a Table and add it to a column in another table.
The Scenario: I have a table (Shopping_Cart). It stores all of my customers shopping cart items in the columns CustomerID, PID, Price, Status (Status can be "IN_CART" which means it was added and "OPEN" means that it has been paid for and ready to be processed and shipped). Then I have a table (Products). It stores product information in columns PID, Price,Weight`. When My customers place an item in the shopping cart I do not capture the price. Prices can change daily so if they add something today, when they come back tomorrow the price may increase or decrease in their shopping cart. When my customer checks out and payment is confirmed, I am trying to grab the Price in the (Products) table where Products.PID = Shopping_Cart.PID and then apply that price to the Shopping_Cart.Price to lock in that final price since the customer has paid for it. Any Ideas? I got it set up to change the items for that customers cart to "OPEN" but I am a little lost on getting my script to grab a value from one table and applying it to another table. Below is my PHP Script for changing the Lines from "IN_CART" to "OPEN".
if($The_Function=="CLOSE_LINES"){
$cart_close_session_id = $_GET['close_session_id'];
$response = array();
require_once __DIR__ . '/db_connect.php';
//connect to my db
$db = new DB_CONNECT();
$result = mysql_query("UPDATE shopping_cart SET Status = 'OPEN' WHERE SessionID LIKE '$cart_close_session_id' AND Status LIKE 'IN_CART'");
if ($result) {
$response["close_success"] = 1;
//GRAB PRICE FROM "PRODUCTS TABLE" AND UPDATE SHOPPING_CART
}else{
$response["close_success"] = 0;
}
echo json_encode($response);
}
Assuming that you have a *shopping_cart* table with a price and a product_id column, you can update it with the price of the products table, like this:
UPDATE shopping_cart SET price =
(SELECT price FROM products WHERE id = shopping_cart.product_id)
You can join against the products table and update the shopping_cart upon purchase as seen below:
UPDATE shopping_cart c
JOIN products p
ON p.pid = c.pid
SET c.price = p.price
WHERE c.customer_id = ?

Categories