Magento error when trying to duplication product - magento-1.7

I am using magento 1.7. i have got issue i don't know why this is happen. i just open product in backend for edit then click on duplicate then i got following error
Warning: Illegal string offset 'new_file' in D:\wamp\www\easyshop\app\code\core\Mage\Catalog\Model\Product\Attribute\Backend\Media.php on line 158
when i try following code to debug file:
print_r($newImages);
die;
then i got this following data
Array
(
[/s/a/samsung_galaxy_s2_front1.jpg] => /s/a/samsung_galaxy_s2_front1_4.jpg
[/s/g/sgs2p1.jpg] => /s/g/sgs2p1_4.jpg
[/s/g/sgs2_11.jpg] => /s/g/sgs2_11_4.jpg
[/s/g/sgs2-4386.jpg] => /s/g/sgs2-4386_4.jpg
)
I thing array keys are wrong can you please give solution to solve this problem

I had the same problem on 1.7.02. The solution I found was to change Magento's (IMHO) bugged code.
On Mage_Catalog_Model_Product_Attribute_Backend_Media i've changed the lines where you find:
// For duplicating we need copy original images.
$duplicate = array();
foreach ($value['images'] as &$image) {
if (!isset($image['value_id'])) {
continue;
}
$duplicate[$image['value_id']] = $this->_copyImage($image['file']);
$newImages[$image['file']] = $duplicate[$image['value_id']];
}
for:
// For duplicating we need copy original images.
$duplicate = array();
foreach ($value['images'] as &$image) {
if (!isset($image['value_id'])) {
continue;
}
$duplicate[$image['value_id']] = $this->_copyImage($image['file']);
$newImages[$image['file']] = array();
$newImages[$image['file']]['new_file'] = $duplicate[$image['value_id']];
$newImages[$image['file']]['label'] = $image['label'];
}
It did the trick for me... Images are now being properly duplicated and enabled on new product.

Related

Tinytext issue on Upgrade magento to 2.3.0

In Magento my website 's current version is magento 2.2.5 . Now i have updated it to latest version magento 2.3.0 .
But there i am getting error when i run
php bin/magento setup:upgrade
I got this error
Cannot process definition to array for type tinytext
Please suggest me solution.
Thank You
You are getting this error because "data type" of any third party extension's table's column is tinytext.
So you need to find out column name using debug in following file.
Open this file /vendor/magento/framework/Setup/Declaration/Schema/Db/DefinitionAggregator.php and check this fromDefinition() method and then add debug code to find column name.
public function fromDefinition(array $data)
{
$type = $data['type'];
if (!isset($this->definitionProcessors[$type])) {
/* Add Code for Debug */
echo "<pre>";
print_r($data); exit();
/* Code End */
throw new \InvalidArgumentException(
sprintf("Cannot process definition to array for type %s", $type)
);
}
$definitionProcessor = $this->definitionProcessors[$type];
return $definitionProcessor->fromDefinition($data);
}
After that please run setup:upgrade command and you will get array of column data in console. so from this array you will get name of column from your third party extension table.
Now from that table please change column's data type "tinytext" to "text" and issue will be fixed.
Note : You might also get issues from ENUM and MEDIUMINT data type as well, so do the same steps if get any other data type issue.
Open file
/vendor/magento/framework/Setup/Declaration/Schema/Db/DefinitionAggregator.php
Replace function fromDefinition:
With:
public function fromDefinition(array $data)
{
$type = $data['type'];
if(in_array($type, ["tinytext", "enum"])){
$data['type'] = 'text';
$type = 'text';
}
if(in_array($type, ['time', 'mediumint'])){
$data['type'] = 'datetime';
$type = 'datetime';
}
if(in_array($type, ['mediumint'])){
$data['type'] = 'int';
$type = 'int';
}
if (!isset($this->definitionProcessors[$type])) {
throw new \InvalidArgumentException(
sprintf("Cannot process definition to array for type %s", $type)
);
}
$definitionProcessor = $this->definitionProcessors[$type];
return $definitionProcessor->fromDefinition($data);
}
Yes it is because of some extensions.I just exported the database and search for keywords tinytext , found a table which use this format, I changed it to TEXT and the problem solved.
You might want to check your extensions. I debugged this error for myself and it originated from an extension which was included with a theme purchased, but not updated.

Get Line Items in an Invoice logic hook in SuiteCRM

