Routing all page with one controller with codeigniter - php

I'm a codeigniter newbie.
I'm triyng to create one controller that control every url in my site; I'm going to explain what i mean:
I've this views folder structure:
-front
--parts
header.php
footer.php
index.php
login.php
register.php
so if on my site example.com I want to go on login page, simply I'll go on example.com/login.
In controllers folder till now, I had a controller for every single page (HomeController.php, LoginController.php, RegisterController.php). Now I want to change strategy and have one controller to govern all my pages.
After some research on Google and Stack overflow, I've found this thread:
Strategy to route to pages in codeigniter
So I've decided to follow that hints and I've build Pages.php controller:
defined( 'BASEPATH' ) OR exit( 'No direct script access allowed' );
class Pages extends CI_Controller {
function _remap( $method )
{
is_file( APPPATH . 'views/front/' . $method . '.php' ) OR show_404();
$this->load->view( $method );
}
}
and in my routes.php:
$route['default_controller'] = 'welcome';
$route['pages'] = "pages/$1";
$route['(:any)'] = "pages/$1";
But I'm not be able to make it work.
In few words I whant create one controller that automatically create url if i create a new file in views/front folder.
I've readed CI docs and a bunch of question on StackOverflow, I've testing different hints, and maybe an answer somewhere, but I'm not finding yet.
I'm in trouble about this by days, maybe I'm missing something basilar in this concept.
Someone could help me to clearify this process?

You can do as below
$route['default_controller'] = 'welcome';
$route['pages']="pages/index";
$route['pages/login']="pages/login";
$route['pages/register']="pages/register";
Your Controller will be like this:
defined( 'BASEPATH' ) OR exit( 'No direct script access allowed' );
class Pages extends CI_Controller {
function _remap( $method )
{
is_file( APPPATH . 'views/front/' . $method . '.php' ) OR show_404();
$this->load->view( $method );
}
public function index() {
$this->load->view('front/index', $data);
}
public function login() {
}
public function register() {
}
}
Your index.php view should like this:
<!DOCTYPE html>
<html lang="en">
<head>
<title>XYZ</title>
<?php $this->load->view('front//header'); ?>
</head>
<body>
<!-- topbar starts -->
<?php $this->load->view('front/sections/top-nav.php'); ?>
<!-- topbar ends -->
<div class="ch-container">
<div class="row">
<!-- left menu starts -->
<?php $this->load->view('front/sections/leftmenu.php'); ?>
<!-- left menu ends -->
</div><!--/fluid-row-->
<!-- Ad ends -->
<?php $this->load->view('front/sections/footer.php'); ?>
</div><!--/.fluid-container-->
<!-- external javascript -->
<?php $this->load->view('front/sections/footerjs.php'); ?>
</body>
Or you can be load:
public function index() {
$this->load->view('front/header');
$this->load->view('front/index', $data);
$this->load->view('front/footer')
}

Related

Infinite redirection in AngularJS

I am implementing AngularJS for redirection in Codeigniter project but it's cause infinite redirection. My Directory and file structure is as under:
application
controllers
admin
home.php
view
admin
home
index.php
listing
index.php
theme
header.php
footer.php
index.php
system
AngularJS CODE:
Header.php
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script>
var sampleApp = angular.module('sampleApp', []);
sampleApp.config(['$routeProvider', '$locationProvider',
function($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$routeProvider.
when('/angular/ci/admin/home/', {
templateUrl: 'home'
}).
when('/angular/ci/admin/home/listing/', {
templateUrl: 'home/listing'
}).
otherwise({
redirectTo: '/angular/ci/admin/home/'
});
}
]);
</script>
<div>header</div>
<div>
Home
Listing
</div>
theme/index.php
<div ng-app="sampleApp">
<?php
$this->load->view(ADMIN_THEME."header.php");
?>
<div class='ng-view'>
<?php
$this->load->view('admin/'.$pagename);
?>
</div>
<?php
$this->load->view(ADMIN_THEME."footer.php");
?>
</div>
controllers/home.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Home extends CI_Controller {
public function index(){
$data['pagename']='home/index';
$this->load->view(ADMIN_THEME.'index',$data);
}
public function listing(){
//echo 'hi';
$this->load->view('admin/listing');
}
}
You need to redirectTo a path that is defined.
in other words, when you redirect to '/', it goes through the paths and looks for a match, and since one is not found, it redirects to '/', etc. You should redirect to /angular/ci/admin/home/ or /angular/ci/admin/home/listing/
good luck.

