cakephp validation response returning data to controller - validation

Hi i have made a custom validation in the model. How can i access the result($visitor) from this in the controller?
model:
<?php
class Visitors extends AppModel
{
var $name = 'Visitors';
var $validate = array(
'xxx' => array(
'rule' => array('checkxxx'),
'message' => 'yyy.'
)
);
function checkIxxx($check){
$visitor = $this->find('first', array('conditions' => $check));
return $visitor;
}
}
?>
in my controller i want this:
function start() {
$this->Visitors->set($this->data);
if($this->Visitors->validates())
{
if($this->Visitors->xxx->type == 'value') //this is a value from the $visitor array in the model**
{
//do something
}
}
is this possible?

Updated to be a relevant answer, apologies.
//Model
var myField = 'invalid';
function myValidation($var){
if($var === true){
// Passed your validation test
$this->myField = 'valid';
}else{
$this->myField = 'invalid';
}
}
// Controller
$this->Model->set($this->data);
$this->Model->validates($this->data);
if($this->Model->myfield == 'valid'){
// Field has passed validation
}
You will want to use
$this->Model->invalidFields()

PS: You dont follow cake conventions
the model should be "Visitor" (singular)

Related

CodeIgniter 3 code does not add data to database into 2 different tables (user_info & phone_info)

The problem is when I entered a new name no data is added. A similar thing happen when I entered an already existing name. Still, no data is added to the database. I am still new to CodeIgniter and not entirely sure my query builder inside the model is correct or not.
In the Model, I check if the name already exists insert data only into the phone_info table. IF name does not exist I insert data into user_info and phone_info.
Controller:
public function addData()
{
$name = $this->input->post('name');
$contact_num = $this->input->post('contact_num');
if($name == '') {
$result['message'] = "Please enter contact name";
} elseif($contact_num == '') {
$result['message'] = "Please enter contact number";
} else {
$result['message'] = "";
$data = array(
'name' => $name,
'contact_num' => $contact_num
);
$this->m->addData($data);
}
echo json_encode($result);
}
Model:
public function addData($data)
{
if(mysqli_num_rows($data['name']) > 0) {
$user = $this->db->get_where('user_info', array('name' => $data['name']))->result_array();
$user_id = $user['id'];
$phone_info = array(
'contact_num' => $data['contact_num'],
'user_id' => $user_id
);
$this->db->insert('phone_info',$phone_info);
} else {
$user_info = array(
'name' => $data['name']
);
$this->db->insert('user_info', $user_info);
$user = $this->db->get_where('user_info', array('name' => $data['name']))->result_array();
$user_id = $user['id'];
$phone_info = array(
'contact_num' => $data['contact_num'],
'user_id' => $user_id
);
$this->db->insert('phone_info', $phone_info);
}
}
DB-Table user_info:
DB-Table phone_info:
Extend and change your model to this:
public function findByTitle($name)
{
$this->db->where('name', $name);
return $this->result();
}
public function addData($data)
{
if(count($this->findByTitle($data['name'])) > 0) {
//.. your code
} else {
//.. your code
}
}
Explanation:
This:
if(mysqli_num_rows($data['name']) > 0)
..is not working to find database entries by name. To do this you can use codeigniters built in model functions and benefit from the MVC Pattern features, that CodeIgniter comes with.
I wrapped the actual findByName in a function so you can adapt this to other logic and use it elswehere later on. This function uses the query() method.
Read more about CodeIgniters Model Queries in the documentation.
Sidenote: mysqli_num_rows is used to iterate find results recieved by mysqli_query. This is very basic sql querying and you do not need that in a MVC-Framework like CodeIgniter. If you every appear to need write a manual sql-query, even then you should use CodeIgniters RawQuery methods.

Put other function on FormRequest in Laravel

I'm building a Laravel 6 application, and I am concerned about "best practices." I have one controller named CustomerController. In my controller, I want to update the Customer model, so I will have a function like the following.
public function update(UpdateCustomer $request, Customer $customer){
//
}
UpdateCustomer is my form request and where I will do the validation. In my update() method, I have classic validation.
public function rules()
{
$validationArray = [];
$validationArray['customer.name'] = 'string|required';
$validationArray['customer.vat'] = 'string|required';
$validationArray['customer.email'] = 'email|required';
return $validationArray;
}
Now I have to do some particular validation other the classic.
Let's assume that I have more data in my model, and I don't want these values to be changed.
For example, I have the following: address, cap, locality. I have a second method on the UpdateCustomer request that I can validate.
public function validateForDataCantChange()
{
$data = $this->input("customer");
$customer = $this->route("customerID");
$validator = Validator::make([], []); // Empty data and rules fields
$arrayDataThatCantChange = [
'address' => $data['address'] ?? NULL,
'cap' => $data['cap'] ?? NULL,
'locality' => $data['locality'] ?? NULL
];
foreach ($arrayDataThatCantChange as $key => $v) {
if ($customer->{$key} !== $v) {
$validator->errors()->add($key, __("messages.the field :field can't be changed", ['field' => $key]));
}
}
if ($validator->errors()->any()) {
throw new ValidationException($validator);
}
}
And then in my controller, I've added the following.
public function update(UpdateCustomer $request, Customer $customer){
$request->validateForDataCantChange();
}
Is this a bad practice? Should I create a new FormRequest? How, in this case (two form requests), can I use two different requests for a single controller?
For the little effort required, I'd personally create a new form request.
If you wish to use the same form request you can do the following:
public function rules()
{
$rules = [
'title' => 'required:unique:posts'
];
// when editing i.e. /posts/2/edit
if ($id = $this->segment(2)) {
$rules['title'] .= ",$id";
}
return $rules;
}
However, I always use a separate class for each action.

Phalcon validation scenario

I used to use Yii framework. I would like to make project using Phalcon. I could not find validation scenario on Phalcon. What is the best way to correctly implement it on Phalcon?
Thanks in advance.
Any data validation:
<?php
use Phalcon\Validation\Validator\PresenceOf,
Phalcon\Validation\Validator\Email;
$validation = new Phalcon\Validation();
$validation->add('name', new PresenceOf(array(
'message' => 'The name is required'
)));
$validation->add('email', new PresenceOf(array(
'message' => 'The e-mail is required'
)));
$validation->add('email', new Email(array(
'message' => 'The e-mail is not valid'
)));
$messages = $validation->validate($_POST);
if (count($messages)) {
foreach ($messages as $message) {
echo $message, '<br>';
}
}
http://docs.phalconphp.com/en/1.2.6/reference/validation.html
If you are working with models:
<?php
use Phalcon\Mvc\Model\Validator\InclusionIn,
Phalcon\Mvc\Model\Validator\Uniqueness;
class Robots extends \Phalcon\Mvc\Model
{
public function validation()
{
$this->validate(new InclusionIn(
array(
"field" => "type",
"domain" => array("Mechanical", "Virtual")
)
));
$this->validate(new Uniqueness(
array(
"field" => "name",
"message" => "The robot name must be unique"
)
));
return $this->validationHasFailed() != true;
}
}
http://docs.phalconphp.com/en/1.2.6/reference/models.html#validating-data-integrity
models also have events, so you can add any logic you need in these functions:
http://docs.phalconphp.com/en/1.2.6/reference/models.html#events-and-events-manager
I would like to use forms for CRUD as they are very dynamic and reusable.
You can achieve that in forms using options.
You can pass additional options to form and act like a scenario.
You can check Form constructor here
https://docs.phalconphp.com/en/latest/api/Phalcon_Forms_Form.html
In your controller you can pass $options
<?php
use Phalcon\Mvc\Controller;
class PostsController extends Controller
{
public function insertAction()
{
$options = array();
$options['scenario'] = 'insert';
$myForm = new MyForm(null, $options);
if($this->request->hasPost('insert')) {
// this will be our model
$profile = new Profile();
// we will bind model to form to copy all valid data and check validations of forms
if($myForm->isValid($_POST, $profile)) {
$profile->save();
}
else {
echo "<pre/>";print_r($myForm->getMessages());exit();
}
}
}
public function updateAction()
{
$options = array();
$options['scenario'] = 'update';
$myForm = new MyForm(null, $options);
}
}
And your form should look like something this
<?php
// elements
use Phalcon\Forms\Form;
use Phalcon\Forms\Element\Text;
// validators
use Phalcon\Validation\Validator\PresenceOf;
class MyForm extends Form {
public function initialize($entity = null, $options = null) {
$name = new Text('first_name');
$this->add($name);
if($options['scenario'] == 'insert') {
// at the insertion time name is required
$name->addValidator(new PresenceOf(array('message' => 'Name is required.')));
}
else {
// at the update time name is not required
// as well you can add more additional validations
}
}
}
now you can add multiple scenarios and act based on scenarios.

How to ajaxify Zend_Form validation

I have a Zend_Form subclass. Some elements are set to belong to arrays.
class My_Form extends Zend_Form {
public function __construct() {
$elem = $this->createElement('text','PROJECT_NAME',
array(
'required' => true
));
$elem->setBelongsTo('project');
$this->addElement($elem);
$elem = $this->createElement(
'text','PLANNED_END_DATE',
array(
'required' => true
)
);
$elem->setBelongsTo('project');
$elem->addValidator(new Zend_Validate_Date(array('format'=>'yyyy-MM-dd')));
$this->addElement($elem);
//and so on
}
}
I have a universal validation controller which does create the form and checks for errors, and returns them in json format:
class ValidateController extends Zend_Controller_Action
{
public function formAction()
{
$params = $this->_getAllParams();
if (isset($params['_frm'])) {
$formName = detect_the_form_class($params['_frm']);
if (class_exists($formName)) {
$form = new $formName();
if ($form instanceof Zend_Form) {
$result = $form->isValidPartial($params);
$messages = $form->getMessages();
$this->getResponse()
->setHeader('Content-Type', 'application/json')
->setBody(json_encode(array(
'result' => $result,
'messages' => $messages
)));
} else {
$this->getResponse()->setHttpResponseCode(500);
}
}
}
}
}
This controller works great for non-array forms, but the form I now need to validate hase arrays, eg elements with name 'project[PROJECT_NAME]'.
But the $form->getMessages() returns messages indexed with base name of elements, without array prefix.
The actual result is:
{ result: false,
messages: {
PROJECT_NAME: {isEmpty: "Value is required"},
PROJECT_END_DATE: {isEmpty: "Value is required"}
}
}
The result I need is:
{ result: false,
messages: {
"project[PROJECT_NAME]": {isEmpty: "Value is required"},
"project[PROJECT_END_DATE]": {isEmpty: "Value is required"}
}
}
or something similar, so I can find the element the validation message is for.
Any ideas?
For subforms use Zend_Form_Subform class:
class My_Form extends Zend_Form
{
public function init()
{
$subForm = new Zend_Form_SubForm();
$elem = $this->createElement('text', 'PROJECT_NAME', array(
'required' => true
));
$subForm->addElement($elem);
$elem = $this->createElement('text', 'PLANNED_END_DATE', array(
'required' => true
));
$subForm->addElement($elem);
$this->addSubForm($subForm, 'project');
}
}
Response:
{
"project":{
"PROJECT_NAME":{"isEmpty":"Value is required and can't be empty"},
"PLANNED_END_DATE":{"isEmpty":"Value is required and can't be empty"}
}
}
For form config it is recommended to use init() method.
For json response you can use build-in action helper:
$this->_helper->json($form->getMessages());

cakePHP form custom validation

Hi all I'm creating an invoice system and trying to make sure that the person sending the request, is sending it to a person who exists. The code that I currently have isn't working and was wondering if someone could give me a hand.
model
'exists'=>array(
'rule'=>'partytwo',
'message'=>'That username doesnt exist.'
));
function userExists($field=array(), $compare_field=null )
{
if($field['exists']= $compare_field)
return TRUE;
else return FALSE;
}
and the validation in relationship the controller
if($this->request->is('post')){
if($this->Relationship->validates(array('fieldlist'=>array('partywo','Relationship.userExists')))){
$this->Relationship->create();
if ($this->Relationship->save($this->request->data))
{
$id=$this->Relationship->id;
$this->Session->setFlash('The relationship has been saved');
}}
else { $this->Session->setFlash('The relationship could not be saved. Please, try again.'); }
}
here is my current model
<?php
class Relationship extends AppModel{
var $name='Relationship';
public $useTable = 'relationships_users';
public $primaryKey = 'id';
var $validate = array(
'date' => array(
'rule' => array('datevalidation', 'systemDate' ),
'message' => 'Current Date and System Date is mismatched'),
'partytwo'=>array(
'partytwoExists'=>array(
'rule'=> 'userExists',
'message'=>'That username doesnt exist.'
)));
function datevalidation( $field=array(), $compare_field=null )
{
if ($field['date'] > $compare_field)
return TRUE;
else return FALSE;
}
function userExists($check)
{
$userExists= $this->find('count', array('conditions'=>$check));
if($userExists == 1)
{return TRUE;
}
else
return FALSE;
}
}
its currently going straight to errors
Have you read the book on validation?
// MODEL
var $validation = array(
'field_name' => array(
'rule' => array( 'customFunction', param ),
'message' => 'Message here'
)
);
function customFunction($field=array(), $compare_field=null )
{
if($field['exists'] == $compare_field)
return TRUE;
else return FALSE;
}
And for controller:
// CONTROLLER
if($this->request->is('post')){
$this->Relationship->set( $this->request->data );
if($this->Relationship->validates(array('fieldlist'=>array('partywo','Relationship.userExists')))){
$this->Relationship->create();
if ($this->Relationship->save($this->request->data))
{
$id=$this->Relationship->id;
$this->Session->setFlash('The relationship has been saved');
}
} else {
$this->Session->setFlash('The relationship could not be saved. Please, try again.');
}
}
It is something along those lines, try that.

Resources