Phalcon save()无声地失败

时间:2016-12-28 21:59:29

标签: phalcon

我已经尝试了我能想到的一切,但是无法使用model-> save()方法来实际更新数据库中的某些列。我的用户模型看起来像这样(使用Phalcon Cashier):

<?php
namespace Vokuro\Models;

use Phalcon\Mvc\Model;
use Phalcon\Validation;
use Phalcon\Cashier\Billable;
use Phalcon\Validation\Validator\Uniqueness;

/**
 * Vokuro\Models\Users
 * 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 \Stripe\Token::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用户/订阅并返回Customer ID(stripe_id),Last 4(card_last_four)等...,这个函数,我希望在转发到IndexController之前将所有这些保存到SessionController中的数据库中。

public function subscribeAction($user)
{

  $subscribe = $user->subscription();

  $user->save();

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

用户名,密码等都保存得很好,但是我无法获得要更新的条带特定列。它们保持为null,除非我运行终端命令来更改它们。我已经能够使用save成功更新它们,如果我等到创建用户之后,然后登录,并运行类似:

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

$user->stripe_id = "123";

$user->save();

3 个答案:

答案 0 :(得分:0)

尝试这样的事情:

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() ?>

答案 1 :(得分:0)

很难说出究竟发生了什么,但它几乎让我觉得你在未提交的数据库事务中。您说在创建帐户时字段正在保存,但在您作为Cashier的一部分在Billable特征上调用方法之后则不会。 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'
  ]);
}

事务系统旨在通过确保您在事务期间编写的所有内容都可以全部或全无,并且直到您明确提交为止,来帮助避免冲突的写入或竞争条件。特别是在处理商务时,这可以帮助您避免让一张桌子表示已经进行了购买,而另一张桌子在该分割秒期间没有任何付款记录正在处理。

This page详细介绍了如何与Phalcon一起使用交易。

答案 2 :(得分:-1)

我也遇到过同样的问题。在对数据库进行一些调整之后,问题在于我们在同一张表上有两个自动编号字段。

通常,第一个是主键。如果我们将第二个自动编号字段删除或更改为正常,那么问题就消失了。