Jump to:

10928 Posts in 2612 Topics by 1809 members

All other Modules

SilverStripe Forums » All other Modules » Default Function

Discuss all other Modules here.

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba, simon_w

Page: 1
Go to End
Author Topic: 1648 Views
  • craigm
    Avatar
    Community Member
    9 Posts

    Default Function Link to this post

    Hi there,

    I've created a module called 'view' which renders a bunch of data into a template. The templates get rendered by calling the function 'viewTemplate' within the page_controller of view and it gets passed a template ID through the urlParams['ID'] variable.

    So to view a template, you'd go to the URL:

    www.mysite.com/view/viewTemplate/1

    Ive created a template called 'InvalidPage' which will get rendered if the user enters an ID that does not exist, which is easy because i just write that into the viewTemplate function.

    What i was wondering is if there was a way to handle incorrect function calls with a default function. So if the user tried to browse to:

    www.mysite.com/view/incorrectFunctionName/1

    Which is a valid page, but an incorrect function, can i get it to render the 'InvalidPage' template?

    should i do something like, create a __construct function for my view page_controller and loop through all the values returned by 'get_defined_functions()' and check them against the URL segment. Then if its not found, renderWith(array('InvalidPage)) ?

    Any other suggestions?

    Cheers.

  • craigm
    Avatar
    Community Member
    9 Posts

    Re: Default Function Link to this post

    ok, so instead of looping through all the defined functions, because there are a lot inherited, ive simply created my own array of allowed function names and written this:

    public function __construct(){
    parent::__construct();
    $functions = array('viewTemplate', 'testFunction');
    $this->validFunction($functions);
    }

    public function validFunction($functions){
    $counter = 0;
    foreach($functions as $function){
    if(Director::urlParam('Action') != $function){
    $counter++;
    }
    }

    if($counter == count($functions)){
    //echo 'invalidFunction';
    return $this->renderWith(array('InvalidPage'));
    }
    }

    if i uncomment out the echo, i do get it when it hits a function that is not valid, however its not rendering my template.

    I get the error: [Notice] Undefined index:

    I assume this is getting thrown by the parent::__construct call but it has to be there otherwise the code breaks.

    Any suggestions?

  • UncleCheese
    Avatar
    4085 Posts

    Re: Default Function Link to this post

    I'm having a really hard time wrapping my head around what you're trying to do. What is this module for, exactly?

    A couple things that might help you:

    1) As of 2.4, you cannot pass arbitrary actions through the URL. Any value for the URLParam "Action" has to be accounted for in your $allowed_actions array.

    2) Without an action to run, a controller falls back on the index() function

    3) You might look into the PHP wildcard method __call() to handle dynamically called functions.

  • craigm
    Avatar
    Community Member
    9 Posts

    Re: Default Function Link to this post

    Ok, so with that not working, ive tried to do it a different way. Instead of rendering the template, ive tried to do a Director::redirect like this:

    public function __construct(){
    parent::__construct();
    $functions = array('viewTemplate', 'invalidFunction');
    $this->checkFunction($functions);
    }//construct

    public function checkFunction($functions){
    $counter = 0;
    foreach($functions as $function){
    if(Director::urlParam('Action') != $function){
    $counter++;
    }
    }

    if($counter == count($functions)){
    Director::redirect('invalidFunction');
    }
    }//checkFunction

    public function invalidFunction(){
    $this->errorMessage = "Im sorry, function that you have tried to call seems to be invalid.";
    return $this->renderWith(array('InvalidPage'));
    }//invalidFunction

    Which as i understand it, should hit the Director::redirect call and then render the page using the 'invalidFunction' function within the current page_controller which will render the 'invalidPage' template.

    If i directly browse to: www.mysite.com/view/invalidFunction
    it does render the 'invalidPage' template properly.

    However, if i browse to: www.mysite.com/view/sdfsfsdfsdfsdfsdfsd which is not a valid function then it breaks and says:

    "Fatal error: Call to a member function getHeader() on a non-object in C:\wamp\www\mysite\sapphire\core\control\Controller.php on line 448"

    so im not sure what exactly is causing that, but for some reason it wont redirect. any ideas?

  • craigm
    Avatar
    Community Member
    9 Posts

    Re: Default Function Link to this post

    haha, crap, thats exactly what i was trying to do except i was basically trying to write that functionality myself because i didnt know it existed!

    Thanks for that!

    So when it hits a function that is not in the $allowed_actions array, is there a way to make it render an template i specify?

    Currently, when i enter an Action that isnt in the array, it simply echos out:

    "Action 'sdfsdfsd' isn't allowed on class View_Controller"

    onto a white screen.

  • Pigeon
    Avatar
    Community Member
    243 Posts

    Re: Default Function Link to this post

    I think you really want to be using the $url_handlers static in the controller.

    This allows you to define the default handling function for URLs.

    eg:

    class Page_Controller extends ContentController {

    static $url_handlers = array(
    '' => 'index',//this is the default handler for a URLSegment
    '$URLSegment/$Action/$ID' => 'myHandler' //this means if there is an action defined, then handle it with the function 'myHandler'
    );

    function index() {
    return $this;
    }

    function myHandler() {
    if ($this->urlParam['Action'] == 'view') {
    $this->renderWith(...);
    }
    ....
    }

    }

    Further reading: http://doc.silverstripe.org/controller#url_handling

    I use this to allow me to do: example.com/image-gallery/1 (and this will show the image in the gallery with ID == 1) rather than example.com/image-gallery/view/1

    1648 Views
Page: 1
Go to Top

Want to know more about the company that brought you SilverStripe? Then check out SilverStripe.com

Comments on this website? Please give feedback.