diff --git a/app/Http/Controllers/Admin/XlangController.php b/app/Http/Controllers/Admin/XlangController.php index 2fefc8a..c7f38d7 100644 --- a/app/Http/Controllers/Admin/XlangController.php +++ b/app/Http/Controllers/Admin/XlangController.php @@ -4,12 +4,22 @@ namespace App\Http\Controllers\Admin; use App\Http\Controllers\Controller; use App\Http\Requests\XlangSaveRequest; +use App\Models\Cat; use App\Models\Product; +use App\Models\Prop; +use App\Models\Setting; use App\Models\Xlang; use Illuminate\Http\Request; use GuzzleHttp\Client; use Illuminate\Support\Facades\Artisan; +use Xmen\StarterKit\Models\Category; +use Xmen\StarterKit\Models\Clip; +use Xmen\StarterKit\Models\Gallery; +use Xmen\StarterKit\Models\Image; +use Xmen\StarterKit\Models\MenuItem; +use Xmen\StarterKit\Models\Post; +use Xmen\StarterKit\Models\Slider; use function Xmen\StarterKit\Helpers\logAdmin; use function Xmen\StarterKit\Helpers\logAdminBatch; @@ -17,6 +27,20 @@ const PREFIX_PATH = __DIR__ . '/../../../../'; class XlangController extends Controller { + public $allowedModels = [ + Product::class, + Cat::class, + Post::class, + Category::class, + Slider::class, + MenuItem::class, + Gallery::class, + Clip::class, + Prop::class, + Setting::class, + Image::class + ]; + public function createOrUpdate(Xlang $xlang, XlangSaveRequest $request) { $xlang->name = $request->input('name'); @@ -24,8 +48,8 @@ class XlangController extends Controller $xlang->rtl = $request->has('rtl'); $xlang->is_default = $request->has('is_default'); - if ($xlang->is_default){ - Xlang::where('is_default','1')->update([ + if ($xlang->is_default) { + Xlang::where('is_default', '1')->update([ 'is_default' => 0, ]); } @@ -73,7 +97,7 @@ class XlangController extends Controller public function store(XlangSaveRequest $request) { // - if ($request->tag != 'en'){ + if ($request->tag != 'en') { define("TRANSLATE_CONFIG_PATH", PREFIX_PATH . 'config/translator.php'); define("TRANSLATE_NEW_FILE", PREFIX_PATH . 'resources/lang/' . $request->tag . '.json'); @@ -162,6 +186,7 @@ class XlangController extends Controller define("TRANSLATE_FILE", PREFIX_PATH . 'resources/lang/' . $tag . '.json'); return response()->download(TRANSLATE_FILE, $tag . '.json'); } + public function ai($tag) { @@ -169,17 +194,17 @@ class XlangController extends Controller define("TRANSLATE_FILE", PREFIX_PATH . 'resources/lang/' . $tag . '.json'); $file = file_get_contents(TRANSLATE_FILE); - $url = 'http://5.255.98.77:3001/json?form=en&to='.$tag; + $url = 'http://5.255.98.77:3001/json?form=en&to=' . $tag; $client = new Client([ - 'headers' => [ 'Content-Type' => 'application/json' ] + 'headers' => ['Content-Type' => 'application/json'] ]); $response = $client->post($url, ['body' => $file] ); - file_put_contents(TRANSLATE_FILE,$response->getBody()); - return redirect()->back()->with(['message' => __("Translated by ai xstack service:").' '.$tag]); + file_put_contents(TRANSLATE_FILE, $response->getBody()->getContents()); + return redirect()->back()->with(['message' => __("Translated by ai xstack service:") . ' ' . $tag]); } public function upload($tag, Request $request) @@ -193,7 +218,7 @@ class XlangController extends Controller return redirect()->back()->withErrors(__("Invalid json file!")); } file_put_contents(TRANSLATE_FILE, $data); - return redirect()->back()->with(['message' => __("Translate updated")]); + return redirect()->back()->with(['message' => __("Translate updated")]); } public function bulk(Request $request) @@ -208,6 +233,73 @@ class XlangController extends Controller default: $msg = __('Unknown bulk action :' . $request->input('bulk')); } - return redirect()->route('admin.customer.index')->with(['message' => $msg]); + return redirect()->route('admin.lang.index')->with(['message' => $msg]); + } + + + public function translateModel($id, $model) + { + + if (!in_array($model, $this->allowedModels)) { + return abort(404); + } + $langs = Xlang::where('is_default', 0)->get(); + $cls = $model; + $model = ($model)::where('id', $id)->firstOrFail(); +// return $model; + $translates = $model->translatable; + return view('admin.langs.translate', compact('model', 'translates', 'langs', 'cls')); } + + public function translateModelSave($id, $model, Request $request) + { + + if (!in_array($model, $this->allowedModels)) { + return abort(404); + } + $langs = Xlang::where('is_default', 0)->get(); + $model = ($model)::where('id', $id)->firstOrFail(); +// $model = Product::whereId('id',$id)->first(); + foreach ($request->input('data') as $lang => $items) { + foreach ($items as $k => $item) { + if ($item != null) { + $model->setTranslation($k, $lang, $item); + } + } + } + + $model->save(); + return redirect()->back()->with(['message' => __('Translate updated')]); + + } + + public function translateModelAi($id, $model, $tag, $field) + { + + if (!in_array($model, $this->allowedModels)) { + return abort(404); + } + $langs = Xlang::where('is_default', 0)->get(); + $model = ($model)::where('id', $id)->firstOrFail(); +// $model = Product::whereId('id',$id)->first(); + $url = 'http://5.255.98.77:3001/text?form=' . config('app.xlang_main') . '&to=' . $tag; + + $client = new Client([ + 'headers' => ['Content-Type' => 'application/x-www-form-urlencoded'] + ]); + + $response = $client->post($url, + ['form_params' => ['body' => $model->$field]], + ); +// file_put_contents(TRANSLATE_FILE, $response->getBody()); + if ($response->getStatusCode() != 200) { + return redirect()->back()->withErrors(__("API error!")); + } +// dd($response->getBody()->getContents()); + $model->setTranslation($field, $tag, $response->getBody()->getContents()); + $model->save(); + return redirect()->back()->with(['message' => __('Translate updated')]); + + } + } diff --git a/composer.json b/composer.json index 84cfebd..9db6e2a 100755 --- a/composer.json +++ b/composer.json @@ -34,7 +34,7 @@ "psr/log": "v2.*", "symfony/dom-crawler": "^6.2", "symfony/psr-http-message-bridge": "^7.0", - "xmen/starter-kit": "^v3.1.0" + "xmen/starter-kit": "^v3.2.5" }, "require-dev": { "barryvdh/laravel-ide-helper": "^2.12", diff --git a/composer.lock b/composer.lock index ffac635..62313b8 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "476fc03eaacbf9c04610c95da580105c", + "content-hash": "38e039d93317f0accb46bc58aa69b9e1", "packages": [ { "name": "artesaos/seotools", @@ -8421,16 +8421,16 @@ }, { "name": "xmen/starter-kit", - "version": "v3.2.2", + "version": "v3.2.5", "source": { "type": "git", "url": "https://github.com/4xmen/starterkit-for-laravel.git", - "reference": "e06fae15e94831babebb1ab3ba4c7f5c57f85a5e" + "reference": "207cafd1abb67f9a0768223f32490e69d1be8a8d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/4xmen/starterkit-for-laravel/zipball/e06fae15e94831babebb1ab3ba4c7f5c57f85a5e", - "reference": "e06fae15e94831babebb1ab3ba4c7f5c57f85a5e", + "url": "https://api.github.com/repos/4xmen/starterkit-for-laravel/zipball/207cafd1abb67f9a0768223f32490e69d1be8a8d", + "reference": "207cafd1abb67f9a0768223f32490e69d1be8a8d", "shasum": "" }, "require": { @@ -8489,9 +8489,9 @@ ], "support": { "issues": "https://github.com/4xmen/starterkit-for-laravel/issues", - "source": "https://github.com/4xmen/starterkit-for-laravel/tree/v3.2.2" + "source": "https://github.com/4xmen/starterkit-for-laravel/tree/v3.2.5" }, - "time": "2024-02-04T12:31:22+00:00" + "time": "2024-02-04T23:17:48+00:00" } ], "packages-dev": [ diff --git a/config/translator.php b/config/translator.php index 9009b23..119b19f 100755 --- a/config/translator.php +++ b/config/translator.php @@ -4,7 +4,7 @@ use Translator\Framework\LaravelConfigLoader; use Translator\Infra\LaravelJsonTranslationRepository; return [ - 'languages' => ["fa","ru","ar"], + 'languages' => ["fa","ru","ar","fr"], 'directories' => [ app_path(), resource_path('views'), diff --git a/database/migrations/2024_02_05_022113_fix_title_for_translate.php b/database/migrations/2024_02_05_022113_fix_title_for_translate.php new file mode 100644 index 0000000..5380a7a --- /dev/null +++ b/database/migrations/2024_02_05_022113_fix_title_for_translate.php @@ -0,0 +1,52 @@ +text('title')->change(); + }); + Schema::table('categories', function ($table) { + $table->text('name')->change(); + }); + Schema::table('cats', function ($table) { + $table->text('name')->change(); + }); + Schema::table('products', function ($table) { + $table->text('name')->change(); + }); + Schema::table('props', function ($table) { + $table->text('label')->change(); + }); + Schema::table('galleries', function ($table) { + $table->text('title')->change(); + }); + Schema::table('menu_items', function ($table) { + $table->text('title')->change(); + }); + Schema::table('images', function ($table) { + $table->text('title')->change(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } +}; diff --git a/public/css/app.css b/public/css/app.css index c5079e0..5347cfd 100755 --- a/public/css/app.css +++ b/public/css/app.css @@ -3734,6 +3734,63 @@ nav a { color: rgba(255, 255, 255, 0.3333333333); } +.lang-support { + background: dodgerblue; + color: white; + padding: 7px; + text-align: center; + font-weight: 300; + margin-top: 1rem; +} + +.btn-ai { + height: 65px; + width: 65px; + background: dodgerblue; + font-size: 25px; + color: white; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + margin: auto; + transition: 400ms; + cursor: pointer; + box-shadow: inset 0 0 0 0 rgba(0, 0, 0, 0.1333333333); +} +.btn-ai:hover { + box-shadow: inset 0 0 0 75px rgba(0, 0, 0, 0.1333333333); +} + +.btn-add { + height: 50px; + width: 50px; + background: #333; + font-size: 25px; + color: white; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + transition: 400ms; + cursor: pointer; + box-shadow: inset 0 0 0 0 rgba(255, 255, 255, 0.1333333333); + position: fixed; + left: 1rem; + bottom: 1rem; + text-decoration: none; +} +.btn-add:hover { + box-shadow: inset 0 0 0 75px rgba(0, 0, 0, 0.1333333333); +} + +.img-squire { + width: 100%; + height: 175px; + -o-object-fit: cover; + object-fit: cover; +} + /*-768px width*/ @media (max-width: 1000px) { .gird4 { @@ -3800,3 +3857,7 @@ nav a { right: auto !important; left: 2rem !important; } + +.no-dec a { + text-decoration: none; +} diff --git a/resources/lang/fa.json b/resources/lang/fa.json index f3d81e6..6f5cb47 100755 --- a/resources/lang/fa.json +++ b/resources/lang/fa.json @@ -26,7 +26,9 @@ ":app Dear customer Your :product signed for you.": ":app\nکاربر گرامی محصول «:product» برای شما ثبت شد.", "A fresh verification link has been sent to your email address.": "یک لینک تاییده برای شما ایمیل شد", "ACL": "سطح دسترسی", + "AI translate form original source": "", "ANSWERED": "پاسخ داده شده", + "API error!": "", "Action": "عملیات", "Actions": "عملیات", "Active": "فعال", @@ -276,6 +278,7 @@ "Magazine": "مجله", "Main address": "آدرس اصلی", "Main category": "سرفصل اصلی", + "Main language content": "", "Main product category": "دسته اصلی محصول", "Manage": "مدیریت", "Max click": "حداکثر تعداد کلیک", @@ -510,6 +513,7 @@ "Total amount": "مقدار کل", "Tracking code": "کد رهگیری", "Translate": "ترجمان", + "Translate model": "", "Translate updated": "ترجمه به روز شد", "Translate with AI": "ترجمه با کمک هوش مصنوعی", "Translated by ai xstack service:": "", @@ -536,6 +540,7 @@ "Username": "نام کاربری", "Users": "کاربران", "Users list": "فهرست کاربران", + "Value": "", "Verify Your Email Address": "تایید رایانامه یا ایمیل خود", "Video clip": "ویدئو کلیپ", "Video clips": "کلیپ ها", diff --git a/resources/lang/ru.json b/resources/lang/ru.json index c1ce49d..fd17012 100644 --- a/resources/lang/ru.json +++ b/resources/lang/ru.json @@ -6,6 +6,8 @@ "$log->action": "$log->действие", ":app Dear customer Your :product signed for you.": ":app Уважаемый клиент, ваш :product подписан для вас.", "A fresh verification link has been sent to your email address.": "На ваш адрес электронной почты была отправлена новая ссылка для подтверждения.", + "AI translate form original source": "", + "API error!": "", "Action": "Действие", "Actions": "Действия", "Active": "Активный", @@ -69,6 +71,7 @@ "City": "Город", "Click": "Нажмите", "Click here to upload or drag and drop here": "Нажмите здесь для загрузки или перетащите сюда", + "Clip": "", "Clip list": "Список клипов", "Clips": "Клипы", "Code": "Код", @@ -211,6 +214,7 @@ "Magazine": "«Журнал»", "Main address": "«Основной адрес»", "Main category": "Главная категория", + "Main language content": "", "Main product category": "«Основная категория товаров»", "Manage": "Управлять", "Max click": "«Макс клик»", @@ -319,6 +323,7 @@ "Properties list": "«Список свойств»", "Properties meta": "«Мета свойства»", "Properties sort": "«Сортировка свойств»", + "Props": "", "Publish now": "«Опубликовать сейчас»", "Published": "Опубликовано", "Quantity": "Количество", @@ -404,6 +409,7 @@ "Total Price": "Итоговая цена", "Total amount": "Общая сумма", "Tracking code": "Код отслеживания", + "Translate model": "", "Translate updated": "", "Translate with AI": "", "Translated by ai xstack service:": "", @@ -429,6 +435,7 @@ "Username": "Имя пользователя", "Users": "«Пользователи»", "Users list": "«Список пользователей»", + "Value": "", "Verify Your Email Address": "Проверьте свой адрес электронной почты", "Video clip": "Видеоклип", "Video clips": "Видеоклипы", diff --git a/resources/sass/app.scss b/resources/sass/app.scss index 5b166cd..f87b18e 100755 --- a/resources/sass/app.scss +++ b/resources/sass/app.scss @@ -183,6 +183,63 @@ nav { color: #ffffff55; } +.lang-support{ + background: dodgerblue; + color: white; + padding: 7px; + text-align: center; + font-weight: 300; + margin-top: 1rem; +} + +.btn-ai{ + height: 65px; + width: 65px; + background: dodgerblue; + font-size: 25px; + color: white; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + margin: auto; + transition: 400ms; + cursor: pointer; + box-shadow: inset 0 0 0 0 #00000022; + + &:hover{ + box-shadow: inset 0 0 0 75px #00000022; + } +} + +.btn-add{ + height: 50px; + width: 50px; + background: #333; + font-size: 25px; + color: white; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + transition: 400ms; + cursor: pointer; + box-shadow: inset 0 0 0 0 #ffffff22; + position: fixed; + left: 1rem; + bottom: 1rem; + text-decoration: none; + + &:hover{ + box-shadow: inset 0 0 0 75px #00000022; + } +} + +.img-squire{ + width: 100%; + height: 175px; + object-fit: cover; +} /*-768px width*/ @media ( max-width: 1000px ) { .gird4 { @@ -250,3 +307,9 @@ nav { right: auto !important; left: 2rem !important; } + +.no-dec{ + a{ + text-decoration: none; + } +} diff --git a/resources/views/admin/cat/catIndex.blade.php b/resources/views/admin/cat/catIndex.blade.php index e99637c..0549721 100755 --- a/resources/views/admin/cat/catIndex.blade.php +++ b/resources/views/admin/cat/catIndex.blade.php @@ -26,8 +26,6 @@
+ {{__("Title")}} + | ++ {{__("Value")}} + | +
---|---|
+ {{$tr}} + | ++ {{($model->{$tr})}} + | +