Observer updated / updating not fired - laravel

I created an observer to make some actions whenever a transaction is created / updated / deleted.
It works fine for the created / deleting method, but for some reason the updating and updated methods aren't being fired.
This is my observer:
<?php
namespace App\Observers\Finance;
use App\Finance\Account;
use App\Finance\Transaction;
use Illuminate\Contracts\Queue\ShouldQueue;
class TransactionObserver implements ShouldQueue
{
/**
* The name of the queue the job should be sent to.
*
* #var string|null
*/
public $queue = 'transactions';
/**
* Updates account balance
*
* #param Account $Account
* #param int $amount
* #param int $old_amount
*/
public function updateAccountBalance(Account $Account, $amount = 0, $old_amount = 0)
{
$newBalance = $Account->balance - ($old_amount * 100) + ($amount * 100);
$Account->update(['balance' => $newBalance]);
}
/**
* Listen to the Transaction created event.
*
* #param Transaction $Transaction
* #return void
*/
public function created(Transaction $Transaction)
{
$this->updateAccountBalance($Transaction->account, $Transaction->amount);
}
/**
* Listen to the Transaction updating event.
*
* #param Transaction $Transaction
* #return void
*/
public function updating(Transaction $Transaction)
{
$this->updateAccountBalance($Transaction->account, 0, $Transaction->amount);
}
/**
* Listen to the Transaction updated event.
*
* #param Transaction $Transaction
* #return void
*/
public function updated(Transaction $Transaction)
{
$this->updateAccountBalance($Transaction->account, $Transaction->amount);
}
/**
* Listen to the Transaction deleted event.
*
* #param Transaction $Transaction
* #return void
*/
public function deleting(Transaction $Transaction)
{
$this->updateAccountBalance($Transaction->account, 0, $Transaction->amount);
}
}
and the update method in the controller:
public function update(Request $request, Transaction $transaction)
{
if (in_array($transaction->id, Transaction::$nonEditable)) {
abort(404);
}
$this->validate($request, [
'title' => 'required|max:255',
'account_id' => 'required|exists:accounts,id',
'season_year' => 'required|integer|exists:seasons,year',
'finance_category_id' => 'required|integer|exists:finance_categories,id',
'amount' => 'numeric',
'date' => 'required|date_format:d/m/Y',
]);
$transaction->update($request->all());;
flash()->success('האובייקט עודכן בהצלחה');
return redirect()->route('transactions.index');
}
What am I doing wrong?
Plus, does ShouldQueue work with observers?

Related

Am I overcomplicating events/listeners/notifications?

