Part of the EllisLab Network
   
1 of 2
1
Whence Library
Posted: 27 July 2008 12:16 AM   [ Ignore ]  
Grad Student
Avatar
Rank
Total Posts:  37
Joined  07-28-2007

Sometimes I want to be able to send users “back where you came from.”  I use this most often in my security library where the user tries to go to a page that requires authentication, they are sent to the login page, maybe they forgot their password so they get it mailed to them, then they successfully login.  I wanted to make the site take them back to the page they originally wanted to load.  Another time I use this feature is when the user if filling in a form.  If the form has validation errors, then the form is reloaded, if they press Cancel, then I want to take them back where they were before they started filling in the form (not the previous page which was the same form). Many of my forms can be reached in more than one way.

This is why I wrote the Whence Library.  It simply tracks where the user has been.  You could easily make breadcrumbs from the data.  The data is stored in a session variable array of configurable size (default = 10).  To add a breadcrumb to the current page, call
$this->whence->push()
or
$this->whence->push(arbitrary_query_string_to_pass_to_redirect)

Going back (similar to clicking the back button… but under server control) is simple too…
$this->whence->popwhence()
or
$this->whence->popwhence(number_of_breadcrumbs_to_pop)

You can also arbitrarily remove breadcrumbs using $this->whence->pop(number_of_breadcrumbs_to_pop) but that hardly ever comes up.

config/whence.php

<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');

$config['maxwhence']10;
$config['homepage']'home/index';
// don't forget to autoload sessions
?> 

libraries/whence.php

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

