How to build in 'maintenance mode' in Codeigniter? - php

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.

Related

Send the function with arguments to the model

I have several index pages
And I put the header page separately
I want the name of each page to be sent to the header
How can I do it, thank you?
model::setnameisset('home');
and model.php page
function setnameisset($name)
{
return $name;
}
Now I want it to be saved in the header page instead of the title tag
<!DOCTYPE html>
<html lang="en">
<head>
<base href="<?= URL ?>">
<meta charset="utf-8">
<!-- <meta http-equiv="Content-Type" content="text/html"> -->
<title></title>
</head>
Now how do I call that function?
See I have several pages like contact page or home page
And I put the header in a page and included it in these pages
The structure is m v c
I just want to send the name of the page or the keyword tag to the header so that it opens with that name during execution.
For example, my index or contact file
<?php model::nametag('homepage'); ?>
<body id="page-top">
</body>
Now I have a model file in the core folder
My controller file is like this
class Controller
{
function __construct()
{
}
function view($viewurl,$data=[],$noincludeheader = '',$noincludefooter = ''){
if ($noincludeheader =='') {
require_once ('views/share-base/header.php'); //panel header
}
require_once ('views/'.$viewurl.'.php'); //panel main page
if ($noincludefooter =='')
{
require_once ('views/share-base/footer.php'); // panel footer
}
}
function model($modelUrl){
require_once ('models/model_'.$modelUrl.'.php');
$classname='model_'.$modelUrl;
$this->model = new $classname;
}
}
And my model file is like this
public function nametag($name)
{
return $name;
}
It's so easy, I just want to be placed in any file, a name should be passed to the header page, I don't know how to use the function.

Routing all page with one controller with codeigniter

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')
}

Page Title Based on Class/Function Variable PHP

