Multiple sites by using only one code - php

when a user open any link of our application i need a controller by name site_check or any else which does the following things, firstly get site url opened exactly like "www.google.com" , i need to store the data like only google.com and if this value is checked with the database if exist.
if exist give a go add a local cookie of the same. Don't need to check this again until session is removed.
i will store the values like i need to pull the title logo and other static data from the platform to this.
how many possible ways are there we can try this to workout.
I am a new to this codeigniter and coding, needed your help.. how to start it I'm not getting any idea, please help me out.

Hi here is my solution and i have used it to develop single core multiple sites create a setting table save basic info like domain, site name and template information in that table add many setting later on, create MY_Controller under core directory check domain exist in your database or not
class MY_Controller extends CI_Controller {
public $site_id = 0;
public $template = '';
function __construct(){
parenet::__construct()
$this->loadSetting();
}
function loadSetting(){
$host = $_SERVER['HTTP_HOST'];
$row = $this->db->where_like('domain',$host)->get('setting')->row();
$this->site_id = $row->id;
$this->template = $row->template;
}
}
Once you setting is done you can add site_id as foreign key in your other tables like pages, news to get site specific pages and news and other information about site. Now extend your Page Controller or News Controller with MY_Controller like this.
class Page_Controller extends MY_Controller {
function __construct(){
parent::__construct();
}
function index(){
$page = $this->db->get_where('pages',array('site_id',$this->site_id))->row();
}
}
if you further want site_id available every where in your application you can create a library and autoload that library and you can put loadSetting method in that library. Like
class Setting {
private $ci;
public $site_id;
public $template;
function __construct(){
$this->ci = get_instance();
$this->loadSetting();
}
function loadSetting(){
$host = $_SERVER['HTTP_HOST'];
$row = $this->ci->db->where_like('domain',$host)->get('setting')->row();
$this->site_id = $row->id;
$this->template = $row->template;
}
}
Now you can access site_id in your application anywhere like models other libraries and controller like this
$this->setting->site_id;
hope this will solve your problem.

I believe you are trying to create Access Control layer for users in your organization to access certain websites which you want to permit. Though in a network environment behind NAT Server a simple proxy server like Microsoft ISA or any third party like Kerio can help you out by creating a simple rule
But if you want to do the same in Codeigniter, you need to startup with the following
Step-1
Create a Database table for Permitted sites like
id | website
----------------------------------
1 | facebook.com
2 | youtube.com
You need to have users table like
id | username | details
-------------------------------------
1 | Mudassar | php developer
You need to have a user-permission table like
id | user_id | site_id | permission
----------------------------------------
1 | 1 | 2 | allowed
Now Login your user
public function Login()
{
if($_POST)
{
// You can perform Validation here
$user_data=$this->Login_Model->checkUser($_POST);
if($user_data)
{
$this->session->set_userdata($user_data);
redirect(base_url().'user/dashboard'); // or whatever link
}
}
else
{
$this->load->view('login_view');
}
}
So now you have user_id in your session. Time to load your dashboard which supposedly have link to different websites
public function dashboard()
{
$data['sites']=$this->User_Model->getPermittedSites();
// Now you are only sending permitted sites to the user view
$this->load->view('dashboard',$data);
}
If you want to make things complicated, there are tons of ways but this is simplest.

Related

Multisite with Codeigniter 3 | Database auto switch

