From 68c5d7e1973f74e0b8d7740c90e54c0e9cdd718d Mon Sep 17 00:00:00 2001 From: n-peugnet Date: Tue, 21 Apr 2020 21:39:28 +0200 Subject: tests: add github annotation reports --- .github/workflows/php.yml | 55 ++++++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index defd044..a7414b5 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -1,27 +1,38 @@ name: build on: - push: - branches: [ master ] - pull_request: - branches: [ master ] + - push + - pull_request jobs: - php-build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - - name: Validate composer.json and composer.lock - run: composer validate - - - name: Install dependencies - run: composer install --prefer-dist --no-progress --no-suggest - - # Add a test script to composer.json, for instance: "test": "vendor/bin/phpunit" - # Docs: https://getcomposer.org/doc/articles/scripts.md - - - name: Run test suite - run: make check -k + php-build: + runs-on: ubuntu-latest + steps: + - name: Git checkout + uses: actions/checkout@v2 + + - name: Validate composer.json and composer.lock + run: composer validate + + - name: Install dependencies + run: composer install --prefer-dist --no-progress --no-suggest + + - name: Run test suite + run: make check -k + + - name: PHPStan xml report + if: always() + run: > + mkdir -p build/phpstan && + vendor/bin/phpstan analyse --no-progress --error-format=checkstyle > build/phpstan/checkstyle.xml + + - name: Analysis Publisher + uses: digirati-labs/analysis-publisher@0.0.1 + if: failure() + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + args: > + --report-type=checkstyle --path=**/build/phpcs/checkstyle.xml + --report-type=checkstyle --path=**/build/phpstan/checkstyle.xml + --publisher=github_check -- cgit v1.2.3 From f9173c85ca612ad6cd90417ad423a9c9f94a1e99 Mon Sep 17 00:00:00 2001 From: n-peugnet Date: Tue, 21 Apr 2020 22:24:44 +0200 Subject: tests: add coverage report and badge --- .github/workflows/php.yml | 12 ++++++++++-- README.md | 11 +++++++---- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index a7414b5..479a9f9 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -22,8 +22,8 @@ jobs: - name: PHPStan xml report if: always() - run: > - mkdir -p build/phpstan && + run: | + mkdir -p build/phpstan vendor/bin/phpstan analyse --no-progress --error-format=checkstyle > build/phpstan/checkstyle.xml - name: Analysis Publisher @@ -36,3 +36,11 @@ jobs: --report-type=checkstyle --path=**/build/phpcs/checkstyle.xml --report-type=checkstyle --path=**/build/phpstan/checkstyle.xml --publisher=github_check + + - name: Coveralls publish + if: always() + env: + COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + composer require --quiet --no-interaction cedx/coveralls + vendor/bin/coveralls build/phpunit/cov.xml diff --git a/README.md b/README.md index e4fd1d5..3336429 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # W-CMS -![github status] ![code style] ![phpstan level] +[![build][github]][action] ![style][codestyle] ![phpstan][phpstan] [![coverage][coverage]][coveralls] W is a lightweight CMS tool, meant to help you design a website using a unique approach. It's targeting artists, or experimental projects. @@ -178,6 +178,9 @@ Then, to make the release, run the following command: To only build the release zip, simply run `make dist`. This will create a zip file in `dist/` of the current version. -[github status]: https://github.com/vincent-peugnet/wcms/workflows/build/badge.svg -[code style]: https://img.shields.io/badge/code%20style-PSR12-brightgreen -[phpstan level]: https://img.shields.io/badge/phpstan-level%205-green \ No newline at end of file +[github]: https://github.com/vincent-peugnet/wcms/workflows/build/badge.svg +[action]: https://github.com/vincent-peugnet/wcms/actions +[codestyle]: https://img.shields.io/badge/code%20style-PSR12-brightgreen +[phpstan]: https://img.shields.io/badge/phpstan-level%205-green +[coverage]: https://coveralls.io/repos/github/vincent-peugnet/wcms/badge.svg?branch=master +[coveralls]: https://coveralls.io/github/vincent-peugnet/wcms?branch=master \ No newline at end of file -- cgit v1.2.3 From df545ce931b32d340e40831d0c3afbc6eabda29d Mon Sep 17 00:00:00 2001 From: n-peugnet Date: Wed, 22 Apr 2020 22:35:39 +0200 Subject: fix: Logger::exception didn't print the error position --- app/class/Logger.php | 2 +- tests/LoggerTest.php | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/app/class/Logger.php b/app/class/Logger.php index 5d2695c..104e23a 100644 --- a/app/class/Logger.php +++ b/app/class/Logger.php @@ -95,7 +95,7 @@ class Logger public static function exception(Throwable $e, bool $withtrace = false) { if (self::$verbosity > 0) { - $msg = $e->getMessage(); + $msg = "{$e->getMessage()} in {$e->getFile()}({$e->getLine()})"; if ($withtrace) { // TODO: Maybe print a more beautiful stack trace. $msg .= PHP_EOL . $e->getTraceAsString(); diff --git a/tests/LoggerTest.php b/tests/LoggerTest.php index 95d6cae..b4b87f4 100644 --- a/tests/LoggerTest.php +++ b/tests/LoggerTest.php @@ -242,21 +242,23 @@ class LoggerTest extends FilesTest * @test * @dataProvider exceptionLoggedProvider */ - public function exceptionLoggedTest(int $verbosity, Throwable $e, string $expected) + public function exceptionLoggedTest(int $verbosity, Throwable $e, string $expected, int $line) { Logger::init($this->logfile, $verbosity); Logger::exception($e); - $expected = " [ ERROR ] tests/LoggerTest.php(248) $expected\n"; + $file = __FILE__; + $line += 258; + $expected = " [ ERROR ] tests/LoggerTest.php(248) $expected in $file($line)\n"; $this->assertEquals($expected, substr(file_get_contents($this->logfile), 25)); } public function exceptionLoggedProvider(): array { return [ - [1, new Exception('Test 1'), 'Test 1'], - [2, new Exception('Test 2'), 'Test 2'], - [3, new Exception('Test 3'), 'Test 3'], - [4, new Exception('Test 4'), 'Test 4'], + [1, new Exception('Test 1'), 'Test 1', 0], + [2, new Exception('Test 2'), 'Test 2', 1], + [3, new Exception('Test 3'), 'Test 3', 2], + [4, new Exception('Test 4'), 'Test 4', 3], ]; } @@ -268,8 +270,8 @@ class LoggerTest extends FilesTest Logger::init($this->logfile, 1); Logger::exception(new Exception('Error'), true); $content = file_get_contents($this->logfile); - $expected = " [ ERROR ] tests/LoggerTest.php(269) Error\n"; + $expected = " [ ERROR ] tests/LoggerTest.php(271) Error "; $this->assertEquals($expected, substr($content, 25, 43)); - $this->assertRegExp('/(#\d+ [\w\/\.]*\(\d+\): .*\)\n)+#\d+ \{main\}\n/U', substr($content, 68)); + $this->assertRegExp('/(#\d+ [\w\/\.]*\(\d+\): .*\)\n)+#\d+ \{main\}\n/U', $content); } } -- cgit v1.2.3 From 94714d94f82d49cf8536d16505c47aceffb01e91 Mon Sep 17 00:00:00 2001 From: n-peugnet Date: Thu, 23 Apr 2020 00:29:34 +0200 Subject: feat: warning, info & debug directly a throwable --- app/class/Logger.php | 54 ++++++++++++++++---- index.php | 8 ++- tests/LoggerTest.php | 142 ++++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 179 insertions(+), 25 deletions(-) diff --git a/app/class/Logger.php b/app/class/Logger.php index 104e23a..e2ab4b6 100644 --- a/app/class/Logger.php +++ b/app/class/Logger.php @@ -2,7 +2,7 @@ namespace Wcms; -use InvalidArgumentException; +use RuntimeException; use Throwable; /** @@ -19,17 +19,18 @@ class Logger * * @param string $path the logfile's path * @param int $verbosity 0: no log, 1: errors only, 2: add warn, 3: add info, 4: add debug. + * @throws RuntimeException if failed to create logfile. */ - public static function init(string $path, int $verbosity = 4) + public static function init(string $path, int $verbosity = 4): void { if (!is_dir(dirname($path))) { - throw new InvalidArgumentException("Parent directory of '$path' does not exist."); + throw new RuntimeException("Parent directory of '$path' does not exist."); } if (!is_writable(dirname($path))) { - throw new InvalidArgumentException("Parent directory of '$path' is not writable."); + throw new RuntimeException("Parent directory of '$path' is not writable."); } if (is_file($path) && !is_writable($path)) { - throw new InvalidArgumentException("The logfile '$path' is not writable."); + throw new RuntimeException("The logfile '$path' is not writable."); } self::$file = fopen($path, "a"); if (self::$file === false) { @@ -49,6 +50,11 @@ class Logger vfprintf(self::$file, date('c') . " %-9s %s(%d) $msg\n", $args); } + protected static function exceptionmessage(Throwable $e): string + { + return "{$e->getMessage()} in {$e->getFile()}({$e->getLine()})"; + } + /** * Log an error message using printf format. */ @@ -60,7 +66,7 @@ class Logger } /** - * Log a xarning message using printf format. + * Log a warning message using printf format. */ public static function warning(string $msg, ...$args) { @@ -90,12 +96,12 @@ class Logger } /** - * Log an exception. + * Log an exception as an error. */ - public static function exception(Throwable $e, bool $withtrace = false) + public static function errorex(Throwable $e, bool $withtrace = false) { if (self::$verbosity > 0) { - $msg = "{$e->getMessage()} in {$e->getFile()}({$e->getLine()})"; + $msg = self::exceptionmessage($e); if ($withtrace) { // TODO: Maybe print a more beautiful stack trace. $msg .= PHP_EOL . $e->getTraceAsString(); @@ -103,4 +109,34 @@ class Logger self::write('ERROR', $msg); } } + + /** + * Log an exception as a warning. + */ + public static function warningex(Throwable $e) + { + if (self::$verbosity > 1) { + self::write('WARN', self::exceptionmessage($e)); + } + } + + /** + * Log an exception as an info. + */ + public static function infoex(Throwable $e) + { + if (self::$verbosity > 2) { + self::write('INFO', self::exceptionmessage($e)); + } + } + + /** + * Log an exception as a debug. + */ + public static function debugex(Throwable $e) + { + if (self::$verbosity > 3) { + self::write('DEBUG', self::exceptionmessage($e)); + } + } } diff --git a/index.php b/index.php index fb05952..230b0e6 100644 --- a/index.php +++ b/index.php @@ -7,7 +7,11 @@ session_start(); require('./vendor/autoload.php'); -Logger::init('w_error.log', 2); +try { + Logger::init('w_error.log', 2); +} catch (Throwable $e) { + die('Unable to init logs: ' . $e->getMessage()); +} $app = new Wcms\Application(); $app->wakeup(); @@ -33,6 +37,6 @@ try { if (isreportingerrors()) { Sentry\captureException($e); } - Logger::exception($e, true); + Logger::errorex($e, true); echo '