codeigniter load view specific javascript

I have a register view file on which there is a very big form. Hence I plan to use a form wizard plugin along with the jquery form validation plugin. I only want these scripts loaded on specific pages. How do I do this ? Here is my controller method.
public function index(){
$data['title'] = "Register";
$this->load->view("site_header", $data);
$this->load->view("site_nav");
$this->load->view("content_register");
$this->load->view("site_footer");
}
I saw a similar post on stackoverflow here but I don't understand what to do. Please help.
You can send which js to load as a variable. Example is here;
Sample controller
class mypage extends CI_Controller{
public function index(){
$data['js_to_load']="index.js";
$this->load->view('header',$data);
$this->load->view('my_html_page');
}
public function second_page(){
$data['js_to_load']='second.js';
$this->load->view('header',$data);
$this->load->view('my_second_html_page');
}
}
header.php - View file
<!-- Needed html code here -->
<? if ($js_to_load != '') : ?>
<script type="text/javascript" src="assets/js/<?=$js_to_load;?>">
<? endif;?>
<!-- Other html code here -->
Whats happening?
We are setting the js file into $data variable, and passing the $data variable to header.
In header file we are checking if js_to_load is set? If yes, we are including the js file.
Also you can pass multi js files by using arrays.
Sample controller
class mypage extends CI_Controller{
public function index(){
$data['js_to_load']=array("index.js","index1.js","index2.js");
$this->load->view('header',$data);
$this->load->view('my_html_page');
}
public function second_page(){
$data['js_to_load']=array("second.js","second2.js","second2.js");
$this->load->view('header',$data);
$this->load->view('my_second_html_page');
}
}
header.php - View file
<!-- Needed html code here -->
<? if (is_array($js_to_load)) : ?>
<? foreach ($js_to_load as $row):
<script type="text/javascript" src="assets/js/<?=$row;?>">
<?endforeach;?>
<? endif;?>
<!-- Other html code here -->
Pass an array of js you want added to the header in the data, and add in in the view, there are probably other ways of doing it (this kind smears the controller/view line, so it's a bit dirty, but it works).
public function index(){
$data['title'] = "Register";
$data['js'] = array('link', 'link', etc);
$this->load->view("site_header", $data);
$this->load->view("site_nav");
$this->load->view("content_register");
$this->load->view("site_footer");
}
It is better to load your .js in your footer as your HTML should fully load before your start running script over it.
see here for reasons
i use a universal footer to handle the .js files
public function index()
{
$this->load->view('template/header');
$this->load->view('template/nav');
$this->load->view('thing/landing');
$this->load->view('template/footer');
}
my footer view is
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
$caller_class = $this->router->class;
$caller_method = $this->router->fetch_method();
?>
<script type="text/javascript" src="<?php echo base_url(); ?>public/js/jquery.min.js"></script>
<?php
//look for JS for the class/controller
$class_js = "public/js/custom-".$caller_class.".js";
if(file_exists(getcwd()."/".$class_js)){
?><script type="text/javascript" src="<?php echo base_url().$class_js; ?>"></script>
<?php
}
//look for JS for the class/controller/method
$class_method_js = "public/js/custom-".$caller_class."-".$caller_method.".js";
if(file_exists(getcwd()."/".$class_method_js)){
?><script type="text/javascript" src="<?php echo base_url().$class_method_js; ?>"></script>
<?php
}
?>
</body>
</html>
using $this->router->class; or $this->router->fetch_method(); to detect what controller or method in the controller is being used. then detecting if a .js file exists for that controller/method
with little management you can have controller and/or method specific scripts without fiddling with the footer.
in file pub/js/custom-mycontrollername-mymethod.js you would then use (jquery);
$(document).ready(function() {
if ( $( "#mydivthing" ).length ) {
$('#mydivthing').html("fetching..");
$.ajax({
........
});
} else {
console.log("skipped js segment");
}
});
here the jquery only runs when the document is ready (as jquery recommends)
and you can also use if ( $( "#mydivthing" ).length ) { to check that your div is actually on the page. so you are not firing events when they are not loaded (for speed). but as jquery is likely doing some checking - this is probably only helpful for larger runs of code than just single button clicks events.
while the question was for views, this answers gets to a controller/methods level. so while a method can have multiple views - this still a view/screen as seen by the user.
added bonus that you can associate .js files to controller/methods just by its filename.
you can use a variable as a controller name and pass this variable to your view like this
Here is Controller
class Blog extends CI_Controller{
public function index(){
$data['controller']="blog_index";
$this->load->view('header',$data);
}
public function second_page(){
$data['controller']="blog_second_page";
$this->load->view('header',$data);
}
}
Header.php File
<? if (isset($controller) && in_array($controller,array('blog_index'))) : ?>
<script type="text/javascript" src="assets/js/custom_blog_index.js">
<? endif;?>
<? if (isset($controller) && in_array($controller,array('blog_second_page'))) : ?>
<script type="text/javascript" src="assets/js/custom_blog_second_page.js">
<? endif;?>
<!-- Other html code here -->
hope this will answer your question
I don't understand your problem. I suppose you load your js files in view site_header or view site_footer, why don't you load another view for these pages? for example:
public function index(){
$data['title'] = "Register";
$this->load->view("site_header_extra_js", $data);
$this->load->view("site_nav");
$this->load->view("content_register");
$this->load->view("site_footer_extra_js");
}
Another solution is to put an if in your view to load extra js files checking the path, you can use $this->uri->segment() for this.

How to build in 'maintenance mode' in Codeigniter?

I'm using latest codeigniter and I need to create a flag (ideally in the config) when turned to 'true', all pages display a 'maintenance mode' message instead of executing their controller code.
What is the best/simplest practice for doing this?
Here my solution, works fine for me:
The below will call maintanance.php immediately, so you can go ahead and break your CI code without the world seeing it.
Also allow you to add you own ip address so that you can still access the site for testing etc.
In index.php add at top:
$maintenance = false; ## set to true to enable
if ($maintenance)
{
if (isset( $_SERVER['REMOTE_ADDR']) and $_SERVER['REMOTE_ADDR'] == 'your_ip')
{
##do nothing
} else
{
error_reporting(E_ALL);
ini_set('display_errors', 1); ## to debug your maintenance view
require_once 'maintenance.php'; ## call view
return;
exit();
}
}
Add file Maintanance.php in same folder as index.php (or update path above):
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Maintenance</title>
<style>
body {
width:500px;
margin:0 auto;
text-align: center;
color:blue;
}
</style>
</head>
<body>
<img src="images/home_page_logo.png">
<h1><p>Sorry for the inconvenience while we are upgrading. </p>
<p>Please revisit shortly</p>
</h1>
<div></div>
<img src="images/under-maintenance.gif" >
</body>
</html>
<?php
header('HTTP/1.1 503 Service Temporarily Unavailable');
header('Status: 503 Service Temporarily Unavailable');
header('Retry-After: 3600');
?>
Extend the CI_Controller by putting a new file in your core directory called MY_Controller.
In this file's constructor, do something like this:
public function __construct()
{
parent::__construct();
if($this->config->item('maintenance_mode') == TRUE) {
$this->load->view('maintenance_view');
die();
}
}
Let all controllers in your app inherit from that class.
Here my solution, simply, clean and effectively for all urls calls and SEO respects:
Add this variables in:
application/config/config.php
$config['maintenance_mode'] = TRUE;
$config['maintenance_ips'] = array('0.0.0.0', '1.1.1.1', '2.2.2.2');
Add this conditional at the end of:
application/config/routes.php
if(!in_array($_SERVER['REMOTE_ADDR'], $this->config->item('maintenance_ips')) && $this->config->item('maintenance_mode')) {
$route['default_controller'] = "your_controller/maintenance";
$route['(:any)'] = "your_controller/maintenance";";
}
Create method maintenance in:
application/controllers/your_controller.php
function maintenance() {
$this->output->set_status_header('503');
$this->load->view('maintenance_view');
}
Create view:
application/views/maintenance_view.php
<!DOCTYPE html>
<html>
<head>
<title>Maintenance</title>
</head>
<body>
<p>We apologize but our site is currently undergoing maintenance at this time.</p>
<p>Please check back later.</p>
</body>
</html>
Here is what I've come up with for creating a maintenance mode.
Enable Hooks in the config.php file
Create an error_maintenance.php page under errors folder
Create a Hook called maintenance
In the hooks config setup your hooks call to run on post_controller
application/errors/error_maintenance.php
<!DOCTYPE html>
<html>
<head>
<title>Maintenance</title>
<style>Style your page</style>
</head>
<body>
<p>We apologize but our site is currently undergoing maintenance at this time.</p>
<p>Please check back later.</p>
</body>
</html>
application/hooks/maintenance.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class maintenance
{
var $CI;
public function maintenance()
{
$this->CI =& get_instance();
$this->CI->load->config("config_maintenance");
if(config_item("maintenance"))
{
$_error =& load_class('Exceptions', 'core');
echo $_error->show_error("", "", 'error_maintenance', 200);
exit;
}
}
}
application/config/hooks.php
$hook['post_controller'][] = array(
'class' => 'maintenance',
'function' => 'maintenance',
'filename' => 'maintenance.php',
'filepath' => 'hooks',
'params' => array()
);
how about this :
create auto-loaded libraries which always check maintenance flag on your database.
create a module for controlling your application maintenance flag.
create a module for redirecting when maintenance mode is on
auto-loaded libraries can contain something like this :
class Maintenance_mode {
function __construct(){
$CI =& get_instance();
$check_maintenance = $CI->db->select('flag_mode')->get('tbl_settings')->result();
if($check_maintenance[0]->flag_mode == '1')
redirect(site_url('maintenance_mode_controller'));
}
}
next step is to create a controller for maintenance page.
this one works well,
application/views/vw_maintenance.php
<!DOCTYPE html>
<html>
<head>
<title>Maintenance</title>
<style>Style your page</style>
</head>
<body>
<p>We apologize but our site is currently undergoing maintenance at this time.</p>
<p>Please check back later.</p>
</body>
</html>
<?php exit(); ?>
the exit() function is very importantn don forget to put it at the bottom, it will prevent all pages from being displayed.
application/libraries/maintenance.php
class Maintenance{
private $CI;
public function __construct() {
$this->CI =& get_instance();
// flag on and off
$this->flag( $this->CI->uri->segment(1) );
// get the flag status
$check_maintenance = $this->CI->db->select('flag_mode')->where(array('setting_name' => 'maintenance'))->get('tbl_settings')->result();
//display view if true
if($check_maintenance[0]->flag_mode == '1')
$this->CI->load->view('vw_maintenance');
}
private function flag($command){
$this->CI->db->where('setting_name', 'evolving');
switch($command){
case "activate":
$this->CI->db->update('tbl_settings', array('flag_mode' => 1) );
break;
case "deactivate":
$this->CI->db->update('tbl_settings', array('flag_mode' => 0) );
redirect(site_url('/'));
break;
}
}
}
autoload the library so it will be check every page load.
now you can activate and deactivate maintenance mode by typing or
I think this was easy, Just call view on the constructor like below.
comment (site will be live)
class home extends CI_Controller {
public function __construct() {
parent::__construct();
//echo $this->load->view('maintenance','',true);exit;
}
}
uncomment (site will be under maintenance)
class home extends CI_Controller {
public function __construct() {
parent::__construct();
echo $this->load->view('maintenance','',true);exit;
}
}
And you can use your own "maintenance.php" page under "view" in CI Application.

Always redirected on 404 page with URL Rewrite and Codeigniter

So I download a clean copy of Codeigniter and replace the welcome controller and welcome_message view with (respectively) :
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Welcome extends CI_Controller
{
public function index()
{
$this->load->view('welcome_message');
}
public function test($number = 3)
{
echo $number;
}
}
/* End of file welcome.php */
/* Location: ./application/controllers/welcome.php */
and
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div>
LOLMDR
</div>
</body>
</html>
and my .htaccess file is :
RewriteEngine on
RewriteRule ^pouet/(.*)-([0-9]+)\.html$ index.php/welcome/test/$2
I thought that when I clicked the link I would be redirected to my welcome/test function and then echoing 2. But instead I have a 404 page and I don't understand why.
Thanks
add this to you routes
$route['test/(:num)'] = 'welcome/test/$1';
then go to url:
http://www.yoursite.com/test/3457
let us know the outcome dude
welcome is your default controller, so :
http://www.yoursite.com , will always = http://www.yoursite.com/welcome

Custom error pages with templates in CodeIgniter

I'm using the template library for CodeIgniter, http://williamsconcepts.com/ci/codeigniter/libraries/template/reference.html, and now I want to implement custom error pages too. I found one method involving a MY_Router extending the default router: http://maestric.com/doc/php/codeigniter_404 but that only treats 404 errors. I want all errors to show a simple user-friendly page, including database errors etc, and I want it to go through a controller, partly so I can use the template library, and partly so I can also implement an email function to send myself information about the error that occurred.
Someone asked about extending the functionality of the above MY_Router method for other errors, like error_db, but got no answer from the author, so I'm turning here to see if anyone knows how to do this, along the lines of the above method or any other simple way of achieving it. Please note that I'm a newbie, so do not assume too much about my knowledge of basic CodeIgniter functionality :-)
I've created an extension for the Exceptions class.
In this extension I've replaced the $this->Exceptions->show_error(); method, witch is used by the show_error() function of CI.
when I call show_error('User is not logged in', 401); this custom method is looking for an error_$status_code file first. In the case of the example above, it will look for an error_401.php file.
When this file does not exists, it wil just load the error_general.php file, like the default $this->Exceptions->show_error(); does.
In your case, you can use the following code to use in your library, controller or whatever should throw an error.
<?php
if(!(isset($UserIsLoggedin))){
$this->load->view('template/header');
show_error('User is not logged in', 401);
$this->load->view('template/footer');
}
?>
Your error_401.php file should than look like this:
<div id="container">
<h1><?php echo 'This is an 401 error'; ?></h1>
<?php echo $message; ?>
</div>
/application/core/MY_Exceptions.php:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class MY_Exceptions extends CI_Exceptions
{
function show_error($heading, $message, $template = 'error_general', $status_code = 500)
{
if((!isset($template)) || ($template == 'error_general')){
if(file_exists(APPPATH.'errors/error_'.$status_code.'.php')) {
$template = 'error_'.$status_code;
}
}
if (!isset($status_code)) $status_code = 500;
set_status_header($status_code);
$message = '<p>'.implode('</p><p>', ( ! is_array($message)) ? array($message) : $message).'</p>';
if (ob_get_level() > $this->ob_level + 1)
{
ob_end_flush();
}
ob_start();
include(APPPATH.'errors/'.$template.'.php');
$buffer = ob_get_contents();
ob_end_clean();
return $buffer;
}
}
?>
I do it like this:
I create my own error page, and whenever I should throw a 404 error, I actually load my 404 page.
So say my default controller is site.php, my site.php looks like this:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Site extends CI_Controller {
public function index()
{
$this->load->view('welcome_message');
}
public function view($page = "home" , $function = "index")
{
do_something();
if($status == "404")
{
$function = "404";
}
$this->load->view('templates/header', $data);
$this->load->view($page.'/'.$function, $data);
$this->load->view('templates/footer', $data);
}
}
/* End of file welcome.php */
/* Location: ./application/controllers/welcome.php */
So I serve the home/404.php whenever an error occurs. i.e., I don't allow CodeIgniter to call show_404(); therefore the 404 page looks like any other page.
p.s. I assume that you followed the nice tutorial in CodeIgniter's website.
The simplest way to create custom error pages is to edit the files at /application/views/errors/html/error_*.php such as error_404.php (for 404s), error_db.php (for database errors) and error_general.php (for most other errors).
As these pages are within your application directory, you are free to customise them to your needs.
If your normal view template looks something like this:
<?php $this->load->view('includes/header'); ?>
...
...
<?php $this->load->view('includes/footer'); ?>
You can adapt this in your /application/views/errors/html/error_*.php files like so:
<?php
$page_title = $heading;
include VIEWPATH.'includes'.DIRECTORY_SEPARATOR.'header.php';
?>
<div class="well">
<h1><?php echo $heading; ?></h1>
<?php echo $message; ?>
</div>
<?php include VIEWPATH.'includes'.DIRECTORY_SEPARATOR.'footer.php'; ?>
Notice that we're no longer using views, but instead including the view files for the header & footer.
Another thing to note:
In the header view, I'm passing a $data object which includes $data['page_title']. As the error pages don't use views, you have to add any variables that you'd normally pass into the view, hence the presence of $page_title.
config/routes.php
edit
$route['404_override'] = '';
type here your controller for example Error
create a function index and load your view

Categories