Shopware 6 - Create product programmatically - import

I have a command script to import products from csv file.
The code i use to create the product is:
$this->productRepository->create([[
'id' => Uuid::randomHex(),
'name' => 'exampls',
'taxId' => 'b6e10c80b24946a48bb74e742d280c75',
'stock' => 999,
'createdAt' => '2022-01-01T10:17:05+02:00',
'price' => [
[
'currencyId' => 'b7d2554b0ce847cd82f3ac9bd1c0dfca',
'gross' => 99,
'net' => 99,
'linked' => true,
]
],
'productNumber' => $suffix,
'visibilities' => [
[
'salesChannelId' => '5ce47a708e484e4d8c20221f8cdfa08f',
'visibility' => ProductVisibilityDefinition::VISIBILITY_ALL,
],
],
]], Context::createDefaultContext());
I get the following error:
An exception occurred while executing 'INSERT INTO `product` (`id`, `version_id`, `parent_version_id`, `product_manufacturer_versio
n_id`, `tax_id`, `product_media_version_id`, `cms_page_version_id`, `price`, `product_number`, `stock`, `restock_time`, `active`, `
is_closeout`, `purchase_steps`, `min_purchase`, `shipping_free`, `created_at`) VALUES ('���zgL��vc�.�p','���jK¾K��u,4%','���
jK¾K��u,4%','���jK¾K��u,4%','��
��IF���Nt-(
u','���jK¾K��u,4%','���jK¾K��u,4%','{\"cb7d2554b0ce847cd82f3ac9bd1c0dfca\":{\
"currencyId\":\"b7d2554b0ce847cd82f3ac9bd1c0dfca\",\"gross\":99.0,\"net\":99.0,\"linked\":true}}','62e2977934944','999',NULL,'1','0
','1','1','0','2022-01-01 08:17:05.000');':
What could i do to get it working? And if there is another way to approach this, i'm open for suggestions. Just started learning Shopware :)

At first glance this looks to be correct. The error message seems to be incomplete. It should say after the query why it failed, be it a syntax error or a wrong foreign key. The latter would be my best guess at what could fail the moment, have you checked all the uuids to exist in their corresponding tables like tax, currency and sales_channel?

Related

TYPO3 - How can I sort a record by a field of a foreign_table and not by it's uid?

'passwordtype' => [
'exclude' => false,
'label' => '###label####',
'config' => [
'type' => 'select',
'renderType' => 'selectMultipleSideBySide',
'foreign_table' => 'passwordtypes',
'foreign_sortby' => 'name',
],
],
That part of the tca works like a charm. The passwordtypes are getting sorted by name when I open the record of a password in the backend.
But I want the sorting of the passwordrecords also happening by the passwordtypes. So I tried 'sortby' => 'passwordtype' under 'ctrl' but that only sorts it by the uid, not by the name of the passwordtypes.
I also tried 'sortby' => 'passwordtype.name' but that creates an error. Is it possible to sort it by the name of passwordtypes instead of the uid? It clearly has the name of the passwordtypes already in the passwordlist because when I change the 'label' under 'ctrl' to 'passwordtype' than I can see the correct names and not uids.
I'm open for every idea even if I have to change my database-structure.
Let's dive into the core...
The record lists are generated via \TYPO3\CMS\Recordlist\Controller\RecordListController::main(). Fot getting the list itself, the method calls
\TYPO3\CMS\Recordlist\RecordList\DatabaseRecordList::generateList().
generateList() does select data only from the actual table itself. No relations are resolved here. Then it becomes clearer why sorting by fields of a relation is not possible: they are not part of the selected data.
But... The labels of foreign records are shown.
Yes, that's done while rendering a concrete row of the list. At that
moment, no sorting can be applied anymore.
But... It works for sorting by UIDs.
Yes and no. You have a 1:n relation, so the UID of the foreign record
is saved as foreign_key in your (passwordrecords) table. The
'sortby' => 'passwordtype' is not applied to the table
passwordtype but to the column passwordrecords.passwordtype containing these UIDs.
Conclusion:
Out of the box, there seems not to be an option for sorting by a foreign table field.
Maybe, you can hook into the recordlist by \TYPO3\CMS\Backend\RecordList\RecordListGetTableHookInterface::getDBlistQuery() (called in \TYPO3\CMS\Recordlist\RecordList\DatabaseRecordList::getTable) and modify the query parts to meet your needs.
Simply put the order in are foreign_table_where:
'passwordtype' => [
'exclude' => false,
'label' => '###label####',
'config' => [
'type' => 'select',
'renderType' => 'selectMultipleSideBySide',
'foreign_table' => 'passwordtypes',
'foreign_table_where' => 'AND 1=1 ORDER BY name',
],
],

Get Disabled/Hidden Relation Table Records using TYPO3 Repository Query

I've a requirement in my custom extension where there are records, lets say which are projects saved in table name: tx_myextension_domain_model_projects and which are categorized using custom category table tx_myextension_domain_model_categories the relation which is mapped in model is m:n and saved in mm table tx_myextension_category_record_mm.
This is the TCA mapping for the category field:
products_category' => [
'exclude' => true,
'label' => 'Category Label',
'config' => [
'type' => 'select',
'renderType' => 'selectTree',
'foreign_table' => 'tx_myextension_domain_model_categories',
'foreign_table_where' => 'ORDER BY tx_myextension_domain_model_categories.sorting',
'MM' => 'tx_myextension_category_record_mm',
'MM_match_fields' => [
'tablenames' => 'tx_myextension_domain_model_projects',
],
'MM_opposite_field' => 'items',
'size' => 20,
'treeConfig' => [
'parentField' => 'parent',
'appearance' => [
'showHeader' => true,
'expandAll' => true,
'maxLevels' => 99,
],
],
],
],
So in one of my use cases I need to get the projects which are categorized with disabled and active categories.
For example this is the categories :
categories = [
A => [
A1 => [
A1.2
]
A2 => [
A2.2
]
],
B => [
B1 => [
B1.2
]
],
];
Lets say A1 is disabled/hidden record and I want to get the projects which are assigned to A1 and its child A1.2. Is there any possibilities to get the project records using TYPO3 Repository query.
Note: I couldn't disable the enable fields using $querySettings->setIgnoreEnableFields(true); because I don't want to disable it for the entire repository of category and also I need to disable it from the Project repository while query the project records. I hope my question is clear. Please let me know the solution for this.
Solution Currently I choosed: I used TYPO3 Connection Pool Query instead of repository query.
Why isnt $query->getQuerySettings()->setIgnoreEnableFields(true); an option for you? You can build the query exactly the way you need it like you would do with the Connection Pool.

Assert\Expression gives Variable Not Valid around position 2

I have a form. I am trying to assert that if one field is not null, then another field must also not be null. Trying to do this with Symfony annotations as I don't want the code in the controller and was told this would be a good way to do it.
I have tried using an Assert\Expression, however I keep getting various errors on the field that I am checking. It's slightly concerning that it says Variable when I need it to be referring to a field.
// The field that I want to check if it is null
'activeTestData',
null,
[
'label' => 'form.label.active_test_data',
'required' => false,
]
)
->add(
// The field that can't be null if the activeTestData field is not null
'activeTestDataUnit',
ChoiceType::class,
[
'label' => 'form.label.active_test_data_unit',
'required' => false,
'choices' => [
'form.label.active_test_please_select' => '',
'Byte(s)' => 'b',
'Kilobyte(s)' => 'k',
'Megabyte(s)' => 'm',
'Gigabyte(s)' => 'g',
],
// Where I am having the issue
'constraints' => [
new Assert\Expression([
'expression' => "!activeTestData == null",
'message' => 'Please enter a unit for active test data'
]),
],
I want a FORM error for when there is nothing in activeTestDataUnit but there is something in activeTestData. Unfortunately I get a symfony error:
Variable "activeTestData" is not valid around position 2 for expression !activeTestData == null.
Correct syntax for this situation would be the following:
"!this.getParent().get('activeTestData')->getData() == null"
You can see more examples and details on symfony documentation.
I updated my answer. In this context "this" is a Form object of a "activeTestDataUnit" field. So to check for a "activeTestData" value you have go to to the parent and then get a correct child.
As of Symfony 4.1 you can pass your custom values to the "values" argument and avoid all of this clutter, by passing $builder->getData(). See here for the more information on symfony documentation

Getting invalid parameter response when creating geo_locations targeting spec in the Facebook Marketing api

I am trying to add cities to my geo_location targeting in a facebook marketing api call.
$targeting_spec = array(
'geo_locations' => [
'countries' => ['US'],
'cities' =>
['key' => '2490299','radius' => 10, 'distance_unit' => 'mile']
],
'age_min' => 13,
);
My code above seems like it should be correct, especially after looking at the docs here. However I get the following error:
{"error":{"message":"Invalid parameter","type":"OAuthException","code":100,"error_subcode":1487079,"is_transient":false,"error_user_title":"Invalid Targeting Spec","error_user_msg":"The specified targeting spec is not valid because: Invalid data for field geo_locations. Invalid Targeting Spec: The specified targeting spec is not valid because: Normalization expecs a KeyedTraversable. TAAL[BLAME_file]\n","fbtrace_id":"HwU9EMDTah1"}}
It seems to be saying there's something invalid about my geo_locations field but I have no idea what that could be. Any ideas? Thank you.
For any lost souls who end up here I figured out what was wrong. The correct targeting is below:
$targeting_spec = array(
'geo_locations' => [
'cities' =>
array(['key' => '2490299','radius' => 10, 'distance_unit' => 'mile'])
],
'age_min' => 13,
);

Using Apache::Session::Memcached with MasonX::Request::WithApacheSession

I'm trying to use Apache::Session::Memcached in an HTML::Mason project where I'm using MasonX::Request::WithApacheSession to handle my sessions. Unfortunately Apache will not launch when I plug in the Memcached module instead of the MySQL one. My custom handler looks something like this (a few snips here and there):
my $ah = HTML::Mason::ApacheHandler->new (
comp_root => $ENV{HTDOCS},
data_dir => $data_dir,
request_class => 'MasonX::Request::WithApacheSession',
session_use_cookie => 0,
args_method => "mod_perl",
session_args_param => 'session_id',
session_class => 'Apache::Session::Memcached',
session_Servers => '127.0.0.1:20000',
session_Readonly => 0,
session_Debug => 1,
session_cookie_domain => $CONF->{global}->{site_name},
session_cookie_expires => "session",
session_allow_invalid_id => 0,
);
The problem I'm running into is that the session_* paramaters specific to Memcached are not being passed through to Apache::Session::Memcached like the docs say it should. This results in this error:
The following parameter was passed in the call to HTML::Mason::ApacheHandler->new()
but was not listed in the validation options: session_Servers
Now, I have gone through and swapped all of the 3 upper case arguments to lower case, to no avail. And the docs for Apache::Session::Memcached list them as upper case.
Thanks a ton for any help.
It looks like you need to register Apache::Session::Memcached with Apache::Session::Wrapper, following the instructions at http://search.cpan.org/perldoc/Apache::Session::Wrapper#REGISTERING_CLASSES like so (code courtesy Jack M.):
Apache::Session::Wrapper::->RegisterClass(
'name' => 'Apache::Session::Memcached',
'required' => [ [ 'Servers' ], ],
'optional' => [ 'NoRehash', 'Readonly', 'Debug', 'CompressThreshold', ],
);