I would like to pass json to action, something similar to passing simple variable:
/** module.config.php
'mobileapplication-topup' => array(
'type' => 'segment',
'options' => array(
'route' => '/mob/topup[/:voucherID]',
'constraints' => array(
'voucherID' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
'controller' => 'Mob\Controller\Topup',
'action' => 'index',
),
),
and TopupController.php
public function indexAction()
{
echo ($this->params('voucherID'));
$result = new ViewModel();
$result->setTerminal(true);
return $result;
}
//** no layout //
$response = $this->getResponse();
$response->setStatusCode(200);
$response->setContent("Error");
return $response;
}
something similar to this, but just a json string instead of voucherID. What kind of constraints should be added to this json variable?
** Is there any way how to POST the form from other domain to ZF2?
I have found solution, but I don't think it is a perfect one...
What I was thinking that there is some way of passing variables using route
mvc.com/controller/param1/param2
and into this for example just pass a json and decode it in one of the controllers...
but at the moment I'm using basing _GET method
mvc.com/controller/param1/param2?"Json"={"p1":"value1","p2":"value2"}
Related
Hello friends I am new in zf2. I stuck at one place. In my project I want to to call one view on many action.
My url is "baseurl/g/any-thing-from-from-database"
I want to call a view on "any-thing-from-from-database" action from another module or same.
My G module have this code on module.config.php
return array(
'controllers' => array(
'invokables' => array(
'G\Controller\G' => 'G\Controller\GController',
),
),
'router' => array(
'routes' => array(
'g' => array(
'type' => 'segment',
'options' => array(
'route' => '/g[/:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'G\Controller\G',
'action' => 'g',
),
),
),
),
),
'view_manager' => array(
'template_path_stack' => array(
'g' => __DIR__ . '/../view',
),
),
);
on GController.php
namespace G\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Zend\Stdlib\RequestInterface as Request;
use Zend\Stdlib\ResponseInterface as Response;
use Zend\View\Renderer\PhpRenderer;
use Students\Form\StudentsForm;
use Students\Model\Students;
class GController extends AbstractActionController
{
public function dispatch(Request $request, Response $response = null)
{
$controller = $this->params('controller');
$nicname = $this->params('action');
if($nicname !== false){
$hosts = $this->getServiceLocator()->get('Manager\Model\HostsTable');
if(($data = $hosts->findByNicname($nicname)) !== null){
$captchaService = $this->getServiceLocator()->get('SanCaptcha');
$form = new StudentsForm($captchaService);
return array('from'=>$form);
}
}
return $this->redirect()->toRoute('home',array('controller'=>'application','action'=>'index'));
}
public function gAction()
{
return new ViewModel();
}
}
To get different actions from url I have used dispatch function that is working correctly. When i get this action from database I want to show a form with some content from different module named Students or G. But this code only showing header and footer and nothing else without any error.Please help me out.Thanks in advance.
I think overwriting dispatch method cannot be very good.
I'm sure you don't see anything, because you don't ever render a ViewModel, so no data are there. This is because you disabled default dispatch behaviour and overwrite the action argument in your route. So if you open http://my.website/g/foobar then foobarAction() would be called - if your dispatch will work correctly.
So what you could do is simple rename your action param to (for example) foo, take your logic to gAction() and do what ever you have to do with $this->param('foo').
Hello friends I am new in zf2. I am creating an action in controller, all things are working correctly. When the form is valid, i would like to pass some of the values to redirect page. how can i do this? Please help me out.
My controller action is
public function studenteditAction(){
$id = (int) $this->params()->fromRoute('id', 0);
if (!$id) {
return $this->redirect()->toRoute('manager', array(
'action' => 'students'
));
}
$form = new StudentsForm();
$request = $this->getRequest();
if ($request->isPost()) {
$students = new Students();
$form->setData($request->getPost());
if ($form->isValid()) {
$students->exchangeArray($form->getData());
$table = $this->getServiceLocator()->get('Students\Model\StudentsTable');
$table->profileStudents($students);
return $this->redirect()->toRoute('manager',array('controller'=>'manager','action'=>'student-view','id'=>$id,'status' => 'profile-ready'));
}
}
return array(
'id' => $id,
'form' => $form,
);
}
I am unable to get the passed status value on controller's view.
'status' => 'profile-ready'
Thanks in advance
You need to modify your routing configuration to accept both 'id' and 'status' values.
'manager' => array(
'type' => 'Segment',
'options' => array(
'route' => '/manager[/:id][/:status]',
'defaults' => array(
'controller' => 'Application\Controller\Manager',
'action' => 'studentView',
),
'constraints' => array(
'id' => '[0-9]*',
'status' => '[a-z-]*'
),
),
),
Controller:
public function studentViewAction()
{
$id = $this->params()->fromRoute('id');
$status = $this->params()->fromRoute('status');
return new ViewModel(array('id' => $id, 'status' => $status));
}
View
<?php
echo $this->id;
echo $this->status;
?>
This is how i pass the required values to another controller's action
I have the code to change the language of site. I would like to extend this functional. I want to make sure that the language parameter in the url is correct when I get the 404 page (or dispatch_error event).
My route example
'about' => array(
'type' => 'Segment',
'options' => array(
'route' => '/[:lang/]about',
'constraints' => array(
'lang' => '[a-zA-Z]{2}?',
),
'defaults' => array(
'controller' => 'Application\Controller\Index',
'action' => 'about',
'lang' => 'en',
),
),
),
If url param isn't correct (example.com/e/about or exampleDotcom//about), then makes redirect to the specific page (for example, example.com/why_did_it_happen). To make this, I create a function checkRedirect and attach it to EVENT_DISPATCH_ERROR . But how to get the LANG parameter from the url and then make a redirect, I don't know. I tried to do this many times, but could not. I've got - Call to a member function getParam () on a non-object. What code would I append to the checkRedirect function to get the LANG parameter from the url and then make a redirect in this function?
My code in Module.php
class Module implements
AutoloaderProviderInterface,
ConfigProviderInterface,
ViewHelperProviderInterface {
public function onBootstrap(MvcEvent $e) {
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
$eventManager->attach(MvcEvent::EVENT_ROUTE, array($this, 'initLocale'), -100);
$eventManager->attach(MvcEvent::EVENT_DISPATCH_ERROR, array($this, 'checkRedirect'), -101);
$eventManager->attach(MvcEvent::EVENT_DISPATCH, array($this, 'preDispatch'), 100);
}
public function initLocale(MvcEvent $e) {
$translator = $e->getApplication()->getServiceManager()->get('translator');
$config = $e->getApplication()->getServiceManager()->get('Config');
$shotLang = $e->getRouteMatch()->getParam('lang'); //or $e->getApplication()->getMvcEvent()->getRouteMatch();
if (isset($config['languages'][$shotLang])) {
$translator->setLocale($config['languages'][$shotLang]['locale']);
} else {
$lang = array_shift($config['languages']);
$translator->setLocale($lang['locale']);
}
}
public function checkRedirect(MvcEvent $e) {
//code here
}
$e->getRouteMatch()->getParam('NAME')
This does work, but 'NAME', but be the name given in the routes.
'route' => '/[:lang/]about',
However, the above route does not match the route *example.com/why_did_it_happen*
Try changing your route to
'route' => '[/:lang]/about',
And you could always default, if a lang is not supplied, i.e.
$e->getRouteMatch()->getParam('lang', 'en');
I have a form with two dates, start and stop. I have a validator for start and I want to validate stop and also that stop is after start. But the after validation only makes sense if start is valid.
isValid($value, $context = null) could be passed the other values in the context variable, but then I have to do the start check again.
So is there a possibility to check the result of the start validation in the stop validator's isValid() function?
You can use Callback
Or just write your own validator
------ Edit - my proposed answer - Input filter with callback or validator ------
I do that like this.
First create a filter with all params:
namespace MyGreatNameSpace\Filter;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\Factory as InputFactory;
class MyDateFilter extends InputFilter
{
public function __construct($myGreatClass)
{
$factory = new InputFactory();
$this->add($factory->createInput(array(
'name' => 'start_date',
'required' => true,
'validators' => array(
array(
'name' => 'Date',
'options' => array(
'format' => '2000-10-10',
),
)
),
)));
$this->add($factory->createInput(array(
'name' => 'end_date',
'required' => true,
'validators' => array(
array(
'name' => 'Date',
'options' => array(
'format' => '2000-10-10',
),
),
array(
'name' => 'Callback',
'options' => array(
'callback' => array($myGreatClass, 'isDateNewer'),
'messages' => array(
'callbackValue' => "The end date is Older then the start date",
),
),
),
),
)));
} // End of __construct
}
Create the callback function
public function isDateNewer($date, $params)
{
$date2 = $params['start_date'];
if ($date > $date2) { // Over simplistic
return TRUE;
}
}
Implant in the controller (I used services to pull the form/filter class)
// Get the form / validator objects from the SM
$form = $this->getServiceLocator()->get('date_form');
$filter = $this->getServiceLocator()->get('date_filter');
// Inject the input filter object to the form object, load the form with data and bind the result to the model
$form->setInputFilter($filter);
$form->setData($post);
$form->bind($myModel); // (if you wish to bind the data to whatever)
if (!$form->isValid()) {
return $this->forward()->dispatch.... (or whatever)
}
Another slightly diffrent way (though cleaner) is to write a validator. Check the Zend\Validator\Identical (note the token)
array(
'name' => '\Application\Validator\myNewNamedValidator',
'options' => array(
'token' => 'start_date',
'messages' => array(
'older' => "The end date is Older then the start date",
),
),
),
I have the following code in config:
<?php
return array(
'di' => array(
'instance' => array(
'alias' => array(
'sms_message' => 'Sms\Message',
),
'sms_message' => array(
'parameters' => array(
'from' => 'SENDER',
),
),
),
),
);
And in Message.php class I have a setter (I dont want to use contructor):
/**
* From
* #var string
*/
protected $from;
/**
* #param string $from
*/
public function setFrom($from)
{
$this->from = $from;
}
But when I try to load it I get unconfigured object:
var_dump($this->getLocator()->get('Sms\Message'));exit;
object(Sms\Message)[596]
protected 'to' => null
protected 'from' => null
protected 'body' => null
How do I can make it work?
For setter-injection you have to use the injections keyword:
array(
'di' => array(
'instance' => array(
'alias' => array(
'sms_message' => 'Sms\Message'
),
'Sms\Message' => array(
'injections' => array(
'setFrom' => array(
'from' => 'SENDER'
),
),
),
),
),
);
I'm not sure if the instance configuration is supposed to work with aliases. Better use the FQCN instead.
I also discovered that currently injections are not executed when requesting an alias while reproducing your example:
// The will call setFrom(...)
$di->get('Sms\Message);
// This will not call setFrom(...)
$di->get('sms_message');
I don't know if this behavior is intended or not. (I'll report this test which is currently failing)