I'm not sure if I'm overcomplicating events/listeners/notifications in Laravel, but it feels like maybe I am, and I'm getting some unexpected results, although technically it's working.
My basic structure is this:
MonthlySummaryCompletedEventis fired.
The HandleMonthlySummaryCompletedEvent listener listens for the event.
It triggers a SendMonthlySummaryCreatedNotification notification.
This is all working (locally at least), except for 2 things:
I've had to put in a 5 second sleep in my livewire component that receives the notification because of timing issues. It almost seems like the pusher notification arrives before the notification has been written to the database.
It appears that 2 messages are sent to pusher:
Here's the code for my event:
class MonthlySummaryCompletedEvent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public User $requestedBy;
public string $fileDownloadUrl;
public string $fileName;
/**
* Create a new event instance.
*
* #return void
*/
public function __construct($event, string $fileDownloadUrl, string $fileName)
{
$this->requestedBy = $event->requestedBy;
$this->fileDownloadUrl = $fileDownloadUrl;
$this->fileName = $fileName;
}
/**
* Get the channels the event should broadcast on.
*
* #return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new PrivateChannel('users.' . $this->requestedBy->id);
}
}
here's the code for my listener:
class HandleMonthlySummaryCompletedEvent implements ShouldQueue
{
/**
* Create the event listener.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* #param object $event
* #return void
*/
public function handle($event)
{
Notification::send($event->requestedBy, new SendMonthlySummaryCreatedNotification($event));
}
}
and here's the code for the notification:
class SendMonthlySummaryCreatedNotification extends Notification implements ShouldQueue, ShouldBroadcast
{
use Queueable;
public $fileDownloadUrl;
public $fileName;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct($event)
{
$this->fileDownloadUrl = $event->fileDownloadUrl;
$this->fileName = $event->fileName;
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return ['database', 'broadcast'];
}
/**
* Get the broadcastable representation of the notification.
*
* #param mixed $notifiable
* #return BroadcastMessage
*/
public function toBroadcast($notifiable)
{
Log::debug($notifiable->toArray());
return new BroadcastMessage([
'title' => 'Monthly Summary Complete',
'message' => "{$this->fileName} is ready. ",
'link' => $this->fileDownloadUrl,
'link_text' => 'Click here to download',
'show_toast' => true,
'user_id' => $notifiable->id
]);
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toDatabase($notifiable)
{
return [
'title' => 'Monthly Summary Complete',
'message' => "{$this->fileName} is ready. ",
'link' => $this->fileDownloadUrl,
'link_text' => 'Click here to download',
'show_toast' => true,
'user_id' => $notifiable->id
];
}
}
And here's my front end livewire component:
public function getListeners()
{
return [
"echo-private:users.{$this->user->id},StatementCompleted" => 'notifyUser',
"echo-private:users.{$this->user->id},MonthlySummaryCompletedEvent" => 'notifyUser',
];
}
public function mount()
{
$this->user = Auth::user();
$this->refreshNotifications();
$this->showNotificationsBadge = ($this->notificationCount > 0) ? true : false;
}
public function render()
{
return view('livewire.components.notifications');
}
public function notifyUser()
{
$this->showNotificationsBadge = true;
sleep(5);
$this->refreshNotifications();
$message = $this->notifications->first()->data['message'];
if (isset($this->notifications->first()->data['show_toast']) && $this->notifications->first()->data['show_toast'] == true) {
$this->dispatchBrowserEvent('triggerToast', [Helper::notification('Success', $message)]);
}
}

Laravel job failed

I use Laravel 8 with supervisor.
I have an error on a few jobs in my application.
All jobs run in about 3 seconds.
I have a 60 second timeout and a 90 second retry_after.
There are only a few jobs that fail per day out of about 3000 jobs. I have the jobs of a client which fails all the time I don't know why.
On some jobs I get the following error:
has been attempted too many times or run too long. The job may have previously timed out. {"exception":"[object] (Illuminate\Queue\MaxAttemptsExceededException(code: 0)
I think I have an error because of the middleware, when I remove it it works.
job.php
class UpdateTimeslots implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $tries = 3;
protected $officeId;
protected $startDate;
protected $endDate;
/**
* Create a new job instance.
*
* #return void
*/
public function __construct(int $officeId, string $startDate = null, string $endDate = null)
{
$this->onQueue('availabilities');
$this->officeId = $officeId;
$this->startDate = $startDate;
$this->endDate = $endDate;
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
app(TimeslotMergedService::class)->update([$this->officeId], $this->startDate, $this->endDate);
}
/**
* Get the middleware the job should pass through.
*
* #return array
*/
public function middleware()
{
return [(new WithoutOverlapping($this->officeId))];
}
/**
* Handle a job failure.
*
* #param \Throwable $exception
* #return void
*/
public function failed(\Throwable $exception)
{
Log::error([
'office_id' => $this->officeId,
'start_date' => $this->startDate,
'end_date' => $this->endDate,
'error' => $exception->getMessage()
]);
}
}
queue.php
'database' => [
'driver' => 'database',
'table' => 'jobs',
'queue' => ['tasks', 'queue'],
'retry_after' => 90,
'after_commit' => false,
],
laravel-worker.conf
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/app/artisan queue:work --queue=tasks,default --tries=3 --max-time=3600
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=welrdv
numprocs=4
redirect_stderr=true
stdout_logfile=/var/www/app/storage/logs/worker.log
stopwaitsecs=3600
Can you help me please ?
UPDATE
here is the middleware code:
<?php
namespace Illuminate\Queue\Middleware;
use Illuminate\Container\Container;
use Illuminate\Contracts\Cache\Repository as Cache;
use Illuminate\Support\InteractsWithTime;
class WithoutOverlapping
{
use InteractsWithTime;
/**
* The job's unique key used for preventing overlaps.
*
* #var string
*/
public $key;
/**
* The number of seconds before a job should be available again if no lock was acquired.
*
* #var \DateTimeInterface|int|null
*/
public $releaseAfter;
/**
* The number of seconds before the lock should expire.
*
* #var int
*/
public $expiresAfter;
/**
* The prefix of the lock key.
*
* #var string
*/
public $prefix = 'laravel-queue-overlap:';
/**
* Create a new middleware instance.
*
* #param string $key
* #param \DateTimeInterface|int|null $releaseAfter
* #param \DateTimeInterface|int $expiresAfter
* #return void
*/
public function __construct($key = '', $releaseAfter = 0, $expiresAfter = 0)
{
$this->key = $key;
$this->releaseAfter = $releaseAfter;
$this->expiresAfter = $this->secondsUntil($expiresAfter);
}
/**
* Process the job.
*
* #param mixed $job
* #param callable $next
* #return mixed
*/
public function handle($job, $next)
{
$lock = Container::getInstance()->make(Cache::class)->lock(
$this->getLockKey($job), $this->expiresAfter
);
if ($lock->get()) {
try {
$next($job);
} finally {
$lock->release();
}
} elseif (! is_null($this->releaseAfter)) {
$job->release($this->releaseAfter);
}
}
/**
* Set the delay (in seconds) to release the job back to the queue.
*
* #param \DateTimeInterface|int $releaseAfter
* #return $this
*/
public function releaseAfter($releaseAfter)
{
$this->releaseAfter = $releaseAfter;
return $this;
}
/**
* Do not release the job back to the queue if no lock can be acquired.
*
* #return $this
*/
public function dontRelease()
{
$this->releaseAfter = null;
return $this;
}
/**
* Set the maximum number of seconds that can elapse before the lock is released.
*
* #param \DateTimeInterface|int $expiresAfter
* #return $this
*/
public function expireAfter($expiresAfter)
{
$this->expiresAfter = $this->secondsUntil($expiresAfter);
return $this;
}
/**
* Set the prefix of the lock key.
*
* #param string $prefix
* #return $this
*/
public function withPrefix(string $prefix)
{
$this->prefix = $prefix;
return $this;
}
/**
* Get the lock key for the given job.
*
* #param mixed $job
* #return string
*/
public function getLockKey($job)
{
return $this->prefix.get_class($job).':'.$this->key;
}
}

Why is my laravel policy authorization not working after a while

I'm following the laracasts 5.7 series and I was working on the authorization part using policies. It was working fine when I first added it. But the next day when I opened the app again (without TOUCHING any of the code) I kept being thrown to a 403 error. This happened the two times already. At first I just thought I messed up the code. So I redid the whole policy authorization again. But the second time, I made sure everything was working fine before I saved my code. And then the same thing happened.
Here's my code so far:
ProjectPolicy.php:
public function touch(User $user, Project $project)
{
return $project->owner_id == $user->id;
}
AuthServiceProvider.php:
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* #var array
*/
protected $policies = [
// 'App\Model' => 'App\Policies\ModelPolicy',
'App/Project' => 'App\Policies\ProjectPolicy',
];
/**
* Register any authentication / authorization services.
*
* #return void
*/
public function boot()
{
$this->registerPolicies();
//
}
}
web.php:
Route::resource('projects', 'ProjectsController')->middleware('can:touch,project');
ProjectsController.php:
use App\Project;
use Illuminate\Http\Request;
class ProjectsController extends Controller
{
public function __construct() {
$this->middleware('auth');
}
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
$projects = Project::where('owner_id', auth()->id())->get();
return view('projects.index', ['projects' => $projects]);
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
return view('projects.create');
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$validated = request()->validate([
'title' => 'required',
'description' => ['required','min:5']
]);
$validated['owner_id'] = auth()->id();
Project::create($validated);
return redirect('/projects');
}
/**
* Display the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function show(Project $project)
{
// $this->authorize('update', $project);
// abort_if($project->owner_id !== auth()->id(), 403);
// $this->authorize('touch', $project); // from ProjectPolicy
// abort_if( \Gate::denies('touch', $project), 403);
return view('projects.show', ['project' => $project]);
}
/**
* Show the form for editing the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function edit(Project $project)
{
return view('projects.edit', ['project' => $project]);
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param int $id
* #return \Illuminate\Http\Response
*/
public function update(Project $project)
{
$project->update(request(['title','description']));
return redirect()->action(
'ProjectsController#show', ['id' => $project->id]
);
}
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function destroy(Project $project)
{
$project->delete();
return redirect('/projects');
}
}
To be clear: It was working the night before, and the next day when I opened the app it kept throwing me to a 403 error even when I didn't edit the code at all. I don't know what's happening at all.