class 
Whence
{
    
protected $maxwhence=10;
    protected 
$homepage='';
    protected 
$_ci=null;
 
    function 
__construct($config)
    
{
        $this
->_ci =& get_instance();
        
// there will always be exactly maxwhence elements in the array
        
$this->maxwhence $config['maxwhence'];
        
$this->homepage $config['homepage'];
        if(!isset(
$this->_ci->session->userdata['whence']))
        
{
            $this
->clearwhence();
        
}
    }
    
    
function Whence($config)
    
{
        $this
->__construct($config);
    
}
    
    
function clearwhence()
    
{
        $defaultwhence 
strtolower($this->homepage);
        
$whencearray = array();
        for(
$i=0;$i<$this->maxwhence;$i++)
        
{
            $whencearray[]
=$defaultwhence;
        
}
        $this
->_ci->session->set_userdata(array("whence"=>$whencearray));
    
}
 
     
function isajax() 
    
{
        
return (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH']=="XMLHttpRequest");
    
}
    
    
function push($uri='')
    
{
        
if($uri=='')
        
{
            $uri 
=strtolower(substr(stristr($_SERVER['REQUEST_URI'],'index.php?/'),11));
            if(
$uri=='')
            
{
                $uri 
strtolower(substr(stristr($_SERVER['REQUEST_URI'],'index.php/'),10));
                if(
$uri=='')
                
{
                    $uri 
$this->homepage;
                
}
            }
        }
        
if($this->isajax() || $uri==$this->_ci->session->userdata['whence'][$this->maxwhence-1] )
        
{
            
// ajax requests and page reloads do not count
            
return;
        
}            
        
// shift
        
$whencearray $this->_ci->session->userdata['whence'];
        
array_shift($whencearray);
        
array_push($whencearray,$uri);
        
$this->_ci->session->set_userdata('whence',$whencearray);
    
}
    
    
function popwhence($n=1)
    
{
        
if(!isset($this->_ci->session->userdata['whence']))
        
{
            
// if the session timed out then start over
            
$this->clearwhence();
        
}
        $n
++;  // last element is where we are NOW,not where we came from
        
$whencearray $this->_ci->session->userdata['whence'];
        
$defaulturi $this->homepage;
        
$whence=$defaulturi;
        for(
$j=0;$j<$n;$j++)
        
{
            
// shift the array
            
$whence=array_pop($whencearray);
            
array_unshift($whencearray,$defaulturi);
        
}
        $this
->_ci->session->set_userdata('whence',$whencearray);
        
redirect($whence);
    
}
    
    
function pop($n=1)
    
{
        
if(!isset($this->_ci->session->userdata['whence']))
        
{
            
// if the session timed out then start over
            
$this->clearwhence();
        
}
        $n
++;  // last element is where are NOW,not where we came from
        
$whencearray $this->_ci->session->userdata['whence'];
        
$defaulturi $this->homepage;
        
$whence=$defaulturi;
        for(
$j=0;$j<$n;$j++)
        
{
            
// shift the array
            
$whence=array_pop($whencearray);
            
array_unshift($whencearray,$defaulturi);
        
}
        $this
->_ci->session->set_userdata('whence',$whencearray);
    
}
    
    
function dump()
    
{
        print_r
($this->_ci->session->userdata['whence']);
    
}
 } 
?> 
Profile
 
 
Posted: 27 July 2008 01:13 AM   [ Ignore ]   [ # 1 ]  
Sr. Research Associate
Avatar
RankRankRankRankRank
Total Posts:  2774
Joined  07-27-2006

I like it. Looks cool. Since this is a CI Library, consider updating your method names to include undersores, like pop_whence instead of popwhence. This would comply with EllisLabs General Style and Syntax Guidelines (http://expressionengine.com/docs/development/guidelines/general.html)

Beyond that nitpicking, looks like a nice solution

 Signature 

Check out the Template Library
Oh yeah, I tweet, too (regarding CodeIgniter on occassion).

Profile
 
 
Posted: 28 July 2008 03:05 PM   [ Ignore ]   [ # 2 ]  
Grad Student
Avatar
Rank
Total Posts:  70
Joined  10-26-2007

Hi,

I’m getting some stupid errors, and i guess it’s because I want to load this always, meaning, I want that breadcrumbs all over my website!

A PHP Error was encountered

Severity
Warning

Message
Missing argument 1 for Whence::__construct(), called in D:\HTDOCS\cdialsystem\system\libraries\Loader.php on line 873 and defined

Filename
libraries/Whence.php

Line Number

Is’t the error! Can you assist to put your library going?

Thank you in advance, and great job!

 Signature 

CodeIgniter Portugal { ci_pt }

http://www.coisasdaweb.pt

Profile
 
 
Posted: 28 July 2008 03:52 PM   [ Ignore ]   [ # 3 ]  
Sr. Research Associate
Avatar
RankRankRankRankRank
Total Posts:  2774
Joined  07-27-2006

Looks like you forgot to create and modify the config/whence.php file.

On the other hand, the Whence constructor should probably set a default value for its argument, and use show_error if the array is empty()

 Signature 

Check out the Template Library
Oh yeah, I tweet, too (regarding CodeIgniter on occassion).

Profile
 
 
Posted: 28 July 2008 04:12 PM   [ Ignore ]   [ # 4 ]  
Lab Technician
RankRankRankRank
Total Posts:  1040
Joined  06-19-2007

Since the class pulls in the super object…doesn’t it make more sense to restructure the config out of the class declaration anyway and just rely on the config class since the config is all there anyway?

Just a thought.

Randy

 Signature 

My new therapist is working with me every day, the third one gave up… ohh

Profile
 
 
Posted: 28 July 2008 04:20 PM   [ Ignore ]   [ # 5 ]  
Sr. Research Associate
Avatar
RankRankRankRankRank
Total Posts:  2774
Joined  07-27-2006

What he is doing is actually a feature of CI Libraries. When a library is loaded, it looks for {lib_class}.php in application/config and load it if it’s found. If the file has $config array, it is passed into the library constructor when the Loader class instantiates the library class.

He could do what you’re saying, but it’s essentially the same thing, just saves code by following the convention.

 Signature 

Check out the Template Library
Oh yeah, I tweet, too (regarding CodeIgniter on occassion).

Profile
 
 
Posted: 28 July 2008 07:32 PM   [ Ignore ]   [ # 6 ]  
Grad Student
Avatar
Rank
Total Posts:  70
Joined  10-26-2007

SOLVED: Stupid error!!

I autoloaded the config file, so it was loaded twice and was giving errors!!!

Thanks for your help! I’ll be counting with you for further questions, if you’re available!

hvalente13

 Signature 

CodeIgniter Portugal { ci_pt }

http://www.coisasdaweb.pt

Profile
 
 
Posted: 28 July 2008 07:40 PM   [ Ignore ]   [ # 7 ]  
Lab Technician
RankRankRankRank
Total Posts:  1040
Joined  06-19-2007

Of course.  Duh. Thanks Colin.

 Signature 

My new therapist is working with me every day, the third one gave up… ohh

Profile
 
 
Posted: 30 July 2008 08:23 AM   [ Ignore ]   [ # 8 ]  
Grad Student
Rank
Total Posts:  58
Joined  03-03-2008

This looks great ......now if i could just work out why i’m getting this

Message: Cannot modify header information - headers already sent by (output started at codeigniter/system/libraries/whence.php:114)

duh ! forget this - i had white space at the end of my file !

Profile
 
 
Posted: 06 February 2011 10:29 PM   [ Ignore ]   [ # 9 ]  
Summer Student
Avatar
Total Posts:  7
Joined  02-06-2011

I like this library very much. But I am not sure if I have applied it wrongly. When I use the “push” function, it will not “save” my current page, instead it will save the “homepage” that I have set in the config file. So everytime I must use: “$this->whence->push(current_url());”. Is it correct?

Profile
 
 
Posted: 06 February 2011 10:53 PM   [ Ignore ]   [ # 10 ]  
Research Assistant
Avatar
RankRankRank
Total Posts:  474
Joined  01-30-2011

This is just what I’ve been looking for. Thanks.

 Signature 

This is the wonderful logo InsiteFX did for me. I had to scale it for this site. But his work is worth showing off.

Profile
 
 
   
1 of 2
1