⚠ Woops ! There is a little problem :

', $e->getMessage(), "\n"; } diff --git a/tests/LoggerTest.php b/tests/LoggerTest.php index b4b87f4..eb237ce 100644 --- a/tests/LoggerTest.php +++ b/tests/LoggerTest.php @@ -3,7 +3,7 @@ namespace Wcms\Tests; use Exception; -use InvalidArgumentException; +use RuntimeException; use PHPUnit\Framework\TestCase; use Throwable; use Wcms\Logger; @@ -40,7 +40,7 @@ class LoggerTest extends FilesTest $dir = 'not/existing/path'; $file = "$dir/w_error.log"; $this->assertDirectoryNotExists($dir); - $this->expectException(InvalidArgumentException::class); + $this->expectException(RuntimeException::class); $this->expectExceptionMessage("Parent directory of '$file' does not exist."); Logger::init($file); $this->assertFileNotExists($file); @@ -55,7 +55,7 @@ class LoggerTest extends FilesTest $file = "$dir/w_error.log"; $this->assertDirectoryExists($dir); $this->assertDirectoryNotIsWritable($dir); - $this->expectException(InvalidArgumentException::class); + $this->expectException(RuntimeException::class); $this->expectExceptionMessage("Parent directory of '$file' is not writable."); Logger::init($file); $this->assertFileNotExists($file); @@ -70,7 +70,7 @@ class LoggerTest extends FilesTest $this->assertDirectoryExists(dirname($file)); $this->assertDirectoryIsWritable(dirname($file)); $this->assertNotIsWritable($file); - $this->expectException(InvalidArgumentException::class); + $this->expectException(RuntimeException::class); $this->expectExceptionMessage("The logfile '$file' is not writable."); Logger::init($file); $this->assertFileNotExists($file); @@ -224,35 +224,35 @@ class LoggerTest extends FilesTest /** * @test - * @dataProvider exceptionNotLoggedProvider + * @dataProvider errorexNotLoggedProvider */ - public function exceptionNotLoggedTest(int $verbosity): void + public function errorexNotLoggedTest(int $verbosity): void { Logger::init($this->logfile, $verbosity); - Logger::exception(new Exception('Error')); + Logger::errorex(new Exception('Error')); $this->assertEmpty(file_get_contents($this->logfile)); } - public function exceptionNotLoggedProvider(): array + public function errorexNotLoggedProvider(): array { return [[0]]; } /** * @test - * @dataProvider exceptionLoggedProvider + * @dataProvider errorexLoggedProvider */ - public function exceptionLoggedTest(int $verbosity, Throwable $e, string $expected, int $line) + public function errorexLoggedTest(int $verbosity, Throwable $e, string $expected, int $line) { Logger::init($this->logfile, $verbosity); - Logger::exception($e); + Logger::errorex($e); $file = __FILE__; $line += 258; $expected = " [ ERROR ] tests/LoggerTest.php(248) $expected in $file($line)\n"; $this->assertEquals($expected, substr(file_get_contents($this->logfile), 25)); } - public function exceptionLoggedProvider(): array + public function errorexLoggedProvider(): array { return [ [1, new Exception('Test 1'), 'Test 1', 0], @@ -265,13 +265,127 @@ class LoggerTest extends FilesTest /** * @test */ - public function exceptionBacktraceTest(): void + public function errorexBacktraceTest(): void { Logger::init($this->logfile, 1); - Logger::exception(new Exception('Error'), true); + Logger::errorex(new Exception('Error'), true); $content = file_get_contents($this->logfile); $expected = " [ ERROR ] tests/LoggerTest.php(271) Error "; $this->assertEquals($expected, substr($content, 25, 43)); $this->assertRegExp('/(#\d+ [\w\/\.]*\(\d+\): .*\)\n)+#\d+ \{main\}\n/U', $content); } + + /** + * @test + * @dataProvider warningexNotLoggedProvider + */ + public function warningexNotLoggedTest(int $verbosity): void + { + Logger::init($this->logfile, $verbosity); + Logger::warningex(new Exception('Error')); + $this->assertEmpty(file_get_contents($this->logfile)); + } + + public function warningexNotLoggedProvider(): array + { + return [[0],[1]]; + } + + /** + * @test + * @dataProvider warningexLoggedProvider + */ + public function warningexLoggedTest(int $verbosity, Throwable $e, string $expected, int $line) + { + Logger::init($this->logfile, $verbosity); + Logger::warningex($e); + $file = __FILE__; + $line += 311; + $expected = " [ WARN ] tests/LoggerTest.php(301) $expected in $file($line)\n"; + $this->assertEquals($expected, substr(file_get_contents($this->logfile), 25)); + } + + public function warningexLoggedProvider(): array + { + return [ + [2, new Exception('Test 1'), 'Test 1', 0], + [3, new Exception('Test 2'), 'Test 2', 1], + [4, new Exception('Test 3'), 'Test 3', 2], + ]; + } + + /** + * @test + * @dataProvider infoexNotLoggedProvider + */ + public function infoexNotLoggedTest(int $verbosity): void + { + Logger::init($this->logfile, $verbosity); + Logger::infoex(new Exception('Error')); + $this->assertEmpty(file_get_contents($this->logfile)); + } + + public function infoexNotLoggedProvider(): array + { + return [[0],[1],[2]]; + } + + /** + * @test + * @dataProvider infoexLoggedProvider + */ + public function infoexLoggedTest(int $verbosity, Throwable $e, string $expected, int $line) + { + Logger::init($this->logfile, $verbosity); + Logger::infoex($e); + $file = __FILE__; + $line += 350; + $expected = " [ INFO ] tests/LoggerTest.php(340) $expected in $file($line)\n"; + $this->assertEquals($expected, substr(file_get_contents($this->logfile), 25)); + } + + public function infoexLoggedProvider(): array + { + return [ + [3, new Exception('Test 1'), 'Test 1', 0], + [4, new Exception('Test 2'), 'Test 2', 1], + ]; + } + + /** + * @test + * @dataProvider debugexNotLoggedProvider + */ + public function debugexNotLoggedTest(int $verbosity): void + { + Logger::init($this->logfile, $verbosity); + Logger::debugex(new Exception('Error')); + $this->assertEmpty(file_get_contents($this->logfile)); + } + + public function debugexNotLoggedProvider(): array + { + return [[0],[1],[2],[3]]; + } + + /** + * @test + * @dataProvider debugexLoggedProvider + */ + public function debugexLoggedTest(int $verbosity, Throwable $e, string $expected, int $line) + { + Logger::init($this->logfile, $verbosity); + Logger::debugex($e); + $file = __FILE__; + $line += 388; + $expected = " [ DEBUG ] tests/LoggerTest.php(378) $expected in $file($line)\n"; + $this->assertEquals($expected, substr(file_get_contents($this->logfile), 25)); + } + + public function debugexLoggedProvider(): array + { + return [ + [4, new Exception('Test 4'), 'Test 4', 0], + ]; + } } -- cgit v1.2.3 From 03d425bdd9a639446ae72ce6556d753f2f162f83 Mon Sep 17 00:00:00 2001 From: n-peugnet Date: Thu, 23 Apr 2020 15:38:17 +0200 Subject: tests(ci): problemMatchers, 3 php versions, optims Add problem matchers for phpcs, phpstan and phpunit. Add composer cache Test over multiple php version --- .github/matchers/phpcs.json | 19 ++++++++++ .github/matchers/phpstan.json | 16 ++++++++ .github/matchers/phpunit.json | 25 ++++++++++++ .github/workflows/php.yml | 88 ++++++++++++++++++++++++++++++++----------- Makefile | 4 +- README.md | 4 +- phpcs.xml | 1 - 7 files changed, 131 insertions(+), 26 deletions(-) create mode 100644 .github/matchers/phpcs.json create mode 100644 .github/matchers/phpstan.json create mode 100644 .github/matchers/phpunit.json diff --git a/.github/matchers/phpcs.json b/.github/matchers/phpcs.json new file mode 100644 index 0000000..339af9a --- /dev/null +++ b/.github/matchers/phpcs.json @@ -0,0 +1,19 @@ +{ + "problemMatcher": [ + { + "owner": "phpcs", + "fileLocation": "relative", + "pattern": [ + { + "regexp": "^\"(.+)\",(\\d+),(\\d+),(.+),\"(.+)\",(.+),(\\d+),(\\d+)$", + "file": 1, + "line": 2, + "column": 3, + "severity": 4, + "message": 5, + "code": 6 + } + ] + } + ] +} \ No newline at end of file diff --git a/.github/matchers/phpstan.json b/.github/matchers/phpstan.json new file mode 100644 index 0000000..3e6bc6c --- /dev/null +++ b/.github/matchers/phpstan.json @@ -0,0 +1,16 @@ +{ + "problemMatcher": [ + { + "owner": "phpstan", + "severity": "error", + "pattern": [ + { + "regexp": "^(.+):(\\d+):(.+)$", + "file": 1, + "line": 2, + "message": 3 + } + ] + } + ] +} \ No newline at end of file diff --git a/.github/matchers/phpunit.json b/.github/matchers/phpunit.json new file mode 100644 index 0000000..0869357 --- /dev/null +++ b/.github/matchers/phpunit.json @@ -0,0 +1,25 @@ +{ + "problemMatcher": [ + { + "owner": "phpunit", + "fileLocation": "absolute", + "pattern": [ + { + "regexp": "^\\d+\\)\\s.*$" + }, + { + "regexp": "^(.*)$", + "message": 1 + }, + { + "regexp": "^\\s*$" + }, + { + "regexp": "^(.*):(\\d+)$", + "file": 1, + "line": 2 + } + ] + } + ] +} \ No newline at end of file diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index 479a9f9..039daca 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -1,46 +1,92 @@ -name: build +name: checks on: - push - pull_request jobs: - php-build: + test-php: + name: test (php ${{ matrix.php-versions }}) runs-on: ubuntu-latest + strategy: + matrix: + php-versions: ['7.2', '7.3', '7.4'] steps: - name: Git checkout uses: actions/checkout@v2 + - name: Setup PHP, with composer and extensions + uses: shivammathur/setup-php@v2 #https://github.com/shivammathur/setup-php + with: + php-version: ${{ matrix.php-versions }} + coverage: xdebug + - name: Validate composer.json and composer.lock run: composer validate + - name: Get composer cache directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Cache dependencies + uses: actions/cache@v1 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer- + - name: Install dependencies run: composer install --prefer-dist --no-progress --no-suggest - - name: Run test suite - run: make check -k - - - name: PHPStan xml report - if: always() + - name: PHPUnit run: | - mkdir -p build/phpstan - vendor/bin/phpstan analyse --no-progress --error-format=checkstyle > build/phpstan/checkstyle.xml - - - name: Analysis Publisher - uses: digirati-labs/analysis-publisher@0.0.1 - if: failure() - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - args: > - --report-type=checkstyle --path=**/build/phpcs/checkstyle.xml - --report-type=checkstyle --path=**/build/phpstan/checkstyle.xml - --publisher=github_check + echo "::add-matcher::.github/matchers/phpunit.json" + make test + echo "::remove-matcher owner=phpunit::" - name: Coveralls publish - if: always() env: COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | composer require --quiet --no-interaction cedx/coveralls vendor/bin/coveralls build/phpunit/cov.xml + + lint: + name: lint + runs-on: ubuntu-latest + steps: + - name: Git checkout + uses: actions/checkout@v2 + + - name: Validate composer.json and composer.lock + run: composer validate + + - name: Get composer cache directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Cache dependencies + uses: actions/cache@v1 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer- + + - name: Install dependencies + run: composer install --prefer-dist --no-progress --no-suggest + + - name: PHPCS + if: always() + run: | + echo "::add-matcher::.github/matchers/phpcs.json" + vendor/bin/phpcs --report=csv + echo "::remove-matcher owner=phpcs::" + + - name: PHPStan + if: always() + run: | + echo "::add-matcher::.github/matchers/phpstan.json" + vendor/bin/phpstan analyse --error-format=raw --no-progress + echo "::remove-matcher owner=phpstan::" diff --git a/Makefile b/Makefile index b68717a..1204a5a 100644 --- a/Makefile +++ b/Makefile @@ -166,7 +166,7 @@ check: vendor lint analyse test # Lint php code with phpcs. .PHONY: lint lint: $(phpcs_dir) - phpcs --report-full --report-checkstyle=$(phpcs_dir)/checkstyle.xml + phpcs --report-full --report-summary --cache=$(phpcs_dir)/result.cache # Analyse php code with phpstan. .PHONY: analyse @@ -176,7 +176,7 @@ analyse: # Test php code with phpunit. .PHONY: test test: $(phpunit_dir) - phpunit --log-junit $(phpunit_dir)/junit.xml + phpunit # Create dirs if the do not exist $(dirs): diff --git a/README.md b/README.md index 3336429..492b6c9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # W-CMS -[![build][github]][action] ![style][codestyle] ![phpstan][phpstan] [![coverage][coverage]][coveralls] +[![checks][github]][action] ![style][codestyle] ![phpstan][phpstan] [![coverage][coverage]][coveralls] W is a lightweight CMS tool, meant to help you design a website using a unique approach. It's targeting artists, or experimental projects. @@ -178,7 +178,7 @@ Then, to make the release, run the following command: To only build the release zip, simply run `make dist`. This will create a zip file in `dist/` of the current version. -[github]: https://github.com/vincent-peugnet/wcms/workflows/build/badge.svg +[github]: https://github.com/vincent-peugnet/wcms/workflows/checks/badge.svg [action]: https://github.com/vincent-peugnet/wcms/actions [codestyle]: https://img.shields.io/badge/code%20style-PSR12-brightgreen [phpstan]: https://img.shields.io/badge/phpstan-level%205-green diff --git a/phpcs.xml b/phpcs.xml index 74932eb..0432286 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -15,7 +15,6 @@ - -- cgit v1.2.3 From 385b3f4adf86606e03941171c136d8f2eb2b35c2 Mon Sep 17 00:00:00 2001 From: n-peugnet Date: Fri, 24 Apr 2020 16:36:12 +0200 Subject: fix: most of PHPStan errors --- app/class/Colors.php | 10 +++++----- app/class/Controller.php | 2 +- app/class/Controlleradmin.php | 2 +- app/class/Controllerconnect.php | 7 +++---- app/class/Controllermedia.php | 6 +++++- app/class/Controllerpage.php | 3 ++- app/class/Dbitem.php | 2 +- app/class/Event.php | 7 ++----- app/class/Flywheel/Formatter/JSON.php | 6 ++---- app/class/Item.php | 6 +++--- app/class/Media.php | 1 + app/class/Modelhome.php | 6 +++--- app/class/Modelmedia.php | 2 +- app/class/Modelpage.php | 7 ++++--- app/class/Modelrender.php | 13 +++++++++---- app/class/Modeltimeline.php | 5 +++-- app/class/Page.php | 15 +++++++-------- app/class/User.php | 2 +- app/fn/fn.php | 4 ++-- 19 files changed, 56 insertions(+), 50 deletions(-) diff --git a/app/class/Colors.php b/app/class/Colors.php index 234adb2..ffa56b6 100644 --- a/app/class/Colors.php +++ b/app/class/Colors.php @@ -5,7 +5,7 @@ namespace Wcms; class Colors extends Item { - protected $file = MODEL::CSS_DIR . 'tagcolors.css'; + protected $file = Model::CSS_DIR . 'tagcolors.css'; protected $rawcss = ""; @@ -27,7 +27,7 @@ class Colors extends Item public function readcssfile(): bool { - if (MODEL::dircheck(MODEL::CSS_DIR) && file_exists($this->file)) { + if (Model::dircheck(Model::CSS_DIR) && file_exists($this->file)) { $this->rawcss = file_get_contents($this->file); return true; } else { @@ -53,7 +53,7 @@ class Colors extends Item /** * Transform a CSS string in a array of `tag => background-color` * - * @return array Ouput array using TAG as key and Hex Color as value + * @return bool Ouput array using TAG as key and Hex Color as value */ public function parsetagcss() { @@ -79,7 +79,7 @@ class Colors extends Item public function writecssfile() { - if (MODEL::dircheck(MODEL::CSS_DIR)) { + if (Model::dircheck(Model::CSS_DIR)) { return file_put_contents($this->file, $this->rawcss); } } @@ -90,7 +90,7 @@ class Colors extends Item foreach ($this->tagcolor as $tag => $color) { $i = ''; $l = ''; - $html .= '\n
  • ' . $i . $l . '
  • '; + $html .= "\n
  • " . $i . $l . '
  • '; } $html .= PHP_EOL . ''; return $html; diff --git a/app/class/Controller.php b/app/class/Controller.php index 4185be8..34b3d11 100644 --- a/app/class/Controller.php +++ b/app/class/Controller.php @@ -33,7 +33,7 @@ class Controller $this->router = $router; $this->pagemanager = new Modelpage(); $this->initplates(); - $this->now = new DateTimeImmutable(null, timezone_open("Europe/Paris")); + $this->now = new DateTimeImmutable("now", timezone_open("Europe/Paris")); } public function setuser() diff --git a/app/class/Controlleradmin.php b/app/class/Controlleradmin.php index d3ceab7..f68cb82 100644 --- a/app/class/Controlleradmin.php +++ b/app/class/Controlleradmin.php @@ -45,7 +45,7 @@ class Controlleradmin extends Controller public function update() { - MODEL::dircheck(MODEL::GLOBAL_DIR); + Model::dircheck(Model::GLOBAL_DIR); $globalcss = file_put_contents(Model::GLOBAL_DIR . 'global.css', $_POST['globalcss']); diff --git a/app/class/Controllerconnect.php b/app/class/Controllerconnect.php index 24b0c3c..9dc788b 100644 --- a/app/class/Controllerconnect.php +++ b/app/class/Controllerconnect.php @@ -83,7 +83,7 @@ class Controllerconnect extends Controller /** * Create a token stored in the database and then a cookie * - * @return string|bool Token in cas of success, otherwise, false. + * @return string|false Token in cas of success, otherwise, false. */ public function createauthtoken() { @@ -95,9 +95,8 @@ class Controllerconnect extends Controller if ($cookiecreation) { return $tokenid; } - } else { - return false; } + return false; } /** @@ -112,7 +111,7 @@ class Controllerconnect extends Controller { $hash = secrethash($token); $cookie = $token . ':' . $hash; - return setcookie('authtoken', $cookie, time() + $conservation * 24 * 3600, null, null, false, true); + return setcookie('authtoken', $cookie, time() + $conservation * 24 * 3600, "", "", false, true); } /** diff --git a/app/class/Controllermedia.php b/app/class/Controllermedia.php index 06885b3..95b4f9b 100644 --- a/app/class/Controllermedia.php +++ b/app/class/Controllermedia.php @@ -18,6 +18,9 @@ class Controllermedia extends Controller $this->mediamanager = new Modelmedia(); } + /** + * @throws Exception + */ public function desktop() { if ($this->user->iseditor()) { @@ -81,8 +84,9 @@ class Controllermedia extends Controller $dir = $_POST['dir'] ?? Model::MEDIA_DIR; $name = idclean($_POST['foldername']) ?? 'new-folder'; $this->mediamanager->adddir($dir, $name); + $this->redirect($this->generate('media') . '?path=/' . $dir . DIRECTORY_SEPARATOR . $name); } - $this->redirect($this->generate('media') . '?path=/' . $dir . DIRECTORY_SEPARATOR . $name); + $this->routedirect('home'); } public function folderdelete() diff --git a/app/class/Controllerpage.php b/app/class/Controllerpage.php index 9d20ded..ad6bf82 100644 --- a/app/class/Controllerpage.php +++ b/app/class/Controllerpage.php @@ -99,7 +99,7 @@ class Controllerpage extends Controller */ public function renderpage(Page $page): Page { - $now = new DateTimeImmutable(null, timezone_open("Europe/Paris")); + $now = new DateTimeImmutable("now", timezone_open("Europe/Paris")); $renderengine = new Modelrender($this->router); @@ -128,6 +128,7 @@ class Controllerpage extends Controller $this->setpage($id, 'pageread/'); $pageexist = $this->importpage(); + $canread = false; if ($pageexist) { $canread = $this->user->level() >= $this->page->secure(); diff --git a/app/class/Dbitem.php b/app/class/Dbitem.php index 44dec2c..29f7a2c 100644 --- a/app/class/Dbitem.php +++ b/app/class/Dbitem.php @@ -11,7 +11,7 @@ abstract class Dbitem extends Item public function dry() { $array = []; - foreach ($this as $var => $value) { + foreach (get_object_vars($this) as $var => $value) { if ($value instanceof DateTime || $value instanceof DateTimeImmutable) { $array[$var] = $this->$var('string'); } else { diff --git a/app/class/Event.php b/app/class/Event.php index 3317a1b..069050a 100644 --- a/app/class/Event.php +++ b/app/class/Event.php @@ -40,7 +40,7 @@ class Event extends Dbitem public function stamp() { - $this->date = new DateTimeImmutable(null, timezone_open("Europe/Paris")); + $this->date = new DateTimeImmutable("now", timezone_open("Europe/Paris")); $this->user = idclean($this->user); if (in_array($this->type, self::EVENT_ART)) { $this->target = idclean($this->target); @@ -66,16 +66,13 @@ class Event extends Dbitem switch ($type) { case 'datetime': return $this->date; - break; case 'string': return $this->date->format(DateTime::ISO8601); - break; case 'hrdi': - $now = new DateTimeImmutable(null, timezone_open("Europe/Paris")); + $now = new DateTimeImmutable("now", timezone_open("Europe/Paris")); return hrdi($this->date->diff($now)); - break; } } diff --git a/app/class/Flywheel/Formatter/JSON.php b/app/class/Flywheel/Formatter/JSON.php index d55c3b6..108c756 100644 --- a/app/class/Flywheel/Formatter/JSON.php +++ b/app/class/Flywheel/Formatter/JSON.php @@ -10,13 +10,11 @@ class JSON implements \JamesMoss\Flywheel\Formatter\FormatInterface } public function encode(array $data) { - $options = defined('JSON_PRETTY_PRINT') ? JSON_PRETTY_PRINT : null; - $options .= JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE; + $options = defined('JSON_PRETTY_PRINT') ? JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE : null; return json_encode($data, $options); } public function decode($data) { - $options = defined('JSON_OBJECT_AS_ARRAY') ? JSON_OBJECT_AS_ARRAY : null; - return json_decode($data, $options); + return json_decode($data, true); } } diff --git a/app/class/Item.php b/app/class/Item.php index 8a8f2d6..a76e700 100644 --- a/app/class/Item.php +++ b/app/class/Item.php @@ -33,7 +33,7 @@ abstract class Item public function dry() { $array = []; - foreach ($this as $var => $value) { + foreach (get_object_vars($this) as $var => $value) { $array[$var] = $this->$var(); } return $array; @@ -74,13 +74,13 @@ abstract class Item } elseif ($option == 'date' || $option == 'sort') { return $this->$property; } elseif ($option == 'hrdi') { - $now = new DateTimeImmutable(null, timezone_open("Europe/Paris")); + $now = new DateTimeImmutable("now", timezone_open("Europe/Paris")); return hrdi($this->$property->diff($now)); } elseif ($option == 'pdate') { return $this->$property->format('Y-m-d'); } elseif ($option == 'ptime') { return $this->$property->format('H:i'); - } elseif ($option = 'dmy') { + } elseif ($option == 'dmy') { return $this->$property->format('d/m/Y'); } } else { diff --git a/app/class/Media.php b/app/class/Media.php index 9df2fef..b08726d 100644 --- a/app/class/Media.php +++ b/app/class/Media.php @@ -5,6 +5,7 @@ namespace Wcms; use DateTime; use DateTimeImmutable; use DateTimeZone; +use Exception; class Media extends Item { diff --git a/app/class/Modelhome.php b/app/class/Modelhome.php index b35fe6d..b798f56 100644 --- a/app/class/Modelhome.php +++ b/app/class/Modelhome.php @@ -29,7 +29,7 @@ class Modelhome extends Modelpage * @param Opt $opt * * @param string $regex Regex to match. - * @param array $options Option search, could be `content` `title` `description`. + * @param array $searchopt Option search, could be `content` `title` `description`. * * @return array associative array of `Page` objects * */ @@ -98,7 +98,7 @@ class Modelhome extends Modelpage /** * Search for regex and count occurences * - * @param array $page list Array of Pages. + * @param array $pagelist list Array of Pages. * @param string $regex Regex to match. * @param array $options Option search, could be `content` `title` `description`. * @@ -279,7 +279,7 @@ class Modelhome extends Modelpage /** - * @param array array of the columns to show from the user + * @param array $columns array of the columns to show from the user * * @return array assoc each key columns to a boolean value to show or not */ diff --git a/app/class/Modelmedia.php b/app/class/Modelmedia.php index ceb9bc7..bd0ff03 100644 --- a/app/class/Modelmedia.php +++ b/app/class/Modelmedia.php @@ -75,7 +75,7 @@ class Modelmedia extends Model * * @param array $medialist * @param string $sortby - * @param int order Can be 1 or -1 + * @param int $order Can be 1 or -1 */ public function medialistsort(array &$medialist, string $sortby = 'id', int $order = 1): bool { diff --git a/app/class/Modelpage.php b/app/class/Modelpage.php index 8bfa757..e2a2718 100644 --- a/app/class/Modelpage.php +++ b/app/class/Modelpage.php @@ -5,6 +5,7 @@ namespace Wcms; use Exception; use JamesMoss\Flywheel\Document; use DateTimeImmutable; +use LogicException; class Modelpage extends Modeldb { @@ -17,7 +18,7 @@ class Modelpage extends Modeldb $this->dbinit(Model::PAGES_DIR); $this->storeinit(Config::pagetable()); if (!$this->dircheck(Model::HTML_RENDER_DIR)) { - throw new Exception("Media error : Cant create /render folder"); + throw new LogicException("Media error : Cant create /render folder"); } } @@ -143,7 +144,7 @@ class Modelpage extends Modeldb /** * Delete a page and it's linked rendered html and css files * - * @param Page|string $id could be an Page object or a id string + * @param Page|string $page could be an Page object or a id string * * @return bool true if success otherwise false */ @@ -423,7 +424,7 @@ class Modelpage extends Modeldb */ public function reset(Page $page, array $reset): Page { - $now = new DateTimeImmutable(null, timezone_open("Europe/Paris")); + $now = new DateTimeImmutable("now", timezone_open("Europe/Paris")); if ($reset['tag']) { $page->settag([]); } diff --git a/app/class/Modelrender.php b/app/class/Modelrender.php index 553857b..7322955 100644 --- a/app/class/Modelrender.php +++ b/app/class/Modelrender.php @@ -3,6 +3,7 @@ namespace Wcms; use Exception; +use LogicException; use Michelf\MarkdownExtra; class Modelrender extends Modelpage @@ -56,7 +57,11 @@ class Modelrender extends Modelpage */ public function upage(string $id): string { - return $this->generate('pageread/', ['page' => $id]); + try { + return $this->router->generate('pageread/', ['page' => $id]); + } catch (Exception $e) { + throw new LogicException($e->getMessage(), $e->getCode(), $e); + } } @@ -128,7 +133,7 @@ class Modelrender extends Modelpage $matches = $this->match($body, $regex); // First, analyse the synthax and call the corresponding methods - if (isset($matches)) { + if (!empty($matches)) { foreach ($matches as $key => $match) { $element = new Element($this->page->id(), $match); $element->setcontent($this->getelementcontent($element->sources(), $element->type())); @@ -534,7 +539,7 @@ class Modelrender extends Modelpage { $matches = $this->match($text, 'MEDIA'); - if (isset($matches)) { + if (!empty($matches)) { foreach ($matches as $match) { $medialist = new Medialist($match); $medialist->readoptions(); @@ -575,7 +580,7 @@ class Modelrender extends Modelpage $modelhome = new Modelhome(); - if (isset($matches)) { + if (!empty($matches)) { foreach ($matches as $match) { $optlist = new Optlist(['render' => $this]); $optlist->parsehydrate($match['options']); diff --git a/app/class/Modeltimeline.php b/app/class/Modeltimeline.php index db9c4f5..be80211 100644 --- a/app/class/Modeltimeline.php +++ b/app/class/Modeltimeline.php @@ -19,7 +19,7 @@ class Modeltimeline extends Modeldb public function get(int $id) { - $eventdata = $this->repo->findById($id); + $eventdata = $this->repo->findById("$id"); if ($eventdata !== false) { return new Event($eventdata); } else { @@ -62,7 +62,7 @@ class Modeltimeline extends Modeldb /** * Store event * - * @param Event The event to be stored in the repositery + * @param Event $event The event to be stored in the repositery * * @return bool retrun true if it works, false if it fails */ @@ -97,6 +97,7 @@ class Modeltimeline extends Modeldb $id = 0; $subid = 0; $lastuser = null; + $groupedevents = []; foreach ($events as $event) { if ($event->user() !== $lastuser) { $subid = 0; diff --git a/app/class/Page.php b/app/class/Page.php index 760521b..da149f7 100644 --- a/app/class/Page.php +++ b/app/class/Page.php @@ -53,8 +53,7 @@ class Page extends Dbitem public const TABS = ['main', 'css', 'header', 'body', 'nav', 'aside', 'footer', 'javascript']; public const VAR_DATE = ['date', 'datecreation', 'datemodif', 'daterender']; - - + // _____________________________________________________ F U N ____________________________________________________ @@ -71,7 +70,7 @@ class Page extends Dbitem public function reset() { - $now = new DateTimeImmutable(null, timezone_open("Europe/Paris")); + $now = new DateTimeImmutable("now", timezone_open("Europe/Paris")); $this->settitle($this->id()); $this->setdescription(''); @@ -460,7 +459,7 @@ class Page extends Dbitem if ($datecreation instanceof DateTimeImmutable) { $this->datecreation = $datecreation; } elseif ($datecreation === true) { - $this->datecreation = new DateTimeImmutable(null, timezone_open("Europe/Paris")); + $this->datecreation = new DateTimeImmutable("now", timezone_open("Europe/Paris")); } else { $this->datecreation = DateTimeImmutable::createFromFormat( DateTime::ISO8601, @@ -508,7 +507,7 @@ class Page extends Dbitem public function setjavascript($javascript) { - if (strlen($javascript < self::LENTEXT && is_string($javascript))) { + if (strlen($javascript) < self::LENTEXT && is_string($javascript)) { $this->javascript = $javascript; } } @@ -516,14 +515,14 @@ class Page extends Dbitem public function setbody($body) { - if (strlen($body < self::LENTEXT && is_string($body))) { + if (strlen($body) < self::LENTEXT && is_string($body)) { $this->body = $body; } } public function setheader($header) { - if (strlen($header < self::LENTEXT && is_string($header))) { + if (strlen($header) < self::LENTEXT && is_string($header)) { $this->header = $header; } } @@ -756,7 +755,7 @@ class Page extends Dbitem public function updateedited() { - $now = new DateTimeImmutable(null, timezone_open("Europe/Paris")); + $now = new DateTimeImmutable("now", timezone_open("Europe/Paris")); $this->setdatemodif($now); $this->addeditcount(); } diff --git a/app/class/User.php b/app/class/User.php index ecb4507..a62091f 100644 --- a/app/class/User.php +++ b/app/class/User.php @@ -90,7 +90,7 @@ class User extends Item if (empty($this->expiredate)) { return 'never'; } else { - $now = new DateTimeImmutable(null, timezone_open("Europe/Paris")); + $now = new DateTimeImmutable("now", timezone_open("Europe/Paris")); if ($this->expiredate < $now) { return 'expired'; } else { diff --git a/app/fn/fn.php b/app/fn/fn.php index 243e056..6b312a2 100644 --- a/app/fn/fn.php +++ b/app/fn/fn.php @@ -24,7 +24,7 @@ function readablesize($bytes, $base = 2 ** 10) } elseif ($bytes < $base ** 3) { $num = round($bytes / $base ** 2, 1); $unit = 'M' . $i; - } elseif ($bytes < $base ** 4) { + } else { $num = round($bytes / $base ** 3, 1); $unit = 'G' . $i; } @@ -87,7 +87,7 @@ function arrayclean($input) return $output; } -function idclean(string $input) +function idclean(string $input): string { $input = urldecode($input); $search = ['é', 'à', 'è', 'ç', 'ù', 'ï', 'î', ' ']; -- cgit v1.2.3