Symfony2, Keep form data across redirect - forms

How to use session for retrieving data during redirect? I am getting the error message: "exception 'Symfony\Component\Form\Exception\AlreadySubmittedException' with message 'You cannot change the data of a submitted form."
C:\Bitnami\wampstack-5.5.30-0\sym_prog\proj3_27\src\MeetingBundle\Controller\UserController.php
/**
* Creates a new User entity.
*
* #Route("/new", name="user_new")
* #Method({"GET", "POST"})
*/
public function newAction(Request $request)
{
$user = new User();
$form = $this->createForm(new UserType(), $user);
$form->handleRequest($request);
$session = $this->getRequest()->getSession();
$form->setData(unserialize($session->get('userFilter')));
if ( $form->isSubmitted() && $form->isValid() ) {
$session->set( 'userFilter', serialize($form->getData()) );
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
return $this->redirectToRoute('user_edit', array('id' => $user->getId()));
}
return $this->render('MeetingBundle::user/new.html.twig', array(
'user' => $user,
'form' => $form->createView(),
));
} // public function newAction(Request $request)
C:\Bitnami\wampstack-5.5.30-0\sym_prog\proj3_27\src\MeetingBundle\EventListener\ExceptionListener.php
<?php
namespace MeetingBundle\EventListener;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Router;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
//every time the Kernel throws the kernel.exception event, the function onKernelException() is called.
/* also must create service :
meeting.exception_listener:
class: MeetingBundle\EventListener\ExceptionListener
arguments: [#templating, #kernel, #router]
tags:
- { name: kernel.event_listener, event: kernel.exception, method: onKernelException }
*/
class ExceptionListener
{
protected $templating;
protected $kernel;
protected $router;
public function __construct( EngineInterface $templating, $kernel, Router $router)
{
$this->templating = $templating;
$this->kernel = $kernel;
$this->router = $router;
}
public function onKernelException(GetResponseForExceptionEvent $event)
{
$exception = $event->getException();
$request=$event->getRequest();
$referer = $event->getRequest()->headers->get('referer');
$msg="";
$excStr=$exception->__toString(); // returns string finally!
$bdup=strpos( $excStr , 'Integrity constraint violation: 1062 Duplicate entry' );
if($bdup) {
$msg=" This username is already taken. Choose another username. ";
}
if(strlen($msg)!=0) {
// flash messsages are displayed in layout.html
$request->getSession()
->getFlashBag()
->add('Error', $msg);
}
$response = new RedirectResponse($referer); // redirect to the error page
if ($exception instanceof HttpExceptionInterface) {
$response->setStatusCode($exception->getStatusCode());
$response->headers->replace($exception->getHeaders());
} else {
$response->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR);
}
$event->setResponse($response);
}
}

Related

Magento 2 - Newsletter subscription issue

I use Martfury theme. When I subscribe to newsletter, it redirects me to /newsletter/subscriber/new/ and there is this message (JSON): {"success":true,"message":"Thank you for your subscription.","redirect":false}
Image:
It should show only notification and not redirect to that URL. In Martfury theme demo it works well.
Code:
In your theme, please check the newsletter controller return. Debug execute function line by line.
controller path: module-newsletter/Controller/Subscriber/NewAction
Then you can check the below function:
/**
* New subscription action
*
* #return Redirect
*/
public function execute()
{
if ($this->getRequest()->isPost() && $this->getRequest()->getPost('email')) {
$email = (string)$this->getRequest()->getPost('email');
try {
$this->validateEmailFormat($email);
$this->validateGuestSubscription();
$this->validateEmailAvailable($email);
$websiteId = (int)$this->_storeManager->getStore()->getWebsiteId();
/** #var Subscriber $subscriber */
$subscriber = $this->_subscriberFactory->create()->loadBySubscriberEmail($email, $websiteId);
if ($subscriber->getId()
&& (int)$subscriber->getSubscriberStatus() === Subscriber::STATUS_SUBSCRIBED) {
throw new LocalizedException(
__('This email address is already subscribed.')
);
}
$storeId = (int)$this->_storeManager->getStore()->getId();
$currentCustomerId = $this->getCustomerId($email, $websiteId);
$subscriber = $currentCustomerId
? $this->subscriptionManager->subscribeCustomer($currentCustomerId, $storeId)
: $this->subscriptionManager->subscribe($email, $storeId);
$message = $this->getSuccessMessage((int)$subscriber->getSubscriberStatus());
$this->messageManager->addSuccessMessage($message);
} catch (LocalizedException $e) {
$this->messageManager->addComplexErrorMessage(
'localizedSubscriptionErrorMessage',
['message' => $e->getMessage()]
);
} catch (\Exception $e) {
$this->messageManager->addExceptionMessage($e, __('Something went wrong with the subscription.'));
}
}
/** #var Redirect $redirect */
$redirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
// phpcs:ignore Magento2.Legacy.ObsoleteResponse
$redirectUrl = $this->_redirect->getRedirectUrl();
return $redirect->setUrl($redirectUrl);
}

