Laravel Validator removing null fields from array - php

I'm writing a test case to simulate a creation of a product. When creating the product, I'm passing an array of formats, and for some reasons, when validating with the controller, the thumbnail key is missing from the data.
This is the data I'm sending:
"formats" => array:1 [
0 => array:3 [
"upc" => "584979099857"
"vcode" => "VX43V14FN910479274209"
"thumbnail" => null
]
]
And I send it like the following in my test case:
$response = $this->post(route('products.store'), $product);
For some reasons, when sending the request, the thumbnail => null disappears from the formats attribute.
Therefore, when validating the request, I always get the error that the thumbnail has to be present.
request()->validate([
'formats' => 'bail|required|array',
'formats.*.upc' => 'bail|required|string|max:255',
'formats.*.vcode' => 'bail|required|string|max:255',
'formats.*.thumbnail' => 'bail|present|image'
]);
I've also tried changing the rules of thumbnail to:
bail|required|nullable|image
Or
bail|nullable|required|image
But then I get the required error.
Does anyone know why the thumbnail key is getting removed from the formats array upon sending the request?

Related

Laravel: Redirect with post route

Been trying to find a way to call to pass a multidimensional array to a Post route with no success.
The array looks like this:
"order" => array:16 [
"id" => "1"
"total" => "4825"
"neighborhood" => "Barrio Bravo"
]
"products" => array:2 [
4 => array:4 [
"id" => "4"
"name" => "Maestro Dobel 750ml"
"price" => "530"
"quantity" => "1"
]
1 => array:4 [
"id" => "1"
"name" => "Don Julio 70 700ml"
"price" => "650"
"quantity" => "1"
]
]
"grandTotal" => "1180"
"balanceToPay" => "354"
"cartTotal" => "826"
I don't have any problem asserting the route in the unit test calling the route like so:
$this->post(route('order.success', $orderInfo));
But when it comes to the controller I can't find the way to redirect to order.success with its orderInfo array.
This won't work since redirect only works with GET:
return redirect(route('order.success', $orderInfo));
Ideas?
It's not going to work with a simple redirection because you cannot choose the HTTP method. It's always GET when you make a redirection. It works in your test because you make a POST request manually.
I can see 2 solutions:
You can send data using GET method (they are added as URL parameters). If they are not confidential it can be a solution.
If you don't want to send those data in the URL, you have to save them somewhere and get them from the storage when you're on the order.success page. You can save them, for instance, in the session storage or in the local storage of your browser.
Also, your test isn't good if it tests a behavior that does not happen in your app (post request instead of redirection).

How to validate an array of datetimes in Laravel?

I have a form that submits an array named prazos, and I want to make sure each item is a valid datetime or null. Following the answers to this question and the Laravel docs, I have this in my Controller:
use Illuminate\Support\Facades\Validator;
// ...
$rules = array([
'prazos' => 'required|array',
'prazos.*' => 'nullable|date'
]);
$validator = Validator::make($request->all(), $rules);
$data = $validator->valid()['prazos'];
foreach($data as $id => $prazo) {
// use $data to update my database
// ...
}
The issue is, the validator is not actually stopping invalid content. If I try to submit "loldasxyz" or other gibberish, I get an error from the database. What am I doing wrong?
Note: previously I had been using validators with the syntax $data = $request->validate($rules), but for some reason it didn't work for the array-type data ($data came back empty). I'm not sure if there is some difference in how those different methods work.
Edit: this is what the parameter bag in $request looks like when I test it (the indices are ids, which is why they start at 1):
#parameters: array:3 [▼
"_token" => "Rf6mAp4lqhpZzQRxaxYsees1M0NfrFKpbGe4Hy28"
"_method" => "PUT"
"prazos" => array:5 [▼
1 => "2021-03-22 21:21"
2 => "2021-03-03 11:27"
3 => "jhbkjhg"
4 => null
5 => "2021-03-02 14:21"
]
]
And this is what the validated $data comes out as:
array:5 [▼
1 => "2021-03-22 21:21"
2 => "2021-03-03 11:27"
3 => "jhbkjhg"
4 => null
5 => "2021-03-02 14:21"
]
I wish it would tell me the third value is invalid.
Heres what youre looking for:
https://laravel.com/docs/8.x/validation#rule-date-equals
The field under validation must be equal to the given date. The dates will be passed into the PHP strtotime function in order to be converted into a valid DateTime instance.

Docusign PHP SDK - Fill Template pre-defined data label value

UPDATE:
As it turns out, I need to enable this setting for data to show up, and using tabs is the correct thing to do.
When an envelope is sent, write the initial value of the field for all recipients
=================================================================
Not sure why this one is not mentioned in API properly ... but how does one go about filling template's custom data label with template?
So, I create a template like this:
$envelope_definition = new EnvelopeDefinition([
'status' => 'sent',
'template_id' => $args['template_id'],
]);
then I create a signer:
$signer = new TemplateRole([
'email' => $args['signer_email'],
'name' => $args['signer_name'],
'role_name' => 'signer',
]);
Here is where the disconnect happened, where do I add a pre-defined template value? I tried two things so far:
1. Add tabs to $signer like so, but by doing so, it ereases all field value in the final document,
new Tabs([
"text_tabs" => [
new Text([
"tab_label" => "price",
"value" => "123456789",
]),
],
]),
Call $envelope_definition->setCustomFields() , like this :
$envelope_definition->setCustomFields(new CustomFields([
'text_custom_fields' => [
'price' => new Text([
'tab_label' => 'price',
'custom_tab_id' => 'price',
'value' => '123456789',
]),
],
]));
It will throw me a C# error, which I don't understand at all:
Error while requesting server, received a non successful HTTP code [400] with response Body: O:8:\"stdClass\":2:{s:9:\"errorCode\";s:20:\"INVALID_REQUEST_BODY\";s:7:\"message\";s:718:\"The request body is missing or improperly formatted. Cannot deserialize the current JSON object (e.g. {\"name\":\"value\"}) into type 'System.Collections.Generic.List`1[API_REST.Models.v2_1.textCustomField]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.\r\nTo fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.\r\nPath 'customFields.textCustomFields.price', line 1, position 45.\";}"
API docs seems to be focusing on creating template and values adhoc ... anyone have something that works? Thanks a lot!
You can find valid PHP example here which shows how to prepopulate template tab values while creating an envelope.
You didn't follow the example correctly.
You didn't create a \DocuSign\eSign\Model\TextCustomField object.
Here it is from Amit's link:
# Create an envelope custom field to save the our application's
# data about the envelope
$custom_field = new \DocuSign\eSign\Model\TextCustomField([
'name' => 'app metadata item',
'required' => 'false',
'show' => 'true', # Yes, include in the CoC
'value' => '1234567']);
$custom_fields = new \DocuSign\eSign\Model\CustomFields([
'text_custom_fields' => [$custom_field]]);
$envelope_definition->setCustomFields($custom_fields);

Passing Form-data Array from one function to another function in same controller

I have a multidimensional array containing data from a form and I need this array in another Controller in the same controller to continue working with it, but I don't know how I do that.
The array can look like this example:
array [
"absender" => "Maxim Ivan",
"email" => "maximivan#example.com",
"telefon" => "1234567890",
"fax" => null,
"grund" => "Gehaltserhöhung",
"termin" => [
0 => [
"person" => "Some Name",
"meeting" => "10.05"
],
1 => [
"person" => "Another Name",
"meeting" => "18.05"
],
2 => [
"person" => "Again another name",
"next-possible-meeting" => "1"
],
3 => [
"person" => "And again",
"next-possible-meeting" => "1"
],
],
"bemerkung" => "some notes by Maxim"
]
This array is created(and the input data validated) in the store-method of the 'TerminController'.
This method will return a view where all of this data gets displayed again, to let the user check the info and can then add a document.
When the document is added and the data gets submitted with an input-button the upload-method in the same Controller gets called.
And there's where I need the array with the form-data to go on working with it.
But how do I achieve passing the array through to the next function that is only called with an input-button.
First approach was to save the array into the session, which did even work even though it was hard due to the multidimensional; but it's a really ugly solution.
Should I save the input data into a database in the store-method and fetch it again in the upload-method?
Or is it somehow possible to pass the array through the Controllers/ make it accessible in the upload-Controller even though it gets created in another one?
I have also heard something about using serialize()and unserialize(), but I'm not exactly sure how this could help me..
Or maybe there's another and even better solution I just don't think of?
I'd appreciate all the help I can get.
The array varies, it can be 17 arrays nested in 'termin' but I can also be just one.
You can store it in the cache:
Cache::put('multiArray', $multiArray); //put array in cache
$array = Cache::get('multiArray'); //retreive from cache

Creating campaign for dynamic TextMerge segment fails

I'm trying to send a campaign to a dynamic list segment based on a custom numeric merge field (GMT_OFFSET, in this case) but the code below yields the following error from the MailChimp API:
"errors" => [
0 => [
"field" => "recipients.segment_opts.conditions.item:0"
"message" => "Data did not match any of the schemas described in anyOf."
]
]
My code, using drewm/mailchimp-api 2.4:
$campaign = $mc->post('campaigns', [
'recipients' => [
'list_id' => config('services.mailchimp.list_id'),
'segment_opts' => [
'conditions' => [
[
'condition_type' => 'TextMerge',
'field' => 'GMT_OFFSET',
'op' => 'is',
'value' => 2,
],
],
'match' => 'all',
],
],
],
// Cut for brevity
];
If I am to take the field description literally (see below), the TextMerge condition type only works on merge0 or EMAIL fields, which is ridiculous considering the Segment Type title says it is a "Text or Number Merge Field Segment". However, other people have reported the condition does work when applied exclusively to the EMAIL field. (API Reference)
I found this issue posted but unresolved on both DrewM's git repo (here) and SO (here) from January 2017. Hoping somebody has figured this out by now, or found a way around it.
Solved it! I passed an integer value which seemed to make sense given that my GMT_OFFSET merge field was of a Number type. MailChimp support said this probably caused the error and suggested I send a string instead. Works like a charm now.

Categories