Zend_Form submission > Resource 'controller::action' not found - zend-framework

I'm taking over a site that's gone through several developers. The site is using Zend version 1.12.0, according to Zend_Version::VERSION, which is a new framework for me. On the site, there's a form class called App_Form_Customers_Edit, which extends Zend_Form. The form's action is /customers/edit, and when submitted, the method editAction of CustomersController is executed.
So, to create a new form, I created a new class App_Form_Customers_EditAddress in the same directory as App_Form_Customers_Edit, and set it's action to /customers/editaddress, created a function called editaddressAction in the CustomersController class and tested the form.
But I get an error saying "Resource 'customers::editaddress' not found"
The form itself is displaying properly, and as far as I can tell I'm using the exact same pattern as the other form which works, and apart from not using the zf command, the same method prescribed here in the Zend documentation: http://framework.zend.com/manual/1.12/en/learning.quickstart.create-form.html
What do I need to do to get my new form working? Do I need to update .zfproject.xml? I can't see anything in there that's related to the working form.
Here's the code for App_Form_Customers_Edit:
class App_Form_Customers_Edit extends Zend_Form
{
public function init ()
{
$this->addPrefixPath('App_Form', 'App/Form/');
$this->setMethod('post');
// ... The rest is just calls to $this->addElement
}
}
And for EditAddress:
class App_Form_Customers_EditAddress extends Zend_Form
{
public function init ()
{
$this->addPrefixPath('App_Form', 'App/Form/')
->setMethod('post')
->setAction('/customers/editaddress');
$this->addElement('submit', 'active', ['value' => 'Activate']);
$this->addElement('submit', 'remove', ['value' => 'Remove']);
$this->addElement('hidden', 'id');
}
}

Check for acl declarations. If you are using acl and you have not declared rules for the action, you might get this type of error.

Best guess:
Your former developer has implemented a custom route somewhere. Probably in the application.ini or the boostrap.php. This custom route is looking for specific urls and /customers/edit conforms to a valid route but /customers/editaddress does not.
I think this is likely because your error is a missing resource rather then a 'page not found' or a missing controller or missing action message. So it seems as though the router is trying to match an invalid resource to a valid route.
Good Luck

Related

using filters with autofac in webapi2

