function smarty_function_select_categories($params, &$smarty)
{
    extract($params);
    if (empty($assign)) {
        $smarty->trigger_error("assign: missing 'assign' parameter");
        return;
    }
    if ($remove_root && !$current_category_id) {
        return false;
    }
    cw_load('category', 'image');
    if ($remove_root) {
        $path = cw_category_get_path($current_category_id);
        $category_id = array_shift($path);
    }
    $categories = cw_category_get_subcategories($category_id, $current_category_id);
    if ($params['images']) {
        foreach ($categories as $k => $v) {
            $categories[$k]['image'] = cw_image_get('categories_images_thumb', $v['category_id']);
        }
    }
    $smarty->assign($assign, $categories);
}
function cw_apply_special_offer_discount(&$product)
{
    global $tables;
    cw_load('category');
    if ($product['taxed_price'] == 0) {
        return $product;
    }
    // Trick: let first time calculate products without offer to gather correct taxed_price
    $special_offers_apply =& cw_session_register("special_offers_apply");
    if (!empty($special_offers_apply['supply']) && $product['promotion_suite']['free_product'] != true) {
        $current_discount = array();
        $discounted_in_bundle = false;
        $discount_was_applied = false;
        $saved_price = $product['price'];
        // for product walk thru all bonuses
        foreach ($special_offers_apply['supply'] as $offer_id => $bonus) {
            if ($bonus['D']['apply'] != PS_APPLY_PRODS) {
                continue;
            }
            $offer_id = intval($offer_id);
            // Eliminate subindex for repeated offers, e.g. 10.2->10
            $is_bundle = cw_query_first_cell("SELECT pid FROM {$tables['ps_offers']} WHERE offer_id='{$offer_id}'") != 0;
            $is_valid_product = false;
            if (is_array($bonus['D']['products']) && in_array($product['product_id'], array_keys($bonus['D']['products']))) {
                $is_valid_product = true;
            } elseif (is_array($bonus['D']['categories'])) {
                foreach ($bonus['D']['categories'] as $cid => $qty) {
                    // Detect if product is from required category or its subcategories
                    $pcats = Product\Category\get($product['product_id']);
                    $parents = cw_category_get_path(array_column($pcats, 'category_id'));
                    $is_parent = in_array($cid, $parents);
                    if (!empty($is_parent)) {
                        $is_valid_product = true;
                        break;
                    }
                }
            }
            if (!$is_valid_product) {
                continue;
            }
            $_current_discount = price_format($bonus['D']['disctype'] == PS_DISCOUNT_TYPE_PERCENT ? $product['price'] * $bonus['D']['discount'] / 100 : $bonus['D']['discount']);
            if ($is_bundle) {
                if ($discounted_in_bundle) {
                    continue;
                }
                # Bundle discount can be applied only once
                # Apply bundle discount immediately to product price
                $product['price'] = max($product['price'] - $_current_discount, 0.0);
                $discounted_in_bundle = $_current_discount;
                $special_offers_apply['discount']['products'][$product['product_id']][] = array('discount_type' => $bonus['D']['disctype'], 'discount' => $bonus['D']['discount'], 'max_discount' => $_current_discount);
            } elseif ($_current_discount > $current_discount['max_discount']) {
                # hey, we've found better regular discount
                $current_discount = array('discount_type' => $bonus['D']['disctype'], 'discount' => $bonus['D']['discount'], 'max_discount' => $_current_discount);
                $special_offers_apply['discount']['products'][$product['product_id']][] = $current_discount;
            }
            $discount_was_applied = true;
        }
        if ($discount_was_applied) {
            $product['promotion_suite']['saved_price'] = $saved_price;
            $product['promotion_suite']['saved_taxed_price'] = $product['taxed_price'];
            $product['price'] = max($product['price'] - $current_discount['max_discount'], 0.0);
        }
    }
    return $product;
}
     cw_unset($update_fields, 'category', 'description');
 }
 cw_array2update('categories', $category_update, "category_id='{$cat}'", $update_fields);
 cw_category_update_status($cat, $category_update['status']);
 cw_category_update_path($cat);
 cw_membership_update('categories', $cat, $category_update['membership_ids'], 'category_id');
 $category_lng = array();
 $category_lng['code'] = $edited_language;
 $category_lng['category_id'] = $cat;
 $category_lng['category'] = $category_update['category'];
 $category_lng['description'] = $category_update['description'];
 cw_array2insert('categories_lng', $category_lng, true, array('code', 'category_id', 'category', 'description'));
 if (cw_image_check_posted($file_upload_data['categories_images_thumb'])) {
     cw_image_save($file_upload_data['categories_images_thumb']);
 }
 $parent_categories = cw_category_get_path($cat);
 if (is_array($parent_categories)) {
     cw_recalc_subcat_count($parent_categories);
 }
 cw_func_call('cw_items_attribute_classes_save', array('item_id' => $cat, 'attribute_class_ids' => $category_update['attribute_class_ids'], 'item_type' => 'C'));
 if ($replicate_attribute_classes == "Y") {
     $child_subcategories = cw_func_call('cw_category_get_subcategory_ids', array('cat' => $cat));
     if (is_array($child_subcategories)) {
         foreach ($child_subcategories as $subcatid) {
             cw_func_call('cw_items_attribute_classes_save', array('item_id' => $subcatid, 'attribute_class_ids' => $category_update['attribute_class_ids'], 'item_type' => 'C'));
         }
     }
 }
 cw_call('cw_attributes_save', array('item_id' => $cat, 'item_type' => 'C', 'attributes' => $attributes, 'language' => $edited_language));
 cw_group_edit_update_category($ge_id, $cat, $fields, $category_update);
 if ($mode == 'add') {
function cw_discount_coupons_is_valid($coupon, $products)
{
    global $tables, $customer_id, $config;
    $my_coupon = cw_query_first("select * from {$tables['discount_coupons']} where coupon='{$coupon}' and status=1 AND expire>" . cw_core_get_time());
    # kornev, may be it's salesman discount
    $salesman_discount = false;
    if (!$my_coupon) {
        $my_coupon = cw_query_first("select * from {$tables['discount_coupons']} where coupon='{$coupon}' and status=1 and salesman_customer_id='{$customer_id}'");
        $salesman_discount = true;
    }
    if (!$my_coupon) {
        return 1;
    }
    if ($my_coupon['per_user']) {
        if (empty($cutomer_id)) {
            return 1;
        }
        $_times_used = cw_query_first_cell("select times_used from {$tables['discount_coupons_cutomer_id']} where coupon='{$coupon}' and cutomer_id='{$cutomer_id}'");
        if ($_times_used >= $my_coupon['times']) {
            return 5;
        }
    }
    if ($my_coupon['coupon_type'] == "percent" && $my_coupon['discount'] > 100) {
        return 1;
    }
    if ($my_coupon['product_id'] > 0) {
        $found = false;
        foreach ($products as $value) {
            if ($value['product_id'] == $my_coupon['product_id']) {
                $found = true;
            }
        }
        return $found ? 0 : 4;
    } elseif ($my_coupon['category_id'] > 0) {
        $found = false;
        $category_ids[] = $my_coupon['category_id'];
        if ($my_coupon['recursive']) {
            $category_ids[] = cw_category_get_path($my_coupon['category_id']);
        }
        if (!is_array($products)) {
            return 4;
        }
        if ($config['Appearance']['categories_in_products'] == '1') {
            foreach ($products as $value) {
                $product_categories = cw_query("SELECT category_id FROM {$tables['products_categories']} WHERE product_id='{$value['product_id']}'");
                $is_valid_product = false;
                foreach ($product_categories as $k => $v) {
                    if (in_array($v['category_id'], $category_ids)) {
                        $is_valid_product = true;
                        break;
                    }
                }
                if ($is_valid_product) {
                    $found = true;
                    break;
                }
            }
        }
        return $found ? 0 : 4;
    } else {
        $total = 0;
        if (!empty($products) && is_array($products)) {
            foreach ($products as $value) {
                $total += $value['price'] * $value['amount'];
            }
        }
        if ($total < $my_coupon['minimum']) {
            return 3;
        } else {
            return 0;
        }
    }
    return 0;
}
 if ($current_bonuses[PS_FREE_SHIP]['apply'] == PS_APPLY_COND) {
     foreach ($_affected_product_ids['ids'] as $pid => $qty) {
         $special_offers_apply['free_shipping']['products'][$pid] += $qty - $affected_product_ids['ids'][$pid];
     }
 }
 // If free shipping applicable to selected products
 if ($current_bonuses[PS_FREE_SHIP]['apply'] == PS_APPLY_PRODS) {
     // Check all free-shipping bonuses of the offer
     foreach ($current_bonuses[PS_FREE_SHIP]['products'] as $pid => $qty) {
         $special_offers_apply['free_shipping']['products'][$pid] += $qty;
     }
     foreach ($current_bonuses[PS_FREE_SHIP]['categories'] as $cid => $qty) {
         foreach ($cart['products'] as $kk => $vv) {
             // Detect if product is from required category or its subcategories
             $pcats = Product\Category\get($vv['product_id']);
             $parents = cw_category_get_path(array_column($pcats, 'category_id'));
             $is_parent = in_array($cid, $parents);
             if ($is_parent) {
                 $special_offers_apply['free_shipping']['products'][$vv['product_id']] += min($vv['amount'], $qty);
                 $qty -= min($vv['amount'], $qty);
             }
         }
     }
 }
 /*
  * END: Prepare common free_shipping array
  */
 /*
  * Prepare common free_products array
  */
 // Re-collect free products array
function cw_category_get_all()
{
    global $tables, $current_language, $current_area, $user_account;
    $fields = array();
    $where = array();
    $orderbys = array();
    $groupbys = array();
    $from_tbls = array('categories');
    $fields[] = "{$tables['categories']}.category_id";
    $fields[] = "{$tables['categories']}.parent_id";
    $fields[] = "{$tables['categories']}.category";
    $fields[] = "{$tables['categories']}.order_by";
    if (in_array($current_area, array('C', 'B'))) {
        $where[] = "({$tables['categories_memberships']}.membership_id = '0' OR {$tables['categories_memberships']}.membership_id = '{$user_account['membership_id']}')";
        $orderbys[] = "{$tables['categories']}.order_by, {$tables['categories']}.category";
        $where[] = "{$tables['categories']}.status = 1";
        $query_joins['categories_subcount'] = array('on' => "{$tables['categories_subcount']}.category_id = {$tables['categories']}.category_id AND {$tables['categories_subcount']}.membership_id = '{$user_account['membership_id']}'");
        $fields[] = "{$tables['categories_subcount']}.subcategory_count";
        $fields[] = "{$tables['categories_subcount']}.product_count";
    } else {
        $query_joins['categories_subcount'] = array('on' => "{$tables['categories_subcount']}.category_id = {$tables['categories']}.category_id");
    }
    $query_joins['categories_lng'] = array('on' => "{$tables['categories_lng']}.code='{$current_language}' AND {$tables['categories_lng']}.category_id={$tables['categories']}.category_id");
    $query_joins['categories_memberships'] = array('on' => "{$tables['categories_memberships']}.category_id = {$tables['categories']}.category_id");
    $fields[] = "IFNULL({$tables['categories_lng']}.category, {$tables['categories_lng']}.category) as category";
    $groupbys[] = "{$tables['categories']}.category_id";
    $search_query = cw_db_generate_query($fields, $from_tbls, $query_joins, $where, $groupbys, null, $orderbys);
    $categories = cw_query($search_query);
    if (!$categories) {
        return array();
    }
    #
    # Add category path
    //    $sort_by = array();
    foreach ($categories as $k => $v) {
        $path = cw_category_get_path($v['category_id']);
        if (is_array($path)) {
            $path_name = array();
            foreach ($path as $kk => $vv) {
                $path_name[] = cw_query_first_cell($sql = "select IFNULL(lng.category, c.category) as category from {$tables['categories']} as c left join {$tables['categories_lng']} as lng on lng.category_id=c.category_id and lng.code='{$current_language}' where c.category_id = {$vv}");
            }
        }
        $categories[$k]['category_path'] = implode('/', $path_name);
        //		$sort_by[] = $categories[$k]['category_path'];
    }
    //	array_multisort($sort_by, $categories, SORT_ASC, SORT_STRING);
    usort($categories, 'cw_category_sort_by_path');
    return $categories;
}
 }
 if (!empty($fields)) {
     $do_not_update = array('price', 'thumbnail', 'product_image', 'category_id', 'category_ids', 'membership_ids');
     $to_update = array_intersect($query_fields, array_keys($fields));
     $to_update = array_intersect($to_update, array_diff($to_update, $do_not_update));
     if (count($to_update)) {
         cw_group_edit_copy($ge_id, 'products', 'product_id', $product_id, $to_update);
     }
 }
 if ($config['Appearance']['categories_in_products'] == '1') {
     cw_recalc_subcat_count($category_id);
     if (is_array($old_product_categories)) {
         $category_ids = cw_array_merge($old_product_categories, $category_ids);
     }
     $category_ids = cw_array_merge($category_ids, $product_data['category_ids'], array($category_id));
     cw_recalc_subcat_count(cw_category_get_path($category_ids));
 }
 if ($is_new_product) {
     cw_add_top_message(cw_get_langvar_by_name('msg_adm_product_add'));
 } else {
     cw_add_top_message(cw_get_langvar_by_name("msg_adm_product_upd"));
 }
 if (!$is_variant) {
     //cw_price_lists_replace_price($product_id, $product_data['price'], 0, $is_new_product, $product_data['is_manual_price']);
     if (isset($product_data['price']) && isset($product_data['list_price'])) {
         cw_product_update_price($product_id, 0, 0, 0, 1, 1, $product_data['price'], $product_data['list_price']);
     }
 }
 if ($fields['price'] && !$is_variant) {
     if ($ge_id) {
         while ($pid = cw_group_edit_each($ge_id, 1, $product_id)) {