I have an API which takes multiple input values. One of them is a date.
When the date is sent, all is fine.
But, when the user isn't sending a date, I have an error 500 with this error message:
Invalid datetime "Some invalid data", expected format Y-m-d\TH:i:sP.
So I wanted to check if the data sent had the format required.
But I don't understand how things are working, hope you can help.
This is what I have
/**
*
* #Rest\Post(
* path = "/signup",
* name = "api_users_add"
* )
* #Rest\View(StatusCode=201, serializerGroups={"user_detail"})
* #ParamConverter(
* "user",
* converter="fos_rest.request_body",
* options={"deserializationContent"={"groups"={"Deserialize"}}},
* )
* #ParamConverter(
* "profile",
* converter="fos_rest.request_body",
* options={"deserializationContent"={"groups"={"Deserialize"}}},
* )
*/
public function postUserAction(Request $request, User $user, Profile $profile)
{
if (!preg_match("^[0-9]{4}-[0-1][0-9]-[0-3][0-9]$",$profile->getBirth())){
return new JsonResponse([
'success' => false,
'message' => "Date d'anniversaire au mauvais format"
]);
}
}
But in fact, I never go into this condition, the error 500 is triggered before.
I guess this has something to do with the #ParamConverter from Profile who can't "deserialize" when birth is not a DateTime.
Thing is, I would like to check what is sent (as I did into my condition) in order to avoid this internal error. But I can't find where this is handled on my code.
Thanks for the help.
Considering this : symfony doc for Param converter fos rest bundle
What I am looking for is to find where the validationErrors are specified.
Related
* #Assert\Type(type="array")
* #Assert\Count(
* min=5,
* max=10
* )
I need validate a type array and then I need to validate if the array has a min and max count.
But when I send a string value, then Assert\Type evaluates that's not a valid type, but despite that validation continues to Assert\Count and there is problem it is not an array and Assert\Count throw UnexpectedValueException and I have message: This value should be of type {{ type }}., and the that's not the correct validation message for me.
Is possible do Assert\Count only when is Assert\Type condition correct?
If i am understanding your question then using Assert Sequentially is the resolution.
Update your Asserts to look like this:
* #Assert\Sequentially({
* #Assert\Type(type="array"),
* #Assert\Count(min=5, max=10),
* })
*/
The first validation will be raised if your Type is not an array and not perform any further validations.
I have a function in Symfony3 that posts data to a mysql database. The function looks like this:
/**
* #Route("/LegoPieces")
* #METHOD("POST")
* #View()
*
* #Annotations\QueryParam(
* name="piece", nullable=false, description="piece"
* )
* #Annotations\QueryParam(
* name="type", nullable=false, description="type"
* )
* #Annotations\QueryParam(
* name="startDate", nullable=false, description="Start Date YYYY-MM-DD HH:MM:SS (Should be in the future)"
* )
* #Annotations\QueryParam(
* name="endDate", nullable=false, description="End Date YYYY-MM-DD HH:MM:SS (Should be no more than 3 weeks in the future)"
* )
*/
public function postAction(ParamFetcherInterface $paramFetcher)
{
$piece = $paramFetcher->get('piece');
$type = $paramFetcher->get('type');
$start = $paramFetcher->get('startDate');
$end = $paramFetcher->get('endDate');
$startDate = DateTime::createFromFormat('Y-m-d H:i:s', $start);
$endDate = DateTime::createFromFormat(' Y-m-d H:i:s', $end);
$em = $this->getDoctrine()->getManager('default');
$data = new LegoPieces();
$data->setPiece($piece);
$data->setType($type);
$data->setStartDate($startDate);
$data->setEndDate($endDate);
$em->persist($data);
$em->flush();
return new JsonResponse("LegoPieces Added Successfully", 200);
}
When I replace the variables ($piece, $type, $startDate, $endDate) with strings the post request works. But when I try to make a post request through something like Postman or javascript like this:
fetch("http://localhost:8000/LegoPieces", {
method: "POST",
body: {
startDate: this.startDate,
endDate: this.endDate,
piece: this.piece,
type: this.type
}
}).then(response => response.json())
);
});
I get a 500 error! I don't understand- thanks for your help!
Look in your logs what is your error.
But you have to improve your controller ! You don't use Symfony Form and you don't have any validations. Even if your haven't 500 error now, you will have some in the future if you don't respect your entity types.
I also don't understand why you use a post request and don't pass all your parameters in your body. You only use get parameters in the url.
Without knowing what exception makes that 500 - you know nothing :(
Try to see response body
Without that info - i have only one idea .
If you arw working on dev envionment , then youur js request simply may not see routes (and the other stuff)
clear all contents of cache folder
rm -rf var/cache/*
and
php bin/console c:w -e prod
I have the following declaration in my user class (Symfony 3, it's an entity class):
/**
* #ORM\Column(type="string", length=128, unique=true)
* #Assert\NotBlank (
* groups={"registration"},
* message = "test"
* )
* #Assert\Email(
* message = "The email '{{ value }}' is not a valid email.",
* groups={"registration"}
* )
*/
private $email;
Everything works fine, except that I can't set a message, instead of my message ('test' for example) a default "This value should not be blank" is displayed.
Yes, I do have
framework:
validation: { enable_annotations: true }
In my config.yml
Edit: and yes I cleared cache by executing:
sudo php bin/console cache:clear
Edit2: Please note that it actually DOES go through validation, Symfony sees that the email is required, it displays a message if I leave the field empty, it's just that it is not my message, Symfony somehow doesn't see the "message" part.
Edit3: Now, after removing the groups={"registration"} part, as well as changing (in controller)
$errors = $validator->validate($user, null, array('registration'));
to
$errors = $validator->validate($user, null);
(removed array('registration'))
the correct message is displayed. However this is not a solution. I need to use groups.
Edit 4:
I'll get crazy...
If I enter no email, and then:
$validator = $this->get('validator');
$errors = $validator->validate($user, null, array('registration'));
dump($errors);
(Notice the "dump" function call) then I see an incorect message displayed on a page (This value should not be blank) but... when I enter the profiler->debug page (the dev tools at the bottom) then I can see that a correct (my) message is there...
Furthermore in profiler->form errors is this incorect message on the list (as only one item) but... it says it refers to a field named "plainPassword" which is not in the form, and does NOT belong to the "registration" group, so it should not be validated in the first place.
What's going on there?
Can You try this?
/**
* #ORM\Column(type="string", length=128, unique=true)
*
*
* #Assert\NotBlank(
* message = "The box cant be left blank")
*
*
* #Assert\Email(
* message = "The email '{{ value }}' is not a valid email."
*
* )
*/
private $email;
I'm writing a unit test and I can't pass the validation for a datetime field. This is my entity with the field that causes problems:
class Page
{
/**
* #var \DateTime
* #Assert\NotBlank(message="NOT_EMPTY")
* #ORM\Column(name="end_date", type="datetime", nullable=true)
*/
private $date;
}
And here is my unit test:
$form = $crawler->filter('#addNew')->form();
$date = new \DateTime();
$params = array(
'formpage[title]' => 'Unitest sample',
'formpage[date]' => $date->format('Y-m-d H:i:s')
);
$form->setValues($params);
$client->submit($form);
This is the error I caught using the debugger, $form->isValid() returns false:
Symfony\Component\Validator\ConstraintViolation
This value is not valid
Unable to reverse value for property path "date": Date parsing failed: U_PARSE_ERROR
Any idea what the problem could be? Thanks in advance.
I think it's failing because of the expected format.
It seems you've defined your widget as a single_text but haven't specified the format (or the one you specified doesn't coincide with the one you're sending). The default format is yyyy-MM-dd if widget is single_text ( no H:i:s part).
Correct this and it should work.
I have searched and found i have been lost all day now, and I feel I am going round in circles.
I have written, (with help of a few guides), a simple API for my Yii based application.
I have now come to document this API for other to use it.
I read everywhere that Swagger seems to be the way to go to implement, API documentation.
However I can seem to get anywhere on how to use this application
I have followed the instructions on Swagger PHP
Now I am lost has anyone got any examples of what to do next.
I have tried doing some self annotations of my ApiController.php and this doesnt work. I have been trying using the swagger.phar command line, but I still get no where.
I know you will need a lot more information but i dont know what bits of info you need so rather than pasting lots of useless information please ask and i will send anything you need.
To be honest all i would like is some simple API documentation but it just seems impossible.
Cheers
I have implemented swagger-php in my project. Please follow the below suggested instructions :
1) Download swagger-php(github.com/zircote/swagger-php) and swagger-ui(github.com/wordnik/swagger-ui). Extract them to your workspace.
2) Create a folder called swagger-api and blank php file called index.php in you workspace and paste the following code.
<?php
use Swagger\Annotations as SWG;
/**
* #SWG\Resource(
* apiVersion="0.2",
* swaggerVersion="1.2",
* resourcePath="/api.php",
* basePath="http://localhost/swagger-api/"
* )
*/
// Run this in url
// localhost/index.php?action=get_app_list
// This is the API,show the list in array
/**
*
* #SWG\Api(
* path="/api.php?action=get_app_list",
* description="Operations about get app list",
* produces="['application/json']",
* #SWG\Operations(
* #SWG\Operation(
* method="GET",
* summary="Find facet by ID",
* notes="Returns a facet based on ID",
* type="ListResult",
* nickname="getAllResults",
* #SWG\ResponseMessages(
* #SWG\ResponseMessage(
* code=400,
* message="Invalid ID supplied"
* ),
* #SWG\ResponseMessage(
* code=404,
* message="facet not found"
* )
* )
* )
* )
* )
*/
function get_app_list()
{
//normally this info would be pulled from a database.
//build JSON array
$app_list = array(array("id" => 1, "name" => "Web Demo"),
array("id" => 2, "name" => "Audio Countdown"),
array("id" => 3, "name" => "The Tab Key"), array("id" => 4,
"name" => "Music Sleep Timer"));
return $app_list;
}
$possible_url = array("get_app_list");
$value = "An error has occurred";
if (isset($_GET["action"]) && in_array($_GET["action"], $possible_url))
{
switch ($_GET["action"])
{
case "get_app_list":
$value = get_app_list();
break;
$value = "Missing argument";
break;
}
}
//return JSON array
echo(json_encode($value));
?>
3) Create a folder named swagger-docs in workspace.
4) Open you terminal and go the location of swagger-php in you workspace(i.e cd workpace/swagger-php).
5) Execute the following in your terminal
php swagger.phar /workspace/swagger-api -o /workspace/swagger-docs (This can be executed where we contain swagger.phar file).
6) You will see some files created on your swagger docs folder.
7) Open index.html in swagger-ui/dist/
8) Replace -: url: "http://petstore.swagger.wordnik.com/api/api-docs" to url: "http:localhost/swagger-docs"
9) Run localhost/swagger-ui/dist in your browser.