I want to create a custom validator in Zend.
for e.g. my code:
$txt_state = new Zend_Form_Element_Text('state');
$txt_state->setLabel('State');
$txt_prop = new Zend_Form_Element_Text('pin');
$txt_prop->setLabel('Property');
Now I want that the form must be submitted only if at least one of these 2 elements are not empty.
you can do it dirty way like this:
if ($this->getRequest()->isPost()) {
if (is_empty($form->getElement('state')->getValue())) {
$form->getElement('pin')->setRequired();
}
if (is_empty($form->getElement('pin')->getValue())) {
$form->getElement('state')->setRequired();
}
if ($form->isValid()) {
//redirect to success page
} else {
//do nothing, display errors messages, refill form
}
}
or cleaner with extended Zend_Form_Element.
Here you can add custom validation like this in controller.
$state = "YOUR VALUE";
$form->state->setValue($state);
$form->getElement('state')->setRequired();
$form->getElement('state')->addValidator( 'Alpha', true, array( 'messages' => array( 'notAlpha' => "Please enter alphabetic character only in state name.
") ));
$mArr = array('state'=>$state);
if( !$form->isValid($mArr) ){
$myErrorArray[] = $form->getMessages();
$is_error = 1;
}
Here $myErrorArray have all error message that you apply on element state.
Related
I have a form validation that, so far, returns an error message if either of two defined words/phrase are present in the input area:
add_filter('gform_validation_3', 'custom_validation');
function custom_validation($validation_result){
$form = $validation_result["form"];
foreach($form['fields'] as &$field){
/* Check that the value of the field that was submitted. e.g. the name="input_1" that is generated by Gravity Forms */
if($_POST['input_4'] == "Your First Name" || "SEO"){
// set the form validation to false
$validation_result["is_valid"] = false;
//The field ID can be found by hovering over the field in the backend of WordPress
if($field["id"] == "4"){
$field["failed_validation"] = true;
$field["validation_message"] = "This field needs to be your actual first name.";
}
}
}
//Assign modified $form object back to the validation result
$validation_result["form"] = $form;
return $validation_result;
}
I'm not sure now how to create an array to define the words that are not allowed, so that I can have a much longer list?
First of all, the first "if" is incorrect, I think you meant:
if($_POST['input_4'] == "Your First Name" || $_POST['input_4'] =="SEO")
A good way to achieve what you long is:
$forbidden_words = ["Your First Name", "SEO"];
$is_valid = !in_array($_POST['input_4'], $forbidden_words); //false if the word is in array
After that you may go:
if($is_valid)
//do magic
You can use function in_array()
<?php
$blacklisted = ['some', 'ugly', 'bad', 'words'];
if(in_array('ugly', $blacklisted)){
echo('bad word spotted');
}
demo: https://repl.it/#kallefrombosnia/DarkvioletDeepPolygons
I have a simple dropdown field with 2 values and a dependent dropdown field:
public function areaForm() {
$datasource = function($val) {
if ($val =='yes') {
$areas = DataObject::get('Area', 'ParentID = 0');
return $areas->map('ID', 'Name');
}
if ($val == 'no') {
return false;
}
};
$fields = new FieldList(
TextField::create('Name', 'Area Name:'),
$dropField = DropdownField::create('isChild', 'Is this a sub Area?', array('yes' => 'Yes', 'no'=>'No' ))
->setEmptyString('Select one'),
DependentDropdownField::create('ParentSelect', 'Select Parent Area:', $datasource)
->setDepends($dropField)
->setEmptyString('Select one')
);
return new Form($this, __FUNCTION__, $fields, FieldList::create(new FormAction('doSaveArea', 'Save area')));
}
public function doSaveArea($data, $form) {
var_dump($data);
exit;
$name = $data['Name'];
$isChild = $data['isChild'];
if ($isChild === 'no') {
$area = new Area();
$area->Name = $name;
$area->ParentID = 0;
$area->write();
}
elseif ($isChild === 'yes') {
$area = new Area();
$area->Name = $name;
$area->ParentID = $data['ParentSelect'];
$area->write();
}
$this->redirectBack();
}
When ever I try to save my object by submitting the form, it gives me the same message:
Please select a value within the list provided. x is not a valid option
The values are being populated correctly. I can see them in the browser by inspecting the element. Yet if I select ID 1 for example it says "1 is not a valid option" etc for each Area object. It gets stuck at validation, doesn't even go to the action. I've done similar things in other parts of the site/other sites and they work fine.
Why is this validation incorrectly blocking the form submission and how do we fix this?
Seems like you just need to create an Array of your Map object.
if ($val =='yes') {
$areas = Area::get()->filter('ParentID', '0');
return $areas->map('ID', 'Name')->toArray();
}
Normally you could just use the Map object as the source for a DropdownField. But I think the DependentDropdownField has a little trouble with the Map object.
I am just completely stumped at this and so is my buddy who created this template system.
I have a registration page that sends the user an email with a link to the account activation page in which they must fill out there password to confirm. Inside the link is their user_id and a random string for a registration key.
Here's what I normal url would look like :
kansasoutlawwrestling.com/kowmanager/activate/10000/da54d6fad5fa5fadf
What I want to do is if either of these statements are true then it shows my 404 error page:
Doesn't have the user_id in the url
Doesn't have the registration key in the url
Doesn't have either the two parameters in the url
Activate Controller:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Activate extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->library('kow_auth');
}
public function index($param1 = NULL, $param2 = NULL)
{
//Config Defaults Start
$msgBoxMsgs = array();//msgType = dl, info, warn, note, msg
$cssPageAddons = '';//If you have extra CSS for this view append it here
$jsPageAddons = '<script src="http://www.kansasoutlawwrestling.com/kowmanager/assets/js/activatevalidate.js"></script>';//If you have extra JS for this view append it here
$metaAddons = '';//Sometimes there is a need for additional Meta Data such in the case of Facebook addon's
$siteTitle = '';//alter only if you need something other than the default for this view.
//Config Defaults Start
//examples of how to use the message box system (css not included).
//$msgBoxMsgs[] = array('msgType' => 'dl', 'theMsg' => 'This is a Blank Message Box...');
/**********************************************************Your Coding Logic Here, Start*/
$x = 0;
if(($param1 !== NULL)&&($param2 !== NULL))
{
//params not null yay..
if((isset($param1))&&((trim($param1) !== '')||(!empty($param1))))
{
if(!is_numeric($param1))
{
$x++;
}
}
if((isset($param2))&&((trim($param2) !== '')||(!empty($param2))))
{
if(!is_string($param2))
{
$x++;
}
}
}
else
{
$x++;
}
if($x !== 0)
{
$bodyContent = "error_page";
}
else
{
$bodyContent = "activate_form";
}
$bodyType = "full";//type of template
/***********************************************************Your Coding Logic Here, End*/
//Double checks if any default variables have been changed, Start.
//If msgBoxMsgs array has anything in it, if so displays it in view, else does nothing.
if(count($msgBoxMsgs) !== 0)
{
$msgBoxes = $this->msgboxes->buildMsgBoxesOutput(array('display' => 'show', 'msgs' =>$msgBoxMsgs));
}
else
{
$msgBoxes = array('display' => 'none');
}
if($siteTitle == '')
{
$siteTitle = $this->metatags->SiteTitle(); //reads
}
//Double checks if any default variables have been changed, End.
$this->data['msgBoxes'] = $msgBoxes;
$this->data['cssPageAddons'] = $cssPageAddons;//if there is any additional CSS to add from above Variable this will send it to the view.
$this->data['jsPageAddons'] = $jsPageAddons;//if there is any addictional JS to add from the above variable this will send it to the view.
$this->data['metaAddons'] = $metaAddons;//if there is any addictional meta data to add from the above variable this will send it to the view.
$this->data['pageMetaTags'] = $this->metatags->MetaTags();//defaults can be changed via models/metatags.php
$this->data['siteTitle'] = $siteTitle;//defaults can be changed via models/metatags.php
$this->data['bodyType'] = $bodyType;
$this->data['bodyContent'] = $bodyContent;
$this->load->view('usermanagement/index', $this->data);
}
function activate_submit()
{
$this->form_validation->set_rules('password', 'Password', 'trim|required|xss_clean|min_length[6]|max_length[12]|alpha_numeric');
$user_id = $this->uri->segment(3);
$registration_key = $this->uri->segment(4);
if (($registration_key == '') OR ($user_id == ''))
{
echo json_encode(array('error' => 'yes', 'message' => 'URL was not complete!'));
}
else
{
if (!$this->form_validation->run())
{
echo json_encode(array('error' => 'yes', 'message' => 'There was a problem submitting the form! Please refresh the window and try again!'));
}
else
{
if ($this->kow_auth->activate_user($user_id, $registration_key, $this->input->post('password')))
{
echo json_encode(array('sucess' => 'yes', 'message' => 'Your account has been successfully activated!'));
}
else
{
echo json_encode(array('error' => 'yes', 'message' => 'The activation code you entered is incorrect or expired!'));
}
}
}
}
}
/* End of file activate.php */
/* Location: ./application/controllers/activate.php */
Routes:
$route['activate/:num/:any'] = 'activate/index/$1/$2';
$route['404_override'] = 'error';
Here's what I'm getting for each of those instances:
kansasoutlawwrestling.com/kowmanager/activate - correct
kansasoutlawwrestling.com/kowmanager/activate/10000/ - correct
kansasoutlawwrestling.com/kowmanager/activate/10000/271cce33ab11ced5fd10aeca41323a3c - incorrect should be showing the activate form
EDIT : Anybody have any ideas because it just seems like nothing is working.
I'll start by simplifying a bit the params checking:
$this->error = FALSE;
if(NULL != $param1 AND NULL != $param2)
{
if(!is_numeric($param1) OR (string)trim($param2)!= '')
{
$this->error = TRUE;
}
}
else
{
$this->error = TRUE;
}
$this->data['bodyContent'] = $this->error? 'error_page' : 'activate_form';
It's late here so I might messed up something, but basically:
if both params are null, set $error to TRUE (they don't have to be null);
if at least one isn't null:
- if param1 isn't numeric (userid) or
- if param2 isn't a string (nor even an empty one), $error is again TRUE.
In the end, if error is FALSE (as initialized), we pass the "activate_form" value to the view, else (i.e. if any of the above condition caused the error to be set to TRUE), we pass the "error_page" value.
Also, as per documentation, custom routes should go after fixed ones:
$route['404_override'] = 'error';
$route['activate/(:num)/(:any)'] = 'activate/index/$1/$2';
Out of curiosity...what happens if you remove the following line?
if(!is_string($param2))
And you just have:
if((isset($param2))&&((trim($param2) !== '')||(!empty($param2))))
{
$x++;
}
You dont need to create a new controlller/module for account activation, simply add a new method inside your existing auth controller/module.
IF you setup a route with conditions and they fail, your shown an error or 404.
class Auth extends CI_Controller
{
public function __construct(){parent::__construct();}
/**
* Activate user account
* $route['activate/(:num)/(:any)'] = 'auth/activate/$1/$2';
*/
public function activate($uid, $code)
{
//if need be, double check
if(!$uid OR !$code){show_404();} //BOTH need to exists
//if $route['activate/(:num)/(:any)'] = 'auth/activate/$1/$2'; FAILS CI will show error or 404
//grab $code and $uid and seek a match from DB, if failure do your own errors.
}
}
I would suggest removing the user id from the uri segment and make the activation code a UNIQUE db constraint so you only have to query for that.
Take a look at Tank Auth
It is a CI library that already does this, but with a key difference, you don't want to pass more than you have to. So just generate a HASH (encrypted for instance), that lets you find the userid & activate at the same time.
It is less checking and less issues with copy & pasting URL. Also eliminates having to do all this extra checking of ID validity + hash validity.
But as I said, look at the tank auth code, and pull out what you need for the activation part, it's fairly straight forward, and already for CI.
I have following action to display a form
public function showformAction() {
$this->view->form = new Form_MyForm();
$this->view->form->setAction( 'submitform' );
}
above action shows a form successfully with only one textarea and submit button.
And I am using following action to submit above form:
public function submitformAction() {
$form = new Form_MyForm();
$request = $this->getRequest();
if ( $request->isPost() ) {
$values = $form->getValues();
print_r($values);die();
} else {
echo 'Invalid Form';
}
}
Above action is showing following output:
Array ( [myfield] => )
It means it is not posting values correctly and always shows empty array or I am not getting posted values correctly. How to post values to submitformAction().
Thanks
I think you must use the isValid() before accessing the values of a submitted form, because it's right there that the values are checked and valorized
public function submitformAction() {
$form = new Form_MyForm();
$request = $this->getRequest();
if ( $request->isPost() ) {
if ($form->isValid( $request->getPost() )) {
$values = $form->getValues();
print_r($values);die();
}
} else {
echo 'Invalid Form';
}
}
In complement to #VAShhh response. With some more details:
You need to do two things, populate your form fields with the POSTed data and applying security filters and validators to that data. Zend_Form provides one simple function which perform both, it's isValid($data).
So you should:
build your form
test you are in a POST request
populate & filter & validate this data
either handle the fact in can be invalid and re-show the form wich is now
decorated with Errors OR retrieve valid data from the form
So you should get:
function submitformAction() {
$form = new Form_MyForm();
$request = $this->getRequest();
if ( $request->isPost() ) {
if (!$form->isValid($request->getPost())) {
$this->view->form = $form;
// here maybe you could connect to the same view script as your first action
// another solution is to use only one action for showform & submitform actions
// and detect the fact it's not a post to do the showform part
} else {
// values are secure if filters are on each form element
// and they are valid if all validators are set
$securizedvalues = $form->getValues();
// temporary debug
print_r($securizedvalues);die();
// here the nice thing to do at the end, after the job is quite
// certainly a REDIRECT with a code 303 (Redirect after POSt)
$redirector = $this->_helper->getHelper('Redirector');
$redirector->setCode(303)
->setExit(true)
->setGotoSimple('newaction','acontroller','amodule');
$redirector->redirectAndExit();
} else {
throw new Zend_Exception('Invalid Method');
}
}
And as said in the code re-showing the form you shoudl really try to use the same function for both showing and handling POST as a lot of steps are really the same:
building the form
showing it in the view in case of errors
By detecting the request is a POST you can detect you are in the POST handling case.
I am using gallery3 php software, which is based on the kohana framework. Does anybody know how to add a checkbox to the album information form?
I tried like this:
static function get_edit_form($parent) {
$form = new Forge(
"albums/update/{$parent->id}", "", "post", array("id" => "g-edit-album-form"));
$form->hidden("from_id")->value($parent->id);
$group = $form->group("edit_item")->label(t("Edit Album"));
$group->input("title")->label(t("Title"))->value($parent->title)
->error_messages("required", t("You must provide a title"))
->error_messages("length", t("Your title is too long"));
$group->textarea("description")->label(t("Description"))->value($parent->description);
/* MPK: information fields for albums */
$group->textarea("information")->label(t("Information text"))->value($parent->information);
$group->checkbox("info")->label(t("Informational"))->value($parent->info);
if ($parent->id != 1) {
$group->input("name")->label(t("Directory Name"))->value($parent->name)
->error_messages("conflict", t("There is already a movie, photo or album with this name"))
->error_messages("no_slashes", t("The directory name can't contain a \"/\""))
->error_messages("no_trailing_period", t("The directory name can't end in \".\""))
->error_messages("required", t("You must provide a directory name"))
->error_messages("length", t("Your directory name is too long"));
$group->input("slug")->label(t("Internet Address"))->value($parent->slug)
->error_messages(
"conflict", t("There is already a movie, photo or album with this internet address"))
->error_messages(
"not_url_safe",
t("The internet address should contain only letters, numbers, hyphens and underscores"))
->error_messages("required", t("You must provide an internet address"))
->error_messages("length", t("Your internet address is too long"));
} else {
$group->hidden("name")->value($parent->name);
$group->hidden("slug")->value($parent->slug);
}
AND
public function update($album_id) {
access::verify_csrf();
$album = ORM::factory("item", $album_id);
access::required("view", $album);
access::required("edit", $album);
$form = album::get_edit_form($album);
try {
$valid = $form->validate();
$album->title = $form->edit_item->title->value;
$album->description = $form->edit_item->description->value;
/* MPK: information fields for albums */
$album->information = $form->edit_item->information->value;
$album->info = $form->edit_item->info->value;
$album->sort_column = $form->edit_item->sort_order->column->value;
$album->sort_order = $form->edit_item->sort_order->direction->value;
if (array_key_exists("name", $form->edit_item->inputs)) {
$album->name = $form->edit_item->inputs["name"]->value;
}
$album->slug = $form->edit_item->slug->value;
$album->validate();
} catch (ORM_Validation_Exception $e) {
// Translate ORM validation errors into form error messages
foreach ($e->validation->errors() as $key => $error) {
$form->edit_item->inputs[$key]->add_error($error, 1);
}
$valid = false;
}
if ($valid) {
$album->save();
module::event("item_edit_form_completed", $album, $form);
log::success("content", "Updated album", "view");
message::success(t("Saved album %album_title",
array("album_title" => html::purify($album->title))));
if ($form->from_id->value == $album->id) {
// Use the new url; it might have changed.
json::reply(array("result" => "success", "location" => $album->url()));
} else {
// Stay on the same page
json::reply(array("result" => "success"));
}
} else {
json::reply(array("result" => "error", "html" => (string)$form));
}
}
The field does show up on the form, but the field value does not get saved to the DB. In the DB it is a tinyint(1).
Kohana uses models to save data in the database. Because of $album->save(); you should have a model somewhere in the application, depending of the version of Kohana.
Go to /modules/gallery/models. There is a file called item.php. This is the model used by the application to save/load/create items (and also albums). At line 447 there is the command which actually saves the contents of the album in the database. You need to change that line in order to save the value of the checkbox.
Solved. The problem was that you have to use 'checked' field of the check-box and not the value field in the assignment.
In album.php
$group->checkbox("info")->label(t("Informational"))->value($parent->info)->checked($parent->info);
In albums.php:
$album->info = $form->edit_item->info->checked;
The field in the DB is also named 'info' and can be a bit.