CakePHP throws validation error for fields which are not in the request - forms

I understood the CakePHP validation that way: Only fields which are in the request (e.g. ['Post']['NAME'] and ['Post']['STREET']) are validated in the appmodel, even if in the appmodel there are declarations for many more fields.
Now I call this->Post->save($this->request->data) and Cake throws validation errors for fields which are not in the request and now I don´t know what to do.
Controller:
debug of this->request->data:
array(
'Post' => array(
'TYPE' => '1',
'B/S' => 'S',
'LATITUDE' => '50.98549',
'LONGITUDE' => '11.31551',
'CART' => 'jkl',
'MARKET' => 'jk',
'INCOMETYPE' => '1',
'INCOME' => '8',
'DEADLINE' => '1',
'DATE' => '31.08.2014',
'TIME' => '',
'PREFERREDDATES' => 'nach Absprache',
'address' => 'Fuldaer Straße, 99423, Weimar',
'STREET' => 'Fuldaer Straße',
'DELIVERYAREA' => '99423',
'CITY' => 'Weimar',
'TEL' => '1234567654321',
'saveAppendix' => 'edit'
)
)
Controller:
debug of $this->Post-validationErrors:
array(
'ZIPCODE' => array(
(int) 0 => 'Bitte eine gültige Postleitzahl eingeben.'
),
'VEHICLE' => array(
(int) 0 => 'Bitte das Fahrzeug angeben'
),
'SPACE' => array(
(int) 0 => 'Bitte den verfügbaren Platz angeben'
)
)
Controller:
Code with debug-statements:
if (isset($this->request->data['Post']['saveAppendix']) && $this->request->data['Post']['saveAppendix'] == "edit") {
debug($this->request->data);
if ($this->Post->save($this->request->data)) {
$this->Session->setFlash('Dein Inserat wurde erfolgreich bearbeitet.', 'flash_success');
$this->set('action', 'goToIndex');
$this->render('addRedirect', 'ajax');
} else {
debug($this->Post->validationErrors);
...further code...
}
}
EDIT
As requested by burzum, the validation rules:
class Post extends AppModel {
public function beforeValidate(array $options = array()) {
$request = $this->data[$this->alias];
if (isset($request['INCOMETYPE']) && ($request['INCOMETYPE'] == "1" || isset($request['INCOMETYPE']) && $request['INCOMETYPE'] == "2")) {
$this->data[$this->alias]['INCOME'] = preg_replace(
'/^([^,]*).*$/', '$1', $request['INCOME']
);
$this->data[$this->alias]['INCOME'] = preg_replace(
'/\D/', '', $request['INCOME']
);
};
//für validation die schaltungsart-variablen setzen
if (isset($request['DEADLINE']) && $request['DEADLINE'] == "1") {
$this->validator()->remove('TIME');
$date = $request['DATE'];
};
if (isset($request['DEADLINE']) && $request['DEADLINE'] == "2") {
$this->validator()->remove('PREFERREDDATES');
$date = $request['DATE'];
};
if (isset($request['DEADLINE']) && $request['DEADLINE'] == "3") {
$this->validator()->remove('DATE');
$this->validator()->remove('TIME');
};
if (isset($date) && $date <> "") {
//datepicker date in sortierbares datum wandeln: Y M D
$tmpdate = list($day, $month, $year) = explode('.', $date);
$altdate = $year.$month.$day;
$this->data[$this->alias]['ALTDATE'] = $altdate;
};
if (isset($request['INCOMETYPE']) && $request['INCOMETYPE'] == "4") {
$this->validator()->remove('INCOME');
};
if (isset($request['INCOMETYPE']) && $request['INCOMETYPE'] == "5") {
$this->validator()->remove('INCOME');
};
// B/S-Feld füllen mit entsprechendem String
if (isset($request['TYPE']) && isset($request['B/S'])) {
if ($request['TYPE'] == 1 && $request['B/S'] == "S") {
$this->data[$this->alias]['B/S'] = "Suche Kurier";
};
if ($request['TYPE'] == 2 && $request['B/S'] == "S") {
$this->data[$this->alias]['B/S'] = "Suche Bildungsdienstleistung";
};
if ($request['TYPE'] == 3 && $request['B/S'] == "S") {
$this->data[$this->alias]['B/S'] = "Suche Elektronik & Technik";
};
if ($request['TYPE'] == 4 && $request['B/S'] == "S") {
$this->data[$this->alias]['B/S'] = "Suche Freizeit & Sport";
};
if ($request['TYPE'] == 5 && $request['B/S'] == "S") {
$this->data[$this->alias]['B/S'] = "Suche Haushalt und Garten";
};
if ($request['TYPE'] == 6 && $request['B/S'] == "S") {
$this->data[$this->alias]['B/S'] = "Suche Soziales";
};
if ($request['TYPE'] == 1 && $request['B/S'] == "B") {
$this->data[$this->alias]['B/S'] = "Biete Kurier";
};
if ($request['TYPE'] == 2 && $request['B/S'] == "B") {
$this->data[$this->alias]['B/S'] = "Biete Bildungsdienstleistung";
};
if ($request['TYPE'] == 3 && $request['B/S'] == "B") {
$this->data[$this->alias]['B/S'] = "Biete Elektronik & Technik";
};
if ($request['TYPE'] == 4 && $request['B/S'] == "B") {
$this->data[$this->alias]['B/S'] = "Biete Freizeit & Sport";
};
if ($request['TYPE'] == 5 && $request['B/S'] == "B") {
$this->data[$this->alias]['B/S'] = "Biete Haushalt & Garten";
};
if ($request['TYPE'] == 6 && $request['B/S'] == "B") {
$this->data[$this->alias]['B/S'] = "Biete Soziales";
};
};
//inserat-datum darf nicht in vergangenheit liegen
/*if ($request['DATE'] == date("d.m.Y") && $request['TIME'] < date("H:i")) {
unset($this->data[$this->alias]['TIME']);
};*/
return parent::beforeValidate($options);
}
var $validate = array(
'STREET' => array(
'rule-1' => array(
'rule' => 'notEmpty',
'message' => 'Hidden input B/S wurde geändert'
),
'rule-2' => array(
'rule' => '/^[a-z]{1,}$/i',
'message' => 'Hacker kommen hier nicht weit!'
)
),
'STREET' => array(
'rule-1' => array(
'rule' => 'notEmpty',
'message' => 'Bitte eine Straße angeben'
),
'rule-2' => array(
'rule' => '/^[a-z0-9_äÄöÖüÜߧ$%&*\/\d\w\s?!\.:,\'"\(\)=\+-]{1,}$/i',
'message' => 'Hacker kommen hier nicht weit!'
)
),
'HOUSENUMBER' => array(
'rule-1' => array(
'rule' => 'notEmpty',
'message' => 'Bitte eine Hausnummer angeben'
),
'rule-2' => array(
'rule' => '/^[a-z0-9_äÄöÖüÜߧ$%&*\/\d\w\s?!\.:,\'"\(\)=\+-]{1,}$/i',
'message' => 'Hacker kommen hier nicht weit!'
)
),
'ZIPCODE' => array(
'rule-1' => array(
'rule' => array('postal', null, 'de'),
'message' => 'Bitte eine gültige Postleitzahl eingeben.',
'last' => true
),
'rule-2' => array(
'rule' => array('ZipExists'),
'message' => 'Postleitzahl existiert nicht!'
)
),
'CITY' => array(
'rule-1' => array(
'rule' => 'notEmpty',
'message' => 'Bitte eine Stadt angeben'
),
'rule-2' => array(
'rule' => '/^[a-z0-9_äÄöÖüÜߧ$%&*\/\d\w\s?!\.:,\'"\(\)=\+-]{1,}$/i',
'message' => 'Hacker kommen hier nicht weit!'
)
),
'CART' => array(
'rule-1' => array(
'rule' => 'notEmpty',
'message' => 'Bitte etwas eingeben'
),
'rule-2' => array(
'rule' => '/^[a-z0-9_äÄöÖüÜߧ$%&*\/\d\w\s?!\.:,\'"\(\)=\+-]{1,}$/i',
'message' => 'Hacker kommen hier nicht weit!'
)
),
'MISC' => array(
'rule-1' => array(
'allowEmpty' => true
),
'rule-2' => array(
'rule' => '/^[a-z0-9_äÄöÖüÜߧ$%&*\/\d\w\s?!\.:,\'"\(\)=\+-]{1,}$/i',
'message' => 'Hacker kommen hier nicht weit!'
)
),
'MARKET' => array(
'rule-1' => array(
'rule' => 'notEmpty',
'message' => 'Bitte einen Markt angeben'
),
'rule-2' => array(
'rule' => '/^[a-z0-9_äÄöÖüÜߧ$%&*\/\d\w\s?!\.:,\'"\(\)=\+-]{1,}$/i',
'message' => 'Hacker kommen hier nicht weit!'
)
),
'DATE' => array(
'rule' => 'notEmpty',
'required' => 'true',
'message' => 'Bitte das Datum eingeben'
),
'PREFERREDDATES' => array(
'rule' => 'notEmpty',
'required' => 'true',
'message' => 'Bitte die passenden Zeiten eingeben'
),
'DEADLINE' => array(
'rule' => 'notEmpty',
'required' => 'true',
'message' => 'Bitte die Art der Schaltung festlegen'
),
'TIME' => array(
'rule' => 'time',
'required' => 'true',
'message' => 'Bitte die Zeit eingeben'
),
'INCOME' => array(
'rule' => 'notEmpty',
'required' => 'true',
'message' => 'Bitte die Bezahlung eingeben'
),
/*'INCOME' => array(
'rule-1' => array(
'rule' => 'notEmpty',
'message' => 'Bitte die Bezahlung angeben'
),
'rule-2' => array(
'rule' => '/^[a-z0-9_äÄöÖüÜߧ$%&*\/\d\w\s?!\.:,\'"\(\)=\+-]{1,}$/i',
'message' => 'Hacker kommen hier nicht weit!'
)
),*/
'INCOMETYPE' => array(
'rule' => 'notEmpty',
'required' => 'true',
'message' => 'Bitte die Art der Bezahlung festlegen'
),
'VEHICLE' => array(
'rule-1' => array(
'rule' => 'notEmpty',
'message' => 'Bitte das Fahrzeug angeben'
),
'rule-2' => array(
'rule' => '/^[a-z0-9_äÄöÖüÜߧ$%&*\/\d\w\s?!\.:,\'"\(\)=\+-]{1,}$/i',
'message' => 'Hacker kommen hier nicht weit!'
)
),
'DELIVERYAREA' => array(
'rule-1' => array(
'rule' => array('postal', null, 'de'),
'message' => 'Bitte eine gültige Postleitzahl eingeben.',
'last' => true
),
'rule-2' => array(
'rule' => array('ZipExists'),
'message' => 'Postleitzahl existiert nicht!'
)
),
'SPACE' => array(
'rule-1' => array(
'rule' => 'notEmpty',
'message' => 'Bitte den verfügbaren Platz angeben'
),
'rule-2' => array(
'rule' => '/^[a-z0-9_äÄöÖüÜߧ$%&*\/\d\w\s?!\.:,\'"\(\)=\+-]{1,}$/i',
'message' => 'Hacker kommen hier nicht weit!'
)
),
'TEL' => array(
'rule-1' => array(
'rule' => 'notEmpty',
'message' => 'Bitte die Telefonnummer eingeben'
),
'rule-2' => array(
'rule' => '/^[0-9_\/\d\w\s?!\.:,\'"\(\)=\+-]{0,}$/i',
'message' => 'Hacker kommen hier nicht weit!'
)
),
'NAME' => array(
'rule' => '/^[a-z0-9_äÄöÖüÜߧ$%&*\/\d\w\s?!\.:,\'"\(\)=\+-]{0,}$/i',
'message' => 'Hacker kommen hier nicht weit!'
),
'LATITUDE' => array(
'rule-1' => array(
'rule' => 'notEmpty',
'message' => 'Bitte gültige Adresse angeben'
),
'rule-2' => array(
'rule' => 'numeric',
'message' => 'Bitte gültige Adresse angeben'
)
),
'LONGITUDE' => array(
'rule-1' => array(
'rule' => 'notEmpty',
'message' => 'Bitte gültige Adresse angeben'
),
'rule-2' => array(
'rule' => 'numeric',
'message' => 'Bitte gültige Adresse angeben'
)
),
'TYPE' => array(
'rule-1' => array(
'rule' => 'numeric'
),
'rule-2' => array(
'rule' => array('maxLength', 1)
)
)
);
public function ZipExists($zipcode){
$value = array_values($zipcode);
$value = $value[0];
$Zipcode = ClassRegistry::init('Zipcode');
$valid = $Zipcode->find('count', array('conditions'=> array('Zipcode.zipcode' =>$value)));
if ($valid >= 1){
return true;
}
else{
return false;
}
}
};

