• 1 Vote(s) - 4 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Solved] Codeigniter: Load Library in a Core Class

#1
Question 
Hey everbody!

I want to extend the /system/core/Log.php library with a couple of functions. One function should send a mail in case of an error via the custom function sendMail() which is part of the Custom_library.php.

Thus, I created the file /application/core/MY_Log.php

PHP Code:
class MY_Log extends CI_Log {
 
 public function __construct()
 
 {
 
   parent::__construct();
 
 }

 
 public function write_log($level$msg)
 
 {
 
   $result parent::write_log($level$msg);

 
   return $result;
 
 }


The problem: I'm not able to load the Custom_library.php. None of these approaches worked:

PHP Code:
//approach 1    
$this->load->library('Custom_library');

//approach 2  
$CI =& get_instance();
$CI->load->library('Custom_library'); 

Error message of the approach 2:
Code:
Fatal error: Uncaught Error: Class 'CI_Controller' not found in /home/gp/public_html/system/core/CodeIgniter.php:366 Stack trace: #0 /home/gp/public_html/application/core/MY_Log.php(13): get_instance() #1 /home/gp/public_html/system/core/Common.php(478): MY_Log->write_log('error', 'Severity: error...') #2 /home/gp/public_html/system/core/Exceptions.php(105): log_message('error', 'Severity: error...') #3 /home/gp/public_html/system/core/Common.php(662): CI_Exceptions->log_exception('error', 'Exception: Clas...', '/home/gp/public...', 366) #4 [internal function]: _exception_handler(Object(Error)) #5 {main} thrown in /home/gp/public_html/system/core/CodeIgniter.php on line 366


The question: Is it possible to load and utilize a Library in a Core Class?

Merci!
Reply

#2
(10-31-2016, 02:40 PM)SirGecco Wrote: The question: Is it possible to load and utilize a Library in a Core Class?

Merci!

You could use require_once('path/to/Custom_library.php')
Reply

#3
(11-01-2016, 01:48 AM)pdthinh Wrote:
(10-31-2016, 02:40 PM)SirGecco Wrote: The question: Is it possible to load and utilize a Library in a Core Class?

Merci!

You could use require_once('path/to/Custom_library.php')

Thanks for your input. Unfortunately this approach provokes further error messages:
Message:

PHP Code:
A PHP Error was encountered

Severity
Notice

Message
Undefined propertyStellen_controller::$bestjob_library

Filename
controllers/Stellen_controller.php

Line Number
32

Backtrace
:

File: /home/gp/public_html/application/controllers/Stellen_controller.php
Line
32
Function: _error_handler

File
: /home/gp/public_html/application/controllers/Stellen_controller.php
Line
19
Function: controller

File
: /home/gp/public_html/index.php
Line
327
Function: require_once 

The undefined property Stellen_controller calls function which are part of the Custom_library.php.
Reply

#4
PHP Code:
//approach 2  
$CI =& get_instance();
$CI->load->library('log'); 
What did you Try? What did you Get? What did you Expect?

Joined CodeIgniter Community 2009.  ( Skype: insitfx )
Reply

#5
(11-01-2016, 03:09 AM)InsiteFX Wrote:
PHP Code:
//approach 2  
$CI =& get_instance();
$CI->load->library('log'); 

Thank you for your input.

PHP Code:
$CI =& get_instance(); 


Already causes an error message:

PHP Code:
Fatal errorUncaught Error: Class 'CI_Controller' not found in /home/gp/public_html/system/core/CodeIgniter.php:366 Stack trace#0 /home/gp/public_html/application/core/MY_Log.php(14): get_instance() #1 /home/gp/public_html/system/core/Common.php(478): MY_Log->write_log('error', 'Severity: error...') #2 /home/gp/public_html/system/core/Exceptions.php(105): log_message('error', 'Severity: error...') #3 /home/gp/public_html/system/core/Common.php(662): CI_Exceptions->log_exception('error', 'Exception: Clas...', '/home/gp/public...', 366) #4 [internal function]: _exception_handler(Object(Error)) #5 {main} thrown in /home/gp/public_html/system/core/CodeIgniter.php on line 366
Fatal errorUncaught Error: Class 'CI_Controller' not found in /home/gp/public_html/system/core/CodeIgniter.php:366 Stack trace#0 /home/gp/public_html/application/core/MY_Log.php(14): get_instance() #1 /home/gp/public_html/system/core/Common.php(478): MY_Log->write_log('error', 'Severity: Error...') #2 /home/gp/public_html/system/core/Exceptions.php(105): log_message('error', 'Severity: Error...') #3 /home/gp/public_html/system/core/Common.php(627): CI_Exceptions->log_exception('Error', 'Uncaught Error:...', '/home/gp/public...', 366) #4 /home/gp/public_html/system/core/Common.php(698): _error_handler(1, 'Uncaught Error:...', '/home/gp/public...', 366) #5 [internal function]: _shutdown_handler() #6 {main} thrown in /home/gp/public_html/system/core/CodeIgniter.php on line 366 
Reply

#6
Where are you loading it from, it is stating that it can not find the Controller.
What did you Try? What did you Get? What did you Expect?

Joined CodeIgniter Community 2009.  ( Skype: insitfx )
Reply

#7
Here's the same answer I posted in response to your stackoverflow question.

I'd be interested in this community's thoughts on my answer.

*********

Extending CI_Log is not going to work if you need to access other libraries. The reason is CI_Log is created long before $CI is created so no "instance" is available for &get_instance() to return.

$this->load doesn't work because $this is not a controller ($this and $CI point to the same object in a controller) and the class load (CI_Loader) hasn't been created yet either.

There might be more than one way around this. Seems to me the least hacked way is to make your logger class utilize CI_Log instead of extend it.

application/libraries/Logger.php

PHP Code:
class Logger
{
 
