I have the wrong path
I want to load dynamic classes
I Use this function
function settings($setting = 'General')
{
$settings = "App\Settings\\" . $setting . "Settings::class";
return app($settings);
}
I get an error
Target class [App\Settings\GeneralSettings::class] does not exist.
When I use this it works
app(App\Settings\GeneralSettings::class)
How can I fix that
Related
Want to check Environment and if matches some case then want to redirect or load some view. get_instance(); not working inside index.php where environment check
what i'm looking something like below:
if (ENVIRONMENT === "production")
{
/*if(error ="db error")
redirect("/someview","refresh");
or load view header and footer
*/
}
i just confused about error handling mechanism in CI. By the help of stackoverflow users i found steps to turn off the errors . but now i can't handle those errors.
If you want to handle a certain error, You can redirect it to a certain view in the process as what you have mentioned in your question.
// Assuming you have a [Home] Controller that extends to your [Common] parent class
class Home extends Common {
public function index()
{
$this->load->helper('url');
$bCheck = false;
if ($bCheck !== true) {
$this->handleRedirectMethod('path/to/your/controller');
}
}
}
Then on your parent [Common] controller. (e.g Common.php)
class Common extends CI_Controller
{
public function handleRedirectMethod($sUrl, $sMethodName = 'refresh', $sStatusCode = '302')
{
$sServerName = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'];
redirect($sServerName . '/' . $sUrl, $sMethodName, $sStatusCode);
}
}
Hope this makes you understand how you can handle those errors
I'm having a problem loading modules inside my template library in CodeIgniter HMVC. The reason I want to load a module in the template library is that I wish to use modules for sideboxes and other content boxes in my template.
PS: I am also using the Smarty template parsing system for CodeIgniter, but I doubt it has anything to do with the errors, but if you have reasons to believe otherwise, please, let me know.
What I tried to do
I tried to load the module in two different ways, and both presented with the same errors.
The errors
A PHP Error was encountered
Severity: Notice
Message: Undefined Property CI::$template
File: MX/Loader.php
Line Number: 141
-
A PHP Error was encountered
Severity: Notice
Message: Undefined Property CI::$template
Filename: MX/Controller.php
Line number: 57
-
Fatal error: Call to a member function load_content() on a non-object in E:\Xampp\htdocs\firecms\application\modules\sidebar_login_box\controllers\sidebar_login_box.php on line 7
The undefined "load_content()" function will be explained further down (in Sidebar Controller).
The Error lines
MX/Loader
/*Line 140*/if (isset($this->_ci_classes[$class]) AND $_alias = $this->_ci_classes[$class])
/*Line 141*/ return CI::$APP->$_alias;
MX/Controller
/*Line 56*/public function __get($class) {
/*Line 57*/ return CI::$APP->$class;
How I tried to load the modules
This was my first attempt (loading the file and instancing its class):
class Template {
//[...]
public function load_sidebars()
{
$sidebars = $this->CI->cms_model->get_sidebars();
foreach ($sidebars as $sidebar)
{
if (trim($sidebar["content"]) == "")
{
//An example of sidebar module name is "sidebar:login_box"
//The function below changes the name to "sidebar_login_box" (the
//module's folder and controller name.
$module = str_replace(':', '_', $sidebar["module"]);
$file_path = APPPATH.'modules/'.$module.'/controllers/'.$module.'.php';
require_once $file_path;
$class = ucfirst($module);
$object = new $class();
$module_data = $object->index();
$this->_section_data["sidebars"][]["content"] = $module_data;
}
else
{
$this->_section_data["sidebars"][]["content"] = $sidebar["content"];
}
}
}
//[...]
}
And this was my second attempt (using the loader function):
public function load_sidebars()
{
$sidebars = $this->CI->cms_model->get_sidebars();
foreach ($sidebars as $sidebar)
{
if (trim($sidebar["content"]) == "")
{
$module = str_replace(':', '_', $sidebar["module"]);
$this->CI->load->module($module);
$module_data = $this->CI->$module->index();
$this->_section_data["sidebars"][]["content"] = $module_data;
}
else
{
$this->_section_data["sidebars"][]["content"] = $sidebar["content"];
}
}
}
The sidebar controller
This is how the sidebar controller looks like:
class Sidebar_login_box extends Fire_Controller {
public function index()
{
$view_data = array();
//The load_content function in the template library is used to parse template files
//and return them as a string.
return $this->template->load_content("login_box", $view_data);
}
}
The Fire Controller
The Fire_Controller is my core controller. My core classes' prefix is Fire_ instead of MY_.
This is how the fire controller looks like:
class Fire_Controller extends MX_Controller {
public function __construct()
{
parent::__construct();
//Load configurations from the database.
$this->config->load_db_configs();
//Set the timezone.
date_default_timezone_set(config_item("timezone"));
//Loads the form validation library.
$this->load->library("form_validation");
//Reset the Form Validation CI Object (to fix problems with HMVC CI).
$this->form_validation->CI =& $this;
//To reduce load time, the template library will not be loaded in ajax
//requests.
if ( ! $this->input->is_ajax_request())
{
$this->load->library("template");
}
//Force access via SSL connection (HTTPS) if necessary.
if ((int)config_item('force_https') === 1)
{
force_https();
}
}
Note: This is a very recent project of mine, which means that the framework and all third party extensions are in the most recent stable version as of January 06, 2015.
Thank you for your time,
Best regards.
Fixed.
The sidebars were loaded from the set_defaults() method, which was called by the constructor method in my template library. And since it wasn't fully loaded, the template object was not saved in CI's super object, thus being inaccessible and throwing the errors in the sidebar module.
I have moved the set_defaults() call to the render_page() function of my template library (which are called by the modules' controllers), and now it's working perfectly.
Too bad I added bounty a few hours before finding the solution, hehe.
You need to load the library before you can use it in the sidebar controller. It isn't being passed from the parent. Try this:
class Sidebar_login_box extends Fire_Controller {
public function index()
{
$view_data = array();
$this->load->library('template');
//The load_content function in the template library is used to parse template files
//and return them as a string.
return $this->template->load_content("login_box", $view_data);
}
}
Cheers!
I have a custom module, and now want to call the add() function from checkout/cart. How do I call the controller and function?
I have tried $this->load->controller('checkout/cart'); but this returns a fatal exception.
I am using OpenCart v 1.5.6.4
In OpenCart 1.5.*, getChild is used to load other controllers. Specifically, it is running a route to the desired controller and function. For example, common/home would load the home controller from the common group/folder. By adding a third option we specify a function. In this case, 'add' - checkout/cart/add.
class ControllerModuleModule1 extends Controller {
protected function index() {
ob_start();
$this->getChild('checkout/cart/add');
$this->response->output();
$response = ob_get_clean();
}
}
Most controllers don't return or echo anything, but specify what to output in the $this->response object. To get what is being rendered you need to call $this->response->output();. In the above code $response is the json string that checkout/cart/add echos.
To solve the same issue, I use $this->load->controller("checkout/cart/add").
If I use getChild, this exception get thrown : "Call to undefined method Loader::getChild()".
What is the difference between the 2 methods? Is getChild better?
The problem with getChild() is it only works if the controller calls $this->response->setOutput() or echo at the end - producing actual output. If on the other hand, you want to call a controller method that returns a variable response, it isn't going to work. There is also no way to pass more than one argument since getChild() accepts only one argument to pass, $args.
My solution was to add this bit in 1.5.6.4 to system/engine/loader.php which allows you to load a controller and call it's methods in the same way as you would a model:
public function controller($controller) {
$file = DIR_APPLICATION . 'controller/' . $controller . '.php';
$class = 'controller' . preg_replace('/[^a-zA-Z0-9]/', '', $controller);
if (file_exists($file)) {
include_once($file);
$this->registry->set('controller_' . str_replace('/', '_', $controller), new $class($this->registry));
} else {
trigger_error('Error: Could not load controller ' . $controller . '!');
exit();
}
}
Now you can do this:
$this->load->controller('catalog/example');
$result = $this->controller_catalog_example->myMethod($var1, $var2, $var3);
I'm building a script that got a static class used to load few things including files and views.
class load
{
public static function view($file_path, $area)
{
debug::log('getting view <b>' . $area . $file_path . '</b>.');
ob_start();
self::file($file_path, 'areas/' . $area . '/views');
debug::log('flushing view <b>' . $area . $file_path . '</b>.');
eturn ob_get_clean();
}
public static function file($file, $folder)
{
if(is_file($file_path = ROOT . '/' . $folder . '/' . $file))
{
if(require_once $file_path)
{
debug::log('file <b>' . $file_path . '</b> included.');
return true;
}
}
else
debug::kill('requested file <b>' . $file_path . '</b> does not exist.');
}
}
In the controller Im calling the view method to get a view:
$html = load::view('public', 'path/to/view/file.php');
Obviously, Im not able to access the variables from the controller at the view file using this practice, so I did a small modification on the view class to capture the vars:
public static function view($file_path, $area, $vars = array())
And added the following lines of codes to get the keys into vars:
while(list($n_list_var,$v_list_var)=each($vars))
$$n_list_var = $v_list_var;
But again I can't access the vars since Im using a method to load a file.
I have a method to load the files because I wanna test and log each file include attempt and not repeat the code every time I need include a file. And I have the loader view inside the loader class so I have all the methods of this kind together. Should I give up on using a class to load files? Should I use the loader view method on a extendable class from my controller?
Instead of going ahead and modify my entire script I would like to hear some opinions ... what would be the best practice to go? Or is there a way to solve my problem? Maybe using __set and __get magic methods?
Thanks,
Why not just pass a $vars argument to load::file() and extract( $vars ) (possibly moving the vars you use inside file() into class variables to prevent them from being overwritten)?
I'm suggesting using extract() instead of:
while(list($n_list_var,$v_list_var)=each($vars))
$$n_list_var = $v_list_var;
By the way, it would be a good idea to name your class Load.
Example #1
bschaeffer'sanswer to this question - in his last example:
$this->load->model('table');
$data = $this->table->some_func();
$this->load->view('view', $data);
How do you handle this when 'table' doesn't exist?
Example #2
try {
$this->load->model('serve_' . $model_name, 'my_model');
$this->my_model->my_fcn($prams);
// Model Exists
} catch (Exception $e) {
// Model does NOT Exist
}
But still after running this (obvously the model doesn't exist - but sometimes will) it fails with the following error:
An Error Was Encountered
Unable to locate the model you have specified: serve_forms
I am getting this function call by:
1) Getting some JSON:
"model_1:{"function_name:{"pram_1":"1", "pram_2":"1"}}
2) And turning it into the function call:
$this->load->model('serve_' . "model_1", 'my_model');
3) Where I call:
$this->my_model->function_name(pram_1=1, pram_2=1);
SOLUTION
The problem lies in the fact that CodeIgniter's show_error(...) function displays the error then exit; ... Not cool ... So I overrode: model(...) -> my_model(..) (you'll get errors if you just override it) and removed the show_error(...) because for some reason you can't override it - weird for Codeigniter). Then in my_model(...) made it throw an Exception
My personal opinion: the calling function should return
show_error("message"); where show_error returns FALSE --- that or
you could take out the exit; - and make show_error(...)
overridable
You can see if the file exists in the models folder.
$model = 'my_model';
if(file_exists(APPPATH."models/$model.php")){
$this->load->model($model);
$this->my_model->my_fcn($prams);
}
else{
// model doesn't exist
}
Maybe this helper function will help you to check if a model is loaded or not.
function is_model_loaded($model)
{
$ci =& get_instance();
$load_arr = (array) $ci->load;
$mod_arr = array();
foreach ($load_arr as $key => $value)
{
if (substr(trim($key), 2, 50) == "_ci_models")
$mod_arr = $value;
}
//print_r($mod_arr);die;
if (in_array($model, $mod_arr))
return TRUE;
return FALSE;
}
source reference
Don't foget that your application may use pakages. This helper function look through all models (even in packages included in your CI app).
if ( ! function_exists('model_exists')){
function model_exists($name){
$CI = &get_instance();
foreach($CI->config->_config_paths as $config_path)if(file_exists(FCPATH . $config_path . 'models/' . $name . '.php'))return true;
return false;
}
}
Cheers
#Endophage No you do not have to explicitly state what the model you are loading will be. They can be loaded dynamically.
Example:
$path = 'path/to/model/';
$model = 'My_model';
$method = '_my_method';
$this->load->model($path . $model);
return $this->$model->$method();
So you could have a single controller that uses the URL or POST vars.
I use this concept a lot with ajax calls. So OP's question is very valid. I would like to make sure that the model exists before I try to load it.