API post request not reaching the application - vue.js

i'm new to laravel and i'm facing a painful problem.
I'm using Crinsane/LaravelShoppingcart in my ecommerce api and i'm trying to send a post request with axios in vuejs that adds a product to the cart by sending the product id and the quantity. The problem is the id and quantity are not reaching the application although i'm pretty sure i specified the correct route link in axios and i'm getting "No query results for model [App\Product]." which i assume means that the controller function that handles the request is working but the id is not being sent/transformed to the resource collection. I don't know if the problem is with the package i'm using or the code or something else.
this is axios request
addCart(item) {
axios
.post('/api/cart/add', item)
.then(response => (response.data.data))
.catch(error => console.log(error.response.data))
this is the route :
Route::post('cart/add', [
'uses' => 'ShoppingController#store',
'as' => 'cart.add'
]);
this is the cart collection
public function toArray($request)
{
return [
'id' => $this->id,
'qty' => $this->qty
];
}
this is the controller
public function store(){
$pdt = Product::findOrFail(request()->id);
$cart = Cart::add([
'id' => $pdt->id,
'name' => $pdt->name,
'qty' => request()->qty,
'price' => $pdt->price
]);
and this is the product model
class Product extends Model
{
protected $fillable = [
'name', 'description', 'image', 'category', 'quantity', 'price', 'sold','remaining','rating', 'bestSelling', 'featured'
];
}
Thank you in advance

The problem seems to be in your controller.
From the docs:
To obtain an instance of the current HTTP request via dependency injection, you should type-hint the Illuminate\Http\Request class on your controller method.
Try this:
public function store(Request, $request){
// Make sure the 'id' exists in the request
if ($request->get('id')) {
$pdt = Product::find($request->get('id'));
if ($request->get('qty')) {
$qty = $request->get('qty')
}
$cart = Cart::add([
'id' => $pdt->id,
'name' => $pdt->name,
'qty' => $qty,
'price' => $pdt->price
]);
}
Then, at the top of your controller, add:
use Illuminate\Http\Request;

So i found that it needed a json object to work and i had to put this code at the end of the store method :
return response()->json(['cart' => $cart], 201);

Related

Magento2 module fields still visible in admin after module is disabled

I am experiencing an issue while trying to disable a Magento2 module causing custom values to still be visible in the customer edit page.
I would like to know what i have to do to completely get rid of a module and its data from a Magento2 system.
Magento version: 2.3.2
PHP version: 7.2.19
A custom(own) Magento2 module was installed by:
Copying code: app/code/VENDOR/MODULE
Running: magento module:enable VENDOR_MODULE
Running magento setup:upgrade
This module creates a couple of Customer EAV attributes that correctly show in the customer edit form.
I am able to populate/save/update values successfully.
I am disabling the module as such:
Running: magento module:disable VENDOR_MODULE
Running magento setup:upgrade
Completely removing the app/code/VENDOR/MODULE directory
When i navigate back to the customer edit page i can still see the attributes, visible and populated with previously entered data.
At this point i have tried the following:
Manually removing the entry in setup_module.
Including a Uninstall class.
A combination of magento cache:clean && magento setup:di:compile.
Classes attached:
InstallData.php
namespace VENDOR\MODULE\Setup;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Customer\Model\Customer;
use Magento\Customer\Setup\CustomerSetupFactory;
class InstallData implements InstallDataInterface {
private $customerSetupFactory;
/**
* Constructor
*
* #param \Magento\Customer\Setup\CustomerSetupFactory $customerSetupFactory
*/
public function __construct(CustomerSetupFactory $customerSetupFactory) {
$this->customerSetupFactory = $customerSetupFactory;
}
/**
* {#inheritdoc}
*/
public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context) {
$this->installModule1($setup, $context);
$this->installModule2($setup, $context);
}
private function installModule1(ModuleDataSetupInterface $setup, ModuleContextInterface $context) {
$customerSetup = $this->customerSetupFactory->create(['setup' => $setup]);
$customerSetup->addAttribute(\Magento\Customer\Model\Customer::ENTITY, 'module1', [
'type' => 'varchar',
'label' => 'Module1 label',
'input' => 'text',
'source' => '',
'required' => false,
'visible' => true,
'position' => 500,
'system' => false,
'backend' => ''
]);
$attribute = $customerSetup->getEavConfig()->getAttribute('customer', 'module1')
->addData(['used_in_forms' => [
'adminhtml_customer',
'adminhtml_checkout',
'customer_account_create',
'customer_account_edit'
]
]);
$attribute->save();
}
private function installModule1(ModuleDataSetupInterface $setup, ModuleContextInterface $context) {
$customerSetup = $this->customerSetupFactory->create(['setup' => $setup]);
$customerSetup->addAttribute(\Magento\Customer\Model\Customer::ENTITY, 'module2', [
'type' => 'varchar',
'label' => 'Module2 label',
'input' => 'text',
'source' => '',
'required' => false,
'visible' => true,
'position' => 500,
'system' => false,
'backend' => ''
]);
$attribute = $customerSetup->getEavConfig()->getAttribute('customer', 'module2')
->addData(['used_in_forms' => [
'adminhtml_customer',
'adminhtml_checkout',
'customer_account_create',
'customer_account_edit'
]
]);
$attribute->save();
}
}
Uninstall.php
namespace VENDOR\MODULE\Setup;
use Magento\Framework\DB\Adapter\AdapterInterface;
use Magento\Framework\Db\Select;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Framework\Setup\UninstallInterface;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\ModuleDataSetupInterface;
class Uninstall implements UninstallInterface {
private $_eavSetupFactory;
private $_mDSetup;
public function __construct(EavSetupFactory $eavSetupFactory, ModuleDataSetupInterface $mDSetup) {
$this->_eavSetupFactory = $eavSetupFactory;
$this->_mDSetup = $mDSetup;
}
public function uninstall(SchemaSetupInterface $setup, ModuleContextInterface $context) {
$installer = $setup;
$eavSetup = $this->_eavSetupFactory->create(['setup' => $this->_mDSetup]);
$eavSetup->removeAttribute(\Magento\Catalog\Model\Customer::ENTITY, 'module1');
$eavSetup->removeAttribute(\Magento\Catalog\Model\Customer::ENTITY, 'module2');
}
}
For Customer attributes you need to delete the specific attributes entry from table "eav_attribute" you can search by "attribute_code" and delete that row, you have to delete attributes from the database because there is no functionality in admin to delete an attribute
This is the method by which the custom attribute can be removed as I also tried manually to delete that module attribute and it took more than 1 day to find this solution.
public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
$eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);
$eavSetup->removeAttribute(Customer::ENTITY, "<attribute name>");
}
You can remove multiple attribute too at same time by separating attribute name by commas.
After this just run -
bin/magento setup:upgrade && bin/magento setup:static-content:deploy -f

