我知道这将是一个奇怪的,所以我会尽量简短明了。
我正在为Grav制作一个插件。我已经确定,实现我的目标的最有效方法是扩展其中一个基类Pages。
结构看起来像这样:
实际上看起来像这样。
的index.php
$grav = Grav::instance(
array(
'loader' => $loader
)
);
Grav.php
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);
};
}
的index.php
try {
$grav->process();
}
Grav.php
public function process()
{
foreach ($this->processors as $processor) {
$processor = $this[$processor];
.....
$processor->process();
.....
}
.....
}
PageProcessor.php
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']]));
.....
}
最后,Plugin.php
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技巧。
所以......想法?
修改 ------------------------
嗯......我仍然想知道是否可以做到这一点,但事实证明,“冻结”这些服务使他们无法被覆盖......现在不是很开心。
答案 0 :(得分:0)
我不知道您真正想要实现什么,但是您对Page的自定义方法必须返回某些东西,并且它们在Twig中使用。
我经常将Page的自定义数据放入页面的标题中。在我的插件中,它获取自定义数据($oldHeader = $page->header()
),计算内容并将最终结果再次作为自定义新属性($page->header($newHeader)
)添加到Page对象,然后在Twig中,我可以访问并打印出我页面的这些新数据({{ page.header.data_generated_in_plugin }}
)。
这样,我可以执行任何操作而无需覆盖Page类。
答案 1 :(得分:0)
事实证明,无论我尝试扩展什么类,在grav环境中我试图做的事情都是不可能的。永远不可能通过插件来完成,因为那些类被grav“冻结”了。