Cakephp 访问其他模型的实体类中的模型类

Cakephp 访问其他模型的实体类中的模型类,cakephp,cakephp-3.4,cakephp-model,Cakephp,Cakephp 3.4,Cakephp Model,我正在使用CakePHP3.4+ 我编写了一个具有多级成员资格的应用程序 Pro会员可以查看外部链接的短url,共享该链接时会记录该url的访问次数 原始url存储在所有用户的PostVideos表中 我已经创建了一个表来存储uniuqe键,用于short-url内部short\u-video\u-post\u-url和列 +----+---------------+------------+-------------+ | id | post_video_id | unique_key | v

我正在使用CakePHP3.4+

我编写了一个具有
多级成员资格的应用程序

Pro
会员可以查看外部链接的短url,共享该链接时会记录该url的访问次数

原始url存储在所有用户的
PostVideos
表中

我已经创建了一个表来存储
uniuqe键
,用于
short-url
内部
short\u-video\u-post\u-url
和列

+----+---------------+------------+-------------+
| id | post_video_id | unique_key | visit_count |
+----+---------------+------------+-------------+
因为,Pro成员的数量将低于普通用户,所以我不想在
short\u video\u post\u URL
中生成
unique\u key entry
,因为它会用无用的记录充斥数据库

所以,我想要的是动态生成它们,并仅为专业会员存储它们

现在,在
模板
文件中,我使用
$postVideo->video\u url
显示
post\u videos
表中的原始视频url

问题:

我想要的是调整
video\u url
实体调用,它将检查

  • 已登录用户的成员级别
  • 如果成员是赞成的
    • 检查所请求url的
      ShortVideoPostUrls
      模型中是否存在唯一键
    • 如果不存在记录,则在
      shortvideopostrls
    • 使用
      unique\u键返回新url
但为此,我需要访问实体类中的
登录用户数据

我尝试了什么?

class PostVideoLog extends Entity
{
    /*
     * ----
     * ----
    */

    protected function _getVideoUrl()
    {
        $user = $this->Users->get($this->Auth->user('id'), [
            'contain' => [
                'MembershipLevels'
            ]
        ]);

        if ($user) {
            if (strtolower($user->membership_level->title) === 'pro') {
                /**
                 * check if unique_key exists for this request
                 */
                $checkShortUrl = $this->ShortVideoPostUrls->find()
                    ->where(['post_video_log_id' => $this->_properties['id']])
                    ->first();

                if ($checkShortUrl) {
                    return $this->_generateUrl($checkShortUrl->unique_key);
                }

                /**
                 * create new record
                 */
                $unique_key_generator = new Hashids(UNIQUE_SHORT_URL_SALT, 4);
                $unique_key = $unique_key_generator->encode($this->_properties['id']);

                $newShortUrl = $this->ShortVideoPostUrls->newEntity();
                $newShortUrl = $this->ShortVideoPostUrls->patchEntity($newShortUrl, [
                    'unique_key' => $unique_key,
                    'post_video_log_id' => $this->_properties['id']
                ]);

                if ($this->ShortVideoPostUrls->save($newShortUrl)) {
                    return $this->_generateUrl($unique_key);
                }
            }
        }

        return $this->_properties['video_url'];
    }

    private function _generateUrl($unique_key)
    {
        $base_url = Router::url('/', true);

        return $base_url . '/u/' . $unique_key;
    }
}
我不确定我的方法是对还是错

要加载
用户
模型和我在上述函数中使用的其他模型,需要使用

$this->loadModel('Users');
但是,
loadModel
在这里似乎不起作用

还有什么方法可以做到这一点?或者如何在实体类中加载外部模型和验证组件?

class PostVideoLog extends Entity
{
    /*
     * ----
     * ----
    */

    protected function _getVideoUrl()
    {
        $user = $this->Users->get($this->Auth->user('id'), [
            'contain' => [
                'MembershipLevels'
            ]
        ]);

        if ($user) {
            if (strtolower($user->membership_level->title) === 'pro') {
                /**
                 * check if unique_key exists for this request
                 */
                $checkShortUrl = $this->ShortVideoPostUrls->find()
                    ->where(['post_video_log_id' => $this->_properties['id']])
                    ->first();

                if ($checkShortUrl) {
                    return $this->_generateUrl($checkShortUrl->unique_key);
                }

                /**
                 * create new record
                 */
                $unique_key_generator = new Hashids(UNIQUE_SHORT_URL_SALT, 4);
                $unique_key = $unique_key_generator->encode($this->_properties['id']);

                $newShortUrl = $this->ShortVideoPostUrls->newEntity();
                $newShortUrl = $this->ShortVideoPostUrls->patchEntity($newShortUrl, [
                    'unique_key' => $unique_key,
                    'post_video_log_id' => $this->_properties['id']
                ]);

                if ($this->ShortVideoPostUrls->save($newShortUrl)) {
                    return $this->_generateUrl($unique_key);
                }
            }
        }

        return $this->_properties['video_url'];
    }

