diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml
new file mode 100644
index 0000000..88865f7
--- /dev/null
+++ b/.github/workflows/build-release.yml
@@ -0,0 +1,47 @@
+name: Build Release
+
+on:
+ push:
+ branches:
+ - 'release/*'
+
+jobs:
+ autocommit:
+ name: Build Release
+ runs-on: ubuntu-latest
+ container:
+ image: ghcr.io/mvorisek/image-php:latest
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ ref: ${{ github.ref }}
+
+ - name: Install PHP dependencies
+ run: composer update --ansi --prefer-dist --no-interaction --no-progress --optimize-autoloader
+
+ - name: Update composer.json
+ run: >-
+ composer config --unset version && php -r '
+ $f = __DIR__ . "/composer.json";
+ $data = json_decode(file_get_contents($f), true);
+ foreach ($data as $k => $v) {
+ if (preg_match("~^(.+)-release$~", $k, $matches)) {
+ $data[$matches[1]] = $data[$k]; unset($data[$k]);
+ }
+ }
+ $str = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . "\n";
+ echo $str;
+ file_put_contents($f, $str);
+ '
+
+ - name: Commit
+ run: |
+ git config --global user.name "$(git show -s --format='%an')"
+ git config --global user.email "$(git show -s --format='%ae')"
+ git add . -N && (git diff --exit-code || git commit -a -m "Branch for stable release")
+
+ - name: Push
+ uses: ad-m/github-push-action@master
+ with:
+ branch: ${{ github.ref }}
+ github_token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/bundler.yml b/.github/workflows/bundler.yml
deleted file mode 100644
index 953db85..0000000
--- a/.github/workflows/bundler.yml
+++ /dev/null
@@ -1,30 +0,0 @@
-name: Bundler
-
-on: create
-
-jobs:
- autocommit:
- name: Update to stable dependencies
- if: startsWith(github.ref, 'refs/heads/release/')
- runs-on: ubuntu-latest
- container:
- image: atk4/image:latest # https://github.com/atk4/image
- steps:
- - uses: actions/checkout@v2
- with:
- ref: ${{ github.ref }}
- - run: echo ${{ github.ref }}
- - name: Update to stable dependencies
- run: |
- # replaces X keys with X-release keys
- jq '. as $in | reduce (keys_unsorted[] | select(endswith("-release")|not)) as $k ({}; . + {($k) : (($k + "-release") as $kr | $in | if has($kr) then .[$kr] else .[$k] end) } )' < composer.json > tmp && mv tmp composer.json
- v=$(echo ${{ github.ref }} | cut -d / -f 4)
- echo "::set-env name=version::$v"
-
- - uses: stefanzweifel/git-auto-commit-action@v4
- with:
- commit_message: Setting release dependencies
- - uses: ad-m/github-push-action@master
- with:
- branch: ${{ github.ref }}
- github_token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml
deleted file mode 100644
index 1a783cf..0000000
--- a/.github/workflows/release-drafter.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-name: Release Drafter
-
-on:
- push:
- # branches to consider in the event; optional, defaults to all
- branches:
- - develop
-
-jobs:
- update_release_draft:
- runs-on: ubuntu-latest
- steps:
- # Drafts your next Release notes as Pull Requests are merged into "master"
- - uses: toolmantim/release-drafter@v5.6.1
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/test-unit.yml b/.github/workflows/test-unit.yml
new file mode 100644
index 0000000..e3f20b9
--- /dev/null
+++ b/.github/workflows/test-unit.yml
@@ -0,0 +1,71 @@
+name: Unit
+
+on:
+ pull_request:
+ push:
+ schedule:
+ - cron: '0 0/2 * * *'
+
+jobs:
+ smoke-test:
+ name: Smoke
+ runs-on: ubuntu-latest
+ container:
+ image: ghcr.io/mvorisek/image-php:${{ matrix.php }}
+ strategy:
+ fail-fast: false
+ matrix:
+ php: ['latest']
+ type: ['Phpunit']
+ include:
+ - php: 'latest'
+ type: 'CodingStyle'
+ - php: 'latest'
+ type: 'StaticAnalysis'
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+
+ - name: Configure PHP
+ run: |
+ rm /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
+ php --version
+
+ - name: Setup cache 1/2
+ id: composer-cache
+ run: |
+ echo "::set-output name=dir::$(composer config cache-files-dir)"
+
+ - name: Setup cache 2/2
+ uses: actions/cache@v2
+ with:
+ path: ${{ steps.composer-cache.outputs.dir }}
+ key: ${{ runner.os }}-composer-smoke-${{ matrix.php }}-${{ matrix.type }}-${{ hashFiles('composer.json') }}
+ restore-keys: |
+ ${{ runner.os }}-composer-
+
+ - name: Install PHP dependencies
+ run: |
+ if [ "${{ matrix.type }}" != "Phpunit" ] && [ "${{ matrix.type }}" != "StaticAnalysis" ]; then composer remove --no-interaction --no-update phpunit/phpunit johnkary/phpunit-speedtrap --dev; fi
+ if [ "${{ matrix.type }}" != "CodingStyle" ]; then composer remove --no-interaction --no-update friendsofphp/php-cs-fixer --dev; fi
+ if [ "${{ matrix.type }}" != "StaticAnalysis" ]; then composer remove --no-interaction --no-update phpstan/\* behat/\* --dev; fi
+ composer update --ansi --prefer-dist --no-interaction --no-progress --optimize-autoloader
+
+ - name: "Run tests: SQLite (only for Phpunit)"
+ if: startsWith(matrix.type, 'Phpunit')
+ run: |
+ echo "not implemented" || vendor/bin/phpunit --exclude-group none --no-coverage -v
+
+ - name: Check Coding Style (only for CodingStyle)
+ if: matrix.type == 'CodingStyle'
+ run: |
+ if [ "$(find demos/ -name '*.php' -print0 | xargs -0 grep -L "namespace Atk4\\\\Chart\\\\Demos[;\\\\]" | tee /dev/fd/2)" ]; then echo 'All demos/ files must have namespace declared' && (exit 1); fi
+ vendor/bin/php-cs-fixer fix --dry-run --using-cache=no --diff --verbose
+ composer config --unset version && composer config --unset require-release
+ composer validate --strict --no-check-lock && composer normalize --dry-run --no-check-lock
+
+ - name: Run Static Analysis (only for StaticAnalysis)
+ if: matrix.type == 'StaticAnalysis'
+ run: |
+ echo "memory_limit = 2G" > /usr/local/etc/php/conf.d/custom-memory-limit.ini
+ vendor/bin/phpstan analyse
diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml
deleted file mode 100644
index d7a89d2..0000000
--- a/.github/workflows/unit-tests.yml
+++ /dev/null
@@ -1,80 +0,0 @@
-name: Unit Testing
-
-on:
- pull_request:
- branches: '**'
- push:
- branches: '**'
- schedule:
- - cron: '0 * * * *'
-
-jobs:
- unit-test:
- name: Unit
- runs-on: ubuntu-latest
- container:
- image: atk4/image:${{ matrix.php }} # https://github.com/atk4/image
- strategy:
- fail-fast: false
- matrix:
- php: ['7.3', 'latest']
- type: ['Phpunit']
- include:
- - php: 'latest'
- type: 'CodingStyle'
- env:
- LOG_COVERAGE: "${{ fromJSON('{true: \"1\", false: \"\"}')[matrix.php == 'latest' && matrix.type == 'Phpunit' && (github.event_name == 'pull_request' || (github.event_name == 'push' && (github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/master')))] }}"
- steps:
- - name: Checkout
- uses: actions/checkout@v2
-
- - name: Configure PHP
- run: |
- if [ -n "$LOG_COVERAGE" ]; then echo "xdebug.mode=coverage" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini; else rm /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini; fi
- php --version
-
- - name: Setup cache 1/2
- id: composer-cache
- run: |
- echo "::set-output name=dir::$(composer config cache-files-dir)"
-
- - name: Setup cache 2/2
- uses: actions/cache@v1
- with:
- path: ${{ steps.composer-cache.outputs.dir }}
- key: ${{ runner.os }}-composer-${{ matrix.php }}-${{ matrix.type }}-${{ hashFiles('composer.json') }}
- restore-keys: |
- ${{ runner.os }}-composer-
-
- - name: Install PHP dependencies
- run: |
- if [ "${{ matrix.type }}" != "Phpunit" ]; then composer remove --no-interaction --no-update phpunit/phpunit phpunit/dbunit phpunit/phpcov --dev ; fi
- if [ "${{ matrix.type }}" != "CodingStyle" ]; then composer remove --no-interaction --no-update friendsofphp/php-cs-fixer --dev ; fi
- composer install --no-suggest --ansi --prefer-dist --no-interaction --no-progress --optimize-autoloader
-
- - name: Init
- run: |
- mkdir -p build/logs
-
- - name: "Run tests: SQLite (only for Phpunit)"
- if: matrix.type == 'Phpunit'
- run: "vendor/bin/phpunit \"$(if [ -n \"$LOG_COVERAGE\" ]; then echo '--coverage-text'; else echo '--no-coverage'; fi)\" -v"
-
- - name: Lint / check syntax (only for CodingStyle)
- if: matrix.type == 'CodingStyle'
- run: find . \( -type d \( -path './vendor/*' \) \) -prune -o ! -type d -name '*.php' -print0 | xargs -0 -n1 php -l
-
- - name: Check Coding Style (only for CodingStyle)
- if: matrix.type == 'CodingStyle'
- run: vendor/bin/php-cs-fixer fix --dry-run --using-cache=no --diff --diff-format=udiff --verbose --show-progress=dots
-
- - name: Upload coverage logs 1/2 (only for "latest" Phpunit)
- if: env.LOG_COVERAGE
- run: vendor/bin/phpcov merge build/logs/ --clover build/logs/cc.xml
-
- - name: Upload coverage logs 2/2 (only for "latest" Phpunit)
- if: env.LOG_COVERAGE
- uses: codecov/codecov-action@v1
- with:
- token: ${{ secrets.CODECOV_TOKEN }}
- file: build/logs/cc.xml
diff --git a/.gitignore b/.gitignore
index ea1efc8..ce729ac 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,9 +1,10 @@
-docs/build
-/build
+/docs/build
+/coverage
/vendor
/composer.lock
.idea
nbproject
+.vscode
.DS_Store
local
@@ -14,4 +15,3 @@ cache
*.cache.*
/phpunit.xml
-/phpunit-*.xml
diff --git a/.php_cs.dist b/.php-cs-fixer.dist.php
similarity index 67%
rename from .php_cs.dist
rename to .php-cs-fixer.dist.php
index 5e91a35..9dfc26b 100644
--- a/.php_cs.dist
+++ b/.php-cs-fixer.dist.php
@@ -8,12 +8,13 @@
'vendor',
]);
-return PhpCsFixer\Config::create()
+return (new PhpCsFixer\Config())
->setRiskyAllowed(true)
->setRules([
'@PhpCsFixer' => true,
- '@PhpCsFixer:risky' =>true,
- '@PHP71Migration:risky' => true,
+ '@PhpCsFixer:risky' => true,
+ '@PHP74Migration:risky' => true,
+ '@PHP74Migration' => true,
// required by PSR-12
'concat_space' => [
@@ -21,6 +22,11 @@
],
// disable some too strict rules
+ 'phpdoc_types' => [
+ // keep enabled, but without "alias" group to not fix
+ // "Callback" to "callback" in phpdoc
+ 'groups' => ['simple', 'meta'],
+ ],
'phpdoc_types_order' => [
'null_adjustment' => 'always_last',
'sort_algorithm' => 'none',
@@ -30,11 +36,12 @@
'equal' => false,
'identical' => false,
],
+ 'native_constant_invocation' => true,
'native_function_invocation' => false,
- 'non_printable_character' => [
- 'use_escape_sequences_in_strings' => true,
- ],
'void_return' => false,
+ 'blank_line_before_statement' => [
+ 'statements' => ['break', 'continue', 'declare', 'return', 'throw', 'exit'],
+ ],
'combine_consecutive_issets' => false,
'combine_consecutive_unsets' => false,
'multiline_whitespace_before_semicolons' => false,
@@ -54,6 +61,10 @@
'nullable_type_declaration_for_default_null_value' => [
'use_nullable_type_declaration' => false,
],
+
+ // fn => without curly brackets is less readable,
+ // also prevent bounding of unwanted variables for GC
+ 'use_arrow_functions' => false,
])
->setFinder($finder)
- ->setCacheFile(__DIR__ . '/.php_cs.cache');
+ ->setCacheFile(sys_get_temp_dir() . '/php-cs-fixer.' . md5(__DIR__) . '.cache');
diff --git a/CHANGELOG.md b/CHANGELOG.md
deleted file mode 100644
index 865320b..0000000
--- a/CHANGELOG.md
+++ /dev/null
@@ -1,20 +0,0 @@
-# Change Log
-
-## [1.0.0](https://github.com/atk4/chart/tree/1.0.0) (2019-03-01)
-
-[Full Changelog](https://github.com/atk4/chart/compare/09fd17a39a808f84b05f75a0222814eb82c0b05e...1.0.0)
-
-**Closed issues:**
-
-- Composer didn't update to 4b593ed34af271af3dea054f2a2dc2dc69592383 [\#5](https://github.com/atk4/chart/issues/5)
-
-**Merged pull requests:**
-
-- show "no data" in label if there is no data [\#4](https://github.com/atk4/chart/pull/4) ([DarkSide666](https://github.com/DarkSide666))
-- fix options [\#3](https://github.com/atk4/chart/pull/3) ([DarkSide666](https://github.com/DarkSide666))
-- bugfix [\#2](https://github.com/atk4/chart/pull/2) ([DarkSide666](https://github.com/DarkSide666))
-- add descriptions, add withCurrencyY [\#1](https://github.com/atk4/chart/pull/1) ([DarkSide666](https://github.com/DarkSide666))
-
-
-
-\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
\ No newline at end of file
diff --git a/codecov.yml b/codecov.yml
index edca4fe..1f1d4d4 100644
--- a/codecov.yml
+++ b/codecov.yml
@@ -1,11 +1,12 @@
ignore:
- - demo
+ - docs
comment: false
coverage:
status:
project:
default:
target: auto
- threshold: 0.1
+ threshold: 0.025
patch: false
changes: false
+
diff --git a/composer.json b/composer.json
index fd3e72f..2eab6b8 100644
--- a/composer.json
+++ b/composer.json
@@ -1,47 +1,58 @@
{
- "name": "atk4/chart",
- "type": "library",
- "description": "ChartJS for Agile UI",
- "keywords": [
- "agile",
- "data",
- "framework",
- "chart",
- "chartjs"
- ],
- "homepage": "https://github.com/atk4/chart",
- "license": "MIT",
- "authors": [
- {
- "name": "Romans Malinovskis",
- "email": "romans@agiletoolkit.org",
- "homepage": "https://nearly.guru/"
+ "name": "atk4/chart",
+ "description": "ChartJS for Agile UI",
+ "license": "MIT",
+ "type": "library",
+ "keywords": [
+ "agile",
+ "data",
+ "framework",
+ "chart",
+ "chartjs"
+ ],
+ "version": "dev-develop",
+ "authors": [
+ {
+ "name": "Romans Malinovskis",
+ "email": "romans@agiletoolkit.org",
+ "homepage": "https://nearly.guru/"
+ }
+ ],
+ "homepage": "https://github.com/atk4/chart",
+ "require": {
+ "php": ">=7.4 <8.2",
+ "atk4/ui": "dev-develop"
+ },
+ "require-release": {
+ "php": ">=7.4 <8.2",
+ "atk4/ui": "~4.0.0"
+ },
+ "require-dev": {
+ "ergebnis/composer-normalize": "^2.13",
+ "friendsofphp/php-cs-fixer": "^3.0",
+ "johnkary/phpunit-speedtrap": "^3.3",
+ "phpstan/extension-installer": "^1.1",
+ "phpstan/phpstan": "^1.0",
+ "phpstan/phpstan-deprecation-rules": "^1.0",
+ "phpunit/phpunit": "^9.5.5"
+ },
+ "minimum-stability": "dev",
+ "prefer-stable": true,
+ "autoload": {
+ "psr-4": {
+ "Atk4\\Chart\\": "src/"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Atk4\\Chart\\Tests\\": "tests/"
+ }
+ },
+ "config": {
+ "allow-plugins": {
+ "ergebnis/composer-normalize": true,
+ "phpstan/extension-installer": true
+ },
+ "sort-packages": true
}
- ],
- "minimum-stability": "dev",
- "prefer-stable": true,
- "config": {
- "sort-packages": true
- },
- "require": {
- "atk4/ui": "dev-develop"
- },
- "require-release": {
- "atk4/ui": "~2.3.0"
- },
- "require-dev": {
- "friendsofphp/php-cs-fixer": "^2.16",
- "phpunit/phpcov": "*",
- "phpunit/phpunit": "*"
- },
- "autoload": {
- "psr-4": {
- "Atk4\\Chart\\": "src/"
- }
- },
- "autoload-dev": {
- "psr-4": {
- "Atk4\\Chart\\Tests\\": "tests/"
- }
- }
}
diff --git a/demo/index.php b/demos/index.php
similarity index 55%
rename from demo/index.php
rename to demos/index.php
index ea22262..1844d00 100644
--- a/demo/index.php
+++ b/demos/index.php
@@ -2,39 +2,44 @@
declare(strict_types=1);
-require '../vendor/autoload.php';
+namespace Atk4\Chart\Demos;
use Atk4\Chart\BarChart;
use Atk4\Chart\ChartBox;
use Atk4\Chart\PieChart;
use Atk4\Data\Model;
-use Atk4\Data\Persistence\Array_;
+use Atk4\Data\Persistence;
use Atk4\Ui\App;
use Atk4\Ui\Columns;
use Atk4\Ui\Layout;
-$p = ['t' => [
- ['name' => 'January', 'sales' => 20000, 'purchases' => 10000],
- ['name' => 'February', 'sales' => 23000, 'purchases' => 12000],
- ['name' => 'March', 'sales' => 16000, 'purchases' => 11000],
- ['name' => 'April', 'sales' => 14000, 'purchases' => 13000],
-]];
-$m = new Model(new Array_($p), 't');
+require '../vendor/autoload.php';
+
+$t = [
+ 1 => ['name' => 'January', 'sales' => 20000, 'purchases' => 10000],
+ 2 => ['name' => 'February', 'sales' => 23000, 'purchases' => 12000],
+ 3 => ['name' => 'March', 'sales' => 16000, 'purchases' => 11000],
+ 4 => ['name' => 'April', 'sales' => 14000, 'purchases' => 13000],
+];
+
+$m = new Model(new Persistence\Array_($t));
$m->addFields(['name', 'sales', 'purchases', 'profit']);
-$m->onHook($m::HOOK_AFTER_LOAD, function ($m) { $m->set('profit', $m->get('sales') - $m->get('purchases')); });
-$app = new App('Chart Demo');
+$m->onHook($m::HOOK_AFTER_LOAD, function ($m) {
+ $m->set('profit', $m->get('sales') - $m->get('purchases'));
+});
+$app = new App(['title' => 'Chart Demo']);
$app->initLayout([Layout\Centered::class]);
// split in columns
$columns = Columns::addTo($app->layout);
-// Lets put your chart into a box:
+// lets put your chart into a box
$cb = ChartBox::addTo($columns->addColumn(8), ['label' => ['Demo Bar Chart', 'icon' => 'book']]);
$chart = BarChart::addTo($cb);
$chart->setModel($m, ['name', 'sales', 'purchases', 'profit']);
$chart->withCurrency('$');
-// Tweak our chart to support currencies better
+// tweak our chart to support currencies better
$cb = ChartBox::addTo($columns->addColumn(8), ['label' => ['Demo Pie Chart', 'icon' => 'book']]);
$chart = PieChart::addTo($cb);
$chart->setModel($m, ['name', 'profit']);
diff --git a/phpstan.neon.dist b/phpstan.neon.dist
new file mode 100644
index 0000000..09b8f29
--- /dev/null
+++ b/phpstan.neon.dist
@@ -0,0 +1,29 @@
+parameters:
+ level: 6
+ paths:
+ - ./
+ excludePaths:
+ - cache/
+ - build/
+ - vendor/
+
+ # TODO review once we drop PHP 7.x support
+ treatPhpDocTypesAsCertain: false
+
+ # some extra rules
+ checkAlwaysTrueCheckTypeFunctionCall: true
+ checkAlwaysTrueInstanceof: true
+ checkAlwaysTrueStrictComparison: true
+ checkExplicitMixedMissingReturn: true
+ checkFunctionNameCase: true
+ # TODO checkMissingClosureNativeReturnTypehintRule: true
+ reportMaybesInMethodSignatures: true
+ reportStaticMethodSignatures: true
+ checkTooWideReturnTypesInProtectedAndPublicMethods: true
+ checkMissingIterableValueType: false # TODO
+
+ ignoreErrors:
+ #- '~^Unsafe usage of new static\(\)\.$~'
+
+ # for src/Chart.php
+ - '~^Call to an undefined method Atk4\\Data\\Model::expr\(\)\.$~'
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
deleted file mode 100644
index 2beed80..0000000
--- a/phpunit.xml.dist
+++ /dev/null
@@ -1,21 +0,0 @@
-