/home/techb158/public_html/wp-content/plugins/kirki/app/Services
Edit: /home/techb158/public_html/wp-content/plugins/kirki/app/Services/CollaborationCommentService.php (9869B)
collaboration_service = $collaboration_service;
}
/**
* Whether the current user may manage (resolve/delete) a comment: its
* author, or a user with an editor/administrator role. Optionally also
* checks the comment belongs to the given post.
*
* @param int|null $comment_id
* @param int|null $post_id
* @return bool
*/
public function can_manage_comment(?int $comment_id, ?int $post_id = null): bool
{
$comment = CollaborationComment::find($comment_id);
if (!$comment || ($post_id && $comment->post_id !== $post_id)) {
return false;
}
$is_author = $comment->user_id === user()->get_id();
return $is_author || user()->has_access(AccessLevels::FULL_ACCESS);
}
/**
* Paginate the top-level comments of a post.
*
* @param CollaborationCommentListFilterDTO $filters
* @return \Kirki\Framework\Database\Query\Paginator
*/
public function paginated(CollaborationCommentListFilterDTO $filters)
{
$query = CollaborationComment::query()->where('parent_id', 0);
if (!empty($filters->post_id)) {
$query->where('post_id', $filters->post_id);
}
$query->with(
[
'replies' => function (QueryBuilder $query) {
$query->oldest();
},
'seen' => function (QueryBuilder $query) use ($filters) {
$query->where('user_id', $filters->user_id);
},
]
)->latest();
return $query->paginate($filters->limit, $filters->page);
}
/**
* Find a single comment with its replies and read status for the given viewer.
*
* @param int $id
* @param int $current_user_id
* @return CollaborationComment|null
*/
public function get_single(int $id, int $current_user_id)
{
return CollaborationComment::with([
'replies' => function (QueryBuilder $query) {
$query->oldest();
},
'seen' => function ($query) use ($current_user_id) {
$query->where('user_id', $current_user_id);
},
])->find($id);
}
/**
* Create a comment (or reply) and broadcast the collaboration update.
*
* @param CreateCollaborationCommentDTO $dto
* @return CollaborationComment
*/
public function create(CreateCollaborationCommentDTO $dto)
{
$data = $dto->all();
$comment = CollaborationComment::create($data);
if ($dto->parent_id === 0) {
CollaborationCommentSeen::create([
'user_id' => $dto->user_id,
'comment_id' => $comment->id,
]);
} else {
CollaborationCommentSeen::where('comment_id', $dto->parent_id)
->where_not('user_id', $dto->user_id)
->delete();
}
$comment = $this->get_single($comment->id, $dto->user_id);
$data = [
'type' => 'COLLABORATION_ADD_KIRKI_COMMENT',
'payload' => [
'comment' => array_merge(CollaborationCommentResource::make($comment), ['read' => 0]),
],
];
$this->collaboration_service->save_action(CreateCollaborationDTO::from_array([
'parent' => 'post',
'parent_id' => $dto->post_id,
'data' => $data,
'session_id' => $dto->session_id,
]));
return $comment;
}
/**
* Update a comment's status (e.g. mark resolved, unresolved) and broadcast the update.
*
* @param ResolveCollaborationCommentDTO $dto
* @return CollaborationComment|null
*/
public function resolve(ResolveCollaborationCommentDTO $dto)
{
CollaborationComment::where('id', $dto->id)->update(['status' => $dto->status]);
$data = [
'type' => 'COLLABORATION_UPDATE_KIRKI_COMMENT',
'payload' => [
'data' => ['status' => $dto->status],
'id' => $dto->id,
],
];
$this->collaboration_service->save_action(CreateCollaborationDTO::from_array([
'parent' => 'post',
'parent_id' => $dto->post_id,
'data' => $data,
'session_id' => $dto->session_id,
]));
return $this->get_single($dto->id, $dto->user_id);
}
/**
* Mark a comment as read by a user.
*
* @param int $id
* @param int $user_id
* @return CollaborationComment|null
*/
public function mark_read(int $id, int $user_id)
{
$comment = CollaborationComment::find($id);
if (empty($comment)) {
throw new NotFoundException((__('No comment found', 'kirki')));
}
CollaborationCommentSeen::first_or_create([
'comment_id' => $id,
'user_id' => $user_id,
]);
return $this->get_single($id, $user_id);
}
/**
* Mark a comment as unread by a user.
*
* @param int $id
* @param int $user_id
* @return CollaborationComment|null
*/
public function mark_unread(int $id, int $user_id)
{
CollaborationCommentSeen::where('comment_id', $id)->where('user_id', $user_id)->delete();
return $this->get_single($id, $user_id);
}
/**
* Delete a comment (and its replies), only when the current user is the
* author or has an editor/administrator role.
*
* @param DeleteCollaborationCommentDTO $dto
* @return bool|Throwable
*/
public function delete(DeleteCollaborationCommentDTO $dto)
{
CollaborationComment::where('id', $dto->id)->or_where('parent_id', $dto->id)->delete();
$data = [
'type' => 'COLLABORATION_DELETE_KIRKI_COMMENT',
'payload' => ['id' => (string) $dto->id],
];
$this->collaboration_service->save_action(CreateCollaborationDTO::from_array([
'parent' => 'post',
'parent_id' => $dto->post_id,
'data' => $data,
'session_id' => $dto->session_id,
]));
return true;
}
/**
* Mark every top-level comment of a post as read by a user.
*
* @param int $post_id
* @param int $user_id
* @return bool
*/
public function mark_all_read(int $post_id, int $user_id)
{
$comment_ids = CollaborationComment::query()
->where('post_id', $post_id)
->where('parent_id', 0)
->pluck('id')
->all();
if (empty($comment_ids)) {
return false;
}
$rows = array_map(function ($comment_id) use ($user_id) {
return ['user_id' => $user_id, 'comment_id' => $comment_id];
}, $comment_ids);
CollaborationCommentSeen::upsert($rows, ['user_id']);
return true;
}
/**
* Resolve every top-level comment of a post and broadcast the update.
*
* @param int $post_id
* @param string $session_id
* @return bool
*/
public function resolve_all(int $post_id, string $session_id)
{
$status = CollaborationCommentResolveStatus::RESOLVED;
CollaborationComment::where('post_id', $post_id)->where('parent_id', 0)->update(['status' => $status]);
$data = [
'type' => 'COLLABORATION_UPDATE_ALL_KIRKI_COMMENT',
'payload' => ['data' => ['status' => $status]],
];
$this->collaboration_service->save_action(CreateCollaborationDTO::from_array([
'parent' => 'post',
'parent_id' => $post_id,
'data' => $data,
'session_id' => $session_id,
]));
return true;
}
/**
* Search users that have at least view access, for the @mention picker.
*
* @param string $query
* @param int $limit
* @return array
*/
public function search_users(string $query, int $limit)
{
$roles = Role::get_roles_by_levels([
AccessLevels::FULL_ACCESS,
AccessLevels::CONTENT_ACCESS,
AccessLevels::VIEW_ACCESS,
]);
return get_users([
'role__in' => $roles,
'orderby' => 'display_name',
'order' => 'ASC',
'number' => $limit,
'search' => '*' . $query . '*',
'search_columns' => ['user_login', 'user_nicename', 'display_name', 'user_email'],
]); // @todo: Update this if we plan to use our own User model to handle user related query
}
}