CodeIgniter Forums

Full Version: Invoking a subset within a CI application
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2

El Forum

[eluser]Kenneth Allen[/eluser]
I looked and did not see any entry on this specifically, but perhaps I did not use the appropriate keywords.

Consider the development of a site that manages a season of games for a sports organization. At the lowest level the site shows the standings and games for the teams within a specific program, and permits authorized people to enter game results and change the date/time/location for individual games.

The schedule for a specific program belongs to a season, which may have several programs. Examples of seasons might be "Spring 2009", Summer 2009", etc.

In an earlier incarnation (not done with CI) I simply used a separate database for each season, because we had no limits. With increased use the need to store multiple seasons within the same database is a requirement.

Furthermore this application resides under an existing web site, and is (currently invoked via a form button on the main site with values passed in via hidden fields.

I am considering a major rewrite of the application to address a number of issues, and I am considering using CI to do this. My concern is that if I want to use a single database, I need to be able to invoke the application but I need to be able to indicate which season is being requested. It is not appropriate to display a screen to permit the user to select a season.

As I understand it, the 'normal' way to do invoke the application for a specific season would be to use a URL like http://my_site/schedule/season/2009Spring, where "schedule" is folder that contains my application, "season" is a model within the application, and the last part is a value for the season. This also implies that someone have type http://my_site/schedule, which would invoke the default action on the application.

I want to be able to support more than one concurrently active season within the same application, possibly with two or more links from the main site that invoke the same application with different parameters.

Is there a way to configure the routes so that I can use a short URL, such as http://my_site/schedule/Spring2009, to invoke the display of the Spring 2009 season directly?

El Forum

[eluser]n0xie[/eluser]
URI routing

El Forum

[eluser]Kenneth Allen[/eluser]
Quite new to this framework approach. Can you provide some examples?

El Forum

[eluser]n0xie[/eluser]
You build a controller named 'schedule, which has a function 'season', which takes an argument like 'spring2009'.
Code:
// written from the top of my head so I might have a syntax error here and there
// system/application/controller/schedule.php
class Schedule extends Controller{

  function Schedule()
  {
    parent::Controller();
  }

  function index()
  {
    // this will be the default action so let's assume spring2009 for now
    // you can always change it to be either dynamic or maybe read from a config file.
    $this->season('spring2009');
  }

  function season($season)
  {
    // do magic here
  }
}

Now your page(s) will be reachable through http://mysite.tld/schedule/season/Spring2009. If you leave out the season it will load the index so http://mysite.tld/schedule will automagically load the default/current season which I set to spring2009 (in the 'index' method). Now we just have to 'chop off' the 'season' bit from our url, which we do in routes.php.

Code:
// system/application/config/routes.php
$route['schedule/(:any)'] = "schedule/season/$1";

Et voila.

El Forum

[eluser]Kenneth Allen[/eluser]
OK, but this still forces me to use a URL that mentions 'season'. What I wanted was an approach that would permit the URL that the user used to omit the season portion, not have a route definition remove it.

El Forum

[eluser]n0xie[/eluser]
[quote author="Kenneth Allen" date="1244959208"]OK, but this still forces me to use a URL that mentions 'season'. What I wanted was an approach that would permit the URL that the user used to omit the season portion, not have a route definition remove it.[/quote]
And what, may I ask, would be the difference?

El Forum

[eluser]Kenneth Allen[/eluser]
The difference would be a shorter URL without the RESTful notation. I like the RESTful approach, but in this case the format of the URL is a bit awkward.

Am I correct in believing that passing the URL http://my_site/schedule and passing a hidden field (season == 'Spring2009') in the POST would work, in that the index() method in the schedule controller could look for that and process it? The only difficulty is that I want to dispatch to the equivalent of http://my_site/schedule/season/Spring2009 but with the URL in the browser remaining as http://my_site/schedule. Is there a way to populate the POST without using a form to define a button?

Or am I just attempting to climb the wrong tree here?

For example, to see the schedule for a specific team in a specific division, the RESTful url would then be http://my_site/schedule/season/Spring2009/program/JuniorCanadian/team/4, which is valid RESTfully, but there are times when sending this information in hidden fields and not exposing it in the URL is desired.

As I say, perhaps I am just not comfortable enough the REST/routes/framework approaches to writing web sites

El Forum

[eluser]jedd[/eluser]
If the user is never permitted to select which season they want .. how do you determine which season they get?

Rather than using POST values, I'd probably go for some session data instead - assuming there's a programmatic way to identify the preferred season - and that you're happy to force cookies upon your users.

Though I do think there's a benefit for having something approaching REST (it's not really, but I get your point) URL's - such that users can sensibly bookmark things and be confident of getting back to the same page later, or being able to send URL's to other people and be confident that they'll see the same/right thing.

