简体   繁体   English

从CakePHP 2.4中自己的类确定控制器和动作

[英]Ascertaining controller and action from my own class in CakePHP 2.4

I have created a class of my own which I'm using from methods which override those in a couple of Cake's caching-related classes in order to customise the filenames of the files that CacheHelper saves. 我创建了一个自己的类,该类使用的方法将覆盖Cake的几个与缓存相关的类中的方法,以自定义CacheHelper保存的文件的文件名。 (The filenames sometimes need to include the type of user so that logged in users don't see cached versions of what non-logged in users would see and vice-versa, for example.) (例如,文件名有时需要包括用户类型,以便已登录用户看不到未登录用户看到的缓存版本,反之亦然。)

My class is called MyCacheUtility and resides in app/Lib/Cache . 我的课程称为MyCacheUtility ,它位于app/Lib/Cache

In this class, I need to ascertain what the controller and action are. 在这一节课中,我需要确定控制器和动作是什么。 What is the best way of doing so, and can I use Cake's CakeRequest class? 最好的方法是什么,我可以使用Cake的CakeRequest类吗?

So far, I have included App::uses('CakeRequest', 'Network'); 到目前为止,我已经包含了App::uses('CakeRequest', 'Network'); , and... 和...

I can't use $this->params('controller') as my class isn't a controller or component: 我不能使用$this->params('controller')因为我的课程不是控制器或组件:

Error: Using $this when not in object context
File: /srv/www/app/Lib/Cache/MyCacheUtility.php
Line: 20

I can't use CakeRequest::param('controller') as (if I understand correctly) CakeRequest 's methods are not designed to be used statically: 我不能使用CakeRequest::param('controller')因为(如果我理解正确) CakeRequest的方法并非旨在静态使用:

Error: Using $this when not in object context
File: /srv/www/cakephp/lib/Cake/Network/CakeRequest.php
Line: 864

The contents of my class: 我班的内容:

App::uses('CakeRequest', 'Network');

class MyCacheUtility {

/**
 * Sets the cache file’s filename to include references to user type
 * and organisation (depending on the current controller and action)
 * so that both logged-in users from different organisations and visitors
 * get the right stuffs.
 */
    public static function getPrefix() {

        $prefix = '';

        switch ('controller') . '/' . 'action') { // this is where I need the controller and action

            case 'user_lists/organisation_lists':
                $prefix .= MyCacheUtility::sessionDataToFilename('currentUser.organisationName');
                break;

        }

        $prefix .= MyCacheUtility::sessionDataToFilename('currentUser.type');

        return $prefix;

    }

/**
 *
 */
    private static function sessionDataToFilename($sessionValue) {

        if (CakeSession::read($sessionValue)) {
            return strtolower(Inflector::slug(CakeSession::read($sessionValue))) . '-';
        }

    }

}

Update: 更新:

I found I wasn't able to pass the CakeRequest object from CacheDispatcher to MyCacheUtility class, and I think this is because CakeRequest has not been instantiated at the point at which CacheDispatcher does its stuff? 我发现我无法将CakeRequest对象从CacheDispatcherMyCacheUtility类,并且我认为这是因为在CacheDispatcher其工作时,尚未实例化CakeRequest吗?

I do now have what I set out to do working. 我现在确实有工作要做。 I'm passing Cake's $path variable through to my method and manually doing some processing based on this: 我将Cake的$path变量传递给我的方法,并基于此手动进行一些处理:

class MyCacheUtility {

    public static function getPrefix($path) {

        $pathParts = explode('/', parse_url($path, PHP_URL_PATH));

        $prefix = '';

        if (count($pathParts) > 1) {
            if ($pathParts[1] == 'shared_lists') {
                $prefix .= MyCacheUtility::sessionDataToFilename('currentUser.organisationName');
            }
        }

        $prefix .= MyCacheUtility::sessionDataToFilename('currentUser.type');

        return $prefix;

    }

    private static function sessionDataToFilename($sessionValue) {

        if (CakeSession::read($sessionValue)) {
            return strtolower(Inflector::slug(CakeSession::read($sessionValue))) . '-';
        }

    }

}

I was hoping to be able to directly apply Cake's own logic, but this seems to be doing the job okay so far. 我希望能够直接应用Cake自己的逻辑,但是到目前为止,这似乎做得还不错。

Why do you need a library class at all? 为什么根本需要一个图书馆课程? Extend the CacheHelper and use your customized cache helper via aliasing as $this->Cache in the views. 扩展CacheHelper并通过在视图中使用别名$this->Cache来使用自定义的缓存帮助器。 To modify the file names it should be enough to override CacheHelper::_writeFile() . 要修改文件名,它应该足以覆盖CacheHelper :: __ writeFile()

If you want to modify the caching itself write a new cache engine or extend an existing one to modify it's behavior. 如果要修改缓存本身,请编写一个新的缓存引擎或扩展现有的缓存引擎以修改其行为。 Your question does not really contain much information about why and what exactly you want to do so I can't give a better advice. 您的问题并未真正包含有关您为什么要做以及到底要做什么的很多信息,因此我无法提供更好的建议。

The CakeRequest object should be nearly everywhere present, so just pass it to the constructor of your cache lib. CakeRequest对象应该几乎存在于任何地方,因此只需将其传递给缓存库的构造函数即可。 But like I said, architecturewise I doubt your approach is the best path to go. 但是就像我说的那样,从架构上来说,我怀疑您的方法是最好的选择。 Show your cache lib code? 显示您的缓存库代码?

new MyCacheLib(CakeRequest $request);

Edit: 编辑:

Write your custom Cache dispatcher or extend the existing one instead. 编写您的自定义缓存调度程序,或者扩展现有的调度程序。 You'll get the request object passed to it by default. 默认情况下,您将获得传递给它的请求对象。 Take a look at the CacheDispatcher filter . 看一下CacheDispatcher过滤器 No need for a lib class here. 这里不需要lib类。

A more simple approach might be to write a custom cache engine and configure the helper to use that, same for the cache dispatcher filter. 一种更简单的方法可能是编写一个自定义缓存引擎并配置帮助程序以使用它,这与缓存调度程序过滤器相同。 This way you can share the code. 这样,您可以共享代码。 Or use a trait (php 5.4) to share the path building logic between the filter and the helper. 或使用特质(php 5.4)在过滤器和帮助器之间共享路径构建逻辑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM