Something good with laravel is "$casts" attribute. Exemple with dates :
protected $casts = [
'date_rec' => 'datetime:Y-m-d',
'date_liv' => 'datetime:Y-m-d',
];
It works well if you return result of eloquent's query.
But if you don't want return full object with all relations it's the hell.
Examples :
protected $casts = [
'date_rec' => 'datetime:Y-m-d',
'date_liv' => 'datetime:Y-m-d',
];
public function asListItem()
{
return [
"try_1" => $this->date_rec, // return : "2021-10-19T22:00:00.000000Z"
"try_2" => $this->date_rec->format('Y-m-d'), // return : "2021-10-19" or error/crash if date is null
"try_3" => substr($this->date_rec ?? '', 0, 10), // work always but boring
"try_4" => json_encode($this->date_rec) // infinite loading and then error timeout
];
}
Is it possible to define how I want laravel parse date globally at serialization ?
Thx
You can use Carbon::setToStringFormat('your format'); in your provider to set a default string format
Related
I am trying to add an asset link to a nested properties value using Eloquents API resource function:
public function toArray($request)
{
return [
'id' => $this->id,
'title' => $this->title,
'image' => isset($this->image) ? asset('storage/'.$this->image) : null,
'properties' => $this->properties,
'created_at' => (string) $this->created_at,
'updated_at' => (string) $this->updated_at
];
}
The following works fine for the image value, but I am using a nested properties['pdf'] file that I need to add asset('storage/') parameter to so it outputs the full URL.
How am I able to pass isset($this->properties['pdf']) ? asset('storage/'.$this->properties['pdf']) : null into the properties value? I still need the pdf value to return inside the properties value.
Note: There are other values inside properties but they are dynamic based on the data returned.
Probably not the cleanest idea but this worked:
$properties = $this->properties;
if(isset($this->properties['pdf']) && $this->properties['pdf'] != null){
$properties['pdf'] = asset('storage/'.$this->properties['pdf']);
}
Then I applied $properties to the return.
My current MongoDB schema is using a custom UUID object type as _id. I'm trying to generate a new UUID in my User model using $attributes = [];. I can't find any solution on how I can pass an object data type into my model.
My model :
use Authenticatable, Authorizable, CanResetPassword;
protected $connection = 'mongodb';
protected $collection = 'users';
protected $fillable = [
'username', 'email', 'password'
];
protected $attributes = [
'_id' => Uuid\Uuid::uuid4(),
'rank' => 1,
'token' => 0,
'banned' => false,
'vote_count' => 0,
'vote_bank' => 0,
'capeAllowed' => false,
'skin' => null,
'cape' => null,
'verified' => false,
'nameChanges' => 0
];
I can't find a way to have my object UUID into _id. It has to be an object type and not a string.
I have tried doing it by passing a new object using the User::create(Uuid::uuidv4()) but it doesn't take it either. The webserver used to be on NodeJS which didn't have any problem using object as data type. The database has already many records using a UUID Binary object as the _id.
I have also tried using many library. Many don't work with Laravel 6.x or the ones that work doesn't return a binary format.
The solution was using the User::create() method. The protected $attributes = [] doesn't accept variables from what I could see. I used PHP's Binary class to convert ramsey/uuidv4 as a UUID type :
new Binary(Uuid::uuid4()->getBytes(), Binary::TYPE_UUID)
In Laravel 5.6 I'm trying to make proper slack logs and I did:
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['single', 'slack'],
],
'slack' => [
'driver' => 'slack',
'url' => env('LOG_SLACK_WEBHOOK_URL'),
'username' => 'TEST',
'icon' => ':boom:',
'level' => 'info',
],
It works but I want to specify additional fields and maybe customize it a little if it match some other conditions.
I was looking at SlackWebhookHandler.php monolog file but not all parameters work in this configuration..
For example emoji and username doesn't work - I don't know if slack already has even options for changing bot username.
Other example is that in this file something it's called useAttachment and here it's just attachment - where the names are stored..?
Back to topic I did:
Log::info('added test',['test'=>'test']);
And it works, but for slack I want to send additional field, in every request for example:
'added test',['test'=>'test', 'more' => 'test2']
How I'm able to accomplish it? I need to connect to Log Class and slack driver in some way but I don't have idea how to do this?
I debugged myself to SlackRecord::getSlackData, there you see how he handles attachments and add's additional data to the record.
For me it totally fitted to set 'context' => true in logging.php for the Slack Channel and define a Processor which just add's the Data I need to the record
class SlackProcessor {
/**
* #param array $record
* #return array
*/
public function __invoke(array $record) {
$record["context"]["Env"] = env("LOG_SLACK_USERNAME", "localhost");
$record["context"]["Full URL"] = Request::fullUrl();
$record["extra"]["Request Data"] = Request::all();
return $record;
}
}
So maybe you could just debug again to getSlackData and see why he jumps over the attachment part you need.
I was able to get closer to solution but still not at all:
On logging.php now I have
'slack' => [
'driver' => 'slack',
'url' => env('LOG_SLACK_WEBHOOK_URL'),
'tap' => [App\Logging\SlackLogger::class],
'username' => 'BOT',
'attachment' => false,
'emoji' => ':boom:',
'level' => 'info',
],
I created App/Logging/SlackLogger.php:
namespace App\Logging;
use Monolog\Logger;
use Monolog\Handler\SlackWebhookHandler;
use Monolog\Formatter\LineFormatter;
use Monolog\Formatter\JsonFormatter;
class SlackLogger
{
/**
* Customize the given logger instance.
*
* #param \Illuminate\Log\Logger $logger
* #return void
*/
public function __invoke($logger)
{
$dateFormat = "Y-m-d H:i:s";
$checkLocal = env('APP_ENV');
foreach ($logger->getHandlers() as $handler) {
if ($handler instanceof SlackWebhookHandler) {
$output = "[$checkLocal]: %datetime% > %level_name% - %message% `%context% %extra%` :poop: \n";
$formatter = new LineFormatter($output, $dateFormat);
$handler->setFormatter($formatter);
$handler->pushProcessor(function ($record) {
$record['extra']['dummy'] = 'test';
return $record;
});
}
}
}
}
And It works only if I don't try to make custom attachment on slack.. When I'm trying to do:
$handler->pushProcessor(function ($record) {
$record['extra']['dummy'] = 'test';
$record['attachments'] = [
'color' => "#36a64f",
"title" => "Slack API Documentation",
"text" => "Optional text that appears within the attachment"
];
return $record;
});
the $record losts 'attachments' array.. I was checking it in SlackWebhookHandler in write function because at this pushProcessor at return it still exists, but not sending to slack. I know that can be related to $handler->setFormatter($formatter); but I if I remove It, the problem still exists - so I still don't know how to solve it.
My model has the following validation and rules :
public $rules = [
'hire_date' => 'date|required|required_with:dismiss_date',
OR
'hire_date' => 'date_format:"Y-m-d"...',
];
protected $casts = [
//'hire_date' => 'date' ,
'dismiss_date' => 'date' ,
];
// Or
protected $dates = [
'hire_date'
];
If I cast the Hire Date or any other date field then it Throws an exception, as if the validation is not checking the format ; e.g 2017-08-AA
A two digit hour could not be found Data missing" on line 582 of
.....nesbot\carbon\src\Carbon\Carbon.php
If I remove the attribute casting for dates the validation works as expected and throws a validation exception. A workaround to keep the casting was to use mutators for all date fields
public function setHireDateAttribute ( $date )
{
$this->attributes['hire_date'] = TZ::isValidateDate($date) ? $date : null;
}
So my question is there something wrong with the setup ? if not what is the point of the date or date_format validations if I have to do it manually.
I have a timestamp column, and I simply want to format it. In GridView I have the following:
[
'attribute' => 'timestamp',
'filter' => false,
'value' => function($model, $key, $index, $column) {
// How to get current timestamp value here???
}
],
Documentation says, $model and $column both return objects, but I still could not find methods that provide column's data. How would I go about this?
You can call any attribute through getter in closure using $model and that will return attribute for current model (according to row in GridView):
[
'attribute' => 'timestamp',
'filter' => false,
'value' => function($model, $key, $index, $column){
return $model->timestamp;
}
],
Obviously such return doesn't make any sense, but you can format it somehow you want. There are some built-in options for date / datetime formatting in Yii2, you can check them in official docs here:
Formatter asDate()
Formatter asDateTime()
I use the following with Yii 1:
[
'attribute' => 'timestamp',
'filter' => false,
'value' => 'Custom::formatDateTime($data->date_stamp)',
],
Obviously formatDateTime is a custom method I created.