Giter Club home page Giter Club logo

tina4-php's Introduction

Tina4 is a light-weight routing and twig based templating system which allows you to write websites and API applications very quickly. Currently, the full deployment is under 8mb in size, and we are aiming at being the PHP framework with the smallest carbon footprint. Due to the nature of the code being very compact and all functionality engineered from the ground up we trust you will find it a pleasant experience.

Join us on Discord to be part of the journey.

The premise of the project is to make you the developer and PHP, the heroes!

PHP Composer

Installing

We are currently testing on latest PHP 8.2, please report any issues you may find.

  • Install PHP7.4 > make sure the following extensions are enabled: fileinfo, mbstring, curl, gd, xml.
  • Install Composer * Windows users must install openssl so that the JWT keys will be generated correctly
  • Create a project folder where you want to work
  • In your project folder terminal / console

Install with composer from terminal

composer require tina4stack/tina4php

Begin your Tina4 project using

composer exec tina4 initialize:run

Spin up a web server with PHP in your terminal in the project folder

composer start

Hit up http://localhost:7145 in your browser, you should see the documentation page

If you want to run the webservice on a specific port

composer start 8080

Database support

The ORM and database modules are all extracted into their own packagist modules. The ORM and database metadata work now using a more uniform mechanism. The service module now is created under bin and tina4 service and tina4 bin executables are replaced when their checksums change.

Database support table

Database Composer Command
Sqlite3 composer require tina4stack/tina4php-sqlite3
ODBC composer require tina4stack/tina4php-odbc
MySQL composer require tina4stack/tina4php-mysql
Firebird composer require tina4stack/tina4php-firebird
MongoDB composer require tina4stack/tina4php-mongodb
PostgreSQL composer require tina4stack/tina4php-postgresql
MSSQL composer require tina4stack/tina4php-mssql
PDO composer require tina4stack/tina4php-pdo

Features

  • Auto templating with TWIG
  • Auto inclusions & project structure
  • Open API Annotations for quick Swagger documentation & security
  • Annotation driven testing, write unit tests as you code
  • Tina4 ORM
  • Service Runner
  • Async triggers and events
  • Out of the box support for Swoole
  • Modular programming, each project is a potential module.

Run tests

composer test

Start service

composer start-service

Tina4 menu

composer tina4

Note The above command only seems to run on Linux and Mac

On Windows do the following:

php bin\tina4

Working with Docker

This requires you to have your docker environment already running

We assume /app is the internal path for the current project Installing

docker run -v $(pwd):/app tina4stack/php:latest composer require tina4stack/tina4php
docker run -v $(pwd):/app tina4stack/php:latest composer exec tina4 initialise:run

Upgrading

docker run -v $(pwd):/app -p7145:7145 tina4stack/php:latest composer upgrade 

Running

docker run -v $(pwd):/app -p7145:7145 tina4stack/php:latest composer start 

On a different port like 8080 for example

docker run -v $(pwd):/app -p8080:8080 tina4stack/php:latest composer start 8080

Quick Reference

The folder layout is as follows and can be overridden by defining PHP constants for TINA4_TEMPLATE_LOCATIONS , TINA4_ROUTE_LOCATIONS & TINA4_INCLUDE_LOCATIONS:

  • src
    • app (helpers, PHP classes)
    • public (system twig files, images, css, js)
    • orm (ORM objects - extend \Tina4\ORM)
    • routes (routing)
    • scss - style sheet templates
    • services (service processes - extend \Tina4\Process)
    • templates (app twig files)

.Env Configuration

Tina4 uses a .env file to set up project constants, a .env will be created for you when the system runs for the first time. If you specify an environment variable on your OS called ENVIRONMENT then .env.ENVIRONMENT will be loaded instead.

[Section]           <-- Group section
MY_VAR=Test         <-- Example declaration, no quotes required or escaping, quotes will be treated as part of the variable
# A comment        <-- This is a comment
[Another Section]
VERSION=1.0.0

Do not include your .env files with your project if they contain sensitive information like password, instead create an example of how it should look.

Example of Routing

Creating API end points and routers in Tina4 is simple as indicated below. If you are adding swagger annotations, simply hit up the /swagger end point to see the OpenApi rendering.

/**
* @description Swagger Description
* @tags Example,Route
*/
\Tina4\Get::add("/hello-world", function(\Tina4\Response $response){
    return $response ("Hello World!");
});

Routes can also be mapped to class methods, static methods are preferred for routing, but you can mix and match for example if you want to keep all functionality neatly together.

/**
 * Example of route calling class , method
 * Note the swagger annotations will go in the class
 */
\Tina4\Get::add("/test/class", ["Example", "route"]);

Example.php

class Example
{
    public function someThing() {
        return "Yes!";
    }
    
    /**
     * @param \Tina4\Response $response
     * @return array|false|string
     * @description Hello Normal -> see Example.php route
     */
    public function route (\Tina4\Response $response) {
        return $response ("OK!");
    }

}

Example of a database connection to SQLite3

You can add lines like this by using the tina4 tool or by pasting the example below into your index.php file.

global $DBA;
$DBA = new \Tina4\DataSQLite3("test.db");
  

Example of ORM Objects in relationship

class Address extends \Tina4\ORM
{
    public $id;
    public $address;
    public $customerId;

    //Link up customerId => Customer object
    public $hasOne = [["Customer" => "customerId"]];
}

class Customer extends \Tina4\ORM
{
    public $primaryKey = "id";
    public $id;
    public $name;

    //Primary key id maps to customerId on Address table
    public $hasMany = [["Address" => "customerId"]];
}

And some code using the above objects