CollectionType with multiple entity type + Ajax

I have a problem creating a form by including a formType that are 2 related entities and that must be combined with a CollectionType.
I use the library jquery.collection for CollectionType ( http://symfony-collection.fuz.org/symfony3/ )
My entities
Product
namespace BBW\ProductBundle\Entity\Product;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model as ORMBehaviors;
/**
* Product
*
* #ORM\Table(name="product_product")
* #ORM\Entity(repositoryClass="BBW\ProductBundle\Repository\Product\ProductRepository")
*/
class Product
{
use ORMBehaviors\Translatable\Translatable;
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var array
* #ORM\ManyToMany(targetEntity="BBW\ProductBundle\Entity\Attribute\AttributeGroup", inversedBy="products", fetch="EAGER")
* #ORM\JoinTable(name="product_join_attribute_group")
*/
private $attributeGroups;
/**
* #var array
* #ORM\ManyToMany(targetEntity="BBW\ProductBundle\Entity\Attribute\Attribute", inversedBy="products", fetch="EAGER")
* #ORM\JoinTable(name="product_join_attribute")
*/
private $attributes;
/**
* Constructor
*/
public function __construct()
{
$this->attributeGroups = new \Doctrine\Common\Collections\ArrayCollection();
$this->attributes = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Add attributeGroup
*
* #param \BBW\ProductBundle\Entity\Attribute\AttributeGroup $attributeGroup
*
* #return Product
*/
public function addAttributeGroup(\BBW\ProductBundle\Entity\Attribute\AttributeGroup $attributeGroup)
{
$this->attributeGroups[] = $attributeGroup;
return $this;
}
/**
* Remove attributeGroup
*
* #param \BBW\ProductBundle\Entity\Attribute\AttributeGroup $attributeGroup
*/
public function removeAttributeGroup(\BBW\ProductBundle\Entity\Attribute\AttributeGroup $attributeGroup)
{
$this->attributeGroups->removeElement($attributeGroup);
}
/**
* Get attributeGroups
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getAttributeGroups()
{
return $this->attributeGroups;
}
/**
* Add attribute
*
* #param \BBW\ProductBundle\Entity\Attribute\Attribute $attribute
*
* #return Product
*/
public function addAttribute(\BBW\ProductBundle\Entity\Attribute\Attribute $attribute)
{
$this->attributes[] = $attribute;
return $this;
}
/**
* Remove attribute
*
* #param \BBW\ProductBundle\Entity\Attribute\Attribute $attribute
*/
public function removeAttribute(\BBW\ProductBundle\Entity\Attribute\Attribute $attribute)
{
$this->attributes->removeElement($attribute);
}
/**
* Get attributes
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getAttributes()
{
return $this->attributes;
}
}
AttributeGroup
namespace BBW\ProductBundle\Entity\Attribute;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model as ORMBehaviors;
/**
* AttributeGroup
*
* #ORM\Table(name="product_attribute_group")
* #ORM\Entity(repositoryClass="BBW\ProductBundle\Repository\Attribute\AttributeGroupRepository")
*/
class AttributeGroup
{
use ORMBehaviors\Translatable\Translatable;
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var int
*
* #ORM\OneToMany(targetEntity="BBW\ProductBundle\Entity\Attribute\Attribute", mappedBy="attributeGroup", cascade={"persist", "remove"}, fetch="EAGER")
* #ORM\JoinColumn(name="attribute_id")
*/
private $attributes ;
/**
* #var array
* #ORM\ManyToMany(targetEntity="BBW\ProductBundle\Entity\Product\Product", mappedBy="attributeGroups", cascade={"persist"}, fetch="EAGER")
*/
private $products;
/**
* Constructor
*/
public function __construct()
{
$this->attributes = new \Doctrine\Common\Collections\ArrayCollection();
$this->products = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Add attribute
*
* #param \BBW\ProductBundle\Entity\Attribute\Attribute $attribute
*
* #return AttributeGroup
*/
public function addAttribute(\BBW\ProductBundle\Entity\Attribute\Attribute $attribute)
{
$this->attributes[] = $attribute;
return $this;
}
/**
* Remove attribute
*
* #param \BBW\ProductBundle\Entity\Attribute\Attribute $attribute
*/
public function removeAttribute(\BBW\ProductBundle\Entity\Attribute\Attribute $attribute)
{
$this->attributes->removeElement($attribute);
}
/**
* Get attributes
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getAttributes()
{
return $this->attributes;
}
/**
* Add product
*
* #param \BBW\ProductBundle\Entity\Product\Product $product
*
* #return AttributeGroup
*/
public function addProduct(\BBW\ProductBundle\Entity\Product\Product $product)
{
$this->products[] = $product;
return $this;
}
/**
* Remove product
*
* #param \BBW\ProductBundle\Entity\Product\Product $product
*/
public function removeProduct(\BBW\ProductBundle\Entity\Product\Product $product)
{
$this->products->removeElement($product);
}
/**
* Get products
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getProducts()
{
return $this->products;
}
}
Attributes
namespace BBW\ProductBundle\Entity\Attribute;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model as ORMBehaviors;
/**
* Attribute
*
* #ORM\Table(name="product_attribute")
* #ORM\Entity(repositoryClass="BBW\ProductBundle\Repository\Attribute\AttributeRepository")
*/
class Attribute
{
use ORMBehaviors\Translatable\Translatable;
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var int
*
* #ORM\ManyToOne(targetEntity="BBW\ProductBundle\Entity\Attribute\AttributeGroup", inversedBy="attributes", cascade={"persist"}, fetch="EAGER")
* #ORM\JoinColumn(name="attribute_group_id")
*/
private $attributeGroup ;
/**
* #var array
* #ORM\ManyToMany(targetEntity="BBW\ProductBundle\Entity\Product\Product", mappedBy="attributes", cascade={"persist"}, fetch="EAGER")
*/
private $products;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set attributeGroup
*
* #param \BBW\ProductBundle\Entity\Attribute\AttributeGroup $attributeGroup
*
* #return Attribute
*/
public function setAttributeGroup(\BBW\ProductBundle\Entity\Attribute\AttributeGroup $attributeGroup = null)
{
$this->attributeGroup = $attributeGroup;
return $this;
}
/**
* Get attributeGroup
*
* #return \BBW\ProductBundle\Entity\Attribute\AttributeGroup
*/
public function getAttributeGroup()
{
return $this->attributeGroup;
}
/**
* Constructor
*/
public function __construct()
{
$this->products = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add product
*
* #param \BBW\ProductBundle\Entity\Product\Product $product
*
* #return Attribute
*/
public function addProduct(\BBW\ProductBundle\Entity\Product\Product $product)
{
$this->products[] = $product;
return $this;
}
/**
* Remove product
*
* #param \BBW\ProductBundle\Entity\Product\Product $product
*/
public function removeProduct(\BBW\ProductBundle\Entity\Product\Product $product)
{
$this->products->removeElement($product);
}
/**
* Get products
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getProducts()
{
return $this->products;
}
}
Explanation
My product must belong to an attribute group and must contain attributes. I have a relationship between my AttributeGroup entity and a Relationship with Attribute.
My Entity AttributeGroup has a relationship with Attribute (functional).
Form Types
In my form I have a CollectionType with another formType as entry_type I have created with two entity types (AttributeGroups / Attributes)
FormType for product
namespace BBW\ProductBundle\Form\Product;
use A2lix\TranslationFormBundle\Form\Type\TranslationsType;
use BBW\CoreBundle\FormTypes\SwitchType;
use BBW\MediaBundle\Transformers\MediaTransformer;
use BBW\ProductBundle\Form\Attribute\Type\AttributeType;
use Doctrine\ORM\Mapping\Entity;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\MoneyType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class ProductEditType extends AbstractType
{
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$locale = $options['int_service'];
$builder
->add('attributes', CollectionType::class, array(
'entry_type' => AttributeType::class,
'entry_options' => array(
'label' => false
),
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
'required' => false,
'attr' => array(
'class' => 'attributes-selector'
),
))
;
}
/**
* {#inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'BBW\ProductBundle\Entity\Product\Product',
'int_service' => ['fr'],
'translation_domain' => 'ProductBundle'
));
}
/**
* {#inheritdoc}
*/
public function getBlockPrefix()
{
return 'bbw_productbundle_edit_product';
}
}
AttributeType
/**
* Form Type: Fields add in product edit form
*/
namespace BBW\ProductBundle\Form\Attribute\Type;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class AttributeType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('attributeGroups', EntityType::class, array(
'label' => false,
'class' => 'BBW\ProductBundle\Entity\Attribute\AttributeGroup',
'choice_label' => 'translate.name',
'attr' => array(
'class' => 'choiceAttributeGroup'
),
))
->add('attributes', EntityType::class, array(
'label' => false,
'class' => 'BBW\ProductBundle\Entity\Attribute\Attribute',
'choice_label' => 'translate.name',
'attr' => array(
'class' => 'choiceAttributes'
)
))
;
}
/**
* {#inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'BBW\ProductBundle\Entity\Product\Product',
'int_service' => ['fr'],
'translation_domain' => 'ProductBundle'
));
}
}
Explanation
The two entities (AttributeGroups / Attributes) are two linked drop-down lists. When I select a group, I must display the data of this group in the second drop-down list. This part works well. I can duplicate as much as I want (with the CollectionType).
First problem when i submit the form:
"Could not determine access type for property "attributeGroups" ".
Second problem when i set "mapped => false" in my two entities:
"Expected value of type "Doctrine\Common\Collections\Collection|array" for association field "BBW\ProductBundle\Entity\Product\Product#$attributes", got "BBW\ProductBundle\Entity\Product\Product" instead."
Screeshoots dump/form
Conclusion
I think my problem is a mapping problem, having tested a lot of code and explanation on the symfony doc or other site, I could not solve my problem. If anyone could help me out and explain the good work of a collectionType with 2 entity and if that is possible. If you have examples of codes I am taker too.
Thank you in advance for your help.

ErrorException in SessionGuard.php | Getting error when trying to register user while creating new order

I want user to register and also buy a package. To do that I took input for registration details and package details. Now when I'm processing order to save package details in session and register, I get this error : Argument 1 passed to Illuminate\Auth\SessionGuard::login() must be an instance of Illuminate\Contracts\Auth\Authenticatable, instance of Illuminate\View\View given, called in C:\xampp\htdocs\rename\app\Traits\OrderRegister.php on line 63 and defined. I'm using an trait to register user and return back to function when registration is complete.
OrderController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Package;
use App\ListingType;
use Illuminate\Support\Facades\Auth;
use App\Order;
use Carbon\Carbon;
use App\Traits\OrderRegister;
class OrderController extends Controller
{
use OrderRegister;
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index($type)
{
$listingtype = ListingType::where('type', '=', $type)->first();
if ($listingtype) {
$packages = $listingtype->packages()->get();
return view('packages.index', compact('packages'));
}
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create($id)
{
$package = Package::where('id', '=', $id)->first();
if (Auth::check()) {
return view('order.create_loggedin', compact('package'));
}
else {
return view('order.create_register', compact('package'));
}
}
/**
* Process a new order request. Store order values in session.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function process(Request $request)
{
$order = ['package_id' => $request->package_id, 'order_qty' => $request->no_of_listing];
session(['order' => $order]);
if (Auth::guest()) {
return $this->register($request); // need to check session for orders available in OrderRegister trait.
}
return $this->store($request);
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request)
{
if($request->session()->has('order')) {
$package = Package::where('id', '=', $request->package_id )->first();
if($request->user() == Auth::user()) {
for( $n=1;$n<=$request->no_of_listing;$n++) {
$order = new Order;
$order->package_id = $request->package_id;
$order->user_id = Auth::user()->id;
$order->expire_at = Carbon::now()->modify('+'.$package->duration_in_months.' months');
$order->save();
}
return redirect('/');
}
}
}
/**
* Display the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param int $id
* #return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
//
}
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function destroy($id)
{
//
}
}
trait : OrderRegister.php
<?php
namespace App\Traits;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Validator;
trait OrderRegister
{
use RedirectsUsers;
/**
* Get a validator for an incoming registration request.
*
* #param array $data
* #return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
'username' => 'required|max:255|unique:users',
'password' => 'required|min:6|confirmed',
]);
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return User
*/
protected function create(array $data)
{
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'username' => $data['username'],
'password' => bcrypt($data['password']),
]);
$user->profile()->save(new UserProfile);
return $user;
}
/**
* Execute the job.
*
* #return void
*/
public function register(Request $request)
{
$validator = $this->validator($request->all());
if ($validator->fails()) {
$this->throwValidationException(
$request, $validator
);
}
Auth::guard($this->getGuard())->login($this->create($request->all()));
return $this->store($request);
}
/**
* Get the guard to be used during registration.
*
* #return string|null
*/
protected function getGuard()
{
return property_exists($this, 'guard') ? $this->guard : null;
}
}
I could not find any solution for this error so created my own thread for the first time please someone help.
It throws an error because you are trying to login a vue.
in your OrderController.php you are using create method which return a view.
this method will override the create method on your trait.
So you have something like this :
Auth::guard($this->getGuard())->login(/* A view */);
you can at least rename the method on the trait from create to createUser for example.
then you call it from the guard like this :
Auth::guard($this->getGuard())->login($this->createUser($request->all()));

Resources