From a296f4dc52b8c5c1f640bc5722a10de20dd6aaed Mon Sep 17 00:00:00 2001 From: Rotimi Ade Date: Thu, 13 May 2021 19:04:44 -0600 Subject: [PATCH] first commit --- .github/workflows/php.yml | 76 ++++++++++++++++++++++++++++++++++ .gitignore | 28 +++++++++++++ LICENSE | 29 +++++++++++++ README.md | 19 +++++++++ TODO.md | 16 +++++++ composer.json | 28 +++++++++++++ index.php | 17 ++++++++ phpunit.xml.dist | 21 ++++++++++ psalm.xml | 15 +++++++ rector.php | 29 +++++++++++++ src/FunctionExecutionTimer.php | 74 +++++++++++++++++++++++++++++++++ src/ObjectifiedCallable.php | 72 ++++++++++++++++++++++++++++++++ 12 files changed, 424 insertions(+) create mode 100644 .github/workflows/php.yml create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 TODO.md create mode 100644 composer.json create mode 100644 index.php create mode 100644 phpunit.xml.dist create mode 100644 psalm.xml create mode 100644 rector.php create mode 100644 src/FunctionExecutionTimer.php create mode 100644 src/ObjectifiedCallable.php diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml new file mode 100644 index 0000000..8446e1e --- /dev/null +++ b/.github/workflows/php.yml @@ -0,0 +1,76 @@ +name: Run PHP Tests and Code Quality Tools + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + schedule: + # Also run every Sunday at midnight + - cron: '0 0 * * 0' + +jobs: + build: + + runs-on: ${{ matrix.os }} + + strategy: + matrix: + php: [8.0, 7.4, 7.3] +# prefer-lowest is causing unit tests to fail when php 7.2 is run against PHPunit 7.x, +# PHPUnit 8.x is the latest stable release that supports PHP 7.2 and that runs fine +# dependency-version: [prefer-lowest, prefer-stable] + dependency-version: [prefer-stable] + os: [ubuntu-18.04, ubuntu-20.04] + include: + - os: ubuntu-18.04 + php: 7.3 + - os: ubuntu-18.04 + php: 7.4 + - os: ubuntu-18.04 + php: 8.0 + - os: ubuntu-20.04 + php: 7.4 + - os: ubuntu-20.04 + php: 8.0 + exclude: + - os: ubuntu-20.04 + php: 7.3 + + name: PHP-${{ matrix.php }} - ${{ matrix.dependency-version }} - ${{ matrix.os }} + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + ini-values: pcre.jit=0, pcre.backtrack_limit=9999999, pcre.recursion_limit=9999999 + coverage: none + + - name: PHP version + run: php -v + + - name: Composer version + run: composer --version + + - name: Validate composer.json and composer.lock + run: composer validate + + - name: Install Dependencies + run: composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction --no-progress + + # Add a test script to composer.json, for instance: "test": "vendor/bin/phpunit" + # Docs: https://getcomposer.org/doc/articles/scripts.md + - name: Run PHPUnit Test Suite + run: vendor/bin/phpunit + + - name: Run Rector + # Run rector for PHP 7.X but not 8.0, rector is currently blowing up with PHP 8.0 + if: matrix.php != '8.0' + run: vendor/bin/rector process src --dry-run + + - name: Run Psalm + run: vendor/bin/psalm diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..034dde5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,28 @@ +/composer.lock +*~ +*.bak +Thumbs.db +desktop.ini +.DS_Store +.buildpath +.project +.settings +*.tmproj +build +.idea +.phpunit.result.cache + +nbproject/ +/nbproject/ +/nbproject/* +/nbproject/*.* +/nbproject/*/ + +vendor/ +/vendor/ +/vendor/* +/vendor/*.* +/vendor/*/ + +composer.lock +phpunit.xml diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..fbb5b69 --- /dev/null +++ b/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2020, Rotexsoft +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..2531d83 --- /dev/null +++ b/README.md @@ -0,0 +1,19 @@ +# Function Execution Timer + +[![PHP Tests and Code Quality Tools](https://github.com/rotexsoft/function-execution-timer/workflows/Run%20PHP%20Tests%20and%20Code%20Quality%20Tools/badge.svg)](https://github.com/rotexsoft/function-execution-timer/actions?query=workflow%3A%22Run+PHP+Tests+and+Code+Quality+Tools%22)   +[![Release](https://img.shields.io/github/release/rotexsoft/function-execution-timer.png?style=flat-square)](https://github.com/rotexsoft/function-execution-timer/releases/latest)   +[![License](https://img.shields.io/badge/license-BSD-brightgreen.png?style=flat-square)](https://github.com/rotexsoft/function-execution-timer/blob/master/LICENSE)   + + +A simple PHP library for tracking the total amount of time a function / method takes to execute and return result(s) (if any). + + +## Installation + +**Via composer:** (Requires PHP 7.3+ or PHP 8.0+). + + composer require rotexsoft/function-execution-timer + +## Introduction + +A simple PHP library for tracking the total amount of time a function / method takes to execute and return result(s) (if any). \ No newline at end of file diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..fa1ad17 --- /dev/null +++ b/TODO.md @@ -0,0 +1,16 @@ +# Things To Do +* ~~Implement Generic Classes implementing the various interfaces~~ [DONE] +* Implement a profiling mechanism for debugging purposes that shows an audit trail of how permissions were calculated when isAllowed is invoked +* ~~Write unit tests~~ [DONE] +* ~~Hook up to travis and other code monitoring services~~ [DONE] +* Implement a separate package illustrating how to implement Owner, User and Group level permission enforcement +* Check other stuff in my other projects that could be of value in this one +* ~~Update class diagram once package is stable~~ [DONE] +* Document using this package using acl examples from existing application and even using examples from the zend packages. + * Add guidelines on how to customize this package to suit various requirements like the + Owner, User and Group level permission enforcement described above. +* Add a logging mechanism to log how permissions are calculated in isAllowed to a string + * This will require adding a getAuditTrail method to the collection interfaces and classes and also to the VersatileAcl class + * When setLogger is called on an instance of VersatileAcl, it will inject that logger into every collection it creates +* Submit to packagist once it's well done. +* When PHP 7.4 becomes the minimum version, change all class properties to typed properties and edit **rector.php** to include PHP 7.4 rules diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..d6c116d --- /dev/null +++ b/composer.json @@ -0,0 +1,28 @@ +{ + "name": "rotexsoft/function-execution-timer", + "description": "A simple PHP library for tracking the total amount of time a function / method takes to execute and return result(s) (if any).", + "license": "BSD-3-Clause", + "keywords": [ "function", "functions", "method", "methods", "profiler", "profiling", "benchmark", "benchmarks", "benchmarking", "execution", "time", "execution time"], + "homepage": "https://github.com/rotexsoft/function-execution-timer", + "authors": [ + { + "name": "Rotimi Adegbamigbe", + "email": "rotexdegba007-function.execution.timer@yahoo.com" + } + ], + "require": { + "php": ">=7.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.0", + "php-coveralls/php-coveralls": "^2.0", + "rector/rector": "^0.8.56", + "vimeo/psalm": "^4.3" + }, + "autoload": { + "classmap": [ "src/", "tests/" ] + }, + "scripts": { + "test": "vendor/bin/phpunit --coverage-text" + } +} diff --git a/index.php b/index.php new file mode 100644 index 0000000..d3aa100 --- /dev/null +++ b/index.php @@ -0,0 +1,17 @@ + + + + + + + + + + + diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..2cd38c2 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,21 @@ + + + + + ./src + + + + + + + + + + ./tests + + + + + + diff --git a/psalm.xml b/psalm.xml new file mode 100644 index 0000000..3e4e3d0 --- /dev/null +++ b/psalm.xml @@ -0,0 +1,15 @@ + + + + + + + + + diff --git a/rector.php b/rector.php new file mode 100644 index 0000000..7e25251 --- /dev/null +++ b/rector.php @@ -0,0 +1,29 @@ +parameters(); + + // Define what rule sets will be applied + $parameters->set(Option::SETS, [ + SetList::DEAD_CODE, + SetList::PHP_72, + SetList::PHP_73, + //SetList::PHP_74, + //SetList::PHP_80, + SetList::PERFORMANCE, + ]); + + // get services (needed for register a single rule) + // $services = $containerConfigurator->services(); + + // register a single rule + // $services->set(TypedPropertyRector::class); +}; diff --git a/src/FunctionExecutionTimer.php b/src/FunctionExecutionTimer.php new file mode 100644 index 0000000..b041869 --- /dev/null +++ b/src/FunctionExecutionTimer.php @@ -0,0 +1,74 @@ + $this->methodName, + 'args' => $args, + 'start_time' => $startTime, + 'end_time' => $endTime, + 'total_execution_time_in_seconds' => ($endTime - $startTime), + 'return_value' => $result, + ]; + + return $result; + } + + /** + * Return an array containing execution stats for all functions / methods called via all instances of this class + * + * @return array an array containing execution stats for all functions / methods called via all instances of this class + */ + public static function getBenchmarks(): array { + + return static::$benchmarks; + } + + /** + * Executes a callable + * + * @param string $funcName a name of your choosing (for the callable to be executed) that adheres to PHP method naming rules + * @param callable $funcImplementation the callable to be executed + * @param mixed $args arguments required by the callable to be executed + * + * @return mixed + */ + public static function callFunc( + string $funcName, callable $funcImplementation, ...$args + ) { + $funcObj = (new self($funcName, $funcImplementation)); + + return $funcObj(...$args); + } +} diff --git a/src/ObjectifiedCallable.php b/src/ObjectifiedCallable.php new file mode 100644 index 0000000..d41181c --- /dev/null +++ b/src/ObjectifiedCallable.php @@ -0,0 +1,72 @@ +methodName) when this object was created + * @param mixed $args arguments to pass to the function / method to be executed + * + * @return mixed result returned from executing function / method registered on an instance of this class + * + * @throws \Exception if $method !== $this->methodName + */ + public function __call($method, $args) { + + if( $this->methodName === $method ) { + + return $this(...$args); + + } else { + + throw new \InvalidArgumentException("Method `$method` not found."); + } + } + + /** + * Executes function / method registered on an instance of this class + * + * @param mixed $args arguments to pass to the function / method to be executed + * + * @return mixed result returned from executing function / method registered on an instance of this class + */ + public function __invoke(...$args) { + + $meth = $this->method; + return $meth(...$args); + } + + /** + * + * @param string $methodName a valid name (conforming to PHP's method naming convention) for the callable to be registered to this object + * @param callable $method a callable that will be executed via this object + */ + public function __construct (string $methodName, callable $method) { + + $cl = \Closure::fromCallable( $method ); + $this->method = $cl; + $this->methodName = $methodName; + } +}