CodeIgniter: Create new helper? - php

I need to loop lot of arrays in different ways and display it in a page. The arrays are generated by a module class. I know that its better not to include functions on 'views' and I want to know where to insert the functions file.
I know I can 'extend' the helpers, but I don't want to extend a helper. I want to kind of create a helper with my loop functions.. Lets call it loops_helper.php

A CodeIgniter helper is a PHP file with multiple functions. It is not a class
Create a file and put the following code into it.
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
if ( ! function_exists('test_method'))
{
function test_method($var = '')
{
return $var;
}
}
Save this to application/helpers/ . We shall call it "new_helper.php"
The first line exists to make sure the file cannot be included and ran from outside the CodeIgniter scope. Everything after this is self explanatory.
Using the Helper
This can be in your controller, model or view (not preferable)
$this->load->helper('new_helper');
echo test_method('Hello World');
If you use this helper in a lot of locations you can have it load automatically by adding it to the autoload configuration file i.e. <your-web-app>\application\config\autoload.php.
$autoload['helper'] = array('new_helper');
-Mathew

Some code that allows you to use CI instance inside the helper:
function yourHelperFunction(){
$ci=& get_instance();
$ci->load->database();
$sql = "select * from table";
$query = $ci->db->query($sql);
$row = $query->result();
}

Well for me only works adding the text "_helper" after in the php file like:
And to load automatically the helper in the folder aplication -> file autoload.php add in the array helper's the name without "_helper" like:
$autoload['helper'] = array('comunes');
And with that I can use all the helper's functions

To create a new helper you can follow the instructions from The Pixel Developer, but my advice is not to create a helper just for the logic required by a particular part of a particular application. Instead, use that logic in the controller to set the arrays to their final intended values. Once you got that, you pass them to the view using the Template Parser Class and (hopefully) you can keep the view clean from anything that looks like PHP using simple variables or variable tag pairs instead of echos and foreachs. i.e:
{blog_entries}
<h5>{title}</h5>
<p>{body}</p>
{/blog_entries}
instead of
<?php foreach ($blog_entries as $blog_entry): ?>
<h5><?php echo $blog_entry['title']; ?></h5>
<p><?php echo $blog_entry['body']; ?></p>
<?php endforeach; ?>
Another benefit from this approach is that you don't have to worry about adding the CI instance as you would if you use custom helpers to do all the work.

Create a file with the name of your helper in /application/helpers and add it to the autoload config file/load it manually.
E.g. place a file called user_helper.php in /application/helpers with this content:
<?php
function pre($var)
{
echo '<pre>';
if(is_array($var)) {
print_r($var);
} else {
var_dump($var);
}
echo '</pre>';
}
?>
Now you can either load the helper via $this->load->helper(‘user’); or add it to application/config/autoload.php config.

Just define a helper in application helper directory
then call from your controller just function name like
helper name = new_helper.php
function test_method($data){
return $data
}
in controller
load the helper
$this->load->new_helper();
$result = test_method('Hello world!');
if($result){
echo $result
}
output will be
Hello World!

To retrieve an item from your config file, use the following function:
$this->config->item('item name');
Where item name is the $config array index you want to retrieve. For example, to fetch your language choice you'll do this:
$lang = $this->config->item('language');
The function returns FALSE (boolean) if the item you are trying to fetch does not exist.
If you are using the second parameter of the $this->config->load function in order to assign your config items to a specific index you can retrieve it by specifying the index name in the second parameter of the $this->config->item() function. Example:
// Loads a config file named blog_settings.php and assigns it to an index named "blog_settings"
$this->config->load('blog_settings', TRUE);
// Retrieve a config item named site_name contained within the blog_settings array
$site_name = $this->config->item('site_name', 'blog_settings');
// An alternate way to specify the same item:
$blog_config = $this->config->item('blog_settings');
$site_name = $blog_config['site_name'];

Related

How to Pass the Controller Data to JS File in CakePHP 3.0

In CakePHP 2.0, I've used the link below to pass controller data to a js file. However, I can longer use this method anymore as CakePHP 3.0 has removed js helper.
Is there a new technique for me to pass the controller data to a js file or alternative method beside using js helper with the link below?
http://www.php-dev-zone.com/2014/01/how-to-pass-controller-data-to-js-file.html
Relevant code:
public function beforeRender()
{
// We are Setting the jsvariables array which holds the
// variables that will be used in js files.
$this->set('jsVars', $this->_jsvariables);
}
<?php echo $this->Html->scriptBlock('var jsVars = '.$this->Js->object($jsVars).';'); ?>
Just check what the JsHelper::object() method was doing, and then do it manually.
https://github.com/cakephp/.../2.7.0/lib/Cake/View/Helper/JsBaseEngineHelper.php#L127
It's basically just a call to json_encode(), so simply replace the helper method call accordingly:
<?php echo $this->Html->scriptBlock('var jsVars = ' . json_encode($jsVars) . ';'); ?>

Codeigniter - Accessing variables from a helper file - not a class

