Opencart 3 getProduct method causes slow page loading - opencart

My Opencart 3.0 is running very slow. In the network tab in the chrome browser inspector, it records 23.02 seconds for the category page to load.
When I try to debug it, I could see that the slow loading happens here
catalog/model/catalog/product.php - public function getProduct($product_id)
Inside this method, when I comment out this line in the returned array - 'product_id' => $query->row['product_id'], the loading speed comes to 7s.
The method getProduct($product_id) is called in this method getProducts($data = array()). The part where the method is called looks like below.
$query = $this->db->query($sql);
foreach ($query->rows as $result) {
$product_data[$result['product_id']] = $this->getProduct($result['product_id']);
}
When I comment out this line
//$product_data[$result['product_id']] = $this->getProduct($result['product_id']);
The loading speed goes to 3.5s.
What I could not figure out is why this part of the code takes time to return - 'product_id' => $query->row['product_id']
I will appreciate your help.

It looks like your issues comes from getProduct() and getProducts() methods in the catalog/model/catalog/product.php file. Especially this row:
'product_id' => $query->row['product_id']
So you could check your DB performance, how much time is taking to complete this query.
If it takes too much time and your columns are not indexed, you could index them.
You could also try to limit the number of rows being retrieved in the query by using a LIMIT clause or a WHERE clause.
You could use Opencart cache system, to reduce time.
On first sign it looks more like DB related problem, instead of code problem.

Related

Round shipping cost in Shopware 5 based on condition

I need to round the shipping costs when an article is added till the order is completed based on if certain condition is active. I already tried subscribing the following events:
'sOrder::getOrderById::after' => 'afterGetOrder',
'Shopware_Modules_Order_SaveOrder_FilterParams' => 'filterOrderParams'
with the following implementation:
public function filterOrderParams(\Enlight_Event_EventArgs $args)
{
$return = $args->getReturn();
$return['invoice_shipping'] = ceil($return['invoice_shipping']);
$return['invoice_shipping_net'] = ceil($return['invoice_shipping_net']);
$subject->sShippingcostsNumeric = ceil($subject->sShippingcostsNumeric);
$subject->sShippingcostsNumericNet = ceil($subject->sShippingcostsNumericNet);
$args->setReturn($return);
}
public function afterGetOrder(\Enlight_Hook_HookArgs $args)
{
if (!$this->checkIfActive()) {
return;
}
$return = $args->getReturn();
$return['invoice_shipping'] = ceil($return['invoice_shipping']);
$return['invoice_shipping_net'] = ceil($return['invoice_shipping_net']);
$args->setReturn($return);
}
But it does not seem to be working. I also tried
Shopware()->Modules()->Order()->sShippingcosts = ceil($sBasket['sShippingcosts']); but nothing. I know there is an event on order save, which I can hook and change the parameters, but that is too late as the cost in the cart and checkout would not be rounded up (not until the order is completed)
So is there a way to round shipping costs in shopware 5 ?
EDIT: Ideally it would also be great if the changes are stored in database directly so any further manipulation on the order shows / updates the correct rounded values.
For anyone looking, I ended up changing the template variable in the Frontend_Checkout event subscriber and letting it change the value in the database on Shopware_Modules_Order_SaveOrder_FilterParams. Hope it helps someone. Took me a while to figure this out. This hook sOrder::getOrderById::after was not needed at all, and doesn't seem to be working either.

Create Inventory Adjustment giving an error

I am trying to create an inventory adjustment from a MAP/REDUCE script. the record from which i am setting the values is getting ftom a search in getInputData(). In map function i am loading that custom record and setting these values
var newcase_inv_Adj = record.create({type:'inventoryadjustment',isDynamic:true});
newcase_inv_Adj.setValue({fieldId:'account',value:creel_account});
newcase_inv_Adj.setValue({fieldId:'custbody_cp_adjreasoncode',value:creel_reasoncode});
newcase_inv_Adj.setValue({fieldId: 'custbody_c_from', value: name});
newcase_inv_Adj.selectNewLine({sublistId:'inventory'});
newcase_inv_Adj.setCurrentSublistValue({sublistId:'inventory',fieldId:'item',value:creel_item});
newcase_inv_Adj.setCurrentSublistValue({sublistId:'inventory',fieldId:'location',value:creellocation});
newcase_inv_Adj.setCurrentSublistValue({sublistId:'inventory',fieldId:'adjustqtyby',value:creel_weigh_oh});
var create_inv_detail = newcase_inv_Adj.getCurrentSublistSubrecord({sublistId: 'inventory',fieldId: 'inventorydetail'});
create_inv_detail.selectNewLine({sublistId:'inventoryassignment' });
create_inv_detail.setCurrentSublistValue({sublistId:'inventoryassignment',fieldId:'receiptinventorynumber',value: creel_casenumber});
create_inv_detail.setCurrentSublistText({sublistId:'inventoryassignment',fieldId:'binnumber',value: creel_bin });
create_inv_detail.setCurrentSublistValue({sublistId:'inventoryassignment',fieldId:'quantity',value: creel_weigh_oh });
create_inv_detail.commitLine('inventoryassignment');log.debug("N","commited inventoryassignment");
newcase_inv_Adj.commitLine({sublistId:'inventory'});log.debug("N","commited inventory");
var invAdjID = newcase_inv_Adj.save();log.debug("N","invAdjID : "+invAdjID);
But, I am getting this error as {"type":"error.SuiteScriptError","name":"UNEXPECTED_ERROR"
Is it because of Map/Reduce script?
I don't find anything wrong in the code.
Few suggestions:
- Follow the sequence: Set subsidiary value before you setvalue for account or any other mandatory field.
- First try with inventory items without serial numbers and see if you continue to face same problem.
- You need to make sure you all your variables has valid value (not null or undefined).
- First try doing this in a schedule script.

Postman accessing the stored results in the database leveldb

So I have a set of results in Postman from a runner on a collection using some data file for iterations - I have the stored data from the runner in the Postman app on Linux, but I want to know how I can get hold of the data. There seems to be a database hidden away in the ~/.config directory (/Desktop/file__0.indexeddb.leveldb) - that looks like it has the data from the results there.
Is there anyway that I can get hold of the raw data - I want to be able to save the results from the database and not faff around with running newman or hacking a server to post the results and then save, I already have 20000 results in a collection. I want to be able to get the responseData from each post and save it to a file - I will not execute the posts again, I need to just work out a way
I've tried KeyLord, FastNoSQL (this crashes), levelDBViewer(Jar), but not having any luck here.
Any suggestions?
inline 25024 of runner.js a simple yet hack for small numbers of results I can do the following
RunnerResultsRequestListItem = __WEBPACK_IMPORTED_MODULE_2_pure_render_decorator___default()(_class = class RunnerResultsRequestListItem extends __WEBPACK_IMPORTED_MODULE_0_react__["Component"] {
constructor(props) {
super(props);
var text = props.request.response.body,
blob = new Blob([text], { type: 'text/plain' }),
anchor = document.createElement('a');
anchor.download = props.request.ref + ".txt";
anchor.href = (window.webkitURL || window.URL).createObjectURL(blob);
anchor.dataset.downloadurl = ['text/plain', anchor.download, anchor.href].join(':');
anchor.click();
it allows me to save but obviously I have to click save for now, anyone know how to automate the saving part - please add something here!

Zend Framework - Doctrine2 - Repository Query Caching

I'm looking at Caching and how to use it in Doctrine.
I've got the following in my Zend Framework Bootstrap.php:
// Build Configuration
$orm_config = new \Doctrine\ORM\Configuration();
// Caching
$cacheOptions = $options['cache']['backendOptions'];
$cache = new \Doctrine\Common\Cache\MemcacheCache();
$memcache = new Memcache;
$memcache->connect($cacheOptions['servers']['host'], $cacheOptions['servers']['port']);
$cache->setMemcache($memcache);
$orm_config->setMetadataCacheImpl($cache);
$orm_config->setQueryCacheImpl($cache);
$orm_config->setResultCacheImpl($cache);
I'm running a very simple query on my DB using:
self::_instance()->_em->getRepository('UserManagement\Users')->find('1');
And I'm not sure if I'm using caching properly, because with it on (as
per the above config) the query seems to take twice as long to execute
as with it disabled, is this right?
Thanks in advance,
Steve
I seem to have sorted this myself, sort of related to enter link description here. Basically, from what I understand a repository query like:
self::_instance()->_em->getRepository('UserManagement\Users')->find('1');
Will not cache the results. If the same query is executed again throughout the script processing, it will not perform the search and use the result it has in memory - this isn't the same as real caching, in my case using Memcache.
The only way to achieve this, is to override the Doctrine EntityRepository find() method in a custom repository with something like:
public function find($id)
{
// Retrieve an instance of the Entity Manager
$qb = $this->getEntityManager()->createQueryBuilder();
$qb->select('u')
->from('UserManagement\Users', 'u')
->where('u.id = :id')
->setParameter('id', $id);
$query = $qb->getQuery();
$query->useResultCache(TRUE);
$result = $query->getSingleResult();
return $result;
}
Notably, the most important line from the above is $query->useResultCache(TRUE); - this informs the Application to cache the results.
Hope this helps.

Codeigniter + Dwoo

I got problem when implementing my CMS using Codeigniter 1.7.2 and Dwoo. I use Phil Sturgeon Dwoo library. My problem is I want user create template from the admin panel, it means all template will be stored into database including all Dwoo variable and functions.My questions:
Is it possible to load dwoo template from database?
How to parse dwoo variable or function from database? I tried to load content from database which is include dwoo var and function inside it, and i have tried to do evaluation using dwoo eval() function and phil sturgeon string_parse() but still have no luck.
for example:
my controller
$data['header'] = "<h1>{$header}</h1>"; --> this could be loaded from database
$this->parser->parse('header',$data);
my view
{$header}
This is the error message:
<h4>A PHP Error was encountered</h4>
<p>Severity: Notice</p>
<p>Message: Undefined index: header_title</p>
<p>Filename: compiled/805659ab5e619e094cac7deb9c8cbfb5.d17.php</p>
<p>Line Number: 11</p>
header_title is dwoo variable that loaded from DB.
Thank you,
It is definitely possible to do this, but for performance reasons it would probably be faster to store the templates as files on the filesystem, even if they're edited by users. If you're smart with file naming you can avoid most hits to the database.
Anyway, if you really want to do it with the database, the following should work:
// rendering the header
$template = '<h1>{$header}</h1>'; // loaded from db, don't use double-quotes for examples or $header will be replaced by nothing
$data = array('header' => 'Hello'); // loaded from db as well I assume
$headerOutput = $this->parser->parse_string($template, $data, true); // true makes it return the output
// now rendering the full page (if needed?)
$data = array('header' => $headerOutput);
$this->parser->parse('header', $data); // no 'true', so goes straight to output
The view would then contain {$header} and the output from the header template is passed to that variable.
Now I'm not sure how CI works so it might be better to just output the result of the first template and skip the second one entirely, but I'll leave that up to you.