TranslateLogic.php 11.1 KB
<?php
/**
 * @remark :
 * @name   :TranslateLogic.php
 * @author :lyh
 * @method :post
 * @time   :2024/1/12 9:42
 */

namespace App\Http\Logic\Bside\Setting;

use App\Http\Logic\Bside\BaseLogic;
use App\Models\Com\UpdateLog;
use App\Models\User\UserLog;
use App\Models\WebSetting\Translate as TranslateModel;
use App\Models\WebSetting\WebLanguage;
use App\Helper\Translate;

class TranslateLogic extends BaseLogic
{
    public function __construct()
    {
        parent::__construct();
        $this->model = new TranslateModel();
        $this->param = $this->requestAll;
    }

    /**
     * @remark :
     * @name   :getTranslateList
     * @author :lyh
     * @method :post
     * @time   :2024/4/9 10:59
     */
    public function getTranslateList(){
        $data = [];
        if($this->param['url'] == 'All' || $this->param['url'] == 'other_all_text'){
            $info = $this->model->read(['url'=>$this->param['url'],'language_id'=>$this->param['language_id'],'type'=>$this->param['type']]);
            if(!empty($info) && !empty($info['data'])){
                $translateInfo = json_decode($info['data'],JSON_UNESCAPED_UNICODE);
                foreach ($translateInfo as $k => $v){
                    $data[] = [$k=>$v];
                }
            }
            return $this->success($data);
        }
        // 需要校对路由
        $url = $this->user['domain'] . (($this->param['url'] != '/') ? $this->param['url'] : '');
        // 需要校对语种
        $languageInfo = $this->getLanguage($this->param['language_id']);
        // 原始校对内容
        $info = $this->model->read(['url'=>$this->param['url'],'language_id'=>$this->param['language_id'],'type'=>$this->param['type']]);
        //获取当前URl的所有文本内容
        $text_array = $this->getUrlRead($url);
        // 原始校对程序
        $old_key = [];//key值组成数据
        if($info !== false){
            $data_read = json_decode($info['data'],JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
            foreach ($data_read as $k => $v){
                $old_key[] = $k;
                $data[] = [$k => $v];
            }
        }
        $arr2 = array_values(array_diff($text_array, $old_key));
        if(!empty($arr2)){
            $i = 0;
            TranslateText:
            $translate_list = Translate::tran($arr2, $languageInfo['short']);
            if(empty($translate_list)){
                if ($i < 3) {
                    $i++;
                    goto TranslateText;
                }
                $this->fail('翻译失败,请稍后重试!');
            }
            if(count($arr2) == 1){
                $data[] = [
                    $arr2[0]=>$translate_list
                ];
            }else{
                foreach ($arr2 as $k => $v){
                    $data[] = [
                        $v=>$translate_list[$k]
                    ];
                }

            }
        }
        return $this->success($data);
    }


    /**
     * @remark :获取图片列表
     * @name   :imageList
     * @author :lyh
     * @method :post
     * @time   :2023/11/23 17:29
     */
    public function getTranslateImageList(){
        if($this->param['url'] == 'All'){
            $info = $this->model->read(['url'=>$this->param['url'],'language_id'=>$this->param['language_id'],'type'=>$this->param['type']]);
            $data = [];
            if(!empty($info) && !empty($info['data'])){
                $translateInfo = json_decode($info['data'],JSON_UNESCAPED_UNICODE);
                foreach ($translateInfo as $k => $v){
                    $data[] = [$k=>$v];
                }
            }
            return $this->success($data);
        }
        $url = $this->user['domain'].(($this->param['url'] != '/') ? $this->param['url'] : '');
        $info = $this->model->read(['url'=>str_replace_url($this->param['url']),'language_id'=>$this->param['language_id'],'type'=>$this->param['type']]);
        $data = [];
        if($info === false){
            $new_list = $this->getUrlImageRead($url);
            foreach ($new_list as $v){
                $data[] = [
                    $v=>$v,
                ];
            }
            return $this->success($data);
        }
        $new_list = $this->getUrlImageRead($url);
        $old_list = [];
        $data_read = json_decode($info['data'],JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        foreach ($data_read as $k=>$v){
            $old_list[] = $k;
            $data[] = [
                $k=>$v,
            ];
        }
        $arr2 = array_values(array_diff($new_list, $old_list));
        if(!empty($arr2)){
            foreach ($arr2 as $v1){
                $data[] = [
                    $v1=>$v1
                ];
            }
        }
        return $this->success($data);
    }
    /**
     * @remark :获取语种信息
     * @name   :getLanguage
     * @author :lyh
     * @method :post
     * @time   :2024/1/12 9:45
     */
    public function getLanguage($language_id){
        //获取语种信息
        $languageModel = new WebLanguage();
        $languageInfo = $languageModel->read(['id'=>$language_id]);
        if($languageInfo === false){
            $this->fail('请选择语种');
        }
        return $this->success($languageInfo);
    }

    /**
     * 获取url HTML需要翻译的文本
     * @param $url
     * @return array
     */
    public function getUrlRead($url){
        $dom = file_get_html($url);
        $texts = $dom->find("text");
        $description = $dom->find("meta[name=description]",0);
        $keywords = $dom->find("meta[name=keywords]",0);
        // 组装需要翻译的内容 HTML内文案、meta description、meta keywords
        $need_tran = [];
        foreach ($texts as $k=>$text) {
            $tag= $text->parent()->tag;
            if (in_array($tag, ['script', 'style', 'root'])){
                continue;
            }
            $string = trim($text->text());
            if (empty($string)){
                continue;
            }
            $country_class = '';
            if (method_exists($text->parent()->parent(),"find") && $text->parent()->parent()->find("b")) {
                $country_class = $text->parent()->parent()->find("b",0)->class;
            }
            if(FALSE !== strpos($country_class, 'country-flag')) {
                continue;
            }
            if(!in_array(htmlspecialchars_decode(html_entity_decode($string)),$need_tran)){
                $need_tran[] = htmlspecialchars_decode(html_entity_decode($string));
            }
        }
        $need_tran[] = $description ? $description->attr['content'] : '';
        $need_tran[] = $keywords ? $keywords->attr['content'] : '';
        return $need_tran;
    }


    /**
     * @remark :获取Url内容
     * @name   :getUrlRead
     * @author :lyh
     * @method :post
     * @time   :2023/11/22 10:02
     */
    public function getUrlImageRead($url){
        $contextOptions = [
            'ssl' => [
                'verify_peer' => false,
                'verify_peer_name' => false,
            ],
        ];
        $pattern = '/<img.*?src="(.*?)".*?>/i';
        $matches = array();
        $context = stream_context_create($contextOptions);
        $sourceCode = file_get_contents($url, false, $context);
        preg_match_all($pattern, $sourceCode, $matches);
        $textContentArray = $matches[1];
        $data = [];
        foreach ($textContentArray as $v){
            if(!empty($v)){
                $data[] = $v;
            }
        }
        $uniqueArray = array_unique($data);
        $data = array_values($uniqueArray);
        return $data;
    }

    /**
     * @name   :(新增/更新多语言)save
     * @author :lyh
     * @method :post
     * @time   :2023/6/12 10:52
     */
    public function translateSave(){
        $data = [];
        if(!empty($this->param['data'])){
            //处理传递的data
            foreach ($this->param['data'] as $k => $v){
                if(!empty($v) && is_array($v)){
                    foreach ($v as $text => $translate){
                        $data[$text] = $translate;
                    }
                }
            }
            $this->param['data'] = $data;
        }
        try {
            $info = $this->model->read(['language_id'=>$this->param['language_id'],'url'=>$this->param['url'],'project_id'=>$this->user['project_id'],'type'=>$this->param['type']]);
            if($info === false){
                $param = [
                    'type'=>$this->param['type'],
                    'project_id'=>$this->user['project_id'],
                    'url'=>str_replace_url($this->param['url']),
                    'language_id'=>$this->param['language_id'],
                    'alias'=>$this->param['alias'],
                ];
                $param['data'] = json_encode($data,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
                $this->model->add($param);
            }else{
                if(!empty($data)){
                    $data = json_encode($data,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
                    $this->model->edit(['data'=>$data],['language_id'=>$this->param['language_id'],'project_id'=>$this->user['project_id'],'url'=>$this->param['url'],'type'=>$this->param['type']]);
                }
            }
            //写日志
            $userLogModel = new UserLog();
            $userLogModel->add(['model'=>'translate/save','remark'=>json_encode($this->param,true),'type'=>0,'operator_id'=>$this->user['id'],'project_id'=>$this->user['project_id']]);
        }catch (\Exception $e){
            $this->fail('系统错误请联系管理员');
        }
        $this->handleRoute($this->param['url']);
        return $this->success();
    }

    /**
     * @remark :处理路由
     * @name   :handleRoute
     * @author :lyh
     * @method :post
     * @time   :2024/1/18 17:25
     */
    public function handleRoute($url){
        $lang =  $this->getLanguage($this->param['language_id'])['short'];
        $str = trim($url,'/');
        $page = 0;
        $route = 'index';
        if(!empty($str)){
            $arr = explode('/',$str);
            $num = count($arr);
            if($num == 1){
                $route = $arr[0];
            }elseif ($num == 2){
                if(ctype_digit($arr[1])){//是数字的情况
                    $page = $arr[1];
                    $route = $arr[0];
                }else{
                    $route = $arr[1];
                }
            }elseif($num == 3){
                if(ctype_digit($arr[2])){//是数字的情况
                    $page = $arr[2];
                    $route = $arr[0];
                }else{
                    if($arr[2] == 'page'){
                        $route = $arr[1];
                    }else{
                        $route = $arr[0];
                    }
                }
            }elseif ($num == 4){
                if(ctype_digit($arr[3])){//是数字的情况
                    $page = $arr[3];
                    $route = $arr[1];
                }
            }
        }
        if($page != 0){
            $data['page'] = $page;
        }
        $data['new_route'] = $route;
        $data['lang'] = $lang;
        $data['project_id']= $this->user['project_id'];
        $this->curlDelRoute($data);
    }
}