Example #1
0
function fn_ult_delete_category_pre(&$category_id, $recurse)
{
    $id_path = db_get_field("SELECT id_path FROM ?:categories WHERE category_id = ?i", $category_id);
    if ($recurse) {
        $categories = db_get_array("SELECT category_id, id_path FROM ?:categories WHERE category_id = ?i OR id_path LIKE ?l", $category_id, "{$id_path}/%");
    } else {
        $categories[] = array('category_id' => $category_id, 'id_path' => $id_path);
    }
    // Select products that doesn't belong to another categories,
    // except categories that are children of being deleted category.
    // This complex query is fast enough to be used instead of several queries nested in foreach loop.
    $sql = <<<SQL
(SELECT pc.product_id FROM ?:products_categories pc
   LEFT JOIN ?:products_categories pc2
    ON pc2.product_id = pc.product_id
    AND pc2.category_id != pc.category_id
 WHERE pc.category_id = ?i AND pc2.product_id IS NULL
)

UNION ALL

(SELECT only_descendants.product_id FROM

   (SELECT DISTINCT pc.product_id
    FROM ?:products_categories pc
      RIGHT JOIN ?:products_categories pc2
        ON pc2.product_id = pc.product_id
           AND pc2.category_id != pc.category_id
      RIGHT JOIN ?:categories AS c
        ON c.category_id = pc2.category_id
           AND c.id_path LIKE ?l
    WHERE pc.category_id = ?i) AS only_descendants

   LEFT JOIN

   (SELECT DISTINCT pc.product_id
    FROM ?:products_categories pc
      RIGHT JOIN ?:products_categories pc2
        ON pc2.product_id = pc.product_id
           AND pc2.category_id != pc.category_id
      RIGHT JOIN ?:categories AS c
        ON c.category_id = pc2.category_id
           AND c.id_path NOT LIKE ?l
    WHERE pc.category_id = ?i) AS only_not_descendants

    USING(product_id)

 WHERE only_not_descendants.product_id IS NULL
)
SQL;
    foreach ($categories as $category_data) {
        $products_to_delete = db_get_fields($sql, $category_data['category_id'], $id_path . '/%', $category_data['category_id'], $id_path . '/%', $category_data['category_id']);
        if (!empty($products_to_delete)) {
            foreach ($products_to_delete as $key => $value) {
                fn_delete_product($value);
            }
        }
        fn_ult_correct_category_products_sharing($category_data['category_id'], $category_data['id_path']);
        fn_update_product_count();
    }
}
Example #2
0
function fn_ult_update_category_post(&$category_data, &$category_id, &$lang_code)
{
    if (!isset($category_data['company_id']) || Registry::get('runtime.simple_ultimate')) {
        return;
    }
    $company_id = $category_data['company_id'];
    $is_company_changed = !Registry::get('runtime.company_id') && isset($category_data['old_company_id']) && $category_data['old_company_id'] != $company_id;
    if ($is_company_changed) {
        $id_path = db_get_field("SELECT id_path FROM ?:categories WHERE category_id = ?i", $category_id);
        // Change company_id of subcategories
        db_query("UPDATE ?:categories SET company_id = ?s WHERE id_path LIKE ?l", $company_id, "{$id_path}/%");
        // Change company_id of products and options with one fast query
        db_query('UPDATE ?:products AS p' . ' INNER JOIN ?:products_categories AS p_c ON p_c.product_id = p.product_id' . ' INNER JOIN ?:categories AS c ON c.category_id = p_c.category_id' . '     AND (c.id_path LIKE ?l OR c.category_id = ?i)' . ' LEFT JOIN ?:product_options AS p_o ON p_o.product_id = p.product_id ' . ' SET p.company_id = ?i, p_o.company_id = ?i', "{$id_path}/%", $category_id, $company_id, $company_id);
        fn_ult_correct_category_products_sharing($category_id, $id_path);
        fn_update_product_count();
    }
}