I have an application build in Laravel where it sends notifications to users.
for Example when a new Post is created it sends notification to multiple users based on some conditions, the problem I'm facing is when multiple posts are create in small period of time for example 30 Minutes I don't want the user to get notified by lots of notifications,
I just want to update the count in last notification.
but I need to prevent creation of a new notification when I update the last notification.
here is what I have written.
public function toDatabase($notifiable): array
$count = 1;
if($notification = $notifiable->notifications()->where('data->search', $this->search->id)
->where('updated_at', '>=', now()->subMinutes(30))
->first()) {
$count = isset($notification->data['count']) ? $notification->data['count'] + 1 : 1;
$notification->update([
'data' => [
'content' => [
'en' => "{$count} new posts matched with your saved search {$this->search->title} has been posted, Press here to view more.",
],
'count' => $count
]
]);
}
return [
'content' => [
'en' => "{$count} new post matched with your saved search {$this->search->title} has been posted, Press here to view more.",
],
'count' => $count,
'search' => $this->search->id,
'parameters' => $this->search->parameters
];
}
How to prevent the code from reaching to return [] ?
maybe add another condition, maybe in your database add an column Last_send
and when executing it compares the current time from Last_send if time is greater than 30min you let it pass.
Related
I have a time tracking application where every time that a new Time Entry is about to be added, I must first verify that all the previous time entries have been closed (meaning that an ending date has been set) and throw and error message using the validate() method.
I don't know how feasable this is or how to do it, reading the documentation it seems that most custome rules require that an attribute be given, but in this case it's more about validating the logical requirements rather than the form of the post request.
When I receive a post request I fetch all previous time entries which come before the post request starting time and have not yet been given an ending time.
Ideally, if I get any time entries returned I would throw an error saying 'You need to close the previous time entry before opening a new one'.
For more clarity, here is what I want to do in code :
$timeEntry= new TimeEntry;
$openTimeEntries = $timeEntry->Where('start_time', '<', $request->startTime)->Where('end_time', 0)->get();
$count = $openTimeEntries->count();
$request->validate([
'comment' => 'string',
'candidateId' => 'required',
'startTime' => 'required|date',
'endTime' => 'date|nullable|after:startTime',
'CustomeTimeEntryRule' => $openTimeEntries->count() > 0, // If false I want this rule to add the message to the validate error array
]);
You are on the right track.
However, If you really customize validation you should create a request for here you can read more about it.
Simply call php artisan make:request TimeEntryStoreRequest
public function rules()
{
return [
'CustomeTimeEntryRule' => $openTimeEntries->count() > 0,
];
}
/**
* #return array|string[]
*/
public function messages(): array
{
return [
'CustomeTimeEntryRule.*' => 'Custom message',
];
}
However, if it is not a form input from a user I think you should check it inside your controller not in the form.
Also you can simplify your code like this:
use App\Models\TimeEntry;
$openTimeEntriesCount = TimeEntry::select('id')->where('start_time', '<', $request->startTime)->where('end_time', 0)->count();
A simple way to do this is to merge the custom attribute to the request :
$timeEntry= new TimeEntry;
$openTimeEntries = $timeEntry->Where('start_time', '<', $request->startTime)->Where('end_time', 0)->get();
$count = $openTimeEntries->count();
$request->merge([
'CustomeTimeEntryRule' => $count,
]);
Then we can validate the attribute using the in rule, which will return a custom validation message which we can specify as a second argument, when the count is not equal to 0:
$request->validate([
'comment' => 'string',
'candidateId' => 'required',
'startTime' => 'required|date',
'endTime' => 'date|nullable|after:startTime',
'CustomeTimeEntryRule' => 'in:0',
], [
'CustomeTimeEntryRule.in' => 'You need to close the previous time entry before opening a new one'
]);
I've got a table called Sides which consists of id, name, side_category_id and some other fields not important at the moment.
I wanted to validate that when creating a new side record, the record doesn't exist already. So, let's say I've got in the database a record such as:
id: 1
name: Salad
side_category_id: 3
If I try to insert a new record with name = 'salad' and side_category_id = 3 then the creation must fail and return an error.
I've achieved this by using the following rule:
$rules = [
'name' => 'required',
'side_category_id' => 'required|exists:side_categories,id|unique:sides,side_category_id,NULL,id,name,' . $this->request->get('name')
]
So far so good. It works as it's supposed to. But now it's returning an error if I want to edit a record and save it without any modifications and this is not my desired outcome.
If I try to update the record with no modifications it should succeed. How can I update my rule to achieve this?
you can use Rule::unique()
for create use like this
$rules = [
'name' => ['required'],
'side_category_id' => ['required',Rule::unique('sides', 'name')->where(function ($query) use($category_id) {
return $query->where('side_category_id', $category_id);
}),Rule::exists('side_categories')]
]
for update
$rules = [
'name' => ['required'],
'side_category_id' => ['required',Rule::unique('sides', 'name')->where(function ($query) use($category_id) {
return $query->where('side_category_id', $category_id);
})->ignore($id),Rule::exists('side_categories')]
]
//$id should be you parameter
At the moment I am adding a task to Cerb using the API (Docs: https://cerb.ai/docs/api/). I can add and edit comments on the task.
An extension is to add file uploads. The API documentation seems to be extremely limited in terms of file uploads and isn't helping much. I have based my current code on https://cerb.ai/docs/api/endpoints/records/#update, using a custom field linked to the task and posting directly to the API.
The process is as follows:
1 - User inserts information on a Laravel form
2 - Form is submitted, task is created
3 - If the user entered a comment or description, the controller then uses the ID from the newly created task toa dd the comment
4 - If the user adds a file, the controller should then use the same ID from the task to attach the file
Task and comment adding has been done through models, which were previously done directly through the API and reformatted once they worked.
Add Task:
$params = [
'title' => $request->input('title'),
'links' => ['project:'.$request->input('project')],
'priority' => $request->input('priority'),
'status_id' => 2
];
$due_date = $request->input('due');
if(!empty($due_date)){
$params['due'] = strtotime($due_date);
}
$success_task = $task->addUpdateRecord('tasks.add', $params);
Add Comment:
$params = [
'author__context' => 'bot',
'author_id' => 3,
'comment' => empty($comment_input) ? request()->comment : $comment_input,
'target__context' => 'task',
'target_id' => $task_id,
'author' => Auth::user()->name // custom field
];
$success = $comment->addUpdateRecord('comments.add', $params);
The addUpdateRecord() essentially does the same thing as the file upload as below:
$cerb = new CerbApi();
$out = $cerb->put($root.'records/file_bundle/1054.json?expand=custom_', $putfields);
$putfields contains a normal file upload object.
I'm getting the following error on request:
array:2 [▼
"__status" => "error"
"message" => "Unknown command (root/records/task/1054.json)"
]
(root removed for confidentiality)
Has anyone worked with this? Anyone able to assist?
Ended up getting it right by using the attachments record type https://cerb.ai/docs/records/types/attachment/ and creating a model for it with its own addUpdateRecord() method.
I then used the records API to do the post for the file as the first step instead of the last one:
$file_upload = new File;
// Get file contents
$data = file_get_contents($file);
// Base64 encode contents
$data = base64_encode($data);
$file_params = [
'name' => $file->getClientOriginalName(),
'content' => $data
];
// Do upload
$file_success = $file_upload->addUpdateRecord('files.add', $file_params);
// Only need to return the file ID to link it to the task
return $file_success["data"]["id"];
And then using the ID that was being returned to link it to the task:
$task = new Task();
$params = [
'title' => $request->input('title'),
'links' => [
'project:'.$request->input('project'),
'file:'.$file_id
],
'priority' => $request->input('priority'),
'status_id' => 2
];
I hope this helps someone in the future.
Note: Cerb API Version 9.2.0
I need get all posts from the current day (today), with the find below I'm not getting anything because the field pub_date (datetime) has time and the new \Datetime() returns the current date and time so, the date will match but the time not.
$posts = $this->find('all', [
'fields' => [
'Posts.id',
'Posts.title',
'Posts.body',
'Posts.pub_date',
],
'conditions' => [
'Posts.is_active' => true,
'Posts.pub_date' => new \Datetime()
],
]);
In short terms, I need get all posts with date equal "today" dont matter the time.
I want to create a small widget which displays the last 3 user registrations in PyroCMS.
What I actually need more specifically is how to get the last 3 registered user IDs, displaying user data would not be a problem.
Managed to get it working this way:
$this->load->driver('Streams');
$params = array(
'stream' => 'profiles',
'namespace' => 'users',
'limit' => '3'
);
$entries = $this->streams->entries->get_entries($params);