Помогите переписать код в ООП

Обсуждаем, как правильно строить приложения
Ответить
Аватара пользователя
Akulenok
Сообщения: 437
Зарегистрирован: 2014.05.05, 18:32
Откуда: localhost

Помогите переписать код в ООП

Сообщение Akulenok »

Добрый день. Написал скрипт выводящий сетку плейофф, но очень хочу разобраться в ООП и написать его в этом стиле и уверен что можно написать его более грамотно, помогите разобраться, хочу разучиться говнокодить
Есть обычная модель (из кода здесь временно убрал кое-что inheritdoc, аттрибутс и тд., чтоб меньше места занимало)

Код: Выделить всё

<?php
namespace app\modules\tour\models;
use Yii;

class TourPlayoff extends \yii\db\ActiveRecord
{
    public static function tableName()
    {
        return '{{%tour_playoff}}';
    }

	
    
    public function rules()
    {
        return [
            [['part', 'tour_id'], 'required'],
            [['id', 'part', 'position',  'tour_id', 'team_id'], 'integer'],
        ];
    }



	высчитываю высоту  для  разделителя между ячейками,  чем больше стадия тем  больше должен быть разделитель между ячейками
    public function getHeight($n, $r)
    {
        $position = $n + 1;
        if ($r < 2) $height = 70;
        if ($r == 2) $height = 90;
        if ($r == 3) $height = 135;
        if ($r == 4) $height = 210;
        if ($r > 4) $height = 250;
        return [
            'height' => $height,
            'position' => $position,
        ];
    }

	
    public function getTeam()
    {
        return $this->hasOne(\app\modules\team\models\Team::className(), ['id' => 'team_id']);
    }
}
Контроллер пока не доделан, там просто передаю модель во вьюху
$playoff = new TourPlayoff();
return $this->render('view', [ 'playoff' => $playoff,]);


и вот самая сложность, это вывод

пока пхп код во вьюхе, я понимаю что это надо все в модель перекинуть или в вспомогательный класс, вот с этим и хочу разобраться как это грамотно и правильно сделать

Код: Выделить всё

<?php
use yii\helpers\Html;
use app\modules\tour\models\TourPlayoff;

//  узнаю сколько  команд  всего,  пока они все на первой стадии
$countPart1 = TourPlayoff::find()->where(['tour_id' => $model->id, 'part' => 1])->count();
//   получаю кол-во стадий плейофф   например 1/4 ,  1/2 ,  final  это три стадии(round)
$round = 1;
for ($i = $countPart1; $i > 1; $i = $i / 2)
    $round++;

$col = $countPart1;


// получаю данные из базы
$new = TourPlayoff::find()->with([ 'team'])->asArray()->where(['tour_id' => $tour_id])->orderBy(['position' => ''])->all();

//  тут создаю нужный массив, который потом буду выводить в хтмл
for ($stage = 0; $stage < $round; $stage++) {
    for ($iteration = 0; $iteration < $col; $iteration++) {
        foreach ($new as $key => $var) {
            if ($iteration == $stage) {
                if ($var['part'] == $iteration + 1) {
                    $data[$iteration]['position'][] = $var['position'];
                    $data[$iteration][$var['position']]['name'] = $var['team']['name'];
                }
            }
        }
    }
}
?>

<!--  пошел вывод в хтмл сетки -->
<table>
    <tr>
        <?php for ($stage = 0; $stage < $round; $stage++): ?>
            <td>

                <?php for ($stageInside = 0; $stageInside <= $round; $stageInside++) : ?>

                    <table>
                        <?php if ($stage == $stageInside): ?>

                            <?php if ($stageInside != 0) {
                                $col = $col / 2;
                            } ?>

                            <?php for ($iteration = 0; $iteration < $col; $iteration++) : ?>

                                <?php
                                $array = $playoff->getHeight($iteration, $stageInside);
                                $height = $array['height'];
                                $position = $array['position'];
                                ?>


                                <tr>
                                    <td class="pf_line">
                                        <?php if ($iteration % 2 == 0 AND $stageInside < 1 AND $iteration != 0): ?>
                                            <div class="pf_separator"></div>
                                        <?php endif; ?>
                                        <?php if ($iteration % 2 == 0 AND $iteration != 0): ?>
                                            <div class="pf_separator"
                                                 style="height:<?= $stageInside * $height ?>pt;"></div>
                                        <?php endif; ?>

                                        <?php if (@in_array($position, $data[$stage]['position'])): ?>
                                            <div class="pf_team">
                                                <?= $data[$stage][$position]['name'] ?>

                                            </div>
                                        <?php else: ?>
                                            <div class="pf_team"></div>
                                        <?php endif; ?>


                                    </td>
                                </tr>

                            <?php endfor; ?>

                        <?php endif; ?>
                    </table>
                <?php endfor; ?>
            </td>
        <?php endfor; ?>
    </tr>
</table>



Вот сам массив с данными которые берутся из базы

Код: Выделить всё

