inconsistent email format of html input field with laravel email validation - html

In my blade file i have a html form for user in which input field email have type email. But i think it provide inconsistent email format validation. example it show abc#xyz and abc#xyz.com both are correct email address but in my controller, validator method return me invalid email format for abc#xyz. How can i resolve this issue???
In my blade file:
<input type="email" name="email" value="">
And in my controller:
$validator = Validator::make($request->all(), [
'email' => 'email|unique:table_name,col_name',
],[
'email.unique' => 'email is already in used',
]);
if ($validator->fails()) {
return redirect()->back()->withInput($request->all())->withErrors($validator);
}

Actually Laravel using PHP builtin function called filter_var (source code).
// Illuminate\Validation\Concerns\ValidateAttributes
/**
* Validate that an attribute is a valid e-mail address.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function validateEmail($attribute, $value)
{
return filter_var($value, FILTER_VALIDATE_EMAIL) !== false;
}
The rules implemented by PHP is quite different with the rules implemented by the browser. abc#xyz passed the browser validation rule because xyz is a valid hostname (you can read it here). But PHP implementing more strict rule that the email address should contains top level domain.

Related

Change the error message in inserting a url with $ form -> $ filed

I want to change the error message that comes out when you enter a url wrong. I show you what I mean:
Image
The message must become: Inserisci un URL valido. Es: https://www.google.it
I am modifying the view.php generated automatically by gii. Here is the code:
<?= $form->field($model, 'link')->input('url')?>
This is the function I use to enter a valid url.
You can change the rules in your model for the attribute link using an inline validator:
public function rules()
{
return [
[['link'], 'required'],
['link', function ($attribute, $params, $validator) {
// Check validity of attribute
if ($this->$attribute != ...) {
$this->addError($attribute, 'Inserisci un URL valido. Es: https://www.google.it');
}
}],
];
}
When checking the validity of the $link attribute, you also can use the Yii2 UrlValidator.

Check text input if email already exist or empty

I want to get the value on txtEmail input and check if it already used once text input is out of focus. Only have one email address suppose to be used which is john.doe#example.com. If email already exist, it will return an error message that it already exist. It will also return an error message if the textfield is empty
"Checkemail.php"
<?php
header('Access-Control-Allow-Origin: *');
if ($_REQUEST['email'] == 'john.doe#example.com') {
echo -1;
} else {
echo 1;
}
?>
Scripts.js
document.getElementById("txtEmail").addEventListener("focusout", outOfFocus);
function outOfFocus(){
var txtEmail = $("#txtEmail").val();
console.log(txtEmail);
$.ajax({
type:"POST",
url:"checkemail.php?email=<email>",
data: txtEmail,
success: function(data){
console.log("Success!");
},
error: function(){
document.getElementById("#emailError").innerHTML = "Email address already used!"
}
})
}
Email.html
<label for="lblEmail">Email : </label>
<input type="email" id="txtEmail">
<label for="emailError" id="emailError"></label><br/>
"blur" is the event you are wanting - there isn't a "focusout" as far as I know, unless you are using some library that has that
Also, when sending a POST request, you don't need the query string (i.e the line should just be url:"checkemail.php", since the data will just be sent in the POST body)
You should also access the variable server-side with $_POST, not $_REQUEST
Likewise, if you are referencing things by POST variable names, you might have to send a key-value object, rather than just the string. Just copy an example from the jQuery docs. You could also use the $.post method, which is a shorthand for setting the $.ajax method as post manually
If you do all of those steps, that should get you most of the way there

Symfony4 (API) - Trying to upload a file using request->files->all() gives me an empty result

I'm trying to upload a file using API in symfony 4, i'm using RESTLET tool to send my file but all i got is a 200 OK but with an empty result.
Content-Type : text/plain
METHOD : POST
FILE SIZE : 1ko
Code :
<?php
namespace App\Controller\Api\Dossier;
use App\Entity\Dossier\Fichier;
use App\Helpers\Constant\ErrorMessage;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
/**
* #Route("/{db}/fichier")
*/
class ApiFichierController extends ApiController
{
/**
* #Route("/", name="api_fichier_enregistrer", methods={"POST"})
* #param Request $request
* #return JsonResponse|RedirectResponse
*/
public function retrieveAction(Request $request){
// retrieve the file with the name given in the form.
$filesResult = array();
$filesBag = $request->files->all();
foreach ($filesBag as $file){
$filename = $file->getClientOriginalName();
$filesResult []= array(
'path' => $file->getPathname(),
'url' => 'ddd'
);
$src = __DIR__;
$file->move( $src ,$filename );
}
return new JsonResponse($filesBag);
}
Result
You want to use Content-Type : multipart/form-data in order to actually upload a file.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type#Content-Type_in_HTML_forms

Empty data in Symfony Request object when Controller is called by Authorize.net webhook

Using Authorize.net sandbox Web UI, set up an webhook to call Symfony controller by URL. By default Auth.net sends POST request with data in JSON format. Verified at Requestb.in that the data is sent:
RAW BODY:
{"notificationId":"f803dsa2c9-32fa-4f44-8dsd-b9b2324lf9a7",
"eventType":"net.authorize.payment.authcapture.created",
"eventDate":"2017-09-19T09:29:46.9455538Z",
"webhookId":"f2a105zd-drf4-491v-ab31-9cdd4a8ad04a",
"payload":{"responseCode":21,
"authCode":"111",
"avsResponse":"M",
"authAmount":12.5,
"entityName":"transaction",
"id":"45"}
}
Then trying to retrieve POST data in Symfony Controller and write it in a sample file, return actually does nothing:
Controller code:
/**
* #Route("/webhook")
* Class DonateController
* #package AppBundle\Controller
*/
class WebHookController extends Controller
{
/**
* #Route("/test", name="webhooktest")
* #param Request $request
* #return \Symfony\Component\HttpFoundation\Response
*/
public function WebHookAction(Request $request){
set_include_path('/var/www/project/web/');
$file = 'webhook_test.txt';
$content = $request->getContent();
$json = json_decode($content, true);
$wr = "Request object test 0: " . $request->request->all() . "\n\n";
$wr = $wr . "Object : " . $request->__toString() . "\n\n";
file_put_contents($file, $wr);
return $this->render('test/webhook.html.twig',
[
'wr' => $wr
]);
}
Unlucky, the $request contains only header, $request->request->all() returns only empty Array
Tried to extend from FOSRestController with body_listener instead of classic Symfony Controller without any difference.
config.xml part:
param_fetcher_listener: true
body_listener:
decoders:
json: fos_rest.decoder.json
Also tried to handle requests with symfony-json-request-transformer and SymfonyBundlesJsonRequestBundle, no result.
What's wrong here?
Resolved switching from HTTP to HTTPS in Authorize.net webhook configuration.
By default HTTP requests with POST data are not recognized and processed as I expected it to do and no data is delivering.
Just used https:// instead of http://url and all the magic happened.
Here is a simple code and it worked. I have tested it by POST with the JSON data and then let this function returned the request data to response. It worked!
/**
* #Route("/products", name="products", methods={"POST"})
*
* #param Request $request
* #return array|JsonResponse|null|object
*/
public function WebHookAction(Request $request)
{
$content = $request->getContent();
$json = json_decode($content, true);
return new JsonResponse($json);
}

Cakephp - If Request is JSON?

I have read the RequestHandler part in cookbook. There are isXml(), isRss(), etc. But there's no isJson().
Any other way to check whether a request is JSON?
So when the url is mysite.com/products/view/1.json it will give JSON data, but without .json it will give the HTML View.
Thanks
I dont think cakePHP has some function like isJson() for json data, you could create your custom though, like:
//may be in your app controller
function isJson($data) {
return (json_decode($data) != NULL) ? true : false;
}
//and you can use it in your controller
if( $this->isJson($your_request_data) ) {
...
}
Added:
if you want to check .json extension and process accordingly, then you could do in your controller:
$this->request->params['ext']; //which would give you 'json' if you have .json extension
CakePHP is handling this correctly, because JSON is a response type and not a type of request. The terms request and response might be causing some confusing. The request object represents the header information of the HTTP request sent to the server. A browser usually sends POST or GET requests to a server, and those requests can not be formatted as JSON. So it's not possible for a request to be of type JSON.
With that said, the server can give a response of JSON and a browser can put in the request header that it supports a JSON response. So rather than check what the request was. Check what accepted responses are supported by the browser.
So instead of writing $this->request->isJson() you should write $this->request->accepts('application/json').
This information is ambiguously shown in the document here, but there is no reference see also links in the is(..) documentation. So many people look there first. Don't see JSON and assume something is missing.
If you want to use a request detector to check if the browser supports a JSON response, then you can easily add a one liner in your beforeFilter.
$this->request->addDetector('json',array('callback'=>function($req){return $req->accepts('application/json');}));
There is a risk associated with this approach, because a browser can send multiple response types as a possible response from the server. Including a wildcard for all types. So this limits you to only requests that indicate a JSON response is supported. Since JSON is a text format a type of text/plain is a valid response type for a browser expecting JSON.
We could modify our rule to include text/plain for JSON responses like this.
$this->request->addDetector('json',array('callback'=>function($req){
return $req->accepts('application/json') || $req->accepts('text/plain');
}));
That would include text/plain requests as a JSON response type, but now we have a problem. Just because the browser supports a text/plain response doesn't mean it's expecting a JSON response.
This is why it's better to incorporate a naming convention into your URL to indicate a JSON response. You can use a .json file extension or a /json/controller/action prefix.
I prefer to use a named prefix for URLs. That allows you to create json_action methods in your controller. You can then create a detector for the prefix like this.
$this->request->addDetector('json',array('callback'=>function($req){return isset($req->params['prefix']) && $req->params['prefix'] == 'json';}));
Now that detector will always work correctly, but I argue it's an incorrect usage of detecting a JSON request. Since there is no such thing as a JSON request. Only JSON responses.
You can make your own detectors. See: http://book.cakephp.org/2.0/en/controllers/request-response.html#inspecting-the-request
For example in your AppController.php
public function beforeFilter() {
$this->request->addDetector(
'json',
[
'callback' => [$this, 'isJson']
]
);
parent::beforeFilter();
}
public function isJson() {
return $this->response->type() === 'application/json';
}
Now you can use it:
$this->request->is('json'); // or
$this->request->isJson();
Have you looked through and followed the very detailed instructions in the book?:
http://book.cakephp.org/2.0/en/views/json-and-xml-views.html
class TestController extends Controller {
public $autoRender = false;
public function beforeFilter() {
$this->request->addDetector('json', array('env' => 'CONTENT_TYPE', 'pattern' => '/application\/json/i'));
parent::beforeFilter();
}
public function index() {
App::uses('HttpSocket', 'Network/Http');
$url = 'http://localhost/myapp/test/json';
$json = json_encode(
array('foo' => 'bar'),
JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP
);
$options = array('header' => array('Content-Type' => 'application/json'));
$request = new HttpSocket();
$body = $request->post($url, $json, $options)->body;
$this->response->body($body);
}
public function json() {
if ($this->request->isJson()) {
$data = $this->request->input('json_decode');
$value = property_exists($data, 'foo') ? $data->foo : '';
}
$body = (isset($value) && $value === 'bar') ? 'ok' : 'fail';
$this->response->body($body);
}
}
Thanks a lot Mr #Schlaefer. I read your comment and try, Wow it's working now.
//AppController.php
function beforeFilter() {
$this->request->addDetector(
'json', [
'callback' => [$this, 'isJson']
]
);
parent::beforeFilter();
...
}
public function isJson() {
return $this->response->type() === 'application/json';
}
//TasksController.php
public $components = array('Paginator', 'Flash', Session','RequestHandler');
//Get tasks function return all tasks in json format
public function getTasks() {
$limit = 20;
$conditions = array();
if (!empty($this->request->query['status'])) {
$conditions = ['Task.status' => $this->request->query['status']];
}
if (!empty($this->request->query['limit'])) {
$limit = $this->request->query['limit'];
}
$this->Paginator->settings = array('limit' => $limit, 'conditions' => $conditions);
$tasks = $this->paginate();
if ($this->request->isJson()) {
$this->set(
array(
'tasks' => $tasks,
'_serialize' => array('tasks')
));
}
}
In case anybody is reading this in the days of CakePHP 4, the correct and easy way to do this is by using $this->request->is('json').