├── .env.dist ├── .github └── workflows │ └── metrics.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Procfile ├── README.md ├── app.json ├── composer.json ├── composer.lock ├── config └── global.php ├── phpstan.neon ├── src └── Action │ ├── Archive │ ├── GetAction.php │ ├── ListAction.php │ ├── StartAction.php │ ├── StopAction.php │ └── ViewAction.php │ ├── EventsAction.php │ ├── IndexAction.php │ ├── JoinAction.php │ ├── RoomAction.php │ ├── SessionAction.php │ └── SignalAction.php ├── templates ├── home.html ├── join.html └── view.html └── web ├── .htaccess └── index.php /.env.dist: -------------------------------------------------------------------------------- 1 | TOKBOX_API_KEY= 2 | TOKBOX_SECRET= -------------------------------------------------------------------------------- /.github/workflows/metrics.yml: -------------------------------------------------------------------------------- 1 | name: Aggregit 2 | 3 | on: 4 | schedule: 5 | - cron: "0 0 * * *" 6 | 7 | jobs: 8 | recordMetrics: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: michaeljolley/aggregit@v1 12 | with: 13 | githubToken: ${{ secrets.GITHUB_TOKEN }} 14 | project_id: ${{ secrets.project_id }} 15 | private_key: ${{ secrets.private_key }} 16 | client_email: ${{ secrets.client_email }} 17 | firebaseDbUrl: ${{ secrets.firebaseDbUrl }} 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | vendor/ 2 | storage/ 3 | .env 4 | .php-version 5 | .vscode -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | - Demonstrating empathy and kindness toward other people 21 | - Being respectful of differing opinions, viewpoints, and experiences 22 | - Giving and gracefully accepting constructive feedback 23 | - Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | - Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | - The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | - Trolling, insulting or derogatory comments, and personal or political attacks 33 | - Public or private harassment 34 | - Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | - Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | devrel@vonage.com. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | For anyone looking to get involved to this project, we are glad to hear from you. Here are a few types of contributions 4 | that we would be interested in hearing about. 5 | 6 | - Bug fixes 7 | - If you find a bug, please first report it using Github Issues. 8 | - Issues that have already been identified as a bug will be labelled `bug`. 9 | - If you'd like to submit a fix for a bug, send a Pull Request from your own fork and mention the Issue number. 10 | - Include a test that isolates the bug and verifies that it was fixed. 11 | - New Features 12 | - If you'd like to accomplish something in the library that it doesn't already do, describe the problem in a new Github Issue. 13 | - Issues that have been identified as a feature request will be labelled `enhancement`. 14 | - If you'd like to implement the new feature, please wait for feedback from the project maintainers before spending too much time writing the code. In some cases, `enhancement`s may not align well with the project objectives at the time. 15 | - Tests, Documentation, Miscellaneous 16 | - If you think the test coverage could be improved, the documentation could be clearer, you've got an alternative implementation of something that may have more advantages, or any other change we would still be glad hear about it. 17 | - If its a trivial change, go ahead and send a Pull Request with the changes you have in mind 18 | - If not, open a Github Issue to discuss the idea first. 19 | 20 | ## Requirements 21 | 22 | For a contribution to be accepted: 23 | 24 | - The test suite must be complete and pass 25 | - Code must follow existing styling conventions 26 | - Commit messages must be descriptive. Related issues should be mentioned by number. 27 | 28 | If the contribution doesn't meet these criteria, a maintainer will discuss it with you on the Issue. You can still continue to add more commits to the branch you have sent the Pull Request from. 29 | 30 | ## How To 31 | 32 | 1. Fork this repository on GitHub. 33 | 1. Clone/fetch your fork to your local development machine. 34 | 1. Create a new branch (e.g. `issue-12`, `feat.add_foo`, etc) and check it out. 35 | 1. Make your changes and commit them. (Did the tests pass?) 36 | 1. Push your new branch to your fork. (e.g. `git push myname issue-12`) 37 | 1. Open a Pull Request from your new branch to the original fork's `master` branch. 38 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: vendor/bin/heroku-php-apache2 web 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OpenTok Getting Started Sample App 2 | 3 | Tokbox is now known as Vonage 4 | 5 | A simple server that uses the [OpenTok](https://tokbox.com/developer/) 6 | [PHP SDK](https://github.com/opentok/Opentok-PHP-SDK) to create sessions, 7 | generate tokens for those sessions, archive (or record) sessions, and download 8 | those archives. 9 | 10 | ## Quick deploy to Heroku 11 | 12 | Heroku is a PaaS (Platform as a Service) that can be used to deploy simple and small applications 13 | for free. To easily deploy this repository to Heroku, sign up for a Heroku account and click this 14 | button: 15 | 16 | 17 | Deploy 18 | 19 | 20 | Heroku will prompt you to add your OpenTok API key and OpenTok API secret, which you can 21 | obtain at the [TokBox Dashboard](https://dashboard.tokbox.com/keys). 22 | 23 | ## Requirements 24 | 25 | - [Composer](https://getcomposer.org/) 26 | - [PHP 7.3 or higher](https://php.net) 27 | 28 | ## Installation & Running on localhost 29 | 30 | 1. Clone the app by running the command 31 | 32 | git clone git@github.com:opentok/learning-opentok-php.git 33 | 34 | 2. `cd` to the root directory. 35 | 36 | 3. Run `composer install` command to fetch and install all dependencies. 37 | 38 | 4. Next, copy the `.env.dist` file to `.env` and edit to add your API Key and Secret: 39 | 40 | ``` 41 | TOKBOX_API_KEY=0000000 42 | TOKBOX_SECRET=abcdef1234567890abcdef01234567890abcdef 43 | ``` 44 | 45 | *Important:* The archiving sample application uses archives that are stored in the OpenTok 46 | cloud. In your [OpenTok Account page](https://tokbox.com/account/), ensure that the OpenTok 47 | project you use (corresponding to the API key and API secret you use here) is *not* set 48 | up to use cloud storage on Microsoft Azure or Amazon S3. However, in a production 49 | application, you will want to use an OpenTok project that has archive file cloud storage 50 | on Microsoft Azure or Amazon S3 enabled, since archives stored on the OpenTok cloud are 51 | only available for 72 hours. 52 | 53 | 5. Start the server using composer: 54 | 55 | `$ composer run --timeout 0 serve` 56 | 57 | 6. Visit the URL in your browser. You should see a JSON response 58 | containing the OpenTok API key, session ID, and token. 59 | 60 | # Exploring the code 61 | 62 | The `web/index.php` file contains setup and routing for the web service. The logic for each route is stored in `src/Action/`. The rest of this tutorial discusses code in these files. 63 | 64 | In order to navigate clients to a designated meeting spot, we associate the Session ID to a room name which is easier for people to recognize and pass. For simplicity, we use a local file storage to implement the association where the room name is the file name and the Session ID is the contents. For production applications, you may want to configure a persistence (such as a database) to achieve this functionality. 65 | 66 | ### Generate a Session and Token 67 | 68 | The `GET /room/:name` route associates an OpenTok session with a "room" name. This route handles the passed room name and performs a check to determine whether the app should generate a new session ID or retrieve a session ID from the local file storage. Then, it generates an OpenTok token for that session ID. Once the API key, session ID, and token are ready, it sends a response with the body set to a JSON object containing the information. 69 | 70 | ```php 71 | $name = $args['name']; 72 | // if a room name is already associated with a session ID 73 | if ($this->storage->exists($name)) { 74 | // fetch the sessionId from local storage 75 | $sessionId = $this->storage[$name]; 76 | 77 | // generate token 78 | $token = $this->opentok->generateToken($sessionId); 79 | $responseData = [ 80 | 'apiKey' => $this->apiKey, 81 | 'sessionId' => $sessionId, 82 | 'token'=>$token 83 | ]; 84 | 85 | return new JsonResponse($responseData); 86 | } else { // Generate a new session and store it off 87 | $session = $this->opentok->createSession([ 88 | 'mediaMode' => MediaMode::ROUTED 89 | ]); 90 | 91 | // store the sessionId into local 92 | $this->storage[$name] = $session->getSessionId(); 93 | 94 | // generate token 95 | $token = $this->opentok->generateToken($session->getSessionId()); 96 | $responseData = [ 97 | 'apiKey' => $this->apiKey, 98 | 'sessionId' => $session->getSessionId(), 99 | 'token'=>$token 100 | ]; 101 | 102 | return new JsonResponse($responseData); 103 | } 104 | ``` 105 | 106 | The `GET /session` route generates a convenient session for quick establishment of communication. 107 | 108 | ```php 109 | $parser = RouteContext::fromRequest($request)->getRouteParser(); 110 | return new RedirectResponse($parser->urlFor('room', ['name' => 'session'])); 111 | ``` 112 | 113 | ### Start an [Archive](https://tokbox.com/developer/guides/archiving/) 114 | 115 | A `POST` request to the `/archive/start` route starts an archive recording of an OpenTok session. 116 | The session ID OpenTok session is passed in as JSON data in the body of the request 117 | 118 | ```php 119 | // Start Archiving and return the Archive 120 | $data = json_decode($request->getBody()->getContents(), true); 121 | $sessionId = $data['sessionId']; 122 | $archive = $this->opentok->startArchive($sessionId, 'Getting Started Sample Archive'); 123 | 124 | return new JsonResponse($archive->toJson()); 125 | ``` 126 | 127 | You can only create an archive for sessions that have at least one client connected. Otherwise, 128 | the app will respond with an error. 129 | 130 | ### Stop an Archive 131 | 132 | A `POST` request to the `/archive:archiveId/stop` route stops an archive recording. 133 | The archive ID is returned by the call to the `archive/start` endpoint. 134 | 135 | ```php 136 | // Stop Archiving and return the Archive 137 | $archive = $this->opentok->stopArchive($args['archiveId']); 138 | return new JsonResponse($archive->toJson()); 139 | ``` 140 | 141 | ### View an Archive 142 | 143 | A `GET` request to `'/archive/:archiveId/view'` redirects the requested clients to 144 | a URL where the archive gets played. 145 | 146 | ```php 147 | // Download the archive 148 | $archive = $this->opentok->getArchive($args['archiveId']); 149 | if ($archive->status=='available') { 150 | return new RedirectResponse($archive->url); 151 | } 152 | else { 153 | return new HtmlResponse(file_get_contents($this->viewsDir . '/view.html')); 154 | } 155 | ``` 156 | 157 | ### Get Archive information 158 | 159 | A `GET` request to `/archive/:archiveId` returns a JSON object that contains all archive properties, including `status`, `url`, `duration`, etc. For more information, see [here](https://tokbox.com/developer/sdks/node/reference/Archive.html). 160 | 161 | ```php 162 | $archive = $this->opentok->getArchive($args['archiveId']); 163 | return new JsonResponse($archive->toJson()); 164 | ``` 165 | 166 | ### Fetch multiple Archives 167 | 168 | A `GET` request to `/archive` with optional `count` and `offset` params returns a list of JSON archive objects. For more information, please check [here](https://tokbox.com/developer/sdks/node/reference/OpenTok.html#listArchives). 169 | 170 | Examples: 171 | ```php 172 | GET /archive // fetch up to 1000 archive objects 173 | GET /archive?count=10 // fetch the first 10 archive objects 174 | GET /archive?offset=10 // fetch archives but first 10 archive objetcs 175 | GET /archive?count=10&offset=10 // fetch 10 archive objects starting from 11st 176 | ``` 177 | 178 | ## More information 179 | 180 | This sample app does not provide client-side OpenTok functionality 181 | (for connecting to OpenTok sessions and for publishing and subscribing to streams). 182 | It is intended to be used with the OpenTok tutorials for Web, iOS, iOS-Swift, or Android: 183 | 184 | * [Web](https://tokbox.com/developer/tutorials/web/basic-video-chat/) 185 | * [iOS](https://tokbox.com/developer/tutorials/ios/basic-video-chat/) 186 | * [iOS-Swift](https://tokbox.com/developer/tutorials/ios/swift/basic-video-chat/) 187 | * [Android](https://tokbox.com/developer/tutorials/android/basic-video-chat/) 188 | 189 | ## Development and Contributing 190 | 191 | Interested in contributing? We :heart: pull requests! See the [Contribution](CONTRIBUTING.md) guidelines. 192 | 193 | ## Getting Help 194 | 195 | We love to hear from you so if you have questions, comments, or find a bug in the project, let us know! You can either: 196 | 197 | - Open an issue on this repository 198 | - See for support options 199 | - Tweet at us! We're [@VonageDev](https://twitter.com/VonageDev) on Twitter 200 | - Or [join the Vonage Developer Community Slack](https://developer.nexmo.com/community/slack) 201 | 202 | ## Further Reading 203 | 204 | - Check out the Developer Documentation at -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Learning OpenTok PHP", 3 | "description": "An OpenTok sample app for handling OpenTok server-side functionality on a PHP server", 4 | "keywords": [ 5 | "WebRTC", 6 | "OpenTok", 7 | "video", 8 | "chat", 9 | "communications" 10 | ], 11 | "website": "https://tokbox.com", 12 | "repository": "https://github.com/opentok/learning-opentok-php", 13 | "env": { 14 | "TOKBOX_API_KEY": { 15 | "description": "OpenTok API key: Login to the TokBox Dashboard (https://dashboard.tokbox.com/keys) to get this value", 16 | "required": true 17 | }, 18 | "TOKBOX_SECRET": { 19 | "description": "OpenTok API secret: Login to the TokBox Dashboard (https://dashboard.tokbox.com/keys) to get this value", 20 | "required": true 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "php": ">=7.4 || <8.0", 4 | "slim/slim": "^4.0", 5 | "opentok/opentok": "^4.6", 6 | "guzzlehttp/guzzle": "^7.0", 7 | "icanboogie/storage": "^4.0 || ^6.0@dev", 8 | "vlucas/phpdotenv": "^5.3", 9 | "laminas/laminas-diactoros": "^2.5", 10 | "php-di/slim-bridge": "^3.1", 11 | "monolog/monolog": "^2.2" 12 | }, 13 | "autoload": { 14 | "psr-4": { 15 | "OTHelloWorld\\": "src/" 16 | } 17 | }, 18 | "scripts":{ 19 | "serve": "php -S 0.0.0.0:3000 -t web/" 20 | }, 21 | "require-dev": { 22 | "phpstan/phpstan": "^0.12.68" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "6dbf02061856cbc5408a92002eab0990", 8 | "packages": [ 9 | { 10 | "name": "firebase/php-jwt", 11 | "version": "v6.10.0", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/firebase/php-jwt.git", 15 | "reference": "a49db6f0a5033aef5143295342f1c95521b075ff" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/firebase/php-jwt/zipball/a49db6f0a5033aef5143295342f1c95521b075ff", 20 | "reference": "a49db6f0a5033aef5143295342f1c95521b075ff", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "php": "^7.4||^8.0" 25 | }, 26 | "require-dev": { 27 | "guzzlehttp/guzzle": "^6.5||^7.4", 28 | "phpspec/prophecy-phpunit": "^2.0", 29 | "phpunit/phpunit": "^9.5", 30 | "psr/cache": "^1.0||^2.0", 31 | "psr/http-client": "^1.0", 32 | "psr/http-factory": "^1.0" 33 | }, 34 | "suggest": { 35 | "ext-sodium": "Support EdDSA (Ed25519) signatures", 36 | "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present" 37 | }, 38 | "type": "library", 39 | "autoload": { 40 | "psr-4": { 41 | "Firebase\\JWT\\": "src" 42 | } 43 | }, 44 | "notification-url": "https://packagist.org/downloads/", 45 | "license": [ 46 | "BSD-3-Clause" 47 | ], 48 | "authors": [ 49 | { 50 | "name": "Neuman Vong", 51 | "email": "neuman+pear@twilio.com", 52 | "role": "Developer" 53 | }, 54 | { 55 | "name": "Anant Narayanan", 56 | "email": "anant@php.net", 57 | "role": "Developer" 58 | } 59 | ], 60 | "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", 61 | "homepage": "https://github.com/firebase/php-jwt", 62 | "keywords": [ 63 | "jwt", 64 | "php" 65 | ], 66 | "support": { 67 | "issues": "https://github.com/firebase/php-jwt/issues", 68 | "source": "https://github.com/firebase/php-jwt/tree/v6.10.0" 69 | }, 70 | "time": "2023-12-01T16:26:39+00:00" 71 | }, 72 | { 73 | "name": "graham-campbell/result-type", 74 | "version": "v1.1.2", 75 | "source": { 76 | "type": "git", 77 | "url": "https://github.com/GrahamCampbell/Result-Type.git", 78 | "reference": "fbd48bce38f73f8a4ec8583362e732e4095e5862" 79 | }, 80 | "dist": { 81 | "type": "zip", 82 | "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/fbd48bce38f73f8a4ec8583362e732e4095e5862", 83 | "reference": "fbd48bce38f73f8a4ec8583362e732e4095e5862", 84 | "shasum": "" 85 | }, 86 | "require": { 87 | "php": "^7.2.5 || ^8.0", 88 | "phpoption/phpoption": "^1.9.2" 89 | }, 90 | "require-dev": { 91 | "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" 92 | }, 93 | "type": "library", 94 | "autoload": { 95 | "psr-4": { 96 | "GrahamCampbell\\ResultType\\": "src/" 97 | } 98 | }, 99 | "notification-url": "https://packagist.org/downloads/", 100 | "license": [ 101 | "MIT" 102 | ], 103 | "authors": [ 104 | { 105 | "name": "Graham Campbell", 106 | "email": "hello@gjcampbell.co.uk", 107 | "homepage": "https://github.com/GrahamCampbell" 108 | } 109 | ], 110 | "description": "An Implementation Of The Result Type", 111 | "keywords": [ 112 | "Graham Campbell", 113 | "GrahamCampbell", 114 | "Result Type", 115 | "Result-Type", 116 | "result" 117 | ], 118 | "support": { 119 | "issues": "https://github.com/GrahamCampbell/Result-Type/issues", 120 | "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.2" 121 | }, 122 | "funding": [ 123 | { 124 | "url": "https://github.com/GrahamCampbell", 125 | "type": "github" 126 | }, 127 | { 128 | "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", 129 | "type": "tidelift" 130 | } 131 | ], 132 | "time": "2023-11-12T22:16:48+00:00" 133 | }, 134 | { 135 | "name": "guzzlehttp/guzzle", 136 | "version": "7.8.1", 137 | "source": { 138 | "type": "git", 139 | "url": "https://github.com/guzzle/guzzle.git", 140 | "reference": "41042bc7ab002487b876a0683fc8dce04ddce104" 141 | }, 142 | "dist": { 143 | "type": "zip", 144 | "url": "https://api.github.com/repos/guzzle/guzzle/zipball/41042bc7ab002487b876a0683fc8dce04ddce104", 145 | "reference": "41042bc7ab002487b876a0683fc8dce04ddce104", 146 | "shasum": "" 147 | }, 148 | "require": { 149 | "ext-json": "*", 150 | "guzzlehttp/promises": "^1.5.3 || ^2.0.1", 151 | "guzzlehttp/psr7": "^1.9.1 || ^2.5.1", 152 | "php": "^7.2.5 || ^8.0", 153 | "psr/http-client": "^1.0", 154 | "symfony/deprecation-contracts": "^2.2 || ^3.0" 155 | }, 156 | "provide": { 157 | "psr/http-client-implementation": "1.0" 158 | }, 159 | "require-dev": { 160 | "bamarni/composer-bin-plugin": "^1.8.2", 161 | "ext-curl": "*", 162 | "php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999", 163 | "php-http/message-factory": "^1.1", 164 | "phpunit/phpunit": "^8.5.36 || ^9.6.15", 165 | "psr/log": "^1.1 || ^2.0 || ^3.0" 166 | }, 167 | "suggest": { 168 | "ext-curl": "Required for CURL handler support", 169 | "ext-intl": "Required for Internationalized Domain Name (IDN) support", 170 | "psr/log": "Required for using the Log middleware" 171 | }, 172 | "type": "library", 173 | "extra": { 174 | "bamarni-bin": { 175 | "bin-links": true, 176 | "forward-command": false 177 | } 178 | }, 179 | "autoload": { 180 | "files": [ 181 | "src/functions_include.php" 182 | ], 183 | "psr-4": { 184 | "GuzzleHttp\\": "src/" 185 | } 186 | }, 187 | "notification-url": "https://packagist.org/downloads/", 188 | "license": [ 189 | "MIT" 190 | ], 191 | "authors": [ 192 | { 193 | "name": "Graham Campbell", 194 | "email": "hello@gjcampbell.co.uk", 195 | "homepage": "https://github.com/GrahamCampbell" 196 | }, 197 | { 198 | "name": "Michael Dowling", 199 | "email": "mtdowling@gmail.com", 200 | "homepage": "https://github.com/mtdowling" 201 | }, 202 | { 203 | "name": "Jeremy Lindblom", 204 | "email": "jeremeamia@gmail.com", 205 | "homepage": "https://github.com/jeremeamia" 206 | }, 207 | { 208 | "name": "George Mponos", 209 | "email": "gmponos@gmail.com", 210 | "homepage": "https://github.com/gmponos" 211 | }, 212 | { 213 | "name": "Tobias Nyholm", 214 | "email": "tobias.nyholm@gmail.com", 215 | "homepage": "https://github.com/Nyholm" 216 | }, 217 | { 218 | "name": "Márk Sági-Kazár", 219 | "email": "mark.sagikazar@gmail.com", 220 | "homepage": "https://github.com/sagikazarmark" 221 | }, 222 | { 223 | "name": "Tobias Schultze", 224 | "email": "webmaster@tubo-world.de", 225 | "homepage": "https://github.com/Tobion" 226 | } 227 | ], 228 | "description": "Guzzle is a PHP HTTP client library", 229 | "keywords": [ 230 | "client", 231 | "curl", 232 | "framework", 233 | "http", 234 | "http client", 235 | "psr-18", 236 | "psr-7", 237 | "rest", 238 | "web service" 239 | ], 240 | "support": { 241 | "issues": "https://github.com/guzzle/guzzle/issues", 242 | "source": "https://github.com/guzzle/guzzle/tree/7.8.1" 243 | }, 244 | "funding": [ 245 | { 246 | "url": "https://github.com/GrahamCampbell", 247 | "type": "github" 248 | }, 249 | { 250 | "url": "https://github.com/Nyholm", 251 | "type": "github" 252 | }, 253 | { 254 | "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", 255 | "type": "tidelift" 256 | } 257 | ], 258 | "time": "2023-12-03T20:35:24+00:00" 259 | }, 260 | { 261 | "name": "guzzlehttp/promises", 262 | "version": "2.0.2", 263 | "source": { 264 | "type": "git", 265 | "url": "https://github.com/guzzle/promises.git", 266 | "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223" 267 | }, 268 | "dist": { 269 | "type": "zip", 270 | "url": "https://api.github.com/repos/guzzle/promises/zipball/bbff78d96034045e58e13dedd6ad91b5d1253223", 271 | "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223", 272 | "shasum": "" 273 | }, 274 | "require": { 275 | "php": "^7.2.5 || ^8.0" 276 | }, 277 | "require-dev": { 278 | "bamarni/composer-bin-plugin": "^1.8.2", 279 | "phpunit/phpunit": "^8.5.36 || ^9.6.15" 280 | }, 281 | "type": "library", 282 | "extra": { 283 | "bamarni-bin": { 284 | "bin-links": true, 285 | "forward-command": false 286 | } 287 | }, 288 | "autoload": { 289 | "psr-4": { 290 | "GuzzleHttp\\Promise\\": "src/" 291 | } 292 | }, 293 | "notification-url": "https://packagist.org/downloads/", 294 | "license": [ 295 | "MIT" 296 | ], 297 | "authors": [ 298 | { 299 | "name": "Graham Campbell", 300 | "email": "hello@gjcampbell.co.uk", 301 | "homepage": "https://github.com/GrahamCampbell" 302 | }, 303 | { 304 | "name": "Michael Dowling", 305 | "email": "mtdowling@gmail.com", 306 | "homepage": "https://github.com/mtdowling" 307 | }, 308 | { 309 | "name": "Tobias Nyholm", 310 | "email": "tobias.nyholm@gmail.com", 311 | "homepage": "https://github.com/Nyholm" 312 | }, 313 | { 314 | "name": "Tobias Schultze", 315 | "email": "webmaster@tubo-world.de", 316 | "homepage": "https://github.com/Tobion" 317 | } 318 | ], 319 | "description": "Guzzle promises library", 320 | "keywords": [ 321 | "promise" 322 | ], 323 | "support": { 324 | "issues": "https://github.com/guzzle/promises/issues", 325 | "source": "https://github.com/guzzle/promises/tree/2.0.2" 326 | }, 327 | "funding": [ 328 | { 329 | "url": "https://github.com/GrahamCampbell", 330 | "type": "github" 331 | }, 332 | { 333 | "url": "https://github.com/Nyholm", 334 | "type": "github" 335 | }, 336 | { 337 | "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", 338 | "type": "tidelift" 339 | } 340 | ], 341 | "time": "2023-12-03T20:19:20+00:00" 342 | }, 343 | { 344 | "name": "guzzlehttp/psr7", 345 | "version": "2.6.2", 346 | "source": { 347 | "type": "git", 348 | "url": "https://github.com/guzzle/psr7.git", 349 | "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221" 350 | }, 351 | "dist": { 352 | "type": "zip", 353 | "url": "https://api.github.com/repos/guzzle/psr7/zipball/45b30f99ac27b5ca93cb4831afe16285f57b8221", 354 | "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221", 355 | "shasum": "" 356 | }, 357 | "require": { 358 | "php": "^7.2.5 || ^8.0", 359 | "psr/http-factory": "^1.0", 360 | "psr/http-message": "^1.1 || ^2.0", 361 | "ralouphie/getallheaders": "^3.0" 362 | }, 363 | "provide": { 364 | "psr/http-factory-implementation": "1.0", 365 | "psr/http-message-implementation": "1.0" 366 | }, 367 | "require-dev": { 368 | "bamarni/composer-bin-plugin": "^1.8.2", 369 | "http-interop/http-factory-tests": "^0.9", 370 | "phpunit/phpunit": "^8.5.36 || ^9.6.15" 371 | }, 372 | "suggest": { 373 | "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" 374 | }, 375 | "type": "library", 376 | "extra": { 377 | "bamarni-bin": { 378 | "bin-links": true, 379 | "forward-command": false 380 | } 381 | }, 382 | "autoload": { 383 | "psr-4": { 384 | "GuzzleHttp\\Psr7\\": "src/" 385 | } 386 | }, 387 | "notification-url": "https://packagist.org/downloads/", 388 | "license": [ 389 | "MIT" 390 | ], 391 | "authors": [ 392 | { 393 | "name": "Graham Campbell", 394 | "email": "hello@gjcampbell.co.uk", 395 | "homepage": "https://github.com/GrahamCampbell" 396 | }, 397 | { 398 | "name": "Michael Dowling", 399 | "email": "mtdowling@gmail.com", 400 | "homepage": "https://github.com/mtdowling" 401 | }, 402 | { 403 | "name": "George Mponos", 404 | "email": "gmponos@gmail.com", 405 | "homepage": "https://github.com/gmponos" 406 | }, 407 | { 408 | "name": "Tobias Nyholm", 409 | "email": "tobias.nyholm@gmail.com", 410 | "homepage": "https://github.com/Nyholm" 411 | }, 412 | { 413 | "name": "Márk Sági-Kazár", 414 | "email": "mark.sagikazar@gmail.com", 415 | "homepage": "https://github.com/sagikazarmark" 416 | }, 417 | { 418 | "name": "Tobias Schultze", 419 | "email": "webmaster@tubo-world.de", 420 | "homepage": "https://github.com/Tobion" 421 | }, 422 | { 423 | "name": "Márk Sági-Kazár", 424 | "email": "mark.sagikazar@gmail.com", 425 | "homepage": "https://sagikazarmark.hu" 426 | } 427 | ], 428 | "description": "PSR-7 message implementation that also provides common utility methods", 429 | "keywords": [ 430 | "http", 431 | "message", 432 | "psr-7", 433 | "request", 434 | "response", 435 | "stream", 436 | "uri", 437 | "url" 438 | ], 439 | "support": { 440 | "issues": "https://github.com/guzzle/psr7/issues", 441 | "source": "https://github.com/guzzle/psr7/tree/2.6.2" 442 | }, 443 | "funding": [ 444 | { 445 | "url": "https://github.com/GrahamCampbell", 446 | "type": "github" 447 | }, 448 | { 449 | "url": "https://github.com/Nyholm", 450 | "type": "github" 451 | }, 452 | { 453 | "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", 454 | "type": "tidelift" 455 | } 456 | ], 457 | "time": "2023-12-03T20:05:35+00:00" 458 | }, 459 | { 460 | "name": "icanboogie/storage", 461 | "version": "6.0.x-dev", 462 | "source": { 463 | "type": "git", 464 | "url": "https://github.com/ICanBoogie/Storage.git", 465 | "reference": "c962f19727157a5d42e870de955de00de8d6ffe8" 466 | }, 467 | "dist": { 468 | "type": "zip", 469 | "url": "https://api.github.com/repos/ICanBoogie/Storage/zipball/c962f19727157a5d42e870de955de00de8d6ffe8", 470 | "reference": "c962f19727157a5d42e870de955de00de8d6ffe8", 471 | "shasum": "" 472 | }, 473 | "require": { 474 | "php": ">=8.1" 475 | }, 476 | "require-dev": { 477 | "ext-apcu": "*", 478 | "ext-json": "*", 479 | "phpunit/phpunit": "^9.5" 480 | }, 481 | "type": "library", 482 | "autoload": { 483 | "psr-4": { 484 | "ICanBoogie\\Storage\\": "lib/" 485 | } 486 | }, 487 | "notification-url": "https://packagist.org/downloads/", 488 | "license": [ 489 | "BSD-3-Clause" 490 | ], 491 | "authors": [ 492 | { 493 | "name": "Olivier Laviale", 494 | "email": "olivier.laviale@gmail.com", 495 | "homepage": "https://olvlvl.com/", 496 | "role": "Developer" 497 | } 498 | ], 499 | "description": "Store and retrieve values, using different/multiple storage backends.", 500 | "homepage": "https://icanboogie.org/", 501 | "keywords": [ 502 | "cache", 503 | "retrieve", 504 | "store" 505 | ], 506 | "support": { 507 | "issues": "https://github.com/ICanBoogie/Storage/issues", 508 | "source": "https://github.com/ICanBoogie/Storage" 509 | }, 510 | "time": "2023-03-04T01:16:21+00:00" 511 | }, 512 | { 513 | "name": "johnstevenson/json-works", 514 | "version": "v1.1.0", 515 | "source": { 516 | "type": "git", 517 | "url": "https://github.com/johnstevenson/json-works.git", 518 | "reference": "97eca2c9956894374d41dcaf8031d123a8705100" 519 | }, 520 | "dist": { 521 | "type": "zip", 522 | "url": "https://api.github.com/repos/johnstevenson/json-works/zipball/97eca2c9956894374d41dcaf8031d123a8705100", 523 | "reference": "97eca2c9956894374d41dcaf8031d123a8705100", 524 | "shasum": "" 525 | }, 526 | "require": { 527 | "php": ">=5.3.3" 528 | }, 529 | "require-dev": { 530 | "phpunit/phpunit": "4.*", 531 | "squizlabs/php_codesniffer": "2.*" 532 | }, 533 | "type": "library", 534 | "autoload": { 535 | "psr-4": { 536 | "JohnStevenson\\JsonWorks\\": "src/" 537 | } 538 | }, 539 | "notification-url": "https://packagist.org/downloads/", 540 | "license": [ 541 | "MIT" 542 | ], 543 | "authors": [ 544 | { 545 | "name": "John Stevenson", 546 | "email": "john-stevenson@blueyonder.co.uk" 547 | } 548 | ], 549 | "description": "Create, edit, query and validate json", 550 | "homepage": "http://github.com/johnstevenson/json-works", 551 | "keywords": [ 552 | "builder", 553 | "json", 554 | "schema", 555 | "validator" 556 | ], 557 | "support": { 558 | "issues": "https://github.com/johnstevenson/json-works/issues", 559 | "source": "https://github.com/johnstevenson/json-works/tree/master" 560 | }, 561 | "time": "2016-01-05T16:23:18+00:00" 562 | }, 563 | { 564 | "name": "laminas/laminas-diactoros", 565 | "version": "2.26.0", 566 | "source": { 567 | "type": "git", 568 | "url": "https://github.com/laminas/laminas-diactoros.git", 569 | "reference": "6584d44eb8e477e89d453313b858daac6183cddc" 570 | }, 571 | "dist": { 572 | "type": "zip", 573 | "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/6584d44eb8e477e89d453313b858daac6183cddc", 574 | "reference": "6584d44eb8e477e89d453313b858daac6183cddc", 575 | "shasum": "" 576 | }, 577 | "require": { 578 | "php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0", 579 | "psr/http-factory": "^1.0", 580 | "psr/http-message": "^1.1" 581 | }, 582 | "conflict": { 583 | "zendframework/zend-diactoros": "*" 584 | }, 585 | "provide": { 586 | "psr/http-factory-implementation": "1.0", 587 | "psr/http-message-implementation": "1.0" 588 | }, 589 | "require-dev": { 590 | "ext-curl": "*", 591 | "ext-dom": "*", 592 | "ext-gd": "*", 593 | "ext-libxml": "*", 594 | "http-interop/http-factory-tests": "^0.9.0", 595 | "laminas/laminas-coding-standard": "^2.5", 596 | "php-http/psr7-integration-tests": "^1.2", 597 | "phpunit/phpunit": "^9.5.28", 598 | "psalm/plugin-phpunit": "^0.18.4", 599 | "vimeo/psalm": "^5.6" 600 | }, 601 | "type": "library", 602 | "extra": { 603 | "laminas": { 604 | "config-provider": "Laminas\\Diactoros\\ConfigProvider", 605 | "module": "Laminas\\Diactoros" 606 | } 607 | }, 608 | "autoload": { 609 | "files": [ 610 | "src/functions/create_uploaded_file.php", 611 | "src/functions/marshal_headers_from_sapi.php", 612 | "src/functions/marshal_method_from_sapi.php", 613 | "src/functions/marshal_protocol_version_from_sapi.php", 614 | "src/functions/marshal_uri_from_sapi.php", 615 | "src/functions/normalize_server.php", 616 | "src/functions/normalize_uploaded_files.php", 617 | "src/functions/parse_cookie_header.php", 618 | "src/functions/create_uploaded_file.legacy.php", 619 | "src/functions/marshal_headers_from_sapi.legacy.php", 620 | "src/functions/marshal_method_from_sapi.legacy.php", 621 | "src/functions/marshal_protocol_version_from_sapi.legacy.php", 622 | "src/functions/marshal_uri_from_sapi.legacy.php", 623 | "src/functions/normalize_server.legacy.php", 624 | "src/functions/normalize_uploaded_files.legacy.php", 625 | "src/functions/parse_cookie_header.legacy.php" 626 | ], 627 | "psr-4": { 628 | "Laminas\\Diactoros\\": "src/" 629 | } 630 | }, 631 | "notification-url": "https://packagist.org/downloads/", 632 | "license": [ 633 | "BSD-3-Clause" 634 | ], 635 | "description": "PSR HTTP Message implementations", 636 | "homepage": "https://laminas.dev", 637 | "keywords": [ 638 | "http", 639 | "laminas", 640 | "psr", 641 | "psr-17", 642 | "psr-7" 643 | ], 644 | "support": { 645 | "chat": "https://laminas.dev/chat", 646 | "docs": "https://docs.laminas.dev/laminas-diactoros/", 647 | "forum": "https://discourse.laminas.dev", 648 | "issues": "https://github.com/laminas/laminas-diactoros/issues", 649 | "rss": "https://github.com/laminas/laminas-diactoros/releases.atom", 650 | "source": "https://github.com/laminas/laminas-diactoros" 651 | }, 652 | "funding": [ 653 | { 654 | "url": "https://funding.communitybridge.org/projects/laminas-project", 655 | "type": "community_bridge" 656 | } 657 | ], 658 | "time": "2023-10-29T16:17:44+00:00" 659 | }, 660 | { 661 | "name": "laravel/serializable-closure", 662 | "version": "v1.3.3", 663 | "source": { 664 | "type": "git", 665 | "url": "https://github.com/laravel/serializable-closure.git", 666 | "reference": "3dbf8a8e914634c48d389c1234552666b3d43754" 667 | }, 668 | "dist": { 669 | "type": "zip", 670 | "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/3dbf8a8e914634c48d389c1234552666b3d43754", 671 | "reference": "3dbf8a8e914634c48d389c1234552666b3d43754", 672 | "shasum": "" 673 | }, 674 | "require": { 675 | "php": "^7.3|^8.0" 676 | }, 677 | "require-dev": { 678 | "nesbot/carbon": "^2.61", 679 | "pestphp/pest": "^1.21.3", 680 | "phpstan/phpstan": "^1.8.2", 681 | "symfony/var-dumper": "^5.4.11" 682 | }, 683 | "type": "library", 684 | "extra": { 685 | "branch-alias": { 686 | "dev-master": "1.x-dev" 687 | } 688 | }, 689 | "autoload": { 690 | "psr-4": { 691 | "Laravel\\SerializableClosure\\": "src/" 692 | } 693 | }, 694 | "notification-url": "https://packagist.org/downloads/", 695 | "license": [ 696 | "MIT" 697 | ], 698 | "authors": [ 699 | { 700 | "name": "Taylor Otwell", 701 | "email": "taylor@laravel.com" 702 | }, 703 | { 704 | "name": "Nuno Maduro", 705 | "email": "nuno@laravel.com" 706 | } 707 | ], 708 | "description": "Laravel Serializable Closure provides an easy and secure way to serialize closures in PHP.", 709 | "keywords": [ 710 | "closure", 711 | "laravel", 712 | "serializable" 713 | ], 714 | "support": { 715 | "issues": "https://github.com/laravel/serializable-closure/issues", 716 | "source": "https://github.com/laravel/serializable-closure" 717 | }, 718 | "time": "2023-11-08T14:08:06+00:00" 719 | }, 720 | { 721 | "name": "monolog/monolog", 722 | "version": "2.9.2", 723 | "source": { 724 | "type": "git", 725 | "url": "https://github.com/Seldaek/monolog.git", 726 | "reference": "437cb3628f4cf6042cc10ae97fc2b8472e48ca1f" 727 | }, 728 | "dist": { 729 | "type": "zip", 730 | "url": "https://api.github.com/repos/Seldaek/monolog/zipball/437cb3628f4cf6042cc10ae97fc2b8472e48ca1f", 731 | "reference": "437cb3628f4cf6042cc10ae97fc2b8472e48ca1f", 732 | "shasum": "" 733 | }, 734 | "require": { 735 | "php": ">=7.2", 736 | "psr/log": "^1.0.1 || ^2.0 || ^3.0" 737 | }, 738 | "provide": { 739 | "psr/log-implementation": "1.0.0 || 2.0.0 || 3.0.0" 740 | }, 741 | "require-dev": { 742 | "aws/aws-sdk-php": "^2.4.9 || ^3.0", 743 | "doctrine/couchdb": "~1.0@dev", 744 | "elasticsearch/elasticsearch": "^7 || ^8", 745 | "ext-json": "*", 746 | "graylog2/gelf-php": "^1.4.2 || ^2@dev", 747 | "guzzlehttp/guzzle": "^7.4", 748 | "guzzlehttp/psr7": "^2.2", 749 | "mongodb/mongodb": "^1.8", 750 | "php-amqplib/php-amqplib": "~2.4 || ^3", 751 | "phpspec/prophecy": "^1.15", 752 | "phpstan/phpstan": "^0.12.91", 753 | "phpunit/phpunit": "^8.5.14", 754 | "predis/predis": "^1.1 || ^2.0", 755 | "rollbar/rollbar": "^1.3 || ^2 || ^3", 756 | "ruflin/elastica": "^7", 757 | "swiftmailer/swiftmailer": "^5.3|^6.0", 758 | "symfony/mailer": "^5.4 || ^6", 759 | "symfony/mime": "^5.4 || ^6" 760 | }, 761 | "suggest": { 762 | "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", 763 | "doctrine/couchdb": "Allow sending log messages to a CouchDB server", 764 | "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", 765 | "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", 766 | "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", 767 | "ext-mbstring": "Allow to work properly with unicode symbols", 768 | "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", 769 | "ext-openssl": "Required to send log messages using SSL", 770 | "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", 771 | "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", 772 | "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", 773 | "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", 774 | "rollbar/rollbar": "Allow sending log messages to Rollbar", 775 | "ruflin/elastica": "Allow sending log messages to an Elastic Search server" 776 | }, 777 | "type": "library", 778 | "extra": { 779 | "branch-alias": { 780 | "dev-main": "2.x-dev" 781 | } 782 | }, 783 | "autoload": { 784 | "psr-4": { 785 | "Monolog\\": "src/Monolog" 786 | } 787 | }, 788 | "notification-url": "https://packagist.org/downloads/", 789 | "license": [ 790 | "MIT" 791 | ], 792 | "authors": [ 793 | { 794 | "name": "Jordi Boggiano", 795 | "email": "j.boggiano@seld.be", 796 | "homepage": "https://seld.be" 797 | } 798 | ], 799 | "description": "Sends your logs to files, sockets, inboxes, databases and various web services", 800 | "homepage": "https://github.com/Seldaek/monolog", 801 | "keywords": [ 802 | "log", 803 | "logging", 804 | "psr-3" 805 | ], 806 | "support": { 807 | "issues": "https://github.com/Seldaek/monolog/issues", 808 | "source": "https://github.com/Seldaek/monolog/tree/2.9.2" 809 | }, 810 | "funding": [ 811 | { 812 | "url": "https://github.com/Seldaek", 813 | "type": "github" 814 | }, 815 | { 816 | "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", 817 | "type": "tidelift" 818 | } 819 | ], 820 | "time": "2023-10-27T15:25:26+00:00" 821 | }, 822 | { 823 | "name": "nikic/fast-route", 824 | "version": "v1.3.0", 825 | "source": { 826 | "type": "git", 827 | "url": "https://github.com/nikic/FastRoute.git", 828 | "reference": "181d480e08d9476e61381e04a71b34dc0432e812" 829 | }, 830 | "dist": { 831 | "type": "zip", 832 | "url": "https://api.github.com/repos/nikic/FastRoute/zipball/181d480e08d9476e61381e04a71b34dc0432e812", 833 | "reference": "181d480e08d9476e61381e04a71b34dc0432e812", 834 | "shasum": "" 835 | }, 836 | "require": { 837 | "php": ">=5.4.0" 838 | }, 839 | "require-dev": { 840 | "phpunit/phpunit": "^4.8.35|~5.7" 841 | }, 842 | "type": "library", 843 | "autoload": { 844 | "files": [ 845 | "src/functions.php" 846 | ], 847 | "psr-4": { 848 | "FastRoute\\": "src/" 849 | } 850 | }, 851 | "notification-url": "https://packagist.org/downloads/", 852 | "license": [ 853 | "BSD-3-Clause" 854 | ], 855 | "authors": [ 856 | { 857 | "name": "Nikita Popov", 858 | "email": "nikic@php.net" 859 | } 860 | ], 861 | "description": "Fast request router for PHP", 862 | "keywords": [ 863 | "router", 864 | "routing" 865 | ], 866 | "support": { 867 | "issues": "https://github.com/nikic/FastRoute/issues", 868 | "source": "https://github.com/nikic/FastRoute/tree/master" 869 | }, 870 | "time": "2018-02-13T20:26:39+00:00" 871 | }, 872 | { 873 | "name": "opentok/opentok", 874 | "version": "v4.14.2", 875 | "source": { 876 | "type": "git", 877 | "url": "https://github.com/opentok/OpenTok-PHP-SDK.git", 878 | "reference": "73ac40b191095e15fbc61f56e28945e73efdfe29" 879 | }, 880 | "dist": { 881 | "type": "zip", 882 | "url": "https://api.github.com/repos/opentok/OpenTok-PHP-SDK/zipball/73ac40b191095e15fbc61f56e28945e73efdfe29", 883 | "reference": "73ac40b191095e15fbc61f56e28945e73efdfe29", 884 | "shasum": "" 885 | }, 886 | "require": { 887 | "ext-json": "*", 888 | "ext-xml": "*", 889 | "firebase/php-jwt": "^6.0", 890 | "guzzlehttp/guzzle": "~6.0|~7.0", 891 | "johnstevenson/json-works": "~1.1", 892 | "php": "^7.2|^8.0" 893 | }, 894 | "require-dev": { 895 | "helmich/phpunit-json-assert": "^3.0.0", 896 | "phing/phing": "~2.16.0", 897 | "php-http/guzzle7-adapter": "^1.0", 898 | "php-http/mock-client": "^1.4", 899 | "phpstan/phpstan": "^0.12", 900 | "phpunit/phpunit": "^7.4|^8.0", 901 | "rector/rector": "^0.8", 902 | "squizlabs/php_codesniffer": "^3.1" 903 | }, 904 | "type": "library", 905 | "autoload": { 906 | "psr-4": { 907 | "OpenTok\\": "src/OpenTok", 908 | "OpenTokTest\\": "tests/OpenTokTest" 909 | } 910 | }, 911 | "notification-url": "https://packagist.org/downloads/", 912 | "license": [ 913 | "MIT" 914 | ], 915 | "authors": [ 916 | { 917 | "name": "Ankur Oberoi", 918 | "email": "ankur@tokbox.com", 919 | "role": "Developer" 920 | }, 921 | { 922 | "name": "Community contributors", 923 | "homepage": "https://github.com/opentok/Opentok-PHP-SDK/graphs/contributors" 924 | } 925 | ], 926 | "description": "OpenTok is a platform for creating real time streaming video applications, created by TokBox.", 927 | "homepage": "https://github.com/opentok/Opentok-PHP-SDK", 928 | "keywords": [ 929 | "OpenTok", 930 | "TokBox", 931 | "WebRTC", 932 | "php", 933 | "streaming", 934 | "video" 935 | ], 936 | "support": { 937 | "email": "support@tokbox.com", 938 | "issues": "https://github.com/opentok/Opentok-PHP-SDK/issues", 939 | "source": "https://github.com/opentok/OpenTok-PHP-SDK/tree/v4.14.2" 940 | }, 941 | "time": "2023-10-23T13:33:46+00:00" 942 | }, 943 | { 944 | "name": "php-di/invoker", 945 | "version": "2.3.4", 946 | "source": { 947 | "type": "git", 948 | "url": "https://github.com/PHP-DI/Invoker.git", 949 | "reference": "33234b32dafa8eb69202f950a1fc92055ed76a86" 950 | }, 951 | "dist": { 952 | "type": "zip", 953 | "url": "https://api.github.com/repos/PHP-DI/Invoker/zipball/33234b32dafa8eb69202f950a1fc92055ed76a86", 954 | "reference": "33234b32dafa8eb69202f950a1fc92055ed76a86", 955 | "shasum": "" 956 | }, 957 | "require": { 958 | "php": ">=7.3", 959 | "psr/container": "^1.0|^2.0" 960 | }, 961 | "require-dev": { 962 | "athletic/athletic": "~0.1.8", 963 | "mnapoli/hard-mode": "~0.3.0", 964 | "phpunit/phpunit": "^9.0" 965 | }, 966 | "type": "library", 967 | "autoload": { 968 | "psr-4": { 969 | "Invoker\\": "src/" 970 | } 971 | }, 972 | "notification-url": "https://packagist.org/downloads/", 973 | "license": [ 974 | "MIT" 975 | ], 976 | "description": "Generic and extensible callable invoker", 977 | "homepage": "https://github.com/PHP-DI/Invoker", 978 | "keywords": [ 979 | "callable", 980 | "dependency", 981 | "dependency-injection", 982 | "injection", 983 | "invoke", 984 | "invoker" 985 | ], 986 | "support": { 987 | "issues": "https://github.com/PHP-DI/Invoker/issues", 988 | "source": "https://github.com/PHP-DI/Invoker/tree/2.3.4" 989 | }, 990 | "funding": [ 991 | { 992 | "url": "https://github.com/mnapoli", 993 | "type": "github" 994 | } 995 | ], 996 | "time": "2023-09-08T09:24:21+00:00" 997 | }, 998 | { 999 | "name": "php-di/php-di", 1000 | "version": "7.0.6", 1001 | "source": { 1002 | "type": "git", 1003 | "url": "https://github.com/PHP-DI/PHP-DI.git", 1004 | "reference": "8097948a89f6ec782839b3e958432f427cac37fd" 1005 | }, 1006 | "dist": { 1007 | "type": "zip", 1008 | "url": "https://api.github.com/repos/PHP-DI/PHP-DI/zipball/8097948a89f6ec782839b3e958432f427cac37fd", 1009 | "reference": "8097948a89f6ec782839b3e958432f427cac37fd", 1010 | "shasum": "" 1011 | }, 1012 | "require": { 1013 | "laravel/serializable-closure": "^1.0", 1014 | "php": ">=8.0", 1015 | "php-di/invoker": "^2.0", 1016 | "psr/container": "^1.1 || ^2.0" 1017 | }, 1018 | "provide": { 1019 | "psr/container-implementation": "^1.0" 1020 | }, 1021 | "require-dev": { 1022 | "friendsofphp/php-cs-fixer": "^3", 1023 | "friendsofphp/proxy-manager-lts": "^1", 1024 | "mnapoli/phpunit-easymock": "^1.3", 1025 | "phpunit/phpunit": "^9.5", 1026 | "vimeo/psalm": "^4.6" 1027 | }, 1028 | "suggest": { 1029 | "friendsofphp/proxy-manager-lts": "Install it if you want to use lazy injection (version ^1)" 1030 | }, 1031 | "type": "library", 1032 | "autoload": { 1033 | "files": [ 1034 | "src/functions.php" 1035 | ], 1036 | "psr-4": { 1037 | "DI\\": "src/" 1038 | } 1039 | }, 1040 | "notification-url": "https://packagist.org/downloads/", 1041 | "license": [ 1042 | "MIT" 1043 | ], 1044 | "description": "The dependency injection container for humans", 1045 | "homepage": "https://php-di.org/", 1046 | "keywords": [ 1047 | "PSR-11", 1048 | "container", 1049 | "container-interop", 1050 | "dependency injection", 1051 | "di", 1052 | "ioc", 1053 | "psr11" 1054 | ], 1055 | "support": { 1056 | "issues": "https://github.com/PHP-DI/PHP-DI/issues", 1057 | "source": "https://github.com/PHP-DI/PHP-DI/tree/7.0.6" 1058 | }, 1059 | "funding": [ 1060 | { 1061 | "url": "https://github.com/mnapoli", 1062 | "type": "github" 1063 | }, 1064 | { 1065 | "url": "https://tidelift.com/funding/github/packagist/php-di/php-di", 1066 | "type": "tidelift" 1067 | } 1068 | ], 1069 | "time": "2023-11-02T10:04:50+00:00" 1070 | }, 1071 | { 1072 | "name": "php-di/slim-bridge", 1073 | "version": "3.4.0", 1074 | "source": { 1075 | "type": "git", 1076 | "url": "https://github.com/PHP-DI/Slim-Bridge.git", 1077 | "reference": "d14c95b34b3c5ba2e8c40020dd93fdcc8f3ba875" 1078 | }, 1079 | "dist": { 1080 | "type": "zip", 1081 | "url": "https://api.github.com/repos/PHP-DI/Slim-Bridge/zipball/d14c95b34b3c5ba2e8c40020dd93fdcc8f3ba875", 1082 | "reference": "d14c95b34b3c5ba2e8c40020dd93fdcc8f3ba875", 1083 | "shasum": "" 1084 | }, 1085 | "require": { 1086 | "php": "^7.1 || ^8.0", 1087 | "php-di/invoker": "^2.0.0", 1088 | "php-di/php-di": "^6.0|^7.0", 1089 | "slim/slim": "^4.2.0" 1090 | }, 1091 | "require-dev": { 1092 | "laminas/laminas-diactoros": "^2.1", 1093 | "phpunit/phpunit": ">= 7.0 < 10" 1094 | }, 1095 | "type": "library", 1096 | "autoload": { 1097 | "psr-4": { 1098 | "DI\\Bridge\\Slim\\": "src/" 1099 | } 1100 | }, 1101 | "notification-url": "https://packagist.org/downloads/", 1102 | "license": [ 1103 | "MIT" 1104 | ], 1105 | "description": "PHP-DI integration in Slim", 1106 | "support": { 1107 | "issues": "https://github.com/PHP-DI/Slim-Bridge/issues", 1108 | "source": "https://github.com/PHP-DI/Slim-Bridge/tree/3.4.0" 1109 | }, 1110 | "time": "2023-06-29T14:08:47+00:00" 1111 | }, 1112 | { 1113 | "name": "phpoption/phpoption", 1114 | "version": "1.9.2", 1115 | "source": { 1116 | "type": "git", 1117 | "url": "https://github.com/schmittjoh/php-option.git", 1118 | "reference": "80735db690fe4fc5c76dfa7f9b770634285fa820" 1119 | }, 1120 | "dist": { 1121 | "type": "zip", 1122 | "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/80735db690fe4fc5c76dfa7f9b770634285fa820", 1123 | "reference": "80735db690fe4fc5c76dfa7f9b770634285fa820", 1124 | "shasum": "" 1125 | }, 1126 | "require": { 1127 | "php": "^7.2.5 || ^8.0" 1128 | }, 1129 | "require-dev": { 1130 | "bamarni/composer-bin-plugin": "^1.8.2", 1131 | "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" 1132 | }, 1133 | "type": "library", 1134 | "extra": { 1135 | "bamarni-bin": { 1136 | "bin-links": true, 1137 | "forward-command": true 1138 | }, 1139 | "branch-alias": { 1140 | "dev-master": "1.9-dev" 1141 | } 1142 | }, 1143 | "autoload": { 1144 | "psr-4": { 1145 | "PhpOption\\": "src/PhpOption/" 1146 | } 1147 | }, 1148 | "notification-url": "https://packagist.org/downloads/", 1149 | "license": [ 1150 | "Apache-2.0" 1151 | ], 1152 | "authors": [ 1153 | { 1154 | "name": "Johannes M. Schmitt", 1155 | "email": "schmittjoh@gmail.com", 1156 | "homepage": "https://github.com/schmittjoh" 1157 | }, 1158 | { 1159 | "name": "Graham Campbell", 1160 | "email": "hello@gjcampbell.co.uk", 1161 | "homepage": "https://github.com/GrahamCampbell" 1162 | } 1163 | ], 1164 | "description": "Option Type for PHP", 1165 | "keywords": [ 1166 | "language", 1167 | "option", 1168 | "php", 1169 | "type" 1170 | ], 1171 | "support": { 1172 | "issues": "https://github.com/schmittjoh/php-option/issues", 1173 | "source": "https://github.com/schmittjoh/php-option/tree/1.9.2" 1174 | }, 1175 | "funding": [ 1176 | { 1177 | "url": "https://github.com/GrahamCampbell", 1178 | "type": "github" 1179 | }, 1180 | { 1181 | "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", 1182 | "type": "tidelift" 1183 | } 1184 | ], 1185 | "time": "2023-11-12T21:59:55+00:00" 1186 | }, 1187 | { 1188 | "name": "psr/container", 1189 | "version": "2.0.2", 1190 | "source": { 1191 | "type": "git", 1192 | "url": "https://github.com/php-fig/container.git", 1193 | "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" 1194 | }, 1195 | "dist": { 1196 | "type": "zip", 1197 | "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", 1198 | "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", 1199 | "shasum": "" 1200 | }, 1201 | "require": { 1202 | "php": ">=7.4.0" 1203 | }, 1204 | "type": "library", 1205 | "extra": { 1206 | "branch-alias": { 1207 | "dev-master": "2.0.x-dev" 1208 | } 1209 | }, 1210 | "autoload": { 1211 | "psr-4": { 1212 | "Psr\\Container\\": "src/" 1213 | } 1214 | }, 1215 | "notification-url": "https://packagist.org/downloads/", 1216 | "license": [ 1217 | "MIT" 1218 | ], 1219 | "authors": [ 1220 | { 1221 | "name": "PHP-FIG", 1222 | "homepage": "https://www.php-fig.org/" 1223 | } 1224 | ], 1225 | "description": "Common Container Interface (PHP FIG PSR-11)", 1226 | "homepage": "https://github.com/php-fig/container", 1227 | "keywords": [ 1228 | "PSR-11", 1229 | "container", 1230 | "container-interface", 1231 | "container-interop", 1232 | "psr" 1233 | ], 1234 | "support": { 1235 | "issues": "https://github.com/php-fig/container/issues", 1236 | "source": "https://github.com/php-fig/container/tree/2.0.2" 1237 | }, 1238 | "time": "2021-11-05T16:47:00+00:00" 1239 | }, 1240 | { 1241 | "name": "psr/http-client", 1242 | "version": "1.0.3", 1243 | "source": { 1244 | "type": "git", 1245 | "url": "https://github.com/php-fig/http-client.git", 1246 | "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" 1247 | }, 1248 | "dist": { 1249 | "type": "zip", 1250 | "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", 1251 | "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", 1252 | "shasum": "" 1253 | }, 1254 | "require": { 1255 | "php": "^7.0 || ^8.0", 1256 | "psr/http-message": "^1.0 || ^2.0" 1257 | }, 1258 | "type": "library", 1259 | "extra": { 1260 | "branch-alias": { 1261 | "dev-master": "1.0.x-dev" 1262 | } 1263 | }, 1264 | "autoload": { 1265 | "psr-4": { 1266 | "Psr\\Http\\Client\\": "src/" 1267 | } 1268 | }, 1269 | "notification-url": "https://packagist.org/downloads/", 1270 | "license": [ 1271 | "MIT" 1272 | ], 1273 | "authors": [ 1274 | { 1275 | "name": "PHP-FIG", 1276 | "homepage": "https://www.php-fig.org/" 1277 | } 1278 | ], 1279 | "description": "Common interface for HTTP clients", 1280 | "homepage": "https://github.com/php-fig/http-client", 1281 | "keywords": [ 1282 | "http", 1283 | "http-client", 1284 | "psr", 1285 | "psr-18" 1286 | ], 1287 | "support": { 1288 | "source": "https://github.com/php-fig/http-client" 1289 | }, 1290 | "time": "2023-09-23T14:17:50+00:00" 1291 | }, 1292 | { 1293 | "name": "psr/http-factory", 1294 | "version": "1.0.2", 1295 | "source": { 1296 | "type": "git", 1297 | "url": "https://github.com/php-fig/http-factory.git", 1298 | "reference": "e616d01114759c4c489f93b099585439f795fe35" 1299 | }, 1300 | "dist": { 1301 | "type": "zip", 1302 | "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", 1303 | "reference": "e616d01114759c4c489f93b099585439f795fe35", 1304 | "shasum": "" 1305 | }, 1306 | "require": { 1307 | "php": ">=7.0.0", 1308 | "psr/http-message": "^1.0 || ^2.0" 1309 | }, 1310 | "type": "library", 1311 | "extra": { 1312 | "branch-alias": { 1313 | "dev-master": "1.0.x-dev" 1314 | } 1315 | }, 1316 | "autoload": { 1317 | "psr-4": { 1318 | "Psr\\Http\\Message\\": "src/" 1319 | } 1320 | }, 1321 | "notification-url": "https://packagist.org/downloads/", 1322 | "license": [ 1323 | "MIT" 1324 | ], 1325 | "authors": [ 1326 | { 1327 | "name": "PHP-FIG", 1328 | "homepage": "https://www.php-fig.org/" 1329 | } 1330 | ], 1331 | "description": "Common interfaces for PSR-7 HTTP message factories", 1332 | "keywords": [ 1333 | "factory", 1334 | "http", 1335 | "message", 1336 | "psr", 1337 | "psr-17", 1338 | "psr-7", 1339 | "request", 1340 | "response" 1341 | ], 1342 | "support": { 1343 | "source": "https://github.com/php-fig/http-factory/tree/1.0.2" 1344 | }, 1345 | "time": "2023-04-10T20:10:41+00:00" 1346 | }, 1347 | { 1348 | "name": "psr/http-message", 1349 | "version": "1.1", 1350 | "source": { 1351 | "type": "git", 1352 | "url": "https://github.com/php-fig/http-message.git", 1353 | "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba" 1354 | }, 1355 | "dist": { 1356 | "type": "zip", 1357 | "url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba", 1358 | "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba", 1359 | "shasum": "" 1360 | }, 1361 | "require": { 1362 | "php": "^7.2 || ^8.0" 1363 | }, 1364 | "type": "library", 1365 | "extra": { 1366 | "branch-alias": { 1367 | "dev-master": "1.1.x-dev" 1368 | } 1369 | }, 1370 | "autoload": { 1371 | "psr-4": { 1372 | "Psr\\Http\\Message\\": "src/" 1373 | } 1374 | }, 1375 | "notification-url": "https://packagist.org/downloads/", 1376 | "license": [ 1377 | "MIT" 1378 | ], 1379 | "authors": [ 1380 | { 1381 | "name": "PHP-FIG", 1382 | "homepage": "http://www.php-fig.org/" 1383 | } 1384 | ], 1385 | "description": "Common interface for HTTP messages", 1386 | "homepage": "https://github.com/php-fig/http-message", 1387 | "keywords": [ 1388 | "http", 1389 | "http-message", 1390 | "psr", 1391 | "psr-7", 1392 | "request", 1393 | "response" 1394 | ], 1395 | "support": { 1396 | "source": "https://github.com/php-fig/http-message/tree/1.1" 1397 | }, 1398 | "time": "2023-04-04T09:50:52+00:00" 1399 | }, 1400 | { 1401 | "name": "psr/http-server-handler", 1402 | "version": "1.0.2", 1403 | "source": { 1404 | "type": "git", 1405 | "url": "https://github.com/php-fig/http-server-handler.git", 1406 | "reference": "84c4fb66179be4caaf8e97bd239203245302e7d4" 1407 | }, 1408 | "dist": { 1409 | "type": "zip", 1410 | "url": "https://api.github.com/repos/php-fig/http-server-handler/zipball/84c4fb66179be4caaf8e97bd239203245302e7d4", 1411 | "reference": "84c4fb66179be4caaf8e97bd239203245302e7d4", 1412 | "shasum": "" 1413 | }, 1414 | "require": { 1415 | "php": ">=7.0", 1416 | "psr/http-message": "^1.0 || ^2.0" 1417 | }, 1418 | "type": "library", 1419 | "extra": { 1420 | "branch-alias": { 1421 | "dev-master": "1.0.x-dev" 1422 | } 1423 | }, 1424 | "autoload": { 1425 | "psr-4": { 1426 | "Psr\\Http\\Server\\": "src/" 1427 | } 1428 | }, 1429 | "notification-url": "https://packagist.org/downloads/", 1430 | "license": [ 1431 | "MIT" 1432 | ], 1433 | "authors": [ 1434 | { 1435 | "name": "PHP-FIG", 1436 | "homepage": "https://www.php-fig.org/" 1437 | } 1438 | ], 1439 | "description": "Common interface for HTTP server-side request handler", 1440 | "keywords": [ 1441 | "handler", 1442 | "http", 1443 | "http-interop", 1444 | "psr", 1445 | "psr-15", 1446 | "psr-7", 1447 | "request", 1448 | "response", 1449 | "server" 1450 | ], 1451 | "support": { 1452 | "source": "https://github.com/php-fig/http-server-handler/tree/1.0.2" 1453 | }, 1454 | "time": "2023-04-10T20:06:20+00:00" 1455 | }, 1456 | { 1457 | "name": "psr/http-server-middleware", 1458 | "version": "1.0.2", 1459 | "source": { 1460 | "type": "git", 1461 | "url": "https://github.com/php-fig/http-server-middleware.git", 1462 | "reference": "c1481f747daaa6a0782775cd6a8c26a1bf4a3829" 1463 | }, 1464 | "dist": { 1465 | "type": "zip", 1466 | "url": "https://api.github.com/repos/php-fig/http-server-middleware/zipball/c1481f747daaa6a0782775cd6a8c26a1bf4a3829", 1467 | "reference": "c1481f747daaa6a0782775cd6a8c26a1bf4a3829", 1468 | "shasum": "" 1469 | }, 1470 | "require": { 1471 | "php": ">=7.0", 1472 | "psr/http-message": "^1.0 || ^2.0", 1473 | "psr/http-server-handler": "^1.0" 1474 | }, 1475 | "type": "library", 1476 | "extra": { 1477 | "branch-alias": { 1478 | "dev-master": "1.0.x-dev" 1479 | } 1480 | }, 1481 | "autoload": { 1482 | "psr-4": { 1483 | "Psr\\Http\\Server\\": "src/" 1484 | } 1485 | }, 1486 | "notification-url": "https://packagist.org/downloads/", 1487 | "license": [ 1488 | "MIT" 1489 | ], 1490 | "authors": [ 1491 | { 1492 | "name": "PHP-FIG", 1493 | "homepage": "https://www.php-fig.org/" 1494 | } 1495 | ], 1496 | "description": "Common interface for HTTP server-side middleware", 1497 | "keywords": [ 1498 | "http", 1499 | "http-interop", 1500 | "middleware", 1501 | "psr", 1502 | "psr-15", 1503 | "psr-7", 1504 | "request", 1505 | "response" 1506 | ], 1507 | "support": { 1508 | "issues": "https://github.com/php-fig/http-server-middleware/issues", 1509 | "source": "https://github.com/php-fig/http-server-middleware/tree/1.0.2" 1510 | }, 1511 | "time": "2023-04-11T06:14:47+00:00" 1512 | }, 1513 | { 1514 | "name": "psr/log", 1515 | "version": "3.0.0", 1516 | "source": { 1517 | "type": "git", 1518 | "url": "https://github.com/php-fig/log.git", 1519 | "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" 1520 | }, 1521 | "dist": { 1522 | "type": "zip", 1523 | "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", 1524 | "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", 1525 | "shasum": "" 1526 | }, 1527 | "require": { 1528 | "php": ">=8.0.0" 1529 | }, 1530 | "type": "library", 1531 | "extra": { 1532 | "branch-alias": { 1533 | "dev-master": "3.x-dev" 1534 | } 1535 | }, 1536 | "autoload": { 1537 | "psr-4": { 1538 | "Psr\\Log\\": "src" 1539 | } 1540 | }, 1541 | "notification-url": "https://packagist.org/downloads/", 1542 | "license": [ 1543 | "MIT" 1544 | ], 1545 | "authors": [ 1546 | { 1547 | "name": "PHP-FIG", 1548 | "homepage": "https://www.php-fig.org/" 1549 | } 1550 | ], 1551 | "description": "Common interface for logging libraries", 1552 | "homepage": "https://github.com/php-fig/log", 1553 | "keywords": [ 1554 | "log", 1555 | "psr", 1556 | "psr-3" 1557 | ], 1558 | "support": { 1559 | "source": "https://github.com/php-fig/log/tree/3.0.0" 1560 | }, 1561 | "time": "2021-07-14T16:46:02+00:00" 1562 | }, 1563 | { 1564 | "name": "ralouphie/getallheaders", 1565 | "version": "3.0.3", 1566 | "source": { 1567 | "type": "git", 1568 | "url": "https://github.com/ralouphie/getallheaders.git", 1569 | "reference": "120b605dfeb996808c31b6477290a714d356e822" 1570 | }, 1571 | "dist": { 1572 | "type": "zip", 1573 | "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", 1574 | "reference": "120b605dfeb996808c31b6477290a714d356e822", 1575 | "shasum": "" 1576 | }, 1577 | "require": { 1578 | "php": ">=5.6" 1579 | }, 1580 | "require-dev": { 1581 | "php-coveralls/php-coveralls": "^2.1", 1582 | "phpunit/phpunit": "^5 || ^6.5" 1583 | }, 1584 | "type": "library", 1585 | "autoload": { 1586 | "files": [ 1587 | "src/getallheaders.php" 1588 | ] 1589 | }, 1590 | "notification-url": "https://packagist.org/downloads/", 1591 | "license": [ 1592 | "MIT" 1593 | ], 1594 | "authors": [ 1595 | { 1596 | "name": "Ralph Khattar", 1597 | "email": "ralph.khattar@gmail.com" 1598 | } 1599 | ], 1600 | "description": "A polyfill for getallheaders.", 1601 | "support": { 1602 | "issues": "https://github.com/ralouphie/getallheaders/issues", 1603 | "source": "https://github.com/ralouphie/getallheaders/tree/develop" 1604 | }, 1605 | "time": "2019-03-08T08:55:37+00:00" 1606 | }, 1607 | { 1608 | "name": "slim/slim", 1609 | "version": "4.12.0", 1610 | "source": { 1611 | "type": "git", 1612 | "url": "https://github.com/slimphp/Slim.git", 1613 | "reference": "e9e99c2b24398b967841c6c4c3048622cc7e2b18" 1614 | }, 1615 | "dist": { 1616 | "type": "zip", 1617 | "url": "https://api.github.com/repos/slimphp/Slim/zipball/e9e99c2b24398b967841c6c4c3048622cc7e2b18", 1618 | "reference": "e9e99c2b24398b967841c6c4c3048622cc7e2b18", 1619 | "shasum": "" 1620 | }, 1621 | "require": { 1622 | "ext-json": "*", 1623 | "nikic/fast-route": "^1.3", 1624 | "php": "^7.4 || ^8.0", 1625 | "psr/container": "^1.0 || ^2.0", 1626 | "psr/http-factory": "^1.0", 1627 | "psr/http-message": "^1.1", 1628 | "psr/http-server-handler": "^1.0", 1629 | "psr/http-server-middleware": "^1.0", 1630 | "psr/log": "^1.1 || ^2.0 || ^3.0" 1631 | }, 1632 | "require-dev": { 1633 | "adriansuter/php-autoload-override": "^1.4", 1634 | "ext-simplexml": "*", 1635 | "guzzlehttp/psr7": "^2.5", 1636 | "httpsoft/http-message": "^1.1", 1637 | "httpsoft/http-server-request": "^1.1", 1638 | "laminas/laminas-diactoros": "^2.17", 1639 | "nyholm/psr7": "^1.8", 1640 | "nyholm/psr7-server": "^1.0", 1641 | "phpspec/prophecy": "^1.17", 1642 | "phpspec/prophecy-phpunit": "^2.0", 1643 | "phpstan/phpstan": "^1.10", 1644 | "phpunit/phpunit": "^9.6", 1645 | "slim/http": "^1.3", 1646 | "slim/psr7": "^1.6", 1647 | "squizlabs/php_codesniffer": "^3.7" 1648 | }, 1649 | "suggest": { 1650 | "ext-simplexml": "Needed to support XML format in BodyParsingMiddleware", 1651 | "ext-xml": "Needed to support XML format in BodyParsingMiddleware", 1652 | "php-di/php-di": "PHP-DI is the recommended container library to be used with Slim", 1653 | "slim/psr7": "Slim PSR-7 implementation. See https://www.slimframework.com/docs/v4/start/installation.html for more information." 1654 | }, 1655 | "type": "library", 1656 | "autoload": { 1657 | "psr-4": { 1658 | "Slim\\": "Slim" 1659 | } 1660 | }, 1661 | "notification-url": "https://packagist.org/downloads/", 1662 | "license": [ 1663 | "MIT" 1664 | ], 1665 | "authors": [ 1666 | { 1667 | "name": "Josh Lockhart", 1668 | "email": "hello@joshlockhart.com", 1669 | "homepage": "https://joshlockhart.com" 1670 | }, 1671 | { 1672 | "name": "Andrew Smith", 1673 | "email": "a.smith@silentworks.co.uk", 1674 | "homepage": "http://silentworks.co.uk" 1675 | }, 1676 | { 1677 | "name": "Rob Allen", 1678 | "email": "rob@akrabat.com", 1679 | "homepage": "http://akrabat.com" 1680 | }, 1681 | { 1682 | "name": "Pierre Berube", 1683 | "email": "pierre@lgse.com", 1684 | "homepage": "http://www.lgse.com" 1685 | }, 1686 | { 1687 | "name": "Gabriel Manricks", 1688 | "email": "gmanricks@me.com", 1689 | "homepage": "http://gabrielmanricks.com" 1690 | } 1691 | ], 1692 | "description": "Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs", 1693 | "homepage": "https://www.slimframework.com", 1694 | "keywords": [ 1695 | "api", 1696 | "framework", 1697 | "micro", 1698 | "router" 1699 | ], 1700 | "support": { 1701 | "docs": "https://www.slimframework.com/docs/v4/", 1702 | "forum": "https://discourse.slimframework.com/", 1703 | "irc": "irc://irc.freenode.net:6667/slimphp", 1704 | "issues": "https://github.com/slimphp/Slim/issues", 1705 | "rss": "https://www.slimframework.com/blog/feed.rss", 1706 | "slack": "https://slimphp.slack.com/", 1707 | "source": "https://github.com/slimphp/Slim", 1708 | "wiki": "https://github.com/slimphp/Slim/wiki" 1709 | }, 1710 | "funding": [ 1711 | { 1712 | "url": "https://opencollective.com/slimphp", 1713 | "type": "open_collective" 1714 | }, 1715 | { 1716 | "url": "https://tidelift.com/funding/github/packagist/slim/slim", 1717 | "type": "tidelift" 1718 | } 1719 | ], 1720 | "time": "2023-07-23T04:54:29+00:00" 1721 | }, 1722 | { 1723 | "name": "symfony/deprecation-contracts", 1724 | "version": "v3.4.0", 1725 | "source": { 1726 | "type": "git", 1727 | "url": "https://github.com/symfony/deprecation-contracts.git", 1728 | "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" 1729 | }, 1730 | "dist": { 1731 | "type": "zip", 1732 | "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", 1733 | "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", 1734 | "shasum": "" 1735 | }, 1736 | "require": { 1737 | "php": ">=8.1" 1738 | }, 1739 | "type": "library", 1740 | "extra": { 1741 | "branch-alias": { 1742 | "dev-main": "3.4-dev" 1743 | }, 1744 | "thanks": { 1745 | "name": "symfony/contracts", 1746 | "url": "https://github.com/symfony/contracts" 1747 | } 1748 | }, 1749 | "autoload": { 1750 | "files": [ 1751 | "function.php" 1752 | ] 1753 | }, 1754 | "notification-url": "https://packagist.org/downloads/", 1755 | "license": [ 1756 | "MIT" 1757 | ], 1758 | "authors": [ 1759 | { 1760 | "name": "Nicolas Grekas", 1761 | "email": "p@tchwork.com" 1762 | }, 1763 | { 1764 | "name": "Symfony Community", 1765 | "homepage": "https://symfony.com/contributors" 1766 | } 1767 | ], 1768 | "description": "A generic function and convention to trigger deprecation notices", 1769 | "homepage": "https://symfony.com", 1770 | "support": { 1771 | "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0" 1772 | }, 1773 | "funding": [ 1774 | { 1775 | "url": "https://symfony.com/sponsor", 1776 | "type": "custom" 1777 | }, 1778 | { 1779 | "url": "https://github.com/fabpot", 1780 | "type": "github" 1781 | }, 1782 | { 1783 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 1784 | "type": "tidelift" 1785 | } 1786 | ], 1787 | "time": "2023-05-23T14:45:45+00:00" 1788 | }, 1789 | { 1790 | "name": "symfony/polyfill-ctype", 1791 | "version": "v1.29.0", 1792 | "source": { 1793 | "type": "git", 1794 | "url": "https://github.com/symfony/polyfill-ctype.git", 1795 | "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4" 1796 | }, 1797 | "dist": { 1798 | "type": "zip", 1799 | "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4", 1800 | "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4", 1801 | "shasum": "" 1802 | }, 1803 | "require": { 1804 | "php": ">=7.1" 1805 | }, 1806 | "provide": { 1807 | "ext-ctype": "*" 1808 | }, 1809 | "suggest": { 1810 | "ext-ctype": "For best performance" 1811 | }, 1812 | "type": "library", 1813 | "extra": { 1814 | "thanks": { 1815 | "name": "symfony/polyfill", 1816 | "url": "https://github.com/symfony/polyfill" 1817 | } 1818 | }, 1819 | "autoload": { 1820 | "files": [ 1821 | "bootstrap.php" 1822 | ], 1823 | "psr-4": { 1824 | "Symfony\\Polyfill\\Ctype\\": "" 1825 | } 1826 | }, 1827 | "notification-url": "https://packagist.org/downloads/", 1828 | "license": [ 1829 | "MIT" 1830 | ], 1831 | "authors": [ 1832 | { 1833 | "name": "Gert de Pagter", 1834 | "email": "BackEndTea@gmail.com" 1835 | }, 1836 | { 1837 | "name": "Symfony Community", 1838 | "homepage": "https://symfony.com/contributors" 1839 | } 1840 | ], 1841 | "description": "Symfony polyfill for ctype functions", 1842 | "homepage": "https://symfony.com", 1843 | "keywords": [ 1844 | "compatibility", 1845 | "ctype", 1846 | "polyfill", 1847 | "portable" 1848 | ], 1849 | "support": { 1850 | "source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0" 1851 | }, 1852 | "funding": [ 1853 | { 1854 | "url": "https://symfony.com/sponsor", 1855 | "type": "custom" 1856 | }, 1857 | { 1858 | "url": "https://github.com/fabpot", 1859 | "type": "github" 1860 | }, 1861 | { 1862 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 1863 | "type": "tidelift" 1864 | } 1865 | ], 1866 | "time": "2024-01-29T20:11:03+00:00" 1867 | }, 1868 | { 1869 | "name": "symfony/polyfill-mbstring", 1870 | "version": "v1.29.0", 1871 | "source": { 1872 | "type": "git", 1873 | "url": "https://github.com/symfony/polyfill-mbstring.git", 1874 | "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec" 1875 | }, 1876 | "dist": { 1877 | "type": "zip", 1878 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec", 1879 | "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec", 1880 | "shasum": "" 1881 | }, 1882 | "require": { 1883 | "php": ">=7.1" 1884 | }, 1885 | "provide": { 1886 | "ext-mbstring": "*" 1887 | }, 1888 | "suggest": { 1889 | "ext-mbstring": "For best performance" 1890 | }, 1891 | "type": "library", 1892 | "extra": { 1893 | "thanks": { 1894 | "name": "symfony/polyfill", 1895 | "url": "https://github.com/symfony/polyfill" 1896 | } 1897 | }, 1898 | "autoload": { 1899 | "files": [ 1900 | "bootstrap.php" 1901 | ], 1902 | "psr-4": { 1903 | "Symfony\\Polyfill\\Mbstring\\": "" 1904 | } 1905 | }, 1906 | "notification-url": "https://packagist.org/downloads/", 1907 | "license": [ 1908 | "MIT" 1909 | ], 1910 | "authors": [ 1911 | { 1912 | "name": "Nicolas Grekas", 1913 | "email": "p@tchwork.com" 1914 | }, 1915 | { 1916 | "name": "Symfony Community", 1917 | "homepage": "https://symfony.com/contributors" 1918 | } 1919 | ], 1920 | "description": "Symfony polyfill for the Mbstring extension", 1921 | "homepage": "https://symfony.com", 1922 | "keywords": [ 1923 | "compatibility", 1924 | "mbstring", 1925 | "polyfill", 1926 | "portable", 1927 | "shim" 1928 | ], 1929 | "support": { 1930 | "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0" 1931 | }, 1932 | "funding": [ 1933 | { 1934 | "url": "https://symfony.com/sponsor", 1935 | "type": "custom" 1936 | }, 1937 | { 1938 | "url": "https://github.com/fabpot", 1939 | "type": "github" 1940 | }, 1941 | { 1942 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 1943 | "type": "tidelift" 1944 | } 1945 | ], 1946 | "time": "2024-01-29T20:11:03+00:00" 1947 | }, 1948 | { 1949 | "name": "symfony/polyfill-php80", 1950 | "version": "v1.29.0", 1951 | "source": { 1952 | "type": "git", 1953 | "url": "https://github.com/symfony/polyfill-php80.git", 1954 | "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b" 1955 | }, 1956 | "dist": { 1957 | "type": "zip", 1958 | "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", 1959 | "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", 1960 | "shasum": "" 1961 | }, 1962 | "require": { 1963 | "php": ">=7.1" 1964 | }, 1965 | "type": "library", 1966 | "extra": { 1967 | "thanks": { 1968 | "name": "symfony/polyfill", 1969 | "url": "https://github.com/symfony/polyfill" 1970 | } 1971 | }, 1972 | "autoload": { 1973 | "files": [ 1974 | "bootstrap.php" 1975 | ], 1976 | "psr-4": { 1977 | "Symfony\\Polyfill\\Php80\\": "" 1978 | }, 1979 | "classmap": [ 1980 | "Resources/stubs" 1981 | ] 1982 | }, 1983 | "notification-url": "https://packagist.org/downloads/", 1984 | "license": [ 1985 | "MIT" 1986 | ], 1987 | "authors": [ 1988 | { 1989 | "name": "Ion Bazan", 1990 | "email": "ion.bazan@gmail.com" 1991 | }, 1992 | { 1993 | "name": "Nicolas Grekas", 1994 | "email": "p@tchwork.com" 1995 | }, 1996 | { 1997 | "name": "Symfony Community", 1998 | "homepage": "https://symfony.com/contributors" 1999 | } 2000 | ], 2001 | "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", 2002 | "homepage": "https://symfony.com", 2003 | "keywords": [ 2004 | "compatibility", 2005 | "polyfill", 2006 | "portable", 2007 | "shim" 2008 | ], 2009 | "support": { 2010 | "source": "https://github.com/symfony/polyfill-php80/tree/v1.29.0" 2011 | }, 2012 | "funding": [ 2013 | { 2014 | "url": "https://symfony.com/sponsor", 2015 | "type": "custom" 2016 | }, 2017 | { 2018 | "url": "https://github.com/fabpot", 2019 | "type": "github" 2020 | }, 2021 | { 2022 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2023 | "type": "tidelift" 2024 | } 2025 | ], 2026 | "time": "2024-01-29T20:11:03+00:00" 2027 | }, 2028 | { 2029 | "name": "vlucas/phpdotenv", 2030 | "version": "v5.6.0", 2031 | "source": { 2032 | "type": "git", 2033 | "url": "https://github.com/vlucas/phpdotenv.git", 2034 | "reference": "2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4" 2035 | }, 2036 | "dist": { 2037 | "type": "zip", 2038 | "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4", 2039 | "reference": "2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4", 2040 | "shasum": "" 2041 | }, 2042 | "require": { 2043 | "ext-pcre": "*", 2044 | "graham-campbell/result-type": "^1.1.2", 2045 | "php": "^7.2.5 || ^8.0", 2046 | "phpoption/phpoption": "^1.9.2", 2047 | "symfony/polyfill-ctype": "^1.24", 2048 | "symfony/polyfill-mbstring": "^1.24", 2049 | "symfony/polyfill-php80": "^1.24" 2050 | }, 2051 | "require-dev": { 2052 | "bamarni/composer-bin-plugin": "^1.8.2", 2053 | "ext-filter": "*", 2054 | "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" 2055 | }, 2056 | "suggest": { 2057 | "ext-filter": "Required to use the boolean validator." 2058 | }, 2059 | "type": "library", 2060 | "extra": { 2061 | "bamarni-bin": { 2062 | "bin-links": true, 2063 | "forward-command": true 2064 | }, 2065 | "branch-alias": { 2066 | "dev-master": "5.6-dev" 2067 | } 2068 | }, 2069 | "autoload": { 2070 | "psr-4": { 2071 | "Dotenv\\": "src/" 2072 | } 2073 | }, 2074 | "notification-url": "https://packagist.org/downloads/", 2075 | "license": [ 2076 | "BSD-3-Clause" 2077 | ], 2078 | "authors": [ 2079 | { 2080 | "name": "Graham Campbell", 2081 | "email": "hello@gjcampbell.co.uk", 2082 | "homepage": "https://github.com/GrahamCampbell" 2083 | }, 2084 | { 2085 | "name": "Vance Lucas", 2086 | "email": "vance@vancelucas.com", 2087 | "homepage": "https://github.com/vlucas" 2088 | } 2089 | ], 2090 | "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", 2091 | "keywords": [ 2092 | "dotenv", 2093 | "env", 2094 | "environment" 2095 | ], 2096 | "support": { 2097 | "issues": "https://github.com/vlucas/phpdotenv/issues", 2098 | "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.0" 2099 | }, 2100 | "funding": [ 2101 | { 2102 | "url": "https://github.com/GrahamCampbell", 2103 | "type": "github" 2104 | }, 2105 | { 2106 | "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", 2107 | "type": "tidelift" 2108 | } 2109 | ], 2110 | "time": "2023-11-12T22:43:29+00:00" 2111 | } 2112 | ], 2113 | "packages-dev": [ 2114 | { 2115 | "name": "phpstan/phpstan", 2116 | "version": "0.12.100", 2117 | "source": { 2118 | "type": "git", 2119 | "url": "https://github.com/phpstan/phpstan.git", 2120 | "reference": "48236ddf823547081b2b153d1cd2994b784328c3" 2121 | }, 2122 | "dist": { 2123 | "type": "zip", 2124 | "url": "https://api.github.com/repos/phpstan/phpstan/zipball/48236ddf823547081b2b153d1cd2994b784328c3", 2125 | "reference": "48236ddf823547081b2b153d1cd2994b784328c3", 2126 | "shasum": "" 2127 | }, 2128 | "require": { 2129 | "php": "^7.1|^8.0" 2130 | }, 2131 | "conflict": { 2132 | "phpstan/phpstan-shim": "*" 2133 | }, 2134 | "bin": [ 2135 | "phpstan", 2136 | "phpstan.phar" 2137 | ], 2138 | "type": "library", 2139 | "extra": { 2140 | "branch-alias": { 2141 | "dev-master": "0.12-dev" 2142 | } 2143 | }, 2144 | "autoload": { 2145 | "files": [ 2146 | "bootstrap.php" 2147 | ] 2148 | }, 2149 | "notification-url": "https://packagist.org/downloads/", 2150 | "license": [ 2151 | "MIT" 2152 | ], 2153 | "description": "PHPStan - PHP Static Analysis Tool", 2154 | "support": { 2155 | "issues": "https://github.com/phpstan/phpstan/issues", 2156 | "source": "https://github.com/phpstan/phpstan/tree/0.12.100" 2157 | }, 2158 | "funding": [ 2159 | { 2160 | "url": "https://github.com/ondrejmirtes", 2161 | "type": "github" 2162 | }, 2163 | { 2164 | "url": "https://github.com/phpstan", 2165 | "type": "github" 2166 | }, 2167 | { 2168 | "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", 2169 | "type": "tidelift" 2170 | } 2171 | ], 2172 | "time": "2022-11-01T09:52:08+00:00" 2173 | } 2174 | ], 2175 | "aliases": [], 2176 | "minimum-stability": "stable", 2177 | "stability-flags": { 2178 | "icanboogie/storage": 20 2179 | }, 2180 | "prefer-stable": false, 2181 | "prefer-lowest": false, 2182 | "platform": { 2183 | "php": ">=7.4 || <8.0" 2184 | }, 2185 | "platform-dev": [], 2186 | "plugin-api-version": "2.6.0" 2187 | } 2188 | -------------------------------------------------------------------------------- /config/global.php: -------------------------------------------------------------------------------- 1 | [ 14 | 'tokbox' => [ 15 | 'api_key' => getenv('TOKBOX_API_KEY'), 16 | 'secret' => getenv('TOKBOX_SECRET'), 17 | ], 18 | 'views_dir' =>__DIR__ . '/../templates', 19 | 'storage_dir' => __DIR__ . '/../storage' 20 | ], 21 | 22 | // IMPORTANT: storage is a variable that associates room names with unique unique sesssion IDs. 23 | // For simplicty, we use a extension called FileStorage to implement this logic. 24 | // Generally speaking, a production application chooses a database system like MySQL, MongoDB, or Redis etc. 25 | // The FileStorage transforms into a file where the name is a room name and its value is session ID. 26 | 'storage' => DI\Factory(function(ContainerInterface $c) { 27 | return new FileStorage($c->get('config')['storage_dir']); 28 | }), 29 | 30 | OpenTok::class => function (ContainerInterface $c) { 31 | $tokboxConfig = $c->get('config')['tokbox']; 32 | return new OpenTok($tokboxConfig['api_key'], $tokboxConfig['secret']); 33 | } 34 | ]; 35 | -------------------------------------------------------------------------------- /phpstan.neon: -------------------------------------------------------------------------------- 1 | parameters: 2 | level: 8 3 | paths: 4 | - src 5 | - web/index.php 6 | - config 7 | -------------------------------------------------------------------------------- /src/Action/Archive/GetAction.php: -------------------------------------------------------------------------------- 1 | opentok = $container->get(OpenTok::class); 21 | } 22 | 23 | /** 24 | * @param array $args 25 | */ 26 | public function __invoke(ServerRequestInterface $request, ResponseInterface $response, array $args) : ResponseInterface 27 | { 28 | $archive = $this->opentok->getArchive($args['archiveId']); 29 | 30 | return new JsonResponse($archive->toJson()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Action/Archive/ListAction.php: -------------------------------------------------------------------------------- 1 | opentok = $container->get(OpenTok::class); 21 | } 22 | 23 | public function __invoke(ServerRequestInterface $request) : ResponseInterface 24 | { 25 | $offset = $request->getQueryParams()['offset'] ? (int) $request->getQueryParams()['offset'] : 0; 26 | $count = $request->getQueryParams()['count'] ? (int) $request->getQueryParams()['count'] : 1000; 27 | $archiveList = $this->opentok->listArchives($offset, $count); 28 | $archives = $archiveList->getItems(); 29 | 30 | $result = array(); 31 | foreach ($archives as $archive) { 32 | $result[] = $archive->toArray(); 33 | } 34 | 35 | return new JsonResponse($result); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Action/Archive/StartAction.php: -------------------------------------------------------------------------------- 1 | opentok = $container->get(OpenTok::class); 21 | } 22 | 23 | public function __invoke(ServerRequestInterface $request) : ResponseInterface 24 | { 25 | $data = json_decode($request->getBody()->getContents(), true); 26 | $sessionId = $data['sessionId']; 27 | $archive = $this->opentok->startArchive($sessionId, ['name' => 'Getting Started Sample Archive']); 28 | 29 | return new JsonResponse($archive->toArray()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Action/Archive/StopAction.php: -------------------------------------------------------------------------------- 1 | opentok = $container->get(OpenTok::class); 21 | } 22 | 23 | /** 24 | * @param array $args 25 | */ 26 | public function __invoke(ServerRequestInterface $request, ResponseInterface $response, array $args) : ResponseInterface 27 | { 28 | $archive = $this->opentok->stopArchive($args['archiveId']); 29 | 30 | return new JsonResponse($archive->toArray()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Action/Archive/ViewAction.php: -------------------------------------------------------------------------------- 1 | opentok = $container->get(OpenTok::class); 28 | $this->viewsDir = $container->get('config')['views_dir']; 29 | } 30 | 31 | /** 32 | * @param array $args 33 | */ 34 | public function __invoke(ServerRequestInterface $request, ResponseInterface $response, array $args) : ResponseInterface 35 | { 36 | try { 37 | $archive = $this->opentok->getArchive($args['archiveId']); 38 | } catch (ClientException $e) { 39 | return new HtmlResponse('

