Codeigniter url routing selecting menu item adds segments to url - codeigniter

In a fresh installation of codeigniter 2.1.3 I have a controller 'home.php' with two functions:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Home extends CI_Controller {
public function index()
{
$this->load->view('home');
}
public function homefunction()
{
$this->load->view('homefunction');
}
}
I have a view 'home.php'. The anchors represent the menu:
<p>Home</p>
<br/>
Home
Home Function
and a view 'homefunction.php'
<p>Function in the Home controller</p>
<br/>
Home
Home Function
my routes:
$route['default_controller'] = "home";
I have 'eliminated' index.php from the URL with .htaccess and config.php
my .htaccess is:
RewriteEngine On
RewriteBase /test/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [PT,L]
in the config.php file I have set:
$config['base_url'] = 'http://localhost/test';
$config['index_page'] = '';
Now I run http://localhost/test and my home page loads with the menu. The url in the browser is localhost/test/. Then I click the 'Home' anchor menu item the url in the browser becomes localhost/test/home. I click the other menu item 'Home Function' the home function page loads and the url becomes localhost/test/home/homefunction. In the menu of the home function view I click the 'home' item and the url becomes localhost/test/home/home. I was expecting to become localhost/test/home. Then I click the menu item 'Home Function' the home function view is not loading and the url becomes localhost/test/home/home/homefunction, the homefunction page is not loading I click again home and I get in the url localhost/test/home/home/home and this goes on each time I click home function menu item and then home menu item a home section is added in the url.
I know it is something simple that maybe has to do with routing but I' stuck and I can't find a similar problem with google. Can anyone help?

Load url helper class. That would make you easy and dynamic.
$this->load->helper('url');
or load it as default, on config/autoload.php
$autoload['helper'] = array('url');
and every time you assign you url as :
Home
Home Function
You are encouraged to use this function any time you need to generate a local URL so that your pages become more portable in the event your URL changes.
URL helper: codeigniter

Go for
Home
Home Function
or
Home
Home Function

Related

Laravel index route issue when using for a subsection in another fw (external public dir)