If i understand you correctly, than you got it all wrong.
cake will validate everything that is in the validation rules, and required. keep in mind that omitting a field, might be a validation error for itself..
edit:
Validation works in the context of the model, not the request. it validates the data that will be saved to the database, against the validation rules.
The meaning is: it will compare the POST data to the rules.
and, if a field is required in the validation-rules, it will throw an error.
Please attach the validation errors

Related

MOODLE ROLES AND CAPABILITIES

I had developed a block in 2.5. I installed the block successfully..and gave permissions settings on front end to view this block only for one role users say 'Manager'. So, Manager/Admin can only view this block and no one else.
But this block is still visible for all. Could you please judge me.. where I went wrong.. Here is my leisure block code
Blocks/block_leisure/block_leisure.php
<?php
class block_leisure extends block_base
{
public function init()
{
global $CFG;
$this->title = get_string('leisure', 'block_leisure');
}
public function get_content()
{
global $COURSE, $DB, $PAGE, $CFG, $USER, $CFG, $SESSION, $OUTPUT;
if ($this->content !== null)
{
return $this->content;
}
$this->content = new stdClass;
$context = $PAGE->context;
$this->content->text = 'This is a leisure block content';
$this->content->footer = 'Footer here...';
return $this->content;
} // Function - get_content().
public function getmodules()
{
return true;
}
}
Blocks/block_leisure/db/access.php
<?php
defined('MOODLE_INTERNAL') || die;
$capabilities = array(
'block/leisure:myaddinstance' => array(
'captype' => 'write',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'user' => CAP_ALLOW
),
'clonepermissionsfrom' => 'moodle/my:manageblocks'
),
'block/leisure:addinstance' => array(
'riskbitmask' => RISK_SPAM | RISK_XSS,
'captype' => 'write',
'contextlevel' => CONTEXT_BLOCK,
'archetypes' => array(
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW
),
'clonepermissionsfrom' => 'moodle/site:manageblocks'
),
'block/leisure:viewpages' => array(
'captype' => 'read',
'contextlevel' => CONTEXT_COURSE,
'legacy' => array(
'guest' => CAP_PREVENT,
'student' => CAP_ALLOW,
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
'coursecreator' => CAP_ALLOW,
'manager' => CAP_ALLOW
)
),
'block/leisure:managepages' => array(
'captype' => 'read',
'contextlevel' => CONTEXT_COURSE,
'legacy' => array(
'guest' => CAP_PREVENT,
'student' => CAP_PREVENT,
'teacher' => CAP_PREVENT,
'editingteacher' => CAP_ALLOW,
'coursecreator' => CAP_ALLOW,
'manager' => CAP_ALLOW
)
)
);
and as usual I have lang folder, version.php and read me file.
You need to do something with the capability you have defined, otherwise it will have no effect.
Check the capability within get_content, then return null if nothing should be displayed.

