In a Prestashop Ecommerce website I have a module that was created specially to compare and set products price in my website,
I need some help understand some of his PHP code.
The followng code set the price of a product in my website after scanning and finding the minumum price in other website link providede at the product backend page:
My Question is: How does this code works? where is the part of the code that scan the other website and get the minumum price in it?
<?php
class ProductCMP extends Module
{
public function __construct()
{
$this->name = 'productcmp';
$this->tab = 'front_office_features';
$this->version = '1.0.0';
$this->author = 'biznesownia';
parent::__construct();
$this->displayName = $this->l('ProductCMP', FALSE, NULL);
}
public function install()
{
return parent::install()
and $this->registerHook('displayAdminProductsExtra')
and $this->registerHook('actionAdminProductsControllerSaveAfter');
}
public function hookDisplayAdminProductsExtra($params)
{
$product = new Product((int) Tools::getValue('id_product'), false);
$tpl = $this->context->smarty->createTemplate(dirname(__FILE__).'/templates/tab.tpl', $this->context->smarty);
$tpl->assign('product', $product);
return $tpl->fetch();
}
public function hookActionAdminProductsControllerSaveAfter($params)
{
# set data
$id_product = (int) Tools::getValue('id_product');
$product = new Product($id_product, false, (int) $this->context->language->id);
$product->compare_active = (bool) Tools::getValue('compare_active', false);
$product->compare_link = (string) Tools::getValue('compare_link', '');
$product->compare_price = (string) Tools::getValue('compare_price', 0);
return $product->save();
}
public function compare()
{
define('PRODUCT_COMPARE_EMAIL', 'uditools#gmail.com');
set_time_limit(60*60);
# get list
$products = Db::getInstance()->executeS("
SELECT p.`id_product`, pl.`name`
FROM `"._DB_PREFIX_."product` p
LEFT JOIN `"._DB_PREFIX_."product_lang` pl ON (p.`id_product` = pl.`id_product` ".Shop::addSqlRestrictionOnLang('pl').")
WHERE
pl.`id_lang` = ".(int)$this->context->language->id."
AND p.`compare_active`=1
ORDER BY p.`id_product`
");
# job
$report = array();
foreach($products as $p)
{
try
{
$result = $this->_compareProduct((int) $p['id_product']);
if($result && $result['changed'])
{
$result['id_product'] = $p['id_product'];
$result['name'] = $p['name'];
$report[] = $result;
}
}
catch(Exception $e)
{
$report[] = array(
'id_product' => $p['id_product'],
'name' => $p['name'],
'res' => false,
'msg' => 'Exception occured',
);
}
}
# if there is nothing to report
if(!$report)
return true;
# output
$output = '';
foreach($report as $row)
{
$link = $this->context->link->getProductLink($row['id_product']);
$output .= $row['id_product'] .' - '. $row['name'] .' '. ($row['res'] ? 'Ok!' : 'Error!') .' : '. $row['msg'] ."\r\n";
}
# send mail
$tpl_vars = array(
'{report_txt}' => strip_tags($output),
'{report_html}' => nl2br($output),
);
Mail::Send(
$this->context->language->id,
'report',
'Price update report',
$tpl_vars,
PRODUCT_COMPARE_EMAIL,
'',
Configuration::get('PS_SHOP_EMAIL'),
Configuration::get('PS_SHOP_NAME'),
null,
null,
dirname(__FILE__).'/mails/',
null,
$this->context->shop->id
);
return true;
}
public function compareTest($id_product)
{
$report = $this->_compareProduct($id_product);
var_dump($report);
die;
}
protected function _compareProduct($id_product)
{
# load product
$product = new Product($id_product, false, $this->context->language->id, $this->context->shop->id);
if(!Validate::isLoadedObject($product))
return false;
if(!$product->compare_link)
return false;
$oldPrice = (float) $product->price;
//******
# request
$data = file_get_contents($product->compare_link);
# analize price
if(!preg_match('!data-free-data=\'([^\']+)\'!i', $data, $matches))
{
return array(
'res' => false,
'msg' => 'Price not found!',
);
}
//******
$prices = json_decode($matches[1], true);
$newPrice = (float) $prices['minPrice'];
if(!$newPrice)
{
return array(
'res' => false,
'msg' => 'Zero price!',
);
}
# check change
$changed = $oldPrice != $newPrice;
if(!$changed)
{
return array(
'res' => false,
'msg' => 'The price is the same.',
);
}
$newPrice += (float) $product->compare_price;
# check change
$changed = $oldPrice != $newPrice;
if(!$changed)
{
return array(
'res' => false,
'msg' => 'The price is the same.',
);
}
# update
$product->price = $newPrice;
if(!$product->save())
{
return array(
'res' => false,
'msg' => 'Not saved!',
);
}
return array(
'res' => true,
'changed' => $changed,
'msg' => 'Updated! From: '.round($oldPrice, 2).' To: '.round($newPrice, 2),
);
}
}
There are needed function
protected function _compareProduct($id_product)
{
# load product
$product = new Product($id_product, false, $this->context->language->id, $this->context->shop->id);
if(!Validate::isLoadedObject($product))
return false;
if(!$product->compare_link)
return false;
$oldPrice = (float) $product->price;
//******
# request
$data = file_get_contents($product->compare_link);
# analize price
if(!preg_match('!data-free-data=\'([^\']+)\'!i', $data, $matches))
{
return array(
'res' => false,
'msg' => 'Price not found!',
);
}
//******
$prices = json_decode($matches[1], true);
$newPrice = (float) $prices['minPrice'];
if(!$newPrice)
{
return array(
'res' => false,
'msg' => 'Zero price!',
);
}
# check change
$changed = $oldPrice != $newPrice;
if(!$changed)
{
return array(
'res' => false,
'msg' => 'The price is the same.',
);
}
$newPrice += (float) $product->compare_price;
# check change
$changed = $oldPrice != $newPrice;
if(!$changed)
{
return array(
'res' => false,
'msg' => 'The price is the same.',
);
}
# update
$product->price = $newPrice;
if(!$product->save())
{
return array(
'res' => false,
'msg' => 'Not saved!',
);
}
return array(
'res' => true,
'changed' => $changed,
'msg' => 'Updated! From: '.round($oldPrice, 2).' To: '.round($newPrice, 2),
);
}
Related
I make a parser of items from DotA 2 user inventory in the Steam service. Every time I try to parse user data, I get an empty value:
{"success":true,"items":[]}, but there are items in my Steam inventory.
My function to parse items:
public function loadMyInventory() {
if(Auth::guest()) return ['success' => false];
$prices = json_decode(Storage::get('prices.txt'), true);
$response = json_decode(file_get_contents('https://steamcommunity.com/inventory/'.$this->user->steamid64.'/570/2?l=russian&count=5000'), true);
if(time() < (Session::get('InvUPD') + 5)) {
return [
'success' => false,
'msg' => 'Error, repeat in '.(Session::get('InvUPD') - time() + 5).' сек.',
'status' => 'error'
];
}
//return $response;
$inventory = [];
foreach($response['assets'] as $item) {
$find = 0;
foreach($response['descriptions'] as $descriptions) {
if($find == 0) {
if(($descriptions['classid'] == $item['classid']) && ($descriptions['instanceid'] == $item['instanceid'])) {
$find++;
# If we find the price of an item, then move on.
if(isset($prices[$descriptions['market_hash_name']])) {
# Search data
$price = $prices[$descriptions['market_hash_name']]*$this->config->curs;
$class = false;
$text = false;
if($price <= $this->config->min_dep_sum) {
$price = 0;
$text = 'Cheap';
$class = 'minPrice';
}
if(($descriptions['tradable'] == 0) || ($descriptions['marketable'] == 0)) {
$price = 0;
$class = 'minPrice';
$text = 'Not tradable';
}
# Adding to Array
$inventory[] = [
'name' => $descriptions['market_name'],
'price' => floor($price),
'color' => $this->getRarity($descriptions['tags']),
'tradable' => $descriptions['tradable'],
'class' => $class,
'text' => $text,
'classid' => $item['classid'],
'assetid' => $item['assetid'],
'instanceid' => $item['instanceid']
];
}
}
}
}
}
Session::put('InvUPD', (time() + 5));
return [
'success' => true,
'items' => $inventory
];
}
But should return approximately the following value:
{"success":true,"items":[{"classid":"2274725521","instanceid":"57949762","assetid":"18235196074","market_hash_name":"Full-Bore Bonanza","price":26}]}
Where my mistake?
First of all, you are iterating on descriptions for every assets, which is assets*descriptions iteration, it's quite a lot, but you can optimize this.
let's loop once for descriptions and assign classid and instanceid as object key.
$assets = $response["assets"];
$descriptions = $response["descriptions"];
$newDescriptions=[];
foreach($descriptions as $d){
$newDescriptions[$d["classid"]][$d["instanceid"]] = $d;
}
this will give as the ability to not loop over description each time, we can access the description of certain asset directly $newDescriptions[$classid][$instanceid]]
foreach($assets as $a){
if(isset($newDescriptions[$a["classid"]]) && isset($newDescriptions[$a["classid"]][$a["instanceid"]])){
$assetDescription = $newDescriptions[$a["classid"]][$a["instanceid"]];
$inventory = [];
if(isset($prices[$assetDescription["market_hash_name"]])){
$price = $prices[$assetDescription['market_hash_name']]["price"]*$this->config->curs;
$class = false;
$text = false;
if($price <= $this->config->min_dep_sum) {
$price = 0;
$text = 'Cheap';
$class = 'minPrice';
}
if(($assetDescription['tradable'] == 0) || ($assetDescription['marketable'] == 0)) {
$price = 0;
$class = 'minPrice';
$text = 'Not tradable';
}
$inventory["priceFound"][] = [
'name' => $assetDescription['market_name'],
'price' => floor($price),
'color' => $this->getRarity($assetDescription['tags']),
'tradable' => $assetDescription['tradable'],
'class' => $class,
'text' => $text,
'classid' => $a['classid'],
'assetid' => $a['assetid'],
'instanceid' => $a['instanceid']
];
}else{
$inventory["priceNotFound"][] = $assetDescription["market_hash_name"];
}
}
}
About your mistake:
are you Sure your "prices.txt" contains market_hash_name?
I don't see any other issue yet, operationg on the data you have provided in comment, I got print of variable $assetDescription. Please doublecheck variable $prices.
Please tell me why I have a " Declaration of BlockRealization::updatePosition($way, $position, $id) should be compatible with ModuleCore::updatePosition($id_hook, $way, $position = NULL)"
I have this code in module.php
A similar question was here
Prestashop custom admin module draggable sort/order not working?
Under my code in module.php
<?php
if (!defined('_PS_VERSION_')) exit;
class BlockRealization extends Module {
protected $_html = '';
public function __construct() {
$this->name = 'blockrealization';
$this->tab = 'front_office_features';
$this->version = '1.0.0';
$this->author = 'XXX';
$this->need_instance = 0;
$this->ps_versions_compliancy = array('min' => '1.6', 'max' => _PS_VERSION_);
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->l('Module realization');
$this->description = $this->l('Display realization on homepage.');
$this->confirmUninstall = $this->l('Are you sure you want to uninstall?');
}
public function install() {
if (!parent::install() ||
!$this->registerHook('displayHeader') ||
!$this->registerHook('home') ||
!$this->createTables()
)
return false;
return true;
}
public function uninstall() {
if (!parent::uninstall() ||
!$this->removeTable())
return false;
return true;
}
protected function createTables() {
/* Realization */
$res = (bool)Db::getInstance()->execute('
CREATE TABLE IF NOT EXISTS `'._DB_PREFIX_.'realization` (
`id_realization_slides` int(10) unsigned NOT NULL AUTO_INCREMENT,
`image_realization` varchar(255) NOT NULL,
`position` int(10) unsigned NOT NULL,
PRIMARY KEY (`id_realization_slides`, `image_realization`)
) ENGINE='._MYSQL_ENGINE_.' DEFAULT CHARSET=UTF8;
');
return $res;
}
protected function removeTable() {
if (!Db::getInstance()->Execute('DROP TABLE `'. _DB_PREFIX_ . 'realization`'))
return false;
return true;
}
public function getContent() {
$output = null;
if (Tools::isSubmit('submit'.$this->name)) {
$errors = '';
if ($_FILES) {
$helper = new HelperImageUploader('realization_img');
$files = $helper->process();
if ($files) {
foreach ($files as $file) {
if (isset($file['save_path'])) {
if (!ImageManager::checkImageMemoryLimit($file['save_path']))
$errors = Tools::displayError('Limit');
if (!$errors) {
if (!ImageManager::resize($file['save_path'], dirname(__FILE__) . '/img/' . $file['name']))
$errors = Tools::displayError('error');
else {
$previous_file = Configuration::get('realization_img');
$file_path = dirname(__FILE__) . '/img/' . $previous_file;
if (file_exists($file_path))
unlink($file_path);
$realization['image_realization'] = $file['name'];
$realization['position'] = count($this->getAll());
if (!Db::getInstance()->insert('realization', $realization))
$errors = Tools::displayError('error');
}
}
unlink($file['save_path']);
}
}
}
}
if ($errors)
$output .= $this->displayError($errors);
else
$output .= $this->displayConfirmation($this->l('Settings updated'));
}
$output .= $this->generateList();
$output .= $this->displayForm();
return $output;
}
public function displayForm() {
// Init Fields form array
$fields_form[0]['form'] = array(
'legend' => array(
'title' => $this->l('Add the realization'),
),
'input' => array(
array(
'type' => 'file',
'label' => $this->l('Image:'),
'name' => 'realization_img',
'hint' => $this->l('Upload image for contact:'),
)
),
'submit' => array(
'title' => $this->l('Save'),
'class' => 'btn btn-default pull-right'
)
);
$helper = new HelperForm();
// Module, token and currentIndex
$helper->module = $this;
$helper->name_controller = $this->name;
$helper->token = Tools::getAdminTokenLite('AdminModules');
$helper->currentIndex = AdminController::$currentIndex.'&configure='.$this->name;
// Title and toolbar
$helper->title = $this->displayName;
$helper->show_toolbar = true; // false -> remove toolbar
$helper->toolbar_scroll = true; // yes - > Toolbar is always visible on the top of the screen.
$helper->submit_action = 'submit'.$this->name;
$helper->toolbar_btn = array(
'save' =>
array(
'desc' => $this->l('Save'),
'href' => AdminController::$currentIndex.'&configure='.$this->name.'&save'.$this->name.
'&token='.Tools::getAdminTokenLite('AdminModules'),
),
'back' => array(
'href' => AdminController::$currentIndex.'&token='.Tools::getAdminTokenLite('AdminModules'),
'desc' => $this->l('Back to list')
)
);
// Load current value
$helper->tpl_vars = array(
'fields_value' => array(
'realization_img' => Configuration::get('realization_img')
)
);
return $helper->generateForm($fields_form);
}
public function generateList() {
$content = $this->getAll();
$fields_list = array(
'id_realization_slides' => array(
'title' => 'ID',
'align' => 'center',
'class' => 'fixed-width-xs',
),
'image_realization' => array(
'title' => $this->l('Image'),
'orderby' => false,
'search' => false
),
'position' => array(
'title' => $this->l('Position'),
'position' => 'position' ,
'orderby' => false,
'search' => false
),
);
$helper = new HelperList();
$helper->shopLinkType = '';
$helper->actions = array('edit', 'delete');
$helper->module = $this;
$helper->listTotal = count($content);
$helper->identifier = 'id_realization_slides';
$helper->title = $this->l('Realizations');
$helper->table = $this->name;
$helper->imageType = 'jpg';
$helper->orderBy = 'position';
$helper->orderWay = 'asc';
$helper->position_identifier = 'id_realization_slides';
$helper->token = Tools::getAdminTokenLite('AdminModules');
$helper->currentIndex = AdminController::$currentIndex.'&configure='.$this->name;
return $helper->generateList($content, $fields_list);
}
public function getAll() {
return Db::getInstance()->ExecuteS('
SELECT *
FROM '._DB_PREFIX_.'realization
');
}
public function ajaxProcessUpdatePositions()
{
$way = (int)Tools::getValue('way');
$id_quicklinks = (int)Tools::getValue('id');
$positions = Tools::getValue('realization_slides');
if (is_array($positions))
foreach ($positions as $position => $value)
{
$pos = explode('_', $value);
if (isset($pos[2]) && (int)$pos[2] === $id_velcroquicklinks)
{
if (isset($position) && $this->updatePosition($way, $position, $id_quicklinks))
echo 'ok position '.(int)$position.' for id '.(int)$pos[1].'\r\n';
else
echo '{"hasError" : true, "errors" : "Can not update id '.(int)$id_quicklinks.' to position '.(int)$position.' "}';
break;
}
}
}
public function updatePosition($way, $position, $id)
{
if (!$res = Db::getInstance()->executeS('
SELECT `id_realization_slides`, `position`
FROM `'._DB_PREFIX_.'realization`
ORDER BY `position` ASC'
))
return false;
foreach ($res as $quicklinks)
if ((int)$quicklinks['id_realization_slides'] == (int)$id)
$moved_quicklinks = $quicklinks;
if (!isset($moved_quicklinks) || !isset($position))
return false;
return (Db::getInstance()->execute('
UPDATE `'._DB_PREFIX_.'realization`
SET `position`= `position` '.($way ? '- 1' : '+ 1').'
WHERE `position`
'.($way
? '> '.(int)$moved_quicklinks['position'].' AND `position` <= '.(int)$position
: '< '.(int)$moved_quicklinks['position'].' AND `position` >= '.(int)$position.'
'))
&& Db::getInstance()->execute('
UPDATE `'._DB_PREFIX_.'realization`
SET `position` = '.(int)$position.'
WHERE `id_realization_slides` = '.(int)$moved_quicklinks['id_quicklinks']));
}
public function hookHome($params) {
return $this->display(__FILE__, "views/templates/hook/realization.tpl");
}
Because you extend the class Module and it already has the same method which you basically override. And in PHP 7+ if you want to override or extend method you have to declare the same parameters(even if they have default values in the parent class method) and the same access level. So you just need to follow the rule and use the same declaration or you can rename your method if it's not necessary to override/extend the parent class one(and it seems so)
i have written this code to receive data from the Android device. it was inserted just one customer data I need to receive multiple customer details if app goes offline. but it was inserting one data into DB in offline mode also.how can i change this for multiple customer data insertions.
function index_post($customerID = false) {
if ($customerID) {
//update the record
$updateData = array();
$allowedparams = array('streetid' => 'streetid', 'name' => 'name', 'mobile' => 'mobile', 'adhaar' => 'adhaar', 'profession' => 'profession', 'address' => 'address', 'pincode' => 'pincode', 'nearby' => 'nearby', 'paddress' => 'paddress', 'isOwned' => 'isOwned');
foreach ($allowedparams as $k => $v) {
if (!$this->IsNullOrEmptyString($this->post($k, true))) {
$updateData[$v] = $this->post($k, true);
}
}
if ($this->model_customer->update($customerID, $updateData)) {
$data = array('status' => true, 'messsage' => 'cusotmer updated succesfully');
$http_code = REST_Controller::HTTP_OK;
} else {
$data = array('status' => false, 'messsage' => 'cusotmer failed to update.');
$http_code = REST_Controller::HTTP_INTERNAL_SERVER_ERROR;
}
} else {
//insert the record
$allowedparams = array('streetid' => 'streetid', 'name' => 'name', 'mobile' => 'mobile', 'adhaar' => 'adhaar', 'profession' => 'profession', 'address' => 'address', 'pincode' => 'pincode', 'cycle' => 'cycle', 'nearby' => 'nearby', 'paddress' => 'paddress', 'isOwned' => 'isOwned');
$requiredParam = array('streetid', 'name', 'mobile', 'cycle');
$insertdata = array();
foreach ($allowedparams as $k => $v) {
if (in_array($k, $requiredParam)) {
//check if its not null
if ($this->post($k) == null || trim($this->post($k)) == '') {
$data = array('status' => false, 'message' => $k . ' parameter missing or empty');
$http_code = REST_Controller::HTTP_BAD_REQUEST;
break;
}
}
$insertData[$v] = $this->post($k, true);
}
if ($customerID = $this->model_customer->create($insertData)) {
$data['customerID'] = $this->_frameCustomer2($this->model_customer->get($customerID)); //you need to put
$http_code = REST_Controller::HTTP_OK;
} else {
$data = array('status' => false, 'message' => 'unable to create customer');
$http_code = REST_Controller::HTTP_INTERNAL_SERVER_ERROR;
}
}
$this->response($data, $http_code);
}
private function _frameCustomer2($c) { //get value from index_get
$data = array();
$data['id'] = $c->id;
$data['name'] = $c->name;
$data['street'] = array('id' => $c->streetid);
$data['creationDate'] = $c->creationdate;
$data['mobile'] = $c->mobile;
$data['adhaar'] = $c->adhaar;
$data['profession'] = $c->profession;
$data['isOwned'] = ($c->isOwned == 1) ? true : false;
$data['address'] = $c->address;
$data['pincode'] = $c->pincode;
$data['status'] = $c->status;
$data['cycle'] = $c->cycle;
$data['balance'] = $c->balance;
$data['creditAvailable'] = $c->creditbalance;
$data['nearby'] = $c->nearby;
$data['accountNumber'] = $c->accountnumber;
$data['permanentAddress'] = $c->paddress;
$data['lastVisit'] = $this->model_customer->lastVisit($c->id);
return $data;
}
and my part of model function is
function create($insertdata = array()) { //new customer insert
if ($this->db->insert('customer', $insertdata)) {
return $this->db->insert_id();
} else {
return false;
}
}
function update($customerID = 0, $updateData = array()) {
$this->db->where('id', $customerID);
if ($this->db->update('customer', $updateData) && $this->db->affected_rows() == 1) {
return true;
} else {
return false;
}
Instead of customer Id, you can ask the mobile developers to send data in the form of array. In both online and offline. In case of online there will be just one element in the request array.
function index_post() {
$request_data = $this->request->body;
foreach($request_data as $key => $value)
{
//Check if customer id is present
if(Customer present)
{
Update the record
} else {
Insert the record
}
}
}
I purchased a search module that displays a popup and would like to add the price of the product I searched for in it, I found the file that I should make the changes, but what should I add to display the product price
This is the responsible function for displaying the product characteristics
protected function _prepareProducts()
{
$isEnabledImage = (bool) Mage::getStoreConfig(self::ENABLE_IMAGE_CONFIG);
$imageHeight = (int) Mage::getStoreConfig(self::IMAGE_HEIGHT_CONFIG);
$imageWidth = (int) Mage::getStoreConfig(self::IMAGE_WIDTH_CONFIG);
$isEnabledDescription = (bool) Mage::getStoreConfig(self::ENABLE_DESCRIPTION_CONFIG);
$lengthDescription = (int) Mage::getStoreConfig(self::DESCRIPTION_LENGTH_CONFIG);
$collection = $this->_getAlternativeProductCollection();
// $this->_prepareQueryPopularity($collection->getSize());
$toolbar = $this->getToolbarBlock();
$toolbar->setCollection($collection);
$size = (int) Mage::getStoreConfig(self::RESULT_SIZE_CONFIG);
$collection->setPageSize($size);
// $collection->getSelect()->limit($size);
$sortOrder = Mage::getStoreConfig(self::SORT_ORDER_PRODUCT);
if (0 < count($collection)) {
$this->_suggestions[$sortOrder][] = array('html' =>
'<p class="headercategorysearch">' . $this->__("") . '</p>'
);
}
if ($isEnabledImage) {
$helper = Mage::helper('catalog/image');
}
foreach ($collection as $_row) {
$_product = Mage::getModel('catalog/product')
->setStoreId($this->getStoreId())
->load($_row->getId());
$_image = $_srcset = $_description = '';
if ($isEnabledImage) {
$_image = (string) $helper->init($_product, 'thumbnail')->resize($imageWidth, $imageHeight);
$_srcset = (string) $helper->init($_product, 'thumbnail')->resize($imageWidth * 2, $imageHeight * 2);
$_srcset .= ' 2x';
}
if ($isEnabledDescription) {
$_description = strip_tags($this->_trim(
$_product->getShortDescription(),
$lengthDescription
));
}
// $store = Mage::app()->getStore();
// $path = Mage::getResourceModel('core/url_rewrite')
// ->getRequestPathByIdPath('product/' . $_product->getId(), $store);
// // $url = $store->getBaseUrl($store::URL_TYPE_WEB) . $path;
// $url = rtrim(Mage::getUrl($path, array('_store' => $store->getStoreId())), '/');
$url = $_product->getProductUrl();
$this->_suggestions[$sortOrder][] = array(
'name' => $_product->getName(),
'url' => $url,
'image' => $_image,
'srcset' => $_srcset,
'description' => $_description,
);
}
}
Simply add this line
'price' => $_product->getPrice() in suggestions array
$this->_suggestions[$sortOrder][] = array(
'name' => $_product->getName(),
'price' => $_product->getPrice(),
'url' => $url,
'image' => $_image,
'srcset' => $_srcset,
'description' => $_description,
);
you may use
$_product->getFinalPrice()
inside this _suggestions property, but i guess there is also a template or a bit of js responsible for output of all this.
I am trying to check if a coupon is still valid (hasn't reached its usage limit) and display content under this condition.
The reason for this is that I want to be able to hand out a coupon code to particular visitors, but obviously don't want to hand out a coupon that has already reached it's usage limit.
I am trying to achieve this with PHP and imagine the code to be something like this:
<?php if (coupon('mycouponcode') isvalid) {
echo "Coupon Valid"
} else {
echo "Coupon Usage Limit Reached"
} ?>
Any help here would be great :)
I believe the recommended way encouraged by WooCommerce is to use the \WC_Discounts Class. Here is an example:
function is_coupon_valid( $coupon_code ) {
$coupon = new \WC_Coupon( $coupon_code );
$discounts = new \WC_Discounts( WC()->cart );
$response = $discounts->is_coupon_valid( $coupon );
return is_wp_error( $response ) ? false : true;
}
Note: It's also possible to initialize the WC_Discounts class with a WC_Order object as well.
It's important to remember doing that inside the wp_loaded hook at least, like this:
add_action( 'wp_loaded', function(){
is_coupon_valid('my-coupon-code');
});
There is an apparent simpler method is_valid() from the WC_Coupon class but it was deprecated in favor of WC_Discounts->is_coupon_valid()
$coupon = new WC_Coupon( 'my-coupon-code' );
$coupon->is_valid();
$code = 'test123';
$coupon = new WC_Coupon($code);
$coupon_post = get_post($coupon->id);
$coupon_data = array(
'id' => $coupon->id,
'code' => $coupon->code,
'type' => $coupon->type,
'created_at' => $coupon_post->post_date_gmt,
'updated_at' => $coupon_post->post_modified_gmt,
'amount' => wc_format_decimal($coupon->coupon_amount, 2),
'individual_use' => ( 'yes' === $coupon->individual_use ),
'product_ids' => array_map('absint', (array) $coupon->product_ids),
'exclude_product_ids' => array_map('absint', (array) $coupon->exclude_product_ids),
'usage_limit' => (!empty($coupon->usage_limit) ) ? $coupon->usage_limit : null,
'usage_count' => (int) $coupon->usage_count,
'expiry_date' => (!empty($coupon->expiry_date) ) ? date('Y-m-d', $coupon->expiry_date) : null,
'enable_free_shipping' => $coupon->enable_free_shipping(),
'product_category_ids' => array_map('absint', (array) $coupon->product_categories),
'exclude_product_category_ids' => array_map('absint', (array) $coupon->exclude_product_categories),
'exclude_sale_items' => $coupon->exclude_sale_items(),
'minimum_amount' => wc_format_decimal($coupon->minimum_amount, 2),
'maximum_amount' => wc_format_decimal($coupon->maximum_amount, 2),
'customer_emails' => $coupon->customer_email,
'description' => $coupon_post->post_excerpt,
);
$usage_left = $coupon_data['usage_limit'] - $coupon_data['usage_count'];
if ($usage_left > 0) {
echo 'Coupon Valid';
}
else {
echo 'Coupon Usage Limit Reached';
}
The code is tested and fully functional.
Reference
WC_API_Coupons::get_coupon( $id, $fields )
add_action( 'rest_api_init', 'coupon' );
function coupon($request) {
register_rest_route('custom-plugin', '/coupon_code/',
array(
'methods' => 'POST',
'callback' => 'coupon_code',
)
);
}
function coupon_code($request)
{
$code = $request->get_param('coupon');
$applied_coupon = $request->get_param('applied_coupon');
$cart_amount = $request->get_param('cart_amount');
$user_id = $request->get_param('user_id');
// $code = 'test123';
$coupon = new WC_Coupon($code);
$coupon_post = get_post($coupon->id);
$coupon_data = array(
'id' => $coupon->id,
'code' => esc_attr($coupon_post->post_title),
'type' => $coupon->type,
'created_at' => $coupon_post->post_date_gmt,
'updated_at' => $coupon_post->post_modified_gmt,
'amount' => wc_format_decimal($coupon->coupon_amount, 2),
'individual_use' => ( 'yes' === $coupon->individual_use ),
'product_ids' => array_map('absint', (array) $coupon->product_ids),
'exclude_product_ids' => array_map('absint', (array) $coupon->exclude_product_ids),
'usage_limit' => (!empty($coupon->usage_limit) ) ? $coupon->usage_limit : null,
'usage_count' => (int) $coupon->usage_count,
'expiry_date' => (!empty($coupon->expiry_date) ) ? date('Y-m-d', $coupon->expiry_date) : null,
'enable_free_shipping' => $coupon->enable_free_shipping(),
'product_category_ids' => array_map('absint', (array) $coupon->product_categories),
'exclude_product_category_ids' => array_map('absint', (array) $coupon->exclude_product_categories),
'exclude_sale_items' => $coupon->exclude_sale_items(),
'minimum_amount' => wc_format_decimal($coupon->minimum_amount, 2),
'maximum_amount' => wc_format_decimal($coupon->maximum_amount, 2),
'customer_emails' => $coupon->customer_email,
'description' => $coupon_post->post_excerpt,
);
if ($coupon_data['code'] != $code) {
$response['status'] = "failed";
$response['message'] = "COUPON ".$code." DOES NOT EXIST!";
return new WP_REST_Response($response);
}
$Acoupon = new WC_Coupon($applied_coupon);
// print_r($Acoupon);exit();
if($Acoupon->individual_use == 'yes'){
$response['status'] = "failed";
$response['message'] = "SORRY, COUPON ".$applied_coupon." HAS ALREADY BEEN APPLIED AND CANNOT BE USED IN CONJUNCTION WITH OTHER COUPONS.";
$response['result'] = $Acoupon->individual_use;
return new WP_REST_Response($response);
}
if ($coupon_data['minimum_amount'] > $cart_amount) {
$response['status'] = "failed";
$response['message'] = "THE MINIMUM SPEND FOR THIS COUPON IS $".$coupon_data['minimum_amount'].".";
return new WP_REST_Response($response);
}
if ($coupon_data['maximum_amount'] < $cart_amount) {
$response['status'] = "failed";
$response['message'] = "THE MAXIMUM SPEND FOR THIS COUPON IS $".$coupon_data['maximum_amount'].".";
return new WP_REST_Response($response);
}
if ($coupon_data['exclude_sale_items'] == true) {
$response['status'] = "failed";
$response['message'] = "SORRY, THIS COUPON IS NOT VALID FOR SALE ITEMS.";
return new WP_REST_Response($response);
}
$usage_left = $coupon_data['usage_limit'] - $coupon_data['usage_count'];
if ($usage_left == 0) {
$response['status'] = "failed";
$response['message'] = "SORRY, COUPON USAGE LIMIT HAS BEEN REACHED.";
return new WP_REST_Response($response);
}
$current_time = date('Y-m-d');
$coupon_Expiry_date = $coupon->expiry_date;
if ($coupon_Expiry_date < $current_time) {
$response['status'] = "failed";
$response['message'] = "THIS COUPON HAS EXPIRED.";
return new WP_REST_Response($response);
}
$user_limite = get_post_meta($coupon_data['id'], 'usage_limit_per_user', true);
$p_id = $coupon_data['id'];
global $wpdb;
$count_of_per_user = $wpdb->get_results("SELECT * FROM wp_postmeta where post_id = $p_id and meta_key = '_used_by' and meta_value = $user_id");
$count = count($count_of_per_user);
if ( $count >= $user_limite) {
$response['status'] = "failed"`enter code here`;
$response['message'] = "COUPON USAGE LIMIT HAS BEEN REACHED.";
return new WP_REST_Response($response);
}enter code here
else{
$response['status'] = "Success";
$response['message'] = "COUPON APPLIED.";
return new WP_REST_Response($response);
}
}
use this function