/FrameworkJet

Light PHP Framework

Primary LanguagePHPMIT LicenseMIT

FrameworkJet - light web application framework

Logo

FrameworkJet is a web application framework created to cover the following requirements:

  • Low response time.
  • To work as light as possible, without additional heavy libraries and dependencies. It's up to you to add external libraries and helpers depending on your particular needs.
  • Server-side rendering of the content.
  • Client-side rendering of the content via communication with an API.
  • Multilingual templating.

Table of Contents

Used technologies

The following technologies and libraries have been used:

Front-end:

Back-end:

Server-side services:

  • composer
  • npm
  • grunt
  • npm task "handlebars" used for precompilation of the handlebar templates
  • npm task "uglify" used for javascript minimization
  • npm task "less" used for the compilation of LESS to CSS
  • npm task "sass" used for the compilation of SASS to CSS
  • npm task "clean" used to clean the cache directory used by Twig (php template engine)
  • npm task "watch" used to watch for changes in particular directories and files and if there are changes, it will automatically call the default grunt task which will call all other tasks (handlebars, uglify, less, sass, clean)*.

Server requirements

The framework has a few system requirements.

  • PHP >= 7.0
  • PHP cURL Extension
  • PDO PHP Extension

Installation

To install the framework, follow the steps below. During the installation we will use commands used in Unix based system, but for the sake of the detailed explanation, we have given a few examples for Windows based systems.

Checkout

Checkout the project on your machine:

git clone https://github.com/frameworkjet/FrameworkJet

For the current example, the name of the directory where we will clone and install the project is “example”.

Go to the directory of the project:

cd example

Services

Before we install any of the required services, we may want to update the file composer.json as it is shown below:

{
	“name”: “NAME-OF-THE-PROJECT/SUB-NAME-OF-THE-PROJECT”,
	“description”: “ADD YOUR OWN DESCRIPTION”,
	...
}

Example:

{
	“name”: “framework/framework”,
	“description”: “Client side of the framework”,
	...
}

Save and close.

Now we will have to install the following services:

Sometimes during the installation of grunt and the npm tasks it is possible to encounter errors and missing dependencies. A possible solution is to delete the folder “node_modules” and to start the process of installation again.

rm -R node_modules/

Configuration

Back-end application

Framework

Go to Config/App.php and set up the following lines:

...
return [
	...
	'DEFAULT_SYSTEM_ADMIN_EMAIL' => 'EMAIL-OF-THE-ADMINISTRATOR',
	'DEFAULT_URL' => 'URL-OF-THE-PUBLIC-WEBSITE'
];

Example:

...
return [
	...
	'DEFAULT_SYSTEM_ADMIN_EMAIL' => 'admin@dev.framework.com',
	'DEFAULT_URL' => 'https://dev.framework.com'
];

Save and close.

Third-party services

Go to Config/Services.php and set up the following:

...
return [
	'mail' => [
		<SETTINGS-USED-TO-SEND-EMAILS>
	],
	'api' => [
		'url' => 'API-URL',
		...
	]
];

Example:

...
return [
	...
	'api' => [
		'url' => 'https://dev-api.framework.com',
		...
	]
];

Save and close.

The mail section is dedicated for the mail server which you may need to send emails. The api section is dedicated for the URL address and the output data format used to make calls to an external RESTful API.

Cache

Go to Config/Cache.php. This file contains the credentials required by the framework to connect to the Memcached server.

Database

Go to Config/SqlDatabase.php. This file contains the credentials required by the framework to connect to the SQL server.

Front-end application

Go to public/js/config.js and set up the following:

...
	"data_manager": {
        "main": "URL-OF-THE-PUBLIC-WEBSITE",
        "api": "URL-OF-THE-API"
	},
...

Example:

...
	"data_manager": {
        "main": "https://dev.framework.com",
        "api": "https://dev-api.framework.com"
	},
...

Save and close.

Gitignore

When we finish with your configurations, you can add the config files to .gitignore which will protect them to be rewritten. Add this to .gitignore:

	/Config/App.php
	/Config/Services.php
	/public/js/config.js

File permissions

Execute the following:

chmod -R 0755 example/
chown -R www-data example/
chgrp -R www-data example/

Web service

Nginx

If you use Nginx and SSL certificate for the encryption of the traffic, use the configuration below (correct it according to your needs).

server {
	listen 80;
	listen [::]:80;

	root /path-to-the-framework/example/public;
	index index.php index.html index.htm;

	server_name dev.framework.com;
	rewrite ^(.*) https://dev.framework.com$1 permanent;
}

