Vanilla 1 is no longer supported or maintained. If you need a copy, you can get it here.
HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.

tips: Empty Vanilla output -or- skip normal execution

edited October 2007 in Vanilla 1.0 Help
I'm trying to improve FeedPublisher. Actually it uses
exit;
to prevent the normal execution of Vanilla and only output the feeds.
I wrote EmptyVanillaOutput( $page ); to clear all normal output:
function EmptyVanillaOutput( $page ) { global $Context, $Head, $Menu, $Panel, $NoticeCollector, $Foot, $PageEnd; $ClassNames = array('Head', 'Menu', 'Panel', 'NoticeCollector', 'Filler', 'PageEnd'); switch ( $page ) { case 'comments.php': $SpecificClassNames = array('CommentGrid', 'DiscussionForm', 'CommentFoot'); case 'search.php': $SpecificClassNames = array('SearchForm'); } $ClassNames = array_merge( $SpecificClassNames, $ClassNames ); // include the code that define the base classes foreach( $ClassNames as $ClassName) { if (!class_exists($ClassName)) { $PrefixArray = $Context->Configuration['LIBRARY_NAMESPACE_ARRAY']; $PrefixArrayCount = count($PrefixArray); $i = 0; for ($i = 0; $i < $PrefixArrayCount; $i++) { $File = $Context->Configuration['LIBRARY_PATH'].$PrefixArray[$i].'/'.$PrefixArray[$i].'.Control.'.$ClassName.'.php'; if (file_exists($File)) { include($File); break; } } } } // page dependant new classes class EmptyCommentGrid extends CommentGrid { function Render() {} } class EmptyDiscussionForm extends DiscussionForm { function Render() {} } class EmptyCommentFoot extends CommentFoot { function Render() {} } class EmptySearchForm extends SearchForm { function Render() {} } // global controls new classes class EmptyHead extends Head { function Render() {} } class EmptyMenu extends Menu { function Render() {} } class EmptyPanel extends Panel { function Render() {} } class EmptyNoticeCollector extends NoticeCollector { function Render() {} } // class EmptyFoot extends Foot { // function Render() {} // } class EmptyFiller extends Filler { function Render() {} } class EmptyPageEnd extends PageEnd { function Render() {} } foreach( $ClassNames as $ClassName ) { $Context->ObjectFactory->SetReference( $ClassName, 'Empty'.$ClassName); } // redefine main controls $Head = $Context->ObjectFactory->CreateControl($Context, 'Head'); $Menu = $Context->ObjectFactory->CreateControl($Context, 'Menu'); $Panel = $Context->ObjectFactory->CreateControl($Context, 'Panel'); $NoticeCollector = $Context->ObjectFactory->CreateControl($Context, 'NoticeCollector'); $Foot = $Context->ObjectFactory->CreateControl($Context, 'Filler', 'foot.php'); $PageEnd = $Context->ObjectFactory->CreateControl($Context, 'PageEnd'); }
As I write this, I imagine I could even redefine the constructors to save some resources.

My questions:
1) What do you think ?
2) Is there a way to inject some code before the instantiation of the global control objects ($Head, $Panel, $Foot, $PageEnd) so I can change the reference to the classes with SetReference() and not be forced to redefine them ?

Comments

  • 1) You just need to clean-up the buffer output before your FeedPublisher and then use <var>$Context->Unload();</var> and <var>exit;</var>. That should be clean enough. 2) Unfortunately, no, you can't.
  • edited October 2007
    1) ...quite simple...
    but I know an extension that needs total Vanilla execution: SimpleCache (that needs feedback by the way)
    I'd like to simply skip the normal execution.

    2) Ok, it's not possible in Vanilla 1. I can manage without.
    But would it be possible to base the Context object on Delegation and add some CallDelegate() before constructing those global control objects ? We would need to read the default.php files of the extensions BEFORE constructing the global controls too. I mean would it be possible in Vanilla 2 ?

    EDIT: And about the constructors, it seems that I can't override them without breaking the framework.
  • FeedPublisher should cache its output itself.
  • So you think that using an extension to cache the output of another one is a bad idea ?
    I thought it was nice to centralize the code in a cache extension.
    The function I wrote on the top of this page seems to work well. I don't understand what the problem is...
  • It is nice if it is too hacky. Here you make sure that none of the core controller will render, but this way, you can't stop extension controllers to render. It would be far easier for FeedPublisher to cache its output by itself.
  • 1) "It is nice if it is too hacky" don't you mean "if it is NOT too hacky" ?

    2) "can't stop extension controllers to render" agreed, that's the kind of thought I needed. Bad news for me. I tried with your "clean the buffer" trick: just replaced
    class EmptyPageEnd extends PageEnd { function Render(){}}
    by
    class EmptyPageEnd extends PageEnd { function Render(){ ob_end_clean();header("Content-type: text/xml\n");echo( $this->Context->Feed ); } }
    and it seems to work well. So now I'm gonna try it with delegates only. It's a shame because we can't prevent (yet!) some processes to be executed if we don't need them.

    3) Maybe, but what if I want the output of another extension to be cached too. I'd like to understand why you don't like my SimpleCache idea.

    Thanks for the input.
  • I have missed it, yep it should work.
This discussion has been closed.