@Leopandro
Разработчик CRM/ERP систем

Как оптимизировать такой код?

Код:
public static function getFullInfo($id)
	{
		$driverCar = DriverCar::findOne([
			'mifar_card_id' => $id
		]);
		if (!$driverCar)
		{
			return false;
		}
		$car = $driverCar->getCar()->one();
		$driver = $driverCar->getDriver()->one();

		$object = new \stdClass();
		if ($car->use_group_tariff && $car->group_tariff_id)
		{
			$groupTariff = GroupTariff::findOne([
				'id' => $car->group_tariff_id
			]);
			$object->town = $groupTariff->town;
			$object->town_center = $groupTariff->town_center;
			$object->km_price = $groupTariff->km_price;
		}
		else
		{
			$driverTariff = DriverTariff::findOne([
				'driver_id' => $driver->id
			]);
			$object->town = $driverTariff->town;
			$object->town_center = $driverTariff->town_center;
			$object->km_price = $driverTariff->km_price;
		}
		$object->company = $car->getCarBrand();
		$object->model = $car->model;
		$object->color = $car->color;
		$object->number = $car->number;
		$object->full_name = $driver->getFullName();
		$object->serial_number = $driver->serial_number;
		return $object;
	}


Причем таких кодов у меня накопилось достаточно. Наверное должен быть какой то метод который бы все это решил.
  • Вопрос задан
  • 264 просмотра
Решения вопроса 2
Rou1997
@Rou1997
JOIN.
Ответ написан
Комментировать
@shagguboy
а YII разве не умеет ходит по связям таблиц через геттеры?
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
@devian3000
Какая версия Yii? если вторая, то проще сделать наверное так.

<?php

public static function getFullInfo($id)
  {
    $driverCar = DriverCar::findOne([
      'mifar_card_id' => $id
    ]);
    if (empty( $driverCar ) ) return false;
	//Если тут одна сущность то делаем так
	// Но у объекта дожны быть методы getCar и getDriver в которых используется $this->hasOne()
    $car = $driverCar->сar;
    $driver = $driverCar->driver;

    $object = array();
	
    if ($driverCar->сar->use_group_tariff && $driverCar->сar->group_tariff_id)
    {
      $groupTariff = GroupTariff::findOne([
        'id' => $driverCar->сar->group_tariff_id
      ]);
	  $object = [
		'town' => $groupTariff->town,
		'town_center' => $groupTariff->town_center,
		'km_price' => $groupTariff->km_price,
	  ]
    }
    else
    {
      $driverTariff = DriverTariff::findOne([
        'driver_id' => $driverCar->driver->id
      ]);
	  $object = [
		'town' => $driverTariff->town,
		'town_center' => $driverTariff->town_center,
		'km_price' => $driverTariff->km_price,
	  ]
    }
	
	$object = array(
	    'company' => $driverCar->сar->getCarBrand();
		'model' => $driverCar->сar->model;
		'color' => $driverCar->сar->color;
		'object' = $driverCar->сar->number;
		'full_name' = $driverCar->driver->getFullName();
		'serial_number' = $driverCar->driver->serial_number;
	);
	

    return (object)$object;
  }
  
//Или так от структуры зависит и логики
  
class Driver extends ActiveRecord{
	
	public function getCar()
	{
		return $this->hasOne(Car::className(),['mifar_card_id' => 'id' ])
			->viaTable('{{%driverCar}}',['driver_id' => 'id']);
	}
	
	public function getTariff(){
		return $this->hasOne(DriverTariff::className(),['driver_id' => 'id'])
	}
	
}

class Car extends ActiveRecord{
	
	public function getTariff(){
		return $this->hasOne(GroupTariff::className(), ['id' => 'driver_id'])
	}
	
}
  
interface IGetTariff{
	public function getTown();
	public function getTownCenter();
	public function getKmPrice();
}
  
class GroupTariff extends ActiveRecord implements GetTariff{}
class DriverTariff extends ActiveRecord implements GetTariff{}
  
class FullDriverCarInfo extends Model{
	
	public static function getFullInfo( $driverId ){
		$driver = Driver::findOne('id'=>$driverId);
		if( empty($driver) ) return;
		
		/** @var $tariff IGetTariff */
		if( $driver->сar->use_group_tariff && $driver->сar->group_tariff_id ){
			$tariff = $driver->car->getTariff();
		}else{
			$tariff = $driver->getTariff();
		}
		
		$result = array(
			'town' => $tariff->getTown(),
			'town_center' => $tariff->getTownCenter(),
			'km_price' => $tariff->getKmPrice(),
			'company' => $driver->сar->getCarBrand();
			'model' => $driver->сar->model;
			'color' => $driver->сar->color;
			'object' = $driver->сar->number;
			'full_name' = $driver->getFullName();
			'serial_number' = $driver->serial_number;
		);
		
		//Так если это отдельная модель
		$this->setAttributes( $result );
		
		return $this;
		
		//Или
		return (object)$result;
		
	}
	
}


Это так, примерно. Можно намного лучше написать, но идею надеюсь донёс.
Ответ написан
Комментировать
@LAV45
namespace app;

use yii\base\Object;
use yii\db\ActiveRecord;

/**
 * @property integer $mifar_card_id
 * @property integer $car_id
 * @property integer $driver_id
 * @property Car $car
 * @property Driver $driver
 * @property TariffInterface $tariff
 */
class DriverCar extends ActiveRecord
{
    public function getCar()
    {
        return $this->hasOne(Car::class, ['id' => 'car_id']);
    }

    public function getDriver()
    {
        return $this->hasOne(Driver::class, ['id' => 'driver_id']);
    }

    public function getTariff()
    {
        return $this->car->tariff ?: $this->driver->tariff;
    }
}

interface chargeableInterface
{
    public function getTariff();
}

/**
 * @property integer $group_tariff_id
 * @property GroupTariff $tariff
 * @property string $model
 * @property string $color
 * @property string $number
 */
class Car extends ActiveRecord implements chargeableInterface
{
    public function getTariff()
    {
        return $this->hasOne(GroupTariff::class, ['id' => 'group_tariff_id']);
    }

    public function getCarBrand()
    {
    }
}

/**
 * @property DriverTariff $tariff
 * @property string $serial_number
 */
class Driver extends ActiveRecord implements chargeableInterface
{
    public function getTariff()
    {
        return $this->hasOne(DriverTariff::class, ['driver_id' => 'id']);
    }

    public function getFullName()
    {
    }
}

interface TariffInterface
{
    public function getTown();

    public function getTownCenter();

    public function getKmPrice();
}

/**
 * @property integer $driver_id
 */
class DriverTariff extends ActiveRecord implements TariffInterface
{
    public function getTown()
    {
    }

    public function getTownCenter()
    {
    }

    public function getKmPrice()
    {
    }
}

class GroupTariff extends ActiveRecord implements TariffInterface
{
    public function getTown()
    {
    }

    public function getTownCenter()
    {
    }

    public function getKmPrice()
    {
    }
}

class DriverCarInfo extends Object
{
    /**
     * @var DriverCar|null
     */
    private $_model;

    public function setModel(DriverCar $model)
    {
        $this->_model = $model;
    }

    public function getTown()
    {
        return $this->_model->tariff->getTown();
    }

    public function getTownCenter()
    {
        return $this->_model->tariff->getTownCenter();
    }

    public function getKmPrice()
    {
        return $this->_model->tariff->getKmPrice();
    }

    public function getCompany()
    {
        return $this->_model->car->getCarBrand();
    }

    public function getModel()
    {
        return $this->_model->car->model;
    }

    public function getColor()
    {
        return $this->_model->car->color;
    }

    public function getNumber()
    {
        return $this->_model->car->number;
    }

    public function getFullName()
    {
        return $this->_model->driver->getFullName();
    }

    public function getSerialNumber()
    {
        return $this->_model->driver->serial_number;
    }
}

function getFullInfo($id)
{
    $model = DriverCar::findOne(['mifar_card_id' => $id]);

    return $model === null ? null : new DriverCarInfo(['model' => $model]);
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы