Tinytext issue on Upgrade magento to 2.3.0 - magento2

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.

Related

How can I override the store function in backpack-for-laravel v5?

I've updated my app from backpack-for-laravel v4.1 to v5, but now I'm having issues with overriding the store function. I followed the upgrade guide and step 15: https://backpackforlaravel.com/docs/5.x/upgrade-guide#step-15
but unfortunately, my preferred option A is not working for me. this is how my function looked in v4.1:
public function store()
{
// do something before validation, before save, before everything
$this->crud->setOperationSetting('saveAllInputsExcept', ['save_action']); //somehow required...
$end = strtotime('+1 hour', strtotime($this->crud->getRequest()->request->get('start'))); //set end automatically after 1h
$this->crud->getRequest()->request->add(['end'=> $end]);
$response = $this->traitStore();
// do something after save
return $response;
}
I've converted it now to match the v5 requirements as below:
public function store()
{
$this->crud->set('strippedRequest', function($request) {
$end = '2023-02-01 14:00:00';
$request->add([ 'end' => $end ]);
return $request->except(['_save_action', '_token', '_http_referrer']);
});
return $this->traitStore();
}
I even tried it with a static value, but I keep getting the error from SQL that the field 'end' doesn't have a default value...meaning no value for end has been added to the request.
Appreciate any kind of support. Thanks
Thanks for the question. Indeed there is an issue in the upgrade guide example.
I've just submitted a PR to docs to fix it: https://github.com/Laravel-Backpack/docs/pull/404
Should be merged soon!
You can see the actual working solution in the PR diff.
Cheers

TYPO3 ConnectionPool find a file after the uid of the file reference and update data

The concept is that, after a successfull save of my object, it should update a text in the database (With a Hook). Lets call the field 'succText'. The table i would like to access is the sys_file but i only get the sys_file_reference id when i save the object. So i thought i could use the ConnectionPool to select the sys_file row of this file reference and then insert the data on the field 'succText'.
I tried this:
public function processDatamap_preProcessFieldArray(array &$fieldArray, $table, $id, \TYPO3\CMS\Core\DataHandling\DataHandler &$pObj) {
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_file_reference');
$findItemsId = $queryBuilder
->select('*')
->from('sys_file_reference')
->join(
'sys_file_reference',
'sys_file',
'reference',
$queryBuilder->expr()->eq('reference.uid', $queryBuilder->quoteIdentifier('uid_local'))
)
->where(
$queryBuilder->expr()->eq('uid_local', $queryBuilder->createNamedParameter($fieldArray['downloads'], \PDO::PARAM_INT))
)
->execute();
}
But this give me back the sys_file_reference id and not the id and the field values of the sys_file table.
As for the update, i havent tried it yet, cause i haven't figured out yet, how to get the row that needs to be updated. I gues with a subquery after the row is found, i don't really know.
The processDatamap_preProcessFieldArray is going to be renamed to post. I only have it this way in order to get the results on the backend.
Thanks in advance,
You might want to make use of the FileRepository class here.
$fileRepository = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Resource\FileRepository::class);
$fileObjects = $fileRepository->findByRelation('tablename', 'fieldname', $uid);
Where $uid is the ID of the record that the files are connected to via file reference.
You will get back an array of file objects to deal with.
I resolved my problem by removing the first code and adding a filerepository instance.
$fileRepository = GeneralUtility::makeInstance(FileRepository::class);
$fileObjects = $fileRepository->findByRelation('targetTable', 'targetField', $uid);
VERY IMPORTANT!
If you are creating a new element then TYPO3 assigns a temp UID variable with a name that looks like this NEW45643476. In order to get the $uid from the processDatamap_afterDatabaseOperations you need to add this code before you get the instance of the fileRepository.
if (GeneralUtility::isFirstPartOfStr($uid, 'NEW')) {
$uid = $pObj->substNEWwithIDs[$uid];
}
Now as far as the text concerns, i extracted from a pdf. First i had to get the basename of the file in order to find its storage location and its name. Since i have only one file i don't really need a foreach loop and i can use the [0] as well. So the code looked like this:
$fileID = $fileObjects[0]->getOriginalFile()->getProperties()['uid'];
$fullPath[] = [PathUtility::basename($fileObjects[0]->getOriginalFile()->getStorage()->getConfiguration()['basePath']), PathUtility::basename($fileObjects[0]->getOriginalFile()->getIdentifier())];
This, gives me back an array looking like this:
array(1 item)
0 => array(2 items)
0 => 'fileadmin' (9 chars)
1 => 'MyPdf.pdf' (9 chars)
Now i need to save the text from every page in a variable. So the code looks like this:
$getPdfText = '';
foreach ($fullPath as $file) {
$parser = new Parser();
$pdf = $parser->parseFile(PATH_site . $file[0] . '/' . $file[1]);
$pages = $pdf->getPages();
foreach ($pages as $page) {
$getPdfText .= $page->getText();
}
}
Now that i have my text i want to add it on the database so i will be able to use it on my search action. I now use the connection pool to get the file from the sys_file.
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_file');
$queryBuilder
->update('sys_file')
->where(
$queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($fileID))
)
->set('pdf_text', $getPdfText)
->execute();
Now everytime i choose a PDF from my extension, i save its text on the database.
EXTRA CONTENT
If you want to include the PDFParser as well and you are on composer mode, then add this on your composer.json:
"smalot/pdfparser" : "*"
and on the autoload:
"Smalot\\PdfParser\\" : "Packages/smalot/pdfparser/src/"
Then under: yourExtension/Classes/Hooks/DataHandler.php add the namespace:
use Smalot\PdfParser\Parser;
Now you are able to use the getPages() and getText() functions.
The Documentation
If i missed something let me know and i will add it.

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.

