Create Project Log(History) Module in symfony with event dispatchers - php

I'm developing a project management tool in Symfony, right now I'm creating a module to recording the logs i.e, to capture every event like New project create, task create, task status changes, deletion of projects and task, etc.
I have a log table where I have planned to insert new rows whenever any of the above event occurs. But for doing this, I need to go into each controller and call the log model to execute the insert query. Its almost like I'm going to work on all the actions in the controller again for appending this code. is there any other way to call the model only once using some event dispatcher like class in Symfony.

Glad your are using Propel, there is a bunch of plugins and/or behavior for tracking what happend to your object. I will give you a list of what I've found:
pmPropelObjectLogBehaviorPlugin: Maintains a class changelog (the changes of each instance).
AuditableBehavior: Add ability to log activity for propel objects
propel-listener-behavior: Makes you attach listeners to propel generated objects that inform you about updates on those.
ncPropelChangeLogBehaviorPlugin: a Behavior for Propel objects that allows you to track any changes made to them.

JMSAOPBundle does exactly that.
If I may suggest, I think it's better to add custom events for each action, with this way you can extend your app with more listener without losing control. If you use doctrine you can also work with doctrine event system

Related

Events vs Observers in laravel

I'm really confused with events and observers. because both are doing same things. what are the differences b/w events and observers? Thanks in advance.
Observers and events do not do the same thing at all.
Simple Difference
Observers are basically predefined events that happen only on Eloquent Models (creating a record, updating a record, deleting, etc). Events are generic, aren't predefined, and can be used anywhere, not just in models.
Observers:
An observer watches for specific things that happen within eloquent such as saving, saved, deleting, deleted (there are more but you should get the point). Observers are specifically bound to a model.
Events:
Events are actions that are driven by whatever the programmer wants. If you want to fire an event when somebody loads a page, you can do that. Unlike observers events can also be queue, and ran via laravel's cron heartbeat. Events are programmer defined effectively. They give you the ability to handle actions that you would not want a user to wait for (example being the purchase of a pod cast)
The documentation does a very good job covering these.
Reference Taken From : https://www.scratchcode.io/laravel/difference-between-events-and-observers-in-laravel/
OK. So, clear up one thing Events and Observers are not doing same things.
What is Event ?
Event is triggered when specific task happens. Such as, some model is created, updated, delete (these are the default ones from laravel). You can dispatch/trigger your custom events as well product.liked or user.commented.
https://laravel.com/docs/5.7/events#defining-events
What are observers ?
As name states these classes observes/handles those events above mentioned. So if we say
we want to do something when user is created or user is creating (this is before making an entry to DB). We define observers and if you are familiar with before and after methods methodology you can relate.
https://laravel.com/docs/5.7/eloquent#observers

doctrine: call symfony method based on Entity DateTime age

I'm new to Symfony and Doctrine.
I got a project where I need a method inside a Symfony service to be called with data from the DB whenever a dateTime object saved in that DB table "expires" (reaches a certain (dynamic) age).
As I'm just starting out I do not have any code yet. What I need is a start point to get me looking in the right direction as neither the life cycle callbacks nor the doctrine event listener / dispatcher structure seems to be able to solve this task.
Am I missing something important here or is it maybe just a totally wrong start to my problem which actually can't be solved by doctrine itself?
What came to my mind is a cron-job'ish structure, but that kind of implementation is not as dynamic as required but bound to specific time frames which may be not reactive enough and maybe even immensly decreases the performance in different situations.
If I'm getting your problem right: You want something that executes when a record's datetime expires.
The main problem is that you would have to call PHP based on a DB event which is not straight forward...
One possible solution can be a Symfony command that's executed periodically(using cron) and you select the expired entities and do the required actions.
So as far as I found out doctrine is really not able to do this task in the descriped way. Of course the DB can't react to a part of a record it saved without an external action triggering the lookup.
So what I will propably go with is a shell programm called at.
It actually is something like I (and katon.abel) mentioned. It is able to enter one time crons which are then executed according to the provided time (that I then do not need to save in the DB but just pass it to at).
This way I can easily create the crons via symfony, save the needed data via doctrine and call the callback method via a script triggered by at.

Symfony, where to put custom methods on entities?

I'm learning Symfony and I'm trying to figure out where to put custom actions over an Entity...
For example, if I have an entity Order, where to put $order->complete()? Or $order->sendToProduction(), $order->queueForDelivery()?
Those are just examples, I have complex entities and I must perform on them many actions.
In the Controller?
No, because the same action may be called from different controllers
In the Entity?
That would be the more appropriate way in a MVC model, but here I can't find an easy way to perform custom mysql query (doctrine/em is not available) from inside the Entity class, which I find strange since db operations should be perfomed at the Entity level, I believe...
In the EntityController?
It doesn't seem appropriate, and it's not easy to call repository methods from a listener, for example, and call them directly on the object...
What else? Do I have to create services? Utility classes?
If the work can be done inside a signle entity (and it's relations of course) then it should be placed there. I mean, if the operation is about changing entity's internal state.
Otherwise, if this job need to use other parts of application like database, or is performed on multiple not related entites, then I would suggest using services.
That's what where are for. Service is basically a class that can do anything. Using Service container, you can pass any dependencies to it so it's very flexible and easy to use.
For example $order->queueForDelivery(). That may mean a few different things:
changing internal state like change status to queued_for_delivery - then it should be in Order entity class
$order should be put in the Queue that is other entity class, then it should be in Queue class like $queue->addOrder($order)
this queue is an external service like RabbitMQ or anything else. Then you should use a service class.

Yii trigger component event from controller action

I'm trying to create a method where I can trigger an event from a controller action (sending parameters with it), and have multiple components (in the same, or in another module) to listen that trigger and execute some random code (maybe some sanitised string or something)..
Is there a way to create such system with Yii Events? Or i'll need to work around something else?
Thanks
Sure,
Yii has a nice event system using CEvent. Have a look at Events explained tutorial.
You can combine it with yii Behaviors, here's another good tutorial if you are interested in Behaviors & Events.
Behaviors are a way of adding methods to a Class without php limitations of class extending since you can attach several behaviors to a same class.

Extending doctrine:build --db to create a DB View

I'm working on a Symfony 1.4 project with Doctrine 1.x, and functionality that merits using a Doctrie_View (as an interface for native MySQL Views).
As I understand it, the View (as in DB View as opposed to the View in MVC) has to be created wth Doctrine so that Doctrine can maintain the association between the View and the original Model from which it's derived.
In an ideal world, I'd like to have the View created as part of the symfony doctrine:build --db task. The sensible way to do this would be to use the observer pattern and Symfony's Event Dispatcher, however, the list of Built In-Events doesn't seem to offer an event for when the database schema is built.
So, what's the best way to have a Doctrine View created when the schema is built?
Or perhaps, if that's not an option, check if a View doesn't exist and then create it as part of ProjectConfiguration::configureDoctrine()?
doctrine:build-sql
I think you should rather look at the doctrine:build-sql task which builds the sql instructions from the model definition.
If you look at the sfDoctrineBuildSqlTask class you'll notice it's rather simple. It really only calls the doctrine cli. If you want to hook into it you should check the Doctrine events rather than symfony.
migrations
What you could also do is creating your view in doctrine migrations. Whenever you need to change your view you'll create another migration (removing old and creating new view).

Categories