Global variables in CodeIgniter view - codeigniter

I am following the Nettuts tutorial to implement Basecamp-style subdomains with CodeIgniter.
Based on the calling subdomain, the subdomain table in the database returns an extension corresponding to that subdomain. So say for stackoverflow.mywebsite.com, it will return the extension sf, and the image folder and CSS file used all over the website will change on the basis of this extension; for example, images_sf, style_sf.css, etc.
Now, what is the best way to fetch this extension anywhere in M, V, or C ?
Options:
Cookies
Dynamically setting CI config variable
Set a variable for this in MY_Controller and access that variable via $this-> anywhere.
Send that variable from each controller to models, helpers, views or libraries.
Did I miss any other options? Also, which one will be best assuming this will be heavily used all over the code?
Thanks

Personally, I would create a base controller for each site that you extend, and just use $this->load->vars($data); to load the information you need globally set.
In the constructor of your specific base Controller just load the data into the views globally like this.
$data->some_var = "some value";
$this->load->vars($data);
And then in all your views loaded by this controller (or base controller) you can utilize the variable $some_var directly in the view.

Your best bet is probably option 3, to put it in the constructor of your base contoller, probably MY_controller or whatever you are extending Controller (now CI_Controller with the CI2.0 official release)
However if all you're doing is getting an extension, there might not be a reason to have a database table, since you could just keep it in a config file
I'd do something like this... in MY_Controller.php (This is CI 2.0 syntax)
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class MY_Controller extends CI_Controller {
function __construct()
{
parent::__construct();
$subdomain_arr = explode('.', $_SERVER['HTTP_HOST'], 2);
$subdomain_name = $subdomain_arr[0];
$this->load->config('sub_prefix');
$pre_arr = $this->config->item('prefixes');
/* Check to make sure the subdomain name is in the config array */
$this->prefix = isset($pre_arr[$subdomain_name]) ? $pre_arr[$subdomain_name] : '';
}
Then in the config file (sub_prefix.php)
<?php if (! defined('BASEPATH')) exit('No direct script access');
$config['prefixes'] = array('subdomain1' => 'sub1',
'stackoverflow' => 'sf');
That way you don't have to run an extra query everytime the page loads for something that is relatively static...if you got to the point where there would be a lot more information you would need other than a prefix, then it would make sense to do it with the database
You can now just use $this->prefix in any of the views, controllers, or models you will be using... the best way to do it for something that is heavily use all over your application.

Related

Isolate external php code in Laravel

I need to integrate Slider Revolution editor into my Laravel (5.5) app.
I've put the editor in public/revslider/ folder to be able to use the visual editor. I also created a helper class to "communicate" with it and be able to use it inside my Blade views:
namespace App\Helpers;
include( public_path('revslider/embed.php') );
class Slider{
/**
* This function is called where you want to put your slider
*/
public static function make($slider){
return \RevSliderEmbedder::putRevSlider( $slider );
}
/**
* This function is called inside <HEAD> tag to include all
* SR assets (js/css/font files)
*/
public static function head(){
return \RevSliderEmbedder::headIncludes(false);
}
}
The SR's PHP code does not use namespaces. In fact it is a strange mix of Code Igniter, Wordpress and vanilla php.
The problem is it is trying to declare a translation function __(...):
if( ! function_exists('__'))
{
function __($string = '')
{
....
}
}
and since there is already such Laravel's helper function, it does not redeclare it and tries to use Laravel's __() function. And that obviously causes errors.
I temporarily managed to fix this problem by changing the name of SR's __() function (and all references to it). But of course it is not a best way to solve this problem, since I will be unable to use SR's automatic updates or will be forced to do these changes after every update.
So my questions are:
Is there any good way of integrating such "bad" code into your project, invoking it safely without conflicts? Is there any way of isolating such code and avoid clashes? By "bad code" I mean code that does not follow strict OOP/PSR rules present in projects like Laravel.
What is the best way to include "external" PHP code? I've just used plain include() inside of my helper class' file, but is there a better/cleaner way? Like, I don't know, loading it through composer?

How can I render a twig template in a custom controller in Silex?

I'm playing with Silex microframework to build a very simple app.
The Silex documentation briefly illustrates how to keep your code organised using controller as class and I've also found this useful article talking about the same practice:
https://igor.io/2012/11/09/scaling-silex.html
but still can't solve my problem
The issue:
in my app.php I'm using
$app->get('/{artist}', 'MyNamespace\\MyController::getAlbum');
This is working. MyController is a class correctly loaded through composer using psr-4.
At the moment the return method of getAlbum($artist) is return $player;
What I'd like to do instead, is returning a twig view from getAlbum, something like:
return $app['twig']->render('player.twig', $player);
To do so, what I've tried to do in my custom class/controller is:
use Silex\Application;
use Symfony\Component\HttpFoundation\Request;
[...]
public function getAlbum(Request $request, Application $app, $artist)
but this is generating the following error when I try to access the routed pages:
ReflectionException in ControllerResolver.php line 43:
Class MyNamespace\Request does not exist
Whic made me think that there's a namespace conflict between myNamespace and the Silex namespaces?!
What am I doing wrong?
Is this the right way to make $app visible in my custom controller in order to use return $app['twig']... ?
Thank you in advance!
EDIT
After several other tries still didn't get to the point (replies still welcome!) but I've found a workaround solution that could be useful to anyone will incur in a similar issue. Directly in my app.php I added this
$app->get('/{artist}', function (Silex\Application $app, $artist) use ($app)
{
$object = new MyNamespace\MyController();
$player = $object->getAlbum($artist);
return $app['twig']->render('player.twig',
array(
//passing my custom method return to twig
'player' => $player,));
});
then in my player.twig I added:
{{player | raw}}
And this basically means that I still need an anonymous function to get use of my custom method which is a working solution I'm not really happy with because:
I'm using 2 functions for 1 purpose.
The return value of getAlbum is dependent from the use of "raw" in twig.
SOLVED
The workflow described works fine. It was a distraction error: I've placed the namespace of my custom class after use Symfony\Component\HttpFoundation\Request;
namespace declaration in PHP needs always to be at the top of the file, Silex wasn't able to injects $app and $request for this reason.

CodeIgniter pagintation - appending the page number to "page" string

What I am trying to achieve is urls outputting via pagination like this:
http://www.mysite.com/users/page5
or
http://www.mysite.com/users/page-5
At present, it will be using the URI segments like this:
http://www.mysite.com/users/page/5
I can modify the routes.php config file to route the path if the first two URLs are used. So, that's not the issue.
What I am having trouble with is, how do I initialize the settings for the pagination, so that the $this->pagination->create_links() will create a pagination with items having links like in the first or the second format?
Let me know if you need more explanation or examples regarding this. I'm not much good in explaining things. :)
Thank you
This functionality already exists in the in-development version of CodeIgniter 3.0. You can view the Pagination class as it sits here.
To use this library, you can either A) use all of CI 3.0 (it's pretty stable), or B) extend (or, more realistically, replace) the Pagination library by creating application/libraries/MY_Pagination.php and filling it with the contents of the link above. (Full disclosure: it's been a while since I tinkered with CI, so I don't know if anything has changed since that may result in errors with any of this answer.)
To use the feature you want, specify your base URL minus the page-X segment, set that you want to use page numbers instead of offset in your URI segment, and then specify a prefix.
$config['base_url'] = site_url('users');
$config['use_page_numbers'] = true;
$config['prefix'] = 'page-';
Make sure to include your other obvious items as well, such as per_page, etc.
To change the functionality of the Pagination library, you can extend the library and override the create_links() function.
Create a file named MY_Pagination.php in application/libraries/
The file should have the following structure, so you can change or add additional functionality to CI's native Pagination library. (It is bad practice to directly change the Pagination library in the system directory.
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class MY_Pagination extends CI_Pagination {
public function __construct()
{
parent::__construct();
}
}
You'll then need to add the create_links() function to your MY_Pagination class, allowing you to override its default functionality. Below is an explanation of what you could change to achieve your desired output (you may want to add flexibility, by adding a parameter to the function, but this is the simplest change that I could think of.)
function create_links()
{
// You can copy the exact functionality of this function from:
// system/libraries/Pagination.php
// The line you want to change is:
// $this->base_url = rtrim($this->base_url, '/') .'/';
// Changing to this: $this->base_url = rtrim($this->base_url, '/') .'';
// Will create links in this format: ../page5
// Or changing to this: $this->base_url = rtrim($this->base_url, '/') .'-';
// Will create links in this format: ../page-5
}

Multilingual set up of codeigniter

I'm using this tutorial http://sumonbd.wordpress.com/2009/09/16/develop-multilingual-site-using-codeigniter-i18n-library/ for multilingual in codeigniter.
I've follow the instruction listed correctly. It does not gave me any error, but I couldn't say that it is working properly.
when I run through mysite.com/en/about and mysite.com/fr/about it always give me the default language which is english. I'm wondering if there is any configuration that I need to set to be able to work properly.
I'm thinking about this in config.php
$config['language']
and
this in autoload.php
$autoload['language']
Do I have to configure those? or any other configuration to work the multilingual properly.
After analyzing the code of CI and the codes in the blog I've come up to this solution.
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class About extends CI_Controller {
function index()
{
// you might want to just autoload these two helpers
$this->load->helper('language');
$this->load->helper('url');
$this->getLang();
$this->load->view('about');
}
function getLang(){
$url = $_SERVER['REQUEST_URI'];
$lang = explode("/", $url);
if($lang[2] == 'en'){
// load language file
return $loadLang = $this->lang->load('english','english');
}
else if($lang[2] == 'fr'){
// load language file
return $loadLang = $this->lang->load('french','french');
}
else{
// load language file
return $loadLang = $this->lang->load('english','english');
}
return false;
}
}
I've created the function getLang() in which I load the language file.
$this->lang->load('language_file','language_folder');
Sorry, you don't provide enough information about what you have done. But I'll try to answer.
I've try the updated tutorial, and it's works like a charm.
First, you point to an out to date tutorial. This is the source of your link with an update: source
Second, a file prefixed with MY_ (default configuration) is a core classes ( see Core Classes ) not a library and should be placed on application/core directory.
Third, in your view file, try to avoid using php short tag (<?=$variabel;?>) because not all server configuration enable php short tag. Use normal echo tag instead <?php echo $var; ?>. Longer, but worth it as you write the standard pattern.
As I said before, if you follow the updated tutorial your script should work as mine. I hope this help. Sorry for my English, correct me if I'm wrong.
i think you should have a look at URI-Language-Identifier i use it for my multilingual projects, and its working as it should.

CodeIgniter 2 and usage of $this->

I'm using CodeIgniter 2 and have installed Ion Auth and also the News tutorial that comes with CodeIgniter.
In the News Controller, the element for the page title is written like this...
$data['title'] = 'Page Title';
However, in the Ion Auth Controller, the element for the page title is written like this...
$this->data['title'] = 'Page Title';
They both seem to work equally well, so can anyone explain the difference(s)? Maybe Ion Auth was written for an older version of CodeIgniter? Is there any practical reason why I'd want to use one over the other? Please link to sources as needed.
I guess it's the author's preference. He likes to use a class property to store the view's data. It allows him to share it across methods. If you look at the author's other projects (Source 1, 2, 3), you can see two examples (source 1 & 2 goes together).
On a side note, for your project, this could allow you to extend the Auth controller with more view data.
class MY_Auth extends Auth {
function __construct()
{
parent::__construct();
}
function index()
{
$this->data['foo'] = 'bar';
parent::index();
}
}
That would allow you to use the $foo variable to your authentication view. (/auth/index in this case.)
In my own projects, I like to use a protected property for my view's data. It does give you much more freedom than a local variable. You don't need to pass the view's data as an argument all the time and you can easily extend your controllers afterward.
Hope this helps!
if you are going to use this $this->data it means you can access $this->data through out the class methods. On the other hand if you are using $data it is only available for the current scope or method and if you need data some where else then you will have to pass it as parameters to the other methods.
Adding $this on the data variable, makes it to be accessible through the class.
I believe the $data or $this->data is only used for "View". It will be passed from the "Controller" to the "View", so we can access that variable through the "View".
So, there will be no differences on the "View" side.

Resources