A rewrited Scarlets framework for website based on PHP
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
evaluate
example
images
src
tests
.gitignore
.htaccess
.travis.yml
LICENSE
README.md
composer.json
composer.lock
net-install
phpunit.xml
require.php

README.md

Written by Software License Build Status Tweet

Scarlets

This framework still under development

Scarlets is a web framework for PHP that can help you build a website with API and another build-in system. This framework have a lazyload on it's system, so you can select which system that you want to use to keep your website in a high performance state.

Scarlets have a build-in traffic monitor for any hacking activity or another security problem. And it will suggest you a security option if you have a backdoor on your system.

Installation instruction

Clone/download this repository and put it on a folder Then copy the example folder and edit the framework path on root.php

Install by using command prompt

Make sure you have installed PHP on your computer (Windows and OSX can use XAMPP)
and make sure the php command is available on the command prompt

$ php -v

If not, then you need to set it up on the environment variables.

When the php command is available, open your command prompt and enter this line

$ php -r "copy('https://raw.githubusercontent.com/ScarletsFiction/Scarlets/master/net-install', 'net-install');"
$ php net-install

The framework will automatically installed, and the example files will be prepared on your project folder.

Upgrade

Scarlets have internal upgrade feature

$ php scarlets upgrade

But if there are any error and the framework was unable to be loaded
Please clone this repository and extract it to vendor/scarletsfiction/scarlets

Usage

Scarlets Console

This framework has a build-in server by calling

$ php scarlets serve (port) (address) (options)

Address: localhost, network, IPAddress
Options: --log, --verbose

alt text

You can also create your own command for your project

alt text

The user defined command are editable on /routes/console.php

Define command

Console::command(pattern, callback, info='');

Console::command('echo {*}', function($message){
    echo($message);
});

Use invisible writting

Console::hiddenInput();

Console::command('input', function(){
    echo("Type something invisible: ");
    print_r("Result: ".Console::hiddenInput());
}, 'Type something');

Change text color

Console::chalk(text, color);

Console::command('echo {*}', function($message){
    echo(Console::chalk("Computer> $message", 'yellow'));
});

Match more pattern

Console::args(pattern, callback);

Console::command('echo {*}', function($all){
    Console::args('{0} {1}', function($name, $message){
        echo("$name> $message");
    });

    // Check if args above was not being called
    if(!Console::$found)
        echo "Computer> $all";
});

Adding help section

Console::help(text, color);

Console::help('echo', "Type 'echo (anything here)' to get echo back.");

Clear console

Console::clear();

Check if running on console

Console::isConsole();

Obtain registered console command

Console::collection();

Arrange result as a table on console

Console::table(array);

WebRouter

This webrouter will help you route any URL Request
All route should be placed on /routes/ folder The router priority is:

  1. status.php (HTTP status)
  2. api.php (API Router)
  3. web.php (Web Router)

Route by Request Method

Route::get(pattern, callback, options=''); The accepted request method are get, post, delete, put, options.

The allowed match pattern are started with parameter index
And followed by:

  1. : (Regex)
  2. ? (Optional)

The parameter index for example below is 0 and the regex [A-Za-z]+

Route::get('/text/{0:[A-Za-z]+}', function($text = ['world']){
    // Serve::raw("Hello, $text[0]");
    return "Hello, $text[0]";
});

Serve views

The views folder are located on /resources/views/ folder

Serve::view(file, parameter);

Route::get('/', function(){
    Serve::view('hello', ['message' => 'World']);
}, 'name:home');

You can easily access the message parameter from target views like below

<p class="msg"> <?= $message ?> </p>

or maybe obtaining POST, GET request with

<p class="msg"> <?= $p['anything'] ?> </p>
<p class="msg"> <?= $q::post('anything') ?> </p>

If you're using frontend MVW framework, you can obtain dynamic view only by set isStatic to true for static view.

Namespace Router group

Route::namespace(namespace, callback);

Route::namespaces('App\Http\Controllers', function(){
    // Class controller at "App\Http\Controllers" Namespace

    // Call 'route' function on "User\Home" Class
    Route::get('/user/{0}', 'User\Home::route');
});

URL Prefix group

Route::prefix(prefix, callback);

Route::prefix('admin', function(){
    Route::get('users', function(){
        // Matches The "/admin/users" URL
        Serve::raw("Hi admin!");

        // Or route to User List
        Route::route('list.users');
    });
});

Router name group

Route::name(name, callback);

Route::name('list', function(){
    Route::get('users', function(){
        // Route assigned name "list.users"
        Serve::raw("User List");
    }, 'name:users');
});

Domain Router

Route::domain(domain, callback);

Route::domain('{0}.framework.test', function($domain){
    Route::get('/home/{0}', function($query){
        // Will be available on "*.framework.test" domain
    });
});

Middleware Router group

Route::domain(domain, callback);

Route::middleware('limit:2,60', function(){
    Route::get('limit', function(){
        Serve::raw("Limited request");
    });
});

// Or you could also set the middleware from request method's router
Route::get('limit', function(){
    Serve::raw("Limited request");
}, 'limit:2,60');

Registering middleware for router

Route\Middleware::$register['limit'] = function($request = 2, $seconds = 30){
    $total = Cache::get('request.limit', 0);

    if($total < $request){
        // Set expiration when it's the first request only ($total == 0)
        $expire = $total === 0 ? $seconds : 0;

        // Put the request count on cache
        Cache::set('request.limit', $total + 1, $expire);

        // Continue request
        return false;
    }

    // Block request
    else{
        Serve::status(404);
        return true;
    }
};