    private function _generateUrl($unique_key)
    {
        $base_url = Router::url('/', true);

        return $base_url . '/u/' . $unique_key;
    }
}
编辑2

没有实体,有没有更好的替代方案来做我想做的事情?或者简单地从每个实体的
模板
调用函数?

class PostVideoLog extends Entity
{
    /*
     * ----
     * ----
    */

    protected function _getVideoUrl()
    {
        $user = $this->Users->get($this->Auth->user('id'), [
            'contain' => [
                'MembershipLevels'
            ]
        ]);

        if ($user) {
            if (strtolower($user->membership_level->title) === 'pro') {
                /**
                 * check if unique_key exists for this request
                 */
                $checkShortUrl = $this->ShortVideoPostUrls->find()
                    ->where(['post_video_log_id' => $this->_properties['id']])
                    ->first();

                if ($checkShortUrl) {
                    return $this->_generateUrl($checkShortUrl->unique_key);
                }

                /**
                 * create new record
                 */
                $unique_key_generator = new Hashids(UNIQUE_SHORT_URL_SALT, 4);
                $unique_key = $unique_key_generator->encode($this->_properties['id']);

                $newShortUrl = $this->ShortVideoPostUrls->newEntity();
                $newShortUrl = $this->ShortVideoPostUrls->patchEntity($newShortUrl, [
                    'unique_key' => $unique_key,
                    'post_video_log_id' => $this->_properties['id']
                ]);

                if ($this->ShortVideoPostUrls->save($newShortUrl)) {
                    return $this->_generateUrl($unique_key);
                }
            }
        }

        return $this->_properties['video_url'];
    }

    private function _generateUrl($unique_key)
    {
        $base_url = Router::url('/', true);

        return $base_url . '/u/' . $unique_key;
    }
}


要在实体中加载其他模型,可以使用
TableRegistry
class

use Cake\ORM\TableRegistry;

class MyModel extends Entity {

    protected function _getVideoUrl() {

        $table = TableRegistry::get('Users');
        $users = $table->find('all')->toArray();
    }
}

我认为在模型中使用
Auth
组件不是最好的主意-我不知道如何“正确”地执行此操作,但所有会话数据(包括Auth数据)仍然可以在
$\u session
array

中加载实体中的其他模型,您可以使用
TableRegistry

use Cake\ORM\TableRegistry;

class MyModel extends Entity {

    protected function _getVideoUrl() {

        $table = TableRegistry::get('Users');
        $users = $table->find('all')->toArray();
    }
}

我认为在模型中使用
Auth
组件不是最好的主意-我不知道如何“正确”地执行此操作,但是所有会话数据(包括Auth数据)仍然可以在
$\u session
array

中使用。您违反了MVC模式:实体中的业务逻辑。没有用几个字符“淹没”数据库,我也不认为需要单独的表。只要在创建时始终保存它们,并根据需要将它们公开到您的用户组中即可。另外,以适当的方式使用路由器生成您的/u/URL。这段代码不会通过我们的内部审查,我会告诉你完全重写它。你违反了MVC模式:实体中的业务逻辑。没有用几个字符“淹没”数据库,我也不认为需要单独的表。只要在创建时始终保存它们,并根据需要将它们公开到您的用户组中即可。另外,以适当的方式使用路由器生成您的/u/URL。这段代码不会通过我们的内部审查,我会告诉你完全重写它。没有正确的方法可以做到这一点,实体不应该超过数据容器,它们不应该包含业务逻辑!另外,请不要直接访问superglobals,当您觉得有必要这样做时,这表明您在以错误的方式进行操作-而是使用框架提供的API。没有正确的方法可以这样做,实体不应该超过数据容器,它们不应该包含业务逻辑!另外,请不要直接访问superglobals,当您觉得有必要这样做时,这表明您正在以错误的方式进行操作-而是使用框架提供的API。