Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

General Questions /

General questions about getting started with SilverStripe that don't fit in any of the categories above.

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

Session exists after Session::destroy("SessionName")


Go to End


11 Posts   3025 Views

Avatar
Bagzli

Community Member, 71 Posts

24 February 2015 at 4:03pm

Edited: 24/02/2015 4:08pm

Hello,

I've been trying to figure out how to combine a form submission and displaying results, and I've come up with the following way:

When you submit the form, it will set a session called SummonerSearch and give it a value of what the user has entered. I do some preliminary validation to prevent cross site scripting. Then the page is redirected back to itself. In the template I call a method that loops through results and prints them out.

My problem is that if I enter a user that exists and search for it, the form will return me the user. Then if I hit refresh page, the results portion will still print and no users will be shown. It is almost as if the session still exists but it is empty.

You can test this at vvv.azularis.com/adl-look-up

Any help is most appreciated!

oh and, I do not want to use URL parameters to search for summoners.

<?php
class ADLLookUp extends Page {
}
class ADLLookUp_Controller extends Page_Controller {
    private static $allowed_actions = array('ADLResultForm');

    public function ADLResultForm() {
        $fields = new FieldList (
            new TextField('Summoner')
        );
        $actions = new FieldList(
            new FormAction('setPlayer', 'Search')
        );
        $form = new Form($this, 'ADLResultForm', $fields, $actions, $requiredFields);
        $requiredFields = new RequiredFields(array('Summoner'));
        $form->Fields()->dataFieldByName('Summoner')->addExtraClass('Summoner');

        return $form;
    }

    function setPlayer($data, $form) {
        if($this->checkBadCharacters($data)){
            if(trim($data['Summoner']) == true){
                Session::set("SummonerSearch", $data['Summoner']);
            }
        }
        return $this->redirectBack();
    }

    function seekPlayer(){
        if($Name = Session::get("SummonerSearch")){
            $player = ADLPlayer::get()->filter('SummonerTag', $Name)->Limit(1);
            Session::destroy("SummonerSearch");
            return $player;
        }
        else{
            return NULL;
        }
    }

    function seekTopPlayers(){
        return ADLPlayer::get()->sort('Rating', 'DESC')->Limit(20);
    }

    public function checkBadCharacters($data){
        foreach($data as $inputValue){
            if(strpos($inputValue, '&') || strpos($inputValue, '<') || strpos($inputValue, '>') || strpos($inputValue, '/') || strpos($inputValue, '\'') || strpos($inputValue, '\"')){
                return FALSE;
            }
        }
        return TRUE;
    }
}

Template:

<% require themedCSS('ADLLookUp') %>
<div id="ADLLookUp">
    <div id="ADLLookUp-Form">$ADLResultForm</div>
    
    <% loop seekPlayer() %>
        <h2>Search Results:</h2>
        <table>
        <tr>
            <th>Summoner</th>
            <th>Rating</th>
            <th>MVP Count</th>
            <th>Games Won</th>
            <th>Games Lost</th>
            <th>Last Played</th>
        </tr>
        <tr>
            <td>$SummonerTag</td>
            <td>$Rating</td>
            <td>$MVPCount</td>
            <td>$GamesWon</td>
            <td>$GamesLost</td>
            <td>$LastPlayed</td>
        </tr>
    </table>
    <% end_loop %>

    <h2>Top Players:</h2>

    <table>
        <tr>
            <th>Summoner</th>
            <th>Rating</th>
            <th>MVP Count</th>
            <th>Games Won</th>
            <th>Games Lost</th>
            <th>Last Played</th>
        </tr>
        <% loop seekTopPlayers() %>
        <tr>
            <td>$SummonerTag</td>
            <td>$Rating</td>
            <td>$MVPCount</td>
            <td>$GamesWon</td>
            <td>$GamesLost</td>
            <td>$LastPlayed</td>
        </tr>
        <% end_loop %>
    </table>
</div>

Avatar
kinglozzer

Community Member, 187 Posts

25 February 2015 at 1:44am

I think you’re looking for Session::clear(), not Session::destroy()

Avatar
Bagzli

Community Member, 71 Posts

25 February 2015 at 4:16am

I tried Session::clear before destroy, and it had same results. Maybe the fault is within my logic? I just don't see it.

Avatar
therussdotcom

Community Member, 13 Posts

26 February 2015 at 6:22am

I was having a similar issue (Displaying results of a form post in a controller method, not the session issue) I don't at the moment see why you need to use a session. If you have the user's name/username at POST time, can you not just send that along and lose the session logic?

Regardless, setPlayer is where your session is kicked-off. If as it sounds, the session is there, but is value-less, then setPlayer() is being re-invoked on form submission, but without a value. You should normally see this as an error thrown by PHP/SilverStripe if Session::set() is being passed empty/null data. So unless you're running PHP with anything other than error_reporting as E_ALL, you should have seen that.

What happens if you poke a Session::destroy("SummonerSearch"); into the else condition as well? As I don't think this scenario is covered off.

Avatar
Bagzli

Community Member, 71 Posts

26 February 2015 at 1:13pm

I have been looking for the code to send the data back but I can't find any examples, if you can show how that would be done I would forever be grateful and I would lose this session method, I only came up with this because I could not figure out how to send the POST back.

To clarify further:

How do I set the controller to return the object player along with all of its fields
How do I loop through the fields of this player in the SS template once the values are returned?

Avatar
therussdotcom

Community Member, 13 Posts

26 February 2015 at 2:02pm

The "Sommoner" field will be POSTed along with the rest of the form's POST vars right? So I'm possibly missing something, but why can't you just use the value of the "Summoner" POST var from the $request variable?

$summoner = $this->request->postVar('Summoner');

If you refresh the page then, you'll always have it.

Another approach (The one I took) is to have a function called "IsSommoner()" or something. Then in your controller / pagetype's teplate use some conditioinal logic:

<% if $IsSommoner %>
<!-- show results -->
<% else %>
<!-- show original form -->

Avatar
Bagzli

Community Member, 71 Posts

26 February 2015 at 4:12pm

Hi,

I'm sorry but I don't follow.

When I enter a name and click search its going to post the form to my controller method (setPlayer($data, $form)). Now this method is going to parse the information and grab the the player object for that specific player. If I redirect the page back to itself that information is lost, how do I redirect it back to itself so that it keeps that player object?

I'm also avoiding to use URL parameters for this, I don't want users to be able to go into url change a few words and get another summoner's information.

You are saying to call

$summoner = $this->request->postVar('Summoner');

However I don't understand how this is going to be used, which controller method would have this?

Another question, if I have "isSummoner()" method and I call it from a template. That method retrieves my player object, how is that data being passed back to the template? I can't use $variable and this is not being looped. This returns a true or false and in the template I don't have any information about that player now.

By the way, I really appreciate the help!

Avatar
therussdotcom

Community Member, 13 Posts

27 February 2015 at 6:27am

So I just checked out your online example and I think it makes more sense now why you went down the Session route. But here's an alternative idea: As I suggested before, POST the Summoner but only their ID, then on page load/reload, perform a DataObject::get_one('Summoner', $this->getRequest()->postVar('SummonerID')). Even better, if all the results are taken from an SS_List subclass (e.g. DataList / ArrayList) you can just to $MyList->find('ID', $this->request->postVar('SummonerID') - no need for the extra DB lookup.

You asked where do I call $this->request->postVar() - well your code is being called from ADLLookUp_Controller and all Controllers are sub-classes of RequestHandler, which means on your controller you can do:

$this->getRequest()->postVar('SummonerID')

...sorry if I confused by using $this->request instead of $this->getRequest().

Go to Top