douying9296 2018-09-13 10:07
浏览 50
已采纳

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

I need to make request on some CRM api in my controller. For making this I have pretty big method. It's look like ugly. I know that there are some "Services" and to put additional code into Service is a good way. But I don't know what is this. Is it a custom classes into app folder? Or maybe it's Service-providers? I have read service-providers documentation and I'm not sure that service-providers is suitable for this. Here is my code:

<?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 = equest()->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()]);
    }
}

}

Look on the makeAMOLead. This is big method in my controller and this is not ok for controller conception.

  • 写回答

1条回答 默认 最新

  • douye2572 2018-09-13 10:26
    关注

    Please use repository pattern to split all the communication between the application and your data source. and call the repository functions inside your controller. It is good practice. Here is an article you can understand about that

    Example:

    Your functions can be separate from controller to repository.

    storeUserInfo

    makeAMOLeadin

    Move your functions an repository and call them into your controller.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码