Error

'. $e->getMessage(), $e->getCode()); 40 | } catch (\Exception $e) { 41 | return new HtmlResponse('

Unknown Error

'. $e->getMessage(), 500); 42 | } 43 | 44 | if ($archive->status=='available') { 45 | return new RedirectResponse($archive->url); 46 | } 47 | else { 48 | $template = file_get_contents($this->viewsDir . '/view.html'); 49 | $template = $template ? $template : 'Unable to find view archive template'; 50 | 51 | return new HtmlResponse($template); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Action/EventsAction.php: -------------------------------------------------------------------------------- 1 | getBody()->getContents() . PHP_EOL, FILE_APPEND); 15 | } 16 | 17 | return new EmptyResponse(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Action/IndexAction.php: -------------------------------------------------------------------------------- 1 | viewsDir = $container->get('config')['views_dir']; 19 | } 20 | 21 | public function __invoke() : ResponseInterface 22 | { 23 | $template = file_get_contents($this->viewsDir . '/home.html'); 24 | $template = $template ? $template : 'Unable to find home template'; 25 | 26 | return new HtmlResponse($template); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Action/JoinAction.php: -------------------------------------------------------------------------------- 1 | 26 | */ 27 | protected $storage; 28 | 29 | /** 30 | * @var string 31 | */ 32 | protected $viewsDir; 33 | 34 | public function __construct(ContainerInterface $container) 35 | { 36 | $this->apiKey = $container->get('config')['tokbox']['api_key']; 37 | $this->opentok = $container->get(OpenTok::class); 38 | $this->storage = $container->get('storage'); 39 | $this->viewsDir = $container->get('config')['views_dir']; 40 | } 41 | 42 | public function __invoke(ServerRequestInterface $request, ResponseInterface $response, array $args) : ResponseInterface 43 | { 44 | $name = $args['name']; 45 | if ($this->storage->exists($name)) { 46 | // fetch the sessionId from local storage 47 | $sessionId = $this->storage[$name]; 48 | 49 | // generate token 50 | $token = $this->opentok->generateToken($sessionId); 51 | $data = [ 52 | 'apiKey' => $this->apiKey, 53 | 'sessionId' => $sessionId, 54 | 'token' => $token 55 | ]; 56 | 57 | $template = file_get_contents($this->viewsDir . '/join.html'); 58 | if ($template) { 59 | foreach ($data as $key => $value) { 60 | $template = str_replace('{{ ' . $key . ' }}', $value, $template); 61 | } 62 | } 63 | $template = $template ? $template : 'Unable to find home template'; 64 | 65 | return new HtmlResponse($template); 66 | } else { // Generate a new session and store it off 67 | return new HtmlResponse('