New to classes, and I'm having an issue dynamically changing a page's title. I think I may know what the issue is, but I don't really know what to do in order to fix the problem. I have two pages, admin.php (where the class is housed) and display-admin.php (displays what the user sees). Within admin.php this is what I have:
class Admin {
public $title;
public function login() {
require("login-form.php");
return $this->title = "Login";
}
...
}
$o = new Admin();
This is what I have within display-admin.php:
<?php
include_once("admin.php");
?>
<!DOCTYPE html>
<html lang="en">
<head>
<?php
if(isset($o->title)) {
echo "<title>My Site | " . $o->title . "</title>";
} else {
echo "<title>My Site</title>";
}
?>
</head>
<body>
<?php
...
switch($action) {
case "login":
$o->login();
break;
default:
$o->displayPages();
}
...
?>
</body>
</html>
The title always stays as My Site. It never adds the title needed. Now, when I tested echoing $o->title at the end (before the <\body> tag), it displayed the string I passed. Is this because I am trying to echo the variable before calling the function? If so, how do I fix in order to display the title, and have my content displayed within the body?
Thanks in advance for the any/all help/suggestions.
In your case it isnt work because $o->title doesnt exist.
It is created in your "login()" method, and this is after your
if(isset($o->title)) {
So you can do this:
class Admin {
public $title;
public function __construct() {
$this->title = "Admin";
}
}
You can do it per example in the constructor of your Admin Class.
The constructur is a magic method. It will be automatically called directly if you created your class.
Hope this will help you.
If you create an object from class Admin the title will be change into 'Admin'
In your Admin Page you can do this:
$o = new Admin();
echo "<title>".$o->title."</title>";

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

create main page with codeigniter

How can i create a main page with codeigniter?
That page should contain a few links like login, register, etc.
I followed a tut to create a login screen. But it made codeigniter only for that purpose. This is the site i'm talking about:
http://tutsmore.com/programming/php/10-minutes-with-codeigniter-creating-login-form/
So basically what im trying to is, use codeigniter for more things than just a login form.
My try routes.php i set these settings:
$route['default_controller'] = "mainpage";
$route['login'] = "login";
My mainpage.php file:
class Mainpage extends Controller
{
function Welcome()
{
parent::Controller();
}
function index()
{
$this->load->view('mainpage.html');
}
}
Mainpage.html:
<HTML>
<HEAD>
<TITLE></TITLE>
<style>
a.1{text-decoration:none}
a.2{text-decoration:underline}
</style>
</HEAD>
<BODY>
<a class="2" href="login.php">login</a>
</BODY>
</HTML>
Login.php looks exactly like the one in that website which i provided the link for in this post:
Class Login extends Controller
{
function Login()
{
parent::Controller();
}
function Index()
{
$this->load->view('login_form');
}
function verify()
{
if($this->input->post('username'))
{ //checks whether the form has been submited
$this->load->library('form_validation');//Loads the form_validation library class
$rules = array(
array('field'=>'username','label'=>'username','rules'=>'required'),
array('field'=>'password','label'=>'password','rules'=>'required')
);//validation rules
$this->form_validation->set_rules($rules);//Setting the validation rules inside the validation function
if($this->form_validation->run() == FALSE)
{ //Checks whether the form is properly sent
$this->load->view('login_form'); //If validation fails load the <b style="color: black; background-color: rgb(153, 255, 153);">login</b> form again
}
else
{
$result = $this->common->login($this->input->post('username'),$this->input->post('password')); //If validation success then call the <b style="color: black; background-color: rgb(153, 255, 153);">login</b> function inside the common model and pass the arguments
if($result)
{ //if <b style="color: black; background-color: rgb(153, 255, 153);">login</b> success
foreach($result as $row)
{
$this->session->set_userdata(array('logged_in'=>true,'id'=>$row->id,'username'=>$row->username)); //set the data into the session
}
$this->load->view('success'); //Load the success page
}
else
{ // If validation fails.
$data = array();
$data['error'] = 'Incorrect Username/Password'; //<b style="color: black; background-color: rgb(160, 255, 255);">create</b> the error string
$this->load->view('login_form', $data); //Load the <b style="color: black; background-color: rgb(153, 255, 153);">login</b> page and pass the error message
}
}
}
else
{
$this->load->view('login_form');
}
}
}
What am i missing guys?
You're using CodeIgniter, right? Do you have some stipulation in your config that you must use .php as an extension on all URLs? If not, you should be sending your hrefs to "/login" not "/login.php". Furthermore, if you haven't removed the "index.php" from your URL in your htaccess file and CI config, you'll probably need to include that in your links.
Furthermore, if I were you, I'd not follow what Sarfraz does in his Mainpage.php file. You shouldn't be using standard PHP includes in CodeIgniter. Anything that is done with an include can easily be done by loading a view. For example, if you want to load the view as a string, you can say:
$loginViewString = $this->load->view('login.php', '', true);
Where the second parameter is whatever information you want passed to your view in an associative array where the key is the name of the variable you'll be passing and the value is the value. That is...
$dataToPassToView = array('test'=>'value');
$loginViewString = $this->load->view('login.php', $dataToPassToView, true);
And then in your login.php view you can just reference the variable $test which will have a value of "value".
Also, you don't really need to have that "login" route declared since you're just redirecting it to the "login" controller. What you could do is have a "user" controller with a "login" method and declare your route like this:
$routes['login'] = 'user/login';
EDIT...
OK, I think this has perhaps strayed one or two steps too far in the wrong direction. Let's start over, shall we?
First let's start with a list of the files that are relevant to this discussion:
application/controllers/main.php (this will be your "default" controller)
application/controllers/user.php (this will be the controller that handles user-related requests)
application/views/header.php (I usually like to keep my headers and footers as separate views, but this is not necessary...you could simply echo the content as a string into a "mainpage" view as you're doing....though I should mention that in your example it appears you're forgetting to echo it into the body)
application/views/footer.php
application/views/splashpage.php (this is the content of the page which will contain the link to your login page)
application/views/login.php (this is the content of the login page)
application/config/routes.php (this will be used to reroute /login to /user/login)
So, now let's look at the code in each file that will achieve what you're trying to do. First the main.php controller (which, again, will be your default controller). This will be called when you go to your website's root address... www.example.com
application/controllers/main.php
class Main extends Controller
{
function __construct() //this could also be called function Main(). the way I do it here is a PHP5 constructor
{
parent::Controller();
}
function index()
{
$this->load->view('header.php');
$this->load->view('splashpage.php');
$this->load->view('footer.php');
}
}
Now let's take a look at the header, footer, and splashpage views:
application/views/header.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="description" content="This is the text people will read about my website when they see it listed in search engine results" />
<title>Yustme's Site</title>
<!-- put your CSS includes here -->
</head>
<body>
application/views/splashpage.php - note: there's no reason why you need a wrapper div here...it's only put there as an example
<div id="splashpagewrapper">
Click here to log in
</div>
application/views/footer.php
</body>
<!-- put your javascript includes here -->
</html>
And now let's look at the User controller and the login.php view:
application/controllers/user.php
class User extends Controller
{
function __construct() //this could also be called function User(). the way I do it here is a PHP5 constructor
{
parent::Controller();
}
function login()
{
$this->load->view('header.php');
$this->load->view('login.php');
$this->load->view('footer.php');
}
}
application/views/login.php
<div id="login_box">
<!-- Put your login form here -->
</div>
And then finally the route to make /login look for /user/login:
application/config/routes.php
//add this line to the end of your routes list
$routes['login'] = '/user/login';
And that's it. No magic or anything. The reason I brought up the fact that you can load views as strings is because you may not want to have separate "header" and "footer" views. In this case, you could simply "echo" out a view as a string INTO another view. Another example is if you have a shopping cart full of items and you want the shopping cart and the items to be separate views. You could iterate through your items, loading the "shoppingcartitem" view as a string for each item, concatenate them together, and echo that string into the "shoppingcart" view.
So that should be it. If you still have questions, please let me know.
Note that you are not specifying the correct method name for your main controller:
class Mainpage extends Controller
{
function Welcome() // < problem should be Mainpage
{
parent::Controller();
}
function index()
{
$this->load->view('mainpage.html');
}
}
Suggestion:
Instead of creating html page, create a php page and use the include command to include the login.php file.
Mainpage.php:
<HTML>
<HEAD>
<TITLE></TITLE>
<style>
a.1{text-decoration:none}
a.2{text-decoration:underline}
</style>
</HEAD>
<BODY>
<?php include './login.php'; ?>
</BODY>
</HTML>
And modify your main controller with this file name eg:
class Mainpage extends Controller
{
function Mainpage()
{
parent::Controller();
}
function index()
{
$this->load->view('mainpage.php');
}
}
I think you should add a file named .htaccess at first in your home folder
for example
<IfModule mod_rewrite.c>
RewriteEngine On
# !IMPORTANT! Set your RewriteBase here and don't forget trailing and leading
# slashes.
# If your page resides at
# http://www.example.com/mypage/test1
# then use
# RewriteBase /mypage/test1/
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /test/index.php?/$1 [L]
</IfModule>
<IfModule !mod_rewrite.c>
# If we don't have mod_rewrite installed, all 404's
# can be sent to index.php, and everything works as normal.
# Submitted by: ElliotHaughin
ErrorDocument 404 /index.php
</IfModule>
in the test field you need to add your homefolder or baseurl
and you need to set the baseurl in config page as
$config['base_url'] = 'http://localhost/test';
And the link inside the html page should be as
<a class="2" href="http://localhost/test/Login">login</a>
In login_form page you need to make action url as
http://localhost/test/Login/verify

Categories