我知道这将是一个奇怪的,所以我会尽量简短明了。
我正在为Grav制作一个插件。我已经确定,实现我的目标的最有效方法是扩展其中一个基类Pages。
结构看起来像这样:
实际上这看起来像什么。
$grav = Grav::instance(
array(
'loader' => $loader
)
);
protected static $diMap = [
.....
'pages' => 'Grav\Common\Page\Pages',
'pagesProcessor' => 'Grav\Common\Processors\PagesProcessor',
.....
];
protected $processors = [
.....
'pagesProcessor',
.....
];
public static function instance(array $values = [])
{
if (!self::$instance) {
self::$instance = static::load($values);
.....
return self::$instance;
}
protected static function load(array $values)
{
$container = new static($values);
.....
$container->registerServices($container);
return $container;
}
protected function registerServices()
{
foreach (self::$diMap as $serviceKey => $serviceClass) {
.....
$this->registerService($serviceKey, $serviceClass);
.....
}
}
protected function registerService($serviceKey, $serviceClass)
{
$this[$serviceKey] = function ($c) use ($serviceClass) {
return new $serviceClass($c);
};
}
try {
$grav->process();
}
public function process()
{
foreach ($this->processors as $processor) {
$processor = $this[$processor];
.....
$processor->process();
.....
}
.....
}
public function __construct(Grav $container)
{
$this->container = $container;
}
public function process()
{
.....
$this->container['pages']->init();
$this->container->fireEvent('onPagesInitialized', new Event(['pages' => $this->container['pages']]));
.....
}
public static function getSubscribedEvents()
{
return [
'onPagesInitialized' => ['onPagesInitialized', 0]
];
}
public function onPagesInitialized(Event $event) {
// Do things here...
}
哇......好的。
现在我想要做的是扩展Pages.php(上面没有列出),以便我可以修改一些没有setter nativly的受保护属性。问题是,没有办法告诉grav使用扩展方法,直到它被启动后。
我总是可以创建我的扩展类的新实例,初始化它,并覆盖现有的实例,但这意味着有效地强制执行两次,这意味着处理时间加倍,这是非常无效的。
我想做的是如下:
Pages.php < - 我不能改变这个:
class Pages
{
protected $grav;
protected $instances;
protected $children;
protected $routes = [];
public function __construct(Grav $c)
{
$this->grav = $c;
}
.....
public function init()
{
.....
$this->instances = [];
$this->children = [];
$this->routes = [];
$this->buildPages();
}
.....
PagesExtended.php < - 我的班级
class PagesExtended extends Pages
{
public function __construct(Pages $original)
{
// set the properties of this class to the original instance
parent = $original;
}
public function setInstances(Array $newInstances){
$this->instances = $newInstances;
}
.....
}
然后在我的Plugin.php中
public function onPagesInitialized(Event $event) {
// Do things here...
$this->grav['pages'] = new PagesExtended($event['pages']);
}
我能想到的另一件事就是某种__call技巧。
那么......想法?
编辑 - - - - - - - - - - - -
嗯......我仍然想知道是否可以做到这一点,但事实证明,“冻结”这些服务使他们无法被覆盖......现在不是很开心。
我不知道你真正想要实现什么,但是你的自定义方法必须返回一些东西,并且它们在Twig中使用。
我经常将Page的自定义数据放入页面标题中。在我的插件中,它获取自定义数据($oldHeader = $page->header()
),计算内容并将最终结果再次添加到Page对象作为自定义新属性($page->header($newHeader)
),然后在Twig中我可以访问并打印出我页面的这些新数据({{ page.header.data_generated_in_plugin }}
) )。
这样我可以做任何事情而不会覆盖Page class。
事实证明,无论我试图扩展什么类,我在grav环境中尝试做的事情都是不可能的。它永远不能从插件中完成,因为这些类被grav“冻结”了。