server {
	isten 443;
	server_name dev.framework.com;

	root /path-to-the-framework/example/public;
	index index.php index.html index.htm;

	ssl on;
	ssl_certificate /etc/ssl/certs/path-to-the-ssl-cert/framework.crt;
	ssl_certificate_key /etc/ssl/certs/path-to-the-ssl-cert/framework.key;

	#enables all versions of TLS, but not SSLv2 or 3 which are weak and now deprecated.
			
	ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

	#Disables all weak ciphers
	ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-A$”;
	ssl_prefer_server_ciphers on;

	location / {
		try_files $uri $uri/ /index.php?$query_string;
	}

	location ~ \.php$ {
		try_files $uri /index.php =404;
		fastcgi_split_path_info ^(.+\.php)(/.+)$;
		fastcgi_pass unix:/var/run/php/php7.0-fpm.sock; 
		fastcgi_index index.php;
		fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
		include fastcgi_params;
	}
}

If you use Nginx and you DON'T use SSL certificate for the encryption of the traffic, use the configuration below (correct it according to your needs).

server {
	listen 80;
	listen [::]:80;

	root /path-to-the-framework/example/public;
	index index.php index.html index.htm;

	server_name dev.framework.com;

	location / {
		try_files $uri $uri/ /index.php?$query_string;
	}

	location ~ \.php$ {
		try_files $uri /index.php =404;
		fastcgi_split_path_info ^(.+\.php)(/.+)$;
		fastcgi_pass unix:/var/run/php/php7.0-fpm.sock; 
		fastcgi_index index.php;
		fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
		include fastcgi_params;
	}
}

Check the validity of the configuration and reload:

nginx -t
service nginx reload

Apache

If you want to run the application on Apache you will have to make sure to enable “mod_rewrite” module. For Windows, go to the directory of the Apache installation and open the folder “conf”. Open the file httpd.conf and find and uncomment the line:

#LoadModule rewrite_module modules/mod_rewrite.so

Find all occurrences of:

AllowOverride None

and change them to:

AllowOverride All

Restart apache.

For Ubuntu you can check this short tutorial: https://www.digitalocean.com/community/tutorials/how-to-set-up-mod_rewrite-for-apache-on-ubuntu-14-04.

Additional configurations (optional)

CRON tasks

In the root directory of the framework you will find a folder named “Tasks“. The purpose of this folder is to contain php files which can be requested by CRON tasks on regular basis. For example, the file “SystemCheckForLogs.php” checks if there are error logs generated during the last 36 hours and if there are, it sends an email to the system administrator with a detail report. You can also write your own logic.

For Ubuntu, if you want to set up a CRON task for that specific file:

crontab -e

Add the following line:

0 0 * * * php /path-to-the-framework/example/Tasks/SystemCheckForLogs.php

Save and close.

This will call the above-mentioned file on every 24 hours.

Structure of the framework and development

More detail document will be provided in the future.

File structure

Before we start with the development of our own application, we will need to know the purpose of each file and folder part of the framework.

App/ - this is the core of the framework you don’t have to change anything here

cache/ - this folder contains cached files generated by Twig template engine

Config/ - this folder contains all configuration required by the framework

	Translations/ - here are all translations required by the php template engine

	App.php - basic configuration of the framework

	Cache.php - connection to the Memcached server

	Router.php - routers

	Services.php - here are all third-party services used by the framerwork

	SqlDatabase.php - connection to the SQL server

Controller/ - here are all controllers called by the routers

Helpers/ - here are stored classes written by us, which execute specific tasks (db connection, communication with the cache server, error logging, sending of emails, curl requests, user sessions, etc.)

images/ - every time when we use the API mapper and we have transfer of images, we will store the images inside this directory before we pass them to the API

logs/ - here are stored all error logs

node_modules/ - packages installed by npm

public/ - public directory

	assets/ - assets like images, fonts, etc.

	css/ - CSS and LESS/SASS files

	js/

		controllers/ - here are all controllers used by the javascript application

		lib/ - contains important javascript libraries like jquery, handlebars, routers, etc.
			
			dataManager.js - data manager used to executed AJAX requests to the API or other service
			
			handlebars.min.js - Handlebars front-end template engine
			
			jquery.min.js - jQuery
			
			router.js - Router
		
		translations/ - translations required by the javascript application
		
		app.js - starting point of the javascript application
		
		config.js - configuration of the js application
		
		custom.min.js - this is minimized js file generated by grunt
		
		lib.min.js - this is minimized js file generated by grunt
		
		routes.js - routes required by the javascript application
		
		templates.js - handlebars pre-compiled templates
	
	templates/ - Handlebars templates used by the front-end
	
	.htaccess - configuration for Apache
	
	index.php - starting point of the framework
	
	robots.txt - robots file for the search engines

