How to get URL params in ViewHelper with Zend Framework 2 - zend-framework2

I've created simple ViewHelper with http://blog.evan.pro/creating-a-simple-view-helper-in-zend-framework-2. How to get URL params in this helper? $this->params('param') works only in controllers...

Given the code from the blog post, you can use this code from inside the view helper:
$this->request->getPost('param'); // post parameter
// or
$this->request->getQuery('param'); // query parameter
The code from the example receives an instance of the Zend\Http\Request object for the current request and stores it in the property called request of the view helper so you can use the request property to access the Request object and information from it.

In view helper you have to add code like this:
Module.php
'factories' => array(
'myViewHelper' => function($pm) {
return new MyView($pm);
},
)
Now in Helper Class file your have to add following piece of code
public function __construct($pm) {
$this->pluginManager = $pm;
$this->serviceLocator = $this->pluginManager->getServiceLocator();
$this->routeMatch = $this->serviceLocator->get('Router')->match($this->serviceLocator->get('Request'));
}
public function __invoke() {
$params = $this->getRouteMatch()->getParams();
}
Here $params will return all route params in array formate.

Related

How to use form view helper into custom view helper in zend framework 2

I am creating custom view helper. and i want to know how can i use formElement "Zend\Form\View\Helper\FormElement" in my own view helper. Here is my code.
use Zend\Form\ElementInterface;
use Zend\Form\FieldsetInterface;
use Zend\Form\View\Helper\FormElement;
use Zend\Form\View\Helper\AbstractHelper;
use Zend\View\Renderer\PhpRenderer;
class JudgeCareerViewHelper extends AbstractHelper {
private $output;
public function __invoke($formCollection) {
foreach ($formCollection as $elementOrFieldset) {
if ($elementOrFieldset instanceof FieldsetInterface) {
$obj = new FormElement();
$this->output .= $obj($elementOrFieldset->get('startServiceDate'));
} elseif ($elementOrFieldset instanceof ElementInterface) {
//set element markup
echo 'element';
}
};
echo $this->output;
die();
}
}
When i echo the output return from FormElement is empty. So i opened the zend "Zend\Form\View\Helper\FormElement" library to find out where is the problem. So i found that, below code return empty. I dont know what is the purpose of $renderer = $this->getView(); and how to get view.
$renderer = $this->getView();
if (!method_exists($renderer, 'plugin')) {
// Bail early if renderer is not pluggable
return '';
}
Purpose of creating custom view helper to generate my own markup (HTML) instead of zend buitin html.
So I found that, code $renderer = $this->getView() return empty.
You will need to ensure that the view helper is not directly instantiated using new but is called via the Zend\View\HelperPluginManager.
I suspect that the issue is because it is not correctly registered with the service manager as an invokable class.
// Module.php
public function getViewHelperConfig()
{
return array(
'invokables' => array(
'JudgeCareer'
=> 'FooModule\Form\View\Helper\JudgeCareerViewHelper',
),
);
}
This is to ensure that the Zend\View\Renderer\PhpRenderer is injected as the view.
Once the JudgeCareerViewHelper has the 'view' injected it would then be able to call other view plugins and have them loaded correctly, again via the HelperPluginManager.
The line:
$obj = new FormElement();
Should then be
$object = $this->getView()->plugin('form_element');
You may call any view helper from within your custom view helper by using
$this->getView()->anyRegisteredViewHelper();
So in your case to call the ZF2 built in form rendering view helpers you would use:
$this->getView()->formElement($element);
Whereby $element is your Form Element object (Select/Textarea/Checkbox etc)
You can of course also call explicit helpers for specific elements:
$this->getView()->formTextarea($textareaElement);

ZF2 set custom URL/route and view

I am using ZF2 as a component of another application.
I am looking for a way to set the URL and View Template of the application between an init() and a run() call. I would like a way to either modify the Request and Response objects, or regenerate them with a different URL.
I currently use ob_start() and ob_get_clean() and a view template that simply generates the_content, thus injecting the output of ZF2 inside a page of another application.
Any suggestions on methodology would be appreciated.
In Module.php you can attach event to event manager for exemple.
class Module
{
public function onBootstrap($e)
{
$eventManager = $e->getApplication()->getEventManager();
$serviceManager = $e->getApplication()->getServiceManager();
$eventManager->attach(MvcEvent::EVENT_ROUTE, function($e) use ($eventManager, $serviceManager){
// your code here
}, -1000);
}
}
Or your action in your controller can dispatch another action and get the result
in action method :
$return = $this->forward()->dispatch('controllerName', array('action' => 'actionName', 'param1' => 'value', ...));
The following code inside another application can be used to set the calling URL and View Template from outside of the application:
$bootstrap = \Zend\Mvc\Application::init( include( '/zf2/config/application.config.php' ) );
$event = $bootstrap->getMvcEvent( );
/* Modify the event with a custom request. */
$request = new \Zend\Http\Request( );
$request->setMethod( \Zend\Http\Request::METHOD_GET );
$request->setUri( $custom_url );
$event->setRequest( $request );
/* Modify the view. */
$event->getViewModel()->setTemplate('layout/custom-layout');
ob_start( );
$bootstrap->run( );
$html = ob_get_clean( );