I have a helper file, it has a variable that I want to pass across to a view, but it comes across as empty, so I am a bit unsure if I have the right code or I have overwritten it later on _ though I am sure I have not!
anyway say the variable in ther helper file is an array that contains a list of data, and I use:
$this->load->helper('helperfile_helper'); //contains the variable 'productList'
$data['productList'] = $productList;
$this->load->view('page', $data);
I would expect that the helper file works like an 'include' with the defined variables available once the helper has been called, is this the casee or have I missed something??
Helpers allow you to use function in your controller, have a look here: http://ellislab.com/codeigniter%20/user-guide/general/helpers.html
So you must create a function in your helper file that will return a value.
For example in your helper:
if( ! function_exists('random_number'))
{
function random_number()
{
return 4;
}
}
and in your controller you can use it:
$this->load->helper('helperfile_helper'); //contains the variable 'productList'
$data['random_number'] = random_number();
$this->load->view('page', $data);
So $data['random_number'] will contain 4

Unset the variables of a view for sub-views in codeigniter

Controller
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Main extends CI_Controller
{
public function index()
{
$this->load->model('Event');
$todays_events = $this->Event->get_todays_events();
$data = array(
'todays_events' => $todays_events
);
$this->load->view('main/index', $data);
}
}
?>
main/index view
<?php $this->load->view('partial/header'); ?>
<?php $this->load->view('components/calendar/mon_to_wed'); ?>
<?php $this->load->view('partial/footer'); ?>
components/calendar/mon_to_wed
(Has access to $todays_events, why is this?)
<div id="calendar_today">
<h1>Whats Happening</h1>
<?php foreach($todays_events as $event) : ?>
<?php var_dump($event); ?>
<?php endforeach; ?>
</div>
I've read the CodeIgniter core files, while hacking the core may solve this issue, another method exists that help to prevent defining variables in inner-views.
In the first view file, do this instruction:
foreach ($_ci_vars as $key => $value) $_ci_vars[$key]=NULL;
$this->load->view('your-inner-view', $_ci_vars);
$this->load->view('your-second-inner-view', $_ci_vars);
$this->load->view('your-third-inner-view', $_ci_vars);
// and so on...
I'll update my post, if I find a better solution
UPDATE:
Finally! I found the real solution, it is better to make your own Loader class instead of using default one. do the instructions below:
Copy Loader.php class from /system/core/ to your /application/core/
Find $this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars); at line #805
change/replace that line to $this->_ci_cached_vars = $_ci_vars;
CodeIgniter has a variable cashing, once you use load->view() method, the variables will be cached in an array, and the second using of load->view() caused to merge cached variables and new variables if exists and then cache the result as a new array (which contains the old variables).
So, stop using of array_merge() would be the solution ;)
The given answer might work for single views, when assembling a view out of multiple sub-views, any data for the overall view gets deleted by the above fix.
What works for me is to explicitly set those data items for the sub-view to null if they are not needed.
For instance the sub-view expects $a, $b and $c.
The first time we render the sub-view we pass $data['a'=>'whatever', 'b'=>'whatever', 'c'=>'whatever'] and the view is rendered correctly.
The second time we pass $data['a'=>'whatever'], $b and $c get rendered in the sub-view with the data from the first call.
If instead we pass $data['a'=>'whatever', 'b'=>null, 'c'=>null], b and c do not get rendered in the sub-view.
This is of course assuming you are checking whether the data is null before you use it in the sub-view.

CodeIgniter default layout problem: How can i create a default layout for whole project in CodeIgniter_2.0.2?