$customer = (new Customer());
$customer->id = 1;
$customer->name = "Test";
$customer->save();

$address = (new Address());
$address->address = "1 Street";
$address->customerId = 1;
$address->save();

$customer = (new Customer());
$customer->addresses[0]->address = "Another Address";
$customer->addresses[0]->address->save(); //Save the address
$customer->load("id = 1");

$address = new Address();
$address->load("id = 1");
$address->address = "New Street Address";
$address->customer->name = "New Name for customer"
$address->customer->save(); //save the customer
$address->save();

Run tests from the command line

Give this a try and see what happens

composer test

Writing unit tests is easy and can be done as an annotation in your code comments

/**
 * Some function to add numbers
 * @tests
 *   assert (1,1) === 2, "1 + 1 = 2"
 *   assert is_integer(1,1) === true, "This should be an integer"
 */
function add ($a,$b) {
    return $a+$b;
}

Triggers and Events

Tina4Php supports a very limited threading or triggering of events using popen to execute and "thread" out triggered code. There are some caveats as the code cannot have comments in and only simple variables can be used. Other than that almost anything can be accomplished.

Example of a trigger and it firing:

//Example of the triggered event, notice the sleep timer which should shut down most code on windows or linux making PHP wait for the result.

\Tina4\Thread::addTrigger("me", static function($name, $sleep=1, $hello="OK"){
    $iCount = 0;
    while ($iCount < 10) {
        file_put_contents("./log/event.log", "Hello {$name} {$hello}!\n", FILE_APPEND);
        sleep($sleep);
        $iCount++;
    }
});

Here the trigger is fired on 2 routes, hit each one up in your browser to see the output in the event.log

\Tina4\Get::add("/test", function(\Tina4\Response $response){
    
    \Tina4\Thread::trigger("me", ["Again", 1, "Moo!"]);

    return $response("OK!");
});

\Tina4\Get::add("/test/slow", function(\Tina4\Response $response){

    \Tina4\Thread::trigger("me", ["Hello", 3]);

    return $response("OK!");
});

The output to the event.log file should happen asynchronously whilst the routes return back immediately to the user browsing.

Triggering deployments using git web hooks

There is a built-in path that will trigger a deployment from a github webhook on your system

https://<site-name>/git/deploy

This requires the following to be in your .env to work; and you will need to generate a secret to be shared between the systems. Additionally, you can specify directories from your repository to be included in your deployment with GIT_DEPLOYMENT_DIRS Make sure you give permissions to git on the system you deploy to if you work with a private repository.

[DEPLOYMENT]
GIT_TINA4_PROJECT_ROOT=.
GIT_BRANCH=master
GIT_REPOSITORY=https://github.com/tina4stack/tina4-php.git
GIT_SECRET=0123456789
GIT_DEPLOYMENT_STAGING=..\staging
GIT_DEPLOYMENT_PATH=deploy-test
GIT_DEPLOYMENT_DIRS=["branding", "bin"]
SLACK_NOTIFICATION_CHANNEL="general"

PhpDocs

docker run --rm -v %cd%:/data phpdoc/phpdoc:3 -d Tina4

Building the docker

docker build . -t tina4stack/php:7.4

Deploy the docker

 docker push tina4stack/php:7.4

Jquery validate cheat sheet

https://gist.github.com/rhacker/3550309

Todo

  • Add health check
  • Add GUID for each request, flow through to the rest of the code

If homebrew breaks after running a pecl install ext for some reason - zsh: killed php

sudo chown -R "$(id -un)":"$(id -gn)" /opt/homebrew

PHP info

Example of a PHP info route if needed.

Route::get("/phpinfo", function(Response $response){
  ob_start();
  phpinfo();
  $data = ob_get_contents();
  ob_clean();
  return $response($data, HTTP_OK, TEXT_HTML);
});

tina4-php's People

Contributors

andrevanzuydam avatar chrismeistre avatar clayton1717 avatar claytonk007 avatar crishigham avatar dependabot[bot] avatar francoisrob avatar huesamai avatar jacquestvanzuydam avatar justin-k-bruce avatar raees-b-19 avatar shaunroselt avatar theremastered1 avatar tina4stack avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

tina4-php's Issues

Tina4 CRUD - read only works on a single table

Context:
While I understand that CRUD is meant to do maintenance on a single table, when creating the CRUD for a linking table, just having ID's is not easily readable.
Problem:
It is easy enough to modify the CRUD code to add in a lookup table that allows a drop down for the fields, and allows them to replace the id in the grid form. However this then breaks the data table search and sorting feature as Tina4, when creating the search filter presumes that all fields are in the ORM table. The offending line on CRUD.php line 336 will give some insight as $tablePrefix is always t.
Solution:
It would be very useful for lookups to be available in CRUD, but requires a rewrite of the getDataTablesFilter(), and some other places. Please confirm, we can move in this direction and we can look at getting this fixed. Thanks

MySql syntax errors failing migrations

For Mysql, when there is an error in the sql syntax, it crashes the migration, rather than returning an error. It is failing on line 44 of the Tina4Database DataConnection.php. Called from line 25 in MySqlExec

First migrate/create fails

I think there is a bug in Tina4. To replicate, create a new project with a mysql database. The first migration/create fails on line 62 of DataResult.php as it tries to count a null (there were no records) . I am not going to put in a fix, as I am not sure where you want it changed in the DataResult or in the DataMySql. Hope I am not wrong, but I have spent some time on it.

Swagger - example object for GET

using the @example object for GET api endpoints breaks the swagger curl. Need to create and @responseexample tag to enable and example object to be provided in the swagger example field for API endusers to understand what will be retured from a GET.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.