Way to hide some form fields for user xyz - zend-framework

at the moment I'm using this way to get the 'role' of an user in a ZEND_FORM.
$identity = Zend_Auth::getInstance()->getIdentity();
For every form field I check for the role in front of adding the form field like:
if($identity->role=='admin') $form->addElement...
Is there a smarter way to do this? Such as an option for the addElement?
Best Regards
Frgtv10

The way you do it could get messy. Its possible you could use 2 forms here. One main one containing what is common to everyone and one that inherits from the first one and adds fonctionnality for admins. This would be much easier to maintain since you would just instantiate the right form depending on role so one check for role instead of a ton everywhere in your form.
So in your controller you would :
if($identity->role=='admin'){
$form = new Form_WhateverAdmin();
} else {
$form = new Form_WhateverNotAdmin();
}
And where
Form_WhateverNotAdmin extends Zend_Form
and
Form_WhateverAdmin extends Form_WhateverNotAdmin

You also can delete existing elemets:
if($identity->role != 'admin') $form->removeElement('name');

Related

SilverStripe custom form retrieve values for form fields

I have a problem with my front end admin update page. How can I retrieve values from a SiteTree page and populate it into a custom form? Is the setValue($values) function the only way? If yes, which is the best method to get the page variable?
I am using this:
$evens = Versioned::get_by_stage('PageCalendrierEvenement', 'Stage')->byID($evenID);
I'm getting values from an ID of a draft page. After I get variables and values like that:
$field = new TextField('Titre', 'Titre');
$field->setValue($evens->Titre);
or
new TextField('Titre','Titre', $evens->Titre);
Which is the better solution?
The solution is 2 part:
Use TextField::create($constructor, $args) instead of new (optional, but not doing so is a pet hate of mine).
Set all fields at once: http://api.silverstripe.org/3.1/class-Form.html#_loadDataFrom

Symfony 2.x Form Field Name

When I render a form, form Filed Name is given as an array. For example: search[item], search[keyword] etc. where search is name of the form.
I'm not great on working with forms but I think, the name should be rendered as simply, name="item" or name="keyword".
I've looked at all the documentation, customizing form rendering topic etc. but I can't find any way to change the default behaviour of Symfony form to render form filed name from 'search[item]' to 'item'.
This way, when I ask for the POST data, I can ask simply $this->getRequest()->request->get('item'), as I have to deal with lots of individual parameters.
Help would be great i) To figure out how to achieve what I want. ii) to let me know, why the name is rendered this way. is this the good practice?
Rather than accessing parameters from the Request object, you can bind the Request object to the form.
For example, in your controller method that you post your form to:
namespace Acme\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Acme\Form\MyFormClass;
class MyFormController extends Controller
{
receiveFormAction(Request $request)
{
$form = new MyFormClass();
// you can specify that a route only accepts a post
// request in the routing definition
if ($request->isMethod('POST')) {
// this populates the form object with the data
// from the form submission
$form->bind($request);
if ( ! $form->isValid()) {
throw new \Exception('Invalid form');
}
// an array of the data the format you require
$data = $form->getData();
$data['item'];
$data['keyword'];
// etc.
}
}
}
The above is the way you should be handling forms in Symfony 2, and is how you can leverage the power that the forms component gives you, with validation etc.
Symfony supports multiple forms on a page. They might be instances of the same form or have similar field names. Having the fields for each form all together in an array makes this easy to do.

Zend creating forms based on requests within one controller/action

