minor fix

master
Константин 2024-01-19 11:57:58 +03:00
parent 427b3eb321
commit 5ac858fcd0
14 changed files with 1191 additions and 364 deletions

45
app/Models/Chats/Chat.php Normal file
View File

@ -0,0 +1,45 @@
<?php
namespace App\Models\Chats;
use App\Models\User;
use App\Support\UuidScopeTrait;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
class Chat extends Model {
use UuidScopeTrait, SoftDeletes;
protected $dates = [
];
protected $fillable = [
'uuid',
'manager_id',
'client_id'
];
protected $hidden = [
'id'
];
public function manager(): BelongsTo {
return $this->belongsTo(User::class);
}
public function client(): BelongsTo {
return $this->belongsTo(Client::class);
}
public function messages(): HasMany {
return $this->hasMany(Message::class);
}
}

View File

@ -0,0 +1,25 @@
<?php
namespace App\Models\Chats;
use App\Support\UuidScopeTrait;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Client extends Model {
use UuidScopeTrait, SoftDeletes;
protected $dates = [
];
protected $fillable = [
'uuid',
'name',
'email'
];
protected $hidden = [
'id'
];
}

View File

@ -0,0 +1,44 @@
<?php
namespace App\Models\Chats;
use App\Models\User;
use App\Support\UuidScopeTrait;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
class Message extends Model {
use UuidScopeTrait, SoftDeletes;
protected $dates = [
'read_at'
];
protected $fillable = [
'uuid',
'chat_id',
'manager_id',
'client_id',
'content',
'read_at'
];
protected $hidden = [
'id'
];
public function chat(): BelongsTo {
return $this->belongsTo(Chat::class);
}
public function manager(): BelongsTo {
return $this->belongsTo(User::class);
}
public function client(): BelongsTo {
return $this->belongsTo(Client::class);
}
}

View File

@ -8,8 +8,6 @@ use App\Models\Advisories\AdvisoryMember;
use App\Models\Applications\Conclusion; use App\Models\Applications\Conclusion;
use App\Models\Companies\Company; use App\Models\Companies\Company;
use App\Models\Companies\CompanyMember; use App\Models\Companies\CompanyMember;
use App\Models\Companies\CompanyMemberRole;
use App\Models\Objects\Field;
use App\Support\HasRolesUuid; use App\Support\HasRolesUuid;
use App\Support\HasSocialLogin; use App\Support\HasSocialLogin;
use App\Support\RelationValuesTrait; use App\Support\RelationValuesTrait;
@ -27,10 +25,12 @@ use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use Laravel\Passport\HasApiTokens; use Laravel\Passport\HasApiTokens;
use RTippin\Messenger\Contracts\MessengerProvider;
use RTippin\Messenger\Traits\Messageable;
use Spatie\Permission\Traits\HasRoles; use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable { class User extends Authenticatable implements MessengerProvider {
use Notifiable, UuidScopeTrait, HasFactory, HasApiTokens, HasRoles, SoftDeletes, HasSocialLogin, RelationValuesTrait, HasRolesUuid { use Notifiable, UuidScopeTrait, HasFactory, HasApiTokens, HasRoles, SoftDeletes, HasSocialLogin, RelationValuesTrait, Messageable, HasRolesUuid {
HasRolesUuid::getStoredRole insteadof HasRoles; HasRolesUuid::getStoredRole insteadof HasRoles;
} }
@ -81,6 +81,11 @@ class User extends Authenticatable {
} }
public function scopeByEmail($query, string $email) {
return $query->where(['email' => $email]);
}
public function getInitialsAttribute(): string { public function getInitialsAttribute(): string {
return collect(explode(' ', $this->name))->slice(0, 2)->map(function($item) { return collect(explode(' ', $this->name))->slice(0, 2)->map(function($item) {
return Str::upper(Str::substr($item, 0, 1)); return Str::upper(Str::substr($item, 0, 1));
@ -164,4 +169,18 @@ class User extends Authenticatable {
Mail::to($this->email)->send(new PasswordResetRequested($this, $token)); Mail::to($this->email)->send(new PasswordResetRequested($this, $token));
} }
public static function getProviderSettings(): array {
return [
'alias' => 'user',
'searchable' => true,
'friendable' => true,
'devices' => true,
'default_avatar' => public_path('vendor/messenger/images/users.png'),
'cant_message_first' => [],
'cant_search' => [],
'cant_friend' => [],
];
}
} }

View File

@ -19,7 +19,7 @@ use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvi
class EventServiceProvider extends ServiceProvider { class EventServiceProvider extends ServiceProvider {
protected $listen = [ protected $listen = [
Registered::class => [ Registered::class => [
SendEmailVerificationNotification::class, SendEmailVerificationNotification::class
], ],
UserRegistered::class => [ UserRegistered::class => [
SendRegistrationNotification::class SendRegistrationNotification::class

View File

@ -0,0 +1,41 @@
<?php
namespace App\Providers;
use App\Models\User;
use Illuminate\Support\ServiceProvider;
use RTippin\Messenger\Facades\Messenger;
use RTippin\Messenger\Facades\MessengerBots;
/**
* Laravel Messenger System, Created by: Richard Tippin.
* @link https://github.com/RTippin/messenger
* @link https://github.com/RTippin/messenger-bots
* @link https://github.com/RTippin/messenger-faker
* @link https://github.com/RTippin/messenger-ui
*/
class MessengerServiceProvider extends ServiceProvider {
/**
* Bootstrap services.
*
* @return void
*/
public function boot() {
Messenger::registerProviders([
User::class,
]);
// Set the video call driver of your choosing.
// Messenger::setVideoDriver(MyVideoBroker::class);
// Register bot handlers you wish to use. You can install the messenger-bots addon for ready-made handlers.
MessengerBots::registerHandlers([
//
]);
// Register the packaged bots you wish to use.
MessengerBots::registerPackagedBots([
//
]);
}
}

View File

@ -0,0 +1,39 @@
<?php
namespace App\Transformers\Chats;
use App\Models\Chats\Chat;
use App\Transformers\Users\UserTransformer;
use League\Fractal\Resource\Collection;
use League\Fractal\Resource\Item;
use League\Fractal\TransformerAbstract;
class ChatTransformer extends TransformerAbstract {
protected array $defaultIncludes = [];
protected array $availableIncludes = [
'manager', 'client', 'messages'
];
public function transform(Chat $model): array {
return [
'id' => $model->uuid,
'content' => $model->content,
'created_at' => $model->created_at ? $model->created_at->toIso8601String() : null
];
}
public function includeManager(Chat $model): ?Item {
return $model->manager ? $this->item($model->manager, new UserTransformer()) : null;
}
public function includeClient(Chat $model): ?Item {
return $model->client ? $this->item($model->client, new ClientTransformer()) : null;
}
public function includeMessages(Chat $model): Collection {
return $this->collection($model->messages, new MessageTransformer());
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace App\Transformers\Chats;
use App\Models\Chats\Client;
use League\Fractal\TransformerAbstract;
class ClientTransformer extends TransformerAbstract {
protected array $defaultIncludes = [];
protected array $availableIncludes = [
];
public function transform(Client $model): array {
return [
'id' => $model->uuid,
'name' => $model->name,
'email' => $model->email
];
}
}

View File

@ -0,0 +1,40 @@
<?php
namespace App\Transformers\Chats;
use App\Models\Chats\Message;
use App\Transformers\Users\UserTransformer;
use League\Fractal\Resource\Item;
use League\Fractal\TransformerAbstract;
class MessageTransformer extends TransformerAbstract {
protected array $defaultIncludes = [];
protected array $availableIncludes = [
'chat', 'manager', 'client'
];
public function transform(Message $model): array {
return [
'id' => $model->uuid,
'content' => $model->content,
'created_at' => $model->created_at ? $model->created_at->toIso8601String() : null,
'updated_at' => $model->updated_at ? $model->updated_at->toIso8601String() : null,
'read_at' => $model->read_at ? $model->read_at->toIso8601String() : null
];
}
public function includeChat(Message $model): ?Item {
return $model->chat ? $this->item($model->chat, new ChatTransformer()) : null;
}
public function includeManager(Message $model): ?Item {
return $model->manager ? $this->item($model->manager, new UserTransformer()) : null;
}
public function includeClient(Message $model): ?Item {
return $model->client ? $this->item($model->client, new ClientTransformer()) : null;
}
}

View File

@ -35,6 +35,7 @@
"maatwebsite/excel": "^3.1", "maatwebsite/excel": "^3.1",
"movemoveapp/laravel-dadata": "^1.0", "movemoveapp/laravel-dadata": "^1.0",
"phpoffice/phpword": "^1.0", "phpoffice/phpword": "^1.0",
"rtippin/messenger": "^1.19",
"seyyedam7/laravel-html-parser": "^3.1", "seyyedam7/laravel-html-parser": "^3.1",
"spatie/laravel-fractal": "^5.8", "spatie/laravel-fractal": "^5.8",
"spatie/laravel-permission": "^3.17", "spatie/laravel-permission": "^3.17",

893
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -148,6 +148,7 @@ return [
App\Providers\AuthServiceProvider::class, App\Providers\AuthServiceProvider::class,
// App\Providers\BroadcastServiceProvider::class, // App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class, App\Providers\EventServiceProvider::class,
App\Providers\MessengerServiceProvider::class,
App\Providers\RouteServiceProvider::class, App\Providers\RouteServiceProvider::class,
Barryvdh\DomPDF\ServiceProvider::class, Barryvdh\DomPDF\ServiceProvider::class,
], ],

371
config/messenger.php Normal file
View File

@ -0,0 +1,371 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Provider UUIDs
|--------------------------------------------------------------------------
|
| All of our tables that have relations to one of your providers will use
| a morphTo. If your providers use UUIDs (char 36) as their primary keys,
| then set this to true. Please note that if you use multiple providers,
| they all must have matching primary key types (int / char / etc).
|
*/
'provider_uuids' => true,
/*
|--------------------------------------------------------------------------
| Filesystem settings for provider avatars and thread files
|--------------------------------------------------------------------------
|
| For each option below, please select the filesystem disk and leading
| directory you wish you use.
|
| *The "avatars" is where each provider's uploaded profile images are stored.
| By default, this will store into the following path
| prefixed by the directory:
|
| **Provider avatars - storage_path('app/public/images/{alias}/{id}')
|
| *The "threads" is where we store any uploads pertaining to a given thread,
| such as images, documents, and audio files. By using the default config
| below, thread files will be stored in the following paths prefixed by
| the directory:
|
| **Avatar - storage_path('app/public/threads/{threadID}/avatar')
| **Images - storage_path('app/public/threads/{threadID}/images')
| **Documents - storage_path('app/public/threads/{threadID}/documents')
| **Audio - storage_path('app/public/threads/{threadID}/audio')
| **Video - storage_path('app/public/threads/{threadID}/videos')
| **Bots - storage_path('app/public/threads/{threadID}/bots/{botID}')
|
*/
'storage' => [
'avatars' => [
'disk' => 'public',
'directory' => 'images',
],
'threads' => [
'disk' => 'public',
'directory' => 'threads',
],
],
/*
|--------------------------------------------------------------------------
| Messenger routing config
|--------------------------------------------------------------------------
|
| Our API is the core of this package, and bootstrap's all of our policies
| and controllers for you. The included middleware 'messenger.provider'
| simply takes the authenticated user via the request and sets them
| as the current messenger provider. You are free to use your own
| custom middleware to set your provider, as well as any other
| middleware you may want, such as 'auth:api' etc.
|
| All API routes return json, and are best used stateless through
| auth:api such as passport or sanctum.
|
| Invite api has individual middleware control, giving fine-grain control
| such as allowing both guest and authed users to access.
|
| *For the broadcasting channels to register, you must have already
| setup/defined your laravel apps broadcast driver.
|
*/
'routing' => [
'api' => [
'domain' => null,
'prefix' => 'api/messenger',
'middleware' => ['web', 'auth', 'messenger.provider:required'],
'invite_api_middleware' => ['web', 'messenger.provider'],
],
'assets' => [
'domain' => null,
'prefix' => 'messenger/assets',
'middleware' => ['web', 'cache.headers:public, max-age=86400;'],
],
'channels' => [
'enabled' => true,
'domain' => null,
'prefix' => 'api',
'middleware' => ['web', 'auth', 'messenger.provider:required'],
],
],
/*
|--------------------------------------------------------------------------
| Use Absolute Route Paths
|--------------------------------------------------------------------------
|
| Whether routes generated from messenger use the absolute or shortened path.
|
*/
'use_absolute_routes' => env('MESSENGER_USE_ABSOLUTE_ROUTES', false),
/*
|--------------------------------------------------------------------------
| API rate limits / request per minute allowed. Use 0 for unlimited
|--------------------------------------------------------------------------
|
*/
'rate_limits' => [
'api' => 1000, // Applies over entire API
'search' => 45, // Applies on search
'message' => 60, // Applies to sending messages per thread
'attachment' => 15, // Applies to uploading images/documents per thread
],
/*
|--------------------------------------------------------------------------
| Max allowed characters for Message body / Edit Message body.
|--------------------------------------------------------------------------
|
*/
'message_size_limit' => env('MESSENGER_MESSAGE_SIZE_LIMIT', 5000),
/*
|--------------------------------------------------------------------------
| File toggles to enable / disable features and default image paths.
| Size limits are the max upload size in kilobytes.
|--------------------------------------------------------------------------
|
*/
'files' => [
'message_documents' => [
'upload' => env('MESSENGER_MESSAGE_DOCUMENT_UPLOAD', true),
'size_limit' => env('MESSENGER_MESSAGE_DOCUMENT_SIZE_LIMIT', 10240),
'mime_types' => env('MESSENGER_MESSAGE_DOCUMENT_MIME_TYPES', 'csv,doc,docx,json,pdf,ppt,pptx,rar,rtf,txt,xls,xlsx,xml,zip,7z'),
],
'message_images' => [
'upload' => env('MESSENGER_MESSAGE_IMAGE_UPLOAD', true),
'size_limit' => env('MESSENGER_MESSAGE_IMAGE_SIZE_LIMIT', 5120),
'mime_types' => env('MESSENGER_MESSAGE_IMAGE_MIME_TYPES', 'jpg,jpeg,png,bmp,gif,webp'),
],
'message_audio' => [
'upload' => env('MESSENGER_MESSAGE_AUDIO_UPLOAD', true),
'size_limit' => env('MESSENGER_MESSAGE_AUDIO_SIZE_LIMIT', 10240),
'mime_types' => env('MESSENGER_MESSAGE_AUDIO_MIME_TYPES', 'aac,mp3,oga,ogg,wav,weba,webm'),
],
'message_videos' => [
'upload' => env('MESSENGER_MESSAGE_VIDEO_UPLOAD', true),
'size_limit' => env('MESSENGER_MESSAGE_VIDEO_SIZE_LIMIT', 15360),
'mime_types' => env('MESSENGER_MESSAGE_VIDEO_MIME_TYPES', 'avi,mp4,ogv,webm,3gp,3g2,wmv,mov'),
],
'avatars' => [
'providers' => env('MESSENGER_PROVIDER_AVATARS_ENABLED', true),
'threads' => env('MESSENGER_THREAD_AVATARS_ENABLED', true),
'bots' => env('MESSENGER_BOT_AVATARS_ENABLED', true),
'size_limit' => env('MESSENGER_AVATARS_SIZE_LIMIT', 5120),
'mime_types' => env('MESSENGER_AVATARS_MIME_TYPES', 'jpg,jpeg,png,bmp,gif,webp'),
],
'default_not_found_image' => public_path('vendor/messenger/images/image404.png'),
'default_ghost_avatar' => public_path('vendor/messenger/images/users.png'),
'default_thread_avatar' => public_path('vendor/messenger/images/threads.png'),
'default_bot_avatar' => public_path('vendor/messenger/images/bots.png'),
],
/*
|--------------------------------------------------------------------------
| Calling
|--------------------------------------------------------------------------
| Enable or disable the calling feature. If enabled, you must also declare
| the driver we will use within a boot method from one of your service
| providers. You may use our messenger facade to set the driver.
|
| Messenger::setVideoDriver(JanusBroker::class);
|
| We provide an event subscriber to listen and react to calling events. You
| may choose to enable it, whether it puts jobs on the queue or not, and
| which queue channel its jobs are dispatched on.
*/
'calling' => [
'enabled' => env('MESSENGER_CALLING_ENABLED', false),
'subscriber' => [
'enabled' => true,
'queued' => true,
'channel' => 'messenger',
],
],
/*
|--------------------------------------------------------------------------
| System Messages
|--------------------------------------------------------------------------
|
| Enable or disable system messages. These are messages generated by actions
| to give feedback in the thread history. Actions such as: call ended, left
| group, promoted admin, etc.
|
| We provide an event subscriber to listen and react to events that will
| generate the system messages. You may choose to enable it, whether it
| puts jobs on the queue or not, and which queue channel its jobs are
| dispatched on.
*/
'system_messages' => [
'enabled' => env('MESSENGER_SYSTEM_MESSAGES_ENABLED', true),
'subscriber' => [
'enabled' => true,
'queued' => true,
'channel' => 'messenger',
],
],
/*
|--------------------------------------------------------------------------
| Bots
|--------------------------------------------------------------------------
|
| Enable or disable the bots feature. When enabled, bots may be created
| within group threads. A bot may contain many actions with triggers
| that will respond to a message.
|
| We provide an event subscriber to listen and react to events that may
| trigger a bot response. You may choose to enable it, whether it puts
| jobs on the queue or not, and which queue channel its jobs are
| dispatched on.
*/
'bots' => [
'enabled' => env('MESSENGER_BOTS_ENABLED', false),
'subscriber' => [
'enabled' => true,
'queued' => true,
'channel' => 'messenger-bots',
],
],
/*
|--------------------------------------------------------------------------
| Push Notification Events
|--------------------------------------------------------------------------
|
| Enable or disable firing our push notification event for every broadcast
| that is not sent over presence. This system only works if you are using
| our default BroadcastBroker for our broadcast driver.
*/
'push_notifications' => env('MESSENGER_PUSH_NOTIFICATIONS_ENABLED', false),
/*
|--------------------------------------------------------------------------
| Thread Verifications | Friendship Checks
|--------------------------------------------------------------------------
|
| Enable or disable friendship checks for threads.
|
| If enabled for private threads, the thread will be marked as pending upon
| creation if the two participants are not friends. The recipient will then
| have the option to accept or deny the new private thread request.
|
| If enabled for group threads, only friends of the active participant may
| be added to the group, otherwise any valid messenger provider may be
| added as a participant.
*/
'thread_verifications' => [
'private_thread_friendship' => env('MESSENGER_VERIFY_PRIVATE_THREAD_FRIENDSHIP', true),
'group_thread_friendship' => env('MESSENGER_VERIFY_GROUP_THREAD_FRIENDSHIP', true),
],
/*
|--------------------------------------------------------------------------
| Message Edits
|--------------------------------------------------------------------------
|
| Enable or disable the edit message feature. When enabled, the owner of a
| message will be allowed to edit that message. A history of the edits will
| be stored, should you enable our default queued_event_listeners. You may
| also allow/deny users in a thread to view the edit history of the message.
|
*/
'message_edits' => [
'enabled' => env('MESSENGER_MESSAGE_EDITS_ENABLED', true),
'history_view' => env('MESSENGER_MESSAGE_EDITS_VIEW_HISTORY', true),
],
/*
|--------------------------------------------------------------------------
| Message Reactions
|--------------------------------------------------------------------------
|
| Enable or disable the message reactions feature and the max unique allowed
| per message. This feature behaves similar to discord, where a single user
| may react to a single message more than once with different emotes.
|
*/
'message_reactions' => [
'enabled' => env('MESSENGER_MESSAGE_REACTIONS_ENABLED', true),
'max_unique' => env('MESSENGER_MESSAGE_REACTIONS_MAX_UNIQUE', 10),
],
/*
|--------------------------------------------------------------------------
| Thread invitations
|--------------------------------------------------------------------------
|
| Enable or disable thread invites. You may also set the max active
| invites each thread may have at any given time. 0 for unlimited
|
*/
'invites' => [
'enabled' => env('MESSENGER_INVITES_ENABLED', true),
'max_per_thread' => env('MESSENGER_INVITES_THREAD_MAX', 3),
],
/*
|--------------------------------------------------------------------------
| Knock knock!! 👊
|--------------------------------------------------------------------------
|
| Enable or disable knocks, and set the timeout limit (in minutes).
| Set to 0 for no timeout.
|
*/
'knocks' => [
'enabled' => env('MESSENGER_KNOCKS_ENABLED', true),
'timeout' => env('MESSENGER_KNOCKS_TIMEOUT', 5),
],
/*
|--------------------------------------------------------------------------
| Provider online/away status
|--------------------------------------------------------------------------
|
| Enable or disable showing online/away states, and set the lifetime the
| status will live in cache (in minutes)
|
*/
'online_status' => [
'enabled' => env('MESSENGER_ONLINE_STATUS_ENABLED', true),
'lifetime' => env('MESSENGER_ONLINE_STATUS_LIFETIME', 4),
],
/*
|--------------------------------------------------------------------------
| Resource collection results limit
|--------------------------------------------------------------------------
|
| Here you can define the default query limits for resource collections
|
*/
'collections' => [
'search' => [
'page_count' => 25,
],
'threads' => [
'index_count' => 100,
'page_count' => 25,
],
'participants' => [
'index_count' => 500,
'page_count' => 50,
],
'messages' => [
'index_count' => 50,
'page_count' => 50,
],
'calls' => [
'index_count' => 25,
'page_count' => 25,
],
],
];

View File

@ -11,7 +11,7 @@ class UsersTableSeeder extends Seeder {
]; ];
public array $admins = [ public array $admins = [
['email' => 'admin@test.ru', 'name' => 'Админ Админович Админов', 'password' => 'DybgEs'] ['email' => 'admin@nirgroup.ru', 'name' => 'Администратор', 'password' => '4bvlxE0p']
]; ];