Skip to content

Commit 9614439

Browse files
authored
Merge pull request #25 from Divergence/develop
Version 3 - (╯°□°)╯︵ ┻━┻
2 parents 1662493 + 8c75659 commit 9614439

70 files changed

Lines changed: 4059 additions & 1316 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ docs
99
.vscode
1010
composer.lock
1111
.phpunit.result.cache
12-
clover.xml
12+
clover.xml
13+
config/db.dev.php

.scrutinizer.yml

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,9 @@ checks:
44
duplication: true
55

66
build:
7-
image: default-bionic
7+
image: default-jammy
88
environment:
9-
php: 8.1.12
10-
variables:
11-
XDEBUG_MODE: 'coverage'
9+
php: 8.4.0
1210
nodes:
1311
coverage:
1412
services:
@@ -26,12 +24,12 @@ build:
2624
- sudo apt install -y ffmpeg exiftool
2725
tests:
2826
override:
29-
- command: ./vendor/bin/phpunit --coverage-clover=build/coverage/clover.xml # Or "./vendor/bin/phpunit --coverage-clover=build/coverage/clover.xml"
27+
- command: mkdir -p build/logs && DIVERGENCE_TEST_DB=tests-mysql phpdbg -qrr ./vendor/bin/phpunit --coverage-clover build/logs/clover.xml
3028
idle_timeout: 300
3129
coverage:
32-
file: 'build/coverage/clover.xml'
30+
file: 'build/logs/clover.xml'
3331
format: 'php-clover'
3432
analysis:
3533
tests:
3634
override:
37-
- php-scrutinizer-run
35+
- php-scrutinizer-run

.travis.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
language: php
22
php:
3-
- '8.1'
3+
- '8.4'
44

55
services:
66
- mysql
@@ -33,7 +33,7 @@ before_script:
3333
- ls -al
3434

3535
script:
36-
- ./vendor/bin/phpunit --coverage-clover build/logs/clover.xml
36+
- composer test:mysql
3737

3838
after_success:
3939
# Submit coverage report to Coveralls servers, see .coveralls.yml
@@ -49,4 +49,4 @@ after_success:
4949
cache:
5050
directories:
5151
- vendor
52-
- $HOME/.cache/composer
52+
- $HOME/.cache/composer