I have a actionfilter something as below.. The filter basically adds a few attributes to the header of the response..
public class myHeaderAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
if (actionExecutedContext.Response != null)
//my code goes here
base.OnActionExecuted(actionExecutedContext);
}
}
I would normally call this in WebApiConfig.Register as config.Filters.Add(new myHeaderAttribute());
I wish to use Autofac in my project..
There is a page in autofac site (http://docs.autofac.org/en/latest/integration/webapi.html)which speaks of implementing IAutofacActionFilter.
But, I'm not very clear as to what I'm supposed to do.
I can create another class which implements IAutofacActionFilter and add the onActionExecuted method.
But do I also keep my present class or remove it along with the line in WebApiConfig.Register.
Also the page speaks of registering the Autofac filter provider as well as the class which implements IAutofacActionFilter. But no complete example exists.
Also, it speaks of using 'service location' in case we need per-request or instance-per-dependency services in our filters.
The whole thing seems a little too confusing to me. I would sincerely appreciate if someone who understands these concepts and has used Autofac in a web api2 project could guide me.
Thanks
Remove it. It explains exactly in the docs you reference yourself that it uses its own action filter resolver. See section "Provide filters via dependency injection".
Update
First register the filter provider:
var builder = new ContainerBuilder();
builder.RegisterWebApiFilterProvider(config);
Then register your actionfilter like so:
builder.Register(c => new myHeaderAttribute())
.AsWebApiActionFilterFor<YourController>(c => c.YourMethod(default(int)))
.InstancePerApiRequest();
So complete code:
var builder = new ContainerBuilder();
builder.RegisterWebApiFilterProvider(config);
builder.Register(c => new myHeaderAttribute())
.AsWebApiActionFilterFor<YourController>(c => c.YourMethod(default(int)))
.InstancePerApiRequest();
It's all right there in the docs. If you have any specific question then you can ask seperately. But this is becoming to be too broad.

What's the best approach for data validation between forms and models on Laravel 5?

I'm used to have model and form validation together, in another framework. But I'm migrating to Laravel and trying to understand its mindset.
What's the best approach for data validation? I've seen some classes that help out on creating forms and validating requests, but isn't it unsafe to have models saving data without validating it before?
How could I integrate form (frontend), request (backend) and model validation so they all play nicely together? Or this is not done in the Laravel world at all?
As a starter in Laravel myself, I can tell a mind of a learner.
The first thing to understand is that Laravel is very very very very very abstract. It offers you thousands of solutions for a single problem. Since you're just starting out, I'm going to assume you're using Laravel 5 (5.1 to be more specific).
The $this->validate() from Controllers
You can use $this->validate() in your controllers.
class SomeController extends Controller {
public function store(Request $request){
$this->validate($request, [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
// This passed validation.
}
}
The Validation Facade
Inside the config/app.php you will find a aliases field that defines the Validator Facade as 'Validator' => Illuminate\Support\Facades\Validator::class. You can make validators from basically anywhere.
public function store(Request $request) {
$validator = Validator::make($request->all(), [
'email' => 'required|unique:emails|email',
]);
if ($validator->fails()) {
// Error logic
}
// Store the blog post...
}
Form Requests
Personally, I like Form Requests. They allow you to reuse validation logic defined once in any controller you feel like it. You can run in your project
php artisan make:request MyCustomRequest
That will generate a new request inside app/Http/Requests where you can write your rules inside the rules method. And then, when you want to use it, just type-hint your controller method.
Here is how to use it:
public function store(CompanyRequest $request){
// This code will only be executed if the rules inside CompanyRequest
// Are true.
}
Here is the file defining CompanyRequest.
class CompanyRequest extends Request {
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize() {
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules() {
return [
'name' => 'required|max:255',
'domain' => 'required|max:40'
];
}
}
Conclusion
There are probably a few more ways to do it. You can, for instance, use Validator::make facade from within your Eloquent models. Laravel offers multiple ways of handling basic problems. You just have to find what is best for you and major in it.
I'm not sure this is the best method or not.
But I'm using this concept and its most popular way of validating forms in most popular CMS.
As usual the form action should point to a controller method. Inside controller method you can init a validator class like below.
$validation = \Validator::make(\Input::all(), with(new UserValidation)->getRules());
if ($validation->fails()) {
return redirect()->route('your route path ')->withErrors($validation)->withInput();
}
Then in your controller use the namespace like .
use VendorName\PackageName\validations\UserValidation;
Here I put the validations in a separate folder called validations. Also notice that I'm using Package development concept in Laravel 5.x you can read more about that here.
Then in that UserValidation class you can put all the validation rules.
class UserValidation {
public function getRules() {
return [
'name' => 'required|max:200|unique:client',
'address'=>'required',
'status' => 'required',
];
}
}
This has several advantage the controller looks much neat and validation customization will be entirely separate file.
Also you can split up the route to a separate folder too.
Hope it make sense..
In the end, the best way I found to solve this matter was stitching together two Laravel extensions: Ardent, an Eloquent extension that includes validation, and a fork of Laravalid, that extends the Form with jQuery basic validation: that fork includes Ardent integration.

Zend Framework 2: How can I add in RESTful API a custom http method?

I'm trying to create a custom http method in RESTful API. I was reading the documentation and it is said that you can do it buy adding a simple action in controller and then for example conifg your route with child routes with action => action_name but in the code I have spotted addHttpMethodHandler() method in Zend\Mvc\Controller\AbstractRestfulController.php so in controller construct method I have added:
$add = function () {
return new JsonModel(array(
'id' => 2222,
));
};
$this->addHttpMethodHandler('someAction', $add);
var_dump($this->customHttpMethodsMap);
With the var_dump I can see that this new function is added but I just wonder how can I call it or maybe I'm missing the point.
Regards,
I actually wrote a blog post on this because I had so much trouble too.
The problem is that in addition to calling addHttpMethodHandler within the abstract restful controller, you also need to make sure that the Zend Request class knows that your http method exists.
Here is a link to a better explanation: http://richardbrock1.wordpress.com/2013/03/23/custom-http-methods-in-zf2/

Zend Framework website.com/username

One of the application I am developing using Zend Framework requires the user's profile page to be accessed via website.com/username, while other pages should be accessed by website.com/controller_name/action_name
I am not too sure how can this be achieved, however, I feel this can be done with some tweaks in the .htaccess file.
Can someone here please help me out?
Many thanks in advance
As suggested before, you can use a custom route that will route single level requests. However, this will also override the default route. If you're using modules, this will no longer work example.com/<module>.
I have done this before but only for static pages. I wanted this:
example.com/about
instead of this:
example.com/<some-id>/about
while maintaining the default route so this still works
example.com/<module>
example.com/<controller>
The way I did this was using a plugin to test if my request could be dispatched. If the request could not be dispatched using the default route, then I would change the request to the proper module to load my page. Here is a sample plugin:
class My_Controller_Plugin_UsernameRoute extends Zend_Controller_Plugin_Abstract
{
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
$dispatcher = Zend_Controller_Front::getInstance()->getDispatcher();
if (!$dispatcher->isDispatchable($request)) {
$username = $request->getControllerName();
$request->setModuleName('users');
$request->setControllerName('dashboard');
$request->setActionName('index');
$request->setParam('username', $username);
/** Prevents infinite loop if you make a mistake in the new request **/
if ($dispatcher->isDispatchable($request)) {
$request->setDispatched(false);
}
}
}
}
What about using Zend_Controller_Router_Route, look here the link http://framework.zend.com/manual/en/zend.controller.router.html#zend.controller.router.routes.standard.variable-requirements

zend framework custom validation classes

I'm writing a custom validator that is going to check for the existence of an email such that if it already exists in the database, the form is not valid. I'm having a hard time figuring out helper paths and namespaces for custom Zend_Validation classes.
I'd like to call the class My_Validate_EmailUnique but I keep getting error messages such as:
there is an error exception 'Zend_Loader_PluginLoader_Exception' with message 'Plugin by name 'My_Validate_EmailUnique' was not found in the registry; used paths: My_Validate_: /var/www/site/arc/helpers/
The class looks like this:
<?php
class My_Validate_EmailUnique extends Zend_Validate_Abstract
{
const EMAIL_UNIQUE = 'notMatch';
Can someone help me with where I register for the Zend_Form to look for custom validators?
You can directly add the validator to your form element. There is no need to write a custom validator for this.
In your form:
$element->addValidator(new Zend_Validate_Db_NoRecordExists('mytablename', 'myemailcolumnname'));
+1 for Db_NoRecordExists - the docs have an example showing exactly what you want to do.
Otherwise, custom validators can be loaded like regular library classes, so try placing it on your include path.
/library/My/Validate/EmailUnique.php
You can also add a new entry to the Zend_Application_Module_Autoloader if you want to keep it in your application folder, as opposed to your library:
// Bootstrap.php
protected function _initAutoloader()
{
$autoloader = new Zend_Application_Module_Autoloader(array(
'namespace' => 'My_',
'basePath' => dirname(__FILE__),
));
$autoloader->addResourceType('validator', 'validators', 'Validate')
return $autoloader;
}
And put the class My_Validate_EmailUnique in:
/application/validators/EmailUnique.php
I've never registered a custom validator as a plugin before, so I can't help you there sorry.