I don't really know how to word the title well, but here's my issue. I decided instead of having 25 controllers to handle pages, I have one PageController with a viewAction that takes in a :page parameter - for example, http://localhost/website/page/about-us would direct to PageController::viewAction() with a parameter of page = about-us. All of the pages are stored in a templates folder, so the viewrenderer is set to render application\templates\default\about-us.phtml.
I did this so I can consolidate and it seemed like a better approach. My question is the following: lets say when the page request is contact-us, I would need a Zend_Form to be used within the contact page. So, I would need a way within PageController::viewAction() to recognize that the page needs to have a form built, build the form, and also upon submission the need to process it (maybe this should be handled in an abstract process method - not sure).
I have no idea how to implement this. I thought maybe I can store a column with the name of a form and a connecting page identifier. Even better, create a one-to-many page to forms, and then in the submission loop through the forms and check if submitted and if so then process it (maybe there is a isSubmitted() method within zend_form. I really don't know how to handle this, and am looking for any help i can get.
Thanks!
Here is something that came to mind that may work or help point you in a direction that works for you.
This may only work well assuming you were to have no more than one form per page, if you need more than one form on a page, you would have to do something beyond this automatic form handling.
Create a standard location for forms that are attached to pages (e.g. application/forms/page). This is where the automatic forms associated with pages will be kept.
In your viewAction, you could take advantage of the autoloader to see if a form for that page exists. For example:
$page = $this->getParam('page');
$page = ucfirst(preg_replace('/-(\w)/ie', "strtoupper('$1')", $page)); // contact-us -> ContactUs
$class = 'Application_Form_Page_' . $page;
// class_exists will invoke the autoloader to map a class to a file
if (class_exists($class)) {
// a form is defined for this page
$form = new $class();
// check if form was posted
if ($this->getRequest()->isPost()) {
if ($form->isValid($this->getRequest()->getPost()) {
// form is valid - determine how to process it
}
}
// assign the form to the view
$this->view->pageForm = $form;
}
All this really leaves out is the action you take to process a specific form. Since the contact form will likely generate an email, and another form may insert data into a database, you will need some sort of callback system or perhaps another class that can be mapped automatically which contains the form processor code.
Anyway something along those lines is what came to mind first, I hope that helps give you some more ideas.

How can I use the sfValidatorEmail validator in Symfony to validate a single email field

I have a form with 2 elements that will be submitted and then update part of a user profile.
I don't want to use the entire generated form and have to remove all the fields except for the two I need. I just want to be able to create a quite simple form to do my update.
Is there a way to utilize Symfony's sfValidatorEmail inside the action on the returned value of an email field?
Since the regex is already written in the validator, I would like to reuse it, but I don't know how to use it in the action after the non-symfony form has been submitted.
Two approaches here - you could construct a simple form anyway extending from sfForm/sfFormSymfony (doesn't have to be ORM-based) that just contains the 2 fields you want. That way you can use the existing validation framework, and then use $myForm->getValues() after everything has been validated to get your values for your profile update.
Alternatively, as you've mentioned, you can use the sfValidatorEmail class in your action like so:
$dirtyValue = "broken.email.address"
$v = new sfValidatorEmail();
try
{
$v->clean($dirtyValue);
}
catch (sfValidatorError $e)
{
// Validation failed
}
The latter approach quickly leads to messy code if you have many values that need cleaning, and it's worth putting the logic back into a form to handle this in the usual manner.
If you're submitting a form with 2 elements, it should be a form on the edit and update end, period. Symfony forms are lightweight, there's no performance reason to not use them. Instead, make a custom form for this purpose:
class ProfileUpdateForm extends ProfileForm
{
public function configure()
{
$this->useFields(array('email', 'other_field'));
}
}

Symfony forms or normal HTML forms

I am using Symfony 1.4 to create project, and i need to create dynamic forms depending upon the question set type coming from database. i have used Symfony forms in rest of my project, but in this case using symfony forms seems to be tough, as i need dynamic form.
can it be safe to use normal HTML forms..in symfony project, or it is advisable to use Symfony forms. so need your help.
You can use html forms, but it would bypass symfony's form validation system.
You can still build dynamic forms by creating and adding input widgets to the current form, or a new form inside an action. You can then echo the form in the template and the dynamically generated fields will be part of the form as well.
If you start with a MyForm.class.php in the lib/forms, make sure to add:
$this->validatorSchema->setOption('allow_extra_fields', true);
Otherwise, you will automatically get validation errors. If you want to add fields to a form in an action you would do something like this:
$this->form = new MyForm();
$widgetSchema = $this->form->getWidgetSchema();
$widgetSchema['add_field'] = new sfWidgetFormInputText();
When you echo your form the 'add_field' input will be added to it.
It would help to have more information about what you're doing, but here's one way in which forms can be dynamic in Symfony. This code creates widgets and validators for a survey dynamically based on the "type" of a question:
class SurveyAnswerForm extends BaseSurveyAnswerForm
{
public function configure()
{
$question = $this->object->Question;
$method = sprintf('createWidgetAndValidatorFor%sInputType', $question->type);
$this->$method($question);
$this->getWidget('value')->setOption('label', $question->question);
$this->getValidator('value')->setOption('required', $question->required);
}
protected function createWidgetAndValidatorForTextFieldInputType(Question $question)
{
$this->setWidget('value', new sfWidgetFormInputText());
$this->setValidator('value', new sfValidatorString());
}
protected function createWidgetAndValidatorForTextAreaInputType(Question $question)
{
$this->setWidget('value', new wfWidgetFormTextareaAutosize());
$this->setValidator('value', new sfValidatorString());
}
//etc. for as many types as you require
}
Note: while this answer is code from one of my projects, it was heavily influenced by this answer over on SymfonyExperts.