vienthuong / shopware-php-sdk Goto Github PK
View Code? Open in Web Editor NEWA PHP SDK for Shopware 6 Admin API
License: MIT License
A PHP SDK for Shopware 6 Admin API
License: MIT License
I tried to import my products which uses custom entities but without success. Then I tried to get a created product with my custom association also without success. So my question is does this sdk support custom extensions at all? I didn't find any documentation about that topic. Thanks
Simple example: Loading categories from Shopware API, children array is empty, even with child categories in Shopware.
Example categories in Shopware are: "Home" and 12 child categories: "Bäume", "Sträucher", "Bodendecker" etc.
If I load the categories with paging like this:
$grantType = new ClientCredentialsGrantType($clientId, $clientSecret);
$adminClient = new AdminAuthenticator($grantType, $shopUrl);
$accessToken=$adminClient->fetchAccessToken();
$context=new Context($shopUrl, $accessToken);
$repository = RepositoryFactory::create(CategoryDefinition::ENTITY_NAME);
$criteria = new Criteria();
$criteria->setLimit(100);
$criteria->setPage(1);
$criteria->setTotalCountMode(Criteria::TOTAL_COUNT_MODE_NEXT_PAGES);
$criteria->addAssociation("children");
$criteria->getAssociation("children")->setLimit(null);
$result=$repository->search($criteria, $context);
echo("Count: ".$result->count(). PHP_EOL. PHP_EOL);
$categoryCollection = $result->getEntities();
foreach ($categoryCollection as $category) {
echo("Category-ID:" . $category->id . ", Name: ".$category->name . PHP_EOL);
if($category->children) {
foreach ($category->children as $child) {
echo("Child-Category-ID:" . $child->id . ", Name: ".$child->name . PHP_EOL);
}
} else {
echo("no childs".PHP_EOL);
}
echo(PHP_EOL);
}
The result looks like
Count: 13
Category-ID:018e84ee474e73fdbe3c7e74717acecc, Name: Home
Category-ID:018f86ee17a97a83aa229b36903cf952, Name: Bäume
no childs
Category-ID:018f86ee7ac772a7b4b93b1cd19c1bbf, Name: Sträucher
no childs
Category-ID:018f86ee80ff7ed989aa2aa7dfc0ddb3, Name: Bodendecker
no childs
Category-ID:018f86ee9a337ae4abad16e97e2eb3d9, Name: Heckenpflanzen
no childs
Category-ID:018f86eeb0db750a8b5118b195a3fc93, Name: Wasserpflanzen
no childs
Category-ID:018f86eeca2271d0b4e337ed212b2a27, Name: Kräuter
no childs
Category-ID:018f86eedaf171c9bf5cd6a047adac4e, Name: Stauden
no childs
Category-ID:018f86eeeb5279f081c59b67b67a4947, Name: Blumenzwiebeln
no childs
Category-ID:018f86ef08f072868c97c4ccd085f8db, Name: Kletterpflanzen
no childs
Category-ID:018f86ef1f1d7e7383ad7ceec97fab2a, Name: Obstgehölze
no childs
Category-ID:018f86ef4bfa7610902d5b9876908222, Name: Ziergehölze
no childs
Category-ID:018f86ef5a2e7c0ab515c67dcc3cc1a5, Name: Zimmerpflanzen
no childs
The first children array should contain the child categories of "Home", but it is empty.
But if I change setLimit to (10) I got this:
Count: 10
Category-ID:018e84ee474e73fdbe3c7e74717acecc, Name: Home
Child-Category-ID:018f86ef1f1d7e7383ad7ceec97fab2a, Name: Obstgehölze
Child-Category-ID:018f86ef4bfa7610902d5b9876908222, Name: Ziergehölze
Child-Category-ID:018f86ef5a2e7c0ab515c67dcc3cc1a5, Name: Zimmerpflanzen
Category-ID:018f86ee17a97a83aa229b36903cf952, Name: Bäume
no childs
Category-ID:018f86ee7ac772a7b4b93b1cd19c1bbf, Name: Sträucher
no childs
Category-ID:018f86ee80ff7ed989aa2aa7dfc0ddb3, Name: Bodendecker
no childs
Category-ID:018f86ee9a337ae4abad16e97e2eb3d9, Name: Heckenpflanzen
no childs
Category-ID:018f86eeb0db750a8b5118b195a3fc93, Name: Wasserpflanzen
no childs
Category-ID:018f86eeca2271d0b4e337ed212b2a27, Name: Kräuter
no childs
Category-ID:018f86eedaf171c9bf5cd6a047adac4e, Name: Stauden
no childs
Category-ID:018f86eeeb5279f081c59b67b67a4947, Name: Blumenzwiebeln
no childs
Category-ID:018f86ef08f072868c97c4ccd085f8db, Name: Kletterpflanzen
no childs
And if I only load the first category with setLimit(1), all children are included.
Possible reason?
In the response from Shopware, the "included" key only includes category objects, which are not already in the "data" key. And the hydrateToMany function only hydrate the "included" json objects.
This is maybe very special, because the included entities are from the same type (both Category). But this can also occur in other requests with linked entities from same type, like in products.
Or did I missed something?
Thanks and best regards
Kai
When I try to get Customers I get the following error:
Vin\ShopwareSdk\Data\Struct::addExtension(): Argument #2 ($extension) must be of type Vin\ShopwareSdk\Data\Struct, null given, called
When I use other entities such as ProductDefinition, the code works fine.
Here is the code I used:
`
$customerRepository = RepositoryFactory::create(CustomerDefinition::ENTITY_NAME);
$grantType = new ClientCredentialsGrantType(Configure::read('Shopware.ACCESS_KEY_ID'), Configure::read('Shopware.ACCESS_KEY_SECRET'));
$adminClient = new AdminAuthenticator($grantType, Configure::read('Shopware.BASE_URL'));
$accessToken = $adminClient->fetchAccessToken();
$context = new Context(Configure::read('Shopware.BASE_URL'), $accessToken);
$criteria = new Criteria();
$customers = $customerRepository->search($criteria, $context)->getEntities();
`
Error code 9, Status 401.
Does the client not make sure that the access token stays valid? It seems like I'm getting a timeout right in the middle of a long running process (after about 623s).
If not, what would be the best practice to keep the token valid and hence the connection alive? Keeping track of the time that has passed seems silly to me.
I'm using the PasswordGrantType.
`
$repository = RepositoryFactory::create(StateMachineStateDefinition::ENTITY_NAME);
$criteria = new Criteria();
$criteria->addAssociations(['orderTransactions', 'orderDeliveries']);
$criteria->addFilter(new EqualsFilter('id', $orderId));
`
shouldnt that return the order state with the transaction and delivery status?
I am getting error like this
[production.ERROR: {"errors":[{"code":"0","status":"405","title":"Method Not Allowed","detail":"No route found for \u0022GET https:\/\/shopware6.mystore.me\/api\/oauth\/token\u0022: Method Not Allowed (Allow: POST)"}]} {"exception":"[object] (Vin\\ShopwareSdk\\Exception\\AuthorizationFailedException(code: 405)](url)
[previous exception] [object] (GuzzleHttp\\Exception\\ClientException(code: 405): Client error: `POST http://shopware6.mystore.me/api/oauth/token` resulted in a `405 Method Not Allowed` response:
{\"errors\":[{\"code\":\"0\",\"status\":\"405\",\"title\":\"Method Not Allowed\",\"detail\":\"No route found for \\u0022GET https:\\/\\/shop (truncated...)
at /var/www/tf/shared/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:113)
Shopware store version: v6.4.6.1
It was working earlier. I don't know this error from shopware after getting upgraded 1.3.2 to 1.3.3 when composer updated.
How to solve this issue? Thanks
Hello together! I already use this library frequently to download orders and upload item information from SW6. Unfortunately, I do not manage to create deliveries in SW6.
I have tinkered for me the simplest case:
$orderRepository = RepositoryFactory::create(OrderDeliveryDefinition::ENTITY_NAME);
$data["orderId"] = $orderId;
$data["stateId"] = "e2d3aa03f8684f53a9f02e5643580a23";
$orderRepository->create($data, $this->authenticateSDK($order->getShop()));
This does not work. Am I on the right track? Ideally, does anyone have a working code example? Thanks a lot! Tobias
Right now hydrated entities are cached in
\Vin\ShopwareSdk\Repository\Traits\EntityHydrator::hydrateEntity
$cacheKey = $entityRaw['type'] . '-' . $entityRaw['id'];
if (array_key_exists($cacheKey, $this->cache)) {
return $this->cache[$cacheKey];
}
This should imo get removed without replacement.
I'd not expect the SDK to do caching for me. In case I want caching I could easily implement it on my own.
There are some downsides of caching:
If you search for an entity without associations and later on search for the same entity with association, the "new" hydrated entity is actually the old one without the associations added -> this is what took me quite some time to figure out.
If you use some web server that doesn't end the PHP progress after the request has been finished this value will be cached forever. Even if the next request comes in after minutes/days/weeks the old value of that entity is still cached. I know common webservers like Apache or Nginx with PHP-FPM start a new process with each request - but new approaches are coming and get more and more popular (Swoole, Roadrunner).
Like I said I don't think caching is necessary (the request to actually get the entity data from Shopware is probably much slower than hydrating the entity) so I'd remove it. In case you think caching should still be present it would be nice to be able to enable/disable it (via Context flag?) or at least to clear it (via method call).
===
Another proposal related:
For now I'd like to replace the method hydrateEntity with my own. If hydrateEntity would be public, EntityHydrator would be a class that get's initialized by some factory and injected to the EntityRepository this would be quite easy.
But as hydrateEntity is a private trait method inside a Trait which is hardly coupled to EntityRepository this is a bit tricky to do.
In general I'd suggest - at least for a library - to avoid Traits and rely on DI instead.
===
PR: #47
Hi,
I wanted to create promotion through API and this is my code
$promotionRepository = RepositoryFactory::create(PromotionDefinition::ENTITY_NAME);
$promotionRepository = $promotionRepository->create([
'name' => 'TEST123',
'active' => true,
'exclusive' => false,
'useCodes' => false,
'useIndividualCodes' => false,
'useSetGroups' => false,
'salesChannels' => [
'salesChannelId' => 'fd22b2830eded4e381b457d44781551'
],
'discounts' => [
'scope' => 'cart',
'value' => 5,
'type' => 'absolute'
],
], $context);
and I am getting error like this
{"errors":[{"code":"0","status":"500","title":"Internal Server Error","detail":"Argument 2 passed to Shopware\\Core\\Framework\\Api\\Converter\\ApiVersionConverter::convertPayload() must be of the type array, string given, called in \/var\/www\/shopware6\/vendor\/shopware\/core\/Framework\/Api\/Converter\/ApiVersionConverter.php on line 66"}]}
I have to pass any extra parameter?
I am using Shopware v6.4.6.1
How to solve this issue? Thanks
If a search call is done with a custom definition, there will be a schema call for each entity of the results.
The reason for this is, that the InfoService is instantiated for each entity.
shopware-php-sdk/src/Repository/Traits/EntityHydrator.php
Lines 18 to 22 in 1962684
The InfoService has a internal cache, but that cache is non static.
Either the InfoService needs to be a singleton or cached somewhere (RepositoryFactory?) or the cache inside InfoService needs to be static.
Content of $response
:
Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 20480 bytes) in <b>/var/www/html/test/shopware6/vendor/shopware/core/Framework/Struct/JsonSerializableTrait.php</b> on line <b>15</b>
Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 65536 bytes) in <b>Unknown</b> on line <b>0</b>
Happened while executing \Vin\ShopwareSdk\Repository\EntityRepository::search()
. Doesn't throw an exception, so difficult to spot. It tried to assign more than 256MB.
Which is strange because I had set ini_set('memory_limit', '1G')
earlier. So I guess it's happening on the server side?
$response = $this->decodeResponse($response)
just returns an empty response which then causes a misleading exception to be thrown in $aggregations = new AggregationResultCollection($response['aggregations'])
.
Currently Shopware is using GET URLs with the parameters location-id
and privileges
these parameters are missing in the validation funtion, therefore the calculates hashes are wrong. Following a proposed fix in the file WebhookAuthenticator
public static function authenticateGetRequest(string $shopSecret): bool
{
$queryString = $_SERVER['QUERY_STRING'];
$queries = [];
parse_str($queryString, $queries);
$shop = new Shop($queries['shop-id'], $queries['shop-url'], $shopSecret);
$queryString = sprintf(
'shop-id=%s&shop-url=%s×tamp=%s&sw-version=%s',
$shop->getShopId(),
$shop->getShopUrl(),
$queries['timestamp'],
$queries['sw-version'],
);
if (array_key_exists('sw-context-language', $queries) && array_key_exists('sw-context-language', $queries)) {
$queryString = sprintf(
'shop-id=%s&shop-url=%s×tamp=%s&sw-version=%s&sw-context-language=%s&sw-user-language=%s',
$shop->getShopId(),
$shop->getShopUrl(),
$queries['timestamp'],
$queries['sw-version'],
$queries['sw-context-language'],
$queries['sw-user-language'],
);
}
if (array_key_exists('location-id', $queries) && array_key_exists('privileges', $queries)) {
$queryString = sprintf(
'location-id=%s&privileges=%s',
$queries['location-id'],
urlencode($queries['privileges'])
) . '&' . $queryString;
}
$hmac = \hash_hmac('sha256', htmlspecialchars_decode($queryString), $shopSecret);
return hash_equals($hmac, $queries['shopware-shop-signature']);
}
Hi,
in the class \Vin\ShopwareSdk\Data\Entity\Integration\IntegrationEntity
the class Vin\ShopwareSdk\Data\Entity\Notification\NotificationCollection
is referenced, but this class does not exist.
The complete directory in src/Data/Entity
for the entity Notification
is missing.
Any idea, what the reason could be?
Best Regards
Martin
{
"extensions": [],
"success": false,
"data": [
{
"extensions": [],
"result": [
{
"entities": [],
"errors": [
{
"code": "0",
"status": "500",
"title": "Internal Server Error",
"detail": "Transaction commit failed because the transaction has been marked for rollback only."
}
]
}
]
}
],
"deleted": [],
"notFound": []
}
I'm not sure where exactly that error's coming from, but I know that I'm stuck because I have no idea how to rectify that. Any ideas? I was POST'ing a product upsert to /api/_action/sync
and that's what came up after fixing some complaints about missing fields and whatnot. I'm using shopware-sdk "^1.7.3" and SW 6.4.20.
Hi,
I am trying to delete relations between products and categories via syncDeleted(). I didn't find any working way to do it other than to change some code in your class and make a pull request today :)
You can find more information on this topic in the pull request itself.
Have a nice day!
Dag
I'm using laravel 8 and want to use this packpage. However, Laravel 8 only require php version from ^7.3
So is there any version that supports from 7.3 or ^7.1 as well
Thx
The main goal of this task is to adhere to the following PSRs:
PSR-18 - HTTP Client
PSR-17 - HTTP Factories
PSR-7 - HTTP Message Interface
Even though you can use other PSR-18 Client as an alternative to GuzzleClient by calling $client->setClient() but the current implementation of this package is required Guzzle as dependencies which are not so great, we need to somehow decouple it and the consumer needs to provide their concrete client following PSR-18
I am implementing an exception handling regarding missing privileges.
During this, I noticed that EntityRepository::search
does throw a ShopwareSearchResponseException
, in case Guzzle returns a BadResponseException
.
I would expect the same from EntityRepository::searchIds
, as the exception could also occur there.
In my example the missing privilege was a manufacturer filter for the product.
Cheers!
Good Morning,
since an new Update of Shopware i get following error:
{"errors":[{"code":"0","status":"500","title":"Internal Server Error","detail":"Malformed UTF-8 characters, possibly incorrectly encoded"}]}
Maybe someone an idea?
Shopware added the ability to add criteria to a delete sync operation in shopware/shopware#3150
class SyncPayload should be changed to support setting criteria for a delete filter
This can be useful to delete mappings
new SyncOperation(
// operation name
'delete-mapping',
// entity type
'product_category',
// sync operation type
SyncOperation::ACTION_DELETE,
// payload
[],
// criteria
[
[
['type' => 'equals', 'field' => 'productId', 'value' => $ids->get('p1')]
['type' => 'nand', 'queries' => [
['type' => 'equalsAny', 'field' => 'categoryId', 'value' => [$ids->get('c1'), $ids->get('c2'), $ids->get('c3')]
]]
],
]),
I can't get the http client to accept a self-signed certificate.
What do I need to modify?
PHP v7.4
Shopware v6.4
When I try to get a token using the below methods
$grantType = new ClientCredentialsGrantType($clientId, $clientSecret);
$adminClient = new AdminAuthenticator($grantType, $shopUrl);
$accessToken = $adminClient->fetchAccessToken();
I'm getting the issue Call to a member function getSource() on null.
I have also tried with a username and password as well. Still, the same issue will generate. Can you please let me know if anyone faced this issue or any solution for it?
Help is very appreciated.
Cheers, Nilesh
The response of this endpoint is the document pdf. The function handleResponse in ApiService class corrupts this response by applying json_decode function.
I created a new DocumentService which handles this very case for my project.
Hi and thanks for that pretty SDK!
I've got a little question regarding the clients config. If I follow your example using a repository for searching the API there is no way to configure the client, is it?
I have to configure "verify" => false
in the client just like in the following example:
$this->client = new GuzzleClient(['defaults' => [
'verify' => false
]]);
... but as far as I can see there is no way to do that when working with repositories.
Could you let me know how to handle that? Thanks in advance 👍
Hi,
you cannot use the _action/document/$documentId/$deepLinkCode
route to receive an order document as pdf file.
The reason is that the pdf content is parsed via json_decode()
here:
Hi,
currently it is not possible to use the AdminActionService for uploading media as binary. Only url based upload is supported.
Expected available API:
(new AdminActionService($context))->execute('POST', "media/$mediaId/upload", $imageAsBinary);
But only this works:
(new AdminActionService($context))->execute('POST', "media/$mediaId/upload", ['url' => 'https://something/image.jpg']);
Best Regards
See line 15 in:
https://github.com/vienthuong/shopware-php-sdk/blob/master/src/Service/AdminActionService.php
Method validation should contain "patch" as an option.
The OrderReturnLineItemEntity
is part of the Shopware Commercial package. It's a great feature that allows return management for order line items and it would be awesome if it was added to the SDK as well
What is the common way to iterate through many entities, for example a thousand products or more?
Now i do it in this way, but it feels not good, what is your solution?
private function getProducts(): \Generator
{
$criteria = new Criteria();
$productRepository = RepositoryFactory::create(ProductDefinition::ENTITY_NAME);
do {
$result = $productRepository->search($criteria, $this->getContext());
/** @var ProductEntity $product */
foreach ($result->getEntities() as $product) {
yield $product;
}
$criteria->setPage($criteria->getPage() + 1);
} while (($result->count()) === $criteria->getLimit());
}
if i remove the limit with $criteria->setLimit(null);
i got the Allowed memory size
error
Sehr geehrte Damen und Herren,
nach dem ich probiert habe mit der shopware-php-sdk eine Landingpage zu erstellen habe ich folgende Fehlermeldung bekommen:
Next Vin\ShopwareSdk\Exception\ShopwareResponseException: {"errors":[{"code":"c1051bb4-d103-4f74-8988-acbcafc7fdc3","status":"400","detail":"Dieser Wert sollte nicht leer sein.","template":"This value should not be blank.","meta":{"parameters":{"{{ value }}":"null"}},"source":{"pointer":"\/0\/salesChannels"}}]}
Welcher Wert sollte nicht leer sein?
Oder geht es um den Parameter value? oder den Parameter salesChannels?
Es wäre schön wenn der fehlende Parameter angegeben wird.
mit freundlichem gruß
Chanel
Is it possible to upsert a media file with a product upsert? Either as a separate payload in the same request or directly via the product upsert?
We have about 10k articles with images I want to sync. Optimal strategy would be to only update the image if the article is created (normally they don't change) and of course do everything in one go (like 100 products at a time).
What I have until now:
$syncService = new SyncService($this->context);
$payload = new SyncPayload();
$payload->set(ProductDefinition::ENTITY_NAME . '-upsert', new SyncOperator(ProductDefinition::ENTITY_NAME, SyncOperator::UPSERT_OPERATOR, [
[
'id' => '018cf59aa9d870008000fbc39f0fcef2',
'name' => 'New Product',
'taxId' => '018de63f1b61715aad18389bfaddf6ba',
'price' => [
[
'currencyId' => 'b7d2554b0ce847cd82f3ac9bd1c0dfca',
'linked' => true,
'gross' => 999.99,
'net' => (999.99 / 1.19),
],
],
'productNumber' => 'FRE832672',
'stock' => 2,
],
]));
echo("============================================");
echo("Sync response");
$response = $syncService->sync($payload);
var_dump($response);
adding a property like
'cover' => [
'url' => 'https://image.shutterstock.com/image-photo/stock-photo-woman-with-static-electric-hair-isolated-on-black-background-250nw-2014152446.jpg',
],
doesn't work...
Calling the AdminActionService's action
method with $method
= 'POST' causes throwing \InvalidArgumentException
(new AdminActionService(...))->execute('POST', ...);
The allow list check should be made case insensitive.
Instead of:
if (!in_array($method, ['get', 'post', 'put', 'patch', 'delete'])) {
This:
if (!in_array(strtolower($method), ['get', 'post', 'put', 'patch', 'delete'])) {
Currently, it is not possible to set criteria limit to null
.
But this should be possible to allow lists without pagination:
https://github.com/shopware/platform/blob/7ed33d9f1ba28888eec93b3ff4f9ba141790a32e/src/Core/Framework/DataAbstractionLayer/Dbal/EntityReader.php#L369
Notice that you're no longer able to determinate this clause if null
is an allowed value:
shopware-php-sdk/src/Data/Criteria.php
Line 310 in 91d0686
Bonus: Currently, it is not possible to pass a custom Criteria
instance to any association
(It's possible to set dedicated limit rates to each association):
shopware-php-sdk/src/Data/Criteria.php
Line 150 in 91d0686
Maybe we should change addAssociation(string $path)
to addAssociation(string $path ?Criteria $criteria = null)
(which creates a new one if not passed to keep BC)?
Based on this documentation:
https://shopware.stoplight.io/docs/admin-api/ZG9jOjEyMzA4NTUx-bulk-payloads#deleting-relations
it is currently not possible to clear out relations because of the predefined id
key mapping here:
shopware-php-sdk/src/Repository/EntityRepository.php
Lines 157 to 159 in 78874d2
I basically had to do this:
$repository->syncDeleted([
[
'productId' => $product->id,
'optionId' => $option->id
]
], $context);
We've released the SDK for a while and as Shopware core is growing really fast as well, the SDK might get a bit out of date APIs, or lack features, using deprecated APIs, etc...
So with this thread, I want to gather the ideas/solutions from the community or even improve PR to make the SDK better. Any comments/suggestions are welcomed and highly appreciated 🤝
For bug issues, please create a new one so I can keep the track of them :)
When using the repositories, I can't have explicit typehints, as the general one is returned for empty results. Would be great, if the correct collection class would be returned for the corresponding repository.
Code:
$criteria1 = new Criteria();
$criteria1->setIds(['ca9f2ea7166c4ff58f42c2e100ca3fd5']);
$criteria2 = new Criteria();
$criteria2->setIds(['0134e8fa91da44c7b5418806d7b95c21']);
/** @var CategoryCollection $categories */
$categories1 = $this->categoryRepository
->search($criteria1, $this->context)
->getEntities();
$categories2 = $this->categoryRepository
->search($criteria2, $this->context)
->getEntities();
README.md:
You can use 1.x to connect to a sw 6.5 but for up-to-date schema and new 6.5 features, you should use 2.x version instead.
There is no version 2, no branch 2, no tag 2.
Most current tag is 1.7.3
Hi!
I have a little question of how to connect properties, categories or tags to a product. I don't get it.
Connecting a manufacturer seems to be easy by using "ProductManufacturer", but there is none for properties, categories neither tags.
How do I set properties, categories and tags for my product?
$manu = 'Nike';
$manu_repo = RepositoryFactory::create(ProductManufacturerDefinition::ENTITY_NAME);
$manu_crit = new Criteria();
$manu_crit->addFilter(new EqualsFilter('name', $manu));
$result = $manu_repo->search($manu_crit,$context)->getEntities()->first();
if (isset($result->id)) {
$manu_id = $result->id;
} else { // new
$manu_id = Uuid::randomHex();
$manu_repo->create([
'id' => $manu_id,
'name' => $manu,
'link' => '/search?search='.str_replace(' ','+',$manu),
],$context);
}
$prop_repo = RepositoryFactory::create(PropertyGroupOptionDefinition::ENTITY_NAME);
$prop_crit = new Criteria();
$prop_crit->addFilter(new EqualsFilter('name', 'yellow'));
$prop_crit->addFilter(new EqualsFilter('groupId', '3eb38e0a80569be587821bdcec94ebe7'));
$prop_result = $prop_repo->search($prop_crit,$context)->getEntities()->first();
$prop_repo2 = RepositoryFactory::create(PropertyGroupOptionDefinition::ENTITY_NAME);
$prop_crit2 = new Criteria();
$prop_crit2->addFilter(new EqualsFilter('name', 'blue'));
$prop_crit2->addFilter(new EqualsFilter('groupId', '3eb38e0a80569be587821bdcec94ebe7'));
$prop_result2 = $prop_repo2->search($prop_crit2,$context)->getEntities()->first();
$new_product = Uuid::randomHex();
$productRepository = RepositoryFactory::create(ProductDefinition::ENTITY_NAME);
$productRepository->create([
'id' => $new_product,
'name' => 'new product '.date('H:i:s'),
'taxId' => "057cef9b692540caa0a54ee0ebd34eeb",
'price' => [[
'currencyId' => 'b7d2554b0ce847cd82f3ac9bd1c0dfca',
'net' => 555.55,
'gross' => 555.55,
'linked' => true,
]],
'productNumber' => "Z".date('His'),
'active' => true,
'stock' => 1,
'weight' => 1.8,
'width' => 105,
'height' => 180,
// 'properties' => [$prop_result,$prop_result2], // this doesn’t work
// 'properties' => [$prop_result->id,$prop_result2->id], // this doesn’t work, either
'length' => 25,
'keywords' => 'test1,test2,test3', // SEO!!!
'metaTitle' => 'some Meta-title',
'metaDescription' => 'some Meta-description',
'customSearchKeywords' => [
'AAA',
'BBB'
],
'manufacturerId' => $manu_id,
], $context);
any help?
Regards
Jens
Your composer dependency says only ^7.4
, could you please add || ^8.0
In Vin\ShopwareSdk\Service\AdminActionService
the $data
parameter has type array
:
class AdminActionService extends ApiService
{
public function execute(string $method, string $path, array $data = [], array $headers = []): ApiResponse
{
// ...
}
// ...
}
But this is wrong considering the fact that some endpoints consume octet-streams.
This would need to be changed to array|string or just left as mixed by default, depending on the target PHP version.
When try to read one entry in the system configuration, like that:
$systemConfigRepository = RepositoryFactory::create(SystemConfigDefinition::ENTITY_NAME);
$criteria = new Criteria();
$criteria->setLimit(1);
$criteria->addFilter(new EqualsFilter('configurationKey', 'MyFavApiTest.config.receiver'));
$result = $systemConfigRepository->search($criteria, $context);
I get an error:
Cannot assign string to property Vin\ShopwareSdk\Data\Entity\SystemConfig\SystemConfigEntity::$configurationValue of type ?array
I changed configurationValue in SystemConfigEntity to data-type of string, and it is working.
Is this really an error, or am I doing something wrong?
Setup:
Shop: Shopware 6.4.8.1 on PHP 8
App: Symfony 6 on PHP 8
The one that produces the error, is the app.
Thanks for all the good work, so far.
It's a pleasure to work with that library.
Hi, first of all, thanks for this package.
Here is my problem. I get all orders from Shopware. I created an invoice in the backend (pdf file) and i think it should be in the documents of OrderEntity, but it shows null.
Since, PHP 8.2 a lot of deprecation warning are thrown because the entity properties doesn't always match the transmitted data from Shopware.
Because this package should be compatible with PHP versions below 8.2, the AllowDynamicProperties
attribute (https://www.php.net/manual/en/class.allowdynamicproperties.php) cannot be used.
Updating the entities with the current versioning strategy makes also no sense, because it would only reflect the entity properties of one Shopware version. So all other versions that should be compatible would throw warnings or errors.
I would suggest to move away from simple versioning like 1.7.3 or 2.0.0 to a versioning like 6.5.6-2.0.0, 6.5.7-2.0.0. The versions could be exactly the same but don't have to be. The idea is that one would fix the own project to a specific Shopware version but allows updates of this package that are not tied to a Shopware version.
To manage the Shopware versions, a "master"/"main" branch per Shopware version would be required. Any changes that are not tied to a specific Shopware version, could be merged into every one of these branches. The branches would have a slightly different base (e.g. some more or less entity properties).
To make the creation of the Shopware version specific branches/changes easier, they could be "copied" from the Shopware Core repository. I don't know how this could be done efficiently, yet ... but I am sure that could be figured out.
best regards,
spigandromeda
After I upload a new media (image) for a product with the method uploadMediaFromUrl with a newly generated media ID, filename, extension and URL this media is connected to a payment service. I did not start to sync a payload with ProductMedia, that step would come next, but (after a few tests) does not have anything to do with this problem.
So I just upload an image through the API and it gets connected to a payment service in Shopware 6.
It's a random payment service though, every time another one...
Code:
$context = new Context($config['shop_url'], $this->accessToken);
$mediaService = new MediaService();
$mediaService->setContext($context);
$mediaRepo = RepositoryFactory::create(MediaDefinition::ENTITY_NAME);
$mediaId = $mediaRepo->searchIds(new Criteria(), $context)->firstId();
$mediaService->uploadMediaFromUrl($mediaId, $url, $ext, $filename);
// This works afterwards , but doesn't have anything to do with the problem, after updating ProductMedia the media is also (ans correctly) connected to the product
//$this->upsertProductMedia($productId, $mediaId, $mediaFolderId, $coverId, $alt, $title, $position);
Finally, thank you for this SDK, I don't just want to criticise something ;)
Hey on my Shopware 6 Side I have extensions made to the ProductEntity, they are transfered through the API. Unfortunately since the extensions are not reflected in the src/Data/Entity/Product/ProductEntity.php
and so they will be dropped in the src/Hydrate/EntityHydrator.php on Line 181
because they are no properties.
What is the correct way to have extensions in the ProductEntity?
I am encountering deprecation log entries when using the latest version (v2.0.0) of the vienthuong/shopware-php-sdk with Shopware version 6.5.8.2. The issue arises specifically when making the following call:
$criteria = new Criteria(); $criteria->addFilter(new EqualsFilter('productNumber', $sku)); $criteria->addAssociations(['media']);
The deprecation log entries include messages like:
Deprecated: Creation of dynamic property Vin\ShopwareSdk\Data\Entity\MediaThumbnail\MediaThumbnailEntity::$path is deprecated in /var/task/vendor/vin-sw/shopware-sdk/src/Data/Entity/Entity.php on line 40
Here are more examples of the debug message:
It appears that Shopware has released additional attributes to their API, which are not properly mapped in the Vin\ShopwareSdk\Data\Entity\Media\MediaEntity
. The missing attribute is not the problem here. The problem is in my opinion that it is logged as an deprecated attribute. Could we instead please ignore this attribute?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.