I wish to know simply if it is possible to preload the create entity form with given values.
My application has a Daily Schedule view with 30 minute intervals. I want the user to be able to click on a time (eg:12:30) on the Daily Schedule and have it preload a Booking entity form along with the current date.
I have searched to no avail a solution, I would have thought this would be a common action.
I figure I need to access the instantiated object (the Booking) prior to it binding to the request however this is all handled by Sonata Admin.
Is it possible to simply override the Create action to preload the form?
Thank you in advance.
Yes, it is. You could set defaults on your Booking entity or overwrite getNewInstance() in your Admin class, like so:
public function getNewInstance()
{
$object = parent::getNewInstance();
$object->setDefaults();
return $object;
}
Related
I'm in searching of the best way of removing business logic from controller and correct usage of model(and maybe services).
Some details below.
Actually, my project is more complicated, but as example I will use Simple Blog application.
I have created my application (Simple Blog) in next steps:
created bundle
generated entities(Topic, Post, Comment)
generated controller for each entity, using doctrine:generate:crud
installed FOSUserBundle and generated User entity
So, I have all needed methods and forms in my controllers. But now I have some troubles:
Admin need to be able see all topics and posts, when simple User can only see
topic and posts where he is owner.
Currently there are indexAction, that return findAll common for any user. As solution, I can check in action, if ROLE_USER or ADMIN and return find result for each condition. But this variant keep some logic at action.
I also can generate action for each role, but what happened if roles amount will increase?
What is the best way to solve this problem with result for each role?
I need to edit some parameters before saving.
For example, I have some scheduler, where I create date in some steps, using features of DateTime.
Before saving I need to do some calculations with date.
I can do it in controller using service or simple $request->params edit.
What is the best way to edit some $request parameters before saving?
My questions I have marked with bold.
Thanks a lot for any help!
What I would do is to create a query which fetches the topics. Afterwards I would have a method argument which specifies if the query should select only the topics for a certain user or all topics. Something like this should do the work in your TopicRepository:
public function findTopics($userId = false)
{
$query = $this->createQueryBuilder('topic');
if($userId) {
$query->join('topic.user', 'user')
->where('user.id = :user_id')
->setParameter(':user_id', $userId)
;
}
return $query->getQuery()->getResult();
}
So, whenever you need to get the topics only by a user, you would pass a $userId to the method and it would return the results only for that user. In your controller you'd have something similar to this code (Symfony 2.6+):
$authorizationChecker = $this->get('security.authorization_checker');
if($authorizationChecker->isGranted('ROLE_ADMIN')){
$results = $this->get('doctrine.orm.entity_manager')->getRepository('TopicRepository')->findTopics();
} else {
$results = $this->get('doctrine.orm.entity_manager')->getRepository('TopicRepository')->findTopics($this->getUser()->getId());
}
You can try using Doctrine Events and create a PreUpdate depending on your case. See the documentation for more information. If you have a TopicFormType, you could also try the form events.
You are not supposed to "edit" a $request, which is why you can't directly do that. You can, however, retrieve a value, save it as a $variable and then do whatever you want with it. You can always create a new Request if you really need it. Could you be more specific what you want to do here and why is this necessary?
I am new with Symfony2 and so I am with FOSUserbundle, the registration form I wrote got different fields mandatory based on if it is a company or private person, I set it up etc and if I hardcode the valdiation group in the fos config it will work, but what I need is to set it up dynamic based on the form submit data, I tried to follow:
http://symfony.com/doc/current/book/forms.html#book-forms-validation-groups
Seeing that FOSUserbundle use the deprecated OptionsResolverInterface , I even tried it with that one, but whatever I do it is never called.
So my question is kinda, what is the right approach with that bundle to change the valdiation group on the fly based on the submitted data?
Figured it out myself how to do and because I could nowhere on the internet find the solution, answering here my own question for the case someone else need that too:
in the config.yml i set the validationgroup like this
validation_groups: [AppBundle\Form\Type\RegistrationFormType, determineValidationGroups]
and inside that class then:
public static function determineValidationGroups(FormInterface $form){
...
}
And that one returns an array with the validations groups, just dont forget to include for registration for example Registration or it wont validate if the user already exists etc
I have an API, with an API call GET /users which returns me a list of users that all have a avatar_url field
in database this field is just the image name, and in the controller i'm then putting the base URL of my static domain serving images. So that it's only one URL to change in my conf , so the code works in staging/production etc.
but things start to get tricky with GET /comments etc. that all have sub-resource users that needs to have the url, so it means that currently every single point using users needs to have this logic, which is not very DRY
I would like to have something like that
// in my entity
use JMS\Serializer\Annotation as Serializer;
/**
* #Serializer\VirtualProperty
* #Serializer\SerializedName("url")
*/
public function getUrl()
{
return $this->container->getParameter('IMG_URL').$this->imgName;
}
so that regardless on how deeply nested my entity is, I will be able to seralize it with the property.
It seems to me it is possible to achieve something like as there's a bundle
https://github.com/KnpLabs/DoctrineBehaviors
which seems to achieve something similar
Check this out. http://jmsyst.com/libs/serializer/master/handlers
From what I understand you could create your own handler for the url serializer. By having the handler as a service written by you, then you can inject anything you want in it.
More info can be found at Creating a JMS Serializer handler in symfony2
I am following this really good tutorial to setup a BaseEntity class that will contain 5 fields:
Active, DateCreated, UserCreated, DateModified, UserModified.
All of my entities that need these tracking fields will inherit from this class.
In the small tutorial below he shows me how to override the SaveChanges() method in my dbContext so that these fields will be set properly based on Creation/Updating.
I am trying to figure out how I would store the current logged in user's ID rather than the Name to the UserCreated and UserModified fields
Please let me know if the UserID shouldn't be what I am storing. This is always what I used to do in some of the webforms apps I created back in the day.
Also, what would be the best way to setup Active to always be true when adding new records. Should this be done in the db context also or within my BaseEntity class. I'm thinking I would create a function in the BaseEntity class called Disable() that will change Active=False.
Please view the small tutorial that I am using
You could create a custom implementation of IIdentity/IPrincipal which contains the UserID. Then you can retrieve this value from the Context or Thread and cast it to the correct type.
Set HttpContext.Current.User from Thread.CurrentPrincipal
I want to create a form for an entity which has a many attributes. To ensure the ease of data entry, I want to split that form in multiple pages (for example 2 or 3 pages).
Let's take the ad entity example:
In page 1, the user will enter the ad text
In page 2, the user will enter his contact
In page 3, the user will provide the (X,Y) position of the ad
This split will require saving the available data (inserting in the database) in the 1st page before moving to the next page. Unfortunately, This is not possible due to constraints.
The question is: Is any documentations or any examples that solve this issue?
If no documentation is available, do you think it is better to split my entity in n entities in order to have one entity per page?
Thanks for you help.
You probably should use CraueFormFlowBundle. It provides facilities for building multi-step forms.
You can create one form type for an entire flow, or one form type per step.
It's very easy to setup. Everything is explained here.
You don't have to split your entity, but your form : create 3 forms, each containing the property needed from the ad entity.
You'll need to :
persist (and not flush) the $ad object at every step inside your controller
pass the $ad object as an argument when forwarding inside your controller
flush the $ad object in the last step
In pseudo-code, your controller would look like this :
public function newAdStep1() {
new Ad() // New instance of $ad
new formStep1($ad) // The first form containing only the ad text field
// The form was filled, manage it...
form->isValid()? {
persist($ad); // Persist the first part of your ad object
forward(newAdStep2, $ad) // Go on to step 2, your $ad object as an argument
}
// ... or display step1 to user
createView createAdStep1.html.twig('form' => $form);
}
public function newAdStep2($ad) {
new formStep2($ad); // Now the second form, containing the "contact" fields
isValid ? {
persist($ad)
forward(newAdStep3, $ad)
}
createView createAdStep2($form, $ad); // Your $ad object needs to be sent to the view
}
public function newAdStep3($ad) {
new formStep3($ad); // Third and last form, containing the (X,Y) fields
isValid ? {
$em->persist($ad);
$em->flush(); // Your instance of $ad can be stored in database now
return('success !');
}
return view createAdStep3($form, $ad);
}
You could store all the submitted data in a session or temporary table, then persist it all together at the end. However, I do my best to avoid extra work like this.
I think it may well be that your form steps follow the order by which the constraints dictate.
Saying that, sometimes I think this kind of problem can be solved by making a better design or process decision. i.e. limit the number of questions or only ask the vital ones at first. Without knowing the ins and outs it's hard to know whether this can be done.