El Forum

[eluser]n0xie[/eluser]
Quote:Am I correct in believing that passing the URL http://my_site/schedule and passing a hidden field (season == ‘Spring2009’) in the POST would work, in that the index() method in the schedule controller could look for that and process it?
Hmm I think you are mixing up a few different principles. For one the URI, for the most part, can be seen as pointer to a resource in your application. So, with a little routing rules, you can basically use any URI you desire and map it to any part of your application.

Quote:The difference would be a shorter URL without the RESTful notation. I like the RESTful approach, but in this case the format of the URL is a bit awkward.
If you had read the link I posted as a first answer you would have realized that my example does exactly what you want: it processes the URI http://mysite.tld/schedule/Spring2009 AS IF you had typed http://mysite.tld/schedule/season/Spring2009. So there IS no difference.

Quote:Am I correct in believing that passing the URL http://my_site/schedule and passing a hidden field (season == ‘Spring2009’) in the POST would work, in that the index() method in the schedule controller could look for that and process it? The only difficulty is that I want to dispatch to the equivalent of http://my_site/schedule/season/Spring2009 but with the URL in the browser remaining as http://my_site/schedule. Is there a way to populate the POST without using a form to define a button?
Yes you could but why would you? The way my example is setup http://mysite.tld/schedule processes it AS IF you had typed http://mysite.tld/schedule/season/Spring2009. The only reason I could think of is if you want all the seasons to have the url http://mysite.tld/schedule and then have a $_POST variable which determines which season you want to display. This would make it more complicated than necessary. But sure if you want to you could.

Quote:For example, to see the schedule for a specific team in a specific division, the RESTful url would then be http://my_site/schedule/season/Spring2009/program/JuniorCanadian/team/4, which is valid RESTfully, but there are times when sending this information in hidden fields and not exposing it in the URL is desired.
For this kind of segmented handling of URI's I think you need to get a little bit better understanding of the CI framework. It can be done quite easily, using some route rules and some simple functions, but in order to get it working correctly, you'd have to get comfortable using the framework.
For example you could write this function for that URI:
Code:
function season ($season, $program, $league, $team, $teamnumber) { }
As you can see that would mean a lot of checks and a lot of parameters. It's doable this way but I guarantee that this will become a rather big and ugly function.

El Forum

[eluser]fijiaaron[/eluser]
If I understand correctly, you want to *optionally* have a default season and also invoke season by default, so that the following URLs all give the same result:

http://my_site/schedule/season/Spring2009
http://my_site/schedule/season
http://my_site/schedule/Spring2009
http://my_site/schedule/

but these URLs (which do other things) are also possible:

http://my_site/schedule/season/Fall2008
http://my_site/schedule/Fall2008
http://my_site/schedule/admin/season/Spring2009
http://my_site/schedule/admin/Spring2009
http://my_site/schedule/admin/someothermethod
http://my_site/schedule/admin

Something like this might work (just dashed it off)...

Code:
class Schedule extends Controller {

  var $default_season;

  var $_season_regex = '(Spring|Summer|Fall|Winter)(19|20)[0-9][0-9]';

  function Schedule()
  {
    parent::Controller();

    $this->default_season = get_season(time());  //returns season (e.g. Spring2009) from current timestamp
  }

  function index()
  {
    // look for method parameter that looks like a season
    if (preg_match($this->_season_regex, $this->uri->segment(2)))
    {
      $season = $this->uri->segment(2);
    }

    // set default season if no other parameters
    if ($this->uri->segment(2) === FALSE))
    {
      $season = $this->default_season;
    }

    // determine whether to pass control to 'season' method or not
    if (isset($season))
    {
      $this->season($season);
    }
    else
    {
      //do normal index things
    }
  }

  function season($season=null)
  {
    if(! isset($season))
    {
       $season = $this->default_season;
    }

    // do magic here
  }

  function admin()
  {
    // you're on your own implementing this
  }
}
Pages: 1 2