Forum Replies Created
-
AuthorPosts
-
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 TABLEcart_product_customfieldsx
ADD INDEXidx_customfieldsx_fieldprodid(fieldprodid),
ADD INDEXidx_customfieldsx_prod_name(fieldprodid,fieldname),
ADD INDEXidx_customfieldsx_name_val(fieldname(50),fieldvalue(50));— 2. cart_sessions: Add index for session cleanup / timestamp lookups
ALTER TABLEcart_sessions
ADD INDEXidx_sessions_sesslastupdated(sesslastupdated);— 3. cart_products: Add composite indexes for availability + visibility + inventory
ALTER TABLEcart_products
ADD INDEXidx_prod_vis_avail_inv(prodvisible,prodavailability,prodcurrentinv),
ADD INDEXidx_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 TABLEcart_products
— ADD COLUMNprodname_digitsVARCHAR(30) GENERATED ALWAYS AS (REGEXP_REPLACE(prodname, ‘[^0-9]’, ”)) STORED,
— ADD INDEXidx_prodname_digits(prodname_digits);— Standard indexed column (universal compatibility across all MySQL / MariaDB versions):
ALTER TABLEcart_products
ADD COLUMNprodname_digitsVARCHAR(30) NOT NULL DEFAULT ” AFTERprodname,
ADD INDEXidx_prodname_digits(prodname_digits);— Populate clean digits in batches:
UPDATEcart_products
SETprodname_digits= REGEXP_REPLACE(prodname, ‘[^0-9]’, ”)
WHEREprodname_digits= ”;— Optional Trigger to keep prodname_digits synced automatically on INSERT/UPDATE:
DELIMITER $$
CREATE TRIGGERtrg_cart_products_digits_insert
BEFORE INSERT ONcart_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 ONcart_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 TABLEcart_sessionsENGINE=InnoDB;
ALTER TABLEcart_system_logENGINE=InnoDB;
ALTER TABLEcart_searchesENGINE=InnoDB;
ALTER TABLEcart_searches_extendedENGINE=InnoDB;
ALTER TABLEcart_product_viewsENGINE=InnoDB;
ALTER TABLEcart_unique_visitorsENGINE=InnoDB;
ALTER TABLEcart_reseller_api_logENGINE=InnoDB;
ALTER TABLEcart_telinta_api_logENGINE=InnoDB;— Transactional & customer tables (Priority 2)
ALTER TABLEcart_usersENGINE=InnoDB;
ALTER TABLEcart_transactionsENGINE=InnoDB;
ALTER TABLEcart_subscribersENGINE=InnoDB;
ALTER TABLEcart_wishlistsENGINE=InnoDB;
ALTER TABLEcart_wishlist_itemsENGINE=InnoDB;
ALTER TABLEcart_reviewsENGINE=InnoDB;
ALTER TABLEcart_returnsENGINE=InnoDB;
ALTER TABLEcart_order_messagesENGINE=InnoDB;
ALTER TABLEcart_order_couponsENGINE=InnoDB;
ALTER TABLEcart_order_downloadsENGINE=InnoDB;
ALTER TABLEcart_gift_certificatesENGINE=InnoDB;
ALTER TABLEcart_gift_certificate_historyENGINE=InnoDB;— Content and catalogue lookup tables (Priority 3)
ALTER TABLEcart_pagesENGINE=InnoDB;
ALTER TABLEcart_newsENGINE=InnoDB;
ALTER TABLEcart_product_comparisonsENGINE=InnoDB;
ALTER TABLEcart_product_configurable_fieldsENGINE=InnoDB;
ALTER TABLEcart_product_customfields_reportENGINE=InnoDB;
ALTER TABLEcart_product_discountsENGINE=InnoDB;
ALTER TABLEcart_product_related_byviewsENGINE=InnoDB;
ALTER TABLEcart_product_tagsENGINE=InnoDB;
ALTER TABLEcart_product_tagassociationsENGINE=InnoDB;
ALTER TABLEcart_product_variation_combinationsENGINE=InnoDB;
ALTER TABLEcart_redirectsENGINE=InnoDB;
ALTER TABLEcart_shipping_addressesENGINE=InnoDB;
ALTER TABLEcart_shipping_methodsENGINE=InnoDB;
ALTER TABLEcart_shipping_zonesENGINE=InnoDB;
ALTER TABLEcart_shipping_zone_locationsENGINE=InnoDB;
ALTER TABLEcart_tax_zonesENGINE=InnoDB;
ALTER TABLEcart_vendorsENGINE=InnoDB;
ALTER TABLEcart_vendor_paymentsENGINE=InnoDB;in reply to: Stripe Integration #16458Hello 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 TABLEcart_product_related_byviewsENGINE=InnoDB;
Also, please delete data older than 6 months from this table.in reply to: Stripe Integration #16457Hello 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.
in reply to: Stripe Integration #16455Hello 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 .
-
This reply was modified 1 day, 8 hours ago by
Nishit Shan.
in reply to: Stripe Integration #16445Hello Andrey,
This link is not accessible on my site , asking for login on Microsoft . Please provide different public link.
in reply to: Stripe Integration #16444Hello 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.
in reply to: Stripe Integration #16439Hello 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.
-
This reply was modified 2 days, 8 hours ago by
Nishit Shan.
in reply to: Stripe Integration #16432Hello 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.
in reply to: Custom Works #16428Hello 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 browserRecommended 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 URLThis approach should achieve the expected behavior.
in reply to: Stripe Integration #16427Hello Andrey,
I am checking the code for #16402 , i will update you the progress by end of the today .
in reply to: Custom Works #16422Hello 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, 13 hours ago by
Nishit Shan.
in reply to: Stripe Integration #16419Hello 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.
in reply to: Stripe Integration #16412Hello 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.
in reply to: Stripe Integration #16410Hello 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.
-
This reply was modified 1 week ago by
Nishit Shan.
in reply to: Stripe Integration #16409Hello 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.
-
This reply was modified 1 day, 8 hours ago by
-
AuthorPosts