Welcome Guest, Not a member yet? Register   Sign In
Custom library available like CI3
#1

Hello,

How to initialize custom Library?
I have some class in Library, in namespace App\Libraries and get it by namespaces is pretty and works fine, but how to get/assign it to base controller. Somethink like CI3.


PHP Code:
$controller->{$library}->someMethodInLibrary(); 


And without modification in 'system' directory.


Thanks for advice.
Reply
#2

Here's one example. There are probably other ways and v4 development team members might be able to suggest more appropriate approaches. But this works.

This example is done using a fresh install of v4.
The only default value changed is that $baseURL in /application/Config/App.php is set with the testing server's URL.
No items are removed or added to the file /application/Config/Routes.php

Here's a very simple "library"

/application/Libraries/Test.php
PHP Code:
<?php namespace App\Libraries;

class 
Test
{
    protected 
$message;

    public function 
__construct()
    {
        
$this->message 'Greetings from the class <em>Test</em>.';
    }

    public function 
getMessage()
    {
        return 
$this->message;
    }



We will create an instance of this class and use the class method getMessge() in the controller Base

/application/Controllers/Base.php
PHP Code:
<?php namespace App\Controllers;

class 
Base extends \CodeIgniter\Controller
{
    
/**
     * @var \App\Libraries\Test instance of Test class
     */
    
protected $testLib;

    public function 
__construct(...$params)
    {
        
parent::__construct(...$params);
        
//create instance of "Test" class assign it to the controller's property
        
$this->testLib = new \App\Libraries\Test();
    }

    public function 
index()
    {
        
$data['title'] = 'Testing 1,2,3'//Browser tab text
        // Use the "Test" class
        
$data['message'] = $this->testLib->getMessage();
        
//show the view file
        
echo view('test_message'$data);
    }



The above controller can be used to extend other controllers and the property $testLib can be accessed in child classes using
$this->testLib.

The "view" is a hacked... er, revised version of welcome_message.php that comes with a clean install.

/applications/Views/test_message.php
Code:
<!doctype html>
<html>
    <head>
        <title><?= $title; ?></title>

        <link rel="shortcut icon" type="image/png" href="/favicon.ico"/>
    </head>
    <body>

        <style {csp-style-nonce}>
            div.logo {
                height: 200px;
                width: 155px;
                display: inline-block;
                opacity: 0.08;
                position: absolute;
                top: 2rem;
                left: 50%;
                margin-left: -73px;
            }
            body {
                height: 100%;
                background: #fafafa;
                font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
                color: #777;
                font-weight: 300;
            }
            h1 {
                font-weight: lighter;
                letter-spacing: 0.8;
                font-size: 3rem;
                margin-top: 145px;
                margin-bottom: 0;
                color: #222;
            }
            .wrap {
                max-width: 1024px;
                margin: 5rem auto;
                padding: 2rem;
                background: #fff;
                text-align: center;
                border: 1px solid #efefef;
                border-radius: 0.5rem;
                position: relative;
            }
            .version {
                margin-top: 0;
                color: #999;
            }
            .guide {
                margin-top: 3rem;
                text-align: left;
            }
            .msg{
                font-weight: bold;
            }
            pre {
                white-space: normal;
                margin-top: 1.5rem;
            }
            code {
                background: #fafafa;
                border: 1px solid #efefef;
                padding: 0.5rem 1rem;
                border-radius: 5px;
                display: block;
            }
            p {
                margin-top: 1.5rem;
            }
            .footer {
                margin-top: 2rem;
                border-top: 1px solid #efefef;
                padding: 1em 2em 0 2em;
                font-size: 85%;
                color: #999;
            }
            a:active,
            a:link,
            a:visited {
                color: #dd4814;
            }
        </style>

        <div class="wrap">

            <h1>Welcome to CodeIgniter</h1>

            <p class="version">version <?= CodeIgniter\CodeIgniter::CI_VERSION ?></p>

            <div class="logo">
                <svg version="1.0" xmlns="http://www.w3.org/2000/svg"
                     width="155.000000px" height="200.000000px" viewBox="0 0 155.000000 200.000000"
                     preserveAspectRatio="xMidYMid meet">
                <g transform="translate(0.000000,200.000000) scale(0.100000,-0.100000)" fill="#000000" stroke="none">
                <path d="M737 1963 c22 -79 -7 -185 -78 -290 -18 -26 -107 -122 -197 -213
                      -239 -240 -336 -371 -403 -544 -79 -206 -78 -408 5 -582 64 -134 212 -264 361
                      -314 l60 -20 -30 22 c-210 152 -229 387 -48 588 25 27 48 50 51 50 4 0 7 -27
                      7 -61 0 -57 2 -62 37 -95 30 -27 46 -34 78 -34 56 0 99 24 116 65 29 69 16
                      120 -50 205 -105 134 -117 233 -43 347 l31 48 7 -47 c13 -82 58 -129 250 -258
                      209 -141 306 -261 328 -405 11 -72 -1 -161 -31 -218 -27 -53 -112 -143 -165
                      -174 -24 -14 -43 -26 -43 -28 0 -2 24 4 53 14 241 83 427 271 482 486 19 76
                      19 202 -1 285 -35 152 -146 305 -299 412 l-70 49 -6 -33 c-8 -48 -26 -76 -59
                      -93 -45 -23 -103 -19 -138 10 -67 57 -78 146 -37 305 30 116 32 206 5 291 -27
                      89 -104 206 -162 247 -17 13 -18 12 -11 -15z"/>
                </g>
                </svg>
            </div>

            <div class="guide">
                <p>This example demonstrates one way to utilize a custom class
                    (a.k.a. library) in a CodeIgniter version 4.0-dev controller.</p>
                <p>The following message was provided by the custom class:
                    <span class="msg"><?= $message; ?></span></p>

                <p>The custom class used is found at:</p>
                <pre><code>application/Libraries/Test.php</code></pre>
                
                <p>If you would like to edit the view file you'll find it located at:</p>
                <pre><code>application/Views/test_message.php</code></pre>

                <p>The controller file for this page is found at:</p>
                <pre><code>application/Controllers/Base.php</code></pre>

            </div>

            <div class="footer">
                Page rendered in {elapsed_time} seconds. Environment: <?= ENVIRONMENT ?>
            </div>

        </div>
    </body>
</html>

Direct your browser to http://yoursite.com/base to see if all the pieces fit together and produce the expected output.
Reply
#3

(This post was last modified: 05-24-2018, 02:25 PM by Przem4S. Edit Reason: update code )

That very helpful - thank you.
I created by your idea simple library User - in this library I check by session if user is logged.
But I have second problem, when User is not logged then I try redirect him to login page by:


PHP Code:
return redirect()->to('/admin/user/login'); 

Do you have any idea how to redirect user from other place (non-controller, like library)?
Reply
#4

(This post was last modified: 07-09-2018, 09:58 AM by John_Betong.)

Many thanks for the complete, working example, it works a treat Smile 

I find it far easier to learn by modifying a working example than trying to understand new concepts from a manual. Afterwards I usually return to the manual with fresh knowledge and it usually makes more sense.

The only problem I had which was easily overcome was by adding the following to Routes.php (even before renaming the files?)
>>> $routes->add('/base',  'C_Base::index');

Modifications:
1. I prefer using uppercase wherever possible because it seems easier to separate my code from PHP scripts.
2. I also renamed all three files by adding prefixes... I know a little bit about reusing Class Methods with the same name but find it tremendously confusing.
3. I tried alternative methods of using extend and added resulting error messages where necessary.
4. The revised View  uses PHP highlight_file() to display contents of Library and Controller because it see the Library and Controller
5. Added DECLARE(strict_types=1); because it catches far more errors 


The revised View: 
PHP Code:
THIS IS THE VIEW
    
/home/john/www/ci4-test/application/Views/v_testMessage.php 
      
Library
->L_Test->_construct()->message ==> "Greetings from the class Test ."

Title
    Just Testing Extend 
Class 

File:./application/Views/
 
   /home/john/www/ci4-test/application/Views/v_testMessage.php 


      


/*
  BEGIN: PHP highlight_file('../application/Libraries/L_Test.php')
*/


<?php // file: ./application/Libraries/L_Test.php 

DECLARE(strict_types=1);  

NAMESPACE App\Libraries;

//=======================================================
CLASS L_Test
{
PROTECTED 
$message 'THIS MESSAGE IS OVER-WRITTEN';

//================================================
PUBLIC FUNCTION __CONSTRUCT()
// :string // ==> CANNOT DECLARE A RETURN TYPE
{
 
 $this->message = <<< ____TMP
    Library->L_Test->_construct()->message 
    ==> 
       "Greetings from the class <em> Test </em>."
____TMP;

}

//================================================
PUBLIC FUNCTION getMessage()
:
STRING
{
 
 return $this->message;
}

}
///
// ################### endof ../application/Libraries/L_Test.php  ################### 

/*
 END: PHP highlight_file('../application/Libraries/L_Test.php'); ############ 
*/




/*
 BEGIN: PHP highlight_file('../application/Controllers/C_Base.php'); ############ 
*/

//  PHP highlight_file('../application/Controllers/C_Base.php') 
<?php 
/*
  file: /Controllers/C_Base.php  
*/
DECLARE(strict_types=1);  

NAMESPACE App\Controllers;

USE 
CodeIgniter\Controller;

//=========================================================
# USE CodeIgniter\Controller;
# NO NEED TO use ABOVE STATEMENT
# CLASS C_Base extends \CodeIgniter\Controller
# {
# ...    
# ...    
# ...    
# }


//=========================================================
# ESSENTIAL TO use CodeIgniter\Controller;
# OTHERWISE
# ERROR: Class 'App\Controllers\Controller' not found
CLASS C_Base EXTENDS Controller 
{
/**
*   @var \App\Libraries\L_Test instance of C_Test class
*/

PROTECTED $testLib// CANNOT HAVE A DEFAULT VALUE


//=========================================================
PUBLIC FUNCTION __CONSTRUCT(...$params)
# PUBLIC FUNCTION __construct()
{
 
 PARENT :: __CONSTRUCT(...$params);
 
 # parent::__construct(); // ERROR: ArgumentCountError

 
 # create instance of "L_Test" Class Library
 
 # assign it to the Controller's property
 
 $this->testLib = NEW \App\Libraries\L_Test;
 
 # ADDING () IS OPTIONAL
 
 # $this->testLib = new \App\Libraries\L_Test();
}


//=========================================================
PUBLIC FUNCTION index()
:
STRING
{
 
 # Browser tab text  
 
 $data['title'] = 'Controller->C_Base->index()->title = "Testing 1,2,3"'

 
 # Use the "L_Test" extended class
 
 $data['message'] = $this->testLib->getMessage();

 
 # show the view file
 
 # echo view('v_testMessage', $data);
 
 return view('v_testMessage'$data);
}

}
/// 

/*
 END: PHP highlight_file('../application/Controllers/C_Base.php'); 
*/ 

I would be grateful if someone could explain the following syntax or a link with details:

>>>  __CONTRUCT(...$params)
Reply
#5

(07-09-2018, 09:54 AM)John_Betong Wrote: I would be grateful if someone could explain the following syntax or a link with details:

>>>  __CONTRUCT(...$params)

The ...$params takes all arguments given to the method and packs them into a new array called $params. Then, when passed back into parent::__construct(...$params) it unpacks the array so that the arguments are passed along as expected. Doing it this way allows you to not have to worry about the exact parameters in your own controllers.

I've been thinking about removing everything from the constructor so it's a little cleaner but haven't made any decisions on that just yet.
Reply
#6

FYI - I just pulled that requirement away from the Controller class, so we no longer use the constructor. That makes one less thing to remember when you make your controllers.
Reply
#7

(07-09-2018, 09:45 PM)kilishan Wrote: FYI - I just pulled that requirement away from the Controller class, so we no longer use the constructor. That makes one less thing to remember when you make your controllers.

Champion, keep it lean, mean no frills and allow users to easily add their own convoluted fancy stuff Smile

With a bit of luck it should also make less testing and the Alpha Release just that little bit sooner!

Keep up the good work.
Reply




Theme © iAndrew 2016 - Forum software by © MyBB