Laravel 5.6 - creation user not working

my application used to working well with registration user but now it dont.
here a portion of my model User
protected $fillable = [
'prenom', 'nom', 'email','photo_path','password',
];
here my validation function :
protected function validator(array $data)
{
return Validator::make($data, [
'prenom' => 'required|string|max:255',
'nom' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'photo_path' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:10000',
'password' => 'required|string|min:6|confirmed',
]);
}
here my create function :
protected function create(array $data)
{
dd($data);
$photoInput = request('photo_path');
$userPhotoPath='users';
$storagePhotoPath = Storage::disk('images')->put($userPhotoPath, $photoInput);
return User::create([
'prenom' => $data['prenom'],
'nom' => $data['nom'],
'email' => $data['email'],
'photo_path' => $storagePhotoPath,
'password' => Hash::make($data['password']),
]);
}
- POST request working ( return 302 ) but return back with input value
- Auth Route are declared in web.php
- Validation working well
but the php interpretor didnt get inside create function...
i just see in debugbar that information :
The given data was invalid./home/e7250/Laravel/ManageMyWorkLife/vendor/laravel/framework/src/Illuminate/Validation/Validator.php#306Illuminate\Validation\ValidationException
public function validate()
{
if ($this->fails()) {
throw new ValidationException($this);
}
$data = collect($this->getData())
but my validation working because i have error message near my InputTexte.
so i dont understand that error message ...
Do you have any clue ?
Well, you need to remove the dd(); function before you run something. Other wise it will end the execution of all other operations.
Check if your User Model has a constructor, if so remove it and check if the problem still accours. This fixed it for me.

Prestashop overriding default behavior

I'm not a big expert with PrestaShop but this is what I would like to achieve: Everytime a customer confirms an order for a particular product, I would like to send an http request to another server to start the production of the product.
This is what I have in mind:
Create a file in /override/controlers/front/OrderConfirmationController.php
class OrderConfirmationController extends OrderConfirmationControllerCore
{
public function initContent()
{
parent::initContent();
$url = 'http://server.com/path';
$data = array('key1' => 'value1', 'key2' => 'value2');
// use key 'http' even if you send the request to https://...
$options = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($data),
),
);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
}
}
The issue is that I need certain specifications from the products (size, color, ...) but not all types of products will be sent to that production center.
I am using version 1.6.1.1
Thanks for your help!
Quentin
take a look into init() method of controller that you override
/controllers/front/OrderConfirmationController.php
there you may see:
$order = new Order((int)($this->id_order));
in child controller you have access to Order object, so:
$products = $order->getProducts();
will to get you products list.

