src/AppBundle/Controller/BaseController.php line 433

Open in your IDE?
  1. <?php
  2. namespace AppBundle\Controller;
  3. use AppBundle\Common\ArrayToolkit;
  4. use AppBundle\Common\Exception\AbstractException;
  5. use AppBundle\Common\Exception\ResourceNotFoundException;
  6. use AppBundle\Common\JWTAuth;
  7. use Biz\Common\CommonException;
  8. use Biz\QiQiuYun\Service\QiQiuYunSdkProxyService;
  9. use Biz\User\CurrentUser;
  10. use Codeages\Biz\Framework\Service\Exception\AccessDeniedException;
  11. use Firebase\JWT\JWT;
  12. use Symfony\Bundle\FrameworkBundle\Controller\Controller;
  13. use Symfony\Component\Form\Extension\Core\Type\FormType;
  14. use Symfony\Component\HttpFoundation\JsonResponse;
  15. use Symfony\Component\HttpFoundation\Request;
  16. use Symfony\Component\HttpFoundation\Response;
  17. use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
  18. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  19. use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
  20. use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
  21. use Symfony\Component\Security\Http\SecurityEvents;
  22. class BaseController extends Controller
  23. {
  24.     /**
  25.      * @return CurrentUser
  26.      */
  27.     protected function getCurrentUser()
  28.     {
  29.         return $this->getUser();
  30.     }
  31.     protected function getBiz()
  32.     {
  33.         return $this->get('biz');
  34.     }
  35.     /**
  36.      * @return CurrentUser
  37.      */
  38.     public function getUser()
  39.     {
  40.         $biz $this->getBiz();
  41.         return $biz['user'];
  42.     }
  43.     /**
  44.      * switch current user.
  45.      *
  46.      * @return CurrentUser
  47.      */
  48.     protected function switchUser(Request $requestCurrentUser $user)
  49.     {
  50.         $user['currentIp'] = $request->getClientIp();
  51.         $token = new UsernamePasswordToken($usernull'main'$user['roles']);
  52.         $this->container->get('security.token_storage')->setToken($token);
  53.         $biz $this->getBiz();
  54.         $biz['user'] = $user;
  55.         $this->get('event_dispatcher')->dispatch(SecurityEvents::INTERACTIVE_LOGIN, new InteractiveLoginEvent($request$token));
  56.         // $this->getLogService()->info('user', 'user_switch_success', '用户切换登录成功');
  57.         return $user;
  58.     }
  59.     protected function prepareLimitedTime($limitedTime 0)
  60.     {
  61.         $limitedTime ltrim($limitedTime0);
  62.         if (empty($limitedTime)) {
  63.             return 0;
  64.         }
  65.         return $limitedTime;
  66.     }
  67.     protected function authenticateUser(array $user)
  68.     {
  69.         $user['currentIp'] = $this->container->get('request_stack')->getCurrentRequest()->getClientIp();
  70.         $currentUser = new CurrentUser();
  71.         $currentUser->fromArray($user);
  72.         return $this->switchUser($this->get('request_stack')->getCurrentRequest(), $currentUser);
  73.     }
  74.     protected function authByToken(Request $request)
  75.     {
  76.         $authorization $request->headers->get('Authorization');
  77.         if (!empty($authorization) && (false !== strpos($authorization'Bearer '))) {
  78.             $token str_replace('Bearer '''$authorization);
  79.         } else {
  80.             $token $request->query->get('token');
  81.         }
  82.         if (empty($token)) {
  83.             return;
  84.         }
  85.         $storage $this->setting('storage', []);
  86.         try {
  87.             $payload JWT::decode($token, [$storage['cloud_access_key'] => $storage['cloud_secret_key']], ['HS256']);
  88.         } catch (\RuntimeException $e) {
  89.             return;
  90.         }
  91.         $user $this->getUserService()->getUser($payload->sub);
  92.         if (empty($user)) {
  93.             return;
  94.         }
  95.         $currentUser = new CurrentUser();
  96.         $currentUser->fromArray($user);
  97.         $biz $this->getBiz();
  98.         $biz['user'] = $currentUser;
  99.     }
  100.     protected function fillUserStatus($conditions)
  101.     {
  102.         if (isset($conditions['userStatus'])) {
  103.             if ('locked' == $conditions['userStatus']) {
  104.                 $conditions['locked'] = '1';
  105.             }
  106.             if ('unlock' == $conditions['userStatus']) {
  107.                 $conditions['locked'] = '0';
  108.             }
  109.             unset($conditions['userStatus']);
  110.             return $conditions;
  111.         }
  112.         return $conditions;
  113.     }
  114.     protected function fillOrgCode($conditions)
  115.     {
  116.         if ($this->setting('magic.enable_org')) {
  117.             if (!isset($conditions['orgCode'])) {
  118.                 $conditions['likeOrgCode'] = $this->getCurrentUser()->getSelectOrgCode();
  119.             } else {
  120.                 $conditions['likeOrgCode'] = $conditions['orgCode'];
  121.                 unset($conditions['orgCode']);
  122.             }
  123.         } else {
  124.             if (isset($conditions['orgCode'])) {
  125.                 unset($conditions['orgCode']);
  126.             }
  127.         }
  128.         return $conditions;
  129.     }
  130.     /**
  131.      * 判断是否微信内置浏览器访问.
  132.      *
  133.      * @return bool
  134.      */
  135.     protected function isWxClient()
  136.     {
  137.         return $this->isMobileClient() && false !== strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger');
  138.     }
  139.     /**
  140.      * 是否移动端访问访问.
  141.      *
  142.      * @return bool
  143.      */
  144.     protected function isMobileClient()
  145.     {
  146.         // 如果有HTTP_X_WAP_PROFILE则一定是移动设备
  147.         if (isset($_SERVER['HTTP_X_WAP_PROFILE'])) {
  148.             return true;
  149.         }
  150.         //如果via信息含有wap则一定是移动设备,部分服务商会屏蔽该信息
  151.         if (isset($_SERVER['HTTP_VIA'])) {
  152.             //找不到为flase,否则为true
  153.             return stristr($_SERVER['HTTP_VIA'], 'wap') ? true false;
  154.         }
  155.         //判断手机发送的客户端标志,兼容性有待提高
  156.         if (isset($_SERVER['HTTP_USER_AGENT'])) {
  157.             $clientkeywords = [
  158.                 'nokia''sony''ericsson''mot''samsung''htc''sgh''lg''sharp',
  159.                 'sie-''philips''panasonic''alcatel''lenovo''iphone''ipod''blackberry''meizu',
  160.                 'android''netfront''symbian''ucweb''windowsce''palm''operamini''operamobi',
  161.                 'openwave''nexusone''cldc''midp''wap''mobile',
  162.             ];
  163.             // 从HTTP_USER_AGENT中查找手机浏览器的关键字
  164.             if (preg_match('/('.implode('|'$clientkeywords).')/i'strtolower($_SERVER['HTTP_USER_AGENT']))) {
  165.                 return true;
  166.             }
  167.         }
  168.         //协议法,因为有可能不准确,放到最后判断
  169.         if (isset($_SERVER['HTTP_ACCEPT'])) {
  170.             // 如果只支持wml并且不支持html那一定是移动设备
  171.             // 如果支持wml和html但是wml在html之前则是移动设备
  172.             if ((false !== strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml'))
  173.                 && (false === strpos($_SERVER['HTTP_ACCEPT'], 'text/html')
  174.                     || (strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') < strpos($_SERVER['HTTP_ACCEPT'], 'text/html'))
  175.                 )) {
  176.                 return true;
  177.             }
  178.         }
  179.         return false;
  180.     }
  181.     protected function purifyHtml($html$trusted false)
  182.     {
  183.         $biz $this->getBiz();
  184.         $htmlHelper $biz['html_helper'];
  185.         return $htmlHelper->purify($html$trusted);
  186.     }
  187.     protected function trans($id, array $parameters = [], $domain null$locale null)
  188.     {
  189.         return $this->container->get('translator')->trans($id$parameters$domain$locale);
  190.     }
  191.     protected function isPluginInstalled($pluginName)
  192.     {
  193.         return $this->get('kernel')->getPluginConfigurationManager()->isPluginInstalled($pluginName);
  194.     }
  195.     public function getPluginVersion($pluginName)
  196.     {
  197.         $plugins $this->get('kernel')->getPluginConfigurationManager()->getInstalledPlugins();
  198.         foreach ($plugins as $plugin) {
  199.             if (strtolower($plugin['code']) == strtolower($pluginName)) {
  200.                 return $plugin['version'];
  201.             }
  202.         }
  203.         return null;
  204.     }
  205.     protected function getTargetPath(Request $request)
  206.     {
  207.         if ($request->query->get('goto')) {
  208.             $targetPath $request->query->get('goto');
  209.         } elseif ($request->getSession()->has('_target_path')) {
  210.             $targetPath $request->getSession()->get('_target_path');
  211.         } else {
  212.             $targetPath $request->headers->get('Referer');
  213.         }
  214.         if (false !== strpos($targetPath'/register')) {
  215.             return $this->generateUrl('homepage');
  216.         }
  217.         if ($targetPath == $this->generateUrl('login', [], UrlGeneratorInterface::ABSOLUTE_URL)) {
  218.             return $this->generateUrl('homepage');
  219.         }
  220.         $url explode('?'$targetPath);
  221.         if ($url[0] == $this->generateUrl('partner_logout', [], UrlGeneratorInterface::ABSOLUTE_URL)) {
  222.             return $this->generateUrl('homepage');
  223.         }
  224.         if ($url[0] == $this->generateUrl('password_reset_update', [], UrlGeneratorInterface::ABSOLUTE_URL)) {
  225.             $targetPath $this->generateUrl('homepage', [], UrlGeneratorInterface::ABSOLUTE_URL);
  226.         }
  227.         if (strpos($url[0], $request->getPathInfo()) > -1) {
  228.             $targetPath $this->generateUrl('homepage', [], UrlGeneratorInterface::ABSOLUTE_URL);
  229.         }
  230.         if (false !== strpos($url[0], 'callback')
  231.             || false !== strpos($url[0], '/login/bind')
  232.             || false !== strpos($url[0], 'crontab')
  233.         ) {
  234.             $targetPath $this->generateUrl('homepage', [], UrlGeneratorInterface::ABSOLUTE_URL);
  235.         }
  236.         if (empty($targetPath)) {
  237.             $targetPath $this->generateUrl('homepage', [], UrlGeneratorInterface::ABSOLUTE_URL);
  238.         }
  239.         return $this->filterRedirectUrl($targetPath);
  240.     }
  241.     protected function setFlashMessage($level$message)
  242.     {
  243.         $this->get('session')->getFlashBag()->add($level$message);
  244.     }
  245.     protected function setFlashException(HttpExceptionInterface $exception)
  246.     {
  247.         $this->setFlashMessage(
  248.             'currentThrowedException',
  249.             [
  250.                 'code' => $exception->getCode(),
  251.                 'message' => $exception->getMessage(),
  252.                 'trace' => $exception->getTraceAsString(),
  253.                 'statusCode' => $exception->getStatusCode(),
  254.             ]
  255.         );
  256.     }
  257.     protected function agentInWhiteList($userAgent)
  258.     {
  259.         // com.tencent.mm.app.Application 是安卓端小程序在播放视频时的UA,无法找到为什么UA是这样的具体原因,为了容错
  260.         $whiteList = ['iPhone''iPad''Android''HTC''com.tencent.mm.app.Application'];
  261.         return ArrayToolkit::some($whiteList, function ($agent) use ($userAgent) {
  262.             return strpos($userAgent$agent) > -1;
  263.         });
  264.     }
  265.     protected function createNamedFormBuilder($name$data null, array $options = [])
  266.     {
  267.         return $this->container->get('form.factory')->createNamedBuilder($nameFormType::class, $data$options);
  268.     }
  269.     protected function createJsonResponse($data null$status 200$headers = [])
  270.     {
  271.         return new JsonResponse($data$status$headers);
  272.     }
  273.     protected function createJsonpResponse($data null$callback 'callback'$status 200$headers = [])
  274.     {
  275.         $response $this->createJsonResponse($data$status$headers);
  276.         return $response->setCallback($callback);
  277.     }
  278.     //@todo 此方法是为了和旧的调用兼容,考虑清理掉
  279.     protected function createErrorResponse($request$name$message)
  280.     {
  281.         $error = ['error' => ['name' => $name'message' => $message]];
  282.         return new JsonResponse($error'200');
  283.     }
  284.     /**
  285.      * JSONM
  286.      * https://github.com/lifesinger/lifesinger.github.com/issues/118.
  287.      */
  288.     protected function createJsonmResponse($data)
  289.     {
  290.         $response = new JsonResponse($data);
  291.         $response->setCallback('define');
  292.         return $response;
  293.     }
  294.     /**
  295.      * 创建消息提示响应.
  296.      *
  297.      * @param string $type     消息类型:info, warning, error
  298.      * @param string $message  消息内容
  299.      * @param string $title    消息抬头
  300.      * @param int    $duration 消息显示持续的时间
  301.      * @param string $goto     消息跳转的页面
  302.      *
  303.      * @return Response
  304.      */
  305.     protected function createMessageResponse($type$message$title ''$duration 0$goto null)
  306.     {
  307.         if (!in_array($type, ['info''warning''error'])) {
  308.             $this->createNewException(CommonException::ERROR_PARAMETER());
  309.         }
  310.         return $this->render('default/message.html.twig', [
  311.             'type' => $type,
  312.             'message' => $message,
  313.             'title' => $title,
  314.             'duration' => $duration,
  315.             'goto' => $this->filterRedirectUrl($goto),
  316.         ]);
  317.     }
  318.     protected function createResourceNotFoundException($resourceType$resourceId$message '')
  319.     {
  320.         return new ResourceNotFoundException($resourceType$resourceId$message);
  321.     }
  322.     public function createAccessDeniedException($message 'Access Denied', \Exception $previous null)
  323.     {
  324.         return new AccessDeniedException($message403$previous);
  325.     }
  326.     protected function createNewException($e)
  327.     {
  328.         if ($e instanceof AbstractException) {
  329.             throw $e;
  330.         }
  331.         throw new \Exception();
  332.     }
  333.     /**
  334.      * 安全的重定向.
  335.      *
  336.      * 如果url不属于非本站域名下的,则重定向到本周首页。
  337.      *
  338.      * @param $url string 重定向url
  339.      * @param $status int 重定向时的HTTP状态码
  340.      *
  341.      * @return \Symfony\Component\HttpFoundation\RedirectResponse
  342.      */
  343.     public function redirectSafely($url$status 302)
  344.     {
  345.         $url $this->filterRedirectUrl($url);
  346.         return $this->redirect($url$status);
  347.     }
  348.     public function render($view, array $parameters = [], Response $response null)
  349.     {
  350.         $biz $this->getBiz();
  351.         foreach ($biz['render_view_resolvers'] as $resolver) {
  352.             $view $resolver->generateRenderView($view$parameters);
  353.         }
  354.         return parent::render($view$parameters$response);
  355.     }
  356.     public function renderView($view, array $parameters = [])
  357.     {
  358.         $biz $this->getBiz();
  359.         foreach ($biz['render_view_resolvers'] as $resolver) {
  360.             $view $resolver->generateRenderView($view$parameters);
  361.         }
  362.         return parent::renderView($view$parameters);
  363.     }
  364.     /**
  365.      * 过滤URL.
  366.      *
  367.      * 如果url不属于非本站域名下的,则返回本站首页地址。
  368.      *
  369.      * @param $url string 待过滤的$url
  370.      *
  371.      * @return string
  372.      */
  373.     public function filterRedirectUrl($url)
  374.     {
  375.         $host $this->get('request_stack')->getCurrentRequest()->getHost();
  376.         $safeHosts = [$host];
  377.         $parsedUrl parse_url($url);
  378.         if (false == $parsedUrl) {
  379.             return $this->generateUrl('homepage', [], UrlGeneratorInterface::ABSOLUTE_URL);
  380.         }
  381.         if (!empty($parsedUrl['host'])) {
  382.             $url $this->unParseUrl($parsedUrl);
  383.         } elseif ('/' != $url[0]) {
  384.             $url $this->generateUrl('homepage', [], UrlGeneratorInterface::ABSOLUTE_URL);
  385.         }
  386.         $isUnsafeHost = isset($parsedUrl['host']) && !in_array($parsedUrl['host'], $safeHosts);
  387.         $isInvalidScheme = isset($parsedUrl['scheme']) && !in_array($parsedUrl['scheme'], ['http''https']);
  388.         if (empty($url) || $isUnsafeHost || $isInvalidScheme) {
  389.             $url $this->generateUrl('homepage', [], UrlGeneratorInterface::ABSOLUTE_URL);
  390.         }
  391.         return strip_tags($url);
  392.     }
  393.     protected function unParseUrl($parsedUrl)
  394.     {
  395.         $scheme = isset($parsedUrl['scheme']) ? $parsedUrl['scheme'].'://' '//';
  396.         $host $parsedUrl['host'] ?? '';
  397.         $port = isset($parsedUrl['port']) ? ':'.$parsedUrl['port'] : '';
  398.         $path $parsedUrl['path'] ?? '';
  399.         $query = isset($parsedUrl['query']) ? '?'.$parsedUrl['query'] : '';
  400.         $fragment = isset($parsedUrl['fragment']) ? '#'.$parsedUrl['fragment'] : '';
  401.         return "$scheme$host$port$path$query$fragment";
  402.     }
  403.     /**
  404.      * 验证验证码token
  405.      *
  406.      * @return [type] [description]
  407.      */
  408.     protected function checkDragCaptchaToken(Request $request$token)
  409.     {
  410.         $enableAntiBrushCaptcha $this->getSettingService()->node('ugc_content_audit.enable_anti_brush_captcha');
  411.         if (empty($enableAntiBrushCaptcha)) {
  412.             return true;
  413.         }
  414.         $session $request->getSession();
  415.         $dragTokens = empty($session->get('dragTokens')) ? [] : $session->get('dragTokens');
  416.         if (in_array($token$dragTokens)) {
  417.             array_splice($dragTokensarray_search($token$dragTokens), 1);
  418.             $session->set('dragTokens'$dragTokens);
  419.             return true;
  420.         }
  421.         return false;
  422.     }
  423.     protected function createSuccessJsonResponse($data = [])
  424.     {
  425.         $data array_merge(['success' => 1], $data);
  426.         return $this->createJsonResponse($data);
  427.     }
  428.     protected function createFailJsonResponse($data = [])
  429.     {
  430.         $data array_merge(['success' => 0], $data);
  431.         return $this->createJsonResponse($data);
  432.     }
  433.     protected function getWebExtension()
  434.     {
  435.         return $this->get('web.twig.extension');
  436.     }
  437.     protected function createService($alias)
  438.     {
  439.         $biz $this->getBiz();
  440.         return $biz->service($alias);
  441.     }
  442.     protected function setting($name$default null)
  443.     {
  444.         return $this->get('web.twig.extension')->getSetting($name$default);
  445.     }
  446.     /**
  447.      * @return \Biz\User\Service\UserService
  448.      */
  449.     protected function getUserService()
  450.     {
  451.         return $this->getBiz()->service('User:UserService');
  452.     }
  453.     /**
  454.      * @return \Biz\System\Service\LogService
  455.      */
  456.     protected function getLogService()
  457.     {
  458.         return $this->getBiz()->service('System:LogService');
  459.     }
  460.     /**
  461.      * @return QiQiuYunSdkProxyService
  462.      */
  463.     protected function getQiQiuYunSdkProxyService()
  464.     {
  465.         return $this->createService('QiQiuYun:QiQiuYunSdkProxyService');
  466.     }
  467.     protected function pushEventTracking($action$data null)
  468.     {
  469.         return $this->getQiQiuYunSdkProxyService()->pushEventTracking($action$data);
  470.     }
  471.     protected function getJWTAuth()
  472.     {
  473.         $setting $this->setting('storage', []);
  474.         $accessKey = !empty($setting['cloud_access_key']) ? $setting['cloud_access_key'] : '';
  475.         $secretKey = !empty($setting['cloud_secret_key']) ? $setting['cloud_secret_key'] : '';
  476.         $key md5($accessKey.$secretKey);
  477.         return new JWTAuth($key);
  478.     }
  479.     protected function getHttpHost()
  480.     {
  481.         return $this->getSchema()."://{$_SERVER['HTTP_HOST']}";
  482.     }
  483.     protected function getSchema()
  484.     {
  485.         $https = empty($_SERVER['HTTPS']) ? '' $_SERVER['HTTPS'];
  486.         if (!empty($https) && 'off' !== strtolower($https)) {
  487.             return 'https';
  488.         }
  489.         return 'http';
  490.     }
  491. }