I'm using a Laravel app with an external public directory, e.g. root/Laravel, and root/html/public.
I need this app to load from a require on a php file (root/html/this-section.php) that already has another framework loading it, hence that other fw has its own head, and body tag. This app will load between the header and footer of that file.
When I set up the routes, i notice that both of the following routes work, but i get different results.
Route::get('/', 'HomeController#index');
Route::get('/this-section', 'HomeController#index');
# this also works as a substitute for above, still same issue though
Route::get('//', 'HomeController#index');
These are the same pages, the controller has the same code, I would expect that the pages load the same. Whats happening is the main index site.com/ is loading correctly, but the latter is loading without the html <head> and <body> tags which exist on this-section.php. So essentially, the latter is not loading the parent page, its only loading what it sees on the blade templates.
I suspect maybe either need to add a rewrite to the .htaccess to cover this, or set up a custom redirect or return of a view or response in the controller (I need help here with suggestions) where I can then make a second method, e.g. thisSectionIndex() and return that suggestion.
At first I had things working with overriding the public_path() to the correct path this-section however that backfired when i made the sub routes
e.g. when using the following route setup
Route::get('/', 'HomeController#index');
Route::get('/feature', 'SectionController#feature');
It caused the feature route to be 500 or 404, I think it couldn't find the files, so I realized I needed to unfortunately add in the /this-section portion to the route ,which opened a can of worms pretty much.
Route::get('/', 'HomeController#index');
Route::get('/this-section', 'HomeController#index');
Route::get('/this-section/feature', 'SectionController#feature');
ON a side note, some fallout for this which I found a temporary work-around for already, was {{assets()}} broke. I had assets() overridden to not have to use the this-section/ portion, e.g. like this {{assets(/this-section/css/styles.css)}}. The temp worksround was to unfortunately have to manually add the paths and forego using {{assets()}} altogether in the blade templates until i figure that part out, because no path is working for them now.
Some background info:
Im overriding the public path like this
#Laravel\app\SectionApplication
class SectionApplication extends \Illuminate\Foundation\Application
{
public function publicPath()
{
$newBasePath = $this->basePath . DIRECTORY_SEPARATOR . '..' .
DIRECTORY_SEPARATOR . 'html/this-section';
return $newBasePath;
}
}
#Laravel/bootstrap/app.php
// $app = new Illuminate\Foundation\Application(
// realpath(__DIR__.'/../')
// );
$app = new App\SectionApplication(
realpath(__DIR__.'/../')
);
Here is the pertinent(adjusted) parts of the laravel bootstrapper index (html/this-section/index.php)
function public_path($path = '')
{
return realpath(__DIR__);
}
//adjust your relative laravel framework path here
$laravelRelPath = '../../Laravel';
//override the blade {{asset()}} helper
function asset($path, $secure = null)
{
$newPubPath = 'this-section/'; //relative from html where the index.php will be
return app('url')->asset($newPubPath . $path, $secure);
}
.htaccess is located outside of Laravel, and in html/
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
#Rewritebase /this-section/
#RewriteRule ^(.*)$ this-section/$1 [L]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</IfModule>
With the help of this topic
and this topic I found a working solution. Adjustments are needed When your loading in the application. You want to bootstrap it from the same path as the file loads the bootstrap, then override the .htaccess for that particular path only.
move laravels bootstrap file html/this-section/index.php file up one directory, next to the file html/this-section.php, and rename it to html/this-section-laravel-boostrap.php
adjust the path for laravel on html/this-section-laravel-boostrap.php by removing one directory ../
e.g. from $laravelRelPath = '../../Laravel'; to $laravelRelPath = '../Laravel';
add the following code to htlm/this-section.php (the file loads the bootstrap)
if (strpos($_SERVER['REQUEST_URI'],'this-section') !== false) {
require_once('this-section-laravel-bootstrap.php');
}
add the following to the .htaccess to snag the uri
#Rewritebase /
RewriteRule ^this-section/?$ / [L,NC]
The only route needed for this-section
Route::get('/this-section', 'HomeController#index')
In your blade templates, call your assets like this so they load on every sub sections url, e.g. for css
<link rel="stylesheet" href="/this-section/css/styles.css">
The application will now bootstrap, and always use the outer contents from the parent file that loads it. See below for an example parent test file(html/this-section.php) for this.
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Parent Application</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
</head>
<body>
<header>
<nav>
<ul>
<li>menu</li>
</ul>
</nav>
</header>
<?php
<--! laravel sandwich -->
if (strpos($_SERVER['REQUEST_URI'],'this-section') !== false) {
require_once('this-section-laravel-bootstrap.php');
}
?>
<footer>
<p>Copyright <?php echo date('Y'); ?> - All rights reserved.</p>
</footer> -->
</body>
</html>
Bonus
assets are now loading correctly, you probably dont need step 5.
{{asset('css/vendors.css')}}

.htaccess, how can I remove pattern from url?