composer.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,12 @@
5050
},
5151
"scripts": {
5252
"fix-code": "php-cs-fixer fix",
53-
"test": "vendor/bin/phpunit --coverage-clover build/logs/clover.xml"
53+
"test": [
54+
"@test:mysql",
55+
"@test:sqlite"
56+
],
57+
"test:mysql": "DIVERGENCE_TEST_DB=tests-mysql vendor/bin/phpunit --coverage-clover build/logs/clover.xml",
58+
"test:sqlite": "DIVERGENCE_TEST_DB=tests-sqlite-memory vendor/bin/phpunit"
5459
},
5560
"support": {
5661
"issues": "https://github.com/Divergence/framework/issues"

config/db.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@
77
* For the full copyright and license information, please view the LICENSE
88
* file that was distributed with this source code.
99
*/
10+
$devConfig = __DIR__ . '/db.dev.php';
11+
12+
if (file_exists($devConfig)) {
13+
return require $devConfig;
14+
}
15+
1016
return [
1117
/*
1218
* MySQL database configuration
@@ -52,4 +58,27 @@
5258
'username' => 'root',
5359
'password' => '',
5460
],
61+
/*
62+
* SQLite database configuration
63+
*/
64+
'sqlite' => [
65+
'path' => __DIR__ . '/../var/sqlite/app.sqlite',
66+
'foreign_keys' => true,
67+
'busy_timeout' => 5000,
68+
],
69+
'dev-sqlite' => [
70+
'path' => __DIR__ . '/../var/sqlite/dev.sqlite',
71+
'foreign_keys' => true,
72+
'busy_timeout' => 5000,
73+
],
74+
'tests-sqlite-memory' => [
75+
'path' => ':memory:',
76+
'foreign_keys' => true,
77+
'busy_timeout' => 5000,
78+
],
79+
'tests-sqlite-files' => [
80+
'path' => __DIR__ . '/../var/sqlite/tests.sqlite',
81+
'foreign_keys' => true,
82+
'busy_timeout' => 5000,
83+
],
5584
];

phpunit.xml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@
1212
</exclude>
1313
</coverage>
1414
<testsuites>
15-
<testsuite name="all">
15+
<testsuite name="tests-mysql">
1616
<directory>tests/Divergence</directory>
1717
</testsuite>
18+
<!--<testsuite name="tests-sqlite-memory">
19+
<file>tests/DivergenceSQLite/SQLiteSuiteLoader.php</file>
20+
</testsuite>-->
1821
</testsuites>
1922
<listeners>
2023
<listener class="Divergence\Tests\TestListener" file="./tests/Divergence/TestListener.php"/>

readme.md

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,34 @@
33
---
44
Divergence is a PHP framework designed for rapid development and modern practices without becoming an over abstracted mess.
55

6+
**Requires PHP 8.1+**
7+
68
## [Documentation](https://github.com/Divergence/docs#divergence-framework-documentation)
79
## [Getting Started](https://github.com/Divergence/docs/blob/release/gettingstarted.md#getting-started)
10+
## [V3 Architecture](docs/v3-architecture.md)
11+
12+
## Minimal Model
13+
14+
```php
15+
<?php
16+
17+
namespace App\Models;
18+
19+
use Divergence\Models\Model;
20+
use Divergence\Models\Mapping\Column;
21+
22+
class Article extends Model
23+
{
24+
public static $tableName = 'articles';
25+
26+
#[Column(type: 'string', notnull: true)]
27+
private string $Title;
28+
29+
#[Column(type: 'clob', notnull: true)]
30+
private string $Body;
31+
}
32+
```
833

9-
[![asciicast](https://asciinema.org/a/FhE9hATLKDhH7oQfFbeNG5hzs.png)](https://asciinema.org/a/FhE9hATLKDhH7oQfFbeNG5hzs)
1034

1135
## Purpose
1236
This collection of classes contains my favorite building blocks for developing websites with PHP and they have an impressive track record with hundreds of currently active websites using one version or another of the classes in this framework. While they were originally written years ago they are all PSR compatible and support modern practices out of the box.
@@ -16,17 +40,18 @@ Unit testing the code base and providing code coverage is a primary goal of this
1640
# Main Features
1741
* Models
1842
* Real PHP classes.
19-
* Map fields with array or attributes.
43+
* Declare fields with static arrays or PHP 8 attributes (`#[Column(...)]`).
44+
* Declare relationships with static arrays or PHP 8 attributes (`#[Relation(...)]`).
2045
* Built in support for relationships and object versioning.
21-
* Speed up prototyping and automate new deployments by automatically creates table based on your models when none are found.
22-
* Built in support for MySQL.
46+
* Speed up prototyping and automate new deployments by automatically creating tables based on your models when none are found.
47+
* Built in support for MySQL and SQLite.
2348

2449
* Routing
2550
* Simpler, faster, tree based routing system.
2651
* Built with basic class inheritance in mind.
2752

2853
* Controllers
29-
* Psr7 compatible controllers.
54+
* PSR-7 compatible controllers.
3055
* Pre-made REST API controllers allow you to build APIs rapidly.
3156
* 100% Unit test coverage for filters, sorters, and conditions.
3257
* Build HTTP APIs in minutes by extending `RecordsRequestHandler` and setting the one config variable: the name of your model class.
@@ -43,6 +68,27 @@ Unit testing the code base and providing code coverage is a primary goal of this
4368
* Manage media remotely with a built in JSON API using the standard permissions interface for all controllers.
4469
* Supports POST and PUT request types for media uploads.
4570

71+
## Installation
72+
73+
```bash
74+
composer require divergence/divergence
75+
```
76+
77+
The [divergence/cli](https://packagist.org/packages/divergence/cli) package is also available to initialize new projects and manage database configurations from the command line.
78+
79+
## Running Tests
80+
81+
```bash
82+
# Run all test suites
83+
composer test
84+
85+
# MySQL suite only
86+
composer test:mysql
87+
88+
# SQLite in-memory suite only
89+
composer test:sqlite
90+
```
91+
4692
### Contributing To Divergence
4793

4894
**All issues and pull requests should be filed on the [Divergence/framework](http://github.com/Divergence/framework) repository.**
@@ -52,5 +98,5 @@ Unit testing the code base and providing code coverage is a primary goal of this
5298
The Divergence framework is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT)
5399

54100
### Credits
55-
- Much of the original code in this framework was published as part of the [PHP framework portion](https://github.com/JarvusInnovations/Emergence-Skeleton) of [Emergence](https://github.com/JarvusInnovations/Emergence) by [Chris Alfano](https://github.com/themightychris).
56-
- This project is maintained by [Henry Paradiz](https://github.com/hparadiz)
101+
- The patterns in this framework are a fork of the [PHP framework portion](https://github.com/JarvusInnovations/Emergence-Skeleton) of [Emergence](https://github.com/JarvusInnovations/Emergence) by [Chris Alfano](https://github.com/themightychris).
102+
- This project is maintained by [Henry Paradiz](https://github.com/hparadiz)

src/Controllers/RecordsRequestHandler.php

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@
1212

1313
use Exception;
1414
use Divergence\Helpers\JSON;
15+
use Divergence\IO\Database\Connections;
1516
use Divergence\Responders\JsonBuilder;
1617
use Divergence\Responders\TwigBuilder;
17-
use Divergence\IO\Database\MySQL as DB;
1818
use Divergence\Responders\JsonpBuilder;
1919
use Psr\Http\Message\ResponseInterface;
2020
use Psr\Http\Message\ServerRequestInterface;
@@ -25,7 +25,6 @@
2525
*
2626
* @package Divergence
2727
* @author Henry Paradiz <henry.paradiz@gmail.com>
28-
* @author Chris Alfano <themightychris@gmail.com>
2928
*/
3029
abstract class RecordsRequestHandler extends RequestHandler
3130
{
@@ -198,14 +197,15 @@ public function handleBrowseRequest($options = [], $conditions = [], $responseID
198197
}
199198

200199
$className = static::$recordClass;
200+
$storageClass = Connections::getConnectionType();
201201

202202
return $this->respond(
203-
isset($responseID) ? $responseID : $this->getTemplateName($className::$pluralNoun),
203+
isset($responseID) ? $responseID : $this->getTemplateName($className::getPluralNoun()),
204204
array_merge($responseData, [
205205
'success' => true,
206206
'data' => $className::getAllByWhere($conditions, $options),
207207
'conditions' => $conditions,
208-
'total' => DB::foundRows(),
208+
'total' => $storageClass::foundRows(),
209209
'limit' => $options['limit'],
210210
'offset' => $options['offset'],
211211
])
@@ -225,7 +225,7 @@ public function handleRecordRequest(ActiveRecord $Record, $action = false)
225225
{
226226
$className = static::$recordClass;
227227

228-
return $this->respond($this->getTemplateName($className::$singularNoun), [
228+
return $this->respond($this->getTemplateName($className::getSingularNoun()), [
229229
'success' => true,
230230
'data' => $Record,
231231
]);
@@ -264,7 +264,8 @@ public function getDatumRecord($datum)
264264
$className = static::$recordClass;
265265
$PrimaryKey = $className::getPrimaryKey();
266266
if (empty($datum[$PrimaryKey])) {
267-
$record = new $className::$defaultClass();
267+
$defaultClass = $className::getDefaultClassName();
268+
$record = new $defaultClass();
268269
$this->onRecordCreated($record, $datum);
269270
} else {
270271
if (!$record = $className::getByID($datum[$PrimaryKey])) {
@@ -344,7 +345,7 @@ public function handleMultiSaveRequest(): ResponseInterface
344345
}
345346

346347

347-
return $this->respond($this->getTemplateName($className::$pluralNoun).'Saved', [
348+
return $this->respond($this->getTemplateName($className::getPluralNoun()).'Saved', [
348349
'success' => count($results) || !count($failed),
349350
'data' => $results,
350351
'failed' => $failed,
@@ -417,7 +418,7 @@ public function handleMultiDestroyRequest(): ResponseInterface
417418
}
418419
}
419420

420-
return $this->respond($this->getTemplateName($className::$pluralNoun).'Destroyed', [
421+
return $this->respond($this->getTemplateName($className::getPluralNoun()).'Destroyed', [
421422
'success' => count($results) || !count($failed),
422423
'data' => $results,
423424
'failed' => $failed,
@@ -432,7 +433,8 @@ public function handleCreateRequest(ActiveRecord $Record = null): ResponseInterf
432433

433434
if (!$Record) {
434435
$className = static::$recordClass;
435-
$Record = new $className::$defaultClass();
436+
$defaultClass = $className::getDefaultClassName();
437+
$Record = new $defaultClass();
436438
}
437439

438440
// call template function
@@ -485,7 +487,7 @@ public function handleEditRequest(ActiveRecord $Record): ResponseInterface
485487
$this->onRecordSaved($Record, $_REQUEST);
486488

487489
// fire created response
488-
$responseID = $this->getTemplateName($className::$singularNoun).'Saved';
490+
$responseID = $this->getTemplateName($className::getSingularNoun()).'Saved';
489491
$responseData = [
490492
'success' => true,
491493
'data' => $Record,
@@ -496,7 +498,7 @@ public function handleEditRequest(ActiveRecord $Record): ResponseInterface
496498
// fall through back to form if validation failed
497499
}
498500

499-
$responseID = $this->getTemplateName($className::$singularNoun).'Edit';
501+
$responseID = $this->getTemplateName($className::getSingularNoun()).'Edit';
500502
$responseData = [
501503
'success' => false,
502504
'data' => $Record,
@@ -522,14 +524,14 @@ public function handleDeleteRequest(ActiveRecord $Record): ResponseInterface
522524
$this->onRecordDeleted($Record, $data);
523525

524526
// fire created response
525-
return $this->respond($this->getTemplateName($className::$singularNoun).'Deleted', [
527+
return $this->respond($this->getTemplateName($className::getSingularNoun()).'Deleted', [
526528
'success' => true,
527529
'data' => $Record,
528530
]);
529531
}
530532

531533
return $this->respond('confirm', [
532-
'question' => 'Are you sure you want to delete this '.$className::$singularNoun.'?',
534+
'question' => 'Are you sure you want to delete this '.$className::getSingularNoun().'?',
533535
'data' => $Record,
534536
]);
535537
}

src/Helpers/JSON.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
*
1616
* @package Divergence
1717
* @author Henry Paradiz <henry.paradiz@gmail.com>
18-
* @author Chris Alfano <themightychris@gmail.com>
1918
*/
2019
class JSON
2120
{

0 commit comments

Comments
 (0)