   protected $CI;

 
   public function __construct()
 
   {
 
       $this->CI = & get_instance();
 
       $this->CI->load->library('custom_library');
 
   }

 
   public function write_log($level$msg)
 
   {
 
       //do stuff with "custom_library"
 
        $this->CI->custom_library->some_function();

 
       //use the built-in logging mechanism, a.k.a. CI_Log
 
       return log_message($level$msg);
 
   }



Your `logger' will need to be loaded in a Controller the same as any other library.

PHP Code:
$this->load->library('logger'); 

A usage example might be something like this

PHP Code:
$this->logger->write_log('error'"This is FUBAR"); 

By the time you call $this->load->library('logger'); the log class has been created and is part of $CI (a.k.a. $this). So this line

PHP Code:
   //use the built-in logging mechanism, a.k.a. CI_Log
 
   return log_message($level$msg); 

could be done this way instead

PHP Code:
   //use the built-in logging mechanism, a.k.a. CI_Log
 
   return $this->CI->log->write_log($level$msg); 

That would be marginally more efficient since all log_message does is call log->write_log anyway. I don't see any problem doing this instead of using log_message.
Reply

#8
(11-01-2016, 07:32 AM)InsiteFX Wrote: Where are you loading it from, it is stating that it can not find the Controller.

I'm loading it directly from the MY_Log.php

-----------------

(11-01-2016, 07:46 AM)dave friend Wrote: Here's the same answer I posted in response to your stackoverflow question.

I'd be interested in this community's thoughts on my answer.

Thank you very much for your input Dave - you're truly a good fellow. I tried your solution and it helped me to get more into the structure of codeigniter, which is great. Your example is running and working whenever e.g.
PHP Code:
$this->logger->write_log('error'"This is FUBAR"); 
is called. I'm not sure at the moment - but is it possible to extend your solution so that every caused error automatically calls the Logger Class? My aim would be to receive a mail for every error with severity 'error'.

Thank you!
Reply

#9
UPDATE:
I thought about the insights stated by dave.

For a current workaround I extended CI_Log as follows:

PHP Code:
class MY_Log extends CI_Log {
 
 public function __construct()
 
 {
 
   parent::__construct();
 
 }

 
 public function write_log($level$msg)
 
 {
 
   $result parent::write_log($level$msg);

 
   //include PHPMailer
 
   require_once(BASE_PATH.'application/libraries/PHPMailer/PHPMailerAutoload.php');

 
   //all the mail stuff
    $mail = new PHPMailer;

    $mail->CharSet "UTF-8";
    $mail->isSMTP();
    $mail->Host 'yoursmtp.server.com';
 
   $mail->send();
 
   //add user, password, etc

 
   return $result;
 
 }


As you can see, I used PHPMailer to send the error message via mail. All other mailing-stuff within CI libraries, views, controllers, etc are still handled by the build in CI Email library.

I'm not happy with the solution and would prefer to solve this without PHPMailer.
What do you guys think about the solution?
Reply

#10
The question I have is: Do you really want to send an email every time something is written to the log? Or, is there some particular process on your site that requires an email notification on error?
Reply


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


  Theme © 2014 iAndrew  
Powered By MyBB, © 2002-2020 MyBB Group.