I would like to clean my urls from this:
https://example.com/track&id=180
to:
https://example.com/track/180
My code is as follow:
My .htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^welcome/([^/]+)/?$ index.php?a=welcome&filter=$1 [NC,QSA,L]
RewriteRule ^track/([^/]+)/?$ index.php?a=track&filter=$1 [NC,QSA,L]
RewriteRule ^(([^/]+)+)(/([^/]{0,32})(/.+)?)?$ index.php?a=$1&q=$3 [L,QSA]
But if I use the 2nd example (the url without &id=) via Ajax it returns "undefined".
I tried the Ajax call with this link button
Click Here
I supposed it's undefined because in my requests I get the id parameter in PHP as $_GET['id'];.
So my question is: why it doesn't work on Ajax?
Here is my functions.js
$(function() {
$("body").on("click", "a[rel='loadpage']", function(e) {
// Get the link location that was clicked
startLoadingBar();
pageurl = $(this).attr('href');
// Replace the path of the url from index to the path with raw content
var custom = pageurl;
var custom = custom.replace(baseUrl+'/track', 'page.php?a=track');
var custom = custom.replace(baseUrl+'/', 'page.php?a=welcome');
// Request the page
$.ajax({url:custom,success: function(data) {
// Show the content
$('#content').html(data);
// Stop the loading bar
stopLoadingBar();
// Scroll the document at the top of the page
$(document).scrollTop(0);
// Reload functions
selectExplore();
reload();
}});
// Store the url to the last page accessed
if(pageurl != window.location){
window.history.pushState({path:pageurl}, '', pageurl);
}
return false;
});
});
.htaccess isn't my forte, so any help would be much appreciated.
Thanks in advance.
You can use this JS code to send your AJAX call:
var custom = pageurl.replace(baseUrl+'/track/', '/page.php?a=track&id=');
// Request the page
$.ajax({url:custom,success: function(data) {
// ...
}

Admin url is not working properly in codeigniter

I have created a small application in codeigniter. Frontend is running properly where as admin section is not opening.
I'm trying to open as yourdomain/admin/index.php/user/(But it showing 404 not found error).
So how to view the catalog section of admin?
Here is my file structure and file content for admin
D:\wamp\www\CodeIgniter\application\views\admin\catalog\catalog_view.php
<?php if (!defined('BASEPATH')) exit(__('No direct script access allowed')); ?>
<?php $this->load->view('admin/inc/header'); ?>
<h1><?php echo __('Catalog Manager'); ?></h1>
<p>Coming Soon...</p>
<?php $this->load->view('admin/inc/footer'); ?>
D:\wamp\www\CodeIgniter\application\controllers\admin\catalog\catalog.php
<?php
/**
* Admin User Controller
*/
class User extends MY_Controller
{
public function __construct()
{
parent::MY_Controller();
}
function index()
{
$data = '';
//---
$html_string = $this->load->view('admin/catalog/catalog_view', $data, true); //Get view data in place of sending to browser.
Library('process')->view($html_string);
}
}
Do you have a good htaccess setup?
Without htaccess you can access admin->index(); this with index.php/admin/index/
Your admin controller file isn't in the right order:
/application/controllers/admin/catalog/catalog.php
Without routing (http://ellislab.com/codeigniter/user-guide/general/routing.html) you cannot make this work, and you need to change your class name from user to catalog.
Ideally, you move the controller to /controllers/admin.php.
Then you can do index.php/admin and the index function will show. No routing needed what so ever.
you can't access it in that way yourdomain/admin/index.php/user/ you have to try first site.com/index.php/admin/...
but you have to be sure you created a controller named controller/admin.php which loads your views/admin/ pages
cause if you don't want to touch the CI core or extend it the rule is
:
http://www.site.com/index.php/controller/method/params
so in your case i would do:
class Admin exntends CI_Controller{
function index(){
//admin home page
//www.site.com/index.php/admin
}
function users(){
//admin users page
//www.site.com/index.php/admin/users
}
//... and so on
}
No Routes needed and if you want to remove index.php from your url just place this htaccess in your project root:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
Please use the route file few settings and easily set the admin URL.
$route['admin'] = 'admin/dashboard';

Unique Inconsistent CI Blank Page Issue

With reference to the CodeIgniter Blank Page question I asked previously.
Some new information has come to light that might shed some light on the problem.
My newly built server (CI 2.1.3 - latest release) where this was working correctly and not giving the WSOD is on a sub-domain of my development server. The WSOD issue is STILL occurring on the "live" site which is not in a sub-domain.
Obviously the "live" site is in public_html and the development version is in the "codeigniter" subdomain. Everything else is identical on both servers. Same PHP 5.3 setup. Same .htaccess file. Same CI 2.1.3 setup, obviously with config changed to point to the sub-domain in "development" and the domain in "live".
The issues are the same. On ENTER PRESS or external link ACTIVATION (such as from an email) I get WSOD in "live" but this works correctly in "development". Every controller that is activated without a button click in "live" gives me WSOD, while ALL the pages work correctly in "development".
As a check, I built a completely fresh CI root install (no sub-domain) and the problem mirrors exactly what is going on in "live".
The processes that are exhibiting the WSOD behaviour do not have views attached but simply print out a message on success.
Here is the code:
.htaccess - in the sub-domain folder of "development" and public_html of "live":
Options -Indexes
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} ^system.*
RewriteRule ^(.*)$ /index.php?/$1 [L]
RewriteCond %{REQUEST_URI} ^application.*
RewriteRule ^(.*)$ /index.php?/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?/$1 [L]
ErrorDocument 404 /index.php
One of the controllers giving the WSOD in "live" when pasting into browser after logging in, but is working in "development" is inviteusers.php simply takes a Company ID and User ID and sends the user a link with login details for the new account. Some extraneous code in the "message" body has been removed to shorten it:
<?php if ( ! defined('BASEPATH')) exit('No Direct Script Access Allowed');
/**
* Invite Users Controller
*
* ----------------------------------------------------------------------------
*/
class InviteUsers extends MY_Controller
{
function __construct()
{
parent::__construct();
$this->load->model('UserDetails_model');
$this->load->helper('date');
}
public function index()
{
if (!$this->session->userdata('clientid') && !$this->session->userdata('userid')) {
redirect('login');
}
// Add Client ID for All Uninvited Users for a Client
$lookupid['clientid'] = "CID";
// Add User ID to Add ONE Uninvited user for a Client
// Change UserDetails_model to take UID if this option is used
$lookupid['userid'] = "UID";
$invites = $this->UserDetails_model->getInvites($lookupid);
foreach ($invites as $invite) {
if ($invite['new'] == "Y") {
$message = "Hi ".$invite['username']." ".$invite['usersurname'].", \n \n";
$this->load->helper('email');
$this->email->set_newline("\r\n");
$this->email->from('email#address.com', 'System Messenger');
$this->email->to($invite['useremail']);
$this->email->bcc('admin#address.com');
$this->email->subject('Temporary Login Details');
$this->email->message($message);
$sent = $this->email->send();
if ($sent) {
echo "SUCCESS!!! ";
echo "NAME: ".$invite['username']." ".$invite['usersurname']." ";
echo "E-MAIL: ".$invite['useremail']." ";
echo "PASSWORD: ".$invite['temppass']." ";
echo "NEW: ".$invite['new']."";
}
} else {
$message = "Hi ".$invite['username']." ".$invite['usersurname'].", \n \n";
$this->load->helper('email');
$this->email->set_newline("\r\n");
$this->email->from('email#address.com', 'System Messenger');
$this->email->to($invite['useremail']);
$this->email->bcc('admin#address.com');
$this->email->subject('Temporary Login Details');
$this->email->message($message);
$sent = $this->email->send();
if ($sent) {
echo "SUCCESS!!! ";
echo "NAME: ".$invite['username']." ".$invite['usersurname']." ";
echo "E-MAIL: ".$invite['useremail']." ";
echo "PASSWORD: ".$invite['temppass']." ";
echo "NEW: ".$invite['new']." ";
}
}
}
}
}
/*
* End of file inviteusers.php
* Location: ./application/controllers/inviteusers.php
*/
As I said before - THIS PROCESS IS WORKING IN DEVELOPMENT but gives WSOD in LIVE.
MY_Controller simply performs the session lookups and checks some variables. It is simple and solid and has been working without mods since forever.
I think there may be a BIG CLUE in the fact that it works correctly in a recently set up sub-domain with the SAME .htaccess file and config changed to reflect the URL. All other environment variables are EXACTLY IDENTICAL. Same server, same hosting company, same Apache version running the same modules, same PHP version with the same modules, timeouts, memory etc. set.
The controllers giving the WSOD provide me with quick and easy access to certain admin functions so they must work... And they do... In a "development" sub-domain on an identical server to "live" which runs in public_html.
If a certain conditional scenario is met, you aren't outputting anything!
You are only echoing information if the $sent variable equates to true, AKA your email has sent successfully. If it doesn't, you aren't showing anything! Since there is no actual PHP errors, enabling those won't solve anything (although 99% of the time, that is the problem behind blank pages).
Throw an else statement on there with the email's debugger, and you should get some sort of indication about what's going on.
if ($sent) {
echo "SUCCESS!!! ";
echo "NAME: ".$invite['username']." ".$invite['usersurname']." ";
echo "E-MAIL: ".$invite['useremail']." ";
echo "PASSWORD: ".$invite['temppass']." ";
echo "NEW: ".$invite['new']."";
}
else
{
echo $this->email->print_debugger();
}
Also, for what it's worth, your .htaccess doesn't need rules for the system and application folders. You also don't need slashes on the front of your RewriteRule URLs (RewriteBase handles that for you).
Options -Indexes
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
ErrorDocument 404 index.php

Default Controller not loading after rerouting

I have a codeigniter multistie install where I have such code that I can serve sites with such links
site.com/sites/sitename/controller/function/vars
site.com/controller/function/vars/
subdom.site.com/controller/function/vars
the challange is that , whith the routing
$route['sites/([^/]+)/(.*)'] = '$2';
$route['default_controller'] = "content";
I get working the links like
site.com/sites/sitename/controller/function/vars
site.com/controller/function/vars
By idea when I go to
www.site.com/sites/sitename/
the default controller is not loading.
I made the config.php so that regarding the link structure, when I visit link
site.com/sites/sitename/controller/function/vars
then
$config['base_url']="http://site.com/sites/sitename";
if I go to
site.com/controller/function/vars
then
$config['base_url']="http://site.com/";
for the second case the default controller loads perfectly. For the subsite case not/
I get just 404
What to do?
UPDATE 2:
I have a multifolder setup.
When user goes to www.site.com/sites/site_name
then a folder of application
/root_folder/usersites/site_name is loaded.
When user goes just site.com/controller/function/var1/var2
a default application folder which is
/root_folder/application is loaded
when user goes to sub1.site.com application folder
/root_folder/domains/sub1_site_com is loaded
So when I enter in address bar
http://site.com/sites/site_name
it should be like no URI. and should load default controller.
// Application folder loading code
$myApp = '';
if($_SERVER['SERVER_ADDR']=='127.0.0.1'){
$main_url='site.com';
}
else{
$main_url='site1.com';
}
//echo $main_url;
switch($_SERVER['HTTP_HOST'])
{
case $main_url;
$uri_string=$_SERVER['REQUEST_URI'];
$link_way=explode('/',$uri_string);
if(strlen($uri_string)>6 and $link_way[1]=='sites' ){
//print_r($link_way);
//var_dump($link_way);
//checking if the link goes to usersites and sitename is bigger and =5
if($link_way[1]=='sites' and strlen($link_way[2])>=5){
$myApp='sites/usersites/'.$link_way[2];
define('SITE_ALIAS','1|'.$link_way[2]);
}
elseif($link_way[1]=='sites' and strlen($link_way[2])<5){
exit('Username should be more than 4 chars');
}
}
else{
define('SITE_ALIAS','0|'.str_replace('.','_',$_SERVER['HTTP_HOST']));
$myApp = 'application';
}
break;
default:
$myApp = str_replace('.','_',$_SERVER['HTTP_HOST']);
$myApp=str_replace('www_','',$myApp);
define('SITE_ALIAS','2|'.$myApp);
$myApp='sites/domains/'.$myApp;
}
$application_folder = $myApp;
What you appear to be doing is looking for a controller with the 'sitename' you are passing through. So if you navigate to site.com/sites/my-site/ you route tells it to look for a controller called my-site and run the index method.
The value of the route should be a path to an actual controller / method pair.
$route['sites/([^/]+)/(.*)'] = '$2';
should be
$route['sites/([^/]+)/(.*)'] = 'sites/index/$1/$2';
This is assuming it's the index method that accepts the sitename as it's first parameter in your sites controller.
It's not totally clear what you're asking, but heres a shot:
You need to create an .htaccess file in the root of your site (i.e. in the same folder that your system folder is in). In that file:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond $1 !^(index\.php)
RewriteRule ^(.*)$ index.php/$1 [L]
</IfModule>
See the "Remove the index.php file" section of this page: http://codeigniter.com/user_guide/general/urls.html for more info.
Also, the route that you're using would make it so that when you go to www.site.com, you will see www.site.com/sites/content.
With the url www.site.com/sites/sitename/content/, sites is your controller, sitename the method or function, and content would be considered a parameter to the sitename function -- this won't work like it seems like you want, but I can't be sure without seeing your controller.
Maybe edit your question and add your controller(s), and we can be of more assistance.
UPDATE:
1: $config['base_url'] has nothing to do with routing or which controller is being used, so this is making your question harder to understand.
2: It isn't clear what you are trying to accomplish (sorry).
By idea when I go to
www.site.com/sites/sitename/
the default controller is not loading.
According to the CI user guide:
CodeIgniter can be told to load a
default controller when a URI is not
present, as will be the case when only
your site root URL is requested. To
specify a default controller, open
your application/config/routes.php
file and set this variable:
So, what this means is that the default_controller is used only when there is no URI present. In other words: the default controller only applies when the URL is www.site.com, and in no other case will it be used (unless you are using sub-folders in the controllers folder -- see below).
If you trying to make it so that each of your sites has its' own controller, you could use subfolders in your controller folder.
In routes.php:
$route['sites/(:any)'] = "$1";
$route['default_controller'] = "content";
Then your folder structure:
So you have your controller folder. In it, create a folder for each site. In each of those controllers create your default controller (named content.php in the above image).
With this setup, www.site.com/sites/site1 will call the default controller (content) from application/controllers/site1/content.php and show the index function of that controller.
If you then want to call other functions of the site1 controller, the URL would look like:
www.site.com/sites/site1/content/otherFunction.
Hope this helps.
$uri_string=$_SERVER['REQUEST_URI'];
$way=explode('/',$uri_string);
/// print_r($way);
//echo $way[3];
if($way[1]=="sites" and strlen($way[2])>2 and strlen($way[3])<1){
echo "JAJA ";
$route['sites/:any'] = "content/show_page/home";
}
else{
$route['sites/([^/]+)/(.*)'] = '$2';
}
this was solution. thanks all who answered. thanks stormdrain. you pointed me to a write direction in your routing example. Thanks

Resources