ZF2 / doctrine ORM authentication different Entity

in my application (ZF2 / ORM) i have 3 Entities (with Single Table inheritance)
User
Owner extends User
Agent extends User
i want to make one single Authentication (Login) for the 3 Entity using
doctrine.authenticationservice.orm_default
module.config.php
//other doctrine config
'authentication' => array(
'orm_default' => array(
'object_manager' => 'Doctrine\ORM\EntityManager',
'identity_class' => 'Application\Entity\User',
'identity_property' => 'email',
'credential_property' => 'password',
'credential_callable' => function(User $user, $passwordGiven) {
return $user->getPassword() == md5($passwordGiven);
},
),
),
and the process of login
//LoginController.php
// ..data validation
$this->authService = $this->getServiceLocator()->get('doctrine.authenticationservice.orm_default');
$AuthAdapter = $this->authService->getAdapter();
$AuthAdapter->setIdentity($this->request->getPost('email'));
$AuthAdapter->setCredential(md5($this->request->getPost('password')));
$result = $this->authService->authenticate();
if($result->isValid()){
$identity = $result->getIdentity();
//continue
}
how can i do this process without caring about object type,
when i try to login with email of an Agent, i get this error
Catchable fatal error: Argument 1 passed to Application\Module::{closure}() must be an instance of User, instance of Application\Entity\Owner given
The error you mention is due to the type hint on:
function(User $user) {
Which leads me to believe that you have a missing namespace declaration in your config file; in which case you can either add it or use the FQCN.
function(\Application\Entity\User $user) {
Nevertheless, I don't think it's actually the problem. You can only define one 'identity_class' with doctrine authentication (which the adapter will use to load the entity from the entity manager). If you have multiple entity classes there is no way to have each of these tested with one adapter.
However, the configuration is really just creating a new authentication adapter, specifically DoctrineModule\Authentication\Adapter\ObjectRepository. One solution would be to create multiple ObjectRepository adapters, each with the correct configuration for the different entities and then loop through each of them while calling authenticate() on the Zend\Authentication\AuthenticationService.
For example :
public function methodUsedToAutheticate($username, $password)
{
// Assume we have an array of configured adapters in an array
foreach($adapters as $adapter) {
$adapter->setIdentity($username);
$adapter->setCredential($password);
// Authenticate using the new adapter
$result = $authService->authenticate($adapter);
if ($result->isValid()) {
// auth success
break;
}
}
return $result; // auth failed
}
As previously mentioned is the doctrine config will not allow for more than one adapter, so you would need to create them manually and remove your current configuration.
Another example
public function getServiceConfig()
{
return [
'factories' => [
'MyServiceThatDoesTheAuthetication' => function($sm) {
$service = new MyServiceThatDoesTheAuthetication();
// Assume some kind of api to add multiple adapters
$service->addAuthAdapter($sm->get('AuthAdapterUser'));
$service->addAuthAdapter($sm->get('AuthAdapterOwner'));
$service->addAuthAdapter($sm->get('AuthAdapterAgent'));
return $service;
},
'AuthAdapterAgent' => function($sm) {
return new DoctrineModule\Authentication\Adapter\ObjectRepository(array(
'object_manager' => $sm->get('ObjectManager'),
'identity_class' => 'Application\Entity\Agent',
'identity_property' => 'email',
'credential_property' => 'password'
));
},
'AuthAdapterOwner' => function($sm) {
return new DoctrineModule\Authentication\Adapter\ObjectRepository(array(
'object_manager' => $sm->get('ObjectManager'),
'identity_class' => 'Application\Entity\Owner',
'identity_property' => 'email',
'credential_property' => 'password'
));
},
// etc...
],
];
}
Hopefully this gives you some ideas as to what is required.
Lastly, if you would consider other modules, ZfcUser already has a 'chainable adapter' which actually does the above (but uses the event manager) so It might be worth taking a look at even if you don't use it.

Get the CSRF token in test

I'm writing functional test and i need to make ajax post request. "The CSRF token is invalid. Please try to resubmit the form". How can i get the token in my functional test ?
$crawler = $this->client->request(
'POST',
$url,
array(
'element_add' => array(
'_token' => '????',
'name' => 'bla',
)
),
array(),
array('HTTP_X-Requested-With' => 'XMLHttpRequest')
);
CSRF token generator is normal symfony 2 service. You can get service and generate token yourself. For example:
$csrfToken = $client->getContainer()->get('form.csrf_provider')->generateCsrfToken('registration');
$crawler = $client->request('POST', '/ajax/register', array(
'fos_user_registration_form' => array(
'_token' => $csrfToken,
'username' => 'samplelogin',
'email' => 'sample#fake.pl',
'plainPassword' => array(
'first' => 'somepass',
'second' => 'somepass',
),
'name' => 'sampleuser',
'type' => 'DSWP',
),
));
The generateCsrfToken gets one important parameter intention which should be the same in the test and in the form otherwise it fails.
After a long search (i've found nothing in doc and on the net about how to retrieve csrf token) i found a way:
$extract = $this->crawler->filter('input[name="element_add[_token]"]')
->extract(array('value'));
$csrf_token = $extract[0];
Extract the token from response before make the request.
In symfony 3, in your WebTestCase, you need to get the CSRF token:
$csrfToken = $client->getContainer()->get('security.csrf.token_manager')->getToken($csrfTokenId);
To get the $csrfTokenId, the best way would be to force it in the options of your FormType ():
class TaskType extends AbstractType
{
// ...
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'csrf_token_id' => 'task_item',
));
}
// ...
}
So in this case: $csrfTokenId = "task_item";. Or you you can try to use the default value, that would be the name of your form.
Then use it as a post parameter:
$client->request(
'POST',
'/url',
[
'formName' => [
'field' => 'value',
'field2' => 'value2',
'_token' => $csrfToken
]
]
);
Just in case someone stumble on this, in symfony 5 you get the token this way:
$client->getContainer()->get('security.csrf.token_manager')->getToken('token-id')->getValue();
where 'token-id' is the id that you used in the configureOptions method in your form type, which would look something like this:
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
"data_class" => Foo::class,
"csrf_protection" => true,
"csrf_field_name" => "field_name", //form field name where token will be placed. If left empty, this will default to _token
"csrf_token_id" => "token-id", //This is the token id you must use to get the token value in your test
]);
}
Then you just put the token in the request as a normal field.