Can the subdomain URL segment be used as a class in Codeigniter? - codeigniter

I need to use a subdomain as a class. ie, instead of:
www.example.com/class/function/ID eg www.example.com/town-name/history/1
I need
class.example.com/function/ID eg town-name.example.com/history/1
I've wildcarded the subdomain in nginx, now I've googled and read
http://codeigniter.com/user_guide/libraries/uri.html
http://codeigniter.com/user_guide/general/urls.html
http://codeigniter.com/user_guide/helpers/url_helper.html
but nothing relevant. I need it to be so that if another town is added to the db, it'll resolve that new town and its details.
I see many discussions about rewrites, redirects etc, but I specifically need to use the subdomain town name as the class variable. If possible, in an idea world, I could use both together, but I doubt that's possible?
I've had it going fine in plain old php for a couple of years now; now I want to upgrade to codeigniter without ruining my old structure if possible (plus there's a good reason for it).
Thanks you.

You can do it. I'm doing it for one of my projects.
In the constructor of your controller, just explode the current url and get the subdomain and pass it in your method as a variable
public class Controller extends CI_Controller {
$subdomain = null;
public __construct()
{
// explode url here and set $this->subdomain = the actual subdomain
}
public function index()
{
if($this->subdomain == null) {
show_404();
} else {
// do what you wish
}
}
}

Related

Laravel: Grab data from the Controller from inside a view composer

Atm I'm creating this view composer for fun. It is collecting .js filenames and then passing it to the layout to be linked. The filenames used depend on the current page. For example a lower ranked page like Slides, doesn't include ajax requests used in UserManagement. Please don't ask me why I would do this xD. Im planning to validate requests anyway. Just being bored.
Anyways, as I'm quite new to laravel I'm still looking for more efficient ways to do things.
Atm Im accessing the file names staticly. The Controller now looks like this
class Controller extends BaseController
{
public static $js_file_names = [];
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
}
In the pagecontroller I construct the filenames:
class SlidesController extends Controller
{
public function __construct()
{
parent::$js_file_names = ['ccs', 'ajax-updates'];
}
And finaly I retreive them inside the registered Viewcomposer like this:
(during development $use_filenames has all files as default)
public function __construct()
{
$filenames = Controller::$js_file_names;
if( !empty($filenames) )
$this->use_filenames = $filenames;
var_dump($this->use_filenames);die;
}
It all seems to be working fine, but the big question is, is there a better way to access controller data from inside a viewcomposer? Every time I try to google this, I get results like 'passing data to views' etc, which is not rly the problem.
Update:
Another idea I had is to store all the filenames to be used in an array inside the viewcomposer itself, and check if the current page exists in that array. This would keep the controllers cleaner.
Using a view composer doesn't really make sense in this situation. Since your controllers already 'know' which files they intent to share, you may as well just pass them to the view like so:
class SlidesController extends Controller
{
public function __construct()
{
View::share('user_filenames', ['ccs', 'ajax-updates']);
}
}
A composer is more for sharing concrete elements such as collections of users, a service provider or some other class instance, for example.

CodeIgniter URI Routing: remove method name index from URL

I am working with CodeIgniter (V:2.2.6) and I have a simple class User with some basic methods like create, update, edit, delete and index. For the index function, I am using an argument $user (which is the second URI segment) in order to display some information regarding that user. So the default URL looks like:
/user/index/john
to display some information about the user 'john'.
Now, I want to remove the term 'index' from the URL, so that it looks like:
/user/john
For that purpose I have added the following rule in routes.php.
$route['user/(:any)'] = "user/index/$1";
It serves the purpose, but it prevents accessing other functions like /user/create and goes inside /user/index automatically. To solve this problem, I can not see any other way except manually adding routing rules like
$route['user/create'] = "user/create";
for each method of the User class, which is not cool at all. So, please can anyone suggest me a better way of routing under the current circumstances?
Here are my codes:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class User extends CI_Controller {
public function index($user = '') {
echo "index!";
}
public function create() {
echo 'create!';
}
}
Note: I have gone through the CodeIgniter documentation for URI Routing and another similar question here, but could not figure out a promising solution. And please don't suggest for CodeIgniter version update.
I'm not sure, if this is the answer you like, but i think it should work.
Just put this function in your user controller.
public function _remap($method)
{
if (method_exists($this, $method))
{
$this->$method();
}
else
{
$this->index($method);
}
}

Codeigniter 2.0.x - Controller subdirectories default controller needs to be in URL

I recently upgraded a site from CodeIgniter 1.7.x to 2.0.3. About the same time someone in my organization requested we add some pages to the site. Underneath a section. In the old version of the site I used some workarounds in the controller to break up a longer URL. But in version 2 I see that I should be able to use subdirectories in the controllers folder to do it in a more proper way. After looking all over the place I've tried all sorts of routing declarations and fiddled with all sorts of things. Hopefully I'm doing something simple, wrong, or perhaps someone has seen a similar issue stemming from the upgrade.
I'm trying to get the URL from something like:
/about/locations
Which used to work with a controller named about.php. To something more like:
/about/social_responsibility/commitment
Where about is now a aub-directory.
Funny thing is, currently it does sorta work. That second URL displays correctly. However my old pages, that first URL, now do not function... My new structure uses a base.php (default_controller) in the about directory. Thus if I write:
/about/base/locations
It does work. But I thought the whole routing thing (default controller) and using subdirectories is supposed to clean the URL up.
My info is as follows...
Current Routing (it's changed a bunch over the last few hours)
$route['default_controller'] = "base";
$route['404_override'] = '';
$route['about'] = "about/base";
Directories and Files
/controllers/about/base.php
/controllers/about/social_responsibility.php
Chunk of base.php
class Base extends MY_Controller
{
public function __construct()
{
parent::__construct();
$this->data['parent'] = "About";
$this->load->model('mnav');
}
public function index()
{
}
public function locations()
{
}
}
I also have a MY_Controller that extends CI_Controller, but all it does is enable FirePHP for me in the development environment.
Anyone have any clues? Or need some more info to help? Thanks!
I just tested on my system, with CI 2.0.2 and it seems that the default controller setting works for subdirectories as well, without any other routes.
// so in your config file, whatever your default_controller is set to...
// you would just use that as the name of the `base` controller in about
// for example, if your default_controller is 'welcome'
// in /application/config.php
$route['default_controller'] = "welcome";
$route['404_override'] = '';
// then, it should work for the subdirectory where there is a controller
// named 'welcome'
// application/controllers/about/base.php
class Welcome extends MY_Controller
{
public function __construct()
{
parent::__construct();
}
public function index()
{
echo "I can be reached with /about";
}
}
So, all you should have to do is remove all of the routes for about
// remove this
$route['about'] = "about/base";
Important
This will only work when accessing /about -- anything in additional segments will be looking for additional controllers. So you'd have to think about how you'd like to access the base controller (whether or not you name it something else).
I'd assume that /about/locations is looking for an actual "locations" controller in your about folder, rather than being the method for your base controller. As far as CI knows, you're trying to execute one of two functions:
About controller's "locations" method
about/Locations controller's index method (obviously doesn't exist)
It follows that any 3-segment or greater URI will work with this scheme, but 2-segment URI's will confuse it. I don't think letting CI fallback to the default controller is going to work here. Try this:
$route['default_controller'] = "base";
$route['404_override'] = '';
$route['([^\/]*)'] = '$1/base';
$route['([^\/]*)/([^\/]*)'] = '$1/base/$2';

Customer session is different in different parts of a Magento website

I have a function inside of a Helper in Magento that returns whether or not a customer attribute equals one.
Here is my Helper class
class Nie_Nie_Helper_Data extends Mage_Core_Helper_Abstract {
public function isNieAdmin() {
if(Mage::getSingleton('customer/session')->getCustomer()->getNieAdmin() == 1) {
return true;
} else {
return false;
}
}
}
Now when I call this function from a class that extends Mage_Core_Block_Template, everything seems to work fine. However when I try to use this inside one of my controllers, it does not work. In fact when I do Mage::getSingleton('customer/session')->getCustomer()->debug() the only variable that is returned is the website_id.
Does anyone know what I have to do in order to get this to work?
At the time of the controller the session objects are not yet initialised (although the session variable must be) so it returns a blank model. My guess is the website_id is deliberately set in the creation of a customer object to act as a default.
You could access $_SESSION['customer'] directly to find what you need, but that is messy. An alternative would be to do what you want in an event that occurs later.
I hope someone can come up with a better answer than mine.
Ok it looks like I had to load up the session myself. I had to put the following in my functions:
Mage::getSingleton('core/session', array('name' => 'frontend'));
Hope this helps.

Codeigniter common templates

Let's say that I have a website that has 100 different pages. Each page uses a common header and footer. Inside the header is some dynamic content that comes from a database.
I'd like to avoid having to have code in every single controller and action that passes this common code into the view.
function index()
{
// It sucks to have to include this on every controller action.
data['title'] = "This is the index page";
data['currentUserName'] = "John Smith";
$this->load->view("main_view", data);
}
function comments()
{
// It sucks to have to include this on every controller action.
data['title'] = "Comment list";
data['currentUserName'] = "John Smith";
$this->load->view("comment_view", data);
}
I realize that I could refactor the code so that the common parts are in a single function and the function is called by the action. Doing so would reduce SOME of the pain, but it still doesn't feel right since I'd still have to make a call to that function every time.
What's the correct way to handle this?
One way I have been doing this is to extend the default controller class. You can read up on extending classes with MY_Controller in the user guide. Inside this extended class you can include something that you ALWAYS want to do, like render the page header template before the main content, or authorise a users access etc.
class MY_Controller extends Controller {
function __construct()
{
parent::Controller();
//code to always do goes here
echo 'Always print this comment';
$this->load->view('partials/template_start');
}
}
Then you can have your normal controller class extend THIS class by using
class MyControllerNameHere extends MY_Controller {
function __construct()
{
//setup here
}
function index()
{
echo 'Only print this bit when this method is called';
$this->load->view('partials/MYPAGENAMEHERE');
}
}
There are other ways of doing this, I use a mixture of the above and William's Concepts Codeigniter Template library. Do a bit of searching - there are a few solutions for you.
I had a similar situation. I created an 'includes' folder, and in there put a file that had the repetitive code from my controllers. Then in the controllers just include('/path/to/includeFile.php');
Don't know if it's the "correct" way, but it works well for me.
I ran across this after a search of their site. http://codeigniter.com/wiki/Header_and_footer_and_menu_on_every_page/ I'll review this page and its links, then post my thoughts.

Resources