Phalcon save () беззвучно завершает работу

Я перепробовал все, что мог придумать, но не могу получить метод model->save() для обновления некоторых столбцов в базе данных. Моя модель пользователей выглядит следующим образом (с помощью Phalcon Cashier):

<?php
namespace VokuroModels;

use PhalconMvcModel;
use PhalconValidation;
use PhalconCashierBillable;
use PhalconValidationValidatorUniqueness;

/**
 * VokuroModelsUsers
 * All the users registered in the application
 */
class Users extends Model
{

use Billable;

/**
 *
 * @var integer
 */
public $id;

/**
 *
 * @var string
 */
public $name;

/**
 *
 * @var string
 */
public $email;

/**
 *
 * @var string
 */
public $password;

/**
 *
 * @var string
 */
public $mustChangePassword;

/**
 *
 * @var string
 */
public $profilesId;

/**
 *
 * @var string
 */
public $banned;

/**
 *
 * @var string
 */
public $suspended;

/**
 *
 * @var string
 */
public $active;

/**
 *
 * @var string
 */
public $stripe_id;

/**
 *
 * @var string
 */
public $card_brand;

/**
 *
 * @var string
 */
public $card_last_four;

/**
 *
 * @var string
 */
public $trial_ends_at;

/**
 * Before create the user assign a password
 */
public function beforeValidationOnCreate()
{
    if (empty($this->password)) {

        // Generate a plain temporary password
        $tempPassword = preg_replace('/[^a-zA-Z0-9]/', '', base64_encode(openssl_random_pseudo_bytes(12)));

        // The user must change its password in first login
        $this->mustChangePassword = 'Y';

        // Use this password as default
        $this->password = $this->getDI()
            ->getSecurity()
            ->hash($tempPassword);
    } else {
        // The user must not change its password in first login
        $this->mustChangePassword = 'N';
    }

    // The account must be confirmed via e-mail
    // Only require this if emails are turned on in the config, otherwise account is automatically active
    if ($this->getDI()->get('config')->useMail) {
        $this->active = 'N';
    } else {
        $this->active = 'Y';
    }

    // The account is not suspended by default
    $this->suspended = 'N';

    // The account is not banned by default
    $this->banned = 'N';

}

/**
 * Send a confirmation e-mail to the user if the account is not active
 */
public function sendConfirmationEmail()
{
    // Only send the confirmation email if emails are turned on in the config
    if ($this->getDI()->get('config')->useMail) {

        if ($this->active == 'N') {

            $emailConfirmation = new EmailConfirmations();

            $emailConfirmation->usersId = $this->id;

            if ($emailConfirmation->save()) {
                $this->getDI()
                    ->getFlash()
                    ->notice('A confirmation mail has been sent to ' . $this->email);

            }
        }
    }
}

/**
 * Validate that emails are unique across users
 */
public function validation()
{
    $validator = new Validation();

    $validator->add('email', new Uniqueness([
        "message" => "The email is already registered"
    ]));

    return $this->validate($validator);
}

public function subscription()
{
  $users = Users::find();
  $user = $users->getLast();
  $result = $user->newSubscription('main', '2017 Online Individual')->create($this->getTestToken());
  return $result;
}

protected function getTestToken()
{
    return StripeToken::create([
        'card' => [
            'number' => '4242424242424242',
            'exp_month' => 5,
            'exp_year' => 2020,
            'cvc' => '123',
        ],
    ], ['api_key' => 'sk_test_98CUmA7w2JTAp25qVyMZweM9'])->id;
}


public function initialize()
{

    $this->belongsTo('profilesId', __NAMESPACE__ . 'Profiles', 'id', [
        'alias' => 'profile',
        'reusable' => true
    ]);

    $this->hasMany('id', __NAMESPACE__ . 'SuccessLogins', 'usersId', [
        'alias' => 'successLogins',
        'foreignKey' => [
            'message' => 'User cannot be deleted because he/she has activity in the system'
        ]
    ]);

    $this->hasMany('id', __NAMESPACE__ . 'PasswordChanges', 'usersId', [
        'alias' => 'passwordChanges',
        'foreignKey' => [
            'message' => 'User cannot be deleted because he/she has activity in the system'
        ]
    ]);

    $this->hasMany('id', __NAMESPACE__ . 'ResetPasswords', 'usersId', [
        'alias' => 'resetPasswords',
        'foreignKey' => [
            'message' => 'User cannot be deleted because he/she has activity in the system'
        ]
    ]);
}

}

После создания полосы пользователя / подписки и возврата идентификатора клиента (stripe_id), Last 4 (card_last_four) и т.д…, эта функция, я хочу сохранить все, что в базе данных в SessionController перед пересылкой в IndexController.

public function subscribeAction($user)
{

  $subscribe = $user->subscription();

  $user->save();

  return $this->dispatcher->forward([
        'controller' => 'index',
        'action' => 'index'
  ]);

Имя пользователя, пароль и т.д. Все сохранить нормально, но я не могу получить полосы конкретных столбцов для обновления. Они остаются пустыми, пока я не выполню команду терминала, чтобы изменить их. Я также смог успешно обновить их с помощью save if I wait until after a user is created, then login, and run something like:

$user = $this->auth->getUser();

$user->stripe_id = "123";

$user->save();

2 ответа

  1. Попробуйте что-то вроде этого:

    if ($user->save($_POST) === false) {
         $messages = $user->getMessages();
    
         $errorMsg = '';
         foreach ($messages as $message) {
             $errorMsg . "{$message} <br>";
         }
         $this->flashSession->error("Error: $errorMsg");
    }
    

    Тогда на ваш взгляд поставьте

    <?php $this->flashSession->output() ?>
    
  2. Трудно сказать, что именно происходит, но мне кажется, что вы находитесь в незафиксированной транзакции базы данных. Вы говорите, что поля сохраняются при создании счета, но не после вызова метода на оплачиваемом чертеже как части Cashier. Кроме того, метод save () возвращает true, что означает, что Phalcon думает, что запись сохранена. Я не вижу кода в Cashier, который явно запускает транзакцию, хотя я не заглядывал вглубь.

    Вот как вы можете проверить мою теорию. Используйте систему транзакций в Phalcon для перехода от неявного к явному

    use Phalcon\Mvc\Model\Transaction\Manager as TxManager;

    Затем в методе subscribeAction:

    public function subscribeAction($user)
    {
      $manager = new TxManager();
    
      // Request a transaction
      $transaction = $manager->get();
    
      $subscribe = $user->subscription();
    
      $user->save();
    
      $transaction->commit();
    
      return $this->dispatcher->forward([
            'controller' => 'index',
            'action' => 'index'
      ]);
    }
    

    Система транзакций разработана, чтобы помочь избежать конфликтующих условий записи или гонки, гарантируя, что все, что вы пишете во время транзакции, доступно на основе «все или ничего», а не до тех пор, пока вы явно не зафиксируете. Особенно при работе с коммерцией, это может помочь вам избежать того, чтобы одна таблица говорила, что покупка была совершена, в то время как другая не имеет никакой записи об оплате в течение той доли секунды, что она обрабатывается.

    Эта страница содержит более подробную информацию о том, как используются транзакции с Phalcon.