Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Pull requests are the best way to propose changes to the codebase (we use [Githu
6. Create a new Pull Request

### Guidelines
* Before opening a PR for additions or changes, please discuss those by filing an issue on [GitHub](https://github.com/equalframework/equal/issues) or asking about it on [Discord](https://discord.gg/BNCPYxD9kk) (#general channel). This will save you development time by getting feedback upfront and make review faster by giving the maintainers more context and details.
* Before opening a PR for additions or changes, please discuss those by filing an issue on [GitHub](https://github.com/equalframework/equal/issues) or asking about it on [Discord](https://discord.gg/xNAXyhbYBp) (#general channel). This will save you development time by getting feedback upfront and make review faster by giving the maintainers more context and details.
* Before submitting a PR, ensure that the code works with all PHP versions that we support (currently PHP 7.0 to PHP 7.4); that the test suite passes and that your code lints.
* If you've changed some behavior, update the 'description' and 'help' attributes (when present).
* If you are going to submit a pull request, please fork from `master`, and submit your pull request back as a fix/feature branch referencing the GitHub issue number
Expand Down Expand Up @@ -88,4 +88,4 @@ When writing Unit Tests, please
* If you change any global settings, make sure that you reset to the default in the `rollback()`.
* Don't over-complicate test code by testing several behaviors in the same test.

This makes it easier to see exactly what is being tested when reviewing the PR. I want to be able to see it in the PR, not have to hunt in other unchanged classes to see what the test is doing.
This makes it easier to see exactly what is being tested when reviewing the PR. We want to be able to see it in the PR, without having to hunt in other unchanged classes to see what the test is doing.
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ This mechanism enables eQual to generate an application without writing a single

## Features

Beside its revolutionary edge, eQal is a fully-featured framework providing an amazing set of both traditional and innovative features.
Beside its revolutionary edge, eQual is a fully-featured framework providing an amazing set of both traditional and innovative features.


### Low-Code
Expand All @@ -56,12 +56,12 @@ Beside its revolutionary edge, eQal is a fully-featured framework providing an a

### Architecture
:white_check_mark: **CQRS architecture**: Division of controllers into Action Handlers, Data Providers, and App Providers.
:white_check_mark: **MVC segregation**: Strict distinction between Models (entites), Views and Controllers.
:white_check_mark: **MVC segregation**: Strict distinction between Models (entities), Views and Controllers.
:white_check_mark: **Dependency injection**: Inject services into classes, methods, controllers, or functions anywhere.
:white_check_mark: **Data Adaptation**: Automatically transform received data based on format and context.
:white_check_mark: **Services Extensibility**: Ability to extend services behavior, and to register custom ones.
:white_check_mark: **Cascading Configuration**: Overridable settings at different levels (default, global, package).
:white_check_mark: **I/O as HTTP messages**: Inputs & outputs are handled as text in all contexts (default is 'aplication/json').
:white_check_mark: **I/O as HTTP messages**: Inputs & outputs are handled as text in all contexts (default is 'application/json').

### Entities & ORM
:white_check_mark: **Model definition**: With support for inheritance, workflows, actions, roles and policies, transitions, and events.
Expand All @@ -82,7 +82,7 @@ Beside its revolutionary edge, eQal is a fully-featured framework providing an a
:white_check_mark: **Multi-formats exports**: Export any Controller data in TXT, CSV, or PDF formats.

### Miscellaneous
:white_check_mark: **Database**: Ablity to connect to various data source (DBMS), with guidelines to develop your own if needed.
:white_check_mark: **Database**: Ability to connect to various data source (DBMS), with guidelines to develop your own if needed.
:white_check_mark: **Multi-user**: Allows concurrency through Optimistic Concurrency Control.
:white_check_mark: **Multi-lang & Multi-locale support**: Provides multilingual support and regional settings.
:white_check_mark: **Self-host**: Supports Docker, Kubernetes, AWS EC2, Google Cloud Run, and more.
Expand Down Expand Up @@ -121,9 +121,9 @@ For a comprehensive documentation that includes examples and step-by-step instru
## Requirements
eQual requires the following environment:

* **PHP 7+** with extensions mysqli (mandatory) + gd opcache zip tidy (optional)
* **PHP 8+** with extensions (opcache, zip, tidy, ...)
* **Apache 2+** or **Nginx**
* **MySQL 5+** compatible DBMS (tested up to MySQL 5.7 and MariaDB 10.3)
* **SQL:2011** compatible DBMS (SQLite, MariaDB Server, Microsoft SQL Server, Oracle MySQL)

## Install

Expand Down Expand Up @@ -159,4 +159,4 @@ For questions or any type of support, you can reach out via [Discord](https://di

## License

eQual framework project - Released under the GNU Lesser General Public License v3.0.
eQual framework project - Released under the [GNU Lesser General Public License v3.0](https://www.gnu.org/licenses/lgpl-3.0).
14 changes: 14 additions & 0 deletions config/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,20 @@
"instant": true,
"default": "DB"
},
"HTTP_TRUSTED_HEADERS": {
"type": "array",
"usage": "text/plain[]",
"description": "Specific HTTP headers that are used to pass information from a proxy or load balancer to the backend server.",
"instant": true,
"default": []
},
"HTTP_TRUSTED_PROXIES": {
"type": "array",
"usage": "ipv4/ddn[]",
"description": "Specific proxy servers or load balancers that an application or server is configured to trust when handling incoming request.",
"instant": true,
"default": []
},
"HTTP_REQUEST_TIMEOUT": {
"type": "integer",
"usage": "time/duration",
Expand Down
2 changes: 1 addition & 1 deletion lib/equal/data/DataValidator.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ public function checkConstraints(Field $field, $value) {
if(!isset($constraint['message'])) {
$constraint['message'] = 'Invalid field.';
}
trigger_error("ORM::given value for field `{$field}` violates constraint : {$constraint['message']}", QN_REPORT_INFO);
trigger_error("ORM::given value for field `{$field}` violates constraint `{$error_id}`: {$constraint['message']}", EQ_REPORT_WARNING);
$result[$error_id] = $constraint['message'];
}
}
Expand Down
3 changes: 3 additions & 0 deletions lib/equal/orm/Field.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ protected function getUsageString(): string {
'datetime' => 'date/time',
'time' => 'time/plain',
'binary' => 'binary/plain:16000000',
'file' => 'binary/plain:16000000',
'many2one' => 'number/integer:9',
'one2many' => 'array',
'many2many' => 'array',
Expand All @@ -99,6 +100,7 @@ public function getContentType(): string {
'datetime' => 'date/datetime',
'time' => 'time/plain',
'binary' => 'binary/plain',
'file' => 'binary/plain',
'many2one' => 'number/natural',
'one2many' => 'array',
'many2many' => 'array',
Expand All @@ -112,6 +114,7 @@ public function getUsage(): Usage {
if(is_null($this->usage)) {
// by default, use the usage string for which the field type is an alias
$this->usage = UsageFactory::create($this->getUsageString());
trigger_error("ORM::no usage set for field `{$this->name}`: assigned to `".$this->getUsageString()."`", EQ_REPORT_INFO);
}
return $this->usage;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/equal/orm/UsageFactory.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,12 @@ public static function create(string $str_usage): Usage {
case 'image':
$usageInstance = new UsageBinary($str_usage);
break;

/* non-generic content-types */
case 'amount':
$usageInstance = new UsageAmount($str_usage);
break;
case 'coordinate':
// #todo
break;
case 'country':
$usageInstance = new UsageCountry($str_usage);
Expand Down
2 changes: 1 addition & 1 deletion lib/equal/orm/usages/UsageBinary.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public function __construct(string $usage_str) {
public function getConstraints(): array {
return [
'size_exceeded' => [
'message' => 'Image exceeds length constraint.',
'message' => 'Binary exceeds length constraint.',
'function' => function($value) {
$len = intval($this->getLength());
$strlen = strlen($value);
Expand Down
27 changes: 21 additions & 6 deletions lib/equal/php/Context.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ public function __toString() {
return 'This is the PHP context instance.';
}

public static function constants() {
return ['HTTP_TRUSTED_HEADERS', 'HTTP_TRUSTED_PROXIES'];
}

public function get($var, $default=null) {
if(isset($this->params[$var])) {
return $this->params[$var];
Expand Down Expand Up @@ -240,13 +244,24 @@ private function getHttpRequestHeaders() {
if(!isset($headers['ETag'])) {
$headers['ETag'] = $headers['If-None-Match'] ?? '';
}
// handle client IP address
// use only REMOTE_ADDR, if present (to prevent spoofing) - fallback to localhost
$headers['X-Forwarded-For'] = '127.0.0.1';
// #memo - using CLI, REMOTE_ADDR is not set
if(isset($_SERVER['REMOTE_ADDR'])) {
$headers['X-Forwarded-For'] = $_SERVER['REMOTE_ADDR'];
// store client IP address in `X-Forwarded-For` header
// use original `X-Forwarded-For` only if trusted or present in trusted proxies (to prevent spoofing) - fallback on REMOTE_ADDR, or localhost
$ip = '127.0.0.1';
if(isset($_SERVER['HTTP_X_FORWARDED_FOR']) && in_array('X-Forwarded-For', constant('HTTP_TRUSTED_HEADERS'))) {
$client_ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
$ip = $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1';
foreach(array_reverse($client_ips) as $client_ip) {
$client_ip = trim($client_ip);
if(!in_array($client_ip, constant('HTTP_TRUSTED_PROXIES'))) {
$ip = $client_ip;
break;
}
}
}
elseif(isset($_SERVER['REMOTE_ADDR'])) {
$ip = $_SERVER['REMOTE_ADDR'];
}
$headers['X-Forwarded-For'] = $ip;
}

// set default content type to 'application/x-www-form-urlencoded'
Expand Down
2 changes: 1 addition & 1 deletion packages/core/apps/apps/version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3259247aafc763abdbb52639061536cb
67985d85f939b2734c5510eabc7d253c
Binary file modified packages/core/apps/apps/web.app
Binary file not shown.
2 changes: 1 addition & 1 deletion packages/core/apps/auth/version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
d6507202322c5ffce6b5c258517d5fd6
8f177a53b1d9439b24c5bfc5d0c959ef
Binary file modified packages/core/apps/auth/web.app
Binary file not shown.
4 changes: 2 additions & 2 deletions packages/core/apps/console.php
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,9 @@

$result = [];

if(file_exists(QN_BASEDIR.'/log/eq_error.log')) {
if(file_exists(QN_BASEDIR.'/log/equal.log')) {
// read raw data from pointer log file
$fp = fopen(QN_BASEDIR.'/log/eq_error.log', "r");
$fp = fopen(QN_BASEDIR.'/log/equal.log', "r");
$result[] = "START LOG";
$i = 0;
$prev_thread_id = 0;
Expand Down
2 changes: 1 addition & 1 deletion packages/core/apps/workbench/source
Submodule source updated 149 files
2 changes: 1 addition & 1 deletion packages/core/apps/workbench/version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
d85e1ea1561f68f47fa57aad8707abec
33d3ea15aca35ca4204c05abdef0d339
Binary file modified packages/core/apps/workbench/web.app
Binary file not shown.
14 changes: 10 additions & 4 deletions packages/core/classes/Mail.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -353,12 +353,18 @@ private static function createEnvelope($message): \Swift_Message {
->setTo($message['to'])
->setFrom([constant('EMAIL_SMTP_ACCOUNT_EMAIL') => constant('EMAIL_SMTP_ACCOUNT_DISPLAYNAME')]);

if(isset($message['cc']) && strlen($message['cc']) > 0) {
$envelope->setCc($message['cc']);
if(isset($message['cc'])) {
if( (is_array($message['cc']) && count($message['cc']) > 0)
|| (is_string($message['cc']) && strlen($message['cc']) > 0) ) {
$envelope->setCc($message['cc']);
}
}

if(isset($message['bcc']) && strlen($message['bcc']) > 0) {
$envelope->setBcc($message['bcc']);
if(isset($message['bcc'])) {
if( (is_array($message['bcc']) && count($message['bcc']) > 0)
|| (is_string($message['bcc']) && strlen($message['bcc']) > 0) ) {
$envelope->setBcc($message['bcc']);
}
}

if(isset($message['reply_to']) && strlen($message['reply_to']) > 0) {
Expand Down
24 changes: 21 additions & 3 deletions public/console.php
Original file line number Diff line number Diff line change
Expand Up @@ -210,9 +210,27 @@
width: 50%;
}

#header {
position: fixed;
top: 0;
height: 105px;
width: 100%;
background: white;
z-index: 4;
}

#searchForm {
padding: 25px 20px 15px 20px;
background: #f5f5f5;
margin: 10px;
border: solid 1px #dfdfdf;
border-radius: 15px;
}

#start {
padding-top: 120px;
padding-top: 110px;
}

.loader-overlay {
display: none;
position: relative;
Expand Down Expand Up @@ -677,8 +695,8 @@ function createTraceElement(trace, i) {
</div>


<div id="header" style="position: fixed; top: 0; height: 100px; width: 100%; background: white; z-index: 4;">
<form id="searchForm" style="padding: 25px 20px 15px 20px; background: #f5f5f5; margin: 5px; border: solid 1px #dfdfdf; border-radius: 15px;">
<div id="header">
<form id="searchForm">
<div style="display: flex; align-items: flex-end;">
<a class="equal-logo" href=""></a>
<div class="material-select" style="width: 100px;">
Expand Down