diff --git a/.gitignore b/.gitignore index 21047c2..8b013d5 100644 --- a/.gitignore +++ b/.gitignore @@ -257,3 +257,4 @@ paket-files/ # in-progress: PHP version src/app/vendor +**/.env diff --git a/src/app/AppUser.php b/src/app/AppUser.php new file mode 100644 index 0000000..1e1035d --- /dev/null +++ b/src/app/AppUser.php @@ -0,0 +1,98 @@ + $_ENV['AUTH0_DOMAIN'], + 'clientId' => $_ENV['AUTH0_CLIENT_ID'], + 'clientSecret' => $_ENV['AUTH0_CLIENT_SECRET'], + 'cookieSecret' => $_ENV['AUTH0_COOKIE_SECRET'] + ]); + } + return self::$auth0; + } + + /** + * Determine the host to use for return URLs + * + * @return string The host for return URLs + */ + private static function host() + { + return 'http' . ($_SERVER['SERVER_PORT'] == 443 ? 's' : '' ) . "://{$_SERVER['HTTP_HOST']}"; + } + + /** + * Generate the log on callback URL + * + * @return string The log on callback URL + */ + private static function logOnCallback() + { + return self::host() . '/user/log-on/success'; + } + + /** + * Initiate a redirect to the Auth0 log on page + * + * @param string $nextUrl The URL (other than /journal) to which the user should be redirected + * @return never This function exits the currently running script + */ + public static function logOn(?string $nextUrl = null): never + { + // TODO: pass the next URL in the Auth0 callback + self::auth0Instance()->clear(); + header('Location: ' . self::auth0Instance()->login(self::logOnCallback())); + exit; + } + + /** + * Process the log on response from Auth0 + * + * @return never This function exits the currently running script + */ + public static function processLogOn(): never + { + self::auth0Instance()->exchange(self::logOnCallback()); + // TODO: check for next URL and redirect if present + header('Location: /journal'); + exit; + } + + /** + * Log off the current user + * + * @return never This function exits the currently running script + */ + public static function logOff(): never + { + header('Location: ' . self::auth0Instance()->logout(self::host() . '/')); + exit; + } + + /** + * Get the current user + * + * @return ?object The current user, or null if one is not signed in + */ + public static function current(): ?object + { + return self::auth0Instance()->getCredentials(); + } +} diff --git a/src/app/Data.php b/src/app/Data.php index 9bdfc3b..937fc1f 100644 --- a/src/app/Data.php +++ b/src/app/Data.php @@ -16,8 +16,7 @@ class Data */ public static function configure() { - Configuration::$connectionString = 'pgsql:host=localhost;port=5432;dbname=leafjson;user=leaf;password=leaf'; - Configuration::$startUp = '\MyPrayerJournal\Data::startUp'; + Configuration::$startUp = '\MyPrayerJournal\Data::startUp'; } /** diff --git a/src/app/Handlers.php b/src/app/Handlers.php new file mode 100644 index 0000000..5d3ed10 --- /dev/null +++ b/src/app/Handlers.php @@ -0,0 +1,63 @@ + $pageTitle, + 'isHtmx' => + array_key_exists('HTTP_HX_REQUEST', $_SERVER) + && (!array_key_exists('HTTP_HX_HISTORY_RESTORE_REQUEST', $_SERVER)), + 'user' => AppUser::current(), + 'hasSnoozed' => false, + ]); + $params['pageContent'] = app()->template->render($template, $params); + // TODO: make the htmx distinction here + response()->markup(app()->template->render('layout/full', $params)); + } + + /** + * Render a BareUI component template + * + * @param string $template The template name to render + * @param ?array $params Parameter to use to render the component (optional) + */ + private static function renderComponent(string $template, ?array $params = null) + { + $params = $params ?? []; + $params['pageContent'] = app()->template->render($template, $params); + header('Cache-Control: no-cache, max-age=-1'); + response()->markup(app()->template->render('layout/component', $params)); + } + + /** GET: /journal */ + public static function journal() + { + if (!AppUser::current()) AppUser::logOn(); + + $user = AppUser::current()->user; + $firstName = (array_key_exists('given_name', $user) ? $user['given_name'] : null) ?? 'Your'; + self::render('journal', $firstName . ($firstName == 'Your' ? '' : '’s') . ' Prayer Journal'); + } + + /** GET: /components/journal-items */ + public static function journalItems() + { + if (!AppUser::current()) AppUser::logOn(); + + self::renderComponent('components/journal_items', [ + 'requests' => Data::getJournal(AppUser::current()->user['sub']) + ]); + } +} diff --git a/src/app/composer.json b/src/app/composer.json index 0995f5e..102a1b3 100644 --- a/src/app/composer.json +++ b/src/app/composer.json @@ -4,7 +4,12 @@ "leafs/bareui": "^1.1", "leafs/db": "^2.1", "netresearch/jsonmapper": "^4.2", - "visus/cuid2": "^3.0" + "visus/cuid2": "^3.0", + "guzzlehttp/guzzle": "^7.8", + "guzzlehttp/psr7": "^2.6", + "http-interop/http-factory-guzzle": "^1.2", + "auth0/auth0-php": "^8.7", + "vlucas/phpdotenv": "^5.5" }, "autoload": { "psr-4": { @@ -12,5 +17,10 @@ "MyPrayerJournal\\": [ "." ], "MyPrayerJournal\\Domain\\": [ "./domain" ] } + }, + "config": { + "allow-plugins": { + "php-http/discovery": true + } } } diff --git a/src/app/composer.lock b/src/app/composer.lock index 5d425bb..f74602b 100644 --- a/src/app/composer.lock +++ b/src/app/composer.lock @@ -4,8 +4,631 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "3e1594cc7c6f8fe6041e1c22822e0ab2", + "content-hash": "14643f9ff62f769d0dc92694ad541085", "packages": [ + { + "name": "auth0/auth0-php", + "version": "8.7.1", + "source": { + "type": "git", + "url": "https://github.com/auth0/auth0-PHP.git", + "reference": "00202f130364add3e3c5708a235ac4a8c4b239bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/auth0/auth0-PHP/zipball/00202f130364add3e3c5708a235ac4a8c4b239bf", + "reference": "00202f130364add3e3c5708a235ac4a8c4b239bf", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-openssl": "*", + "php": "^8.0", + "php-http/multipart-stream-builder": "^1", + "psr-discovery/all": "^1", + "psr/http-client-implementation": "^1", + "psr/http-factory-implementation": "^1", + "psr/http-message-implementation": "^1" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3", + "mockery/mockery": "^1", + "pestphp/pest": "^2", + "phpstan/phpstan": "^1", + "phpstan/phpstan-strict-rules": "^1", + "psr-mock/http": "^1", + "rector/rector": "0.17.6", + "spatie/ray": "^1", + "symfony/cache": "^4 || ^5 || ^6", + "symfony/event-dispatcher": "^4 || ^5 || ^6", + "vimeo/psalm": "^5", + "wikimedia/composer-merge-plugin": "^2" + }, + "suggest": { + "psr/cache-implementation": "(PSR-6 Cache) Improve performance by avoiding making redundant network requests.", + "psr/event-dispatcher-implementation": "(PSR-14 Event Dispatcher) Observe and react to events when they occur." + }, + "type": "library", + "extra": { + "merge-plugin": { + "ignore-duplicates": false, + "include": [ + "composer.local.json" + ], + "merge-dev": true, + "merge-extra": false, + "merge-extra-deep": false, + "merge-scripts": false, + "recurse": true, + "replace": true + } + }, + "autoload": { + "psr-4": { + "Auth0\\SDK\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Auth0", + "email": "support@auth0.com", + "homepage": "https://auth0.com/" + } + ], + "description": "PHP SDK for Auth0 Authentication and Management APIs.", + "homepage": "https://github.com/auth0/auth0-PHP", + "keywords": [ + "Authentication", + "JSON Web Token", + "JWK", + "OpenId", + "api", + "auth", + "auth0", + "authorization", + "json web key", + "jwt", + "login", + "oauth", + "protect", + "secure" + ], + "support": { + "issues": "https://github.com/auth0/auth0-PHP/issues", + "source": "https://github.com/auth0/auth0-PHP/tree/8.7.1" + }, + "time": "2023-08-07T04:45:57+00:00" + }, + { + "name": "composer/semver", + "version": "3.3.2", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9", + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.4", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.3.2" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-04-01T19:23:25+00:00" + }, + { + "name": "graham-campbell/result-type", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/GrahamCampbell/Result-Type.git", + "reference": "672eff8cf1d6fe1ef09ca0f89c4b287d6a3eb831" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/672eff8cf1d6fe1ef09ca0f89c4b287d6a3eb831", + "reference": "672eff8cf1d6fe1ef09ca0f89c4b287d6a3eb831", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "phpoption/phpoption": "^1.9.1" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.32 || ^9.6.3 || ^10.0.12" + }, + "type": "library", + "autoload": { + "psr-4": { + "GrahamCampbell\\ResultType\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "An Implementation Of The Result Type", + "keywords": [ + "Graham Campbell", + "GrahamCampbell", + "Result Type", + "Result-Type", + "result" + ], + "support": { + "issues": "https://github.com/GrahamCampbell/Result-Type/issues", + "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", + "type": "tidelift" + } + ], + "time": "2023-02-25T20:23:15+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "7.8.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "1110f66a6530a40fe7aea0378fe608ee2b2248f9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/1110f66a6530a40fe7aea0378fe608ee2b2248f9", + "reference": "1110f66a6530a40fe7aea0378fe608ee2b2248f9", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.5.3 || ^2.0.1", + "guzzlehttp/psr7": "^1.9.1 || ^2.5.1", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "provide": { + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.1", + "ext-curl": "*", + "php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999", + "php-http/message-factory": "^1.1", + "phpunit/phpunit": "^8.5.29 || ^9.5.23", + "psr/log": "^1.1 || ^2.0 || ^3.0" + }, + "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "psr-18", + "psr-7", + "rest", + "web service" + ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.8.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", + "type": "tidelift" + } + ], + "time": "2023-08-27T10:20:53+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "111166291a0f8130081195ac4556a5587d7f1b5d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/111166291a0f8130081195ac4556a5587d7f1b5d", + "reference": "111166291a0f8130081195ac4556a5587d7f1b5d", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.1", + "phpunit/phpunit": "^8.5.29 || ^9.5.23" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/2.0.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2023-08-03T15:11:55+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "2.6.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "be45764272e8873c72dbe3d2edcfdfcc3bc9f727" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/be45764272e8873c72dbe3d2edcfdfcc3bc9f727", + "reference": "be45764272e8873c72dbe3d2edcfdfcc3bc9f727", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0", + "ralouphie/getallheaders": "^3.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.1", + "http-interop/http-factory-tests": "^0.9", + "phpunit/phpunit": "^8.5.29 || ^9.5.23" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/2.6.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", + "type": "tidelift" + } + ], + "time": "2023-08-27T10:13:57+00:00" + }, + { + "name": "http-interop/http-factory-guzzle", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/http-interop/http-factory-guzzle.git", + "reference": "8f06e92b95405216b237521cc64c804dd44c4a81" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/http-interop/http-factory-guzzle/zipball/8f06e92b95405216b237521cc64c804dd44c4a81", + "reference": "8f06e92b95405216b237521cc64c804dd44c4a81", + "shasum": "" + }, + "require": { + "guzzlehttp/psr7": "^1.7||^2.0", + "php": ">=7.3", + "psr/http-factory": "^1.0" + }, + "provide": { + "psr/http-factory-implementation": "^1.0" + }, + "require-dev": { + "http-interop/http-factory-tests": "^0.9", + "phpunit/phpunit": "^9.5" + }, + "suggest": { + "guzzlehttp/psr7": "Includes an HTTP factory starting in version 2.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Http\\Factory\\Guzzle\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "An HTTP Factory using Guzzle PSR7", + "keywords": [ + "factory", + "http", + "psr-17", + "psr-7" + ], + "support": { + "issues": "https://github.com/http-interop/http-factory-guzzle/issues", + "source": "https://github.com/http-interop/http-factory-guzzle/tree/1.2.0" + }, + "time": "2021-07-21T13:50:14+00:00" + }, { "name": "leafs/anchor", "version": "v1.5.0", @@ -513,6 +1136,1124 @@ }, "time": "2023-04-09T17:37:40+00:00" }, + { + "name": "php-http/discovery", + "version": "1.19.1", + "source": { + "type": "git", + "url": "https://github.com/php-http/discovery.git", + "reference": "57f3de01d32085fea20865f9b16fb0e69347c39e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/discovery/zipball/57f3de01d32085fea20865f9b16fb0e69347c39e", + "reference": "57f3de01d32085fea20865f9b16fb0e69347c39e", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0|^2.0", + "php": "^7.1 || ^8.0" + }, + "conflict": { + "nyholm/psr7": "<1.0", + "zendframework/zend-diactoros": "*" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "*", + "psr/http-factory-implementation": "*", + "psr/http-message-implementation": "*" + }, + "require-dev": { + "composer/composer": "^1.0.2|^2.0", + "graham-campbell/phpspec-skip-example-extension": "^5.0", + "php-http/httplug": "^1.0 || ^2.0", + "php-http/message-factory": "^1.0", + "phpspec/phpspec": "^5.1 || ^6.1 || ^7.3", + "symfony/phpunit-bridge": "^6.2" + }, + "type": "composer-plugin", + "extra": { + "class": "Http\\Discovery\\Composer\\Plugin", + "plugin-optional": true + }, + "autoload": { + "psr-4": { + "Http\\Discovery\\": "src/" + }, + "exclude-from-classmap": [ + "src/Composer/Plugin.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Finds and installs PSR-7, PSR-17, PSR-18 and HTTPlug implementations", + "homepage": "http://php-http.org", + "keywords": [ + "adapter", + "client", + "discovery", + "factory", + "http", + "message", + "psr17", + "psr7" + ], + "support": { + "issues": "https://github.com/php-http/discovery/issues", + "source": "https://github.com/php-http/discovery/tree/1.19.1" + }, + "time": "2023-07-11T07:02:26+00:00" + }, + { + "name": "php-http/multipart-stream-builder", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/multipart-stream-builder.git", + "reference": "f5938fd135d9fa442cc297dc98481805acfe2b6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/multipart-stream-builder/zipball/f5938fd135d9fa442cc297dc98481805acfe2b6a", + "reference": "f5938fd135d9fa442cc297dc98481805acfe2b6a", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "php-http/discovery": "^1.15", + "psr/http-factory-implementation": "^1.0" + }, + "require-dev": { + "nyholm/psr7": "^1.0", + "php-http/message": "^1.5", + "php-http/message-factory": "^1.0.2", + "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Http\\Message\\MultipartStream\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com" + } + ], + "description": "A builder class that help you create a multipart stream", + "homepage": "http://php-http.org", + "keywords": [ + "factory", + "http", + "message", + "multipart stream", + "stream" + ], + "support": { + "issues": "https://github.com/php-http/multipart-stream-builder/issues", + "source": "https://github.com/php-http/multipart-stream-builder/tree/1.3.0" + }, + "time": "2023-04-28T14:10:22+00:00" + }, + { + "name": "phpoption/phpoption", + "version": "1.9.1", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/php-option.git", + "reference": "dd3a383e599f49777d8b628dadbb90cae435b87e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/dd3a383e599f49777d8b628dadbb90cae435b87e", + "reference": "dd3a383e599f49777d8b628dadbb90cae435b87e", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.32 || ^9.6.3 || ^10.0.12" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": true + }, + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpOption\\": "src/PhpOption/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh" + }, + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "Option Type for PHP", + "keywords": [ + "language", + "option", + "php", + "type" + ], + "support": { + "issues": "https://github.com/schmittjoh/php-option/issues", + "source": "https://github.com/schmittjoh/php-option/tree/1.9.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", + "type": "tidelift" + } + ], + "time": "2023-02-25T19:38:58+00:00" + }, + { + "name": "psr-discovery/all", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/psr-discovery/all.git", + "reference": "73deceb26d3190f53a5cd3b95751c6a223804a8b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/psr-discovery/all/zipball/73deceb26d3190f53a5cd3b95751c6a223804a8b", + "reference": "73deceb26d3190f53a5cd3b95751c6a223804a8b", + "shasum": "" + }, + "require": { + "php": "^8.0", + "psr-discovery/cache-implementations": "^1.0", + "psr-discovery/container-implementations": "^1.0", + "psr-discovery/event-dispatcher-implementations": "^1.0", + "psr-discovery/http-client-implementations": "^1.0", + "psr-discovery/http-factory-implementations": "^1.0", + "psr-discovery/log-implementations": "^1.0" + }, + "type": "metapackage", + "extra": { + "merge-plugin": { + "ignore-duplicates": false, + "include": [ + "composer.local.json" + ], + "merge-dev": true, + "merge-extra": false, + "merge-extra-deep": false, + "merge-scripts": false, + "recurse": true, + "replace": true + } + }, + "autoload": { + "psr-4": { + "PsrDiscovery\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Evan Sims", + "email": "hello@evansims.com", + "homepage": "https://evansims.com/" + } + ], + "description": "Lightweight library that discovers available PSR implementations by searching for a list of well-known classes that implement the relevant interface, and returns an instance of the first one that is found.", + "homepage": "https://github.com/psr-discovery", + "keywords": [ + "PSR-11", + "discovery", + "psr", + "psr-14", + "psr-17", + "psr-18", + "psr-3", + "psr-6" + ], + "support": { + "source": "https://github.com/psr-discovery/all/tree/1.0.0" + }, + "time": "2023-03-27T16:37:46+00:00" + }, + { + "name": "psr-discovery/cache-implementations", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/psr-discovery/cache-implementations.git", + "reference": "33b63d8e324f4aff296508b592bbd4d71b45da68" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/psr-discovery/cache-implementations/zipball/33b63d8e324f4aff296508b592bbd4d71b45da68", + "reference": "33b63d8e324f4aff296508b592bbd4d71b45da68", + "shasum": "" + }, + "require": { + "php": "^8.0", + "psr-discovery/discovery": "^1.0", + "psr/cache": "^1.0 | ^2.0 | ^3.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.14", + "infection/infection": "^0.26", + "mockery/mockery": "^1.5", + "pestphp/pest": "^2.0", + "phpstan/phpstan": "^1.10", + "phpstan/phpstan-strict-rules": "^1.5", + "rector/rector": "^0.15", + "vimeo/psalm": "^5.8", + "wikimedia/composer-merge-plugin": "^2.0" + }, + "type": "library", + "extra": { + "merge-plugin": { + "ignore-duplicates": false, + "include": [ + "composer.local.json" + ], + "merge-dev": true, + "merge-extra": false, + "merge-extra-deep": false, + "merge-scripts": false, + "recurse": true, + "replace": true + } + }, + "autoload": { + "psr-4": { + "PsrDiscovery\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Evan Sims", + "email": "hello@evansims.com", + "homepage": "https://evansims.com/" + } + ], + "description": "Lightweight library that discovers available PSR-6 Cache implementations by searching for a list of well-known classes that implement the relevant interface, and returns an instance of the first one that is found.", + "homepage": "https://github.com/psr-discovery", + "keywords": [ + "cache", + "cache-implementation", + "discovery", + "psr", + "psr-6" + ], + "support": { + "issues": "https://github.com/psr-discovery/cache-implementations/issues", + "source": "https://github.com/psr-discovery/cache-implementations/tree/1.0.0" + }, + "time": "2023-03-27T06:19:44+00:00" + }, + { + "name": "psr-discovery/container-implementations", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/psr-discovery/container-implementations.git", + "reference": "366612e9260f247d8b8ee279094a33dd4cbc6886" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/psr-discovery/container-implementations/zipball/366612e9260f247d8b8ee279094a33dd4cbc6886", + "reference": "366612e9260f247d8b8ee279094a33dd4cbc6886", + "shasum": "" + }, + "require": { + "php": "^8.0", + "psr-discovery/discovery": "^1.0", + "psr/container": "^1.0 | ^2.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.14", + "infection/infection": "^0.26", + "mockery/mockery": "^1.5", + "pestphp/pest": "^2.0", + "phpstan/phpstan": "^1.10", + "phpstan/phpstan-strict-rules": "^1.5", + "rector/rector": "^0.15", + "vimeo/psalm": "^5.8", + "wikimedia/composer-merge-plugin": "^2.0" + }, + "type": "library", + "extra": { + "merge-plugin": { + "ignore-duplicates": false, + "include": [ + "composer.local.json" + ], + "merge-dev": true, + "merge-extra": false, + "merge-extra-deep": false, + "merge-scripts": false, + "recurse": true, + "replace": true + } + }, + "autoload": { + "psr-4": { + "PsrDiscovery\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Evan Sims", + "email": "hello@evansims.com", + "homepage": "https://evansims.com/" + } + ], + "description": "Lightweight library that discovers available PSR-11 Container implementations by searching for a list of well-known classes that implement the relevant interface, and returns an instance of the first one that is found.", + "homepage": "https://github.com/psr-discovery/http-client-implementations", + "keywords": [ + "PSR-11", + "discovery", + "psr" + ], + "support": { + "issues": "https://github.com/psr-discovery/container-implementations/issues", + "source": "https://github.com/psr-discovery/container-implementations/tree/1.0.0" + }, + "time": "2023-03-27T06:18:27+00:00" + }, + { + "name": "psr-discovery/discovery", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/psr-discovery/discovery.git", + "reference": "83e746a138705d56f8e3dc102e28c79f32ae9b54" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/psr-discovery/discovery/zipball/83e746a138705d56f8e3dc102e28c79f32ae9b54", + "reference": "83e746a138705d56f8e3dc102e28c79f32ae9b54", + "shasum": "" + }, + "require": { + "composer/semver": "^3.0", + "php": "^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.14", + "infection/infection": "^0.26", + "mockery/mockery": "^1.5", + "pestphp/pest": "^2.0", + "phpstan/phpstan": "^1.10", + "phpstan/phpstan-strict-rules": "^1.5", + "rector/rector": "^0.15", + "vimeo/psalm": "^5.8", + "wikimedia/composer-merge-plugin": "^2.0" + }, + "type": "library", + "extra": { + "merge-plugin": { + "ignore-duplicates": false, + "include": [ + "composer.local.json" + ], + "merge-dev": true, + "merge-extra": false, + "merge-extra-deep": false, + "merge-scripts": false, + "recurse": true, + "replace": true + } + }, + "autoload": { + "psr-4": { + "PsrDiscovery\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Evan Sims", + "email": "hello@evansims.com", + "homepage": "https://evansims.com/" + } + ], + "description": "Lightweight library that discovers available PSR implementations by searching for a list of well-known classes that implement the relevant interfaces, and returning an instance of the first one that is found.", + "homepage": "https://github.com/psr-discovery/discovery", + "keywords": [ + "PSR-11", + "discovery", + "psr", + "psr-14", + "psr-17", + "psr-18", + "psr-3", + "psr-6" + ], + "support": { + "issues": "https://github.com/psr-discovery/discovery/issues", + "source": "https://github.com/psr-discovery/discovery/tree/1.0.2" + }, + "time": "2023-03-27T19:49:39+00:00" + }, + { + "name": "psr-discovery/event-dispatcher-implementations", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/psr-discovery/event-dispatcher-implementations.git", + "reference": "903d05afe29bd1a17c18924004d282d28bda1759" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/psr-discovery/event-dispatcher-implementations/zipball/903d05afe29bd1a17c18924004d282d28bda1759", + "reference": "903d05afe29bd1a17c18924004d282d28bda1759", + "shasum": "" + }, + "require": { + "php": "^8.0", + "psr-discovery/discovery": "^1.0", + "psr/event-dispatcher": "^1.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.14", + "infection/infection": "^0.26", + "mockery/mockery": "^1.5", + "pestphp/pest": "^2.0", + "phpstan/phpstan": "^1.10", + "phpstan/phpstan-strict-rules": "^1.5", + "rector/rector": "^0.15", + "vimeo/psalm": "^5.8", + "wikimedia/composer-merge-plugin": "^2.0" + }, + "type": "library", + "extra": { + "merge-plugin": { + "ignore-duplicates": false, + "include": [ + "composer.local.json" + ], + "merge-dev": true, + "merge-extra": false, + "merge-extra-deep": false, + "merge-scripts": false, + "recurse": true, + "replace": true + } + }, + "autoload": { + "psr-4": { + "PsrDiscovery\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Evan Sims", + "email": "hello@evansims.com", + "homepage": "https://evansims.com/" + } + ], + "description": "Lightweight library that discovers available PSR-14 Event Dispatcher implementations by searching for a list of well-known classes that implement the relevant interface, and returns an instance of the first one that is found.", + "homepage": "https://github.com/psr-discovery/http-client-implementations", + "keywords": [ + "discovery", + "psr", + "psr-18" + ], + "support": { + "issues": "https://github.com/psr-discovery/event-dispatcher-implementations/issues", + "source": "https://github.com/psr-discovery/event-dispatcher-implementations/tree/1.0.0" + }, + "time": "2023-03-27T06:17:31+00:00" + }, + { + "name": "psr-discovery/http-client-implementations", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/psr-discovery/http-client-implementations.git", + "reference": "ca0cbc370789a3fd0f6aa3e7c4f4e5c123eadef3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/psr-discovery/http-client-implementations/zipball/ca0cbc370789a3fd0f6aa3e7c4f4e5c123eadef3", + "reference": "ca0cbc370789a3fd0f6aa3e7c4f4e5c123eadef3", + "shasum": "" + }, + "require": { + "php": "^8.0", + "psr-discovery/discovery": "^1.0", + "psr/http-client": "^1.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.14", + "infection/infection": "^0.26", + "mockery/mockery": "^1.5", + "pestphp/pest": "^2.0", + "phpstan/phpstan": "^1.10", + "phpstan/phpstan-strict-rules": "^1.5", + "rector/rector": "^0.15", + "vimeo/psalm": "^5.8", + "wikimedia/composer-merge-plugin": "^2.0" + }, + "type": "library", + "extra": { + "merge-plugin": { + "ignore-duplicates": false, + "include": [ + "composer.local.json" + ], + "merge-dev": true, + "merge-extra": false, + "merge-extra-deep": false, + "merge-scripts": false, + "recurse": true, + "replace": true + } + }, + "autoload": { + "psr-4": { + "PsrDiscovery\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Evan Sims", + "email": "hello@evansims.com", + "homepage": "https://evansims.com/" + } + ], + "description": "Lightweight library that discovers available PSR-18 HTTP Client implementations by searching for a list of well-known classes that implement the relevant interface, and returns an instance of the first one that is found.", + "homepage": "https://github.com/psr-discovery/http-client-implementations", + "keywords": [ + "discovery", + "psr", + "psr-18" + ], + "support": { + "issues": "https://github.com/psr-discovery/http-client-implementations/issues", + "source": "https://github.com/psr-discovery/http-client-implementations/tree/1.0.0" + }, + "time": "2023-03-27T06:16:24+00:00" + }, + { + "name": "psr-discovery/http-factory-implementations", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/psr-discovery/http-factory-implementations.git", + "reference": "064bb0ec6d2e49aeb6f15aa5a8793abe02daf56b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/psr-discovery/http-factory-implementations/zipball/064bb0ec6d2e49aeb6f15aa5a8793abe02daf56b", + "reference": "064bb0ec6d2e49aeb6f15aa5a8793abe02daf56b", + "shasum": "" + }, + "require": { + "php": "^8.0", + "psr-discovery/discovery": "^1.0", + "psr/http-factory": "^1.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.14", + "infection/infection": "^0.26", + "mockery/mockery": "^1.5", + "pestphp/pest": "^2.0", + "phpstan/phpstan": "^1.10", + "phpstan/phpstan-strict-rules": "^1.5", + "rector/rector": "^0.15", + "vimeo/psalm": "^5.8", + "wikimedia/composer-merge-plugin": "^2.0" + }, + "type": "library", + "extra": { + "merge-plugin": { + "ignore-duplicates": false, + "include": [ + "composer.local.json" + ], + "merge-dev": true, + "merge-extra": false, + "merge-extra-deep": false, + "merge-scripts": false, + "recurse": true, + "replace": true + } + }, + "autoload": { + "psr-4": { + "PsrDiscovery\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Evan Sims", + "email": "hello@evansims.com", + "homepage": "https://evansims.com/" + } + ], + "description": "Lightweight library that discovers available PSR-17 HTTP Factory implementations by searching for a list of well-known classes that implement the relevant interface, and returns an instance of the first one that is found.", + "homepage": "https://github.com/psr-discovery/http-factory-implementations", + "keywords": [ + "discovery", + "psr", + "psr-18" + ], + "support": { + "issues": "https://github.com/psr-discovery/http-factory-implementations/issues", + "source": "https://github.com/psr-discovery/http-factory-implementations/tree/1.0.1" + }, + "time": "2023-04-26T06:22:45+00:00" + }, + { + "name": "psr-discovery/log-implementations", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/psr-discovery/log-implementations.git", + "reference": "7be7af9bb1bf41a4985356b16cc654e0227eed38" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/psr-discovery/log-implementations/zipball/7be7af9bb1bf41a4985356b16cc654e0227eed38", + "reference": "7be7af9bb1bf41a4985356b16cc654e0227eed38", + "shasum": "" + }, + "require": { + "php": "^8.0", + "psr-discovery/discovery": "^1.0", + "psr/log": "^1.0 | ^2.0 | ^3.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.14", + "infection/infection": "^0.26", + "mockery/mockery": "^1.5", + "pestphp/pest": "^2.0", + "phpstan/phpstan": "^1.10", + "phpstan/phpstan-strict-rules": "^1.5", + "rector/rector": "^0.15", + "vimeo/psalm": "^5.8", + "wikimedia/composer-merge-plugin": "^2.0" + }, + "type": "library", + "extra": { + "merge-plugin": { + "ignore-duplicates": false, + "include": [ + "composer.local.json" + ], + "merge-dev": true, + "merge-extra": false, + "merge-extra-deep": false, + "merge-scripts": false, + "recurse": true, + "replace": true + } + }, + "autoload": { + "psr-4": { + "PsrDiscovery\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Evan Sims", + "email": "hello@evansims.com", + "homepage": "https://evansims.com/" + } + ], + "description": "Lightweight library that discovers available PSR-3 Log implementations by searching for a list of well-known classes that implement the relevant interface, and returns an instance of the first one that is found.", + "homepage": "https://github.com/psr-discovery", + "keywords": [ + "discovery", + "log", + "log-implementation", + "psr", + "psr-3" + ], + "support": { + "issues": "https://github.com/psr-discovery/log-implementations/issues", + "source": "https://github.com/psr-discovery/log-implementations/tree/1.0.0" + }, + "time": "2023-03-27T06:14:11+00:00" + }, + { + "name": "psr/cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "support": { + "source": "https://github.com/php-fig/cache/tree/3.0.0" + }, + "time": "2021-02-03T23:26:27+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/0955afe48220520692d2d09f7ab7e0f93ffd6a31", + "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client/tree/1.0.2" + }, + "time": "2023-04-10T20:12:12+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "e616d01114759c4c489f93b099585439f795fe35" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", + "reference": "e616d01114759c4c489f93b099585439f795fe35", + "shasum": "" + }, + "require": { + "php": ">=7.0.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory/tree/1.0.2" + }, + "time": "2023-04-10T20:10:41+00:00" + }, + { + "name": "psr/http-message", + "version": "2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/2.0" + }, + "time": "2023-04-04T09:54:51+00:00" + }, { "name": "psr/log", "version": "3.0.0", @@ -563,6 +2304,365 @@ }, "time": "2021-07-14T16:46:02+00:00" }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-05-23T14:45:45+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", + "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", + "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, { "name": "visus/cuid2", "version": "3.0.0", @@ -621,6 +2721,90 @@ "source": "https://github.com/visus-io/php-cuid2/tree/3.0.0" }, "time": "2023-08-11T16:22:53+00:00" + }, + { + "name": "vlucas/phpdotenv", + "version": "v5.5.0", + "source": { + "type": "git", + "url": "https://github.com/vlucas/phpdotenv.git", + "reference": "1a7ea2afc49c3ee6d87061f5a233e3a035d0eae7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/1a7ea2afc49c3ee6d87061f5a233e3a035d0eae7", + "reference": "1a7ea2afc49c3ee6d87061f5a233e3a035d0eae7", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "graham-campbell/result-type": "^1.0.2", + "php": "^7.1.3 || ^8.0", + "phpoption/phpoption": "^1.8", + "symfony/polyfill-ctype": "^1.23", + "symfony/polyfill-mbstring": "^1.23.1", + "symfony/polyfill-php80": "^1.23.1" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "ext-filter": "*", + "phpunit/phpunit": "^7.5.20 || ^8.5.30 || ^9.5.25" + }, + "suggest": { + "ext-filter": "Required to use the boolean validator." + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": true + }, + "branch-alias": { + "dev-master": "5.5-dev" + } + }, + "autoload": { + "psr-4": { + "Dotenv\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Vance Lucas", + "email": "vance@vancelucas.com", + "homepage": "https://github.com/vlucas" + } + ], + "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", + "keywords": [ + "dotenv", + "env", + "environment" + ], + "support": { + "issues": "https://github.com/vlucas/phpdotenv/issues", + "source": "https://github.com/vlucas/phpdotenv/tree/v5.5.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", + "type": "tidelift" + } + ], + "time": "2022-10-16T01:01:54+00:00" } ], "packages-dev": [], diff --git a/src/app/documents/Configuration.php b/src/app/documents/Configuration.php index 2aaa2f0..9daad55 100644 --- a/src/app/documents/Configuration.php +++ b/src/app/documents/Configuration.php @@ -28,7 +28,7 @@ class Configuration $db = $_ENV['PGDOC_DB'] ?? 'postgres'; $user = $_ENV['PGDOC_USER'] ?? 'postgres'; $pass = $_ENV['PGDOC_PASS'] ?? 'postgres'; - self::$connectionString = "pgsql:host=$host;port=$port;dbname=$db;user=$user;pass=$pass"; + self::$connectionString = "pgsql:host=$host;port=$port;dbname=$db;user=$user;password=$pass"; } } diff --git a/src/app/documents/Document.php b/src/app/documents/Document.php index f402980..fb2e54a 100644 --- a/src/app/documents/Document.php +++ b/src/app/documents/Document.php @@ -405,7 +405,7 @@ class Document */ private static function createCustomQuery(string $sql, array $params): PDOStatement { - $query = pdo()->prepare($sql, self::NO_PREPARE); + $query = pdo()->prepare($sql, [ \PDO::ATTR_EMULATE_PREPARES => false ]); array_walk($params, fn ($value, $name) => $query->bindParam($name, $value)); $query->execute(); return $query; diff --git a/src/app/index.php b/src/app/index.php index cb810a6..a2adfd8 100644 --- a/src/app/index.php +++ b/src/app/index.php @@ -1,14 +1,15 @@ load(); -use MyPrayerJournal\Data; +use MyPrayerJournal\{ AppUser, Data, Handlers }; Data::configure(); app()->template->config('path', './pages'); app()->template->config('params', [ - 'page_link' => function (string $url, bool $checkActive = false) { + 'page_link' => function (string $url, bool $checkActive = false) { echo 'href="'. $url . '" hx-get="' . $url . '"'; if ($checkActive && str_starts_with($_SERVER['REQUEST_URI'], $url)) { echo ' class="is-active-route"'; @@ -18,31 +19,26 @@ app()->template->config('params', [ 'version' => 'v4', ]); -function renderPage(string $template, array $params, string $pageTitle) + +app()->get('/', fn () => Handlers::render('home', 'Welcome')); + +app()->get('/components/journal-items', Handlers::journalItems(...)); + +app()->get('/journal', Handlers::journal(...)); + +app()->get('/legal/privacy-policy', fn () => Handlers::render('legal/privacy-policy', 'Privacy Policy')); +app()->get('/legal/terms-of-service', fn () => Handlers::render('legal/terms-of-service', 'Terms of Service')); + +app()->get('/user/log-on', AppUser::logOn(...)); +app()->get('/user/log-on/success', AppUser::processLogOn(...)); +app()->get('/user/log-off', AppUser::logOff(...)); + +// TODO: remove before go-live +$stdOut = fopen('php://stdout', 'w'); +function stdout(string $msg) { - if (is_null($params)) { - $params = []; - } - $params['pageTitle'] = $pageTitle; - $params['isHtmx'] = - array_key_exists('HTTP_HX_REQUEST', $_SERVER) - && (!array_key_exists('HTTP_HX_HISTORY_RESTORE_REQUEST', $_SERVER)); - $params['userId'] = false; - $params['pageContent'] = app()->template->render($template, $params); - // TODO: make the htmx distinction here - response()->markup(app()->template->render('layout/full', $params)); + global $stdOut; + fwrite($stdOut, $msg . "\n"); } -app()->get('/', function () { - renderPage('home', [], 'Welcome'); -}); - -app()->get('/legal/privacy-policy', function () { - renderPage('legal/privacy-policy', [], 'Privacy Policy'); -}); - -app()->get('/legal/terms-of-service', function () { - renderPage('legal/terms-of-service', [], 'Terms of Service'); -}); - app()->run(); diff --git a/src/app/pages/components/journal_items.view.php b/src/app/pages/components/journal_items.view.php new file mode 100644 index 0000000..92ad231 --- /dev/null +++ b/src/app/pages/components/journal_items.view.php @@ -0,0 +1,16 @@ +template->render('components/no_results', [ + 'heading' => 'No Active Requests', + 'link' => '/request/new/edit', + 'buttonText' => 'Add a Request', + 'text' => 'You have no requests to be shown; see the “Active” link above for snoozed or ' + . 'deferred requests, and the “Answered” link for answered requests' + ]); +} else { ?> +
+ items + |> List.map (journalCard now tz) +
+
+
+

+ class="btn btn-primary"> +
+ diff --git a/src/app/pages/journal.view.php b/src/app/pages/journal.view.php new file mode 100644 index 0000000..5335ea0 --- /dev/null +++ b/src/app/pages/journal.view.php @@ -0,0 +1,58 @@ +
+

+

+ class="btn btn-primary"> + add_box Add a Prayer Request + +

+

+ Loading your prayer journal… +

+ +
diff --git a/src/app/pages/layout/_head.view.php b/src/app/pages/layout/_head.view.php index 568b6c8..2893528 100644 --- a/src/app/pages/layout/_head.view.php +++ b/src/app/pages/layout/_head.view.php @@ -1,5 +1,5 @@ - <?php echo htmlentities($pageTitle); ?> « myPrayerJournal « myPrayerJournal diff --git a/src/app/pages/layout/_nav.view.php b/src/app/pages/layout/_nav.view.php index 1046f39..6ce97da 100644 --- a/src/app/pages/layout/_nav.view.php +++ b/src/app/pages/layout/_nav.view.php @@ -4,7 +4,7 @@ myPrayerJournal