Too many Redirects with Controller

When I try to define my routes with an ImagesController, I get a "site redirected you too many times" error when going to what should be the index. I'm stumped. Am I over-tired and not seeing something obvious?
web.php
Route::prefix('images')->group(function(){
Route::post('add-tag', 'ImagesController#addTag');
Route::get('test', 'ImagesController#index');
});
When I access /images/test, the controller responds correctly. When I have it defined as '' or / it redirects too much. I'm not setting them simultaneously.
Route::prefix('images')->group(function(){
Route::post('add-tag', 'ImagesController#addTag');
// like this:
Route::get('', 'ImagesController#index');
// or like the following:
Route::get('/', 'ImagesController#index');
});
I've even tried to define /images before the prefix group to no avail. images/test is fine in this case.
Route::get('images', 'ImagesController#index');
Route::prefix('images')->group(function(){
Route::post('add-tag', 'ImagesController#addTag');
Route::get('test', 'ImagesController#index');
});
ImagesController.php
namespace App\Http\Controllers;
use \Auth;
use App\Helpers;
use App\Image;
use App\Tag;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Symfony\Component\Console\Helper\Helper;
class ImagesController extends Controller
{
private $sortBy = [
'created_at',
'updated_at',
'orig_name',
'orig_size'
];
private $defaultSortBy = 'created_at';
private $defaultOrder = 'desc';
/**
* #param Request $request
* #return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function index(Request $request)
{
$sort = $request->get('sort', $this->defaultSortBy);
$sort = in_array($sort, $this->sortBy) ? $sort : 'created_at';
$order = $request->get('order', $this->defaultOrder);
$order = $order == 'desc' ? 'desc' : 'asc';
$images = Image::orderBy($sort, $order)
->whereQuestionable(0)
->wherePrivate(0)
->paginate(config('image.images_per_page'));
if ($images !== null && $sort !== $this->defaultSortBy) {
$images->appends(['sort' => $sort]);
}
if ($images !== null && $order !== $this->defaultOrder) {
$images->appends(['order' => $order]);
}
return view(
'images.index',
[
'images' => $images,
'sort' => $sort,
'order' => $order
]
);
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request)
{
//
}
/**
* 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)
{
//
}
//this function works correctly, but I suppose it may be interfering?
public function addTag(Request $request)
{
Log::debug(print_r($request->all(), true));
$error = '';
$uid = trim($request->input('uid', ''));
$newTag = Helpers::prepTag($request->input('tag', ''));
if (!Auth::check()){
$error .= 'You can only add tags to images if you are logged in.';
} else if ($uid === '' || $newTag === '') {
$error .= 'UID and tag cannot be empty';
} else {
$image = Image::whereUid($uid)->unQuestionable()->first();
$currentTags = [];
if (count($image->tags)){
foreach ($image->tags as $currentTag) {
$currentTags[$currentTag->id] = $currentTag->tag;
}
}
if ($image === null) {
$error .= "Image $uid was not found.";
} else {
$tag = Tag::firstOrNew(['tag'=>$newTag]);
if ($tag->ip == '') {
$tag->ip = $request->getClientIp();
$tag->user_id = Auth::check() ? Auth::user()->id : 5;
$tag->save();
}
//\Log::info(print_r($currentTags, true));
//\Log::info(print_r($tag, true));
$addTag = !(bool)isset($currentTags[$tag->id]);
$image->tags()->sync([$tag->id], false);
}
}
if ($request->ajax()) {
if ($error !== '') {
return response()->json(['message' => $error],400);
}
return response()->json(['tagId' => $tag->id, 'imageUid' => $image->uid, 'tag' => $tag->tag, 'isAdmin' => true, 'addTag' => $addTag]);
} else {
if ($error !== '') {
Helpers::alert(3, $error, 'Tag Not Added');
}
return redirect('/');
}
}
}
As I have a model named Images implicit binding was interfering with my defined routes for a controller with the name ImagesController, and applying the prefix /images. After changing the name in the routing to image this issue went away.

Zend Framewok not populating all table field's value

I'm beginner for Zend Framework and using Zend Framework 2.5 veresion. I'm getting same issue and can't be resolved.My Model.php is different than show above.
Model.php
namespace User;
use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
class Module implements AutoloaderProviderInterface, ConfigProviderInterface{
public function getAutoloaderConfig(){
return array(
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__.'/src/'.__NAMESPACE__,
)
)
);
}
public function getConfig(){
return include __DIR__. '/config/module.config.php';
}
}
My 'tbl_user' has fields with '_' like 'first_name', 'last_name', 'contact_num' which are not listing. other without underscore '_' fields are listing.
What is wrong with me, can anyone help me?
My output is:
User\Model\User Object
(
[id:protected] => 4
[first_name:protected] =>
[last_name:protected] =>
[contact_num:protected] =>
[email:protected] => dev#email.com
[designation:protected] => C++Programmer
[text:protected] =>
[name:protected] =>
[profile_pic:protected] =>
)
here is my Model 'User.php'
<?php
namespace User\Model;
class User implements UserInterface{
protected $id;
protected $first_name;
protected $last_name;
protected $contact_num;
protected $email;
protected $designation;
protected $text;
protected $name;
protected $profile_pic;
public function getId(){
return $this->id;
}
public function setId($id){
$this->id = $id;
}
public function getName(){
return $this->name;
}
public function setName($first_name, $last_name){
$this->name = $first_name.' '.$last_name;
}
public function getContact(){
return $this->contact_num;
}
public function setContact($contact_num){
$this->contact_num = $contact_num;
}
public function getEmail(){
return $this->email;
}
public function setEmail($email){
$this->email = $email;
}
public function getDesignation(){
return $this->designation;
}
public function setDesignation($designation){
$this->designation = $designation;
}
public function getProfilePic(){
return $this->profile_pic;
}
public function setProfilePic($profile_pic){
$this->profile_pic = $profile_pic;
}
/*public function getText(){
return $this->text;
}
public function setText($text){
$this->text = $text;
}*/
}
?>
and this is my 'ZendDbSqlMapper.php'
<?php
namespace User\Mapper;
use User\Model\UserInterface;
use Zend\Db\Adapter\AdapterInterface;
use Zend\Db\Adapter\Driver\ResultInterface;
use Zend\Db\ResultSet\HydratingResultSet;
use Zend\Stdlib\Hydrator\HydratorInterface;
use Zend\Db\Sql\Sql;
use Zend\Db\Sql\Insert;
use Zend\Db\Sql\Update;
class ZendDbSqlMapper implements UserMapperInterface{
protected $dbAdapter;
protected $hydrator;
protected $userPrototype;
public function __construct(
AdapterInterface $dbAdapter,
HydratorInterface $hydrator,
UserInterface $userPrototype
){
$this->dbAdapter = $dbAdapter;
$this->hydrator = $hydrator;
$this->userPrototype = $userPrototype;
}
public function find($id){
$sql = new Sql($this->dbAdapter);
$select = $sql->select('tbl_users');
$select->where(array('id = ?' => $id));
$stmt = $sql->prepareStatementForSqlObject($select);
$result = $stmt->execute();
if($result instanceof ResultInterface && $result->isQueryResult() && $result->getAffectedRows()){
return $this->hydrator->hydrate($result->current(), $this->userPrototype);
}
throw new \InvalidArgumentException("User with given ID:{$id} not found");
}
public function findAll(){
$sql = new Sql($this->dbAdapter);
$select = $sql->select('tbl_users');
$stmt = $sql->prepareStatementForSqlObject($select);
$result = $stmt->execute();
//\Zend\Debug\Debug::dump($result); die;
if($result instanceof ResultInterface && $result->isQueryResult()){
//$resultSet = new ResultSet();
$resultSet = new HydratingResultSet($this->hydrator, $this->userPrototype);
//\Zend\Debug\Debug::dump($resultSet->initialize($result)); die;
return $resultSet->initialize($result);
}
return array();
}
public function save(UserInterface $userObject){
$userData = $this->hydrator->extract($userObject);
unset($userData['id']);
if($userObject->getId()){
$action = new Update('tbl_users');
$action->setData($userData);
$action->where(array('id = ?' => $userObject->getId()));
}else{
$action = new Insert('tbl_users');
$action->values($userData);
}
$sql = new Sql($this->dbAdapter);
$stmt = $sql->prepareStatementForSqlObject($action);
$result = $stmt->execute();
if($result instanceof ResultInterface){
if($newId = $result->getGeneratedValue()){
$userObject->setId($newId);
}
return $userObject;
}
return new \Exception("Database Error");
}
}
?>
here is 'ListController.php'
<?php
namespace User\Controller;
use User\Service\UserServiceInterface;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class ListController extends AbstractActionController{
protected $userService;
public function __construct(UserServiceInterface $userService){
$this->userService = $userService;
}
public function indexAction(){
return new ViewModel(array(
'users' => $this->userService->findAllUsers()
));
}
public function detailAction(){
$id = $this->params()->fromRoute('id');
try {
$user = $this->userService->findUser($id);
}catch(\InvalidArgumentException $ex){
return $this->redirect()->toRoute('user');
}
return new ViewModel(
array( 'user' =>$user )
);
}
}
?>
thank you.

