Laravel 5.6,在哪里保留额外的类(附加功能)?

问题描述 投票:1回答:1

我需要在我的控制器中对某些CRM api提出请求。为了做到这一点,我有很大的方法。它看起来很难看。我知道有一些“服务”,并将额外的代码放入服务是一个好方法。但我不知道这是什么。它是app文件夹中的自定义类吗?或者也许是服务提供商?我已阅读服务提供商文档,我不确定服务提供商是否适合这一点。这是我的代码:

<?php

namespace App\Http\Controllers;

use App\User;
use App\UserInfo;
use Validator;
use Illuminate\Http\Request;

class UserController extends Controller
{
/**
 * Display a listing of the resource.
 *
 * @return \Illuminate\Http\Response
 */
public function index(Request $request)
{
    $users = User::with('info')
            ->paginate(20);

    $users->withPath(DIRECTORY_SEPARATOR . $request->path() .DIRECTORY_SEPARATOR);

    return response()->json($users)->setEncodingOptions(JSON_UNESCAPED_UNICODE);
}

/**
 * Store a newly created resource in storage.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return \Illuminate\Http\Response
 */
public function store(Request $request)
{
    $data = $request->json()->all();
    $rules = [
            'name' => 'required',
            'phone' => 'required|unique:users'
    ];
    $validator = Validator::make($data, $rules);
    if ($validator->fails()) return response()->json(['errors'=>$validator->errors()]);

        $user = new User();
        $user->name = request('name');
        $user->phone = request('phone');
        $user_info_obj = $this->storeUserInfo();
        if($user_info_obj === null){
            return response('Impassible to define user geo data', 400);
        }
        $user->info_id = $user_info_obj->id;
        $user->save();

        $this->makeAMOLead($user->name,
            $user->phone,
            $user_info_obj->user_agent,
            $user_info_obj->city,
            $user_info_obj->country);

        return response()->json(['success' => 'User created successfully']);
}

public function storeUserInfo()
{
    $ip = request()->ip();

    $reader = new \GeoIp2\Database\Reader('../resources/geo-lite2-city_20180807/GeoLite2-City.mmdb');

    try {
        $record = $reader->city($ip);
    }
    catch (\Throwable $e){
        // Code bellow is for testing on localhost, Because of maybe exception instead of geo obj on localhost.
        $info = new UserInfo();
        $info->ip = '127.0.0.1';
        $info->city = 'Some city';
        $info->country = 'Some country';
        $info->country_code = 'Some code';
        $info->continent = 'Some continent';
        $info->continent_code = 'no';
        $info->user_agent = 'User agent';

        $info->save();

        return $info;

        //return null;
    }

    $city = $record->city->names['ru'];
    $continent = $record->continent->names['ru'];
    $continent_code = $record->continent->code;
    $country = $record->country->names['ru'];
    $country_code = $record->country->isoCode;
    $user_agent = \request()->userAgent();

    $info = new UserInfo();
    $info->ip = $ip;
    $info->city = $city;
    $info->country = $country;
    $info->country_code = $country_code;
    $info->continent = $continent;
    $info->continent_code = $continent_code;
    $info->user_agent = $user_agent;

    $info->save();

    return $info;
}

private function makeAMOLead($name, $phone, $userAgent, $city, $country)
{
    $domain = env('AMO_DOMAIN');
    $login = env('AMO_LOGIN');
    $hash = env('AMO_HASH');

    try {
        $credentials = new \ddlzz\AmoAPI\CredentialsManager($domain, $login, $hash);

        $settings = new \ddlzz\AmoAPI\SettingsStorage();
        $settings->setCookiePath(env('AMO_COOKIE_FILE_PATH'));

        $request = \ddlzz\AmoAPI\ClientFactory::create($credentials, $settings);

        $lead = new \ddlzz\AmoAPI\Model\Amo\Lead();

        $lead['name'] =  $name;

        if(env('AMO_PIPELINE_ID', null)){
            $lead['pipeline_id'] = intval(env('AMO_PIPELINE_ID'));
        }

        $lead['name'] = 'New pickup user ' . $name;

        $lead['custom_fields'] = [
            [
                'id' => env('AMO_NAME_FIELD_ID'),
                'values' => [
                   ['value' => $name],
                ]
            ],
            [
                'id' => env('AMO_USER_AGENT_FIELD_ID'),
                'values' => [
                    ['value' => $userAgent]
                ]
            ],
            [
                'id' => env('AMO_CITY_FIELD_ID'),
                'values' => [
                    ['value' => $city]
                ]
            ],
            [
                'id' => env('AMO_COUNTRY_FIELD_ID'),
                'values' => [
                    ['value' => $country]
                ]
            ],

        ];

        $lead['created_at'] = time();
        $result = $request->add($lead);

        $pipelineId = json_decode($result)->_embedded->items{0}->id;

        // create contact
        $contact = new \ddlzz\AmoAPI\Model\Amo\Contact();
        $contact['name'] = $name;
        $contact['created_at'] = time();
        $contact['leads_id'] = "$pipelineId";
       // dd($request->accountInfo(), true); // Call this, if you need to know ids of default fields (like phone, or position)

        $contact['custom_fields'] = [
            [
                'id' => env('AMO_CONTACT_PHONE_ID'),
                'values' => [
                    [
                        'value' => $phone,
                        'enum' => 'MOB',
                    ],
                ]
            ],
        ];

        $result = $request->add($contact);

    } catch (Exception $e) {
        echo response()->json(['error' => $e->getFile() . ': ' . $e->getMessage()]);
    }
}

}

看看makeAMOLead。这是我的控制器中的一个很好的方法,这对于控制器概念来说并不合适。

php laravel laravel-5.6
1个回答
1
投票

请使用repository pattern拆分应用程序和数据源之间的所有通信。并调用控制器内的存储库函数。这是一种很好的做法。这是一个你可以理解的article

例:

您的功能可以从控制器到存储库分开。

storeUserInfo

makeAMOLeadin

将您的函数移动到存储库并将其调用到控制器中。

© www.soinside.com 2019 - 2024. All rights reserved.