Fat Free framework not updating record

Here is the code in my unit test...
public static function member_put($f3,$args) {
// Id is for member: locohost
$f3->mock('PUT /member/c4774904-f15f-11e2-b7e4-00ffe024bd0b', array(
'firstname' => 'Not-Mark',
'lastname' => 'Not-Deibert'
));
}
Here is the Member model put method being called...
public static function put($f3,$args) {
self::validateArgs($args);
self::validatePost();
self::findById($args['id']);
self::$member->copyFrom('POST');
//var_dump(self::$member);
self::$member->save();
self::returnModel();
}
The Member put method is being called as expected, however the Member is not getting the new name fields from copyFrom('POST'). The var_dump still shows old values in the name fields. What am I doing wrong?
$_POST is available for POST method only.
For other methods (PUT, PATCH, DELETE) but also POST and GET, the http request body is stored in the BODY variable.
Therefore your put() function should look like:
public static function put($f3,$args) {
self::validateArgs($args);
self::validatePost();
self::findById($args['id']);
parse_str($f3->get('BODY'),$input);
$f3->set('INPUT',$input);
self::$member->copyFrom('INPUT');
//var_dump(self::$member);
self::$member->save();
self::returnModel();
}
Note that the request body is in the form of a query string: firstname=Not-Mark&lastname=Not-Deibert. That explains why it needs to be parsed with parse_str.

Generate hyperlink in ASP.NET MVC 2 controller?

I've been scouring the web for a way to do this.
I want to generate a hyperlink to an action from my controller and put it in a string. I need to be able to define the label and give it html attributes. I can get Url.Action(...) working but that method doesn't let me define the label on the link.
HtmlHelper.GenerateLink(...) looks promising but I can't find any concrete examples on how to use it.
The link should look something like this:
View
Add this property to your base controller:
protected HtmlHelper Html
{
get
{
var viewContext = new ViewContext( ControllerContext, new WebFormView( Request.CurrentExecutionFilePath ),
new ViewDataDictionary(), new TempDataDictionary(), Response.Output )
{
RouteData = ControllerContext.RouteData
};
return new HtmlHelper( viewContext, new ViewPage() );
}
}
and then call it from anywhere:
var link = Html.ActionLink( "Click Me", "action" );
try this
string str = string.Concat("View"
and then pass this in ViewData and call it in view
<%= str%>
there are a few ways to do this - here are 2:
Link name here
Html.ActionLink(article.Title,
"Login", // <-- Controller Name.
"Item", // <-- ActionMethod
new { id = "<arguments here" }, // <-- Route arguments.
null // <-- htmlArguments .. which are none. You need this value
// otherwise you call the WRONG method ...
// (refer to comments, below).
)
there are other overloads of each available
Perhaps a little more information on why you would want to do this would be a little more helpful. If you return a string that contains HTML it will by default be HTML encoded and rendered useless on the client. If you have a custom view where this will be rendered why not build the link there using #Html.ActionLink?
I guess I am trying to figure out the benefit of doing it in the controller rather than the view...

ASP.NET MVC Map String Url To A Route Value Object

I am creating a modular ASP.NET MVC application using areas. In short, I have created a greedy route that captures all routes beginning with {application}/{*catchAll}.
Here is the action:
// get /application/index
public ActionResult Index(string application, object catchAll)
{
// forward to partial request to return partial view
ViewData["partialRequest"] = new PartialRequest(catchAll);
// this gets called in the view page and uses a partial request class to return a partial view
}
Example:
The Url "/Application/Accounts/LogOn" will then cause the Index action to pass "/Accounts/LogOn" into the PartialRequest, but as a string value.
// partial request constructor
public PartialRequest(object routeValues)
{
RouteValueDictionary = new RouteValueDictionary(routeValues);
}
In this case, the route value dictionary will not return any values for the routeData, whereas if I specify a route in the Index Action:
ViewData["partialRequest"] = new PartialRequest(new { controller = "accounts", action = "logon" });
It works, and the routeData values contains a "controller" key and an "action" key; whereas before, the keys are empty, and therefore the rest of the class wont work.
So my question is, how can I convert the "/Accounts/LogOn" in the catchAll to "new { controller = "accounts", action = "logon" }"??
If this is not clear, I will explain more! :)
Matt
This is the "closest" I have got, but it obviously wont work for complex routes:
// split values into array
var routeParts = catchAll.ToString().Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
// feels like a hack
catchAll = new
{
controller = routeParts[0],
action = routeParts[1]
};
You need to know what part is what in the catchAll parameter. Then you need to parse it yourself (like you are doing in your example or use a regexp). There is no way for the framework to know what part is the controller name and what is the action name and so on, as you haven't specified that in your route.
Why do you want to do something like this? There is probably a better way.

Resources