I am new Moodle and working on form data saving. I have created a group of checkbox which will take some input from the users and store it to the database, but unfortunately it is storing only 0/1 in the database. I have no clue where I made the mistake.
This my php file where I added the form field-
class custom_signup_form extends moodleform {
//Add elements to form
public function definition() {
global $CFG;
global $DB;
$mform = $this->_form; // Don't forget the underscore!
//$mform->addElement('text', 'email', get_string('email')); // Add elements to your form.
//$mform->setType('email', PARAM_NOTAGS); // Set type of element.
//$mform->setDefault('email', 'Please enter email'); // Default value.
if($this->content !== Null){
return $this->content;
}
$courses = $DB->get_records('course');
$categories = $DB->get_records('course_categories');
$interestedcourse=array();
foreach($courses as $course){
$coursestring = $course->fullname;
$interestedcourse[] = $mform->createElement('advcheckbox', 'interestedcourse[]','', $coursestring, array('group' => 1), array('',$coursestring));
}
$mform->addGroup($interestedcourse, 'interestedcoursegroup', get_string('interestedcourse', 'assignsubmission_metadata'),array('<br>'), false);
$interestedcategory=array();
foreach($categories as $category){
$categorystring = $category->name;
$interestedcategory[] = $mform->createElement('advcheckbox', 'interestedcategory[]','', $categorystring, array('group' => 1), array('',$categorystring));
}
$mform->addGroup($interestedcategory, 'interestedcategorygroup', get_string('interestedcategory', 'assignsubmission_metadata'),array('<br>'), false);
$this->add_action_buttons();
This is the php file for saving form data-
require_once(__DIR__ . '/../../config.php');
require_once($CFG->dirroot . '/local/custom_signup/classes/form/edit.php');
global $DB;
$PAGE->set_url(new moodle_url('/local/custom_signup/signupform.php'));
$PAGE->set_title(get_string('custom_signup', 'local_custom_signup'));
#custom form for signup
$mform = new custom_signup_form();
if ($mform->is_cancelled()) {
// Go back to manage.php page
redirect($CFG->wwwroot . '/local/custom_signup/manage.php', get_string('cancelled_form', 'local_message'));
}
else if ($fromform = $mform->get_data()) {
var_dump($fromform);
die;
}
echo $OUTPUT->header();
$mform->display();
echo $OUTPUT->render_from_template('local_custom_signup/signupform', $templatecontext);
echo $OUTPUT->footer();
object returned from the form submission-
object(stdClass)#288 (3) { ["interestedcourse"]=> array(1) { [""]=> string(0) "" } ["interestedcategory"]=> array(1) { [""]=> string(0) "" } ["submitbutton"]=> string(12) "Save changes" }
Related
Hai i want to insert my form fields into database and retrive records from database in moodle. how to do that :
Here is my form what i created :
Uplo.php
<?php
require_once('config.php');
require_once("$CFG->libdir/formslib.php");
class uplo extends moodleform {
public function definition() {
global $CFG;
$mform = $this->_form;
$buttonarray=array();
$mform->addElement('text', 'name', get_string('name'));
$mform->setType('name', PARAM_NOTAGS);
$mform->setDefault('name', 'Please enter name');
$mform->addElement('text', 'email', get_string('email'));
$mform->setType('email', PARAM_NOTAGS);
$mform->setDefault('email', 'Please enter email');
$buttonarray[] = &$mform->createElement('submit', 'submitbutton', get_string('savechanges'));
$buttonarray[] = &$mform->createElement('cancel');
$mform->addGroup($buttonarray, 'buttonar', '', array(' '), false);
$mform->closeHeaderBefore('buttonar');
}
function validation($data, $files) {
return array();
}
}
?>
Testing.php:
<?php
define('_DB_HOST_NAME','localhost');
define('_DB_USER_NAME','root');
define('_DB_PASSWORD','');
define('_DB_DATABASE_NAME','moodle_test');
$dbConnection = mysqli_connect(_DB_HOST_NAME,_DB_USER_NAME,_DB_PASSWORD,_DB_DATABASE_NAME);
?>
<?php
require_once('uplo.php');
$mform = new uplo();
$mform->display();
if(isset($_POST['submitbutton'])){
$name = $mform->get_data('name');
$email = $mform->get_data('email');
$table='insert';
$res=insert_record($table, $name,$email, $returnid=true, $primarykey='id') ;
}
?>
This one is i tried. how to do that in a right way
Make sure you require_once(dirname(FILE).'/../../config.php') (adjust the number of '/../' based on the subdirectory your file is in, relative to config.php).
The use the Moodle data manipulation API https://docs.moodle.org/dev/Data_manipulation_API
Im trying to secure my Zend form with crsf token. Allways if I add token element to my form, it always send me back notEmpty error message for token. Im I doing something wrong? Thx
class Application_Form_Test3 extends Zend_Form {
public function init() {
$this->setMethod('post');
//..some elements
$note = new Zend_Form_Element_Textarea('note');
$note->addValidator('stringLength', false, array(2, 50));
$note->setRequired(true);
$note->class = 'form-control';
$note->setLabel('Poznámka:');
$note->setAttrib('placeholder', 'poznamka ke spisu');
$note->setOptions(array('cols' => '20', 'rows' => '4'));
$submit = new Zend_Form_Element_Submit('submit');
$submit->class = 'btn btn-success';
$submit->setValue('odeslat');
$this->addElements(array(
$number,
$year,
$owner,
$note,
$submit,
));
$this->addElement('hash', 'no_csrf_foo', array('salt' => 'unique'));
}
}
Action in controller:
public function findAction() {
$request = $this->getRequest();
$form = new Application_Form_Test3();
if ($this->getRequest()->isPost()) {
if ($form->isValid($request->getPost())) {
var_dump($request->getPost());
} else {
var_dump("ERROR");
}
}
$this->view->form = $form;
}
In my view I render form and dump error messages
...
<?php echo $form->renderForm(false); ?>
...
//render single elements here
//eg. <?php echo $form->note->renderViewHelper(); ?>
...
<?php var_dump($form->getMessages()) ?>
...
After each validation of form, i get array of error messages like that:
array(2) { ["note"]=> array(1) { ["isEmpty"]=> string(36) "Value is required and can't be empty" } ["no_csrf_foo"]=> array(1) { ["isEmpty"]=> string(36) "Value is required and can't be empty" } }
if I fill good values to elements, the last one error is always for token - NotEmpty, so my form is never valid.
Problem solved. I didnt render token element in my View so i added to View:
<?php echo $form->no_csrf_foo->renderViewHelper(); ?>
I am trying to use Symfony forms to handle REST requests.
I was facing issue with binding request data in symfony form. While going through Symfony's code, I found it uses
HttpFoundationRequestHandler->handleRequest
In that, for POST,
if ('' === $name) {
$params = $request->request->all();
$files = $request->files->all();
} elseif ($request->request->has($name) || $request->files->has($name)) {
$default = $form->getConfig()->getCompound() ? array() : null;
$params = $request->request->get($name, $default);
$files = $request->files->get($name, $default);
} else {
// Don't submit the form if it is not present in the request
return;
}
If you see above code, if there is form name in Our form type class, it tries to get values from request as
$request->request->get($name) // $name is form name.
This may work if we render form as HTML but if we post request through REST, it doesnt find data.
To make it work we either have to namespace it like below in request (I haven't tested personally this but have read it somewhere)
{
'form_name': {
'field1' => 'value1'
}
}
Only below requst doesnt't bind data
{
'field1' => 'value1'
}
or we will have to return form name as null from getName from form type so that it use root namespace.
public function getName()
{
return null;
}
If we return null, then it creates other problem, if there are any extra parameters in request other than form fields it gives validation errors.
"This form should not contain extra fields."
Ideally form should just fetch the feild values from request which are configured in form and should ignore any other request parameters which are unknowne to it.
e.g. if this is the form
class SampleFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('field1', 'text', array('constraints' => new NotBlank()))
->add('field2', 'password', array('constraints' => new NotBlank()));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'csrf_protection' => false,
));
}
public function getName()
{
return null;
}
}
but in request if I am sending
{
'field1' => 'value1',
'field2' => 'value2',
'field3' => 'value3'
}
It gives above validation errors. It should ideally simply ignore field3 and fetch feild1 & field2 from request.
If we compare code in NativeRequestHandler & HttpFoundationRequestHandler,
NativeRequestHandler seem to have handled it properly
if ('' === $name) {
$params = $_POST;
$files = $fixedFiles;
} elseif (array_key_exists($name, $_POST) || array_key_exists($name, $fixedFiles)) {
$default = $form->getConfig()->getCompound() ? array() : null;
$params = array_key_exists($name, $_POST) ? $_POST[$name] : $default;
$files = array_key_exists($name, $fixedFiles) ? $fixedFiles[$name] : $default;
} else {
// Don't submit the form if it is not present in the request
return;
}
where as HttpFoundationRequestHandler doesn't
if ('' === $name) {
$params = $request->request->all();
$files = $request->files->all();
} elseif ($request->request->has($name) || $request->files->has($name)) {
$default = $form->getConfig()->getCompound() ? array() : null;
$params = $request->request->get($name, $default);
$files = $request->files->get($name, $default);
} else {
// Don't submit the form if it is not present in the request
return;
}
So either we need to be able to use NativeRequestHandler or we need fix in HttpFoundationRequestHandler ?
I see below works though only in case of content-type text request (doesnt work with application/json),
$form->submit(array('field1' => $request->request->get('field1'), 'field2' => $request->request->get('field2')))
But using $form->handleRequest($request) looks more simpler and abstract.
If there is any other better and simpler solution please do suggest.
I am implementing an updatePasswordAction and its not displaying an error with an invalid current password. I could not implement this with a Zend_Validate class to use with a supplied record->password, so i just validated for now in my controller action and if failed then i add the error message to the form element. this is just before i run $form->isValid. In any case, its working. but when the validation fails, its not displaying the error message on this on the element. any help would be greatly appreciated.
FYI: When I submit a blank current password, it shows the validation
class Admin_Form_UserPassword extends Katana_Form
{
public function init()
{
$element = $this->createElement('hidden', 'id');
$this->addElement($element);
$element = $this->createElement('password','password');
$element->setLabel('Current Password:');
$element->setRequired(true);
$this->addElement($element);
$element = $this->createElement('password','new_password');
$element->setLabel('New Password:');
$element->addValidator('StringLength', false, array(6,24));
$element->setRequired(true);
$element->addValidator('NotEmpty');
$this->addElement($element);
$element = $this->createElement('password','new_password_confirm');
$element->setLabel('Confirm:');
$element->addValidator('StringLength', false, array(6,24));
$element->addValidator('IdenticalField', false, array('new_password', 'Confirm Password'));
$element->setRequired(true);
$this->addElement($element);
$this->addElement('submit', 'submit', array('label' => 'Submit'));
}
}
public function updatePasswordAction()
{
$resourceModel = new Core_Model_Resource_User();
$form = new Admin_Form_UserPassword();
$form->setMethod(Katana_Form::METHOD_POST);
$form->setAction($this->getActionUrl('update-password'));
if($this->getRequest()->isPost()){
$id = $this->getRequest()->getParam('id');
$record = $resourceModel->find($id)->current();
$currPassword = $record->password;
$typedPassword = md5($this->getRequest()->getParam('password'));
if($currPassword !== $typedPassword){
$form->getElement('password')->addError('Current password is incorrect.');
}
if($form->isValid($_POST)){
$data = $form->getValues();
$result = $resourceModel->updatePassword($id, $data['new_password']);
if($result){
$this->redirectSimple('list');
}
}
} else {
$id = $this->getRequest()->getParam('id');
$recordData = array(
'id' => $id
);
$form->populate($recordData);
}
$this->getView()->form = $form;
}
Adding an error to the element doesn't cause the form itself to then be invalid.
There are at least 2 methods I use to get around this:
if($currPassword !== $typedPassword){
$form->getElement('password')->addError('Current password is incorrect.');
$form->markAsError();
}
// or
if ($form->isValid($_POST) && 0 == sizeof($form->getMessages()) {
// form was valid, and no errors were set on elements
}
To clarify, when you add the error to the form ELEMENT, there is an error attached to that element, but Zend_Form::isValid only runs the validators and sets appropriate errors, it doesn't check to see if you had set an error on a particular element.
You can however call $form->getMessages() to get all the error messages attached to the form or its child elements. If this is 0 and you have validated your form, then it means there were no errors. If your form passed isValid but you added an error to an element, it will include the error message you added.
I made it work this way.
Controller:
if ($trial->getKind() != 'debt' && $_POST['kind'] == 'debt')
{
$editForm->getElement('kind')->markAsError();
}
if ($editForm->isValid($_POST)) { ... }
Form:
public function isValid($data)
{
$valid = parent::isValid($data);
if ($this->getElement('kind')->hasErrors()) {
$this->getElement('kind')->addError($this->_translate->translate('You can\'t change trial kind to debt.'));
$valid = false;
}
return $valid;
}
And this comment helped me.
As the title says, I tried calling the receive() function either of Form Element and the Adapter Object(not one after another of course). I printed the returned value - was 1 in both cases - which means receive() returned true.
The file was not found on the server though. I tried setting encrypt type of zend form to multipart/form-data - didn't help.
I'm totally clueless so any info is welcomed.
Calling receive() on transfer adapter: file location and upload name are constants.
$this->uploadName = $uploadName;
$this->upload = new Zend_File_Transfer_Adapter_Http();
$this->upload->setDestination($this->fileLocation);
...
$val = $this->upload->receive();
$quoteName = $this->upload->getFileName($this->uploadName);
$size = $this->upload->getFileSize($this->uploadName);
calling receive on form element:
//form creation - my form extends zend form
$staticForm = Srm_Form::getForm(my form,null,null,
my config);
$staticForm->setEnctype('multipart/form-data');
$staticForm->getElement(my file element name)->setDestination(my dest);
//calling receive
$form = Srm_Form::getForm(my form,null,null,my config);
$form->setEnctype('multipart/form-data');
if(!$form->isValid($_POST)){
print_r($form->getMessages());
}
// echo $form->getElement(my file element)->getValue();
$val = $form->getElement(my file element)->receive();
echo "bbbbbb".$val;
I should add that this code works when it is called after the file element is added to the form manually and not through use of a config file.
Okay, the problem was found -
The destination was not set for the file element (it was set manually for the transfer adapter in other place)when handling the submitted form.
I define a simple form with the Zend_Form_Element_File element
<?php
class Form_UploadForm extends Zend_Form
{
public function __construct($options = null)
{
parent::__construct($options);
$this->setMethod('post');
$this->setAttrib('enctype', 'multipart/form-data');
$decors = array(
array('ViewHelper'),
array('HtmlTag'),//array('tag'=>'table')),
array('Label', array('separator' => ' ')), // those unpredictable newlines
array('Errors', array('separator' => ' ')), // in the render output
);
$file = new Zend_Form_Element_File('file');
$file->setDestination('/a/b/c/upload');
$file->setLabel('Document File Path')
->setRequired(true)
->addValidator('NotEmpty');
$this->addElement($file);
$submit = new Zend_Form_Element_Submit('submit');
$submit->setLabel('Upload File');
$this->addElement($submit);
}
}
?>
My action method in the Controller is
function uploadAction()
{
$this->view->pageTitle = "Zend_Form File Upload Example";
$this->view->bodyCopy = "<p>Please fill out this form.</p>";
$form = new Form_UploadForm();
if ($this->_request->isPost())
{
$formData = $this->_request->getPost();
if ($form->isValid($formData))
{
try
{
$form->file->receive();
}
catch (Zend_File_Transfer_Exception $e)
{
throw new Exception('unable to recieve : '.$e->getMessage());
}
$uploadedData = $form->getValues();
//Zend_Debug::dump($form->file->getFileName(), 'tmp_file');
$this->processFile($form->file->getFileName());
}
else
{
$form->populate($formData);
}
}
$this->view->form = $form;
}
Note - i don't call the Zend_File_Transfer_Adapter_Http directly
The final piece is the view
<?php echo $this->form; ?>