symfony2 embedded forms validation for fosuserbundle

HI in my case embedded forms validation doesn't work.
And i have set 'cascade_validation' => true, even tried with Valid constraint in my model to force validation on a child object. Also doesn't work.
Here how it looks like:
My User class:
/**
* #ORM\OneToOne(targetEntity="Info", inversedBy="user", cascade={"persist"})
* #Assert\Valid
*/
protected $info;
As we see it contain an extra info field type.
And now my overwritten controller:
public function registerBrandAction(Request $request)
{
/** #var $formFactory \FOS\UserBundle\Form\Factory\FactoryInterface */
$formFactory = $this->container->get('fos_user.registration.form.factory');
/** #var $userManager \FOS\UserBundle\Model\UserManagerInterface */
$userManager = $this->container->get('fos_user.user_manager');
/** #var $dispatcher \Symfony\Component\EventDispatcher\EventDispatcherInterface */
$dispatcher = $this->container->get('event_dispatcher');
$user = $userManager->createUser();
$user->setEnabled(true);
$event = new GetResponseUserEvent($user, $request);
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_INITIALIZE, $event);
if (null !== $event->getResponse()) {
return $event->getResponse();
}
$form = $formFactory->createForm(new RegistrationFormType($user));
$form->setData($user);
$form->add('info', new InfoFormType());
$brand = new Info();
$user->setBrand($info);
if ('POST' === $request->getMethod()) {
$form->bind($request);
if ($form->isValid()) {
$event = new FormEvent($form, $request);
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_SUCCESS, $event);
$em = $this->container->get('doctrine')->getManager();
$em->persist($info);
$user->addRole('ROLE_ADMIN');
$userManager->updateUser($user, false);
$em->flush();
if (null === $response = $event->getResponse()) {
$url = $this->container->get('router')->generate('fos_user_registration_confirmed');
$response = new RedirectResponse($url);
}
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_COMPLETED, new FilterUserResponseEvent($user, $request, $response));
return $response;
}
}
return $this->container->get('templating')->renderResponse('FOSUserBundle:Registration:registerAdmin.html.' . $this->getEngine(), array(
'form' => $form->createView(),
));
}
So in my RegistrationFormType i have enabled cascade_validation. But Validations still doesn't work. Can anyone help me ? And also why am i adding this in controller ? Becous i have to 2 of users and i dont want to form have that Info for other one.
easy as that!
just add to your validations fos user registration form group
* #Assert\NotBlank(groups={"registration"})
and to your form:
'validation_groups' => array('registration'),
and it works!

