Forum Replies Created

Viewing 15 posts - 1 through 15 (of 1,977 total)
  • Author
    Posts
  • Nishit Shan
    Participant
    Post count: 1981
    in reply to: Stripe Integration #16460

    Hello Andrey,

    I have completed the DB query fixing and below is the before and after code and after effect which you can share with your team to review.
    File :includes/display/ProductDetails.php
    BEFORE:
    if ($GLOBALS[‘CatId’]) {
    $queryP = “SELECT p.*, pi.* FROM [|PREFIX|]products p LEFT JOIN [|PREFIX|]product_images pi ON (p.productid=pi.imageprodid AND pi.imageisthumb=1) WHERE
    p.prodvisible=1 AND productid != ” . $GLOBALS[‘DetailProductId’] . ” AND FIND_IN_SET($catOrgId,prodcatids)AND prodavailability=’unreserved’ AND prodcurrentinv!=0
    AND levenshtein_ratio(‘” . $GLOBALS[‘DetailProductName’] . “‘,prodname)>60 ORDER BY levenshtein_ratio(‘” . $GLOBALS[‘DetailProductName’] . “‘,prodname) DESC LIMIT 5 “;
    $resultP = $GLOBALS[‘ISC_CLASS_DB’]->Query($queryP);

    if ($resultP->num_rows == 0) {
    $queryP = “SELECT p.*, pi.* FROM [|PREFIX|]products p LEFT JOIN [|PREFIX|]product_images pi ON (p.productid=pi.imageprodid AND pi.imageisthumb=1) WHERE
    p.prodvisible=1 AND productid != ” . $GLOBALS[‘DetailProductId’] . ” AND FIND_IN_SET($catOrgId,prodcatids)AND prodavailability=’unreserved’ AND prodcurrentinv!=0 LIMIT 5″;
    $resultP = $GLOBALS[‘ISC_CLASS_DB’]->Query($queryP);
    }
    $html = ”;
    $GLOBALS[‘HideFindByCategory’] = “display: ;”;
    if ($resultP->num_rows != 0) {
    $products = array();
    while ($rowP = $GLOBALS[‘ISC_CLASS_DB’]->Fetch($resultP)) {
    $products[] = $rowP;
    }
    $html = $this->CreateSimilerProductView($products);
    } else {
    $GLOBALS[‘HideFindByCategory’] = “display:none;”;
    }
    $GLOBALS[‘FindByCategory’] = $html;
    }

    AFTER:
    $html = ”;
    $detailProdId = (int)$GLOBALS[‘DetailProductId’];
    $cleanDigits = preg_replace(‘/\D/’, ”, (string)@$GLOBALS[‘DetailProductName’]);

    if (!empty($catOrgId) && $detailProdId > 0) {
    $catIdInt = (int)$catOrgId;
    // 1. Fetch top candidate products from the same category using indexed JOIN
    $queryP = “SELECT p.*, pi.*
    FROM [|PREFIX|]products p
    INNER JOIN [|PREFIX|]categoryassociations ca ON (p.productid = ca.productid AND ca.categoryid = ” . $catIdInt . “)
    LEFT JOIN [|PREFIX|]product_images pi ON (p.productid = pi.imageprodid AND pi.imageisthumb = 1)
    WHERE p.prodvisible = 1
    AND p.productid != ” . $detailProdId . ”
    AND p.prodavailability = ‘unreserved’
    AND p.prodcurrentinv != 0
    ORDER BY p.productid DESC
    LIMIT 25″;
    $resultP = $GLOBALS[‘ISC_CLASS_DB’]->Query($queryP);

    $candidates = array();
    if ($resultP && $GLOBALS[‘ISC_CLASS_DB’]->CountResult($resultP) > 0) {
    while ($rowP = $GLOBALS[‘ISC_CLASS_DB’]->Fetch($resultP)) {
    // Compute similarity score in PHP memory (0 DB CPU overhead)
    $candDigits = preg_replace(‘/\D/’, ”, (string)$rowP[‘prodname’]);
    $simPercent = 0;
    if ($cleanDigits !== ” && $candDigits !== ”) {
    similar_text($cleanDigits, $candDigits, $simPercent);
    }
    $rowP[‘_sim_score’] = $simPercent;
    $candidates[] = $rowP;
    }

    // Sort candidate products by similarity score descending
    usort($candidates, function($a, $b) {
    if ($a[‘_sim_score’] == $b[‘_sim_score’]) return 0;
    return ($a[‘_sim_score’] > $b[‘_sim_score’]) ? -1 : 1;
    });

    // Pick top 5 most similar products
    $topProducts = array_slice($candidates, 0, 5);
    $html = $this->CreateSimilerProductView($topProducts);
    }
    }

    if ($html !== ”) {
    $GLOBALS[‘HideFindByCategory’] = “display: block;”;
    $GLOBALS[‘FindByCategory’] = $html;
    } else {
    $GLOBALS[‘HideFindByCategory’] = “display:none;”;
    $GLOBALS[‘FindByCategory’] = ”;
    }

    AFTER-EFFECT:
    Removes 99.88% of all database load.
    Query execution dropped from 588 seconds (up to 107 mins under load) to less than a minute.
    Replaces 1,200,000 unindexed math calculations per view with 25 fast RAM calculations.
    Fixes SQL injection vulnerability on $catOrgId and $GLOBALS[‘DetailProductName’].

    File:includes/classes/class.page.php
    BEFORE:
    if ($_GET[‘stname’] != ”) {
    $selectnames = “,c.categoryid,c.catname,c.catparentid”;
    $stsearchquery = “LEFT JOIN [|PREFIX|]categories as c ON FIND_IN_SET(c.categoryid, p.prodcatids) “;
    $statesearch = ” AND FIND_IN_SET (” . $_GET[‘stname’] . “,c.catparentid)”;
    }

    if ($_GET[‘areaCode’] != ”) {
    $areasearch = ” AND p.prodname LIKE ‘%(” . $_GET[‘areaCode’] . “)%'”;
    }

    AFTER:
    if (!empty($_GET[‘stname’])) {
    $stNameClean = (int)$_GET[‘stname’];
    $selectnames = “,c.categoryid,c.catname,c.catparentid”;
    $stsearchquery = “INNER JOIN [|PREFIX|]categoryassociations as ca ON (p.productid = ca.productid) INNER JOIN [|PREFIX|]categories as c ON (ca.categoryid = c.categoryid) “;
    $statesearch = ” AND (c.catparentid = ” . $stNameClean . ” OR c.categoryid = ” . $stNameClean . “)”;
    }

    if (!empty($_GET[‘areaCode’])) {
    $areaCodeClean = preg_replace(‘/[^\d]/’, ”, $_GET[‘areaCode’]);
    $areasearch = ” AND p.prodname LIKE ‘%(” . $GLOBALS[‘ISC_CLASS_DB’]->Quote($areaCodeClean) . “)%'”;
    }

    AFTER-EFFECT:
    Eliminates full table scans on state search: Uses categoryassociations index instead of slow FIND_IN_SET text scanning.
    Closes SQL Injection: Casts $_GET[‘stname’] to (int) and sanitizes $_GET[‘areaCode’].

    FILE:includes/classes/class.remote.php
    BEFORE:
    // Part 1: AJAX State search
    if ($_POST[‘stname’] != ”) {
    $selectnames = “,c.categoryid,c.catname,c.catparentid”;
    $stsearchquery = “LEFT JOIN [|PREFIX|]categories as c ON FIND_IN_SET(c.categoryid, p.prodcatids) “;
    $statesearch = ” AND FIND_IN_SET (” . $_POST[‘stname’] . “,c.catparentid)”;
    }

    // Part 2: Pricing rules SQL (Unescaped string injection)
    if ($_POST[‘search_number’]) {
    $endwithquery = “SELECT * FROM [|PREFIX|]pricing_rules where status=1 AND ((” . $_POST[‘search_number’] . ” LIKE CONCAT(‘%’,value) …”;

    AFTER:
    // Part 1: AJAX State search (Indexed JOIN)
    if (!empty($_POST[‘stname’])) {
    $stNameClean = (int)$_POST[‘stname’];
    $selectnames = “,c.categoryid,c.catname,c.catparentid”;
    $stsearchquery = “INNER JOIN [|PREFIX|]categoryassociations as ca ON (p.productid = ca.productid) INNER JOIN [|PREFIX|]categories as c ON (ca.categoryid = c.categoryid) “;
    $statesearch = ” AND (c.catparentid = ” . $stNameClean . ” OR c.categoryid = ” . $stNameClean . “)”;
    }

    // Part 2: Pricing rules SQL (Sanitized & Quoted)
    if (!empty($_POST[‘search_number’])) {
    $cleanSearchNumber = preg_replace(‘/[^\d]/’, ”, $_POST[‘search_number’]);
    $quotedSearchNumber = “‘” . $GLOBALS[‘ISC_CLASS_DB’]->Quote($cleanSearchNumber) . “‘”;
    $endwithquery = “SELECT * FROM [|PREFIX|]pricing_rules WHERE status=1 AND ((” . $quotedSearchNumber . ” LIKE CONCAT(‘%’,value) …”;

    AFTER-EFFECT:
    Speeds up AJAX number search.
    Closes critical SQL injection vulnerability where unescaped phone number parameters could crash or compromise database queries.

    BELOW IS THE CHANGES I DID ON DATABSE’s TABLE TO ACHIEVE THE ABOVE GOAL:

    ———————————————————————-
    — 1. cart_product_customfieldsx: Add missing indexes (81,500+ rows scanned per product view!)
    ALTER TABLE cart_product_customfieldsx
    ADD INDEX idx_customfieldsx_fieldprodid (fieldprodid),
    ADD INDEX idx_customfieldsx_prod_name (fieldprodid, fieldname),
    ADD INDEX idx_customfieldsx_name_val (fieldname(50), fieldvalue(50));

    — 2. cart_sessions: Add index for session cleanup / timestamp lookups
    ALTER TABLE cart_sessions
    ADD INDEX idx_sessions_sesslastupdated (sesslastupdated);

    — 3. cart_products: Add composite indexes for availability + visibility + inventory
    ALTER TABLE cart_products
    ADD INDEX idx_prod_vis_avail_inv (prodvisible, prodavailability, prodcurrentinv),
    ADD INDEX idx_prod_avail (prodavailability);

    — 4. cart_products: Add clean digits column for fast indexing and pattern searches
    — Option A: Stored Generated Column (MariaDB 10.2+ / MySQL 5.7+)
    — If your MariaDB version supports REGEXP_REPLACE in generated columns:
    — ALTER TABLE cart_products
    — ADD COLUMN prodname_digits VARCHAR(30) GENERATED ALWAYS AS (REGEXP_REPLACE(prodname, ‘[^0-9]’, ”)) STORED,
    — ADD INDEX idx_prodname_digits (prodname_digits);

    — Standard indexed column (universal compatibility across all MySQL / MariaDB versions):
    ALTER TABLE cart_products
    ADD COLUMN prodname_digits VARCHAR(30) NOT NULL DEFAULT ” AFTER prodname,
    ADD INDEX idx_prodname_digits (prodname_digits);

    — Populate clean digits in batches:
    UPDATE cart_products
    SET prodname_digits = REGEXP_REPLACE(prodname, ‘[^0-9]’, ”)
    WHERE prodname_digits = ”;

    — Optional Trigger to keep prodname_digits synced automatically on INSERT/UPDATE:
    DELIMITER $$
    CREATE TRIGGER trg_cart_products_digits_insert
    BEFORE INSERT ON cart_products
    FOR EACH ROW
    BEGIN
    SET NEW.prodname_digits = REGEXP_REPLACE(NEW.prodname, ‘[^0-9]’, ”);
    END$$

    CREATE TRIGGER trg_cart_products_digits_update
    BEFORE UPDATE ON cart_products
    FOR EACH ROW
    BEGIN
    IF NEW.prodname != OLD.prodname OR NEW.prodname_digits = ” THEN
    SET NEW.prodname_digits = REGEXP_REPLACE(NEW.prodname, ‘[^0-9]’, ”);
    END IF;
    END$$
    DELIMITER ;

    – High-frequency write & session tables (Priority 1)
    ALTER TABLE cart_sessions ENGINE=InnoDB;
    ALTER TABLE cart_system_log ENGINE=InnoDB;
    ALTER TABLE cart_searches ENGINE=InnoDB;
    ALTER TABLE cart_searches_extended ENGINE=InnoDB;
    ALTER TABLE cart_product_views ENGINE=InnoDB;
    ALTER TABLE cart_unique_visitors ENGINE=InnoDB;
    ALTER TABLE cart_reseller_api_log ENGINE=InnoDB;
    ALTER TABLE cart_telinta_api_log ENGINE=InnoDB;

    — Transactional & customer tables (Priority 2)
    ALTER TABLE cart_users ENGINE=InnoDB;
    ALTER TABLE cart_transactions ENGINE=InnoDB;
    ALTER TABLE cart_subscribers ENGINE=InnoDB;
    ALTER TABLE cart_wishlists ENGINE=InnoDB;
    ALTER TABLE cart_wishlist_items ENGINE=InnoDB;
    ALTER TABLE cart_reviews ENGINE=InnoDB;
    ALTER TABLE cart_returns ENGINE=InnoDB;
    ALTER TABLE cart_order_messages ENGINE=InnoDB;
    ALTER TABLE cart_order_coupons ENGINE=InnoDB;
    ALTER TABLE cart_order_downloads ENGINE=InnoDB;
    ALTER TABLE cart_gift_certificates ENGINE=InnoDB;
    ALTER TABLE cart_gift_certificate_history ENGINE=InnoDB;

    — Content and catalogue lookup tables (Priority 3)
    ALTER TABLE cart_pages ENGINE=InnoDB;
    ALTER TABLE cart_news ENGINE=InnoDB;
    ALTER TABLE cart_product_comparisons ENGINE=InnoDB;
    ALTER TABLE cart_product_configurable_fields ENGINE=InnoDB;
    ALTER TABLE cart_product_customfields_report ENGINE=InnoDB;
    ALTER TABLE cart_product_discounts ENGINE=InnoDB;
    ALTER TABLE cart_product_related_byviews ENGINE=InnoDB;
    ALTER TABLE cart_product_tags ENGINE=InnoDB;
    ALTER TABLE cart_product_tagassociations ENGINE=InnoDB;
    ALTER TABLE cart_product_variation_combinations ENGINE=InnoDB;
    ALTER TABLE cart_redirects ENGINE=InnoDB;
    ALTER TABLE cart_shipping_addresses ENGINE=InnoDB;
    ALTER TABLE cart_shipping_methods ENGINE=InnoDB;
    ALTER TABLE cart_shipping_zones ENGINE=InnoDB;
    ALTER TABLE cart_shipping_zone_locations ENGINE=InnoDB;
    ALTER TABLE cart_tax_zones ENGINE=InnoDB;
    ALTER TABLE cart_vendors ENGINE=InnoDB;
    ALTER TABLE cart_vendor_payments ENGINE=InnoDB;

    Nishit Shan
    Participant
    Post count: 1981
    in reply to: Stripe Integration #16458

    Hello Andrey,

    There is some good news for you!
    After using multiple technologies and conducting continuous research for the past 8 hours, I have identified and implemented a solution. Please ask your server team to check it again and share their feedback .

    1.
    Issue: Every time a customer viewed a single phone number, the server was forced to scan all 594,000+ numbers twice, running a heavy mathematical formula row-by-row. This single feature was taking up to 10 minutes per page view and choking the server.
    Fixed: Completely modernized and rewritten the “Similar Numbers” widget. Instead of forcing the database to perform 1.2 million heavy calculations per view, it now uses instant database lookups and calculates matches in computer memory.

    2.
    Issue:Several large database tables (including product reservations and session tables) had no indexes, forcing the database to scan tens of thousands of rows on basic lookups.
    Fixed:Optimized category queries to use direct relationships instead of slow comma-separated text searches.

    3.
    Issue:Multiple active tables were locking the entire table every time a visitor performed a search or visited a page, queuing up other customers.
    Fixed:Prepared clean indexing scripts and converted high-traffic tables to InnoDB (row-level locking), allowing multiple customers to shop simultaneously without waiting.

    There is one table that I am unable to handle and convert to InnoDB (cart_product_related_byviews). Please ask the server team to convert it to InnoDB by running the following query:
    ALTER TABLE cart_product_related_byviews ENGINE=InnoDB;
    Also, please delete data older than 6 months from this table.

    Nishit Shan
    Participant
    Post count: 1981
    in reply to: Stripe Integration #16457

    Hello Andrey,

    Please provide a priority order between nanotelecom.us, database query fixes, and the previous registration and other issues you mentioned, so I can proceed accordingly.

    Nishit Shan
    Participant
    Post count: 1981
    in reply to: Stripe Integration #16455

    Hello Andrey,

    I have seen the report and i will need to review the project’s code and database and this need to create a separate task and assign budget for it . It is not a task can be fix in a ongoing task .

    This task will require minimum of 7 days .

    Nishit Shan
    Participant
    Post count: 1981
    in reply to: Stripe Integration #16445

    Hello Andrey,

    https://techlyncs-my.sharepoint.com/:t:/r/personal/salman_techlyncs_com/Documents/Attachments/slow-query-analysis-new.md?d=we4c5ea0dac2d4e388893b1dfa89fe8e6&csf=1&web=1&e=ndekB0

    This link is not accessible on my site , asking for login on Microsoft . Please provide different public link.

    Nishit Shan
    Participant
    Post count: 1981
    in reply to: Stripe Integration #16444

    Hello Andrey,
    Thanks for the post #16441 .
    I’m sorry, I think I did not express my point correctly. When I said I was not surprised, it did not mean I ignored the issue. I was not surprised because, at that time, this was the only or best solution to achieve the goal. Nowadays, queries are handled differently, and query building has become more modern and updated. I did not make this change because it required adding an additional table as a pilot table, and implementing it would have required code and database structural changes. I did not want to disturb your running site or risk any mishap.

    Although, I want to clarify that I was aware of that particular function not causing issues. I only realized it was causing issues after the team shared the query.

    I will review your other points and get back to you. The above is just my clarification.

    Nishit Shan
    Participant
    Post count: 1981
    in reply to: Stripe Integration #16439

    Hello Andrey,

    I have fixed all the remaining tasks mentioned in post #16402. Please check the following link for reference:
    [video src="https://excellentnumbers.com/temp_vid/Screencast%20from%202026-09-08%2016-04-51.mp4" /]
    The 1 you are seeing on the device is nothing to be surprised about. It is basically a serial number, and there is no need to remove it—just something to be aware of.

    Regarding the database issue, below are my findings. This is not related to the Bootstrap template integration. As an experienced developer, I am not surprised this issue exists because the technology used in the codebase is outdated, and query building was not as modern as it is today.

    The related-products query is slow because:
    It checks every product using levenshtein_ratio().
    It calculates the same similarity multiple times.
    Categories are stored as comma-separated values, so FIND_IN_SET() cannot use indexes.
    Phone numbers are being matched as fuzzy product names.
    The fallback query may return unrelated products.

    The levenshtein_ratio() function is the main cause of the performance issue. To properly resolve this, I will need to create a relational table because categories are currently stored in a comma-separated format. After that, the query will need to be updated accordingly. If you would like me to proceed, please ensure that a backup of the latest database is taken.

    Regarding database cleaning, I cannot safely remove data because records may be interlinked, and this is not a small project. However, you can clean data for a specific date range if you are sure it can be deleted.

    Nishit Shan
    Participant
    Post count: 1981
    in reply to: Stripe Integration #16432

    Hello Andrey,

    Please check the video for reference:
    [video src="https://excellentnumbers.com/temp_vid/Screencast%20from%202026-09-07%2014-38-52.mp4" /]

    I have implemented all the registration process changes you mentioned in post #16402, including making the company name optional and adding a processing loader.
    I am currently reviewing the remaining tasks in post #16402.

    Since I am actively working on this, I will try to complete the Nanotel tasks within the next 2–3 days.

    Nishit Shan
    Participant
    Post count: 1981
    in reply to: Custom Works #16428

    Hello Andrey,

    Sorry, I am not a server expert, so I may not be able to explain this in depth. However, I did some research on your point, and below is a suggestion that might help your team:

    Simply adding an A Record is not enough.
    Why?
    DNS only maps a domain to a server IP address. It does not handle:
    Routing
    Proxying
    Keeping the same URL in the browser

    Recommended approach: Reverse Proxy
    On the AWS server (using Nginx or Apache):
    Accept requests for portal.nt.com
    Internally fetch content from portal.nt.us
    Return the response without changing the browser URL

    This approach should achieve the expected behavior.

    Nishit Shan
    Participant
    Post count: 1981
    in reply to: Stripe Integration #16427

    Hello Andrey,

    I am checking the code for #16402 , i will update you the progress by end of the today .

    Nishit Shan
    Participant
    Post count: 1981
    in reply to: Custom Works #16422

    Hello Andrey,

    How are they working on the .com domain? Could you please ask them to explain how they are connecting it with the .us side? We have worked on the .us domain, not the .com domain, and the .us site is working both with and without “www”. Kindly ask them to explain the complete process step by step so we can understand what they have done to achieve this.

    Also, just to inform you, I have fixed the hidden error issue on the login page:

    Problem: Previously, when a user entered incorrect credentials, an expired captcha, or encountered a profile sync issue, the page would sometimes refresh without showing any error message.
    Solution: I updated the system to properly capture all authentication responses, ensuring that every failure reason is clearly displayed to the user.
    Updated the background authentication connection (Telinta API) to fail safely and gracefully without breaking the page layout or crash redirects if a temporary connection delay occurs.

    • This reply was modified 6 days, 5 hours ago by Nishit Shan.
    Nishit Shan
    Participant
    Post count: 1981
    in reply to: Stripe Integration #16419

    Hello Andrey,

    For post #16375, I have reviewed the screenshot you provided. I understand that these queries take time because they are connected with external APIs like Intelequient, so the database queries may take longer to complete.

    For post #16402, I am reviewing each point carefully and will work on them one by one.

    For post #16405, regarding the error page, please refer to my responses in posts #16410 and #16412.

    Nishit Shan
    Participant
    Post count: 1981
    in reply to: Stripe Integration #16412

    Hello Andrey,

    I have strengthened the index page code conditions and log conditions. I have also tested it with and without a VPN, and on 3G, 4G, and 5G networks. I am seeing that the site is running without any issues.

    So I would request you to please ask the customer to test it and provide feedback as soon as possible. I also want to resolve this issue quickly and ensure you are not frustrated.

    Thank you for your patience and cooperation.

    Nishit Shan
    Participant
    Post count: 1981
    in reply to: Stripe Integration #16410

    Hello Andrey,

    Just for reference, please check the screenshot using this link: https://ibb.co/zWLtjczK

    Although ,I am digging deep into the code to make sure I can fix the issue.

    Nishit Shan
    Participant
    Post count: 1981
    in reply to: Stripe Integration #16409

    Hello Andrey,

    Sorry for the frustration. I have tried to reproduce this issue many times, but I am not able to see it on my end.

    Could you please try accessing the URL yourself and let me know if you are also facing the issue mentioned in post #16405?

    I understand this is frustrating, but I’m not seeing the issue on my side for any reason.

Viewing 15 posts - 1 through 15 (of 1,977 total)