Library

Database

Before using this library, you must modify the database configuration on /config/database.php

Get database connection

$myDatabase = Scarlets\Library\Database::connect(databaseName='{default}');

Select table rows

$myDatabase->select(tableName, $columns, $where=[]);

$myDatabase->select('test', ['name', 'data'], {
    'OR'=>['id'=>123, 'words[~]'=>'hello'],
    'LIMIT'=>1
});
// SELECT name, data FROM test WHERE (id = ? OR (words LIKE ?)) LIMIT 1

The other database library documentation is almost similar with SFDatabase-js

Below are the undocumented library

The library documentation still in progress
If you're willing to help write this documentation I will gladly accept it

LocalFile system

You may need to assign the namespace to the top of your code

use \Scarlets\Library\FileSystem\LocalFile;

The filesystem configuration are stored on /config/filesystem.php.
Then you can pass {the storage name}/your/path to the LocalFile function.

load

Load contents from file

LocalFile::load(path);

$data = LocalFile::load('{app}/data/text.inf');

load, size, append, prepend, createDir, put, search, lastModified, copy, rename, move, delete, read, tail, zipDirectory, extractZip, zipStatus

Cache

You may need to assign the namespace to the top of your code

use \Scarlets\Library\Cache;

get

Cache::get(key, default=null);

The example below will return data from timestamp key
but if the key was not found or expired, then it will return
default value.

$data = Cache::get('timestamp', 0);
set

Cache::set(key, value, seconds=0);

The example below will set time() on timestamp key
and expired after 20 second.

$data = Cache::set('timestamp', time(), 20);

has, pull, forget, flush, extendTime

Crypto

You may need to assign the namespace to the top of your code

use \Scarlets\Library\Crypto;

The security configuration are stored on /config/security.php.
The default cipher will be used if the cipher parameter was false.

This library is using openssl php extension.
So make sure you have enabled it before use.
And the available cipher are listed on php documentation.

encrypt

Crypto::encrypt(text, pass=false, cipher=false, mask=false);

Set the mask parameter to true if you want to encode any symbol
to text. Make sure you have change default crypto_mask
on the configuration to improve security.

$data = Cache::encrypt('hello', 'secretcode', false, false);
// Output:
// Tst2nVw4sDMB5M5jwwSPiTp+Olh4QTRhek55YnF6VFdPUURYa1ZKbHc9PQ==
decrypt

Crypto::decrypt(encryptedText, pass=false, cipher=false, mask=false);

$data = Cache::decrypt('hello', 'secretcode');

Language

You may need to assign the namespace to the top of your code

use \Scarlets\Library\Language;

The default language are configured on /config/app.php.
And the languages files are located on /resources/lang/.

get

Language::get($key, $values = [], $languageID='')

$text = Language::get('time.current_date', [date('d M Y')], 'en');

Socket

You may need to assign the namespace to the top of your code

use \Scarlets\Library\Socket;

create

This function will open new socket server that able
to process multiple request at the same time.

Socket::create(address, port, readCallback, connectionCallback=0)

Socket::create('localhost', 8000, function($socketResource, $data){
    echo("Data received:");
    print_r($data);
}, function($socketResource, $status){
    echo("Someone $status");
});
simple

This function will open new socket server than able
to process single request at the a time.

Socket::simple(address, port, readCallback)

Socket::simple('localhost', 8000, function($socketResource, $data){
    echo("Data received:");
    print_r($data);
});
ping

Socket::ping(domain, port=80)

WebRequest

You may need to assign the namespace to the top of your code

use \Scarlets\Library\WebRequest;

loadURL

Web Request with curl extension

WebRequest::loadURL(url, data="")

$data = WebRequest::loadURL('https://www.google.com', [
    'ssl'=>false, // Skip ssl verification
    'header'=>['Some: header'],
    'post'=>['data' => 'anything'],
    /*
    'cookiefile'=>'path',
    'cookie'=>'urlencoded=data',
    'limitSize'=>10, // In KB
    'proxy'=>['ip' => '127.0.0.1', 'port' => 8000],
    'returnheader' => true // Return header only
    */
]);
giveFiles

From this server to client browser

WebRequest::giveFiles(filePath, fileName = null)

download

From other server to local file

WebRequest::download(from, to, type="curl")

receiveFile

From client browser to this server

WebRequest::receiveFile(directory, allowedExt, rename='')

Make sure you limit the allowed extension to
avoid security issue

allowedExt = ['css', 'js', 'png']

Accessing App Configuration

Get all configuration array reference

The sample below will return loaded configuration from /config/ folder

$config = Scarlets\Config::load('app'); /* (App folder)/config/app.php -> hostname value $config['app.hostname'] = 'localhost'; */

Debugging

Error warning

Scarlets\Error::warning('Something happen');

Log

Scarlets\Log::message('Something happen');

Register shutdown callback

Scarlets::onShutdown(callback);

The callback will be called when the framework is going to shutdown

Contribution

If you want to help in Scarlets framework, please fork this project and edit on your repository, then make a pull request to here.

Keep the code simple and clear.

Support

If you have any question please ask on stackoverflow with tags 'scarlets-php'.
But if you found bug or feature request, you post an issue on this repository.

For any private support, you can contact the author of this framework:
StefansArya (Indonesia, English)
stefansarya1 at gmail

License

Scarlets is under the MIT license.

Help improve this framework by support the author \(≧▽≦)/