SitePoint Sponsor

User Tag List

Page 1 of 2 12 LastLast
Results 1 to 25 of 34
  1. #1
    SitePoint Enthusiast
    Join Date
    Oct 2004
    Posts
    88
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Need evaluation of a new framework

    Hi,
    I'm working on a new php framework. Before wasting my time furthermore, i would ask if some of the php devs in this forum could take a look. Suggestions, critics are welcome.

    It is based on event handlers and has a plug and play module structure.

    Please go here for detailed informations:
    SMART PHP Framework

    Thanks in advance,
    atu

  2. #2
    SitePoint Enthusiast feti's Avatar
    Join Date
    Jun 2004
    Location
    Northeastern Ohio
    Posts
    42
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'd like to offer some criticism but I fear that it will be taken as if I'm completely bias because I run a framework project myself. But I'm going to bump this thread so others will see it, because it needs some attention. You're well on your way to creating a nice framework.
    feti
    Mojavi Project - Mojavi 3.0.0-dev available now!

  3. #3
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    What do you mean by "modules"?

  4. #4
    SitePoint Enthusiast
    Join Date
    Oct 2004
    Posts
    88
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    What do you mean by "modules"?
    The base framework has no high level functionalities. The main job of this framework is to manage modules (user, navigation, articles, ...).

  5. #5
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    i'm having a look at it, and i have quite a few remarks regarding coding style etc., but i'll spare you of that. but please try and drop those global statements ... stick with $GLOBAL

    one thing though. in some of your templates you have lines like this :
    PHP Code:
    <?php //### Index template. It is loaded by default if no template is defined. ### ?>
    see the trouble there ? the double-slash-comment hides the closing-tag for php.

  6. #6
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Still not entirely sure what modules are in your design.

    Anyway, it looks like everything is called by the templates, in effect making them controllers. That doesn't sound good.

    Where would you add centralised request logic? If templates are controlling everything, will you have to edit every single page template to add common tasks?

  7. #7
    SitePoint Enthusiast
    Join Date
    Oct 2004
    Posts
    88
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Where would you add centralised request logic? If templates are controlling everything, will you have to edit every single page template to add common tasks?
    Yes and No.

    Here an example of what you could find in a template:

    Template of an entry page of a public website:

    HTML Code:
    <html>
    <body>
    
    <!-- Get the template array $B->tpl_nav with the top level 
           navigation nodes  . -->
    
    <?php $B->M( MOD_NAVIGATION,
                 'GET',
                 array( 'var' => 'tpl_nav')); ?>
    
    <!-- echo the the top level navigation nodes 
           (usually in the left side of a layout)-->
    
    <?php foreach($B->tpl_nav as $node): ?>
      <a href="index.php?tpl=nav&id_node=<?php echo $B->tpl_nav['id_node']; ?>">
          <?php echo $B->tpl_nav['node_name']; ?>
      </a>
    <?php endforeach; ?>
    
    
    
    <!-- Get titles of the latest 10 articles -->
    <?php $B->M( MOD_ARTICLE,
                  'GET',
                  array('var'     => 'tpl_article',
                          'limit'   => 10,
                          'order'   => 'desc',
                          'fields'  => array('date','title'))); ?>
    
    <!-- echo the latest 10 article titles in the middle of 
           this template layout -->
    <?php foreach($B->tpl_article as $article): ?>
        DATE:   <?php echo $article['date']; ?><br>
        TITLE:  <?php echo $article['title']; ?><br><br>
    <?php endforeach; ?>
    
    
    <!-- Get titles of the latest 5 news -->
    <?php $B->M( MOD_NEWS,
                 'GET',
                 array('var'     => 'tpl_news',
                      'limit'     => 5,
                      'order'   => 'desc',
                      'fields'   => array('date','title'))); ?>
    
    <!-- echo the latest 5 news titles in the right side 
           of this template layout -->
    <?php foreach($B->tpl_news as $news): ?>
        DATE:   <?php echo $news['date']; ?><br>
        TITLE:  <?php echo $news['title']; ?><br><br>
    <?php endforeach; ?>
    
    </body>
    </html>


    As described at the framework homepage , each event function from inside a template is related to a corresponding module action class. The control of what a template designer can do with such event functions lies in the hands of the devs of the action classes and so finally of the design of a module or the design of the whole application modules.

    To come back to the example; you can place the control of how many articles are displayed in the admin section. Example.
    HTML Code:
    <!-- Get titles of the latest articles -->
    <?php $B->M( MOD_ARTICLE,
                  'GET',
                  array('var'     => 'tpl_article',
                          'limit'   => true,
                          'fields'  => array('date','title'))); ?>
    
    <!-- echo the latest article titles in the middle of 
           this template layout -->
    <?php foreach($B->tpl_article as $article) ?>
        DATE:   <?php echo $article['date']; ?><br>
        TITLE:  <?php echo $article['title']; ?><br><br>
    <?php endforeach; ?>
    Here the template designer have only the control to the limit the result but not how many.

    The framework is based on this idea of using callback functions to maintain plug and play code. But the final logic (What is controlled where?) is the choice the application module designer. I can imagine more than one concept.

    This framework is my answer to the question:
    What callbacks can do for application designs?

    See: http://www.phppatterns.com/index.php...eview/95/1/11/
    Last edited by atu; Oct 6, 2004 at 02:58.

  8. #8
    SitePoint Enthusiast
    Join Date
    Oct 2004
    Posts
    88
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    kyberfabrikken wrote:

    <?php //### Index template. It is loaded by default if no template is defined. ### ?>

    see the trouble there ? the double-slash-comment hides the closing-tag for php.
    Did you have php parsing problems?

  9. #9
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Did you have php parsing problems?
    odd ... when i messed around with your code, i swear i saw the effect of the above, but i can't reproduce it now ?

  10. #10
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    solved the mystery. seems you forgot a < in the file unavailable_index.tpl.ph

  11. #11
    SitePoint Enthusiast
    Join Date
    Oct 2004
    Posts
    88
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    kyberfabrikken wrote:

    solved the mystery. seems you forgot a < in the file unavailable_index.tpl.ph
    Thanks. The test package is now up to date.

  12. #12
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by atu
    Yes and No.
    It's important to have a means of adding actions common to all requests. Say you have a problem with spam bots: you might attempt to detect these with user-agent and IP checks. With some kind of Chain of Responsibility, you could easily pop a checker object in and out as required. It's a powerful pattern and the first thing I looked for in your framework.

    In general the design doesn't seem to say anything about non client output actions - client output could be just one of a range of things to do. You can, I suppose, add non-output modules in the templates but IMO it's not the job of templates to carry out a controller role. Quite apart from that, they would have to be hard-coded in each template.

    Incidentally I found $B->M() to be a real turn-off: what's a B? What's an M? OK I worked it out but people shouldn't be required to work it out; more explanatory names would be much better.

    Just trying to give an honest response. Maybe you can redress the balance by explaining what you see as the particular strengths or advantages of your framework?

  13. #13
    SitePoint Enthusiast
    Join Date
    Oct 2004
    Posts
    88
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by McGruff

    It's important to have a means of adding actions common to all requests. Say you have a problem with spam bots: you might attempt to detect these with user-agent and IP checks. With some kind of Chain of Responsibility, you could easily pop a checker object in and out as required. It's a powerful pattern and the first thing I looked for in your framework.

    You can, I suppose, add non-output modules in the templates but IMO it's not the job of templates to carry out a controller role. Quite apart from that, they would have to be hard-coded in each template.
    Each of the public and the admin front controller sends an init event to all modules and the system it self before loading any template. The action class which take the init part of a spam module (to come back to your spam bot example) could take the part of detecting spam bots.

    Originally Posted by McGruff

    Maybe you can redress the balance by explaining what you see as the particular strengths or advantages of your framework?
    To response as quickly as possible to a client demand. For a new template function you have only to write a new action class and save it in a module folder. Writing new modules is a bit more to work. It depends on the problem such a module have to solve. In sum a module contains an event handler and action classes.

    The question is; A client is asking you this and that. How fast can you response (or how many code lines you have to write to response) to his demand?

    This framework is may not the best solution for all possible circumstances. But IMO a simple solution, which is easy to understand.

  14. #14
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    OK my mistake. After looking at your diagram I thought the templates called everything - but you also have a FrontController which can do all the usual FrontController-ish things.

    Sorry to keep banging on about chains, but I think this could be very useful for your aim of creating a nice modular design. Here's some links for Chain of Responsibility and InterceptingFilter.

    http://www.javaworld.com/javaworld/j...npatterns.html
    http://www.javaworld.com/javaworld/j...816-chain.html
    http://java.sun.com/blueprints/corej...ingFilter.html
    http://msdn.microsoft.com/library/de...tingFilter.asp
    http://www.allapplabs.com/j2ee_desig...ing_filter.htm
    http://wact.sourceforge.net/index.ph...rceptingFilter

  15. #15
    SitePoint Enthusiast
    Join Date
    Oct 2004
    Posts
    88
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by McGruff

    After looking at your diagram I thought the templates called everything - but you also have a FrontController which can do all the usual FrontController-ish things.
    I will change the global diagram. It is not clear at all. Event calls can be done from almost every where of the system. Not only from inside the templates. In fact at the begining of writing this framework i planned to include an existing template solution. But i couldnt resist to use event calls even in templates. It simplify things (hopefully). But of course under the condition to not abuse this feature to write bad mixed code in templates.

    Many thanks for the links. I will check them.

  16. #16
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Since McGruff already mentioned some of the more formal things (well I guess i did myself), i'll like to point out that you use a code-standard different from what most php'ers does. Especially since you use PEAR, you should consider changing.

    The base framework has no high level functionalities.
    if this is the aim (and i agree that it should be), you may want to seperate the part of your framework, that handles events and the actual controllers. i'm not completely sure how/if this could be dopne, but it would be really convincing if you had a stand-alone eventhandling-mechanism, that could be coupled with a controller-oriented framework (like mojavi or phrame)

  17. #17
    SitePoint Enthusiast
    Join Date
    Oct 2004
    Posts
    88
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by kyberfabrikken

    if this is the aim (and i agree that it should be), you may want to seperate the part of your framework, that handles events and the actual controllers. i'm not completely sure how/if this could be dopne, but it would be really convincing if you had a stand-alone eventhandling-mechanism, that could be coupled with a controller-oriented framework (like mojavi or phrame)
    I'm not shure what you mean.

    What the public and the admin controllers does is; sending some base events to the modules. Example

    $B->M( SF_AUTH_MODULE, 'SYS_AUTHENTICATE' );
    Send a authentication event to the module event handler which takes the authentication part (usually the "user" module)

    $B->B( 'SYS_INIT' );
    Send a broadcast init event to all module handlers and the system handler. Here the corresponding module action classes can do some init proceedure (doing module upgrade, or what ever is necessary)

    Of course those event calls give only a sense if there are modules which receives those events (event handlers), and finally action classes, which react on them.

    To be frank, i have only really base knowledg of the mvc principle and not yet time to analyse other frameworks like mojavi or wact. Time is a preciouse value. But i think i should take this time soon.

  18. #18
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm not shure what you mean.
    i'd like to elaborate on it, but i'm not completely sure what i mean either.

    i think i meant something along the lines of : try and scrap everything you made so far, except for the basic eventhandling-mechanism, and then apply this to something like phrame. not that i'm a big fan of phrame, but it's a very naked implementation of the mvc. mojavi is a bit too matured for this, i think. and wact is even worse in this concern.

  19. #19
    SitePoint Enthusiast
    Join Date
    Oct 2004
    Posts
    88
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I would like to compare this framework (the name is "SMART") with the Model-View-Controller design pattern. As a novice i'm asking me; where is the difference?

    1. Model : the module event handlers and action classes
    2. View : the templates
    3. Controller : the front controller files index.php with included authentication and init event calls.


    I'm not shure about the role of the templates. Including event calls in templates is in a way a controller role !?! Those event calls are pulling the data from the model to the view.

  20. #20
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    it seems logical to me to consider events as controller-code. but you may have the concept interweaved with eachother.
    view ~ templates is quite true, but mvc-purists will insist that the view can _not_ take action on them selves. allowing the view to pull data from model-code may be acceptable though.

  21. #21
    SitePoint Enthusiast
    Join Date
    Oct 2004
    Posts
    88
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by kyberfabrikken:

    but mvc-purists will insist that the view can _not_ take action on them selves.
    Thats the point.
    But i think the advantage is flexibility with a minimal effort.

    Simple Example:

    An event call function, which assign a template var with a "Hello world" string.

    Here the template:

    HTML Code:
    <html>
    <body>
    
    <?php $B->M( MOD_TEST, 
                'PRINT', 
                 array( 'var'    => 'tpl_string' )); ?> 
    
    
    <?php echo $B->tpl_string; ?>
    
    </body>
    </html>

    Here the corresponding action class:
    You have to paste this class in the test module folder. (A similar example exist in the test package)

    PHP Code:
    <?php

    class TEST_PRINT
    {
        
    /**
         * Global system instance
         * @var object $B
         */
        
    var $B;
        
        
    /**
         * constructor
         *
         */
        
    function TEST_PRINT()
        {
           
    $this->= & $GLOBALS['B'];
        }
        
        
    /**
         * Assign a string to a template variable
         *
         * The $data array is the third argument of a template
         * event call function.
         *
         * Structure of the $data array:
         * $data['var'] - template var name to store string data
         *
         * @param array $data
         */  
        
    function perform$data )
        {
            
    // get var name defined in the public template
            // to store the result
            
    $_result = & $this->B->$data['var']; 
            
            
    // assign the string to the template variable
            
    $_result  'Hello World';     
        }
    }

    ?>


    Now, how would you do this in phrame, mojavi or wact ?

  22. #22
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    PHP Code:
    <?php $B->MMOD_TEST
                
    'PRINT'
                 array( 
    'var'    => 'tpl_string' )); ?>
    belongs in the controller, while the rest make up the view.
    i'm beginning to think that event-calling is something that should only be done from within controllercode (and possibly modelcode aswell ?)

  23. #23
    SitePoint Enthusiast
    Join Date
    Oct 2004
    Posts
    88
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by McGruff:

    After looking at your diagram I thought the templates called everything - but you also have a FrontController which can do all the usual FrontController-ish things.
    I will include in the next version prepend and append intercepting filter event calls in both front controllers.

    Here the short version of the public front controller:

    PHP Code:
    <?php

        
    // Include the base file
        
    include( SF_BASE_DIR "/admin/include/base.inc.php" );

        
    // Directed authentication event to the module handler, 
        // which take the authentication part
        
    $B->MSF_AUTH_MODULE'SYS_AUTHENTICATE' );

        
    // Broadcast init event to all registered event handlers
        
    $B->B'SYS_INIT' );

        
    // Broadcast intercepting filter event (auto_prepend)
        
    $B->B'SYS_PREPEND' );

        
    // Include the requested template
        
    include ( $B->template_file );

        
    // Broadcast intercepting filter event (auto_append)
        
    $B->B'SYS_APPEND' );

        
    // Send the output buffer to the client
        
    ob_end_flush();

    ?>
    As you can see there are broadcast event calls before and after rendering a requested template. Those events are looking for action classes in each module, which should doing filter jobs. E.g. detecting spam bots, parsing the template, starting caching, ...

    The problem is the order of executing those filters. May a priority scale from 1 to 10. Where at level 1 respectively 10 there can only be one filter action. But i dont know how to manage such a priority list.

  24. #24
    Non-Member
    Join Date
    Sep 2004
    Location
    Florida
    Posts
    19
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    But i dont know how to manage such a priority list.
    i think you could manage the order using the intercepting filter as you then register each filter as you want them?

  25. #25
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by atu
    The problem is the order of executing those filters. May a priority scale from 1 to 10. Where at level 1 respectively 10 there can only be one filter action. But i dont know how to manage such a priority list.
    Good candidates for a filter chain are items which do their own thing independently from anything else which is going on. In a perfect world the precise order in which they execute shouldn't matter (given only that some you might want to call before the client output and some after).

    It would be nice if the same filters were always called for all requests. If not, you'll need to configure filter chains dynamically per request. In either case, you can specify a particular execution order, if that's necessary.

    There's actually a serious problem with the InterceptingFilter pattern - at least in my opinion. As commonly described, request-handling entities are often added here - ie things which make decisions about the logical flow. I think that's a bad design flaw which can lead to request-handling roles cropping up in more than one location. A good filter might be a magic quotes filter: check if magic quotes is on, remove if yes. A bad (request-handling) filter might be user-input validation. Detecting a bad request would lead to a 400 response whereas, with the magic quotes filter, it operates "silently" without affecting any other processing decisions.

    Since you can have filters which don't actually filter anything in the dictionary sense of the word, a better name for the IF pattern might be "CoreWrapper". It's a location to place independent entities which wrap the application core and which do not interact with the core. Even if you don't initially think you'll need it, it's good to know how to slot it in later so that you can easily add "filters" common to all requests - or configurable filter chains per request.

    The request-handling items which are often listed as candidate filters for InterceptingFilter might possibly be given a separate chain of their own (something I'm experimenting with in my own framework explorations). This would be a strict GoF Chain of Responsibility ie only one handler actually executes (compared to a redefined InterceptingFilter/CoreWrapper where all filters are always active). Handlers are chained PageControllers where each PageController maps one to one with a particular client page. Each request maps to a single handler chain. A simple handler chain might be:

    BadRequest (400 page) --> FooPageController (the Foo page) --> NotFound (404 page)

    Handlers for authentication, authorisation, form redisplay, etc might be added for other requests.

    As with all designs, the aim is to separate concerns. You might identify four main responsibilities at the framework level: "silent" filters which wrap the core (and do not affect application logic), request handling (which does), client output, and finally non-client actions. The Chain of Responsibility - particularly configurable chains - provides a very simple way to add and remove items either in the CoreWrapper or in a request handling chain, without distrurbing anything else. Common items can be shared easily without having to copy paste code all over the place, and individual requests can be customised as required. The aim is to make future maintenance as simple as possible.

    How best to manage configuration is something I'm still working on. At present I'm experimenting with a configuration manager which assigns requests to various groups and compiles ini files per request (item lists need to cascade but lists don't have to be calculated for every request). Ask me again in a month if it's a good idea


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •