Толстая модель Тощий контроллер в CodeIgniter - PullRequest
6 голосов
/ 26 сентября 2011

Я уже давно пользуюсь CodeIgniter и неплохо разбираюсь в MVC, PHP и т. Д.

Однако мне трудно придерживаться идеала Skinny Controller для Fat Model.

Я много видел об этом;включая псевдокод, включаемый в каждый файл, но без реальных примеров.(Пожалуйста, дайте ссылку на некоторые статьи, если я пропустил очевидные!)

Мне трудно переместить логику формы в модель.Например, я использую собственную библиотеку для моей системы аутентификации, которая имеет свою собственную модель.Должен ли я сделать модель сайта пользователем для входа пользователей?Или я должен просто сделать модель сайта, чтобы сделать это?Или форма Модель?

Чтобы помочь мне, кто-нибудь может посоветовать мне, как сделать скин-контроллер этого контроллера?Я понимаю, что кода много, но простые указатели были бы хороши.(Пожалуйста, обратите внимание, я только что написал этот код, поэтому он не подвергался рефакторингу, но он должен дать хороший пример того, как некоторые из моих методов выходят из-под контроля.)

public function register()
{
    session_start();
    if ($this->tf_login->logged_in())
    {
        redirect('profile');
    }
    if ($_GET['oauth'] == 'true')
    {
        $type = $_GET['type'];
        try 
        {
            $token = $this->tf_login->oauth($type, '', 'email');
        }
        catch (TFLoginCSRFMismatchException $e)
        {
            $this->tf_assets->add_data('error_message', $e->getMessage());
        }
        catch (TFLoginOAuthErrorException $e)
        {
            $this->tf_assets->add_data('error_message', $e->getMessage());
        }
        if ($token)
        {
            $user_details = $this->tf_login->call('https://graph.facebook.com/me?fields=email,first_name,last_name,username&access_token=' . $token);
            $user_details_decoded = json_decode($user_details);
            if ($user_details_decoded->email)
            {
                try 
                {
                    $id = $this->tf_login->create_user($user_details_decoded->username,
                    md5($user_details_decoded->username . time()),
                    $user_details_decoded->email,
                    '',
                    TRUE,
                    TRUE);
                }
                catch (TFLoginUserExistsException $e)
                {
                    try
                    {
                        if ($this->tf_login->oauth_login($type, $user_details_decoded->email, $token))
                        {
                            $this->session->set_flashdata('success_message', 'You have successfully logged in.');
                            redirect('profile');
                        }
                        else
                        {
                            $this->session->set_flashdata('error_message', 'An account with these details exists, but currently isn\'t synced with ' . $type . '. Please log in to sync the account.');
                        }
                    }
                    catch (Exception $e)
                    {
                        $this->session->set_flashdata('error_message', $e->getMessage());
                    }
                }
                catch (TFLoginUserNotCreated $e)
                {
                    $this->tf_assets->add_data('error_message', 'You could not be registered, please try again.');
                }
                if ($id)
                {
                    $this->tf_login->add_user_meta($id, 'first_name', $user_details_decoded->first_name);
                    $this->tf_login->add_user_meta($id, 'surname', $user_details_decoded->last_name);
                    $this->tf_login->sync_accounts($id, $type, $token);
                    $this->session->set_flashdata('success_message', 'Welcome ' . $this->input->post('first_name', TRUE) . ' ' . $this->input->post('surname', TRUE) . '. Your account has been sucessfully created. You will shortly receive an email with a verification link in.');
                    redirect('login');
                }
            }
            else
            {
                $this->session->set_flash_data('error_message', 'You could not be logged in, please try again.');
            }
        }
        // Redirect to clear URL
        redirect(current_url());
    }

    if ($this->form_validation->run() !== FALSE)
    {
        try
        {
            $id = $this->tf_login->create_user($_POST['username'], $_POST['password'], $_POST['email'], '', FALSE);
        }
        catch (Exception $e)
        {
            $this->tf_assets->add_data('error_message', $e->getMessage());
        }
        if ($id)
        {
            $this->tf_login->add_user_meta($id, 'first_name', $_POST['first_name']);
            $this->tf_login->add_user_meta($id, 'surname', $_POST['surname']);
            if ($this->tf_login->register_verification_email())
            {
                $this->session->set_flashdata('success_message', 'Welcome ' . $this->input->post('first_name', TRUE) . ' ' . $this->input->post('surname', TRUE) . '. Your account has been sucessfully created. You will shortly receive an email with a verification link in.');
                redirect('login');
            }
            else
            {
                $this->tf_login->login_user($id);
                $this->session->set_flashdata('success_message','Your account has been sucessfully created.');
                redirect('profile');
            }
        }
        else
        {
            $this->tf_assets->add_data('error_message', $this->tf_login->get_errors());
        }
    }
    if (validation_errors())
    {
        $this->tf_assets->add_data('error_message', validation_errors());
    }
    $this->tf_assets->set_content('public/register');
    $this->tf_assets->add_data('page_title', "Register");
    $this->tf_assets->render_layout();
}

Заранее спасибо!

1 Ответ

3 голосов
/ 28 сентября 2011

Из того, что я могу сказать, большая часть или весь этот код принадлежит контроллеру или компоненту, поэтому я не думаю, что ваша проблема - это путаница между моделью и контроллером.

Однако код трудно читать из-за глубоко вложенных структур и неспособности разбить конкретные задачи на их собственные методы.Основной рефакторинг, от которого вы выиграете, - это создание новых частных методов для выделения отдельных подзадач, которые вы выполняете.Это имеет дополнительное важное преимущество, заключающееся в уточнении структуры высокого уровня вашего текущего метода.Таким образом, вы получите что-то похожее (просто чтобы дать вам грубый пример):

public function register()
{
    session_start();
    if ($this->tf_login->logged_in())
    {
        redirect('profile');
    }
    if ($_GET['oauth'] == 'true')
    {
        $this->oauthRegister();
    }

    $this->normalRegister();
}

Аналогично, метод oatuhRegister и normalRegister будут разбиты на более мелкие методы,так что, когда вы закончите, каждый метод будет придерживаться SRP и, вероятно, будет содержать менее 10 строк кода.Это значительно улучшит читабельность и удобство обслуживания вашего кода.Я также рекомендовал бы проверить Чистый код , который дает веские аргументы в пользу того, чтобы ваш метод был коротким.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...