404 Not Found

The room you requested was not found', 404); 68 | } 69 | 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/Action/RoomAction.php: -------------------------------------------------------------------------------- 1 | 27 | */ 28 | protected $storage; 29 | 30 | public function __construct(ContainerInterface $container) 31 | { 32 | $this->apiKey = $container->get('config')['tokbox']['api_key']; 33 | $this->opentok = $container->get(OpenTok::class); 34 | $this->storage = $container->get('storage'); 35 | } 36 | 37 | /** 38 | * @param array $args 39 | */ 40 | public function __invoke(ServerRequestInterface $request, ResponseInterface $response, array $args) : ResponseInterface 41 | { 42 | $name = $args['name']; 43 | // if a room name is already associated with a session ID 44 | if ($this->storage->exists($name)) { 45 | // fetch the sessionId from local storage 46 | $sessionId = $this->storage[$name]; 47 | 48 | // generate token 49 | $token = $this->opentok->generateToken($sessionId); 50 | $responseData = [ 51 | 'apiKey' => $this->apiKey, 52 | 'sessionId' => $sessionId, 53 | 'token'=>$token 54 | ]; 55 | 56 | return new JsonResponse($responseData); 57 | } else { // Generate a new session and store it off 58 | $session = $this->opentok->createSession([ 59 | 'mediaMode' => MediaMode::ROUTED 60 | ]); 61 | 62 | // store the sessionId into local 63 | $this->storage[$name] = $session->getSessionId(); 64 | 65 | // generate token 66 | $token = $this->opentok->generateToken($session->getSessionId()); 67 | $responseData = [ 68 | 'apiKey' => $this->apiKey, 69 | 'sessionId' => $session->getSessionId(), 70 | 'token'=>$token 71 | ]; 72 | 73 | return new JsonResponse($responseData); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/Action/SessionAction.php: -------------------------------------------------------------------------------- 1 | getRouteParser(); 18 | return new RedirectResponse($parser->urlFor('room', ['name' => 'session'])); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Action/SignalAction.php: -------------------------------------------------------------------------------- 1 | opentok = $container->get(OpenTok::class); 21 | } 22 | 23 | /** 24 | * @param array $args 25 | */ 26 | public function __invoke(ServerRequestInterface $request, ResponseInterface $response, array $args) : ResponseInterface 27 | { 28 | $data = json_decode($request->getBody()->getContents(), true); 29 | $sessionId = $data['sessionId']; 30 | $signalData = 'Signal from server at ' . date('l jS \of F Y h:i:s A'); 31 | $this->opentok->sendSignal($sessionId, 'from-server', $signalData); 32 | 33 | return new EmptyResponse(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /templates/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Learning OpenTok PHP 7 | 8 | 9 | 21 | 22 | 23 |

24 | This is a sample web service for use with OpenTok. See the OpenTok 25 | 26 | learning-opentok-php repo on GitHub. 27 |

28 |

29 | Resources are defined at the following endpoints: 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 |

62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /templates/join.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | OpenTok Getting Started 4 | 5 | 6 | 7 | 8 | 9 |
10 |
11 |
12 |
13 | 14 | 59 | 60 | -------------------------------------------------------------------------------- /templates/view.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | View Archive 7 | 8 | 9 | 10 |

Waiting for the archive...

11 |

This page will refresh until the archive status is available.

12 | 13 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /web/.htaccess: -------------------------------------------------------------------------------- 1 | RewriteEngine On 2 | 3 | RewriteCond %{REQUEST_FILENAME} !-f 4 | RewriteRule ^ index.php [QSA,L] 5 | 6 | -------------------------------------------------------------------------------- /web/index.php: -------------------------------------------------------------------------------- 1 | load(); 30 | } catch (InvalidPathException $e) { 31 | // No-op, user is allowed to set things via a real environment variable as well 32 | } 33 | 34 | 35 | // PHP CLI webserver compatibility, serving static files 36 | $filename = __DIR__.preg_replace('#(\?.*)$#', '', $_SERVER['REQUEST_URI']); 37 | if (php_sapi_name() === 'cli-server' && is_file($filename)) { 38 | return false; 39 | } 40 | 41 | $builder = new ContainerBuilder(); 42 | $builder->addDefinitions(__DIR__ . '/../config/global.php'); 43 | AppFactory::setContainer($builder->build()); 44 | $app = AppFactory::create(); 45 | 46 | $app->get('/', IndexAction::class)->setName('index'); 47 | $app->get('/session', SessionAction::class)->setName('session'); 48 | $app->get('/room/{name}', RoomAction::class)->setName('room'); 49 | $app->get('/room/{name}/join', JoinAction::class)->setName('room.join'); 50 | $app->get('/archive', ListAction::class)->setName('archive.list'); 51 | $app->map(['GET', 'POST'], '/archive/start', StartAction::class)->setName('archive.start'); 52 | $app->map(['GET', 'POST'], '/archive/{archiveId}', GetAction::class)->setName('archive.get'); 53 | $app->map(['GET', 'POST'], '/archive/{archiveId}/stop', StopAction::class)->setName('archive.stop'); 54 | $app->map(['GET', 'POST'], '/archive/{archiveId}/view', ViewAction::class)->setName('archive.view'); 55 | 56 | // return HTTP 200 for HTTP OPTIONS requests 57 | $app->options('/:routes+', function(RequestInterface $request, ResponseInterface $response) { 58 | return $response; 59 | }); 60 | $app->add(function (RequestInterface $request, $handler) use ($app) { 61 | $response = $handler->handle($request); 62 | return $response 63 | ->withHeader('Access-Control-Allow-Origin', '*') 64 | ->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization') 65 | ->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS') 66 | ; 67 | }); 68 | 69 | $app->run(); 70 | --------------------------------------------------------------------------------
GET /sessionReturn an OpenTok API key, session ID, and token.
GET /room/:name Return an OpenTok API key, session ID, and token associated with a room name.
POST /archive/startStart an archive for the specified OpenTok session.
POST /archive/:archiveId/stopStop the specified archive.
GET /archive/:archiveId/viewView the specified archive.
GET /archive/:archiveIdReturn metadata for the specified archive.
GET /archiveReturn a list of archives. More InformationPagination is enabled by applying either count or offset parameteres.