CodeIgniter Forums
How can I accomplish this? pls - Printable Version

+- CodeIgniter Forums (https://forum.codeigniter.com)
+-- Forum: Archived Discussions (https://forum.codeigniter.com/forum-20.html)
+--- Forum: Archived Development & Programming (https://forum.codeigniter.com/forum-23.html)
+--- Thread: How can I accomplish this? pls (/thread-5522.html)

Pages: 1 2


How can I accomplish this? pls - El Forum - 01-25-2008

[eluser]my_immortal[/eluser]
I had developed my site.
assume that i had default controller to 'main_page.php'
if someone calls to "www.mysite.com" the "main_page.php" will be called.
but if i want to someone call to his/her profile like "www.mysite.com/username1"
with the controller name "profile.php"
I try to remap URI rounting but i can't find any solution for this one

How can I accomplish this? Pls suggest Me.
Since I remove the "index.php" with .htaccess.

If any mistask with my english pls advice me. I don't good at english.


How can I accomplish this? pls - El Forum - 01-25-2008

[eluser]xwero[/eluser]
you can add the routing rule
Code:
$route[':any'] = 'profile/$1';

But it's best to add this rule as low as possible because it will catch any url that isn't caught by the rules before it. In your controller you should also add a check to see if the the username is known or not. If it's not you have to find out if it's a typo in the user name or a typo/urlhack in any other url.


How can I accomplish this? pls - El Forum - 01-25-2008

[eluser]my_immortal[/eluser]
xwero, Thanks for suggestion.

but if I had any other controller e.g."help.php, forum.php, contact.php ... etc".
Code:
$route['help'] = 'help';
$route['forum'] = 'forum';
.
.
$route[':any'] = 'profile/$1';
I affraid that if I had a lot of controllers I must add every controller to $route before the
profile controller.
Is there any solution that simpler than this?
best regards.


How can I accomplish this? pls - El Forum - 01-25-2008

[eluser]wiredesignz[/eluser]
forget routes

Grab the first URI segment in a base_controller that also does the profile methods for you, do a database lookup on usernames before any other page controller runs. If the username is found then the base_controller loads the profile model/views and exit()s. If the name isn't found then continue to run the requested page controller.

All page controllers would extend base_controller.


How can I accomplish this? pls - El Forum - 01-25-2008

[eluser]xwero[/eluser]
using regex you could get it in one line
Code:
$route['(help|forum)(.+)?'] = '$1$2';
You only need to add your controllers or first directory and the rest will be picked up by the second part of the regex.


How can I accomplish this? pls - El Forum - 01-25-2008

[eluser]my_immortal[/eluser]
Many thanks.
Now I have 3 solutions.
xwero.
Code:
$route['(help|forum)(.+)?'] = '$1$2';
$route[':any'] = 'profile/$1';
In .htaccess
Code:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(help|forum|contact) index.php?/$1 [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?/profile/$1 [L,QSA]
wiredesignz( but I change it a bit. cause i think lookup in database probably slow than array).
Code:
//in default controller.
function remap()
{
  $controller_name = $this->uri->segment(3); // Assume this is where the controller place.
  $reserve_file = array('help', 'forum', 'contact', .... 'user_setting')
  foreach($reserve_file as $file)
  {
    if(!file_exists($controller_name.'.php') && $controller_name != $file)
    {
       include 'profile.php';
    }else{
       include $file.'.php';  
    }
  }
}
Which is the best solution? About speed or perfomance.
Thanks for both guys.


How can I accomplish this? pls - El Forum - 01-25-2008

[eluser]wiredesignz[/eluser]
I re-wrote my suggestion a few times til I was happy... read it again you may get better idea.

I don't really like to use include() here.

Use the profile controller as base controller, if you find username in URI do profile things and exit()

if not continue to run normal page controller.

One database query to find username is not too slow.

No arrays, no need for special routes, no list of page names.


How can I accomplish this? pls - El Forum - 01-25-2008

[eluser]xwero[/eluser]
[quote author="my_immortal" date="1201284242"]
Which is the best solution?[/quote]
That is for you to find out Wink


How can I accomplish this? pls - El Forum - 01-25-2008

[eluser]Phil Sturgeon[/eluser]
Ok I had this one dirty way of doing something similar before. Basically if it got a 404 (meaning no controllers exist) it would then do a cheeky check in the db for it, all done through a controller.

Make a file libraries/MY_Exceptions.php

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

class MY_Exceptions extends CI_Exceptions
{
    function show_404($page = '')
    {
        global $CFG;
        
        // Removes the name of the script from the request uri, so we can grab segment1
        $uri_string = str_replace($_SERVER['SCRIPT_NAME'], '', $_SERVER['REQUEST_URI']);
        $segments = explode('/', $uri_string);
        
        // Send em to check the page only if it exists
        $check = (isset($semgents[1])) ? '/check/'.urlencode($segments[1]) : '';
        
        // Redirect to a CI controller where we have more API access
        header('Location: '.$CFG->item('base_url').'index.php/page_missing'.$check);

/*
        log_message('error', '404 Page Not Found --> '.$page);
        echo $this->show_error($heading, $message, 'error_404', $title);
        exit;
*/
    }

}    
?>

Then in the page_missing controller, I had one function that would run a check and see if the segment was in the database as a group title (for you it would be user name). Then if its not, it passes it to the default part of page_missing which is just a 404 error. With this code you can customise your 404's alot better than the normal ones too, so it has two benefits.

This is an example of my 404 controller.

Code:
<?php
class Page_missing extends Controller {

    function index()
    {
        $this->load->load('404');
    }


    // All 404's come through here, we check there is no user with the name
    function check($possible_match = '')
    {
        // Send straight to normal page missing
        if(empty($possible_match)):
            redirect('page_missing');
        endif;

        $this->load->model('user_model');

        // Its a user!
        if($user = $this->user_model->getByUsername($short_name)

        // Go to the normal page missing page
        else:
            redirect('page_missing');
        endif;
    }

}
?>



How can I accomplish this? pls - El Forum - 01-25-2008

[eluser]xwero[/eluser]
The only reason for using the extended libraries is that you can add and remove controllers without having to edit the routes configuration, is this right?