[
    0 => [
        'id' => '1'
        'part' => '1'
        'position' => '1'
        'tour_id' => '4'
        'team_id' => '30'

        'team' => [
            'id' => '30'
            'name' => 'CSKA Moscow'
            'category_id' => '1'
            'country_id' => '1'
            'pic' => '58624614d2b52.png'
        ]
    ]
    1 => [
        'id' => '5'
        'part' => '2'
        'position' => '1'
    
        'tour_id' => '4'
        'team_id' => '30'
    
        'team' => [
            'id' => '30'
            'name' => 'CSKA Moscow'
            'category_id' => '1'
            'country_id' => '1'
            'pic' => '58624614d2b52.png'
        ]
    ]
    2 => [
        'id' => '7'
        'part' => '3'
        'position' => '1'
  
        'tour_id' => '4'
        'team_id' => '32'
    
        'team' => [
            'id' => '32'
            'name' => 'Spartak Moscow'
            'category_id' => '1'
            'country_id' => '1'
            'pic' => '58624617163e3.png'
        ]
    ]
    3 => [
        'id' => '2'
        'part' => '1'
        'position' => '2'
 
        'tour_id' => '4'
        'team_id' => '31'
    
        'team' => [
            'id' => '31'
            'name' => 'Lokomotiv Moscow'
            'category_id' => '1'
            'country_id' => '1'
            'pic' => '58624615ea012.png'
        ]
    ]
    4 => [
        'id' => '6'
        'part' => '2'
        'position' => '2'
     
        'tour_id' => '4'
        'team_id' => '32'
    
        'team' => [
            'id' => '32'
            'name' => 'Spartak Moscow'
            'category_id' => '1'
            'country_id' => '1'
            'pic' => '58624617163e3.png'
        ]
    ]
А вот массив, который получается после обратотки, из которого и выводится хтмл

Код: Выделить всё

[
    0 => [
        'position' => [
            0 => '1'
            1 => '2'
            2 => '3'
            3 => '4'
        ]
        1 => [
            'name' => 'CSKA Moscow'
        ]
        2 => [
            'name' => 'Lokomotiv Moscow'
        ]
        3 => [
            'name' => 'Spartak Moscow'
        ]
        4 => [
            'name' => 'Zenit St. Petersburg'
        ]
    ]
    1 => [
        'position' => [
            0 => '1'
            1 => '2'
        ]
        1 => [
            'name' => 'CSKA Moscow'
        ]
        2 => [
            'name' => 'Spartak Moscow'
        ]
    ]
    2 => [
        'position' => [
            0 => '1'
        ]
        1 => [
            'name' => 'Spartak Moscow'
        ]
    ]
]
и стили для вывода хтмл

Код: Выделить всё

.pf_team {
    width: 200px;
    height: 40px;
    border: 1px solid #c0c0c0;
    border-radius: 3px;
    -webkit-border-radius: 3px;
    -moz-border-radius: 3px;
    padding:6px;
    margin:5px;
}
.pf_separator { height: 20px; }
.pf_line { border-right:1px #F0DBB4 solid; border-top:1px #F1F1E3 solid; border-bottom:1px #F1F1E3 solid }
ភាសាខ្មែរ Yii2 - это кайф!
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Помогите переписать код в ООП

Сообщение ElisDN »

Это просто вывод массива в HTML. ООП здесь не нужно.
Аватара пользователя
Akulenok
Сообщения: 437
Зарегистрирован: 2014.05.05, 18:32
Откуда: localhost

Re: Помогите переписать код в ООП

Сообщение Akulenok »

Хм... я собирался сделать всякие методы типа $playoff->getRound(); ..getData(); т.е. расчеты производить в классе и возвращать результат,
но это все равно не ООП? как то на функции больше смахивает? Есть смысл так делать?

Я понимаю что разбиратся в этом коде никому не охота, но может кто-нибудь по чуть чуть подскажет как можно его оптимизирорвать? я для этого и привел сразу данные в виде массива, можно легко протестить
ភាសាខ្មែរ Yii2 - это кайф!
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Помогите переписать код в ООП

Сообщение ElisDN »

Akulenok писал(а): 2017.02.04, 14:12 Хм... я собирался сделать всякие методы типа $playoff->getRound(); .getData(); т.е. расчеты производить в классе и возвращать результат,
но это все равно не ООП? как то на функции больше смахивает? Есть смысл так делать?
Если они будут с полями объекта работать, то это как раз и будут методы объекта $playoff. А так уберите getHeight из TourPlayoff.
Аватара пользователя
Akulenok
Сообщения: 437
Зарегистрирован: 2014.05.05, 18:32
Откуда: localhost

Re: Помогите переписать код в ООП

Сообщение Akulenok »

Сразу какой-то косяк
Создаю экземпляр класса, и передаю в конструктор айди турнира
$playoff = new TourPlayoff($id);

в классе

Код: Выделить всё

class TourPlayoff extends \yii\db\ActiveRecord
{
    private $round = 1;
    private $tour_id;
    
    public function __construct($tour_id, $config = [])
    {
        $this->tour_id = $tour_id;
        parent::__construct($config);
    }
   .....
   public function getData()
    {
        return TourPlayoff::find()->with(['team', 'user', 'profile'])->asArray()->where(['tour_id' => $this->tour_id])->orderBy(['position' => ''])->all();
    }
в представление вызываю $playoff->getData();
и получаю Warning
Missing argument 1 for app\modules\tour\models\TourPlayoff::__construct(), called in /home/akula/domains/site.ru/vendor/yiisoft/yii2/db/ActiveQueryTrait.php on line 164 and defined
не могу понять где я пропустил этот аргумент, почему так? при вызове же передаю tour_id
ភាសាខ្មែរ Yii2 - это кайф!
Loveorigami
Сообщения: 977
Зарегистрирован: 2014.08.27, 21:54

Re: Помогите переписать код в ООП

Сообщение Loveorigami »

Потому что вы в своем конструкторе объявили обязательный параметр $tour_id.
Теперь во всех вызовах TourPlayoff::find() и выкидывается предупреждение об этом
Аватара пользователя
Akulenok
Сообщения: 437
Зарегистрирован: 2014.05.05, 18:32
Откуда: localhost

Re: Помогите переписать код в ООП

Сообщение Akulenok »

Вот допилил до такого состояния, скажите теперь это ООП? Многие вещи делал наобум, даже не совсем четко понимаю как они работают, но они работают :shock:
Вот контроллер
http://pastebin.com/VQAMZm33

Вьюха
http://pastebin.com/9DZCDjBT

И модель
http://pastebin.com/nXgA3CMx



Поправьте плиз если вообще бред, я все равно должен написать этот скрипт на ООП :roll:
ភាសាខ្មែរ Yii2 - это кайф!
Loveorigami
Сообщения: 977
Зарегистрирован: 2014.08.27, 21:54

Re: Помогите переписать код в ООП

Сообщение Loveorigami »

Для начала - возьмем этот метод
----------

Код: Выделить всё

    
class TourPlayoff extends \yii\db\ActiveRecord
{
private function getRound() {
        $countPart1 = TourPlayoff::find()->where(['tour_id' => $this->getTourId(), 'part' => 1])->count();
        $round = 1;
 
        for($i = $countPart1; $i > 1; $i = $i / 2) {
            $round++;
        }
        return [
            'round' => $round,
            'countPart1' => $countPart1,
        ];
    }

1. что сразу бросается в глаза? TourPlayoff::find() - вы же находитесь в этом же классе
2. Для чего в ActiveRecord метод find()? Не логично ли в нем выполнять все запросы и получать готовый результат...
3. обычно через get называют то, что служит гетером, значит должно быть public. Иначе нарветесь на магию Yii2 и получите незнамо что... Назовите там loadRound или еще как... Поскольку раунд зависит от тура - можно назвать loadRoundByTour...
-----
Сам же метод не понятен для чтения.
Читаю как - найти из плейофф число частей 1 для первого раунда.
Вроде искал раунд - а получаю массив раунда и каких то частей. Если так задумано, снабдите метод phpDoc - ом.
А лучше разбить на два метода...
Вы через время сможете прочитать, что тут происходит?
-----------
Под таким же ракурсом рассмотрите и метод public function getData()
Последний раз редактировалось Loveorigami 2017.02.04, 20:50, всего редактировалось 2 раза.
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Помогите переписать код в ООП

Сообщение ElisDN »

Akulenok писал(а): 2017.02.04, 20:02 ...скажите теперь это ООП? Многие вещи делал наобум, даже не совсем четко понимаю как они работают, но они работают
А давайте Вы сначала месяц-два почитаете и посмотрите что-нибудь про ООП, чтобы понимать, как всё работает, а потом уж к нам с вопросами придёте?
Аватара пользователя
Akulenok
Сообщения: 437
Зарегистрирован: 2014.05.05, 18:32
Откуда: localhost

Re: Помогите переписать код в ООП

Сообщение Akulenok »

1. что сразу бросается в глаза? TourPlayoff::find() - вы же находитесь в этом же классе
то есть вы про то что надо сделать так self::find() ?
2. Для чего в ActiveRecord метод find()? Не логично ли в нем выполнять все запросы и получать готовый результат...
вот тут не понял, можно пример о чем речь?
3. обычно через get называют то, что служит гетером,
это понял, спасибо.
А лучше разбить на два метода...
Я следовал из того, что если сделать два метода то будет 2 запроса в базу, а сейчас понял что можно один метод для запроса в БД а второй запустить уже с результатом из бд.
ភាសាខ្មែរ Yii2 - это кайф!
Loveorigami
Сообщения: 977
Зарегистрирован: 2014.08.27, 21:54

Re: Помогите переписать код в ООП

Сообщение Loveorigami »

вот тут не понял, можно пример о чем речь?
Вы используете этот метод, но у Вас в модели его нет. Поиграйте в детектива, найдите, где он есть, что он делает...
--------
Не найдете, тогда подсказка тут
https://github.com/trntv/yii2-starter-k ... mon/models

Но так ООП не учат...
Ответить