I want to create a default layout for whole codeigniter project. (like cakephp)
I also need to pass value from database (through controller) to default layout.
How can i do this ?
You can use the hooks to achieve this
post_controller - You can set vars with this.
Called immediately after your controller is fully executed.
display_override - You can override display and include your own view.
Overrides the _display() function, used to send the finalized page to the web browser at the end of system execution. This permits you to use your own display methodology. Note that you will need to reference the CI superobject with $this->CI =& get_instance() and then the finalized data will be available by calling $this->CI->output->get_output()
reference : http://codeigniter.com/user_guide/general/hooks.html
You can consider using a template system. For example Template library
The CodeIgniter wiki is a great place to look for this type of help.
For example, here are four different approaches to achieve what you want to do.
Actually there's a very simple solution that you can use. This is a micro-library that I have written for using layouts in CodeIgniter :
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Layout {
protected $CI;
public function __construct() {
$this->CI =& get_instance();
}
/**
* This method loads either the default layout (defined in the config.php file with the key default_layout) or a specific layout
* #param string $view
* #param array $params
* #param string $layout
*/
public function load_layout($view, $params = array(), $layout = "") {
// get the name of the layout file
$layout_file = file_exists(dirname(__FILE__) . "../views/" . $layout) ? $layout : $this->CI->config->item("default_layout");
// load it, transmit the params
$this->CI->load->view(
$layout_file,
array(
"view_name" => $view,
"view_params" => $params
)
);
}
?>
Add this file to your project in a Layout.php file, then just go to your config file and add the following line :
$config['default_layout'] = "your-default-layout-name.php";
And finally create a new file into the application/views folder of your project and name it with the value you put into your config file i.e. your-default-layout-name.php. Paste all the contents of the basic structure of your pages and add in the main wrapper :
<?php
// load required view
if (isset($view_name)) {
$this->load->view(
$view_name, $view_params
);
}
?>
Okay ! now you can simply replace the native :
$this->load->view("view-name.php", $params);
by :
// load the default layout
$this->layout->load_layout("view-name.php", $params);
// load a specific layout
$this->layout->load_layout("view-name.php", $params, "my-specific-layout.php");
And it will work like a charm !
Note: do not forget to include the library, either in you autoload.php file or directly in your script.

Two controllers for one view, CodeIgniter?

Hey guys, I am new to CodeIgniter and need some help. I have a controller that formats the content area of a post. The problem is that I also need to create a sidebar that contains dynamic groups, and a right column that contains recent posts. This isn't hard, the problem I'm running into is that I want the sidebar, and right column on every page, and I don't want to recode the same bits to get the data in every controller.
What would be the best way to do this without copy/paste?
There are a lot of ways to do this.
1) Templating: This is my preference for most cases (because my templates are complex), I render my view into a variable using something like:
$content = $this->load->view('myview', $page_data, true);
Then I load it into the template parser (fyi you could load it into another view too) like this:
$this->load->library('parser');
$data = array(
'page_title' => 'My Page Title',
'page_content' => $content,
'side_bar' => side_bar(), // function which generates your side bar
'right_col' => right_col() // function which generates your right column
);
$this->parser->parse('my_template', $data);
Then your template is like:
<html>
<head>
<title>{page_title}</title>
</head>
<body>
<div>{side_bar}</div>
<div>{page_content}</div>
<div>{right_col}</div>
</body>
</html>
2) Load another view in your view: (assumes you menu is a view not a controller) Something like this:
<?php $this->load->view('menu_view'); ?>
3) PHP Includes: exactly how you would do it in plain PHP (just include a url which points to a controller which returns a menu), Something like this:
<?php include("/common/sidebar"); ?>
Codeigniter will render that page and then include it.
4) AJAX.. i use this if the content in the "template" content is less important, like banners, suggested related item lists and such.
Use PHP to generate a static HTML page, such as side_bar.html...
Then you can include it on other pages.
You could look into HMVC. It's especially suited for "widget"-type areas like you are talking about.
Essentially what you will do is create two full MVC structures - one for your sidebar and right column, including a controller, a model(if required), and a partial view. Then, you can call this controller directly from the main view to pull the required content in to the page.
To actually call it from within a view, just place the following in the markup wherever you want the sidebar to appear:
<?php echo modules::run('module/sidebar/index'); ?>
The index isn't required, but I put it there to demonstrate that you can call different methods using modules::run(). You can also pass an unlimited number of parameters to modules::run().
In code igniter, there is an optional third parameter to $this->load->view that lets you return a rendered view as a string, which can in turn be used for assignment. What you can do is create a master template, that has all the common parts, as a very simplified example:
<html>
<head>
</head>
<body>
<?php echo $sidebar; ?>
<?php echo $content; ?>
<?php echo $right_column; ?>
</body>
</html>
Then you can create a private function in your controller to populate the dynamic content of your common parts, and combine them with your content and master template:
private function BuildTemplate($view, $data) {
// Generate sidebar content
$sidebar_data['...'] = 'blah blah';
$master_data['sidebar'] = $this->load->view('sidebar', $sidebar_data, true);
// Generate right column data
$right_data['...'] = 'blah blah';
$master_data['right_column'] = $this->load->view('right_column', $right_data, true);
// Now load your content
$master_data['content'] = $this->load->view($view, $data, true);
// Merge it into the master template and return it
return $this->load->view('master' $master_data, true);
}
Then in your appropriate controller method:
public function index() {
$data['...'] = 'blah';
echo $this->BuildTemplate('index', $data);
}
Which will pull everything together for you. You can optionally add extra arguments to BuildTemplate if you want to add things like page specific titles or scripts.
I'm not sure if your problem is in the view, or in the (dynamic) data to be shown in the (common parts of) that view.
If it's the later (as seems to suggest the phrase 'I don't want to recode the same bits to get the data in every controller'), then you have several options. For example.
Put the logic to get the 'common' data in some function outside the controller, as a helper or inside some model, and call it from your controllers.
Make your controllers inherit your own custom controller, that implements that data gathering function.
Refactor your two controllers into a single controller, with different functions for each scenario.
1-Create a custom library class in library folder with the below code
if (!defined('BASEPATH')) exit('No direct script access allowed');
class LoadView{
function __construct(){
$this->CI =& get_instance();
}
function load_view($page){
$this->CI->load->view('header');
$this->CI->load->view('sidebar');
$this->CI->load->view($page);
$this->CI->load->view('footer');
}
}
2-Now load this library in your controller like this
$this->load->library('loadview');
3-Now call the library method and simply insert your page name and you don't have to include header,sidebar and footer again and again as they will be dynamically included by your library.
$this->loadview->load_view('about.php');

Categories