I'm trying to deserialise the following XML:
<?xml version="1.0" encoding="utf-8"?>
<customers>
<customer>
<name>..</name>
<address>..</address>
<email>..</email>
<website>..</website>
</customer>
<customer>
...
</customer>
<customers>
I have made the following entity:
use JMS\Serializer\Annotation as JMS;
class customers
{
public function __construct()
{
$this->customers = new ArrayCollection();
}
/**
* #JMS\Type("ArrayCollection<MyBundle\Entity\customer>")
* #JMS\XmlList(entry="customer")
*/
public $customers;
}
This is the second entity:
use JMS\Serializer\Annotation as JMS;
class customer
{
/**
* #JMS\Type("string")
*/
public $name;
/**
* #JMS\Type("string")
*/
public $address;
/**
* #JMS\Type("string")
*/
public $email;
/**
* #JMS\Type("string")
*/
public $website;
}
Then I use the following code in the controller to serialise:
$serializer = $this->get('jms_serializer');
$customers = $serializer->deserialize($inputStr, 'MyBundle\Entity\customers', 'xml');
Only the object keeps up getting empty?
Try changing, in class Customers, the annotation to #JMS\XmlList(inline=true, entry="customer")
Related
Does anyone knows to modify product data using Shopware\Storefront\Page\Product\ProductPageLoadedEvent ?
services.xml
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="Swag\BasicExample\Service\AddDataToPage" >
<argument type="service" id="product.repository"/>
<tag name="kernel.event_subscriber" />
</service>
</services>
</container>
AddDataToPage.php
<?php declare(strict_types=1);
namespace Swag\BasicExample\Service;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
class AddDataToPage implements EventSubscriberInterface
{
/**
* #var EntityRepositoryInterface
*/
private $productRepository;
/**
* #param EntityRepositoryInterface $productRepository
*/
public function __construct(
EntityRepositoryInterface $productRepository
)
{
$this->productRepository = $productRepository;
}
/**
* #return string[]
*/
public static function getSubscribedEvents(): array
{
return [
ProductPageLoadedEvent::class => 'onProductsLoaded'
];
}
/**
* #param ProductPageLoadedEvent $event
* #return void
*/
public function onProductsLoaded(
ProductPageLoadedEvent $event
)
{
// the product is inside the page object
$productData = $event->getPage()->getProduct();
//modifying name
$this->log($productData->getName());
$productData->setName('Prefix Product Name' . $productData->getName());
$this->log($productData->getName());
//modifying ManufacturerNumber
$this->log($productData->getManufacturerNumber());
$productData->setManufacturerNumber('Prefix ManufacturerNumber' . $productData->getManufacturerNumber());
$this->log($productData->getManufacturerNumber());
$event->getPage()->setProduct($productData);
}
/**
* #param $message
* #return void
*/
private function log($message)
{
$logFileName = 'someFile.log';
file_put_contents(
$logFileName,
$message . PHP_EOL,
FILE_APPEND
);
}
}
After modifying the above mentioned changes it still shows the original data although
$event->getPage()->setProduct($productData);
I'm in doubt whether ProductPageLoadedEvent is an after dispatching event or before dispatching the event.
I try to add field to customer / Shop User registration for sylius api to the path /shop/customers.
I extends Customer Model :
<?php
declare(strict_types=1);
namespace App\Entity\Customer;
use Doctrine\ORM\Mapping as ORM;
use Sylius\Component\Core\Model\Customer as BaseCustomer;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* #ORM\Entity
* #ORM\Table(name="sylius_customer")
*/
class Customer extends BaseCustomer
{
/**
* #ORM\Column(type="string", length=14)
* #Groups({"shop:customer:create"})
*/
private $siret;
public function getSiret(): ?string
{
return $this->siret;
}
public function setSiret(string $siret): self
{
$this->siret = $siret;
return $this;
}
}
And extends Sylius\Bundle\ApiBundle\Command\RegisterShopUser :
<?php
namespace App\Controller\ShopAPI\Commands;
use Sylius\Bundle\ApiBundle\Command\RegisterShopUser;
class UserRegistrationCommand extends RegisterShopUser
{
protected string $siret;
public function __construct(
string $email,
string $plainPassword,
string $firstName,
string $lastName,
string $channelCode,
?bool $subscribedToNewsletter,
?string $phoneNumber,
string $siret
)
{
parent::__construct(
$email,
$plainPassword,
$firstName,
$lastName,
$channelCode,
$subscribedToNewsletter,
$phoneNumber
);
$this->siret = $siret;
}
public function siret(): string
{
return $this->siret;
}
public static function fromHttpRequestAndChannel(Request $request, ChannelInterface $channel): ChannelBasedRequestInterface
{
return new self($request, $channel->getCode());
}
}
I add to the services.yaml :
App\Controller\ShopAPI\Commands\UserRegistrationCommand:
arguments:
$siret: "%siret%"
But when i post with Postman a json with the new field (siret) i have an error 500 with Integrity constraint violation The 'siret' field cannot be empty (null).
I have been looking for the solution for several days but cannot find one.
If anyone can direct me please.
If you are wanting to allow the field to be null ...
You need to allow a null value in the database, update the column annotation as follows:
* #ORM\Column(type="string", length=14, nullable=true)
In UserRegistrationCommand::__construct and Customer::setSiret change the argument type declarations to nullable:
?string $siret
Update the database schema symfony console doctrine:schema:update --force
I thought it was just necessary to add Customer.xml :
enter image description here
with :
<collectionOperations>
<collectionOperation name="shop_post">
<attribute name="method">POST</attribute>
<attribute name="path">/shop/customers</attribute>
<attribute name="openapi_context">
<attribute name="summary">Registers a new customer</attribute>
</attribute>
<attribute name="denormalization_context">
<attribute name="groups">shop:customer:create</attribute>
</attribute>
<attribute name="messenger">input</attribute>
<attribute name="input">App\Command\RegisterShopUser</attribute>
<attribute name="output">false</attribute>
</collectionOperation>
</collectionOperations>
and extends Sylius\Bundle\ApiBundle\Command\RegisterShopUser :
<?php
declare(strict_types=1);
namespace App\Command;
use Sylius\Bundle\ApiBundle\Command\RegisterShopUser as BaseRegisterShopUser;
/**
* #experimental
*/
class RegisterShopUser extends BaseRegisterShopUser
{
/**
* #var int
* #psalm-immutable
*/
public $siret;
public function __construct(
int $siret
) {
$this->siret = $siret;
}
}
I certainly forgot a step...
Here are my codes. When I tried to save product newfile123456789.txt file is not updated.
Codes of events.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="controller_action_catalog_product_save_entity_after">
<observer name="Company_Module_Product_Save_After" instance="Company\Module\Observer\productSaveAfter" />
</event>
</config>
Codes of ProductSaveAfter.php
namespace Company\Module\Observer;
use Magento\Framework\Event\ObserverInterface;
class productSaveAfter implements ObserverInterface
{
/**
* #var ObjectManagerInterface
*/
protected $_objectManager;
/**
* #param \Magento\Framework\ObjectManagerInterface $objectManager
*/
public function __construct(
\Magento\Framework\ObjectManagerInterface $objectManager
) {
$this->_objectManager = $objectManager;
}
/**
* customer register event handler
*
* #param \Magento\Framework\Event\Observer $observer
* #return void
*/
public function execute(\Magento\Framework\Event\Observer $observer)
{
//$_product = $observer->getProduct(); // you will get product object
//$_sku = $_product->getSku(); // for sku
$myfile = fopen("newfile123456789.txt", "w") or die("Unable to open file!");
$txt = "John Doe\n";
fwrite($myfile, $txt);
fclose($myfile);
die('Observer Is called!');
}
}
Please define product save event as given below:-
<event name="catalog_product_save_after">
<observer name="Company_Module_Product_Save_After" instance="YCompany\Module\Observer\productSaveAfter" />
</event>
Also please make sure that your observer is working and folder in which file is created has write permission.
I am a newbie to magento 2x. However I tried to create a custom module and a webservice to check a customer email is exist or not. But as a result I am getting just a blank array. Here is what I have done so far:
1. app/code/Test/Customers/registration.php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Test_Customers',
__DIR__
);
2. app/code/Test/Customers/etc/module.xml
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"><module name="Test_Customers" setup_version="1.0.0"></module></config>
3. app/code/Test/Customers/etc/di.xml
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"><preference for="Test\Customers\Api\AccountInterface" type="Test\Customers\Model\Account"/></config>
4. app/code/Test/Customers/etc/webapi.xml
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd"><route url="/V1/customers/isEmailExist/" method="POST"><service class="Test\Customers\Api\AccountInterface" method="isEmailExist"/><resources><resource ref="anonymous"/></resources></route></routes>
5. app/code/Test/Customers/Api/AccountInterface.php
namespace Test\Customers\Api;
/**
* Account interface.
* #api
*/
interface AccountInterface
{
/**
* Check if given email is associated with a customer account in given website.
* #api
* #param string $customerEmail
* #return \Test\Customers\Api\AccountInterface
* #throws \Magento\Framework\Exception\LocalizedException
*/
public function isEmailExist($customerEmail);
}
6. app/code/Test/Customers/Model/Account.php
namespace Test\Customers\Model;
use Test\Customers\Api\AccountInterface;
use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Framework\Exception\NoSuchEntityException;
class Account implements AccountInterface
{
/**
* #var CustomerRepositoryInterface
*/
private $customerRepository;
/** #var \Magento\Framework\Controller\Result\JsonFactory */
protected $resultJsonFactory;
/**
* #param CustomerRepositoryInterface $customerRepository
* #param \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory
*/
public function __construct(
CustomerRepositoryInterface $customerRepository,
\Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory
)
{
$this->customerRepository = $customerRepository;
$this->resultJsonFactory = $resultJsonFactory;
}
/**
* {#inheritdoc}
*/
public
function isEmailExist($customerEmail)
{
/** #var \Magento\Framework\Controller\Result\JsonFactory */
$result = $this->resultJsonFactory->create();
try {
$this->customerRepository->get($customerEmail);
} catch (NoSuchEntityException $e) {
}
return $result->setData(['success' => true]);
}
}
I tried a POST request from REST client
http://127.0.0.1/PATH_TO_MAGENTO_DIRECTORY/index.php/rest/V1/customers/isEmailExist
POST Body:
{
"customerEmail": "sa#example.com"
}
and got a [] as response
I created a module in path app/code/Smartshore/Subscription
I want to create a route that displays a form and save data in it. I have the code but I don't know what is missing: Please see the below code:
Smartshore/Subscription/etc/frontend/routes.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="standard">
<route id="subscription" frontName="subscription">
<module name="Smartshore_Subscription" />
</route>
</router>
</config>
Smartshore/Subscription/Controller/Index/Index.php
<?php
namespace Smartshore\Subscription\Controller\Index;
use \Magento\Framework\App\Action\Action;
class Index extends Action
{
/** #var \Magento\Framework\View\Result\Page */
protected $resultPageFactory;
/**
* #param \Magento\Framework\App\Action\Context $context
*/
public function __construct(\Magento\Framework\App\Action\Context $context,
\Magento\Framework\View\Result\PageFactory $resultPageFactory)
{
$this->resultPageFactory = $resultPageFactory;
parent::__construct($context);
}
/**
* Subscription Index, shows a list of subscriptions
*
* #return \Magento\Framework\View\Result\PageFactory
*/
public function execute()
{
return $this->resultPageFactory->create();
}
}
Smartshore/Subscription/Controller/Index/Add.php
<?php
namespace Smartshore\Subscription\Controller;
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;
class Add extends Action
{
protected $resultPageFactory;
public function __construct(Context $context, PageFactory $pageFactory)
{
$this->resultPageFactory = $pageFactory;
parent::__construct($context);
}
public function execute()
{
$resultPage = $this->resultPageFactory->create();
return $resultPage;
}
}
Smartshore/Subscription/Controller/Index/Result.php
<?php
namespace Smartshore\Subscription\Controller;
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Framework\View\Element\Messages;
use Magento\Framework\View\Result\PageFactory;
class Result extends Action
{
/** #var PageFactory $resultPageFactory */
protected $resultPageFactory;
/**
* Result constructor.
* #param Context $context
* #param PageFactory $pageFactory
*/
public function __construct(Context $context, PageFactory $pageFactory)
{
$this->resultPageFactory = $pageFactory;
parent::__construct($context);
}
/**
* The controller action
*
* #return \Magento\Framework\View\Result\Page
*/
public function execute()
{
$number = $this->getRequest()->getParam('number');
$resultPage = $this->resultPageFactory->create();
/** #var Messages $messageBlock */
$messageBlock = $resultPage->getLayout()->createBlock(
'Magento\Framework\View\Element\Messages',
'answer'
);
if (is_numeric($number)) {
$messageBlock->addSuccess($number . ' times 2 is ' . ($number * 2));
}else{
$messageBlock->addError('You didn\'t enter a number!');
}
$resultPage->getLayout()->setChild(
'content',
$messageBlock->getNameInLayout(),
'answer_alias'
);
return $resultPage;
}
}
Smartshore/Subscription/view/frontend/layout/subscription_index_add.xml
<?xml version="1.0"?>
<page layout="2columns-left" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<head>
<title>New Subscription</title>
</head>
<body>
<referenceBlock name="navigation.sections" remove="true" />
<referenceContainer name="content">
<block class="Magento\Framework\View\Element\Template" name="subscriptionform.add" template="Smartshore_Subscription::form.phtml"/>
</referenceContainer>
</body>
</page>
Smartshore/Subscription/view/frontend/layout/subscription_index_result.xml
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column"
xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<head>
<title>Result</title>
</head>
</page>
I have other files as well. But I have shown here files respect to my form and its submission.
When I enter /subscription/index/add I get No route found.
What is the problem?
Check namespaces in Add and Result files/classes. It should be namespace Smartshore\Subscription\Controller\Index