Hello guys I need some help with multisite using Codeigniter.
So I was developing a multisite system where different companies register and they are given their sub-domain (E.g Company ABC go to www.system.com and register, then they are given sub-domain abc.system.com) then database abc (encrypted) is generated and default tables are created by the system.
All companies use the same interface, so the only thing change is the database.
My ideas was every time someone access abc.system.com I explode (abc.system.com) and I take abc encrypt it and I change DB connection in the config/database.php to
$db['company'] = array(
'database' => 'encrypted(abc)',
And User will use $this->db->query
But now when am thinking about it, disaster will happen when someone else happen to login to xyz.system.com because connection will change again to encrypted(xyz) because he/she will also be using $this->db->query
Remember the system is one and only database are changing.
I did not understand the technique of multisite using .htaccess
Now am stuck guys any ideas on how I can go around it?
Am using codeigniter 3.
I can recommend you to init this 2nd "company" DB inside a MY_Controller class which you can extend in all your Controllers (perhaps only those which are companies related.
By CI default configurations you are able to create MY_Conroller inside the core folder which will extend CI_Controller and any controller inside your controllers can extend it.
Inside this MY_Controller you will be able to parse the host (domain) and to set the right DB..
Example :
class My_Controller extends CI_Controller {
protected $dbC;
public function __construct(){
parent::__construct();
//HERE YOU CAN MAKE THE 2nd DB load after you detect that you are in valid subdomain
$expHost = explode('.', $_SERVER['HTTP_HOST']));
if( count($expHost) === 3 && $expHost !== 'www') {
$dbC_config = // Get your DB COMPANY configurations or input it here as array..
$dbC_config['database'] = 'encrypted('.$expHost[0].')';
$this->dbC = $this->load->database($dbC_config);
}
}
}

How do I change codeigniter existing login system using 3rd party authentication system

I really need help in making modifications to a script I purchased which was designed using codeigniter (a system I am totally new to). The project is designed to have only two user roles with fixed permission (admin, others(is_logged_in)). After couple of hours of learning how MVC works I have been able to change so little yet insignificant stuff in project.
My big problem is this:
I want to use the script to complete a web POS app which I have been working on basically in native php, the project uses ion-auth for the login systems and authentications, please I want to use another 3rd party acl systems like flexiauth, oauth, Aauth, etc but I don't have enough knowledge to know what files I will be replacing and which controller (s) I will need to made modification in.....I am totally stuck....please help me
What I need is simple enough:
I want to have multiple groups and users with access to different resources in the web app e.g a cashier (should have access to pos, customer, report daily_sales, close register, print invoice) AND (an account should have access to dashboard, reports, order etc), manager should be able to create new user, view sales, void sales etc, AND admin should of course have overall access.
What I have now is admin(full access to all the resources) other logged_in users: restricted in some areas.
Groups I have is 2:
Admin
Staff.
I don't know how to continue.
i think i find the custom library used to define the access
Please check the follow code and advice on where i can start:
class MY_Controller extends CI_Controller {
function __construct() {
parent::__construct();
define("DEMO", 0);
$this->Settings = $this->site->getSettings();
$this->lang->load('app', $this->Settings->language);
$this->Settings->pin_code = $this->Settings->pin_code ? md5($this->Settings->pin_code) : NULL;
$this->theme = $this->Settings->theme.'/views/';
$this->data['assets'] = base_url() . 'themes/default/assets/';
$this->data['Settings'] = $this->Settings;
$this->loggedIn = $this->tec->logged_in();
$this->data['loggedIn'] = $this->loggedIn;
$this->data['categories'] = $this->site->getAllCategories();
$this->Admin = $this->tec->in_group('admin') ? TRUE : NULL;
$this->data['Admin'] = $this->Admin;
$this->m = strtolower($this->router->fetch_class());
$this->v = strtolower($this->router->fetch_method());
$this->data['m']= $this->m;
$this->data['v'] = $this->v;
}
function page_construct($page, $data = array(), $meta = array()) {
if(empty($meta)) { $meta['page_title'] = $data['page_title']; }
$meta['message'] = isset($data['message']) ? $data['message'] : $this->session->flashdata('message');
$meta['error'] = isset($data['error']) ? $data['error'] : $this->session->flashdata('error');
$meta['warning'] = isset($data['warning']) ? $data['warning'] : $this->session->flashdata('warning');
$meta['ip_address'] = $this->input->ip_address();
$meta['Admin'] = $data['Admin'];
$meta['loggedIn'] = $data['loggedIn'];
$meta['Settings'] = $data['Settings'];
$meta['assets'] = $data['assets'];
$meta['suspended_sales'] = $this->site->getUserSuspenedSales();
$meta['qty_alert_num'] = $this->site->getQtyAlerts();
$this->load->view($this->theme . 'header', $meta);
$this->load->view($this->theme . $page, $data);
$this->load->view($this->theme . 'footer');
}
}
Codeigniter doesn't come with native login system, so the script you purchased is already using a third party package/plugin.
Look for login script code in the following locations : Models, Libraries.
The controller is where you control everything, so you can have a look at that later, first you need to determine which files are being used as the core of login functionalities. Once you have determined, you can look at the code and understand how they are handling user groups/ previlages etc.
About the groups and previlages, either they have their on table in database where the values are stored for admin, public etc or the values are stored in a config file, you can find all the config files in the application\config directory. Use PHPMYAdmin to check database and check non codeigniter config files too.
Check the Auth in every controller. Remove them and put your exiting auth system.

Codeigniter URI routing and security

In codeigniter or restful structure, the page can be route to through the URI
For example, if I would like to look at the item list of id: 1 , then I just need to create a path like that:
domain.com/item/view/1
And in controller
function view() {
$id = $this->uri->segment(3);
//database get data and return view...
}
This should be the standard way to implement restful structure. However, when in the member system, and the item id is dependent to the user, how can I protect the link?
So that other user can not brute force to try different ID and read the other member item.
One approach is just compare the user_id and item_id in each function. But if the system is large that means I need to compare in each function and that is a lot of coding and checking .
Are there any smarter way to reduce the overhead / coding ?
Thanks
There is no way to protect URL's. Someone could simply change the number in the URL and fetch different data. If the ID is sensitive, you would not want to pass the information through the URL.
One option is to encrypt the ID being passed in the URL (ex: 29 could be encrypted so it appears as 'S84jG483dJd').
The ID could also be passed through using the code-igniter session library or even with flash data (stored for one request). This way if the ID's are sensitive, the likelihood of anyone altering them would be slim (enable session cookie encryption in CI for more security).
However, if the information is that sensitive, I would always have checks in place before the database is fetched and shown to the user. It is always good practice to code with your users worst intentions in mind!
In domain.com/item/view/1, always stands for base_url/controller/Method
so if you create controller (item), then function (view).
class Item extends CI_Controller
{
public function __construct()
{
parent::__construct();
}
public function view($id)
{
//so in $id it will assign the 3rd value to it.
$new_id = $id;
echo $new_id;
}

Codeigniter how can I make this route work

I've looked around in the documentation and a few other places and I am not sure how to achieve the results I want. I have a domain name set up that will only server public profile pages to visitor. When someone comes straight to the site I want it to display a welcome screen telling more about what the website is about. (example.com) When someone visits example.com/my-public-page I want it to run a default controller that grabs the 'my-public-page from the url, searches the database for a user with that info in a column and displays their info.
I would image that I just set the default_controller to my controller and then check for a second string in the url. If its present search for that in the database. After looking around I am not sure how to make this work and not sure what to search for to get the results I need.
Thanks for your help,
After defining an encryption key for sessions in config.php you can use something like this:
class Wellcome extends CI_Controller {
public function __construct() {
parent::__construct();
$this -> load -> library('session');
if(!$this->session->userdata('visit_time')) {
$this->session->set_userdata('visit_time', time());
redirect('first_visit');
}
}
}

Activity Feed Structure

I am building a function that will add a log of what my user has done into my database so that I can then build a activity feed for other users' activity feed.
What I imagine it to resemble so far.
Activity table
id | user_id | source | source_id | timestamp
Example Input
1 | 1 | photo_upload | 54 | 1333906150 //54 being the ID of the photo in my DB
2 | 1 | follow | 2 | 1333906159 // 2 being the id of a user
This way I can easily pull information from the database for a users activity, "user_id = {$followers} then show them according to what their source is e.g show the image for a photo_upload.
EDIT
What would be the best way to display different types of the feed.
This is what I currently have but it seems a bit much.
<?php
$grab = mysql_query("SELECT * FROM `activity` WHERE `user_id` IN (".$following.") ORDER BY `id` DESC");
while($row = mysql_fetch_array($grab)){
switch ($row['source']) {
case "photoupload":
// Display photo upload layout
break;
case "follow":
// Display follow layout
break;
}
}
?>
Does anyone see any ways to improve upon this?
Create an abstract class describing a feeditem type:
abstract class Application_Feed_Item_Abstract {
protected $_item;
public function __construct($itemData) {
$this->_item = $itemData;
}
abstract public function render();
}
Implement this class for different kinds of content:
class Application_Feed_Item_Photo extends Application_Feed_Item_Abstract {
public function render() {
//Custom rendering logic for a Photo
return '<div>Watch my photo</div>';
}
}
class Application_Feed_Item_Follow extends Application_Feed_Item_Abstract {
public function render() {
//Custom rendering logic for a Follower
return '<div>I got a new follower</div>';
}
}
So when you pull a record, you are able to create a renderer object on the fly depending on the kind of feeditem:
//Pull items from database and store them as an Array or other iterable object.
//Here i assume we call this collection of rows from the database $feeditems
//Mapping of source to renderer classes
$types = array(
"photoupload" => "Application_Feed_Item_Photo",
"follow" => "Application_Feed_Item_Request",
"somethingelse" => "Application_Feed_Item_Somethingelse"
);
//Process every item
foreach($feeditems as $item) {
$type = $item['source'];
if(!array_key_exists($type, $types)) {
throw new Exception("Unsupported feeditem type.");
}
$type = $types[$type];
$renderer = new $type($item);
echo $renderer->render();
}
Just a loose idea for a way to implement it. But as stated by another user, there are many different ways to do it, depending on your requirements. The method you used in your question would work just fine
There are many ways to skin a cat. Similarly there are many ways to achieve the same results you require.
Some suggestions for "improving" IMO would be -
1. Fetching this data as pre-generated HTML with an AJAX call.
Using an AJAX call once the page is loaded, you could have your server build the HTML segments of your users activity feed. This will allow your page to load much faster and your content will be loaded shortly after.
You don't even have to build HTML on the server - you could also pass a JSON object back from the AJAX call and build your HTML with JavaScript.
2. Creating a cached static HTML file of the users feed that is simply included into the markup.
You could have your server generate all the HTML needed for a users feed at a certain interval - every 30 minutes for example - and then save that HTML into a file to be included in the existing HTML. You can do this using PHP's include() function.
Using this method the activity feed will have a delay when refreshing so it might not be the best option - but if you make the interval smaller - every 5 minutes for example, you'll be saving a lot of calls to the DB.
Check out cron jobs - you could possibly use them to schedule the updates.
3. Place an index on the user_id field in your DB since you are using it to search by user.
This is a very important one especially if you are expecting many entries to exist in your DB. Placing an index on the fields that you use to search a table will vastly increase the performance of your queries.
I'm sure there are many more things that can be suggested here.

Categories