Zend Framework - Passing a variable request in controller

In one of these php frameworks I've noticed a posibility to request the object Request in action as $this->request->paramName
class MyRequest extends Zend_Controller_Request_Http{
public $params = array();
public function __construct() {
$this->params = $this->getParams();
parent::__construct();
}
public function __get($name) {
if (isset($this->_params[$name])) {
return $this->_params[$name];
}
}
public function __isset($name) {
return isset($this->_params[$name]);
}
}
in MyController I've added variable request
public $request = null;
How can I change that standart Request to my one?
public function __construct(
Zend_Controller_Request_Abstract $request,
Zend_Controller_Response_Abstract $response,
array $invokeArgs = array()) {
$request = new MyRequest();
parent::__construct($request, $response, $invokeArgs);
$this->request = $this->getRequest();
}
This function has given no results.
Option 1 is make method _initRequest() in bootstrap:
protected function _initRequest() {
$this->bootstrap ( 'FrontController' );
$front = $this->getResource ( 'FrontController' );
$request = $front->getRequest ();
if (null === $front->getRequest ()) {
$request = new MyRequest();
$front->setRequest ( $request );
}
return $request;
}
A bit dirty and untested solution. Would love to hear if it works.
//Bootstrap:
public function _initRequest()
{
$this->bootstrap('frontController');
$front = $this->getResource('frontController');
$front->setRequest(new MyRequest());
}
Try this it might help you:
in controller file
public function exampleAction(){
$result = $this->_request;
$model = new Employer_Model_JobInfo();
$results = $model->sample($result);
}
// the above line stores the values sent from the client side in $result.then sends that values to Model file with parameter $result ..
in model file
class Employer_Model_JobInfo extends Gears_Db_Table_Abstract{
public function sample($param){
$paramVal = $param->getParam('name');
$paramVal1 = $param->getParam('email');
}
}
The name and email are what name used to sent the data from client to server.