This commit is contained in:
mobin
2026-04-08 07:22:13 +00:00
parent 2adb741dac
commit a6b5f27343
30300 changed files with 134406 additions and 1504 deletions
+361
View File
@@ -0,0 +1,361 @@
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cookie;
use Illuminate\Support\Facades\Redis;
use Illuminate\Console\View\Components\Task;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Response;
use App\Models\Attendance;
use \App\Models\AttendanceBreak;
use App\Models\ai;
use Illuminate\Support\Facades\Http;
use Morilog\Jalali\Jalalian;
use GuzzleHttp\Client;
use App\Models\Tasks;
use App\Models\Pivot_Tasks;
class AdminController extends Controller
{
public function dashboard()
{
if (isset($_COOKIE['token-0'])) {
$uname = $_COOKIE['token-0'];
setcookie("user_identity", $_COOKIE['token-0'], time() + (60 * 60 * 24 * 365), '/');
Cookie::queue(Cookie::forget('token-0'));
} else
$uname = $_COOKIE['user_identity'];
$u = User::select('name', 'is_admin')
->where('user_name', $uname)
->first();
if ($u->is_admin == '1') {
setcookie('ad', '1', time() + (60 * 60 * 24 * 365 * 5), "/");
$users = User::wherenotnull('user_name')
->with('attendances')
->get();
$records = [];
foreach ($users as $user) {
$rec = [
"user_name" => $user->user_name,
"name" => $user->name,
"attendances" => []
];
foreach ($user->attendances as $attendance) {
$key = "att-tempreq:{$user->user_name}:{$attendance->id}";
$get = json_decode(Redis::get("{$key}"));
$date = $attendance->entered_at ? Carbon::parse($attendance->entered_at)->format('Y-m-d') : null;
if ($get)
if ($get->function != 'rejected')
$rec['attendances'][] = $get;
}
// $key = "att-tempreq:{$user->user_name}:new";
$create_requests_key = "att-tempreq:creates:{$user->user_name}";
$create_requests = Redis::connection()->lrange($create_requests_key, 0, -1); // خواندن تمام آیتم های لیست
foreach ($create_requests as $req_json) {
$get = json_decode($req_json);
if ($get && $get->function != 'rejected') {
$rec['attendances'][] = $get;
}
}
// $get = json_decode(Redis::get("{$key}"));
// if ($get) {
//// dd($get);
//
// if ($get->function != 'rejected')
//
// $rec['attendances'][] = $get;
// }
$records[] = $rec;
}
// dd($users);
// dd(json_decode($json,true));
return view("admin..admin")->with(['message', [
'color' => '#ff8800ff',
"text" => 'شما به پنل ادمین وارد شدید✔️'
],
"users" => $users,
'reqs' => $records
]);
}
return redirect()->back()->with('message', [
'color' => '#ff8800ff',
"text" => 'شما دسترسی به این صفحه را ندارید!'
]);
}
public function newUser()
{
// dd('hello world');
return view('admin.new');
}
public function addUser(Request $request)
{
// dd($request);
try {
$user = new User();
$user->name = $request->name;
$user->email = $request->email;
$user->user_name = $request->username;
$user->chatid = $request->chatid;
$user->number = $request->number;
$user->save();
return redirect(route('admin.dashboard'))->with('message', [
'color' => '#009900ff',
'text' => 'کاربر با موفقیت ایجاد شد✔️'
]);
} catch (\Exception $exception) {
return redirect(route('admin.dashboard'))->with('message', [
'color' => '#ff9900ff',
'text' => 'مقادیر وارد شده تکراری یا اشتباه است✖️'
]);
}
}
public function edit(Request $request)
{
// dd($request);
$allData = array_merge($request->all(), $request->query());
$converted = $this->fa2en_numbers($allData);
$request->merge($converted);
$id = $request->id;
$nstartt = $request->starttime;
$nendt = $request->endtime;
// dd($request);
if ($id == 'new') {
$user_name = $request->uname;
if($request->display_date == null){
$date = Carbon::now()->format('Y-m-d');
}else{
// dump($date);
$date = \Morilog\Jalali\CalendarUtils::convertNumbers($request->display_date, true);
$date = str_replace('/', '-', $date);
// dump($date);
$date = Jalalian::fromFormat('Y-m-d', $date)->toCarbon()->format('Y-m-d');
// $date = \Morilog\Jalali\CalendarUtils::createCarbonFromFormat('Y-m-d', $date)->format('Y-m-d');
}
if (($nendt > $nstartt) || ($nendt === null && $nstartt !== null)) {
$attendance = new Attendance();
$attendance->ip_address = 'admin-manual';
$attendance->user_identity = $user_name;
$attendance->entered_at = $nstartt ? $date . ' ' . $nstartt : null;
$attendance->exited_at = $nendt ? $date . ' ' . $nendt : null;
$attendance->duration = $nendt !== null ? $attendance->duration($nstartt, $nendt) : null;
$attendance->save();
return redirect()->back()->with('message', [
'color' => '#6aff00ff',
"text" => 'تغییرات با موفقیت ذخیره شد.✔️'
]);
} else {
return redirect()->back()->with('message', [
'color' => '#ff4400ff',
"text" => 'مقادیر اشتباه وارد شده است✖️'
]);
}
} else {
$attendance = Attendance::find($id);
$date = Carbon::parse($attendance->entered_at ?? $attendance->exited_at)->format('Y-m-d');
$ostartt = Carbon::parse($attendance->entered_at)->format('H:i');
$oendt = Carbon::parse($attendance->exited_at)->format('H:i');
if (($ostartt != $nstartt || $oendt != $nendt) && ($nendt != null ? $nendt > $nstartt : true)) {
$attendance->entered_at = $date . ' ' . $nstartt;
$attendance->exited_at = $nendt ? $date . ' ' . $nendt : null;
$attendance->duration = $nendt ? $attendance->duration($nstartt, $nendt) : null;
$attendance->save();
return redirect()->back()->with('message', [
'color' => '#6aff00ff',
"text" => 'تغییرات با موفقیت ذخیره شد.✔️'
]);
} else {
return redirect()->back()->with('message', [
'color' => '#ff4400ff',
"text" => 'مقادیر اشتباه وارد شده است✖️'
]);
}
}
}
public function delete(Request $request)
{
// dd($request);
$id = $request->id;
$attendance = Attendance::find($id);
if ($attendance) {
$attendance->delete();
return redirect()->back()->with('message', [
'color' => '#6aff00ff',
"text" => 'حذف با موفقیت انجام شد.✔️'
]);
} else {
return redirect()->back()->with('message', [
'color' => '#ff4400ff',
"text" => 'خطا در حذف رکورد✖️'
]);
}
}
public function update(Request $request)
{
// dd($request);
$data = json_decode($request->data);
if ($request->update == 'approve') {
if ($data->function == 'delete') {
$st = Attendance::find($data->id);
if ($st) {
$st->delete();
if ($st) {
tel_notif($st->user_identity, "تایید");
$create_requests_key = "att-tempreq:creates:{$data->userid}";
Redis::connection()->lrem($create_requests_key, 1, json_encode($data));
// Redis::connection()->del("att-tempreq:{$data->userid}:{$data->id}");
return redirect()->back()->with('message', [
'color' => '#6aff00ff',
'text' => 'رکورد با موفقیت حذف شد✔️'
]);
} else {
return redirect()->back()->with('message', [
'color' => '#ff8800ff',
'text' => 'حذف رکورد با شکست مواجه شد✖️️'
]);
}
} else {
return redirect()->back()->with('message', [
'color' => '#ff8800ff',
'text' => 'رکورد پیدا نشد✖️'
]);
}
} elseif ($data->function == 'edit') {
// dd($data);
$record = Attendance::find($data->id);
$attendance = new Attendance();
$date = Carbon::parse($record->entered_at)->format('Y-m-d');
$record->ip_address = 'admin-edited';
$record->user_identity = $data->userid;
$record->entered_at = $data->newenter ? $date . ' ' . $data->newenter : null;
if ($data->newexit != null) {
//جریمه
// if($data->newexit > '16:00:00'){
// $data->newexit = date('H:i:s', strtotime($data->newexit . ' -1 hour'));
// }
$record->exited_at = $date . ' ' . $data->newexit;
$record->duration = $attendance->duration($data->newenter, $data->newexit);
} else {
$record->exited_at = null;
$record->duration = null;
}
$record->requested = '';
$record->save();
$create_requests_key = "att-tempreq:creates:{$data->userid}";
Redis::connection()->lrem($create_requests_key, 1, json_encode($data));
// Redis::connection()->del("att-tempreq:{$data->userid}:{$data->id}");
tel_notif($record->user_identity, "تایید");
return redirect()->back()->with('message', [
'color' => '#6aff00ff',
"text" => 'رکورد با موفقیت ذخیره شد.✔️'
]);
} elseif ($data->function == 'new') {
// dd($data);
$starttime = $data->oldenter ? Carbon::parse($data->oldenter)->format('H:i:s') : null;
$endtime = $data->oldexit ? Carbon::parse($data->oldexit)->format('H:i:s') : null;
if (is_null($endtime) || $endtime > $starttime) {
$attendance = new Attendance();
$attendance->ip_address = 'admin-new';
$attendance->user_identity = $data->userid;
$attendance->entered_at = $data->oldenter ?: null;
$attendance->exited_at = $data->oldexit ?: null;
$attendance->duration = $data->oldexit ? $attendance->duration($data->oldenter, $data->oldexit) : null;
$attendance->save();
$create_requests_key = "att-tempreq:creates:{$data->userid}";
Redis::connection()->lrem($create_requests_key, 1, json_encode($data));
// Redis::connection()->del("att-tempreq:{$data->userid}:{$data->id}");
tel_notif($data->userid, "تایید");
return redirect()->back()->with('message', [
'color' => '#6aff00ff',
"text" => 'درخواست با موفقیت تایید شد.✔️'
]);
}
}
}
if ($request->update == 'reject') {
$create_requests_key = "att-tempreq:creates:{$data->userid}";
Redis::connection()->lrem($create_requests_key, 1, json_encode($data));
// Redis::connection()->del("att-tempreq:{$data->userid}:{$data->id}");
// dd($data->id);
if ($data->id !== "new") {
$att = Attendance::find($data->id);
// dd($att);
$att->requested = null;
$att->save();
}
tel_notif($data->userid, "رد");
return redirect()->back()->with('message', [
'color' => '#6aff00ff',
"text" => 'درخواست با موفقیت رد شد.✔️'
]);
}
}
private function fa2en_numbers($input) {
if (is_string($input)) {
$fa_numbers = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'];
$en_numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
return str_replace($fa_numbers, $en_numbers, $input);
} elseif (is_array($input)) {
return array_map([$this, __FUNCTION__], $input);
} else {
return $input;
}
}
}
function tel_notif($username, $status)
{
$message = "درخواست شما {$status} شد.";
$user = User::where('user_name', $username)->whereNotNull('chatid')->select('chatid', 'user_name')->first();
if ($user) {
Http::get("https://api.wwwapp.ir/telegran_send.php", [
'botToken' => "7467099619:AAF2V6yYcbAb8oSIRSCyH5i2GKfdWVO3a7k",
'chatId' => $user->chatid,
'message' => $message,
]);
}
}
@@ -0,0 +1,721 @@
<?php
namespace App\Http\Controllers;
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
use function PHPUnit\Framework\throwException;
use Illuminate\Support\Facades\Cookie;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Http;
use App\Models\AttendanceBreak;
use Morilog\Jalali\Jalalian;
use Illuminate\Http\Request;
use App\Models\Pivot_Tasks;
use App\Models\Attendance;
use App\Models\Tasks;
use App\Models\User;
use App\Models\Log;
use Carbon\Carbon;
use App\Models\ai;
class AttendanceController extends Controller
{
public function index()
{
if (isset($_COOKIE['user_identity'])) {
$Attendance = isset($_COOKIE['user_identity'])
? ($_COOKIE['user_identity'] == 1370
? Attendance::all()
: Attendance::where('user_identity', $_COOKIE['user_identity'])->get())
: collect();
$jalalian_object = Jalalian::now();
$first_day_of_month = $jalalian_object->subDays($jalalian_object->getDay() - 1);
$carbon_gregorian = $first_day_of_month->toCarbon();
$thismonth = $carbon_gregorian->format('Y-m-d 00:00:00');
$ids = json_decode(request()->cookie('seen_angizeh_ids', '[]'), true) ?: [];
$s = ai::where('key', 'angizeh')
->when($ids, fn($q) => $q->whereNotIn('id', $ids))
->orderByDesc('id')
->first()
?? ai::where('key', 'angizeh')->orderByDesc('id')->first();
$ids = array_merge($ids, [$s->id]);
Cookie::queue('seen_angizeh_ids', json_encode($ids), 14400);
//total time
$now = Jalalian::fromCarbon(Carbon::now());
$tsec = 0;
//dd(->user_profile);
if (isset($_COOKIE['token01'])) {
$a = json_decode($_COOKIE['token01']);
$user = User::where('user_name', $a->user_profile)->with('attendances')->first();
} else {
$user = isset($_COOKIE['user_identity']) ? User::where('user_name', $_COOKIE['user_identity'])->with('attendances')->first() : null;
}
//dd($user);
if (!empty($user->attendances)) {
foreach ($user->attendances as $att) {
$date = $att->entered_at != null ? Jalalian::fromCarbon(Carbon::parse($att->entered_at)) : null;
$att->date = $date != null ? $date->format('Y/m/d') : null;
if ($att->duration != null && $date != null && $now->getMonth() == $date->getMonth()) {
[$h, $m, $sec] = explode(':', $att->duration);
$tsec += $h * 3600 + $m * 60 + $sec;
}
}
}
$hours = floor($tsec / 3600);
$minutes = floor(($tsec % 3600) / 60);
$totalTime = sprintf('%02d:%02d', $hours, $minutes);
$formaction = (isset($_COOKIE['ad']) && $_COOKIE['ad'] == 1)
? 'admin/'
: 'attendance/';
$now = Carbon::now()->format('Y-m-d 00:00:00');
$existed = $Attendance->whereNull('exited_at')->where('entered_at', '>=', $now)->first();
$user = User::where('user_name', $_COOKIE['user_identity'])->first();
$until_now = null;
if ($user->break == 1) {
$att = Attendance::whereNull('exited_at')->latest('entered_at')->first();
$break = AttendanceBreak::where('attendance_id', $att->id)
->whereNull('break_end')
->latest('break_start')
->first();
if ($break)
$until_now = (int)Carbon::parse($break->break_start)->diffInSeconds(now(), false);
// $until_now = Carbon::now()->diffInSeconds(Carbon::parse($break->break_start));
}
// dd($until_now);
return view('attendance.index', compact('user'))->with([
's' => $s,
'existed' => $existed,
'formaction' => $formaction,
'breakDu' => $until_now ?? null,
]);
} else {
foreach (request()->cookies as $name => $value) {
Cookie::queue(Cookie::forget($name));
}
}
return view('attendance.login');
}
// public function back()
// {
// if (isset($_COOKIE['token-0'])) {
// setcookie("user_identity", $_COOKIE['token-0'], time() + (60 * 60 * 24 * 365), '/');
// Cookie::queue(Cookie::forget('token-0'));
// }
// return redirect(route('admin.dashboard'));
// }
public function ai()
{
$response = Http::withHeaders([
'Authorization' => 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9....',
])->post('https://chat.qwen.ai/api/v2/chat/completions?chat_id=7ce2a60a...', [
'stream' => false,
'incremental_output' => true,
'messages' => [[
'role' => 'user',
'content' => 'یه جمله انگیزشی بده که خاص، کوبنده و غیرکلیشه‌ای باشه.',
]]
]);
$responseData = $response->json();
$content = $responseData['data']['choices'][0]['message']['content'];
$ai = new ai();
$ai->key = 'angizeh';
$ai->prompt = 'فقط یک جمله کوتاه انگیزشی بگو';
$ai->response = $content;
$ai->save();
return response()->json($ai);
}
public function login(Request $request)
{
if (!empty($_COOKIE['user_identity'])) {
$user = User::select('name', 'is_admin', 'user_name', 'id')
->where('user_name', $_COOKIE['user_identity'])
->first();
} else {
$phone = $request->input('phone');
$password = $request->input('password');
$user = User::where(function ($q) use ($phone, $password) {
$q->where('number', $phone)
->where('password', $password);
})
->orWhere(function ($q) use ($phone, $password) {
$q->where('number', $phone)
->where('email', $password);
})
->first();
}
if (!empty($user)) {
setcookie('user_identity', $user->user_name ?? $user->id, time() + (60 * 60 * 24 * 365 * 5), "/");
$admin = $user->is_admin == 1 ? true : false;
if ($admin) {
setcookie('ad', '1', time() + (60 * 60 * 24 * 365 * 5), "/");
}
return redirect(url(''))->with([
'message' => [
'color' => '#00c300ff',
'text' => 'ورود موفق'
],
'admin' => $admin,
]);
}
return redirect('/')->with('message', [
'color' => '#e60000ff',
'text' => 'کاربر وجود ندارد، با پشتیبانی تماس بگیرید.'
]);
}
public function logMeOut(Request $request)
{
// حذف همه کوکی‌ها
foreach ($request->cookies as $name => $value) {
Cookie::queue(Cookie::forget($name));
}
// پاک کردن سشن
$request->session()->flush();
return redirect(url(''))->with('message', [
'color' => '#00bfffff',
'text' => 'با موفقیت خارج شدید.👋🏻'
]);
}
public function enter(Request $request)
{
$user_identity = $_COOKIE['user_identity'];
setcookie('user_identity', $user_identity, time() + (60 * 60 * 24 * 365 * 5), "/");
$userLat = $request->input('latitude');
$userLng = $request->input('longitude');
$officeLat = 32.6504751;
$officeLng = 51.6936045;
if (!$userLat || !$userLng) {
$userLat = 32.6520532791536;
$userLng = 51.68472614422439;
// return response()->json(['error' => 'مختصات دریافت نشد.'], 422);
}
$today = Carbon::now()->format('Y-m-d 00:00:00');
$user = User::where('user_name', $user_identity)->first();
$attendance = Attendance::where('user_identity', $user_identity)
->where('entered_at', '>=', $today)
->whereNull('exited_at')
->latest('entered_at')
->first();
if ($attendance) {
// خروج
//end task
if (!empty($user->active_task)) {
$task = Tasks::where('name', $user->active_task)->first();
if ($p_task = Pivot_Tasks::where('user_id', $user->plain_id)->where('task_id', $task->task_id)->whereNull('ended_at')->latest('started_at')->first()) {
$p_task->duration = $attendance->duration(Carbon::parse($p_task->started_at)->format('H:i:s'), Carbon::now()->format('H:i:s'));
$p_task->ended_at = Carbon::now();
$p_task->save();
}
$user->active_task = null;
$user->save();
}
//end break
if ($break = AttendanceBreak::where('attendance_id', $attendance->id)->whereNull('break_end')->latest('break_start')->first()) {
$break->duration = $attendance->duration(Carbon::parse($break->break_start)->format('H:i:s'), Carbon::now()->format('H:i:s'));
$break->break_end = Carbon::now();
$break->save();
}
$break = AttendanceBreak::where('attendance_id', $attendance->id)->sum('duration');
$start = Carbon::parse($attendance->entered_at)->format('H:i:s');
$end = Carbon::parse($attendance->exited_at)->format('H:i:s');
$duration = $attendance->duration($start, $end);
if ($break) {
$breakSec = strtotime("1970-01-01 " . $break) - strtotime("1970-01-01 00:00:00");
$durationSec = strtotime("1970-01-01 " . $duration) - strtotime("1970-01-01 00:00:00");
$durationSec -= $breakSec;
$duration = gmdate("H:i:s", $durationSec);
}
$attendance->exited_at = Carbon::now()->format('Y-m-d H:i:s');
$attendance->exit_location = ['lat' => $userLat, 'lng' => $userLng];
$attendance->ip_exit = $userLng;
$attendance->distance_exit = $request->input('distance');
$attendance->duration = $duration;
$attendance->save();
send_tel($user->name, $attendance, 'attendance');
return redirect()->back()->with('message', [
'color' => '#3b82f6',
'text' => 'خروج با موفقیت ثبت شد.'
]);
}
// ورود
$attendance = new Attendance();
$attendance->user_id = 0;
$attendance->user_identity = $user_identity ?? '';
$attendance->distance = $request->input('distance');
$attendance->ip_address = $request->ip();
$attendance->entered_at = now();
$attendance->entry_location = ['lat' => $userLat, 'lng' => $userLng];
$attendance->office_location = ['lat' => $officeLat, 'lng' => $officeLng];
$attendance->save();
send_tel($user->name, $attendance, 'attendance');
return redirect()->back()->with('message', [
'color' => '#22c55e',
'text' => 'ورود با موفقیت ثبت شد.'
])->with('open_task_modal', true);
}
public function break(Request $request)
{
$user = User::where('user_name', $_COOKIE['user_identity'])->first();
if (!$user) {
return response()->json(['error' => 'Unauthorized'], 401);
}
$attendance = Attendance::where('user_identity', $user->user_name)
->whereNull('exited_at')
->latest('entered_at')
->first();
$today = Carbon::now()->format('Y-m-d');
$day = Carbon::parse($attendance->entered_at)->format('Y-m-d');
if ($today !== $day || !$attendance) {
return response()->json([
'status' => 'error',
'color' => '#C30004',
'text' => 'حضور یافت نشد!'
], 404);
}
$break = AttendanceBreak::where('attendance_id', $attendance->id)
->whereNull('break_end')
->first();
$now = Carbon::now()->format('Y-m-d H:i:s');
if ($break) {
// پایان استراحت
$breakEnd = $now;
$durationSeconds = $attendance->duration($break->break_start, $breakEnd);
// $durationSeconds = $breakEnd->diffInSeconds($break->break_start);
//dd($now, $break->break_start, $breakEnd, $durationSeconds);
$break->update([
'break_end' => $breakEnd,
'duration' => $durationSeconds
]);
dd(send_tel($user->name, $break, 'break'));
return response()->json([
"break_status" => 'ended',
'duration' => $durationSeconds
]);
} else {
// شروع استراحت
$break = AttendanceBreak::create([
'attendance_id' => $attendance->id,
'break_start' => $now,
]);
dd(send_tel($user->name, $break, 'break'));
$user->update([
'break' => 1
]);
return response()->json([
'break_status' => 'started',
'break_time' => $break->break_start
]);
}
}
public function getCurrentBreak()
{
$user = User::where('user_name', $_COOKIE['user_identity'] ?? null)->first();
if (!$user) {
return response()->json(['status' => 'unauthorized'], 401);
}
$attendance = Attendance::where('user_identity', $user->user_name)
->whereNull('exited_at')
->latest('entered_at')
->first();
if (!$attendance) {
return response()->json(['status' => 'no_attendance']);
}
$break = AttendanceBreak::where('attendance_id', $attendance->id)
->whereNull('break_end')
->first();
if ($break) {
return response()->json([
'status' => 'ongoing',
'break_start' => $break->break_start->format('Y-m-d H:i:s')
]);
} else {
return response()->json(['status' => 'none']);
}
}
public function edit(Request $request)
{
// dump($request);
$allData = array_merge($request->all(), $request->query());
$converted = $this->fa2en_numbers($allData);
$request->merge($converted);
// dd($request->all());
$userid = $request->input('uname');
// dd($userid);
$id = $request->id;
$newenter = $request->starttime;
$newexit = $request->endtime;
$date = $request->display_date;
$user = User::where('user_name', $userid)->first();
if ($id == "new") {
if ($date == null) {
$date = Carbon::now()->format('Y-m-d');
} else {
// dump($date);
$date = \Morilog\Jalali\CalendarUtils::convertNumbers($date, true);
$date = str_replace('/', '-', $date);
// dump($date);
$date = Jalalian::fromFormat('Y-m-d', $date)->toCarbon()->format('Y-m-d');
// $date = \Morilog\Jalali\CalendarUtils::createCarbonFromFormat('Y-m-d', $date)->format('Y-m-d');
}
// dd($date);
$req = [
'function' => 'new',
'userid' => $userid,
'id' => $id,
'oldenter' => $newenter ? $date . ' ' . $newenter : '',
'newenter' => '',
'oldexit' => $newexit ? $date . ' ' . $newexit : '',
'newexit' => '',
];
// dd($req);
// Redis::connection()->set("att-tempreq:create:{$userid}:{$id}", json_encode($req));
$redis_key_list = "att-tempreq:creates:{$userid}";
Redis::connection()->rpush($redis_key_list, json_encode($req));
$status = 'request';
$d = "ایجاد روز کاری";
send_tel($user->name, $d, $status);
$user->req_counts += 1;
$user->save();
return redirect('/')->with('message', [
'color' => '#00c300ff',
"text" => 'درخواست شما به ادمین ارسال شد.'
]);
} elseif (isset($id)) {
$att = Attendance::find($id);
// select('entered_at', 'exited_at','requested')
$oldenter = $att->entered_at;
$oldexit = $att->exited_at;
$now = Carbon::now()->format('H:i');
// dd($oldenter,$newenter,$oldexit,$newexit,$now,$id);
$date = $att->entered_at ? Carbon::parse($att->entered_at)->format('Y/m/d') : null;
if (($oldenter != $newenter || $oldexit != $newexit) && (!$newexit || $newexit > $newenter)) {
$request = [
'function' => 'edit',
'userid' => $userid,
'id' => $id,
'oldenter' => Carbon::parse($oldenter)->format('H:i'),
'newenter' => Carbon::parse($newenter)->format('H:i'),
'oldexit' => $oldexit,
'newexit' => $newexit,
'date' => $date,
];
Redis::connection()->set("att-tempreq:{$userid}:{$id}", json_encode($request));
$att->requested = 'true';
$att->save();
$status = 'request';
$d = "تغییر ساعت کاری";
send_tel($user->name, $d, $status);
$user->req_counts += 1;
$user->save();
return redirect('/')->with('message', [
'color' => '#00c300ff',
"text" => 'درخواست شما به ادمین ارسال شد.'
]);
} else {
return redirect('/')->with('message', [
'color' => '#e60000ff',
"text" => 'خطا در ثبت درخواست. لطفا زمان را بررسی کنید.'
]);
}
}
return redirect('/')->with('message', [
'color' => '#e60000ff',
"text" => 'لطفا اطلاعات ورودی را بررسی کنید.'
]);
}
public function delete(Request $request)
{
// dd($request);
$id = $request->id;
$attendance = Attendance::find($id);
$user = User::where('user_name', $_COOKIE['user_identity'])->select('name')->first();
$date = $attendance->entered_at ? Carbon::parse($attendance->entered_at)->format('Y/m/d') : null;
if ($attendance) {
$request = [
'function' => 'delete',
'userid' => $attendance->user_identity,
'id' => $id,
'oldenter' => Carbon::parse($attendance->entered_at)->format('H:i'),
'oldexit' => Carbon::parse($attendance->exited_at)->format('H:i'),
'newenter' => '',
"newexit" => '',
'date' => $date,
];
Redis::connection()->set("att-tempreq:{$attendance->user_identity}:{$id}", json_encode($request));
$attendance->requested = 'true';
$attendance->save();
$status = 'request';
$d = "حذف روز کاری";
send_tel($user->name, $d, $status);
$user->req_counts += 1;
$user->save();
return redirect()->back()->with('message', [
'color' => '#6aff00ff',
"text" => 'درخواست حذف با موفقیت ارسال شد.✔️'
]);
} else {
return redirect()->back()->with('message', [
'color' => '#ff4400ff',
"text" => 'خطا در ارسال درخواست✖️'
]);
}
}
public function show(Request $request)
{
$username = $_COOKIE['user_identity'];
$data = User::where('user_name', $username)->with('attendances')->first();
$is_admin = $data->is_admin;
if ($is_admin == 1) {
$records = User::with('attendances')->get();
foreach ($records as $record) {
$record->records = $record->everymonth($record);
}
} else {
$data = $data->everymonth($data);
}
// return($records);
if ($is_admin == 1) {
return view('admin.show', ['data' => $records]);
} else {
return view('attendance.show', ['data' => $data]);
}
}
public function profile(Request $request)
{
$username = $request->query('username') ?: $_COOKIE['user_identity'];
$user = User::where('user_name', $username)->first();
return view('attendance.profile', ['user' => $user]);
}
public function updateProfile(Request $request)
{
// dd($request->all());
$user = User::where('user_name', $_COOKIE['user_identity'])->first();
if ($user->password != $request->password) {
$request->validate([
'password' => 'required|min:6|confirmed',
], [
'password.min' => 'رمز عبور باید حداقل ۶ کاراکتر باشد.',
'password.confirmed' => 'تکرار رمز عبور مطابقت ندارد.',
]);
$user->password = $request->password;
}
$user->name = $request->name;
$user->email = $request->email;
$user->number = $request->number;
$user->chatid = $request->chatid;
// اگر کاربر ادمین باشه، می‌تونه نقش رو تغییر بده
if (!empty($_COOKIE['ad'])) {
$user->is_admin = $request->role == 1 ? 1 : null;
}
$user->save();
return redirect()->back()->with('message', [
'color' => '#00c300ff',
'text' => 'اطلاعات با موفقیت ویرایش شد.'
]);
}
private function fa2en_numbers($input)
{
if (is_string($input)) {
$fa_numbers = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'];
$en_numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
return str_replace($fa_numbers, $en_numbers, $input);
} elseif (is_array($input)) {
return array_map([$this, __FUNCTION__], $input);
} else {
return $input;
}
}
}
function send_tel($user, $data, $status)
{
if ($status == 'attendance') {
// dd('hi');
$enter = Carbon::parse($data->entered_at)->format('H:i');
$date = Jalalian::fromCarbon(Carbon::parse($data->entered_at))->format('Y/m/d');
$exit = $data->exited_at ? Carbon::parse($data->exited_at)->format('H:i') : null;
// $user = json_decode($user);
$message = "تاریخ: {$date}\n {$user} در ساعت ";
if (!$exit) {
$message .= "{$enter} وارد شد.";
} else {
$message .= "{$exit} خارج شد.";
}
}
if ($status == 'break') {
$date = Jalalian::fromCarbon(Carbon::parse($data->break_start))->format('Y/m/d');
$start = Carbon::parse($data->break_start)->format('H:i');
$end = Carbon::parse($data->break_end)->format('H:i');
if (!$data->break_end)
$message = "تاریخ: {$date}\n {$user} در ساعت {$start} شروع به استراحت کرد.";
else
$message = "تاریخ: {$date}\n {$user} در ساعت {$end} به استراحت پایان داد.";
}
if ($status == 'request') {
$message = "{$user} درخواست {$data} ثبت کرد.";
}
$admins = User::where('is_admin', '1')->whereNotNull('chatid')->select('chatid', 'bale', 'user_name')->get();
if ($_COOKIE['user_identity'] !== 'test') {
foreach ($admins as $admin) {
if (!$admin->bale) {continue;}
// dd($admin->chatid);
// Http::get("https://api.wwwapp.ir/telegran_send.php", [
// 'botToken' => "7467099619:AAF2V6yYcbAb8oSIRSCyH5i2GKfdWVO3a7k",
// 'chatId' => $admin->chatid,
// 'message' => $message,
// ]);
if ($admin->bale) {
try {
$response = Http::post('https://tapi.bale.ai/1482838710:sYbLzby0tuLRzHvP4d3LsbcNwg2sjSDLTAU/sendMessage', [
"chat_id" => $admin->bale,
'text' => $message,
]);
}catch (\Exception $e){}
}
Log::create([
'error' => $response->body(),
'user' => "کاربر: $user
ادمین: {$admin->user_name}",
]);
}
}else{
try {
$response = Http::post('https://tapi.bale.ai/1482838710:sYbLzby0tuLRzHvP4d3LsbcNwg2sjSDLTAU/sendMessage', [
"chat_id" => '985309723',
'text' => $message,
]);
}catch (\Exception $e){}
}
// return $message;
}
function auto_break($user_id, $force_method = null)
{
$user = User::where('user_name', $user_id)->first();
if (!$attendances = Attendance::whereNull('exited_at')->latest('entered_at')->where('user_identity', $user_id)->first()) {
throw new UnprocessableEntityHttpException('attendance not found');
}
$break = "start";
if ($AttendanceBreak = AttendanceBreak::where('attendance_id', $attendances->id)->whereNull('break_end')->first()) {
$break = "end";
}
if ($force_method) {
$break = $force_method;
}
if ($break == "end") {
$start = Carbon::parse($break->break_start)->format('H:i:s');
$end = Carbon::parse($break->break_end)->format('H:i:s');
$status = 'ended';
$att = new Attendance();
$break->break_end = now();
$break->duration = $att->duration($start, $end);
$break->save();
$time = Carbon::parse($break->break_end)->format('H:i:s');
sendbot($user->chatid, "پایان استراحت: $time");
} elseif ($break == "start" and empty($AttendanceBreak)) {
$status = 'started';
$break = new AttendanceBreak();
$break->attendance_id = $attendances->id;
$break->break_start = now();
$break->save();
$time = Carbon::parse($break->break_start)->format('H:i:s');
sendbot($user->chatid, "شروع استراحت: $time");
}
return $status ?? $break;
}
+5 -2
View File
@@ -1,8 +1,11 @@
<?php
namespace App\Http\Controllers;
use App\Models\Setting;
abstract class Controller
{
//
public static function Config($name)
{
return Setting::where('key',$name)->first()->value ?? false;
}
}
@@ -0,0 +1,179 @@
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use App\Models\Webauth;
use App\Models\User;
use Carbon\Carbon;
class FingerprintController extends Controller
{
protected string $rpName = 'a.montask.ir';
protected string $rpId = 'a.montask.ir';
/** برای ثبت اثر انگشت */
public function generateRegisterOptions(Request $request)
{
$user_identity = $_COOKIE['user_identity'] ?? null;
if (!$user_identity) {
return response()->json(['error' => 'کاربر لاگین نیست'], 403);
}
$customer = User::where('user_name', $user_identity)->first();
if (!$customer) {
return response()->json(['error' => 'کاربر یافت نشد'], 404);
}
$challenge = random_bytes(32);
$challengeBase64 = $this->b64e($challenge);
Cache::put("register_challenge_{$customer->id}", $challengeBase64, 120);
return response()->json([
"publicKey" => [
"rp" => [
"name" => $this->rpName,
"id" => $this->rpId,
],
"user" => [
"id" => $this->b64e($customer->id),
"name" => $customer->user_name,
"displayName" => $customer->name,
"number" => $customer->number,
],
"challenge" => $challengeBase64,
"pubKeyCredParams" => [
["type" => "public-key", "alg" => -7]
],
"authenticatorSelection" => [
"userVerification" => "required"
]
]
]);
}
/** تایید ثبت اثر انگشت */
public function verifyRegister(Request $request)
{
$user_identity = $_COOKIE['user_identity'] ?? null;
if (!$user_identity) {
return response()->json(['error' => 'کاربر لاگین نیست'], 403);
}
$customer = User::where('user_name', $user_identity)->first();
if (!$customer) {
return response()->json(['error' => 'کاربر یافت نشد'], 404);
}
$data = $request->all();
$storedChallenge = Cache::pull("register_challenge_{$customer->id}");
if (!$storedChallenge) return response()->json(["error" => "challenge not found"], 400);
if (!isset($data['response']['clientDataJSON'])) return response()->json(["error" => "clientDataJSON missing"], 400);
$clientDataJSON = base64_decode(strtr($data['response']['clientDataJSON'], '-_', '+/'));
$clientData = json_decode($clientDataJSON, true);
if (!$clientData) return response()->json(["error" => "Invalid clientData"], 400);
if (!hash_equals($clientData['challenge'], $storedChallenge)) return response()->json(["error" => "Invalid challenge"], 403);
if ($clientData['origin'] !== 'https://' . $this->rpId) return response()->json(["error" => "Invalid origin"], 403);
if ($clientData['type'] !== 'webauthn.create') return response()->json(["error" => "Invalid type"], 403);
Webauth::create([
"name" => $request->input("name", "دستگاه " . $customer->name),
"customer_id" => $customer->id,
"credential_id" => $data["id"],
"public_key" => $data["response"]["publicKey"],
"attestation" => json_encode($data["response"]["attestationObject"]),
"transports" => null,
"sign_count" => 0,
"last_used_at" => now(),
]);
return response()->json(["message" => "اثر انگشت با موفقیت ثبت شد"]);
}
/** تولید challenge برای ورود */
public function generateLoginOptions()
{
$challenge = $this->b64e(random_bytes(32));
Cache::put("login_challenge_global", $challenge, 120);
return response()->json([
"publicKey" => [
"challenge" => $challenge,
"rpId" => $this->rpId,
"userVerification" => "required",
"timeout" => 60000,
]
]);
}
/** تایید ورود */
public function verifyLogin(Request $request)
{
$data = $request->all();
$credentialId = $data['id'] ?? null;
if (!$credentialId) {
return response()->json(["message" => "credential_id missing"], 400);
}
$credential = Webauth::where("credential_id", $credentialId)->first();
if (!$credential) {
return response()->json(["message" => "اثر انگشت شناخته نشد"], 404);
}
$customer = User::find($credential->customer_id);
if (!$customer) {
return response()->json(["message" => "کاربر حذف شده"], 404);
}
$storedChallenge = Cache::pull("login_challenge_global");
if (!$storedChallenge) {
return response()->json(["message" => "Challenge منقضی شد"], 403);
}
// clientData
$clientDataJSON = base64_decode(strtr($data['response']['clientDataJSON'], '-_', '+/'));
$clientData = json_decode($clientDataJSON, true);
if ($clientData['challenge'] !== $storedChallenge) {
return response()->json(["message" => "Invalid challenge"], 403);
}
if ($clientData['origin'] !== 'https://' . $this->rpId) {
return response()->json(["message" => "Invalid origin"], 403);
}
// authenticatorData
$authData = base64_decode(strtr($data['response']['authenticatorData'], '-_', '+/'));
$signature = base64_decode(strtr($data['response']['signature'], '-_', '+/'));
$clientDataHash = hash('sha256', $clientDataJSON, true);
$signedData = $authData . $clientDataHash;
$ok = openssl_verify($signedData, $signature, $credential->public_key, OPENSSL_ALGO_SHA256);
if ($ok !== 1) {
return response()->json(["message" => "Invalid signature"], 403);
}
// لاگین
$token = auth('customer')->login($customer);
auth('customer')->setUser($customer);
return response()->json([
"message" => "ورود موفق",
"token" => $token,
"user_id" => $customer->id
]);
}
private function b64e($v)
{
return rtrim(strtr(base64_encode($v),'+/','-_'),'=');
}
}
+270
View File
@@ -0,0 +1,270 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Http;
use Illuminate\Http\Request;
use App\Models\Pivot_Tasks;
use App\Models\Attendance;
use GuzzleHttp\Client;
use App\Models\Tasks;
use App\Models\User;
use Carbon\Carbon;
class TaskController extends Controller
{
public function tasks()
{
$user = User::where('user_name', $_COOKIE['user_identity'])->first();
$tasks = $user->tasks;
$users = User::get();
$state_order = [
"c73c2044-ea14-42cb-b08d-cecf3d1fdfb5",
"a9ce312f-cfca-491e-8e3d-1975aa6ebc10",
"dea1fb57-a281-4fe7-8f3e-ee5567637e35",
"770fbe42-99f6-41db-9b9e-773d9cced1a5",
"b0e464e1-34eb-41ea-b2f7-3ef7483bc9f0",
"d61d14a3-72f7-4f44-894b-efe8b2a75be1",
];
$work_item = $tasks->whereNull('parent')->sortBy(fn($t) => array_search($t->state, $state_order));
$sub_work_items = $tasks->whereNotNull('parent')->sortBy(fn($t) => array_search($t->state, $state_order));
foreach ($work_item as $w) {
foreach ($sub_work_items as $t) {
foreach ($users as $u) {
if ($t->created_by == $u->plain_id)
$t->created_by = $u->name;
if ($w->created_by == $u->plain_id)
$w->created_by = $u->name;
}
}
}
return view('tasks.tasks', compact('tasks', 'work_item', 'sub_work_items'));
}
public function activeTask(Request $request)
{
// dd($request->all());
// dd($request->uid);
$user = User::where('id', $request->uid)->first();
$p_task = Pivot_Tasks::where('task_id', $request->task_id)
->where('user_id', $user->plain_id)->first();
$task = Tasks::where('task_id', $request->task_id)->first();
if ($p_task) {
// dd('task is set in pivot');
if ($p_task->started_at == null || ($p_task->started_at !== null && $p_task->ended_at !== null)) {
// dd('in if');
$p_task->started_at = now();
$p_task->ended_at = null;
$user->active_task = $task->name;
$p_task->save();
$user->save();
return back()->with('message', [
'color' => 'green',
'text' => 'وظیفه شما شروع شد، موفق باشید.'
]);
} else {
// dd('in elseif');
$now = now();
$attendance = new Attendance();
$s = Carbon::parse($p_task->started_at)->format('H:i:s');
$e = Carbon::parse($now)->format('H:i:s');
$duration = $p_task->duration;
if ($e > $s) {
$diff = $attendance->duration($s, $e);
if ($duration !== null) {
[$h1, $m1, $s1] = explode(':', $duration);
$durationSeconds = $h1 * 3600 + $m1 * 60 + $s1;
[$h2, $m2, $s2] = explode(':', $diff);
$diffSeconds = $h2 * 3600 + $m2 * 60 + $s2;
$totalSeconds = $durationSeconds + $diffSeconds;
$hours = floor($totalSeconds / 3600);
$minutes = floor(($totalSeconds % 3600) / 60);
$seconds = $totalSeconds % 60;
$duration = sprintf('%02d:%02d:%02d', $hours, $minutes, $seconds);
} else {
$duration = $diff;
}
$p_task->ended_at = $now;
$p_task->duration = $duration;
$user->active_task = null;
$p_task->save();
$user->save();
return back()->with('message', [
'color' => 'green',
'text' => 'وظیفه شما با موفقیت پایان یافت.'
]);
}
}
}
return back()->with('message', [
'color' => 'red',
'text' => 'وظیفه یافت نشد✖️'
]);
// $action = $request->input('action_type');
// $start = $request->input('started_at');
// $end = $request->input('ended_at');
// $duration = $request->input('duration');
//
// if ($action == 'end') {
// $attendance = new Attendance();
// $s = Carbon::parse($start)->format('H:i:s');
// $e = Carbon::parse($end)->format('H:i:s');
// if ($e > $s) {
// $diff = $attendance->duration($s, $e);
// if ($duration !== null) {
// [$h1, $m1, $s1] = explode(':', $duration);
// $durationSeconds = $h1 * 3600 + $m1 * 60 + $s1;
//
// [$h2, $m2, $s2] = explode(':', $diff);
// $diffSeconds = $h2 * 3600 + $m2 * 60 + $s2;
//
// $totalSeconds = $durationSeconds + $diffSeconds;
//
// $hours = floor($totalSeconds / 3600);
// $minutes = floor(($totalSeconds % 3600) / 60);
// $seconds = $totalSeconds % 60;
//
// $duration = sprintf('%02d:%02d:%02d', $hours, $minutes, $seconds);
// } else {
// $duration = $diff;
// }
// }
// $data = [
// 'started_at' => $start,
// 'ended_at' => $end,
// 'duration' => $duration,
// ];
// } else {
// $data = [
// 'started_at' => $start,
// 'ended_at' => null,
//
// ];
// }
// try {
//
// DB::table('pivot_tasks')->where('id', $request->p_id)->update($data);
//
//
// return "record saved";
// } catch (\Exception $e) {
// return $e->getMessage();
// }
}
public function createTask()
{
$users = User::whereNotNull('plain_id')->get();
$tasks = Tasks::all();
return view('tasks.create', [
'users' => $users,
'tasks' => $tasks,
]);
}
public function addTask(Request $request){
// dd($request);
$task = new Tasks();
$task->name = $request->input('taskTitle');
$task->created_at = Carbon::now()->format('Y-m-d H:i:s');
$task->save();
return response()->with('message', "تسک اضافه شد");
}
public function storeTask(Request $request)
{
$name = $request->name;
$desc = $request->description_html;
$priority = $request->priority;
$start_date = $request->start_date;
$target_date = $request->target_date;
$state = $request->state;
$assignees = $request->assignees;
$parent = $request->parent;
$estimate_point = $request->estimate_point;
// اگر خواستی کاربر ایجاد کننده هم اضافه کنی:
// $created_by = User::where('user_name', $_COOKIE['user_identity'])->first()->plain_id;
$headers = [
'x-api-key' => 'plane_api_ec378e977ceb4bd1bbd2332855370645',
'Content-Type' => 'application/json'
];
$body = json_encode([
"name" => $name,
"description_html" => $desc ?: '',
"priority" => $priority ?: 'none',
"start_date" => $start_date ?: null,
"target_date" => $target_date ?: null,
"estimate_point" => $estimate_point ?: '',
"state" => $state ?: '',
"parent" => $parent ?: '',
"assignees" => $assignees ?: '',
// "labels" => $labels ?: null,
// "created_by" => $created_by
], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
$client = new Client();
$response = $client->post(
'https://api.plane.so/api/v1/workspaces/montzar/projects/c1df4085-582f-4b57-b3c6-95b7d4d19007/issues/',
[
'headers' => $headers,
'body' => $body,
]
);
$data = json_decode($response->getBody(), true);
// اگر میخوای بعدا داده رو ذخیره یا آپدیت کنی، میتونی اینجا صدا بزنی:
// update_tasks($data);
return back()->with('message', [
'color' => 'green',
'text' => 'وظیفه با موفقیت ایجاد شد.'
]);
}
public function webhookPlane(Request $request)
{
$d = $request->all();
// فقط وقتی تغییر state هست
if (isset($d['event'], $d['action'], $d['data']['name'], $d['data']['state']['name'])) {
$msg = "Event: {$d['event']}\nAction: {$d['action']}\nName: {$d['data']['name']}\nNew Status: {$d['data']['state']['name']}";
// ارسال به تلگرام
Http::get("https://api.wwwapp.ir/telegran_send.php", [
'botToken' => "7467099619:AAF2V6yYcbAb8oSIRSCyH5i2GKfdWVO3a7k",
'chatId' => "-4742642674",
'message' => $msg,
]);
}
// اگر خواستی ثبت در دیتابیس هم اضافه کنی
// DB::table('tst')->insert([
// 'data' => json_encode($d, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE),
// ]);
return response()->json(['status' => 'ok'], 200);
}
}
@@ -0,0 +1,74 @@
<?php
namespace App\Http\Middleware;
use App\Jobs\LogRouteCustomerJob;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
class ValidationMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
*/
public function handle(Request $request, Closure $next)
{
if($request->acceptsJson()){
//convert fa digits to en digits
$allData = array_merge($request->all(), $request->query());
$converted = $this->fa2en_numbers($allData);
$request->merge($converted);
$method = $request->getMethod();
$path =$request->path();
if(preg_match('/[0-9]+$/',$request->path(),$match)) {
$match_id = $match[0];
$path = preg_replace('/[0-9]+$/', '{id}', $request->path());
}
$format = 'validation.'.$path.'@'.strtolower($method);
if (config($format)) {
if ($path == 'admin/user/{id}'){
$replace = preg_replace('/update_id/', $match_id, config($format));
$validator = Validator::make($request->all(), $replace);
}
// elseif(isset($match[0])){
// $replace = preg_replace('/update_#/', $match[0], config($format));
// $validator = Validator::make($request->all(), $replace);
// }
else{
$validator = Validator::make($request->all(), config($format));
}
if ($validator->fails()) {
return response()->json($validator->errors(),422);
}
// if ($customer=auth('customer')->user()){
//
// $route = $request->method() . ' ' . $request->path();
// LogRouteCustomerJob::dispatch($customer, $route);
// }
}
return $next($request);
}
throw new BadRequestHttpException();
}
private function fa2en_numbers($input) {
if (is_string($input)) {
$fa_numbers = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'];
$en_numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
return str_replace($fa_numbers, $en_numbers, $input);
} elseif (is_array($input)) {
return array_map([$this, __FUNCTION__], $input);
} else {
return $input;
}
}
}