Joomla 3.3: Get data from column 'attribs' in the table 'content'

I'm using the Aixeena Easy CCK-plugin in my Joomla 3.3-website. It's a plugin that allows me to add custom fields in my Article Edit-page. The content I fill out there (should) show up on my website. The plugin stores his information in the #_content table in the attribs column.
On their website, Aixeena says that I have to use the following code to make the filled out text visible on my website:
$attrb = json_decode($this->item->attribs);
echo $attrb->fieldname;
This code drops the following error:
Notice: Undefined property: JDocumentHTML::$item in /Applications/MAMP/htdocs/buutpot/templates/buutpot.nl-standaardtemplate/index.php on line 123
Notice: Trying to get property of non-object in /Applications/MAMP/htdocs/buutpot/templates/buutpot.nl-standaardtemplate/index.php on line 123
Fatal error: Call to a member function get() on a non-object in /Applications/MAMP/htdocs/buutpot/templates/buutpot.nl-standaardtemplate/index.php on line 124
I think it is written for an older version of Joomla. Then I searched around and found this code:
$params = $this->item->params;
echo $params->get('fieldname');
When I use this code on my site, it gives me the following error's:
Notice: Undefined property: JDocumentHTML::$item in /Applications/MAMP/htdocs/buutpot/templates/buutpot.nl-standaardtemplate/index.php on line 123
Notice: Trying to get property of non-object in /Applications/MAMP/htdocs/buutpot/templates/buutpot.nl-standaardtemplate/index.php on line 123
Notice: Trying to get property of non-object in /Applications/MAMP/htdocs/buutpot/templates/buutpot.nl-standaardtemplate/index.php on line 124
That's without a fatal error. I'm not sure why it is without.
Could anybody help me out getting the right code to get my variable out of the table? Thanks in advance!
EDIT 1: Link to the plugin: http://www.aixeena.org/aixeena-lab/aixeena-easy-cck
EDIT 2: Edited my question in reply on the comment of Elin.
So like the notices say, the problem is that $this->item does not exist. You need to figure out what the actual name of the object is and use that rather than $this->item. You will probably do that by looking in the layout of whereever it is that you are trying to display. Can you please check your template to see if it has a layout override for the article view (assuming that is the view you are trying to access the form from)?
I used this code to do a query on the database:
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select('attribs');
$query->from($db->quoteName('#__content'));
$query->where($db->quoteName('id')." = ".JRequest::getInt('id'));
$db->setQuery($query);
$attribs = $db->loadResult();
$attribs = json_decode($attribs, 'true');
$firstattr = $attribs['firstattr'];
$secondattr = $attribs['secondattr'];
$thirdattr = $attribs['thirdattr'];
$fourthattr = $attribs['fourthattr'];
But I'm sure this can be done simpler.
$attribs = new JRegistry($article->attribs);
echo $fieldname = $attribs['fieldname'];
For example, I use this code in on ContentPrepare like this
function onContentPrepare($context, &$article, &$params, $page) {
$attribs = new JRegistry($article->attribs);
//url is my custom field for the content
$url = $attribs['url'];
......

Magento error when trying to duplication product

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.