Tasks/ - tasks requested by CRON tasks written by us

Templates/ - Twig templates used by the back-end

vendor/ - packages managed by composer

.gitignore - ignore file for git

composer.json - a list of packages required by the framework

Gruntfile.js - grunt configuration

package.json - grunt configuration

Task runners and package managers

In addition, we will mention a few important things required during the development of your own application. First, the composer is used to update the packages required by the framework. To update to the most current versions, use this command:

composer update

Grunt and all npm tasks which we’ve already installed, have the following purpose.

grunt less

Compiles the LESS file /public/css/style.less and converts it to the CSS file /public/css/style.css.

grunt sass

Compiles the SASS file /public/css/style.scss and converts it to a the CSS file /public/css/style.css.

grunt uglify

Takes all javascript files, minimize them and unites them in one single file named /public/js/lib.min.js.

grunt handlebars

Takes all handlebar templates located in "/public/templates" and pre-compiles them. The pre-compiled templates are saved in /public/js/templates.js.

grunt clean:cache

Cleans the content of folder “cache/”.

grunt clean:logs

Cleans the content of folder “logs/”.

grunt clean

Cleans the content of folders “cache/” and “logs/”.

grunt

Executes all npm tasks listed above.

grunt watch

If you run this task in the terminal, grunt will start a script which will watch for changes in all directories and files which are related to all above tasks. If there are changes, the script will automatically run the default grunt task which on other hand will run all other tasks. As a consequence, all LESS/SASS files will be regenerated, all js files will be minified, all handlebars templates will be pre-complited, etc.

Server-side

Routing, Controllers and Templating

The names of the controllers and the Twig templates must be chosen according to the routes defined inside /Config/Router.php. For example, if we have a route:

'example-first-page' => [Router::GET, 'example\FirstPage'],

We must take into account:

  • The HTTP Request type /GET, DELETE, PUT, POST/;
  • The strings “example” and “FirstPage”;

They will require the following controller and template. In the folder /Controllers we must create a new controller (the word “example” with first capital letter):

ExampleController.php

With the following method (the HTTP Request with lowercase letters and the word “FirstPage”):

getFirstPage()

In the folder /Templates we must create the following sub-folder (if it still not created) and template (the word “example” and the word “FirstPage”):

example/exampleFirstPage.html.twig

When we request URL/example-first-page, the framework will check for the controllers, methods and templates with these names. If any of them is not defined, it will return an error.

In the folder with Twig templates we can define other templates and macroses which can be included in any of the other templates according to the Twig rules.

Mapping

In the routes configuration you can add the following example pattern:

':mapping' => '[A-Za-z0-9\-\_\/]+',

and example route:

'mapper/:mapping' => [Router::ALL, 'mapper\Request'],

This type of routing can be used to map requests sent to an external API. For example, if we send the following request to the framework:

URL/mapper/v1/content/countries/json

This request will be forwarded to controller “Mapper”, method “Request” and we can write our own logic which sends it to the following example API URL:

API-URL/v1/content/countries/json

User session

The user session is managed by the helper Session which takes into account oAuth2 protocol.

Twig templates

Within each Twig template by default we have access to the following variables:

  • {{ is_logged }} - its purpose is to tell us if the user is logged. It can take one of the two values - TRUE or FALSE.
  • {{ trans.SOME_KEY }} - this is an array containing a list of translations which will be used for templating

Sometimes when we submit forms, we will have access to the following variables:

  • {{ is_done }} - if this variable is TRUE, this means that the form has been submitted successfully and we can display a message for success
  • {{ error_message }} - is is_done is not TRUE, we most probably will have this one which will contain an error message
  • {{ form_data }} - every time when we submit a form and after the submission we go back to the same page, we will have access to a list of variables and their values which have been submitted

Cliend-side

Variables

On the client-side you can access the cookie “is_logged” which has the only purpose to tell us if the user is logged. It can take one of the two values - TRUE or FALSE.

Contributing

How can you contribute:

  1. Fork it.
  2. Create your feature branch (git checkout -b my-new-feature).
  3. Commit your changes (git commit -am 'Added some feature').
  4. Push to the branch (git push origin my-new-feature).
  5. Create a new Pull Request.

License

The FrameworkJet framework is open-sourced software licensed under the MIT license.