Page MenuHomeIn-Portal Phabricator

product_option_combinations_event_handler.php
No OneTemporary

File Metadata

Created
Mon, Aug 18, 2:20 AM

product_option_combinations_event_handler.php

<?php
/**
* @version $Id: product_option_combinations_event_handler.php 16693 2021-08-31 09:24:39Z alex $
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software is protected by copyright law and international treaties.
* Unauthorized reproduction or unlicensed usage of the code of this program,
* or any portion of it may result in severe civil and criminal penalties,
* and will be prosecuted to the maximum extent possible under the law
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class ProductOptionCombinationsEventHandler extends kDBEventHandler {
/**
* Apply custom processing to item
*
* @param kEvent $event
* @param string $type
* @return void
* @access protected
*/
protected function customProcessing(kEvent $event, $type)
{
if ( $type == 'after' ) {
return;
}
switch ($event->Name) {
case 'OnCreate':
case 'OnUpdate':
/** @var kDBItem $object */
$object = $event->getObject();
$options = unserialize($object->GetDBField('Combination'));
ksort($options);
$object->SetDBField('CombinationCRC', kUtil::crc32(serialize($options)));
break;
case 'OnMassDelete':
// delete only option combinations that has no associated inventory
/** @var kDBItem $object */
$object = $event->getObject();
$ids = $event->getEventParam('ids');
$sql = 'SELECT ' . $object->IDField . '
FROM ' . $object->TableName . '
WHERE (' . $object->IDField . ' IN (' . implode(',', $ids) . ')) AND
(QtyInStock = 0) AND (QtyReserved = 0) AND (QtyBackOrdered = 0) AND (QtyOnOrder = 0)';
$event->setEventParam('ids', $this->Conn->GetCol($sql));
break;
}
}
/**
* GetOptionValues
*
* @param kEvent $event
*/
function GetOptionValues($event, $option_id)
{
$object = $event->getObject();
if ($object->IsTempTable()) {
$table = $this->Application->GetTempName(TABLE_PREFIX.'ProductOptions', 'prefix:'.$event->Prefix);
}
else {
$table = TABLE_PREFIX.'ProductOptions';
}
$query = 'SELECT `Values` FROM '.$table.' WHERE ProductOptionId = '.$option_id;
return explode(',', $this->Conn->GetOne($query));
}
function CreateCombinations(kEvent $event, $fields, $current_option=null)
{
$recursed = false;
$combination = $fields['Combination'];
foreach ($combination as $option_id => $option)
{
if ($option_id == $current_option || $recursed) continue;
if ($option == '_ANY_') {
$recursed = true;
$values = $this->GetOptionValues($event, $option_id);
foreach ($values as $a_value) {
$fields['Combination'][$option_id] = $a_value;
$this->CreateCombinations($event, $fields, $option_id);
}
}
}
if (!$recursed) {
/** @var kDBItem $object */
$object = $event->getObject();
$salt = $fields['Combination'];
ksort($salt);
$object->Load(kUtil::crc32(serialize($salt)), 'CombinationCRC');
$object->SetFieldsFromHash($fields);
$event->setEventParam('form_data', $fields);
$this->customProcessing($event,'before');
if ( $object->isLoaded() ) { // Update if such combination already exists
if( $object->Update() )
{
$this->customProcessing($event,'after');
$event->status=kEvent::erSUCCESS;
}
}
else {
if( $object->Create($event->getEventParam('ForceCreateId')) )
{
$this->customProcessing($event,'after');
$event->status=kEvent::erSUCCESS;
}
}
}
}
function UpdateCombinations(kEvent $event, $fields, $current_option=null)
{
$recursed = false;
$combination = $fields['Combination'];
foreach ($combination as $option_id => $option)
{
if ($option_id == $current_option || $recursed) continue;
if ($option == '_ANY_') {
$recursed = true;
$values = $this->GetOptionValues($event, $option_id);
foreach ($values as $a_value) {
$fields['Combination'][$option_id] = $a_value;
$this->UpdateCombinations($event, $fields, $option_id);
}
}
}
if (!$recursed) {
/** @var kDBItem $object */
$object = $event->getObject();
$edit_id = $object->GetId();
$salt = $fields['Combination'];
ksort($salt);
// try to load combination by salt - if loaded, it will update the combination
$object->Load(kUtil::crc32(serialize($salt)), 'CombinationCRC');
if ( !$object->isLoaded() ) {
$object->Load($edit_id);
}
$object->SetFieldsFromHash($fields);
$event->setEventParam('form_data', $fields);
$this->customProcessing($event,'before');
if( $object->Update() )
{
$this->customProcessing($event,'after');
$event->status=kEvent::erSUCCESS;
}
}
}
/**
* Creates new kDBItem
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnCreate(kEvent $event)
{
/** @var kDBItem $object */
$object = $event->getObject(Array ('skip_autoload' => true));
$items_info = $this->Application->GetVar($event->getPrefixSpecial(true));
if ( !$items_info ) {
return;
}
$id = key($items_info);
$field_values = $items_info[$id];
$object->setID($id);
$object->SetFieldsFromHash($field_values);
$event->setEventParam('form_data', $field_values);
if ( !$object->Validate() ) {
$event->status = kEvent::erFAIL;
$event->redirect = false;
$this->Application->SetVar($event->getPrefixSpecial() . '_SaveEvent', 'OnCreate');
return;
}
$this->CreateCombinations($event, $field_values);
}
/**
* Updates kDBItem
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnUpdate(kEvent $event)
{
/** @var kDBItem $object */
$object = $event->getObject( Array('skip_autoload' => true) );
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
if($items_info)
{
foreach($items_info as $id => $field_values)
{
$object->Load($id);
$object->SetFieldsFromHash($field_values);
$event->setEventParam('form_data', $field_values);
if (!$object->Validate()) {
$event->status = kEvent::erFAIL;
$event->redirect = false;
return;
}
$this->UpdateCombinations($event, $field_values);
/*$this->customProcessing($event, 'before');
if( $object->Update($id) )
{
$this->customProcessing($event, 'after');
$event->status=kEvent::erSUCCESS;
}
else
{
$event->status=kEvent::erFAIL;
$event->redirect=false;
break;
}*/
}
}
$this->Application->SetVar($event->GetPrefixSpecial().'_id', '');
}
/**
* Builds item (loads if needed)
*
* Pattern: Prototype Manager
*
* @param kEvent $event
* @access protected
*/
protected function OnItemBuild(kEvent $event)
{
/** @var kDBItem $object */
$object = $event->getObject();
$this->dbBuild($object, $event);
$sql = $this->ItemPrepareQuery($event);
$sql = $this->Application->ReplaceLanguageTags($sql);
$object->setSelectSQL($sql);
// 2. loads if allowed
$auto_load = $this->Application->getUnitOption($event->Prefix, 'AutoLoad');
$skip_autoload = $event->getEventParam('skip_autoload');
if ( $auto_load && !$skip_autoload ) {
$this->LoadItem($event);
}
/** @var Params $actions */
$actions = $this->Application->recallObject('kActions');
$actions->Set($event->getPrefixSpecial() . '_GoTab', '');
$actions->Set($event->getPrefixSpecial() . '_GoId', '');
}
/**
* Load item if id is available
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function LoadItem(kEvent $event)
{
/** @var kDBItem $object */
$object = $event->getObject();
$id = $this->getPassedID($event);
if ( !$id ) {
$event->CallSubEvent('OnNew');
return;
}
if ( $object->Load($id) ) {
/** @var Params $actions */
$actions = $this->Application->recallObject('kActions');
$actions->Set($event->getPrefixSpecial() . '_id', $object->GetId());
}
}
/**
* Returns special of main item for linking with sub-item
*
* @param kEvent $event
* @return string
* @access protected
*/
protected function getMainSpecial(kEvent $event)
{
$special = $event->getEventParam('main_special');
if ( $special === false || $special == '$main_special' ) {
$special = $event->Special;
}
if ( $special == 'grid' ) {
$special = '';
}
return $special;
}
/**
* Occurs before an item has been cloned
* Id of newly created item is passed as event' 'id' param
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnBeforeClone(kEvent $event)
{
parent::OnBeforeClone($event);
$event->Init($event->Prefix, '-item');
/** @var kDBItem $object */
$object = $event->getObject();
$options_mapping = $this->Application->GetVar('poc_mapping');
if ( !$options_mapping ) {
return;
}
foreach ($options_mapping as $original => $new) {
$n_combs = array ();
$comb_data = unserialize($object->GetDBField('Combination'));
foreach ($comb_data as $key => $val) {
$n_key = $key == $original ? $new : $key;
$n_combs[$n_key] = $val;
}
ksort($n_combs);
$n_combs = serialize($n_combs);
$n_crc = kUtil::crc32($n_combs);
$object->SetDBField('Combination', $n_combs);
$object->SetDBField('CombinationCRC', $n_crc);
}
}
/**
* Restore back values from live table to temp table before overwriting live with temp
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnBeforeDeleteFromLive(kEvent $event)
{
parent::OnBeforeDeleteFromLive($event);
// check if product inventory management is via options and then proceed
$id = $event->getEventParam('id');
$products_table = $this->Application->getUnitOption('p', 'TableName');
$table_name = $this->Application->getUnitOption($event->Prefix, 'TableName');
$id_field = $this->Application->getUnitOption($event->Prefix, 'IDField');
$sql = 'SELECT p.InventoryStatus
FROM ' . $products_table . ' p
LEFT JOIN ' . $table_name . ' poc ON poc.ProductId = p.ProductId
WHERE poc.' . $id_field . ' = ' . $id;
$inventory_status = $this->Conn->GetOne($sql);
if ( $inventory_status == ProductInventory::BY_OPTIONS ) {
/** @var kDBItem $live_object */
$live_object = $this->Application->recallObject($event->Prefix . '.itemlive', null, Array ('skip_autoload' => true));
$live_object->SwitchToLive();
$live_object->Load($id);
/** @var kDBItem $temp_object */
$temp_object = $this->Application->recallObject($event->Prefix . '.itemtemp', null, Array ('skip_autoload' => true));
$temp_object->SwitchToTemp();
$temp_object->Load($id);
$temp_object->SetDBFieldsFromHash($live_object->GetFieldValues(), Array ('QtyInStock', 'QtyReserved', 'QtyBackOrdered', 'QtyOnOrder'));
$temp_object->Update();
}
}
/**
* Create search filters based on search query
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnSearch(kEvent $event)
{
parent::OnSearch($event);
$this->_saveProduct($event);
}
/**
* Clear search keywords
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnSearchReset(kEvent $event)
{
parent::OnSearchReset($event);
$this->_saveProduct($event);
}
/**
* Makes event remember product id (if passed)
*
* @param kEvent $event
*/
function _saveProduct($event)
{
$product_id = $this->Application->GetVar('p_id');
if ($product_id) {
$event->SetRedirectParam('p_id', $product_id);
}
}
}

Event Timeline