My ajax Drupal form shows up old values

I have developed ajax drupal and add a form (textfield and button) in it using #ajax key and callback function where I do my process and return my form new element.
So when I starts adding my data form, it works fine for me and form_state['values'] are updated fine.
The problem here is when I reload my form and I add some data, form_state['values'] are not the same in my form fields.
Here is my code:
function my_horoscope_menu() {
$items = array();
$items['admin/horoscopes'] = array(
'title' => 'Horoscopes',
'page callback' => 'drupal_get_form',
'page arguments' => array('my_horoscope_admin_form'),
'access arguments' => array('Administer site configuration '),
//'type' => MENU_LOCAL_TASK,
);
return $items;
}
function my_horoscope_admin_form($form, &$form_state) {
$form['settings']['horoscopes']['add_horoscopes'] = array(
'#type' => 'fieldset',
'#title' => t('Add horoscopes'),
'#collapsible' => TRUE,
'#collaspsed' => TRUE,
);
$form['settings']['horoscopes']['add_horoscopes']['name'] = array(
'#type' => 'textfield',
'#title' => t('Horoscope name'),
'#default_value' => t('Horoscope name'),
'#size' => 20,
'#maxlength' => 60,
'#required' => FALSE,
);
$form['settings']['horoscopes']['add_horoscopes']['beginning_date_rang'] = array(
'#type' => 'date',
'#title' => t('Horoscope beginning date rang'),
'#description' => t('Set the beginning date rang of this horoscope.'),
'#required' => FALSE,
);
$form['settings']['horoscopes']['add_horoscopes']['ending_date_rang'] = array(
'#type' => 'date',
'#title' => t('Horoscope ending date rang'),
'#description' => t('Set the ending date rang of this horoscope.'),
'#required' => FALSE,
);
$form['settings']['horoscopes']['add_horoscopes']['add_button'] = array(
'#type' => 'button',
'#value' => t('Add this horoscope'),
'#submit' => array(''),
'#ajax' => array(
'event' => 'click',
'callback' => 'add_horoscope_ajax_process',
'wrapper' => 'add_horoscope_wrapper',
),
);
$form['settings']['horoscopes']['add_horoscopes']['adding_horoscope_wrapper'] = array(
'#type' => 'markup',
'#prefix' => '<div id="add_horoscope_wrapper">',
'#suffix' => '</div>',
);
return $form;
}
function add_horoscope_ajax_process ($form, &$form_state) {
if (isset($form_state['values'])) {
if (isset($form_state['values']['name']) AND $form_state['values']['name'] != '') {
$name = $form_state['values']['name'];
}
if (isset($form_state['values']['beginning_date_rang']) AND $form_state['values']['beginning_date_rang'] != '') {
$beginning_date_rang = $form_state['values']['beginning_date_rang'];
$beginning_date_rang1 = sprintf("%04d-%02d-%02d", $beginning_date_rang['year'], $beginning_date_rang['month'], $beginning_date_rang['day']);
}
if (isset($form_state['values']['ending_date_rang']) AND $form_state['values']['ending_date_rang'] != '') {
$ending_date_rang = $form_state['values']['ending_date_rang'];
$ending_date_rang1 = sprintf("%04d-%02d-%02d", $ending_date_rang['year'], $ending_date_rang['month'], $ending_date_rang['day']);
}
// Prepare record to add
$record = array(
'h_name' => $name,
'h_date_begin' => $beginning_date_rang1,
'h_date_end' => $ending_date_rang1,
);
// Add the record
$res = drupal_write_record('my_horoscope_structure', $record);
if($res != FALSE) {
drupal_set_message(t('Horoscope #name is inserted successfully!', array('#name' => $name)));
}
}
// return $form
return $form['settings']['horoscopes']['add_horoscopes']['adding_horoscope_wrapper'];
}

