I'm creating my own blog engine to learn Symfony, and I have a question :
In the generated administration pages for a blog post, I have a drop-down list of authors, to indicate the author_id.
I'd like to hide that drop-down list, and set the author_id to the id of the current logged-in user when the post is created (but not when it is edited)
How can I accomplish that ?
Edit
I've tried those :
$request->setParameter(sprintf("%s[%s]", $this->form->getName(), "author_id"), $this->getUser()->getAttribute("user_id"));
$request->setParameter("content[author_id]", $this->getUser()->getAttribute("user_id"));
$request->setParameter("author_id", $this->getUser()->getAttribute("user_id"));
$request->setParameter("author_id", 2);
$request->setParameter("content[author_id]", 2);
$request->setParameter("author_id", "2");
$request->setParameter("content[author_id]", "2");
In processForm() and executeCreate()
Resolved !
The final code is :
public function executeCreate(sfWebRequest $request)
{
$form = $this->configuration->getForm();
$params = $request->getParameter($form->getName());
$params["author_id"] = $this->getUser()->getGuardUser()->getId();;
$request->setParameter($form->getName(), $params);
parent::executeCreate($request);
}
Override the executeCreate function in the actions file. When binding post data to the form, merge the current user's id into it.
2nd update
I did some experimenting, and this works:
class fooActions extends autoFooActions
{
public function executeCreate(sfWebRequest $request)
{
$form = $this->configuration->getForm();
$params = $request->getParameter($form->getName());
$params["author_id"] = 123;
$request->setParameter($form->getName(), $params);
parent::executeCreate($request);
}
}
change the widget in the form with the sfWidgetFormInputHidden and set the value with sfUser attribute (that defined when a user logged in)
override the executeCreate() and set the author_id widget (thanks to maerlyn :D )
public function executeCreate(sfWebRequest $request){
parent::executeCreate($request);
$this->form->setWidget('author_id', new sfWidgetFormInputHidden(array(),array('value'=>$this->getUser()->getAttribute('author_id'))) );
}
In Objects , the solution is: (new and $this)
class fooActions extends autoFooActions
{
public function executeCreate(sfWebRequest $request)
{
$this->form = new XxxxxForm();
$params = $request->getParameter($this->form->getName());
$params["author_id"] = 123;
$request->setParameter($this->form->getName(), $params);
parent::executeCreate($request);
}
}
Related
I m training but I'm under symfony 3
i have problem i get this error
Expected argument of type "string",
"Test\FrontBundle\Form\Type\SheetType" given
the code on SheetType.php is
<?php
namespace Test\FrontBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\FormBuilderInterface;
class SheetType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name',null,array('label'=>'Titre de l\'album'))
->add('type')
->add('artist')
->add('duration')
->add('released', DateType::class)
;
}
}
and on my SheetController.php i do that form my controller
i dont know how i can solve this all time i try else i got error
public function createAction(Request $request)
{
$form = $this->createForm(new SheetType());
$form->handleRequest($request);
if($request->isMethod('post') && $form->isValid()){
$em = $this->getDoctrine()->getManager();
$em->persist($form->getData());
$em->flush();
return $this->redirect($this->generateUrl('test_front_sheet_list'));
}
return $this->render('TestFrontBundle:Sheet:create.html.twig', array('form' => $form->createView()));
}
Since symfony 2.8 you have to pass a full qualified class name instance as argument when create a form or form builder, it does not take an instance of FormTypeInterface anymore.
see https://github.com/symfony/symfony/blob/2.8/UPGRADE-2.8.md
So you should use $form = $this->createForm(SheetType::class); instead.
I am using ZF2
I am want to get the user information who has logged into the system. Basically I am having a create_userid and last_update_userid for every table. I want to populate this with the id of the user who has logged in and performing the operations.
I can pass this as a parameter into my operations from the controller; I would like to get this automatically from the system.
I am sure someone else would have thought about this and performed this.
I did some research and found when a class is created to implement ServiceLocatorAwareInterface we can do all sorts of things with the service locator. Also, the servicelocator is set automatically by the MVC engine.
I created the Table to implement ServiceLocatorAwareInterface and I could get the user id of the logged in user.
I have the code below
namespace UserAdmin\Model;
use Zend\Db\TableGateway\TableGateway;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class UserTable implements ServiceLocatorAwareInterface {
protected $serviceLocator = null;
protected $loggedUser = 0;
protected $tableGateway;
protected $table = "user";
public function __construct( TableGateway $tableGateway ) {
$this->tableGateway = $tableGateway;
}
public function setServiceLocator(ServiceLocatorInterface $serviceLocator) {
$this->serviceLocator = $serviceLocator;
}
public function getServiceLocator() {
return $this->serviceLocator;
}
protected function setLoggedUser( ) {
$serviceLocator = $this->getServiceLocator( );
$authService = $serviceLocator->get( 'AuthService' );
if ( $authService->hasIdentity( ) ) {
$this->loggedUser = $authService->getIdentity( )->user_id;
}
}
...
...
public function saveUser ( User $user ) {
if ( $this->loggedUser == 0 ) {
$this->setLoggedUser( );
}
...
...
$data [ 'last_update_userid' ] = $this->loggedUser;
$data [ 'last_update_timestamp' ] = date ( 'Y-m-d H:i:s' );
if ( is_null( $user_id ) ) {
$data [ 'create_userid' ] = $this->loggedUser;
$data [ 'create_timestamp' ] = date ( 'Y-m-d H:i:s' );
$this->tableGateway->insert( $data );
} else {
if ( $this->getUser ( $user_id ) ) {
$this->tableGateway->update( $data, array ( 'user_id' => $user_id, ) );
} else {
throw new \Exception ( "Could not find row in table $this->table for update" );
}
}
}
}
This takes care of most of my needs. There is just two aspects.
a> I tried calling the setLoggedUser function from the constructor and it does not work. I think the service locator is set after the entire construction. so I am calling the function just before a save, and that is when I need it. Is this a clean implementation or is there another way to do this.
b> An User can register himself on the site; and the userid is an autogenerated sequence so how do I populate the userid to be the same as the new userid.
Two things come to my mind;
1> After insert read the user record and update the record with the userid
2> Not worry about this so much and have a system superadmin id as the id to write users who self register.
This is a problem only for self registrations of users only. Any other table within the system will be inserted or updated only after the user is logged in.
To set the Service Locator in the UserTable Class -
In UserAdmin/Module.php -
'UserAdmin\Model\UserTable' => function($sm) {
$tableGateway = $sm->get('UserTableGateway');
$table = new UserTable($tableGateway);
//This way the serviceLocator is injected to the Table.
$table->setServiceLocator($sm);
return $table;
},
Now, when you will call the setLoggedUser from the controller, the value will be set.
Important:
Rather than having the above private function, the best approach will be to have a Controller Plugin. This plugin will check if any user is logged in or not and if yes then return the user's id.
I'm using AbstractTableGateway and HydratingResultset to do db operations. (with BjyProfiler)
when i post my form data with add action it works, but edit action doesn't work. when i make a bind it works, but i m redirected to the add page because submitting the form resets paramaters coming from route.
here is my code for editAction() (same with Album editAction())
$id = (int)$this->params()->fromRoute('id');
if (!$id) {
return $this->redirect()->toRoute('voyage', array('action'=>'add'));
}
$voyage = $this->getVoyageTable()->getVoyage($id);
$form = new VoyageForm($this->getTypeVoyageTable());
$form->bind($voyage);
$form->get('submit')->setAttribute('value', 'Edit');
$request = $this->getRequest();
if ($request->isPost()) {
$form->setData($request->getPost());
if ($form->isValid()) {
$this->getVoyageTable()->saveVoyage($voyage);
// Redirect to list of voyages
return $this->redirect()->toRoute('voyage');
}
}
return array(
'id' => $id,
'form' => $form,
);
}
and my table :
class VoyageTable extends AbstractTableGateway
{
protected $table ='voyages';
public function __construct(Adapter $adapter)
{
$this->adapter = $adapter;
$this->resultSetPrototype = new HydratingResultSet();
$this->resultSetPrototype->setObjectPrototype(new Voyage());
$this->initialize();
}
[...]
Can sombody help me? How can i fix this problem ? Thanks.
You need to inform the form about the hydrator since ClassMethods is not the default
$form->setHydrator(new ClassMethods());
Hi I created two modules first application second comment.
Idea is to use comment module(Widget) in any application action (website page).
Application module
Test controller
public function commentAction(){
//seting redirection for form
$this->getCommentService()->setRedirection('test/comment');
$list = $this->forward()->dispatch('comment_controrller', array('action' => 'list'));
$add = $this->forward()->dispatch('comment_controrller', array('action' => 'add'));
$view = new ViewModel();
$view->addChild($list, 'list');
$view->addChild($add, 'add');
return $view;
}
View
Comment module
Comment controller
public function addAction()
{
$form = new CommentForm();
$form->get('submit')->setAttribute('value', 'Add');
$request = $this->getRequest();
if ($request->isPost()) {
$comment = new Comment();
$form->setInputFilter($comment ->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
$comment ->exchangeArray($form->getData());
$this->getCommentTable()->saveComment($comment);
// Redirect to test controller in application module
return $this->redirect()->toRoute($this->getCommentService()->getRedirection());
}
}
return array('form' => $form);
}
public function listAction()
{
return new ViewModel(array(
$list=> 'test'
));
}
With simple variable (list) all working fine,
Problem I get when trying to redirect form back to comment action in test controller
I can add redirection to test/comment in case form is not valid
but how I will pass all validating errors to test/comment(form)
Can you tell me, if what I'm doing logically correct or in ZF2 we have different way to do widgets
Thanks for help
Answer from weierophinney
http://zend-framework-community.634137.n4.nabble.com/zf2-widget-base-app-logic-td4657457.html
This what I've got so far:
https://github.com/nsenkevich/comment
On my website, I use a ReCaptcha widget in the form used to add comments. Once the form has been correctly sent, I write a cookie to the user's computer.
I would like to remove the ReCaptcha widget when the user has that cookie, so that returning visitors don't have to type a captcha. Can I do that in forms/commentForm.class.php, or do I need to create a new form ?
Save your flag in session:
<?php
...
if ($form->isValid()) {
...
// comment added
$this->getUser()->setAttribute('is_bot', false);
...
}
In another action:
<?php
$this->form = new CommentForm();
if ($this->getUser()->getAttribute('is_bot', true)) {
$this->form->setWidget(); // set captcha widget
$this->form->setValdiator(); // set captcha valdiator
}
Hope this helps.
It is often handy to pass a User instance as an option when creating a form in action:
public function executeNew(sfWebRequest $request)
{
$this->form = new ModelForm(null, array('user'=>$this->getUser));
}
Now you can configure you form based on user session attributes:
class ModelForm extends BaseModelForm
{
public function configure()
{
if ($this->getOption('user')->getAttribute('is_bot', false)
{
//set your widgets and validators
}
}
}