Codeigniter simplicity with Laravel performance - Support PHP 7.4, 8.0, 8.1 Tested in production despite some notifications everything works without problems.
Download LaraCode
git clone https://github.com/humolot/LaraCode.git
cd LaraCode
composer install --ignore-platform-reqs
configure .env.development /.env.production
JWT
- Six algorithms supported:
'HS256', 'HS384', 'HS512', 'RS256', 'RS384', 'RS512'
kid
support.- Leeway support 0-120 seconds.
- Timestamp spoofing for tests.
- Passphrase support for
RS*
algos.
use Ahc\Jwt\JWT;
// Instantiate with key, algo, maxAge and leeway.
$jwt = new JWT('secret', 'HS256', 3600, 10);
Only the key is required. Defaults will be used for the rest:
$jwt = new JWT('secret');
// algo = HS256, maxAge = 3600, leeway = 0
For
RS*
algo, the key should be either a resource like below:
$key = openssl_pkey_new([
'digest_alg' => 'sha256',
'private_key_bits' => 1024,
'private_key_type' => OPENSSL_KEYTYPE_RSA,
]);
OR, a string with full path to the RSA private key like below:
$key = '/path/to/rsa.key';
// Then, instantiate JWT with this key and RS* as algo:
$jwt = new JWT($key, 'RS384');
Pro You dont need to specify pub key path, that is deduced from priv key.
Generate JWT token from payload array:
$token = $jwt->encode([
'uid' => 1,
'aud' => 'http://site.com',
'scopes' => ['user'],
'iss' => 'http://api.mysite.com',
]);
Retrieve the payload array:
$payload = $jwt->decode($token);
Oneliner:
$token = (new JWT('topSecret', 'HS512', 1800))->encode(['uid' => 1, 'scopes' => ['user']]);
$payload = (new JWT('topSecret', 'HS512', 1800))->decode($token);
Pro
Can pass extra headers into encode() with second parameter:
$token = $jwt->encode($payload, ['hdr' => 'hdr_value']);
Spoof time() for testing token expiry:
$jwt->setTestTimestamp(time() + 10000);
// Throws Exception.
$jwt->parse($token);
Call again without parameter to stop spoofing time():
$jwt->setTestTimestamp();
$jwt = new JWT(['key1' => 'secret1', 'key2' => 'secret2']);
// Use key2
$token = $jwt->encode(['a' => 1, 'exp' => time() + 1000], ['kid' => 'key2']);
$payload = $jwt->decode($token);
$token = $jwt->encode(['a' => 1, 'exp' => time() + 1000], ['kid' => 'key3']);
// -> Exception with message Unknown key ID key3
Obtain API keys from the Digital Ocean Applications & API dashboard
use SpacesAPI\Spaces;
// Connect to a space
$spaces = new Spaces('api-key', 'api-secret');
$space = $spaces->space('space-name');
// Download a file
$file = $space->file('remote-file-1.txt');
$file->download('local/file/path/file.txt');
// Upload text to a file
$file2 = $space->uploadText("Lorem ipsum","remote-file-2.txt");
// Get a signed public link, valid for 2 hours
$file2url = $file2->getSignedURL("2 hours");
// Make a copy
$file3 = $file2->copy('remote-file-3.txt');
// Make a file public and get the URL
$file3->makePublic();
$file3url = $file3->getURL();
Use the credentials from your Pusher Channels application to create a new Pusher\Pusher
instance.
$app_id = 'YOUR_APP_ID';
$app_key = 'YOUR_APP_KEY';
$app_secret = 'YOUR_APP_SECRET';
$app_cluster = 'YOUR_APP_CLUSTER';
$pusher = new Pusher\Pusher($app_key, $app_secret, $app_id, ['cluster' => $app_cluster]);
The fourth parameter is an $options
array. The additional options are:
scheme
- e.g. http or httpshost
- the host e.g. api.pusherapp.com. No trailing forward slashport
- the http portpath
- a prefix to append to all request paths. This is only useful if you are running the library against an endpoint you control yourself (e.g. a proxy that routes based on the path prefix).timeout
- the HTTP timeoutuseTLS
- quick option to use scheme of https and port 443.cluster
- specify the cluster where the application is running from.encryption_master_key
- a 32 char long key. This key, along with the channel name, are used to derive per-channel encryption keys. Per-channel keys are used encrypt event data on encrypted channels.
For example, by default calls will be made over HTTPS. To use plain HTTP you can set useTLS to false:
$options = [
'cluster' => $app_cluster,
'useTLS' => false
];
$pusher = new Pusher\Pusher($app_key, $app_secret, $app_id, $options);
Image manipulation doesn't have to be hard. Here are a few examples on how this package makes it very easy to manipulate images.
use Spatie\Image\Image;
// modifying the image so it fits in a 100x100 rectangle without altering aspect ratio
Image::load($pathToImage)
->width(100)
->height(100)
->save($pathToNewImage);
// overwriting the original image with a greyscale version
Image::load($pathToImage)
->greyscale()
->save();
// make image darker and save it in low quality
Image::load($pathToImage)
->brightness(-30)
->quality(25)
->save();
// rotate the image and sharpen it
Image::load($pathToImage)
->orientation(90)
->sharpen(15)
->save();
- Need more then one database connection ??
You can have more then one database in your application and you can use them simultaneously in your app just like Codeigniter Active Data Record.
- Open application/config/mongo_db.php file and create one more database group inside that file. For example:
$config['mongo_db']['newdb']['hostname'] = 'localhost';
$config['mongo_db']['newdb']['port'] = '27017';
$config['mongo_db']['newdb']['username'] = 'username';
$config['mongo_db']['newdb']['password'] = 'password';
$config['mongo_db']['newdb']['database'] = 'database';
$config['mongo_db']['newdb']['db_debug'] = TRUE;
$config['mongo_db']['newdb']['write_concerns'] = (int)1;
$config['mongo_db']['newdb']['journal'] = TRUE;
$config['mongo_db']['newdb']['read_preference'] = NULL;
$config['mongo_db']['newdb']['read_preference_tags'] = NULL;
You can change group name from "newdb" to anything else you want. After changing the group name, save the file.
- Now open your controller or model file, where you need another database connection active and write below code in the constructor of the class.
$this->load->library('mongo_db', array('activate'=>'newdb'),'mongo_db2');
This will make new connection on new mongoDB and make it available to use as $this->mongo_db2-> inside class
insert
Insert a new document into a collectionbatch_insert
Insert multiple new documents into a collection
select
Get select fields from returned documentswhere
ORget_where
Where section of the querywhere_in
Where something is in an array of somethingwhere_in_all
Where something is in all of an array of * somethingwhere_not_in
Where something is not in array of somethingwhere_or
Where something is based on orwhere_gt
Where something is greater than somethingwhere_gte
Where something is greater than or equal to somethingwhere_lt
Where something is less than somethingwhere_lte
Where something is less than or equal to somethingwhere_between
Where something is in between to somethingwhere_between_ne
Where something is in between and but not equal to somethingwhere_ne
Where something is not equal to somethinglike
Where something is search by like queryorder_by
Order the resultslimit
ORoffset
Limit the number of returned resultscount
Document Count based on where querydistinct
Retrieve a list of distinct values for the given key across a single collectionfind_one
Retrieve single document from collection
set
Sets a field to a valueunset_field
Unsets a fieldaddtoset
Adds a value to an array if doesn't existpush
Pushes a value into an array fieldpop
Pops a value from an array fieldpull
Removes an array by the value of a fieldrename_field
Rename a fieldinc
Increments the value of a fieldmul
Multiple the value of a fieldmax
Updates the value of the field to a specified value if the specified value is greater than the current value of the fieldmin
Updates the value of the field to a specified value if the specified value is less than the current value of the field.update
Update a single document in a collectionupdate_all
Update all documents in a collection
delete
Delete a single document in a collectiondelete_all
Delete all documents in a collection
aggregate
Perform aggregation query on document
output_benchmark
return complete explain data for all the find based query performed
add_index
Create a new index on collectionremove_index
Remove index from collectionlist_indexes
Show all index created on collections
switch_db
Switch to a different databasedrop_db
Drops a databasedrop_collection
Drops a collectioncommand
Perform MongoDB command
date
Create or convert date to MongoDB based Date
use Encryption\Encryption;
use Encryption\Exception\EncryptionException;
$text = 'The quick brown fox jumps over the lazy dog';
$key = 'secretkey';
try {
$encryption = Encryption::getEncryptionObject();
$iv = $encryption->generateIv();
$encryptedText = $encryption->encrypt($text, $key, $iv);
$decryptedText = $encryption->decrypt($encryptedText, $key, $iv);
printf('Cipher : %s%s', $encryption->getName(), PHP_EOL);
printf('Encrypted: %s%s', $encryptedText, PHP_EOL);
printf('Decrypted: %s%s', $decryptedText, PHP_EOL);
printf('Version : %s%s', Encryption::VERSION, PHP_EOL);
}
catch (EncryptionException $e) {
echo $e;
}
To get a list of ciphers supported by your system and this library you can call Encryption::listAvailableCiphers()
to receive an array of available ciphers. This list is an intersection of available ciphers from your system's
installed version of Openssl and ciphers supported by this library.
Total ciphers supported: 139
Default cipher: AES-256-CBC (version 1)
use Ozdemir\Datatables\Datatables;
use Ozdemir\Datatables\DB\CodeigniterAdapter;
class Welcome extends CI_Controller {
public function index()
{
$this->load->view('welcome_message');
}
public function ajax()
{
$datatables = new Datatables(new CodeigniterAdapter);
$datatables->query('Select film_id, title, description from film');
echo $datatables->generate();
}
}
This is the list of available public methods.
query($query) required
- sets the sql query
generate() required
- runs the queries and build outputs
- returns the output as json
- same as generate()->toJson()
toJson()
- returns the output as json
- should be called after generate()
toArray()
- returns the output as array
- should be called after generate()
add($column, function( $row ){})
- adds extra columns for custom usage
edit($column, function($row){})
- allows column editing
filter($column, function(){})
- allows custom filtering
- it has the methods below
- escape($value)
- searchValue()
- defaultFilter()
- between($low, $high)
- whereIn($array)
- greaterThan($value)
- lessThan($value)
hide($columns)
- removes the column from output
- It is useful when you only need to use the data in add() or edit() methods.
setDistinctResponseFrom($column)
- executes the query with the given column name and adds the returned data to the output with the distinctData key.
setDistinctResponse($output)
- adds the given data to the output with the distinctData key.
getColumns()
- returns column names (for dev purpose)
getQuery()
Eloquent: Getting Started Eloquent: Getting Started
Database: Getting Started Database: Getting Started
Step 1: Add this to your controller (should be before any of your code)
use chriskacerguis\RestServer\RestController;
Step 2: Extend your controller
class Example extends RestController
Here is a basic example. This controller, which should be saved as Api.php
, can be called in two ways:
http://domain/api/users/
will return the list of all usershttp://domain/api/users/id/1
will only return information about the user with id = 1
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
use chriskacerguis\RestServer\RestController;
class Api extends RestController {
function __construct()
{
// Construct the parent class
parent::__construct();
}
public function users_get()
{
// Users from a data store e.g. database
$users = [
['id' => 0, 'name' => 'John', 'email' => '[email protected]'],
['id' => 1, 'name' => 'Jim', 'email' => '[email protected]'],
];
$id = $this->get( 'id' );
if ( $id === null )
{
// Check if the users data store contains users
if ( $users )
{
// Set the response and exit
$this->response( $users, 200 );
}
else
{
// Set the response and exit
$this->response( [
'status' => false,
'message' => 'No users were found'
], 404 );
}
}
else
{
if ( array_key_exists( $id, $users ) )
{
$this->response( $users[$id], 200 );
}
else
{
$this->response( [
'status' => false,
'message' => 'No such user found'
], 404 );
}
}
}
}
use raelgc\view\Template;
The basic working of the template engine is based on the following idea: you have a PHP file (which will use the library), and this file will not contain any HTML code. The HTML code will be separated, in a file that will contain only HTML codes. This HTML file will be read by the PHP file. Incidentally, everything will be processed in the PHP file.
That said, let's go to the first example, the already familiar Hello world. Let's create 2 files: the PHP responsible for all the logic, and the HTML file with our layout.
Then, create an HTML file, called hello.html with the content below:
<html>
<body>
Hello PHP!
</body>
</html>
Usage
use raelgc\view\Template;
$tpl = new Template("hello.html");
$tpl->show();
Now for an important concept: template variables. As you can imagine, we're going to want to change various parts of the HTML file. How to do this? Simple: on the HTML side, you create so-called template variables. See the example below:
<html>
<body>
Hello {EXAMPLE}, PHP!
</body>
</html>
use raelgc\view\Template;
$tpl = new Template("hello.html");
$tpl->EXAMPLE = "LaraCode";
$tpl->show();
Template variables that do not have a value assigned will be cleared from the final generated code.
use raelgc\view\Template;
$tpl = new Template("hello.html");
$tpl->EXAMPLE = "LaraCode";
die("Value of Example: ".$tpl->EXAMPLE);
$tpl->show();
If you want to assign a value to a template variable, but you are not sure if the variable exists, you can use the exists() method to check.
use raelgc\view\Template;
$tpl = new Template("layout.html");
if($tpl->exists("EXAMPLE")) $tpl->EXAMPLE = "LaraCode";
$tpl->show();
This is the second and final concept you need to know about this template library: blocks.
Imagine that you would like to list the total number of products registered in a database. If there are no products, you will display a warning that no products were found.
We will then use two blocks: one that shows the total amount; and another that warns that there are no registered products, if the bank is really empty. The HTML code for this is:
<html>
<body>
<p>Number of products registered in the system:</p>
<!-- BEGIN BLOCK_NUMBERS -->
<div class="destaque">There are {QUANTITY} products registered.</div>
<!-- END BLOCK_NUMBERS -->
<!-- BEGIN BLOCK_EMPTY -->
<div class="vazio">There is no registered product.</div>
<!-- END BLOCK_EMPTY -->
</body>
</html>
The words BEGIN and END must always be capitalized. The block name must contain only letters, numbers or underscores.
And then, on the PHP side, let's check if the products exist. If so, we will show the BLOCK_NUMBERS
block. If not, we will display the BLOCK_EMPTY
block.
use raelgc\view\Template;
$tpl = new Template("hello.html");
$numbers = 5;
if($numbers > 0){
$tpl->QUANTITY = $numbers;
$tpl->block("BLOCK_NUMBERS");
}
else {
$tpl->block("BLOCK_EMPTY");
}
$tpl->show();
Notice that we only have one HTML table row for the product data, inside a block. Let's then assign value to these variables, and duplicate the content of the block as we list the products:
use raelgc\view\Template;
$tpl = new Template("hello.html");
$products = array(
array("name" => "Washing powder", "amount" => 15),
array("name" => "Toothbrush", "amount" => 53),
array("name" => "Toothpaste", "amount" => 37)
);
foreach($products as $p){
$tpl->NAME = $p["name"];
$tpl->AMOUNT = $p["amount"];
$tpl->block("BLOCK_PRODUCTS");
}
$tpl->show();
Let's now put together the 2 examples of using blocks that we saw: we want to show product data in a block, but if there are no products registered, we will display a message with a warning. Let's do this now using nested blocks, i.e. blocks inside other blocks:
<html>
<body>
<p>Products registered in the system:</p>
<!-- BEGIN BLOCK_PRODUCTS -->
<table border="1">
<tr><td>Name</td><td>Amount</td></tr>
<!-- BEGIN BLOCK_DATA -->
<tr>
<td> {NAME} </td>
<td> {AMOUNT} </td>
</tr>
<!-- END BLOCK_DATA -->
</table>
<!-- END BLOCK_PRODUCTS -->
<!-- BEGIN BLOCK_EMPTY -->
<div class="none">No records found.</div>
<!-- END BLOCK_EMPTY -->
</body>
</html>
And then, if there are products, we display the PRODUCTS
block. Otherwise, we display the EMPTY
block:
use raelgc\view\Template;
$tpl = new Template("hello.html");
$tpl->addFile("CONTENT", "content.html"); // header.html, footer.html etc.
$products = array(
array("name" => "Washing powder", "amount" => 15),
array("name" => "Toothbrush", "amount" => 53),
array("name" => "Toothpaste", "amount" => 37)
);
foreach($products as $p){
$tpl->NAME = $p["name"];
$tpl->AMOUNT = $p["amount"];
$tpl->block("BLOCK_DATA");
}
// If there are products, then we show the block with the data of all
if(isset($products) && is_array($products) && sizeof($products) > 0){
$tpl->block("BLOCK_PRODUCTS");
}
// Otherwise, we show the block with the warning of no registered
else {
$tpl->block("BLOCK_EMPTY");
}
$tpl->show();
?>
Let's assume that for some reason you need to keep a template variable in the final output of your HTML. For example: you are writing a system that automatically generates the templates for you.
For that, let's assume you have the HTML below:
<html>
<body>
{CONTENT}
</body>
</html>
And you need {CONTENT}
not to be replaced (or removed), but to remain in the final HTML.
To do this, escape by including {_}
inside the variable:
<html>
<body>
{{_}CONTENT}
</body>
</html>
Below are the meanings for the error messages displayed by the Template class:
-
Parse error: syntax error, unexpected T_STRING, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or '}'
: you are probably using PHP < 7 (see the requirements needed to use this library). -
addFile: var <varname> doesn't exist
: you are using the addFile() method to add an HTML file (or equivalent), but the template variable you want to put the content in does not exist. -
var <varname> does not exist
: you are trying to assign value to a variable that does not exist. Make sure that the name of the template variable is correct, and that you are using as the name of this variable only letters, numbers and underscore, between braces. -
file <filename> does not exist
: you are providing the path to an HTML file (or equivalent) that does not exist, or whose read permission is denied. -
file <filename> is empty
: the HTML file (or equivalent) you are passing as a parameter is empty. If it's empty, either you're entering a wrong file, or you forgot to put content in it. -
duplicate block: <blockname>
: the name you are trying to assign to the block has already been given to another block. Remember that the block name must be unique. If you are using more than one HTML file (or equivalent), the block with the same name as yours may be in one of the other files. -
block <blockname> is malformed
: the block you declared is defective. Maybe you used theBEGIN BLOCK
tag with one name, and ended up (theEND BLOCK
tag) with another. Or, you forgot theEND BLOCK
tag. Or you put theFINALLY BLOCK
tag in the wrong place. -
block <blockname> does not exist
: you are telling theblock()
method the name of a block that does not exist. Make sure that the block name is correct, and that you are using only letters, numbers and underscores as the name of this block. -
there is no method in class <classname> to access <object>-><property>
: there is no method to access the property you are calling. If you call in HTMLOBJECT->NAME
, this object's class must have a method called getName() or isName(). See more details in the "Using Objects" section.
use Ramsey\Uuid\Uuid;
$uuid = Uuid::uuid4();
printf(
"UUID: %s\nVersion: %d\n",
$uuid->toString(),
$uuid->getFields()->getVersion()
);
UUID: Getting Started UUID: Getting Started
LaraCode works with Codeigniter v3.1.13 full documentation + Eloquent + Laravel Database + Whoops + JWT + ResetApi Server + Spaces-API + Pusher Server + SpatieImage + MongoDb + PHP Encryption + Template Engine + phpspreadsheet + phpmailer + yidas.
You can start your multi tenant using helper domain.
Use codetisan to create your controllers, models and views
php index.php codetisan
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Please make sure to update tests as appropriate.