Creating drupal form with wrappers

I have created a form in drupal programmatically. How could i wrap each elements of the form with div. Below is my sample code
function emailusers_compose_form($context, $account) {
$form['to'] = array(
'#type' => 'value',
'#value' => $account,
);
$form['message']['subject'] = array(
'#type' => 'textfield',
'#title' => t('Subject'),
'#size' => 50,
'#maxlengh' => 255,
'#description' => t('The subject of the email message.'),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Send Mail'),
);
return $form;
}
Here is the answer
function emailusers_compose_form($context, $account) {
$form['to'] = array(
'#type' => 'value',
'#value' => $account,
);
$form['message']['subject'] = array(
'#type' => 'textfield',
'#title' => t('Subject'),
'#size' => 50,
'#maxlengh' => 255,
'#description' => t('The subject of the email message.'),
'#prefix' => '<div id="elementid">',
'#suffix' => '</div>'
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Send Mail'),
);
return $form;
}

Nesting Fieldsets under Radio or Checkbox items: Zend Framework 2

I would like to create a fieldset under each radio/checkbox item.
e.g
Which animals do you like:
[x] Cats
[Fieldset of cat related questions]
[ ] Dogs
[Fieldset of dog related questions]
...
I can create Fieldsets and Forms with ease, but nesting them under each item is causing me some headaches.
Ultimately I had in mind something like this:
$this->add(array(
'type' => 'Zend\Form\Element\Radio',
'name' => 'profile_type',
'options' => array(
'label' => 'Which animals do you like:',
'label_attributes' => array('class'=>'radio inline'),
'value_options' => array(
'1' =>'cats',
'fieldsets' => array(
array(
'name' => 'sender',
'elements' => array(
array(
'name' => 'name',
'options' => array(
'label' => 'Your name',
),
'type' => 'Text'
),
array(
'type' => 'Zend\Form\Element\Email',
'name' => 'email',
'options' => array(
'label' => 'Your email address',
),
),
),
)),
'2'=>'dogs',
'fieldsets' => array(
array(
'name' => 'sender',
'elements' => array(
array(
'name' => 'name',
'options' => array(
'label' => 'Your name',
),
'type' => 'Text'
),
array(
'type' => 'Zend\Form\Element\Email',
'name' => 'email',
'options' => array(
'label' => 'Your email address',
),
),
),
))
),
),
'attributes' => array(
'value' => '1' //set checked to '1'
)
));
Ok I managed to get round this issue using a bit of a hack, but it works.
TestForm.php (note the additional attributes in the elements ('parent' and 'childOf')
class TestForm extends Form
{
public $user_agent;
public $user_ip;
public function __construct($name = null)
{
// we want to ignore the name passed
parent::__construct('profile');
$this->setAttributes(array(
'method'=>'post',
'class'=>'form-horizontal',
));
$this->add(array(
'type' => 'Zend\Form\Element\Radio',
'name' => 'profile_type',
'options' => array(
'label' => 'Which animals do you like:',
'label_attributes' => array('class'=>'radio inline'),
'value_options' => array(
array('label' =>'cats', 'value'=>1, 'parent'=>'cat'),
array('label'=>'dogs', 'value'=>2, 'parent'=>'dog'),
),
),
'attributes' => array(
'value' => '1' //set checked to '1'
)
));
$this->add(array(
'type' => 'Text',
'name' => 'name',
'attributes' => array(
'childOf' => 'cat',
),
'options' => array(
'label' => 'Your name',
),
));
$this->add(array(
'type' => 'Zend\Form\Element\Email',
'name' => 'email',
'attributes' => array(
'childOf' => 'dog',
),
'options' => array(
'label' => 'Your email address',
),
));
}
}
Then extended Zend\Form\View\Helper\FormMultiCheckbox and overwrote the RenderOptions Method (look out for the new optionSpec 'parent') this basically creates a tag e.g.{#cat#} after the parent element:
protected function renderOptions(MultiCheckboxElement $element, array $options, array $selectedOptions,
array $attributes)
{
$escapeHtmlHelper = $this->getEscapeHtmlHelper();
$labelHelper = $this->getLabelHelper();
$labelClose = $labelHelper->closeTag();
$labelPosition = $this->getLabelPosition();
$globalLabelAttributes = $element->getLabelAttributes();
$closingBracket = $this->getInlineClosingBracket();
if (empty($globalLabelAttributes)) {
$globalLabelAttributes = $this->labelAttributes;
}
$combinedMarkup = array();
$count = 0;
foreach ($options as $key => $optionSpec) {
$count++;
if ($count > 1 && array_key_exists('id', $attributes)) {
unset($attributes['id']);
}
$value = '';
$parent = '';
$label = '';
$inputAttributes = $attributes;
$labelAttributes = $globalLabelAttributes;
$selected = isset($inputAttributes['selected']) && $inputAttributes['type'] != 'radio' && $inputAttributes['selected'] != false ? true : false;
$disabled = isset($inputAttributes['disabled']) && $inputAttributes['disabled'] != false ? true : false;
if (is_scalar($optionSpec)) {
$optionSpec = array(
'label' => $optionSpec,
'value' => $key
);
}
if (isset($optionSpec['value'])) {
$value = $optionSpec['value'];
}
if (isset($optionSpec['parent'])) {
$parent = $optionSpec['parent'];
}
if (isset($optionSpec['label'])) {
$label = $optionSpec['label'];
}
if (isset($optionSpec['selected'])) {
$selected = $optionSpec['selected'];
}
if (isset($optionSpec['disabled'])) {
$disabled = $optionSpec['disabled'];
}
if (isset($optionSpec['label_attributes'])) {
$labelAttributes = (isset($labelAttributes))
? array_merge($labelAttributes, $optionSpec['label_attributes'])
: $optionSpec['label_attributes'];
}
if (isset($optionSpec['attributes'])) {
$inputAttributes = array_merge($inputAttributes, $optionSpec['attributes']);
}
if (in_array($value, $selectedOptions)) {
$selected = true;
}
$inputAttributes['value'] = $value;
$inputAttributes['checked'] = $selected;
$inputAttributes['disabled'] = $disabled;
$input = sprintf(
'<input %s%s',
$this->createAttributesString($inputAttributes),
$closingBracket
);
if (null !== ($translator = $this->getTranslator())) {
$label = $translator->translate(
$label, $this->getTranslatorTextDomain()
);
}
$tag = ($parent != '')? "{#*".$parent."*#}": "";
$label = $escapeHtmlHelper($label);
$labelOpen = $labelHelper->openTag($labelAttributes);
$template = $labelOpen . '%s%s%s' . $labelClose;
switch ($labelPosition) {
case self::LABEL_PREPEND:
$markup = sprintf($template, $label, $input, $tag);
break;
case self::LABEL_APPEND:
default:
$markup = sprintf($template, $input, $label, $tag);
break;
}
$combinedMarkup[] = $markup;
}
return implode($this->getSeparator(), $combinedMarkup);
}
Extended and overwrote Zend\Form\View\Helper\FormRow render method this is the same except for the return of the method:
..... more code .....
$child_of = $element->getAttribute('childOf');
if($child_of != '')
{
return array($child_of => sprintf('<div class="control-group%s">%s</div>', $status_type, $markup));
}
return sprintf('<div class="control-group%s">%s</div>', $status_type, $markup);
And finally extended and overwrote the render method of Zend\Form\View\Helper\FormCollection and changed the element foreach loop, basically overwriting the tags if the element is an array, and therefore has a ChildOf tag. Then a clean up of tags:
foreach ($element->getIterator() as $elementOrFieldset) {
if ($elementOrFieldset instanceof FieldsetInterface) {
$markup .= $fieldsetHelper($elementOrFieldset);
} elseif ($elementOrFieldset instanceof ElementInterface) {
$elementString = $elementHelper($elementOrFieldset);
if(!is_array($elementString))
{
$markup .= $elementString;
}
// is child of another element
else
{
foreach($elementString as $key => $value)
{
$match = "{#*".$key."*#}";
$replacement = $value.$match;
$markup = str_replace($match, $replacement, $markup);
}
}
}
}
$pattern = '/[{#\*]+[a-z0-0A-Z]*[\*#}]+/';
$markup = preg_replace($pattern, '', $markup);
This (although ugly) produces the desired results, also because we are just playing with the rendering, validation and form creation are untouched.
All the best,
Aborgrove

Drupal7 Custom Form Submit Handler Not Working

I am writing a custom module which has a form but the submit handler is just not working, the form just submits back to itself?
Any help much appreciated.
I have an add guest custom form and that is working fine.
The URL on my site is: /user/booking_editguest/LBD0413/1
The code is below:
function uUserBookings_editGuestForm($form, &$form_state, $ManageBooking) {
//var_dump($ManageBooking);
$guestSeq = arg(3);
$masterEventCode = $ManageBooking->Contact->{'MasterEventCode'};
$eventCode = $ManageBooking->Contact->{'EventCode'};
$attendeeContact = $ManageBooking->Contact->{'AttendeeContact'};
global $user;
$account = user_load($user->uid);
$memberCode = $account->name;
// booking
$form['booking'] = array(
//'#type' => 'vertical_tabs',
);
foreach($ManageBooking->guests as $Guest)
{
if ($guestSeq == $Guest->{'GuestSeq'} )
{
$form['guest_form']['FirstName'] = array(
'#required' => TRUE,
'#type' => 'textfield',
'#title' => t('GUEST FIRST NAME'),
'#default_value' => $Guest->{'Guest FirstName'}
);
$form['guest_form']['Surname'] = array(
'#required' => TRUE,
'#type' => 'textfield',
'#title' => t('GUEST LAST NAME'),
'#default_value' => $Guest->{'Guest Surname'}
);
$form['guest_form']['DietaryRequirements'] = array(
'#required' => FALSE,
'#type' => 'textfield',
'#title' => t('SPECIAL DIETARY REQUIREMENTS'),
'#default_value' => $Guest->{'Dietary Requirements'}
);
$form['guest_form']['CompanyName'] = array(
'#required' => TRUE,
'#type' => 'textfield',
'#title' => t('GUEST COMPANY NAME'),
'#default_value' => $Guest->{'Company Name'}
);
$form['guest_form']['Position'] = array(
'#required' => TRUE,
'#type' => 'textfield',
'#title' => t('GUEST POSITION'),
'#default_value' => $Guest->{'Attendee Position'}
);
$form['guest_form']['Email'] = array(
'#required' => TRUE,
'#type' => 'textfield',
'#title' => t('GUEST EMAIL'),
'#default_value' => $Guest->{'Guest Email'}
);
//MasterEventCode
$form['guest_form']['masterEventCode'] = array(
'#required' => TRUE,
'#type' => 'hidden',
'#default_value' => $masterEventCode
);
//EventCode
$form['guest_form']['eventCode'] = array(
'#required' => TRUE,
'#type' => 'hidden',
'#default_value' => $eventCode
);
//Member_code
$form['guest_form']['memberCode'] = array(
'#required' => TRUE,
'#type' => 'hidden',
'#default_value' => $memberCode
);
//Attendee_Contact
$form['guest_form']['Attendee_Contact'] = array(
'#required' => TRUE,
'#type' => 'hidden',
'#default_value' => $attendeeContact
);
//GuestSeq
$form['guest_form']['GuestSeq'] = array(
'#required' => TRUE,
'#type' => 'hidden',
'#default_value' => $Guest->{'GuestSeq'}
);
//GuestID
$form['guest_form']['GuestID'] = array(
'#required' => TRUE,
'#type' => 'hidden',
'#default_value' => $Guest->{'Guest Contact Counter'}
);
//EventNameDetailsID uniqueidentifier
$form['guest_form']['EventNameDetailsID'] = array(
'#required' => TRUE,
'#type' => 'hidden',
'#default_value' => $Guest->{'EventNameDetailsID'}
);
//ID uniqueidentifier
$form['guest_form']['ID'] = array(
'#required' => TRUE,
'#type' => 'hidden',
'#default_value' => $Guest->{'ID'}
);
$form['guest_form']['Submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
'#submit' => array('tmsUserBookings_editGuestForm_submit')
);
}
}
return $form;}
function userBookings_editGuestForm_validate($form, &$form_state) {
// Validation logic.
// Don't custom-validate if previous validation errors (still) exist
if (form_get_errors()) return;
// .. Otherwise, process custom form validation goes here }
function userBookings_editGuestForm_submit($form, &$form_state) {
//Get Form variables
$guestFirstname = $form_state['input']['FirstName'];
$guestSurname = $form_state['input']['Surname'];
$guestDietary = $form_state['input']['DietaryRequirements'];
$guestCompany = $form_state['input']['CompanyName'];
$guestPosition = $form_state['input']['Position'];
$guestEmail = $form_state['input']['Email'];
$memberCode = $form_state['input']['Member_code'];
$masterEventCode = $form_state['input']['MasterEventCode'];
$eventCode = $form_state['input']['EventCode'];
$bookerContactCounter = $form_state['input']['Attendee_Contact'];
$guestSeq = $form_state['input']['GuestSeq'];
$guestTitle = $form_state['input']['Title'];
$guestContactCounter = $form_state['input']['GuestID'];
$eventNameDetailsId = $form_state['input']['EventNameDetailsID'];
$id = $form_state['input']['ID'];
//Redirect back to the Booking.
$form_state['redirect'] = '/user/booking_guestupdated';}
For those using hidden textfields and have them set as required, make sure you check the values being entered!