Via a logic hook I'm trying to update fields of my products, after an invoice has been saved.
What I understand so far is, that I need to get the invoice related AOS_Products_Quotes and from there I could get the products, update the required fields and save the products. Does that sound about right?
The logic hook is being triggered but relationships won't load.
function decrement_stocks ( $bean, $event, $arguments) {
//$bean->product_value_c = $bean->$product_unit_price * $bean->product_qty;
$file = 'custom/modules/AOS_Invoices/decrement.txt';
// Get the Invoice ID:
$sInvoiceID = $bean->id;
$oInvoice = new AOS_Invoices();
$oInvoice->retrieve($sInvoiceID);
$oInvoice->load_relationship('aos_invoices_aos_product_quotes');
$aProductQuotes = $oInvoice->aos_invoices_aos_product_quotes->getBeans();
/*
$aLineItemslist = array();
foreach ($oInvoice->aos_invoices_aos_product_quotes->getBeans() as $lineitem) {
$aLineItemslist[$lineitem->id] = $lineitem;
}
*/
$sBean = var_export($bean, true);
$sInvoice = var_export($oInvoice, true);
$sProductQuotes = var_export($aProductQuotes, true);
$current = $sProductQuotes . "\n\n\n------\n\n\n" . $sInvoice . "\n\n\n------\n\n\n" . $sBean;
file_put_contents($file, $current);
}
The invoice is being retrieved just fine. But either load_relationship isn't doing anything ($sInvoice isn't changing with or without it) and $aProductQuotes is Null.
I'm working on SuiteCRM 7.8.3 and tried it on 7.9.1 as well without success. What am I doing wrong?
I'm not familiar with SuiteCRM specifics, however I'd always suggest to check:
Return value of retrieve(): bean or null?
If null, then no bean with the given ID was found.
In such case $oInvoice would stay empty (Your comment suggests that's not the case here though)
Return value of load_relationship(): true (success) or false (failure, check logs)
And I do wonder, why don't you use $bean?
Instead you seem to receive another copy/reference of $bean (and calling it $oInvoice)? Why?
Or did you mean to receive a different type bean that is somehow connected to $bean?
Then its surely doesn't have the same id as $bean, unless you specifically coded it that way.

How to generate JSDoc comments for functions when no comment exists?

I'm trying to create a plugin for JSDoc.
I'm following the documentation (which, ironically, is lacking) and I'm not sure how to do this.
My plugin is loaded properly, and I'm trying a simple example. Here's my plugin (which loads, because I can throw an error from there to stop jsdoc from running):
visitNode: function(node, e, parser, currentSourceName) {
if(node.type === 109){
if(!e.comment || e.comment ==="#undocumented"){
var startComment = '/**',
endComment = '\n*/';
var params = node.getParams(),
paramsComment = '';
for(var i=0; i<params.length; i++){
paramsComment += '\n* #param ' + params[i];
}
e.comment = startComment +
paramsComment +
endComment;
}
}
please note that node.type === 109 is equivalent to Token.FUNCTION, which should be available as per their example here, but Token is undefined in the plugin.
If you know of a better site which explains how to write a JSDoc plugin, then that would be very much appreciated too... thanks
I also had this problem and it seems strange that JSDoc does not have some kind of already made option for that or at least a plugin.
Anyway creating this plugin has solved my problem. I am using JSDoc version 3.4:
'use strict';
exports.handlers = {
symbolFound:function(e) {
if(e.astnode.type === "FunctionDeclaration" ) {
if( (e.comment==="#undocumented")){
e.comment = '/** undocumented */';
}
}
}
};

WWW::Mechanize::Firefox looping though links

I am using a foreach to loop through links. Do I need a $mech->back(); to continue the loop or is that implicit.
Furthermore do I need a separate $mech2 object for nested for each loops?
The code I currently have gets stuck (it does not complete) and ends on the first page where td#tabcolor3 is not found.
foreach my $sector ($mech->selector('a.link2'))
{
$mech->follow_link($sector);
foreach my $place ($mech->selector('td#tabcolor3'))
{
if (($mech->selector('td#tabcolor3', all=>1)) >= 1)
{
$mech->follow_link($place);
print $_->{innerHTML}, '\n'
for $mech->selector('td.dataCell');
$mech->back();
}
else
{
$mech->back();
}
}
You cannot access information from a page when it is no longer on display. However, the way foreach works is to build the list first before it is iterated through, so the code you have written should be fine.
There is no need for the call to back as the links are absolute. If you had used click then there must be a link in the page to click on, but with follow_link all you are doing is going to a new URL.
There is also no need to check the number of links to follow, as a for loop over an empty list will simply not be executed.
To make things clearer I suggest that you assign the results of selector to an array before the loop.
Like this
my #sectors = $mech->selector('a.link2');
for my $sector (#sectors) {
$mech->follow_link($sector);
my #places = $mech->selector('td#tabcolor3');
for my $place (#places) {
$mech->follow_link($place);
print $_->{innerHTML}, '\n' for $mech->selector('td.dataCell');
}
}
Update
My apologies. It seems that follow_link is finicky and needs to follow a link on the current page.
I suggest that you extract the href attribute from each link and use get instead of follow_link.
my #selectors = map $_->{href}, $mech->selector('a.link2');
for my $selector (#selectors) {
$mech->get($selector);
my #places = map $_->{href}, $mech->selector('td#tabcolor3');
for my $place (#places) {
$mech->get($place);
print $_->{innerHTML}, '\n' for $mech->selector('td.dataCell');
}
}
Please let me know whether this works on the site you are connecting to.
I recommend to use separate $mech object for this:
foreach my $sector ($mech->selector('a.link2'))
{
my $mech = $mech->clone();
$mech->follow_link($sector);
foreach my $place ($mech->selector('td#tabcolor3'))
{
if (($mech->selector('td#tabcolor3', all=>1)) >= 1)
{
my $mech = $mech->clone();
$mech->follow_link($place);
print $_->{innerHTML}, '\n'
for $mech->selector('td.dataCell');
#$mech->back();
}
# else
# {
# $mech->back();
# }
}
I am using WWW:Mechanize::Firefox to loop over a bunch of URLs with loads of Javascript. The page does not render immediately so need test if a particular page element is visible (similar to suggestion in Mechanize::Firefox documentation except 2 xpaths in the test) before deciding next action.
The page eventually renders a xpath to 'no info' or some wanted stuff after about 2-3 seconds. If no info we go to next URL. I think there is some sort of race condition with both xpaths not existing at once causing the MozRepl::RemoteObject: TypeError: can't access dead object error intermittently (at the sleep 1 in the loop oddly enough).
My solution that seems to work/improve reliability is to enclose all the $mech->getand$mech->is_visible in an eval{}; like this:
eval{
$mech->get("$url");
$retries = 15; #test to see if element visible = page complete
while ($retries-- and ! $mech->is_visible( xpath => $xpath_btn ) and ! $mech->is_visible( xpath => $xpath_no_info )){
sleep 1;
};
last if($mech->is_visible( xpath => $xpath_no_info) ); #skip rest if no info page
};
Others might suggest improvements on this.

Zend framework 1.11 Gdata Spreadsheets insertRow very slow

I'm using insertRow to populate an empty spreadsheet, it starts off taking about 1 second to insert a row and then slows down to around 5 seconds after 150 rows or so.
Has anyone experienced this kind of behaviour?
There aren't any calculations on the data in the spreadsheet that could be getting longer with more data.
Thanks!
I'll try to be strict.
If you take a look at class "Zend_Gdata_Spreadsheets" you figure that the method insertRow() is written in a very not optimal way. See:
public function insertRow($rowData, $key, $wkshtId = 'default')
{
$newEntry = new Zend_Gdata_Spreadsheets_ListEntry();
$newCustomArr = array();
foreach ($rowData as $k => $v) {
$newCustom = new Zend_Gdata_Spreadsheets_Extension_Custom();
$newCustom->setText($v)->setColumnName($k);
$newEntry->addCustom($newCustom);
}
$query = new Zend_Gdata_Spreadsheets_ListQuery();
$query->setSpreadsheetKey($key);
$query->setWorksheetId($wkshtId);
$feed = $this->getListFeed($query);
$editLink = $feed->getLink('http://schemas.google.com/g/2005#post');
return $this->insertEntry($newEntry->saveXML(), $editLink->href, 'Zend_Gdata_Spreadsheets_ListEntry');
}
In short, it loads your whole spreadsheet just in order to learn this value $editLink->href in order to post new row into your spreadsheet.
The cure is to avoid using this method insertRow.
Instead, get your $editLink->href once in your code and then insert new rows each time by reproducing the rest of behaviour of this method. I.e, in your code instead of $service->insertRow() use following:
//get your $editLink once:
$query = new Zend_Gdata_Spreadsheets_ListQuery();
$query->setSpreadsheetKey($key);
$query->setWorksheetId($wkshtId);
$query->setMaxResults(1);
$feed = $service->getListFeed($query);
$editLink = $feed->getLink('http://schemas.google.com/g/2005#post');
....
//instead of $service->insertRow:
$newEntry = new Zend_Gdata_Spreadsheets_ListEntry();
$newCustomArr = array();
foreach ($rowData as $k => $v) {
$newCustom = new Zend_Gdata_Spreadsheets_Extension_Custom();
$newCustom->setText($v)->setColumnName($k);
$newEntry->addCustom($newCustom);
}
$service->insertEntry($newEntry->saveXML(), $editLink->href, 'Zend_Gdata_Spreadsheets_ListEntry');
Don't forget to encourage this great answer, it costed me few days to figure out. I think ZF is great however sometimes you dont want to rely on their coode too much when it comes to resources optimization.