├── README.md ├── composer.json ├── composer.lock ├── src └── udokmeci │ └── yii2beanstalk │ ├── Beanstalk.php │ └── BeanstalkController.php └── test.sh /README.md: -------------------------------------------------------------------------------- 1 | yii2-beanstalk 2 | ============== 3 | 4 | Yii2 [beanstalkd][1] web and console component which is an interface on the top of [pda/pheanstalk][2]. Thanks [Paul Annesley][3] for such a complete work. 5 | 6 | [1]: http://xph.us/software/beanstalkd/ 7 | [2]: https://github.com/pda/pheanstalk 8 | [3]: http://paul.annesley.cc/ 9 | 10 | 11 | How to use? 12 | ============== 13 | ## Installation with Composer 14 | Just add the line under `require` object in your `composer.json` file. 15 | ``` json 16 | { 17 | "require": { 18 | ... 19 | "udokmeci/yii2-beanstalk" : "^1.0.0" 20 | } 21 | } 22 | ``` 23 | Then run 24 | 25 | ``` console 26 | $> composer update 27 | ``` 28 | 29 | ## Configuration 30 | Now add following lines in to your `main` and `console` configuration file under `components` 31 | ``` php 32 | 'beanstalk'=>[ 33 | 'class' => 'udokmeci\yii2beanstalk\Beanstalk', 34 | 'host' => '127.0.0.1', // default host 35 | 'port' => 11300, //default port 36 | 'connectTimeout' => 1, 37 | 'sleep' => false, // or int for usleep after every job 38 | ], 39 | ``` 40 | 41 | Now add following in to your `console` configuration only. 42 | 43 | ``` php 44 | ... 45 | 'params' => $params, 46 | // add you controller with name and class name next to params. 47 | 'controllerMap' => [ 48 | 'worker' => [ 49 | 'class' => 'app\commands\WorkerController', 50 | ] 51 | ], 52 | ``` 53 | 54 | ## Producing 55 | Now if everything is fine, you can run `beandstalkd` and access to controller as 56 | ``` php 57 | \Yii::$app->beanstalk 58 | ->putInTube('tube', $mixedData, $priority, $delay); 59 | ``` 60 | `$mixedData` is added on v1.0 for complex usage. Anything else then `string` will be send as `json` format. So you can sent anything within it suppoted by `json`. 61 | 62 | ## Worker 63 | For worker it also has a built in controller which runs an infinite loop and wait for new jobs. Most of the work is done in `BeanstalkController`. All you have to do is to create a controller and action like below. 64 | 65 | ### Controller 66 | Create a controller under your `commands` folder. Give the name anything you want to it and `extend` your controller from `udokmeci\yii2beanstalk\BeanstalkController` 67 | 68 | ##### Example Controller 69 | 70 | ``` php 71 | getData(); 105 | try { 106 | // something useful here 107 | 108 | 109 | 110 | if($everythingIsAllRight == true){ 111 | fwrite(STDOUT, Console::ansiFormat("- Everything is allright"."\n", [Console::FG_GREEN])); 112 | //Delete the job from beanstalkd 113 | return self::DELETE; 114 | } 115 | 116 | if($everythingWillBeAllRight == true){ 117 | fwrite(STDOUT, Console::ansiFormat("- Everything will be allright"."\n", [Console::FG_GREEN])); 118 | //Delay the for later try 119 | //You may prefer decay to avoid endless loop 120 | return self::DELAY; 121 | } 122 | 123 | if($IWantSomethingCustom==true){ 124 | Yii::$app->beanstalk->release($job); 125 | return self::NO_ACTION; 126 | } 127 | 128 | fwrite(STDOUT, Console::ansiFormat("- Not everything is allright!!!"."\n", [Console::FG_GREEN])); 129 | //Decay the job to try DELAY_MAX times. 130 | return self::DECAY; 131 | 132 | // if you return anything else job is burried. 133 | } catch (\Exception $e) { 134 | //If there is anything to do. 135 | fwrite(STDERR, Console::ansiFormat($e."\n", [Console::FG_RED])); 136 | // you can also bury jobs to examine later 137 | return self::BURY; 138 | } 139 | } 140 | } 141 | ``` 142 | 143 | ##### Running Worker 144 | Running console is the easiest part. Run ./yii Your `controller` 145 | ``` console 146 | $> php ./yii worker 147 | ``` 148 | Controller will tell you, whether there are actions for correspanding tubes or beanstalk server is accessible and which tubes are listening currently. The controller handles with signals. So exit whenever you want, reserved job will not be hanged. 149 | 150 | Any forks are welcome. 151 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "udokmeci/yii2-beanstalk", 3 | "type": "library", 4 | "description": "Yii2 Beanstalk Client at the top of Paul Annesley's pheanstalk", 5 | "keywords": ["beanstalkd","beanstalk client","yii2"], 6 | "homepage": "https://github.com/udokmeci/yii2-beanstalk", 7 | "license": "MIT", 8 | "authors": [ 9 | { 10 | "name": "Uğur DÖKMECİ", 11 | "email": "ugurdokmeci@gmail.com", 12 | "homepage": "https://github.com/udokmeci/yii2-beanstalk", 13 | "role": "Developer" 14 | } 15 | ], 16 | "support": { 17 | "email": "ugurdokmeci@gmail.com", 18 | "source": "https://github.com/udokmeci/yii2-beanstalk" 19 | }, 20 | "require": { 21 | "php": ">=5.5", 22 | "yiisoft/yii2": ">=2.0.38", 23 | "pda/pheanstalk": "~3" 24 | }, 25 | "require-dev": { 26 | "phpunit/phpunit": "~4.0" 27 | }, 28 | "autoload": { 29 | "psr-0" : { 30 | "udokmeci\\yii2beanstalk" : "src" 31 | } 32 | }, 33 | "extra": { 34 | "branch-alias": { 35 | "dev-master": "1.2-dev" 36 | } 37 | }, 38 | "repositories": [ 39 | { 40 | "type": "composer", 41 | "url": "https://asset-packagist.org" 42 | } 43 | ] 44 | } 45 | -------------------------------------------------------------------------------- /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": "4c67ef5f6587412414f394b8ad6e97f7", 8 | "packages": [ 9 | { 10 | "name": "bower-asset/inputmask", 11 | "version": "3.3.11", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/RobinHerbots/Inputmask.git", 15 | "reference": "5e670ad62f50c738388d4dcec78d2888505ad77b" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/RobinHerbots/Inputmask/zipball/5e670ad62f50c738388d4dcec78d2888505ad77b", 20 | "reference": "5e670ad62f50c738388d4dcec78d2888505ad77b" 21 | }, 22 | "require": { 23 | "bower-asset/jquery": ">=1.7" 24 | }, 25 | "type": "bower-asset", 26 | "license": [ 27 | "http://opensource.org/licenses/mit-license.php" 28 | ] 29 | }, 30 | { 31 | "name": "bower-asset/jquery", 32 | "version": "3.5.1", 33 | "source": { 34 | "type": "git", 35 | "url": "git@github.com:jquery/jquery-dist.git", 36 | "reference": "4c0e4becb8263bb5b3e6dadc448d8e7305ef8215" 37 | }, 38 | "dist": { 39 | "type": "zip", 40 | "url": "https://api.github.com/repos/jquery/jquery-dist/zipball/4c0e4becb8263bb5b3e6dadc448d8e7305ef8215", 41 | "reference": "4c0e4becb8263bb5b3e6dadc448d8e7305ef8215" 42 | }, 43 | "type": "bower-asset", 44 | "license": [ 45 | "MIT" 46 | ] 47 | }, 48 | { 49 | "name": "bower-asset/punycode", 50 | "version": "v1.3.2", 51 | "source": { 52 | "type": "git", 53 | "url": "git@github.com:bestiejs/punycode.js.git", 54 | "reference": "38c8d3131a82567bfef18da09f7f4db68c84f8a3" 55 | }, 56 | "dist": { 57 | "type": "zip", 58 | "url": "https://api.github.com/repos/bestiejs/punycode.js/zipball/38c8d3131a82567bfef18da09f7f4db68c84f8a3", 59 | "reference": "38c8d3131a82567bfef18da09f7f4db68c84f8a3" 60 | }, 61 | "type": "bower-asset" 62 | }, 63 | { 64 | "name": "bower-asset/yii2-pjax", 65 | "version": "2.0.7.1", 66 | "source": { 67 | "type": "git", 68 | "url": "git@github.com:yiisoft/jquery-pjax.git", 69 | "reference": "aef7b953107264f00234902a3880eb50dafc48be" 70 | }, 71 | "dist": { 72 | "type": "zip", 73 | "url": "https://api.github.com/repos/yiisoft/jquery-pjax/zipball/aef7b953107264f00234902a3880eb50dafc48be", 74 | "reference": "aef7b953107264f00234902a3880eb50dafc48be" 75 | }, 76 | "require": { 77 | "bower-asset/jquery": ">=1.8" 78 | }, 79 | "type": "bower-asset", 80 | "license": [ 81 | "MIT" 82 | ] 83 | }, 84 | { 85 | "name": "cebe/markdown", 86 | "version": "1.2.1", 87 | "source": { 88 | "type": "git", 89 | "url": "https://github.com/cebe/markdown.git", 90 | "reference": "9bac5e971dd391e2802dca5400bbeacbaea9eb86" 91 | }, 92 | "dist": { 93 | "type": "zip", 94 | "url": "https://api.github.com/repos/cebe/markdown/zipball/9bac5e971dd391e2802dca5400bbeacbaea9eb86", 95 | "reference": "9bac5e971dd391e2802dca5400bbeacbaea9eb86", 96 | "shasum": "" 97 | }, 98 | "require": { 99 | "lib-pcre": "*", 100 | "php": ">=5.4.0" 101 | }, 102 | "require-dev": { 103 | "cebe/indent": "*", 104 | "facebook/xhprof": "*@dev", 105 | "phpunit/phpunit": "4.1.*" 106 | }, 107 | "bin": [ 108 | "bin/markdown" 109 | ], 110 | "type": "library", 111 | "extra": { 112 | "branch-alias": { 113 | "dev-master": "1.2.x-dev" 114 | } 115 | }, 116 | "autoload": { 117 | "psr-4": { 118 | "cebe\\markdown\\": "" 119 | } 120 | }, 121 | "notification-url": "https://packagist.org/downloads/", 122 | "license": [ 123 | "MIT" 124 | ], 125 | "authors": [ 126 | { 127 | "name": "Carsten Brandt", 128 | "email": "mail@cebe.cc", 129 | "homepage": "http://cebe.cc/", 130 | "role": "Creator" 131 | } 132 | ], 133 | "description": "A super fast, highly extensible markdown parser for PHP", 134 | "homepage": "https://github.com/cebe/markdown#readme", 135 | "keywords": [ 136 | "extensible", 137 | "fast", 138 | "gfm", 139 | "markdown", 140 | "markdown-extra" 141 | ], 142 | "support": { 143 | "issues": "https://github.com/cebe/markdown/issues", 144 | "source": "https://github.com/cebe/markdown" 145 | }, 146 | "time": "2018-03-26T11:24:36+00:00" 147 | }, 148 | { 149 | "name": "ezyang/htmlpurifier", 150 | "version": "v4.13.0", 151 | "source": { 152 | "type": "git", 153 | "url": "https://github.com/ezyang/htmlpurifier.git", 154 | "reference": "08e27c97e4c6ed02f37c5b2b20488046c8d90d75" 155 | }, 156 | "dist": { 157 | "type": "zip", 158 | "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/08e27c97e4c6ed02f37c5b2b20488046c8d90d75", 159 | "reference": "08e27c97e4c6ed02f37c5b2b20488046c8d90d75", 160 | "shasum": "" 161 | }, 162 | "require": { 163 | "php": ">=5.2" 164 | }, 165 | "require-dev": { 166 | "simpletest/simpletest": "dev-master#72de02a7b80c6bb8864ef9bf66d41d2f58f826bd" 167 | }, 168 | "type": "library", 169 | "autoload": { 170 | "psr-0": { 171 | "HTMLPurifier": "library/" 172 | }, 173 | "files": [ 174 | "library/HTMLPurifier.composer.php" 175 | ], 176 | "exclude-from-classmap": [ 177 | "/library/HTMLPurifier/Language/" 178 | ] 179 | }, 180 | "notification-url": "https://packagist.org/downloads/", 181 | "license": [ 182 | "LGPL-2.1-or-later" 183 | ], 184 | "authors": [ 185 | { 186 | "name": "Edward Z. Yang", 187 | "email": "admin@htmlpurifier.org", 188 | "homepage": "http://ezyang.com" 189 | } 190 | ], 191 | "description": "Standards compliant HTML filter written in PHP", 192 | "homepage": "http://htmlpurifier.org/", 193 | "keywords": [ 194 | "html" 195 | ], 196 | "support": { 197 | "issues": "https://github.com/ezyang/htmlpurifier/issues", 198 | "source": "https://github.com/ezyang/htmlpurifier/tree/master" 199 | }, 200 | "time": "2020-06-29T00:56:53+00:00" 201 | }, 202 | { 203 | "name": "pda/pheanstalk", 204 | "version": "v3.2.1", 205 | "source": { 206 | "type": "git", 207 | "url": "https://github.com/pda/pheanstalk.git", 208 | "reference": "57b6e76f1b06ca798e739a8dee92c2dac04fd170" 209 | }, 210 | "dist": { 211 | "type": "zip", 212 | "url": "https://api.github.com/repos/pda/pheanstalk/zipball/57b6e76f1b06ca798e739a8dee92c2dac04fd170", 213 | "reference": "57b6e76f1b06ca798e739a8dee92c2dac04fd170", 214 | "shasum": "" 215 | }, 216 | "require": { 217 | "php": ">=5.3.0" 218 | }, 219 | "require-dev": { 220 | "phpunit/phpunit": "~4.0" 221 | }, 222 | "type": "library", 223 | "extra": { 224 | "branch-alias": { 225 | "dev-master": "3.1-dev" 226 | } 227 | }, 228 | "autoload": { 229 | "psr-4": { 230 | "Pheanstalk\\": "src/" 231 | } 232 | }, 233 | "notification-url": "https://packagist.org/downloads/", 234 | "license": [ 235 | "MIT" 236 | ], 237 | "authors": [ 238 | { 239 | "name": "Paul Annesley", 240 | "email": "paul@annesley.cc", 241 | "homepage": "http://paul.annesley.cc/", 242 | "role": "Developer" 243 | } 244 | ], 245 | "description": "PHP client for beanstalkd queue", 246 | "homepage": "https://github.com/pda/pheanstalk", 247 | "keywords": [ 248 | "beanstalkd" 249 | ], 250 | "support": { 251 | "issues": "https://github.com/pda/pheanstalk/issues", 252 | "source": "https://github.com/pda/pheanstalk/tree/master" 253 | }, 254 | "time": "2018-09-19T12:16:28+00:00" 255 | }, 256 | { 257 | "name": "yiisoft/yii2", 258 | "version": "2.0.39.1", 259 | "source": { 260 | "type": "git", 261 | "url": "https://github.com/yiisoft/yii2-framework.git", 262 | "reference": "964237b01725fb636e5291dfe72f481227902bc0" 263 | }, 264 | "dist": { 265 | "type": "zip", 266 | "url": "https://api.github.com/repos/yiisoft/yii2-framework/zipball/964237b01725fb636e5291dfe72f481227902bc0", 267 | "reference": "964237b01725fb636e5291dfe72f481227902bc0", 268 | "shasum": "" 269 | }, 270 | "require": { 271 | "bower-asset/inputmask": "~3.2.2 | ~3.3.5", 272 | "bower-asset/jquery": "3.5.*@stable | 3.4.*@stable | 3.3.*@stable | 3.2.*@stable | 3.1.*@stable | 2.2.*@stable | 2.1.*@stable | 1.11.*@stable | 1.12.*@stable", 273 | "bower-asset/punycode": "1.3.*", 274 | "bower-asset/yii2-pjax": "~2.0.1", 275 | "cebe/markdown": "~1.0.0 | ~1.1.0 | ~1.2.0", 276 | "ext-ctype": "*", 277 | "ext-mbstring": "*", 278 | "ezyang/htmlpurifier": "~4.6", 279 | "lib-pcre": "*", 280 | "php": ">=5.4.0", 281 | "yiisoft/yii2-composer": "~2.0.4" 282 | }, 283 | "bin": [ 284 | "yii" 285 | ], 286 | "type": "library", 287 | "extra": { 288 | "branch-alias": { 289 | "dev-master": "2.0.x-dev" 290 | } 291 | }, 292 | "autoload": { 293 | "psr-4": { 294 | "yii\\": "" 295 | } 296 | }, 297 | "notification-url": "https://packagist.org/downloads/", 298 | "license": [ 299 | "BSD-3-Clause" 300 | ], 301 | "authors": [ 302 | { 303 | "name": "Qiang Xue", 304 | "email": "qiang.xue@gmail.com", 305 | "homepage": "http://www.yiiframework.com/", 306 | "role": "Founder and project lead" 307 | }, 308 | { 309 | "name": "Alexander Makarov", 310 | "email": "sam@rmcreative.ru", 311 | "homepage": "http://rmcreative.ru/", 312 | "role": "Core framework development" 313 | }, 314 | { 315 | "name": "Maurizio Domba", 316 | "homepage": "http://mdomba.info/", 317 | "role": "Core framework development" 318 | }, 319 | { 320 | "name": "Carsten Brandt", 321 | "email": "mail@cebe.cc", 322 | "homepage": "http://cebe.cc/", 323 | "role": "Core framework development" 324 | }, 325 | { 326 | "name": "Timur Ruziev", 327 | "email": "resurtm@gmail.com", 328 | "homepage": "http://resurtm.com/", 329 | "role": "Core framework development" 330 | }, 331 | { 332 | "name": "Paul Klimov", 333 | "email": "klimov.paul@gmail.com", 334 | "role": "Core framework development" 335 | }, 336 | { 337 | "name": "Dmitry Naumenko", 338 | "email": "d.naumenko.a@gmail.com", 339 | "role": "Core framework development" 340 | }, 341 | { 342 | "name": "Boudewijn Vahrmeijer", 343 | "email": "info@dynasource.eu", 344 | "homepage": "http://dynasource.eu", 345 | "role": "Core framework development" 346 | } 347 | ], 348 | "description": "Yii PHP Framework Version 2", 349 | "homepage": "http://www.yiiframework.com/", 350 | "keywords": [ 351 | "framework", 352 | "yii2" 353 | ], 354 | "support": { 355 | "forum": "http://www.yiiframework.com/forum/", 356 | "irc": "irc://irc.freenode.net/yii", 357 | "issues": "https://github.com/yiisoft/yii2/issues?state=open", 358 | "source": "https://github.com/yiisoft/yii2", 359 | "wiki": "http://www.yiiframework.com/wiki/" 360 | }, 361 | "funding": [ 362 | { 363 | "url": "https://github.com/yiisoft", 364 | "type": "github" 365 | }, 366 | { 367 | "url": "https://opencollective.com/yiisoft", 368 | "type": "open_collective" 369 | }, 370 | { 371 | "url": "https://tidelift.com/funding/github/packagist/yiisoft/yii2", 372 | "type": "tidelift" 373 | } 374 | ], 375 | "time": "2020-11-10T20:15:57+00:00" 376 | }, 377 | { 378 | "name": "yiisoft/yii2-composer", 379 | "version": "2.0.10", 380 | "source": { 381 | "type": "git", 382 | "url": "https://github.com/yiisoft/yii2-composer.git", 383 | "reference": "94bb3f66e779e2774f8776d6e1bdeab402940510" 384 | }, 385 | "dist": { 386 | "type": "zip", 387 | "url": "https://api.github.com/repos/yiisoft/yii2-composer/zipball/94bb3f66e779e2774f8776d6e1bdeab402940510", 388 | "reference": "94bb3f66e779e2774f8776d6e1bdeab402940510", 389 | "shasum": "" 390 | }, 391 | "require": { 392 | "composer-plugin-api": "^1.0 | ^2.0" 393 | }, 394 | "require-dev": { 395 | "composer/composer": "^1.0 | ^2.0@dev", 396 | "phpunit/phpunit": "<7" 397 | }, 398 | "type": "composer-plugin", 399 | "extra": { 400 | "class": "yii\\composer\\Plugin", 401 | "branch-alias": { 402 | "dev-master": "2.0.x-dev" 403 | } 404 | }, 405 | "autoload": { 406 | "psr-4": { 407 | "yii\\composer\\": "" 408 | } 409 | }, 410 | "notification-url": "https://packagist.org/downloads/", 411 | "license": [ 412 | "BSD-3-Clause" 413 | ], 414 | "authors": [ 415 | { 416 | "name": "Qiang Xue", 417 | "email": "qiang.xue@gmail.com" 418 | }, 419 | { 420 | "name": "Carsten Brandt", 421 | "email": "mail@cebe.cc" 422 | } 423 | ], 424 | "description": "The composer plugin for Yii extension installer", 425 | "keywords": [ 426 | "composer", 427 | "extension installer", 428 | "yii2" 429 | ], 430 | "support": { 431 | "forum": "http://www.yiiframework.com/forum/", 432 | "irc": "irc://irc.freenode.net/yii", 433 | "issues": "https://github.com/yiisoft/yii2-composer/issues", 434 | "source": "https://github.com/yiisoft/yii2-composer", 435 | "wiki": "http://www.yiiframework.com/wiki/" 436 | }, 437 | "funding": [ 438 | { 439 | "url": "https://github.com/yiisoft", 440 | "type": "github" 441 | }, 442 | { 443 | "url": "https://opencollective.com/yiisoft", 444 | "type": "open_collective" 445 | }, 446 | { 447 | "url": "https://tidelift.com/funding/github/packagist/yiisoft/yii2-composer", 448 | "type": "tidelift" 449 | } 450 | ], 451 | "time": "2020-06-24T00:04:01+00:00" 452 | } 453 | ], 454 | "packages-dev": [ 455 | { 456 | "name": "doctrine/instantiator", 457 | "version": "1.4.0", 458 | "source": { 459 | "type": "git", 460 | "url": "https://github.com/doctrine/instantiator.git", 461 | "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" 462 | }, 463 | "dist": { 464 | "type": "zip", 465 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", 466 | "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", 467 | "shasum": "" 468 | }, 469 | "require": { 470 | "php": "^7.1 || ^8.0" 471 | }, 472 | "require-dev": { 473 | "doctrine/coding-standard": "^8.0", 474 | "ext-pdo": "*", 475 | "ext-phar": "*", 476 | "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", 477 | "phpstan/phpstan": "^0.12", 478 | "phpstan/phpstan-phpunit": "^0.12", 479 | "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" 480 | }, 481 | "type": "library", 482 | "autoload": { 483 | "psr-4": { 484 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" 485 | } 486 | }, 487 | "notification-url": "https://packagist.org/downloads/", 488 | "license": [ 489 | "MIT" 490 | ], 491 | "authors": [ 492 | { 493 | "name": "Marco Pivetta", 494 | "email": "ocramius@gmail.com", 495 | "homepage": "https://ocramius.github.io/" 496 | } 497 | ], 498 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", 499 | "homepage": "https://www.doctrine-project.org/projects/instantiator.html", 500 | "keywords": [ 501 | "constructor", 502 | "instantiate" 503 | ], 504 | "support": { 505 | "issues": "https://github.com/doctrine/instantiator/issues", 506 | "source": "https://github.com/doctrine/instantiator/tree/1.4.0" 507 | }, 508 | "funding": [ 509 | { 510 | "url": "https://www.doctrine-project.org/sponsorship.html", 511 | "type": "custom" 512 | }, 513 | { 514 | "url": "https://www.patreon.com/phpdoctrine", 515 | "type": "patreon" 516 | }, 517 | { 518 | "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", 519 | "type": "tidelift" 520 | } 521 | ], 522 | "time": "2020-11-10T18:47:58+00:00" 523 | }, 524 | { 525 | "name": "phpdocumentor/reflection-common", 526 | "version": "2.2.0", 527 | "source": { 528 | "type": "git", 529 | "url": "https://github.com/phpDocumentor/ReflectionCommon.git", 530 | "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" 531 | }, 532 | "dist": { 533 | "type": "zip", 534 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", 535 | "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", 536 | "shasum": "" 537 | }, 538 | "require": { 539 | "php": "^7.2 || ^8.0" 540 | }, 541 | "type": "library", 542 | "extra": { 543 | "branch-alias": { 544 | "dev-2.x": "2.x-dev" 545 | } 546 | }, 547 | "autoload": { 548 | "psr-4": { 549 | "phpDocumentor\\Reflection\\": "src/" 550 | } 551 | }, 552 | "notification-url": "https://packagist.org/downloads/", 553 | "license": [ 554 | "MIT" 555 | ], 556 | "authors": [ 557 | { 558 | "name": "Jaap van Otterdijk", 559 | "email": "opensource@ijaap.nl" 560 | } 561 | ], 562 | "description": "Common reflection classes used by phpdocumentor to reflect the code structure", 563 | "homepage": "http://www.phpdoc.org", 564 | "keywords": [ 565 | "FQSEN", 566 | "phpDocumentor", 567 | "phpdoc", 568 | "reflection", 569 | "static analysis" 570 | ], 571 | "support": { 572 | "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", 573 | "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" 574 | }, 575 | "time": "2020-06-27T09:03:43+00:00" 576 | }, 577 | { 578 | "name": "phpdocumentor/reflection-docblock", 579 | "version": "5.2.2", 580 | "source": { 581 | "type": "git", 582 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", 583 | "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556" 584 | }, 585 | "dist": { 586 | "type": "zip", 587 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/069a785b2141f5bcf49f3e353548dc1cce6df556", 588 | "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556", 589 | "shasum": "" 590 | }, 591 | "require": { 592 | "ext-filter": "*", 593 | "php": "^7.2 || ^8.0", 594 | "phpdocumentor/reflection-common": "^2.2", 595 | "phpdocumentor/type-resolver": "^1.3", 596 | "webmozart/assert": "^1.9.1" 597 | }, 598 | "require-dev": { 599 | "mockery/mockery": "~1.3.2" 600 | }, 601 | "type": "library", 602 | "extra": { 603 | "branch-alias": { 604 | "dev-master": "5.x-dev" 605 | } 606 | }, 607 | "autoload": { 608 | "psr-4": { 609 | "phpDocumentor\\Reflection\\": "src" 610 | } 611 | }, 612 | "notification-url": "https://packagist.org/downloads/", 613 | "license": [ 614 | "MIT" 615 | ], 616 | "authors": [ 617 | { 618 | "name": "Mike van Riel", 619 | "email": "me@mikevanriel.com" 620 | }, 621 | { 622 | "name": "Jaap van Otterdijk", 623 | "email": "account@ijaap.nl" 624 | } 625 | ], 626 | "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", 627 | "support": { 628 | "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", 629 | "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/master" 630 | }, 631 | "time": "2020-09-03T19:13:55+00:00" 632 | }, 633 | { 634 | "name": "phpdocumentor/type-resolver", 635 | "version": "1.4.0", 636 | "source": { 637 | "type": "git", 638 | "url": "https://github.com/phpDocumentor/TypeResolver.git", 639 | "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0" 640 | }, 641 | "dist": { 642 | "type": "zip", 643 | "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", 644 | "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", 645 | "shasum": "" 646 | }, 647 | "require": { 648 | "php": "^7.2 || ^8.0", 649 | "phpdocumentor/reflection-common": "^2.0" 650 | }, 651 | "require-dev": { 652 | "ext-tokenizer": "*" 653 | }, 654 | "type": "library", 655 | "extra": { 656 | "branch-alias": { 657 | "dev-1.x": "1.x-dev" 658 | } 659 | }, 660 | "autoload": { 661 | "psr-4": { 662 | "phpDocumentor\\Reflection\\": "src" 663 | } 664 | }, 665 | "notification-url": "https://packagist.org/downloads/", 666 | "license": [ 667 | "MIT" 668 | ], 669 | "authors": [ 670 | { 671 | "name": "Mike van Riel", 672 | "email": "me@mikevanriel.com" 673 | } 674 | ], 675 | "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", 676 | "support": { 677 | "issues": "https://github.com/phpDocumentor/TypeResolver/issues", 678 | "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.4.0" 679 | }, 680 | "time": "2020-09-17T18:55:26+00:00" 681 | }, 682 | { 683 | "name": "phpspec/prophecy", 684 | "version": "v1.10.3", 685 | "source": { 686 | "type": "git", 687 | "url": "https://github.com/phpspec/prophecy.git", 688 | "reference": "451c3cd1418cf640de218914901e51b064abb093" 689 | }, 690 | "dist": { 691 | "type": "zip", 692 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/451c3cd1418cf640de218914901e51b064abb093", 693 | "reference": "451c3cd1418cf640de218914901e51b064abb093", 694 | "shasum": "" 695 | }, 696 | "require": { 697 | "doctrine/instantiator": "^1.0.2", 698 | "php": "^5.3|^7.0", 699 | "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0", 700 | "sebastian/comparator": "^1.2.3|^2.0|^3.0|^4.0", 701 | "sebastian/recursion-context": "^1.0|^2.0|^3.0|^4.0" 702 | }, 703 | "require-dev": { 704 | "phpspec/phpspec": "^2.5 || ^3.2", 705 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" 706 | }, 707 | "type": "library", 708 | "extra": { 709 | "branch-alias": { 710 | "dev-master": "1.10.x-dev" 711 | } 712 | }, 713 | "autoload": { 714 | "psr-4": { 715 | "Prophecy\\": "src/Prophecy" 716 | } 717 | }, 718 | "notification-url": "https://packagist.org/downloads/", 719 | "license": [ 720 | "MIT" 721 | ], 722 | "authors": [ 723 | { 724 | "name": "Konstantin Kudryashov", 725 | "email": "ever.zet@gmail.com", 726 | "homepage": "http://everzet.com" 727 | }, 728 | { 729 | "name": "Marcello Duarte", 730 | "email": "marcello.duarte@gmail.com" 731 | } 732 | ], 733 | "description": "Highly opinionated mocking framework for PHP 5.3+", 734 | "homepage": "https://github.com/phpspec/prophecy", 735 | "keywords": [ 736 | "Double", 737 | "Dummy", 738 | "fake", 739 | "mock", 740 | "spy", 741 | "stub" 742 | ], 743 | "support": { 744 | "issues": "https://github.com/phpspec/prophecy/issues", 745 | "source": "https://github.com/phpspec/prophecy/tree/v1.10.3" 746 | }, 747 | "time": "2020-03-05T15:02:03+00:00" 748 | }, 749 | { 750 | "name": "phpunit/php-code-coverage", 751 | "version": "2.2.4", 752 | "source": { 753 | "type": "git", 754 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git", 755 | "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" 756 | }, 757 | "dist": { 758 | "type": "zip", 759 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", 760 | "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", 761 | "shasum": "" 762 | }, 763 | "require": { 764 | "php": ">=5.3.3", 765 | "phpunit/php-file-iterator": "~1.3", 766 | "phpunit/php-text-template": "~1.2", 767 | "phpunit/php-token-stream": "~1.3", 768 | "sebastian/environment": "^1.3.2", 769 | "sebastian/version": "~1.0" 770 | }, 771 | "require-dev": { 772 | "ext-xdebug": ">=2.1.4", 773 | "phpunit/phpunit": "~4" 774 | }, 775 | "suggest": { 776 | "ext-dom": "*", 777 | "ext-xdebug": ">=2.2.1", 778 | "ext-xmlwriter": "*" 779 | }, 780 | "type": "library", 781 | "extra": { 782 | "branch-alias": { 783 | "dev-master": "2.2.x-dev" 784 | } 785 | }, 786 | "autoload": { 787 | "classmap": [ 788 | "src/" 789 | ] 790 | }, 791 | "notification-url": "https://packagist.org/downloads/", 792 | "license": [ 793 | "BSD-3-Clause" 794 | ], 795 | "authors": [ 796 | { 797 | "name": "Sebastian Bergmann", 798 | "email": "sb@sebastian-bergmann.de", 799 | "role": "lead" 800 | } 801 | ], 802 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", 803 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage", 804 | "keywords": [ 805 | "coverage", 806 | "testing", 807 | "xunit" 808 | ], 809 | "support": { 810 | "irc": "irc://irc.freenode.net/phpunit", 811 | "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", 812 | "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/2.2" 813 | }, 814 | "time": "2015-10-06T15:47:00+00:00" 815 | }, 816 | { 817 | "name": "phpunit/php-file-iterator", 818 | "version": "1.4.5", 819 | "source": { 820 | "type": "git", 821 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git", 822 | "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" 823 | }, 824 | "dist": { 825 | "type": "zip", 826 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", 827 | "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", 828 | "shasum": "" 829 | }, 830 | "require": { 831 | "php": ">=5.3.3" 832 | }, 833 | "type": "library", 834 | "extra": { 835 | "branch-alias": { 836 | "dev-master": "1.4.x-dev" 837 | } 838 | }, 839 | "autoload": { 840 | "classmap": [ 841 | "src/" 842 | ] 843 | }, 844 | "notification-url": "https://packagist.org/downloads/", 845 | "license": [ 846 | "BSD-3-Clause" 847 | ], 848 | "authors": [ 849 | { 850 | "name": "Sebastian Bergmann", 851 | "email": "sb@sebastian-bergmann.de", 852 | "role": "lead" 853 | } 854 | ], 855 | "description": "FilterIterator implementation that filters files based on a list of suffixes.", 856 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", 857 | "keywords": [ 858 | "filesystem", 859 | "iterator" 860 | ], 861 | "support": { 862 | "irc": "irc://irc.freenode.net/phpunit", 863 | "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", 864 | "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/1.4.5" 865 | }, 866 | "time": "2017-11-27T13:52:08+00:00" 867 | }, 868 | { 869 | "name": "phpunit/php-text-template", 870 | "version": "1.2.1", 871 | "source": { 872 | "type": "git", 873 | "url": "https://github.com/sebastianbergmann/php-text-template.git", 874 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" 875 | }, 876 | "dist": { 877 | "type": "zip", 878 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 879 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 880 | "shasum": "" 881 | }, 882 | "require": { 883 | "php": ">=5.3.3" 884 | }, 885 | "type": "library", 886 | "autoload": { 887 | "classmap": [ 888 | "src/" 889 | ] 890 | }, 891 | "notification-url": "https://packagist.org/downloads/", 892 | "license": [ 893 | "BSD-3-Clause" 894 | ], 895 | "authors": [ 896 | { 897 | "name": "Sebastian Bergmann", 898 | "email": "sebastian@phpunit.de", 899 | "role": "lead" 900 | } 901 | ], 902 | "description": "Simple template engine.", 903 | "homepage": "https://github.com/sebastianbergmann/php-text-template/", 904 | "keywords": [ 905 | "template" 906 | ], 907 | "support": { 908 | "issues": "https://github.com/sebastianbergmann/php-text-template/issues", 909 | "source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1" 910 | }, 911 | "time": "2015-06-21T13:50:34+00:00" 912 | }, 913 | { 914 | "name": "phpunit/php-timer", 915 | "version": "1.0.9", 916 | "source": { 917 | "type": "git", 918 | "url": "https://github.com/sebastianbergmann/php-timer.git", 919 | "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" 920 | }, 921 | "dist": { 922 | "type": "zip", 923 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", 924 | "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", 925 | "shasum": "" 926 | }, 927 | "require": { 928 | "php": "^5.3.3 || ^7.0" 929 | }, 930 | "require-dev": { 931 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" 932 | }, 933 | "type": "library", 934 | "extra": { 935 | "branch-alias": { 936 | "dev-master": "1.0-dev" 937 | } 938 | }, 939 | "autoload": { 940 | "classmap": [ 941 | "src/" 942 | ] 943 | }, 944 | "notification-url": "https://packagist.org/downloads/", 945 | "license": [ 946 | "BSD-3-Clause" 947 | ], 948 | "authors": [ 949 | { 950 | "name": "Sebastian Bergmann", 951 | "email": "sb@sebastian-bergmann.de", 952 | "role": "lead" 953 | } 954 | ], 955 | "description": "Utility class for timing", 956 | "homepage": "https://github.com/sebastianbergmann/php-timer/", 957 | "keywords": [ 958 | "timer" 959 | ], 960 | "support": { 961 | "issues": "https://github.com/sebastianbergmann/php-timer/issues", 962 | "source": "https://github.com/sebastianbergmann/php-timer/tree/master" 963 | }, 964 | "time": "2017-02-26T11:10:40+00:00" 965 | }, 966 | { 967 | "name": "phpunit/php-token-stream", 968 | "version": "1.4.12", 969 | "source": { 970 | "type": "git", 971 | "url": "https://github.com/sebastianbergmann/php-token-stream.git", 972 | "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16" 973 | }, 974 | "dist": { 975 | "type": "zip", 976 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/1ce90ba27c42e4e44e6d8458241466380b51fa16", 977 | "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16", 978 | "shasum": "" 979 | }, 980 | "require": { 981 | "ext-tokenizer": "*", 982 | "php": ">=5.3.3" 983 | }, 984 | "require-dev": { 985 | "phpunit/phpunit": "~4.2" 986 | }, 987 | "type": "library", 988 | "extra": { 989 | "branch-alias": { 990 | "dev-master": "1.4-dev" 991 | } 992 | }, 993 | "autoload": { 994 | "classmap": [ 995 | "src/" 996 | ] 997 | }, 998 | "notification-url": "https://packagist.org/downloads/", 999 | "license": [ 1000 | "BSD-3-Clause" 1001 | ], 1002 | "authors": [ 1003 | { 1004 | "name": "Sebastian Bergmann", 1005 | "email": "sebastian@phpunit.de" 1006 | } 1007 | ], 1008 | "description": "Wrapper around PHP's tokenizer extension.", 1009 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/", 1010 | "keywords": [ 1011 | "tokenizer" 1012 | ], 1013 | "support": { 1014 | "issues": "https://github.com/sebastianbergmann/php-token-stream/issues", 1015 | "source": "https://github.com/sebastianbergmann/php-token-stream/tree/1.4" 1016 | }, 1017 | "abandoned": true, 1018 | "time": "2017-12-04T08:55:13+00:00" 1019 | }, 1020 | { 1021 | "name": "phpunit/phpunit", 1022 | "version": "4.8.36", 1023 | "source": { 1024 | "type": "git", 1025 | "url": "https://github.com/sebastianbergmann/phpunit.git", 1026 | "reference": "46023de9a91eec7dfb06cc56cb4e260017298517" 1027 | }, 1028 | "dist": { 1029 | "type": "zip", 1030 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/46023de9a91eec7dfb06cc56cb4e260017298517", 1031 | "reference": "46023de9a91eec7dfb06cc56cb4e260017298517", 1032 | "shasum": "" 1033 | }, 1034 | "require": { 1035 | "ext-dom": "*", 1036 | "ext-json": "*", 1037 | "ext-pcre": "*", 1038 | "ext-reflection": "*", 1039 | "ext-spl": "*", 1040 | "php": ">=5.3.3", 1041 | "phpspec/prophecy": "^1.3.1", 1042 | "phpunit/php-code-coverage": "~2.1", 1043 | "phpunit/php-file-iterator": "~1.4", 1044 | "phpunit/php-text-template": "~1.2", 1045 | "phpunit/php-timer": "^1.0.6", 1046 | "phpunit/phpunit-mock-objects": "~2.3", 1047 | "sebastian/comparator": "~1.2.2", 1048 | "sebastian/diff": "~1.2", 1049 | "sebastian/environment": "~1.3", 1050 | "sebastian/exporter": "~1.2", 1051 | "sebastian/global-state": "~1.0", 1052 | "sebastian/version": "~1.0", 1053 | "symfony/yaml": "~2.1|~3.0" 1054 | }, 1055 | "suggest": { 1056 | "phpunit/php-invoker": "~1.1" 1057 | }, 1058 | "bin": [ 1059 | "phpunit" 1060 | ], 1061 | "type": "library", 1062 | "extra": { 1063 | "branch-alias": { 1064 | "dev-master": "4.8.x-dev" 1065 | } 1066 | }, 1067 | "autoload": { 1068 | "classmap": [ 1069 | "src/" 1070 | ] 1071 | }, 1072 | "notification-url": "https://packagist.org/downloads/", 1073 | "license": [ 1074 | "BSD-3-Clause" 1075 | ], 1076 | "authors": [ 1077 | { 1078 | "name": "Sebastian Bergmann", 1079 | "email": "sebastian@phpunit.de", 1080 | "role": "lead" 1081 | } 1082 | ], 1083 | "description": "The PHP Unit Testing framework.", 1084 | "homepage": "https://phpunit.de/", 1085 | "keywords": [ 1086 | "phpunit", 1087 | "testing", 1088 | "xunit" 1089 | ], 1090 | "support": { 1091 | "issues": "https://github.com/sebastianbergmann/phpunit/issues", 1092 | "source": "https://github.com/sebastianbergmann/phpunit/tree/4.8.36" 1093 | }, 1094 | "time": "2017-06-21T08:07:12+00:00" 1095 | }, 1096 | { 1097 | "name": "phpunit/phpunit-mock-objects", 1098 | "version": "2.3.8", 1099 | "source": { 1100 | "type": "git", 1101 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", 1102 | "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983" 1103 | }, 1104 | "dist": { 1105 | "type": "zip", 1106 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", 1107 | "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983", 1108 | "shasum": "" 1109 | }, 1110 | "require": { 1111 | "doctrine/instantiator": "^1.0.2", 1112 | "php": ">=5.3.3", 1113 | "phpunit/php-text-template": "~1.2", 1114 | "sebastian/exporter": "~1.2" 1115 | }, 1116 | "require-dev": { 1117 | "phpunit/phpunit": "~4.4" 1118 | }, 1119 | "suggest": { 1120 | "ext-soap": "*" 1121 | }, 1122 | "type": "library", 1123 | "extra": { 1124 | "branch-alias": { 1125 | "dev-master": "2.3.x-dev" 1126 | } 1127 | }, 1128 | "autoload": { 1129 | "classmap": [ 1130 | "src/" 1131 | ] 1132 | }, 1133 | "notification-url": "https://packagist.org/downloads/", 1134 | "license": [ 1135 | "BSD-3-Clause" 1136 | ], 1137 | "authors": [ 1138 | { 1139 | "name": "Sebastian Bergmann", 1140 | "email": "sb@sebastian-bergmann.de", 1141 | "role": "lead" 1142 | } 1143 | ], 1144 | "description": "Mock Object library for PHPUnit", 1145 | "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", 1146 | "keywords": [ 1147 | "mock", 1148 | "xunit" 1149 | ], 1150 | "support": { 1151 | "irc": "irc://irc.freenode.net/phpunit", 1152 | "issues": "https://github.com/sebastianbergmann/phpunit-mock-objects/issues", 1153 | "source": "https://github.com/sebastianbergmann/phpunit-mock-objects/tree/2.3" 1154 | }, 1155 | "abandoned": true, 1156 | "time": "2015-10-02T06:51:40+00:00" 1157 | }, 1158 | { 1159 | "name": "sebastian/comparator", 1160 | "version": "1.2.4", 1161 | "source": { 1162 | "type": "git", 1163 | "url": "https://github.com/sebastianbergmann/comparator.git", 1164 | "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be" 1165 | }, 1166 | "dist": { 1167 | "type": "zip", 1168 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", 1169 | "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", 1170 | "shasum": "" 1171 | }, 1172 | "require": { 1173 | "php": ">=5.3.3", 1174 | "sebastian/diff": "~1.2", 1175 | "sebastian/exporter": "~1.2 || ~2.0" 1176 | }, 1177 | "require-dev": { 1178 | "phpunit/phpunit": "~4.4" 1179 | }, 1180 | "type": "library", 1181 | "extra": { 1182 | "branch-alias": { 1183 | "dev-master": "1.2.x-dev" 1184 | } 1185 | }, 1186 | "autoload": { 1187 | "classmap": [ 1188 | "src/" 1189 | ] 1190 | }, 1191 | "notification-url": "https://packagist.org/downloads/", 1192 | "license": [ 1193 | "BSD-3-Clause" 1194 | ], 1195 | "authors": [ 1196 | { 1197 | "name": "Jeff Welch", 1198 | "email": "whatthejeff@gmail.com" 1199 | }, 1200 | { 1201 | "name": "Volker Dusch", 1202 | "email": "github@wallbash.com" 1203 | }, 1204 | { 1205 | "name": "Bernhard Schussek", 1206 | "email": "bschussek@2bepublished.at" 1207 | }, 1208 | { 1209 | "name": "Sebastian Bergmann", 1210 | "email": "sebastian@phpunit.de" 1211 | } 1212 | ], 1213 | "description": "Provides the functionality to compare PHP values for equality", 1214 | "homepage": "http://www.github.com/sebastianbergmann/comparator", 1215 | "keywords": [ 1216 | "comparator", 1217 | "compare", 1218 | "equality" 1219 | ], 1220 | "support": { 1221 | "issues": "https://github.com/sebastianbergmann/comparator/issues", 1222 | "source": "https://github.com/sebastianbergmann/comparator/tree/1.2" 1223 | }, 1224 | "time": "2017-01-29T09:50:25+00:00" 1225 | }, 1226 | { 1227 | "name": "sebastian/diff", 1228 | "version": "1.4.3", 1229 | "source": { 1230 | "type": "git", 1231 | "url": "https://github.com/sebastianbergmann/diff.git", 1232 | "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4" 1233 | }, 1234 | "dist": { 1235 | "type": "zip", 1236 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4", 1237 | "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4", 1238 | "shasum": "" 1239 | }, 1240 | "require": { 1241 | "php": "^5.3.3 || ^7.0" 1242 | }, 1243 | "require-dev": { 1244 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" 1245 | }, 1246 | "type": "library", 1247 | "extra": { 1248 | "branch-alias": { 1249 | "dev-master": "1.4-dev" 1250 | } 1251 | }, 1252 | "autoload": { 1253 | "classmap": [ 1254 | "src/" 1255 | ] 1256 | }, 1257 | "notification-url": "https://packagist.org/downloads/", 1258 | "license": [ 1259 | "BSD-3-Clause" 1260 | ], 1261 | "authors": [ 1262 | { 1263 | "name": "Kore Nordmann", 1264 | "email": "mail@kore-nordmann.de" 1265 | }, 1266 | { 1267 | "name": "Sebastian Bergmann", 1268 | "email": "sebastian@phpunit.de" 1269 | } 1270 | ], 1271 | "description": "Diff implementation", 1272 | "homepage": "https://github.com/sebastianbergmann/diff", 1273 | "keywords": [ 1274 | "diff" 1275 | ], 1276 | "support": { 1277 | "issues": "https://github.com/sebastianbergmann/diff/issues", 1278 | "source": "https://github.com/sebastianbergmann/diff/tree/1.4" 1279 | }, 1280 | "time": "2017-05-22T07:24:03+00:00" 1281 | }, 1282 | { 1283 | "name": "sebastian/environment", 1284 | "version": "1.3.8", 1285 | "source": { 1286 | "type": "git", 1287 | "url": "https://github.com/sebastianbergmann/environment.git", 1288 | "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea" 1289 | }, 1290 | "dist": { 1291 | "type": "zip", 1292 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea", 1293 | "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea", 1294 | "shasum": "" 1295 | }, 1296 | "require": { 1297 | "php": "^5.3.3 || ^7.0" 1298 | }, 1299 | "require-dev": { 1300 | "phpunit/phpunit": "^4.8 || ^5.0" 1301 | }, 1302 | "type": "library", 1303 | "extra": { 1304 | "branch-alias": { 1305 | "dev-master": "1.3.x-dev" 1306 | } 1307 | }, 1308 | "autoload": { 1309 | "classmap": [ 1310 | "src/" 1311 | ] 1312 | }, 1313 | "notification-url": "https://packagist.org/downloads/", 1314 | "license": [ 1315 | "BSD-3-Clause" 1316 | ], 1317 | "authors": [ 1318 | { 1319 | "name": "Sebastian Bergmann", 1320 | "email": "sebastian@phpunit.de" 1321 | } 1322 | ], 1323 | "description": "Provides functionality to handle HHVM/PHP environments", 1324 | "homepage": "http://www.github.com/sebastianbergmann/environment", 1325 | "keywords": [ 1326 | "Xdebug", 1327 | "environment", 1328 | "hhvm" 1329 | ], 1330 | "support": { 1331 | "issues": "https://github.com/sebastianbergmann/environment/issues", 1332 | "source": "https://github.com/sebastianbergmann/environment/tree/1.3" 1333 | }, 1334 | "time": "2016-08-18T05:49:44+00:00" 1335 | }, 1336 | { 1337 | "name": "sebastian/exporter", 1338 | "version": "1.2.2", 1339 | "source": { 1340 | "type": "git", 1341 | "url": "https://github.com/sebastianbergmann/exporter.git", 1342 | "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4" 1343 | }, 1344 | "dist": { 1345 | "type": "zip", 1346 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4", 1347 | "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4", 1348 | "shasum": "" 1349 | }, 1350 | "require": { 1351 | "php": ">=5.3.3", 1352 | "sebastian/recursion-context": "~1.0" 1353 | }, 1354 | "require-dev": { 1355 | "ext-mbstring": "*", 1356 | "phpunit/phpunit": "~4.4" 1357 | }, 1358 | "type": "library", 1359 | "extra": { 1360 | "branch-alias": { 1361 | "dev-master": "1.3.x-dev" 1362 | } 1363 | }, 1364 | "autoload": { 1365 | "classmap": [ 1366 | "src/" 1367 | ] 1368 | }, 1369 | "notification-url": "https://packagist.org/downloads/", 1370 | "license": [ 1371 | "BSD-3-Clause" 1372 | ], 1373 | "authors": [ 1374 | { 1375 | "name": "Jeff Welch", 1376 | "email": "whatthejeff@gmail.com" 1377 | }, 1378 | { 1379 | "name": "Volker Dusch", 1380 | "email": "github@wallbash.com" 1381 | }, 1382 | { 1383 | "name": "Bernhard Schussek", 1384 | "email": "bschussek@2bepublished.at" 1385 | }, 1386 | { 1387 | "name": "Sebastian Bergmann", 1388 | "email": "sebastian@phpunit.de" 1389 | }, 1390 | { 1391 | "name": "Adam Harvey", 1392 | "email": "aharvey@php.net" 1393 | } 1394 | ], 1395 | "description": "Provides the functionality to export PHP variables for visualization", 1396 | "homepage": "http://www.github.com/sebastianbergmann/exporter", 1397 | "keywords": [ 1398 | "export", 1399 | "exporter" 1400 | ], 1401 | "support": { 1402 | "issues": "https://github.com/sebastianbergmann/exporter/issues", 1403 | "source": "https://github.com/sebastianbergmann/exporter/tree/master" 1404 | }, 1405 | "time": "2016-06-17T09:04:28+00:00" 1406 | }, 1407 | { 1408 | "name": "sebastian/global-state", 1409 | "version": "1.1.1", 1410 | "source": { 1411 | "type": "git", 1412 | "url": "https://github.com/sebastianbergmann/global-state.git", 1413 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" 1414 | }, 1415 | "dist": { 1416 | "type": "zip", 1417 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", 1418 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", 1419 | "shasum": "" 1420 | }, 1421 | "require": { 1422 | "php": ">=5.3.3" 1423 | }, 1424 | "require-dev": { 1425 | "phpunit/phpunit": "~4.2" 1426 | }, 1427 | "suggest": { 1428 | "ext-uopz": "*" 1429 | }, 1430 | "type": "library", 1431 | "extra": { 1432 | "branch-alias": { 1433 | "dev-master": "1.0-dev" 1434 | } 1435 | }, 1436 | "autoload": { 1437 | "classmap": [ 1438 | "src/" 1439 | ] 1440 | }, 1441 | "notification-url": "https://packagist.org/downloads/", 1442 | "license": [ 1443 | "BSD-3-Clause" 1444 | ], 1445 | "authors": [ 1446 | { 1447 | "name": "Sebastian Bergmann", 1448 | "email": "sebastian@phpunit.de" 1449 | } 1450 | ], 1451 | "description": "Snapshotting of global state", 1452 | "homepage": "http://www.github.com/sebastianbergmann/global-state", 1453 | "keywords": [ 1454 | "global state" 1455 | ], 1456 | "support": { 1457 | "issues": "https://github.com/sebastianbergmann/global-state/issues", 1458 | "source": "https://github.com/sebastianbergmann/global-state/tree/1.1.1" 1459 | }, 1460 | "time": "2015-10-12T03:26:01+00:00" 1461 | }, 1462 | { 1463 | "name": "sebastian/recursion-context", 1464 | "version": "1.0.5", 1465 | "source": { 1466 | "type": "git", 1467 | "url": "https://github.com/sebastianbergmann/recursion-context.git", 1468 | "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7" 1469 | }, 1470 | "dist": { 1471 | "type": "zip", 1472 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7", 1473 | "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7", 1474 | "shasum": "" 1475 | }, 1476 | "require": { 1477 | "php": ">=5.3.3" 1478 | }, 1479 | "require-dev": { 1480 | "phpunit/phpunit": "~4.4" 1481 | }, 1482 | "type": "library", 1483 | "extra": { 1484 | "branch-alias": { 1485 | "dev-master": "1.0.x-dev" 1486 | } 1487 | }, 1488 | "autoload": { 1489 | "classmap": [ 1490 | "src/" 1491 | ] 1492 | }, 1493 | "notification-url": "https://packagist.org/downloads/", 1494 | "license": [ 1495 | "BSD-3-Clause" 1496 | ], 1497 | "authors": [ 1498 | { 1499 | "name": "Jeff Welch", 1500 | "email": "whatthejeff@gmail.com" 1501 | }, 1502 | { 1503 | "name": "Sebastian Bergmann", 1504 | "email": "sebastian@phpunit.de" 1505 | }, 1506 | { 1507 | "name": "Adam Harvey", 1508 | "email": "aharvey@php.net" 1509 | } 1510 | ], 1511 | "description": "Provides functionality to recursively process PHP variables", 1512 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context", 1513 | "support": { 1514 | "issues": "https://github.com/sebastianbergmann/recursion-context/issues", 1515 | "source": "https://github.com/sebastianbergmann/recursion-context/tree/master" 1516 | }, 1517 | "time": "2016-10-03T07:41:43+00:00" 1518 | }, 1519 | { 1520 | "name": "sebastian/version", 1521 | "version": "1.0.6", 1522 | "source": { 1523 | "type": "git", 1524 | "url": "https://github.com/sebastianbergmann/version.git", 1525 | "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" 1526 | }, 1527 | "dist": { 1528 | "type": "zip", 1529 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", 1530 | "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", 1531 | "shasum": "" 1532 | }, 1533 | "type": "library", 1534 | "autoload": { 1535 | "classmap": [ 1536 | "src/" 1537 | ] 1538 | }, 1539 | "notification-url": "https://packagist.org/downloads/", 1540 | "license": [ 1541 | "BSD-3-Clause" 1542 | ], 1543 | "authors": [ 1544 | { 1545 | "name": "Sebastian Bergmann", 1546 | "email": "sebastian@phpunit.de", 1547 | "role": "lead" 1548 | } 1549 | ], 1550 | "description": "Library that helps with managing the version number of Git-hosted PHP projects", 1551 | "homepage": "https://github.com/sebastianbergmann/version", 1552 | "support": { 1553 | "issues": "https://github.com/sebastianbergmann/version/issues", 1554 | "source": "https://github.com/sebastianbergmann/version/tree/1.0.6" 1555 | }, 1556 | "time": "2015-06-21T13:59:46+00:00" 1557 | }, 1558 | { 1559 | "name": "symfony/polyfill-ctype", 1560 | "version": "v1.20.0", 1561 | "source": { 1562 | "type": "git", 1563 | "url": "https://github.com/symfony/polyfill-ctype.git", 1564 | "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41" 1565 | }, 1566 | "dist": { 1567 | "type": "zip", 1568 | "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f4ba089a5b6366e453971d3aad5fe8e897b37f41", 1569 | "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41", 1570 | "shasum": "" 1571 | }, 1572 | "require": { 1573 | "php": ">=7.1" 1574 | }, 1575 | "suggest": { 1576 | "ext-ctype": "For best performance" 1577 | }, 1578 | "type": "library", 1579 | "extra": { 1580 | "branch-alias": { 1581 | "dev-main": "1.20-dev" 1582 | }, 1583 | "thanks": { 1584 | "name": "symfony/polyfill", 1585 | "url": "https://github.com/symfony/polyfill" 1586 | } 1587 | }, 1588 | "autoload": { 1589 | "psr-4": { 1590 | "Symfony\\Polyfill\\Ctype\\": "" 1591 | }, 1592 | "files": [ 1593 | "bootstrap.php" 1594 | ] 1595 | }, 1596 | "notification-url": "https://packagist.org/downloads/", 1597 | "license": [ 1598 | "MIT" 1599 | ], 1600 | "authors": [ 1601 | { 1602 | "name": "Gert de Pagter", 1603 | "email": "BackEndTea@gmail.com" 1604 | }, 1605 | { 1606 | "name": "Symfony Community", 1607 | "homepage": "https://symfony.com/contributors" 1608 | } 1609 | ], 1610 | "description": "Symfony polyfill for ctype functions", 1611 | "homepage": "https://symfony.com", 1612 | "keywords": [ 1613 | "compatibility", 1614 | "ctype", 1615 | "polyfill", 1616 | "portable" 1617 | ], 1618 | "support": { 1619 | "source": "https://github.com/symfony/polyfill-ctype/tree/v1.20.0" 1620 | }, 1621 | "funding": [ 1622 | { 1623 | "url": "https://symfony.com/sponsor", 1624 | "type": "custom" 1625 | }, 1626 | { 1627 | "url": "https://github.com/fabpot", 1628 | "type": "github" 1629 | }, 1630 | { 1631 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 1632 | "type": "tidelift" 1633 | } 1634 | ], 1635 | "time": "2020-10-23T14:02:19+00:00" 1636 | }, 1637 | { 1638 | "name": "symfony/yaml", 1639 | "version": "v3.4.46", 1640 | "source": { 1641 | "type": "git", 1642 | "url": "https://github.com/symfony/yaml.git", 1643 | "reference": "88289caa3c166321883f67fe5130188ebbb47094" 1644 | }, 1645 | "dist": { 1646 | "type": "zip", 1647 | "url": "https://api.github.com/repos/symfony/yaml/zipball/88289caa3c166321883f67fe5130188ebbb47094", 1648 | "reference": "88289caa3c166321883f67fe5130188ebbb47094", 1649 | "shasum": "" 1650 | }, 1651 | "require": { 1652 | "php": "^5.5.9|>=7.0.8", 1653 | "symfony/polyfill-ctype": "~1.8" 1654 | }, 1655 | "conflict": { 1656 | "symfony/console": "<3.4" 1657 | }, 1658 | "require-dev": { 1659 | "symfony/console": "~3.4|~4.0" 1660 | }, 1661 | "suggest": { 1662 | "symfony/console": "For validating YAML files using the lint command" 1663 | }, 1664 | "type": "library", 1665 | "autoload": { 1666 | "psr-4": { 1667 | "Symfony\\Component\\Yaml\\": "" 1668 | }, 1669 | "exclude-from-classmap": [ 1670 | "/Tests/" 1671 | ] 1672 | }, 1673 | "notification-url": "https://packagist.org/downloads/", 1674 | "license": [ 1675 | "MIT" 1676 | ], 1677 | "authors": [ 1678 | { 1679 | "name": "Fabien Potencier", 1680 | "email": "fabien@symfony.com" 1681 | }, 1682 | { 1683 | "name": "Symfony Community", 1684 | "homepage": "https://symfony.com/contributors" 1685 | } 1686 | ], 1687 | "description": "Symfony Yaml Component", 1688 | "homepage": "https://symfony.com", 1689 | "support": { 1690 | "source": "https://github.com/symfony/yaml/tree/v3.4.46" 1691 | }, 1692 | "funding": [ 1693 | { 1694 | "url": "https://symfony.com/sponsor", 1695 | "type": "custom" 1696 | }, 1697 | { 1698 | "url": "https://github.com/fabpot", 1699 | "type": "github" 1700 | }, 1701 | { 1702 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 1703 | "type": "tidelift" 1704 | } 1705 | ], 1706 | "time": "2020-10-24T10:57:07+00:00" 1707 | }, 1708 | { 1709 | "name": "webmozart/assert", 1710 | "version": "1.9.1", 1711 | "source": { 1712 | "type": "git", 1713 | "url": "https://github.com/webmozart/assert.git", 1714 | "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" 1715 | }, 1716 | "dist": { 1717 | "type": "zip", 1718 | "url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", 1719 | "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", 1720 | "shasum": "" 1721 | }, 1722 | "require": { 1723 | "php": "^5.3.3 || ^7.0 || ^8.0", 1724 | "symfony/polyfill-ctype": "^1.8" 1725 | }, 1726 | "conflict": { 1727 | "phpstan/phpstan": "<0.12.20", 1728 | "vimeo/psalm": "<3.9.1" 1729 | }, 1730 | "require-dev": { 1731 | "phpunit/phpunit": "^4.8.36 || ^7.5.13" 1732 | }, 1733 | "type": "library", 1734 | "autoload": { 1735 | "psr-4": { 1736 | "Webmozart\\Assert\\": "src/" 1737 | } 1738 | }, 1739 | "notification-url": "https://packagist.org/downloads/", 1740 | "license": [ 1741 | "MIT" 1742 | ], 1743 | "authors": [ 1744 | { 1745 | "name": "Bernhard Schussek", 1746 | "email": "bschussek@gmail.com" 1747 | } 1748 | ], 1749 | "description": "Assertions to validate method input/output with nice error messages.", 1750 | "keywords": [ 1751 | "assert", 1752 | "check", 1753 | "validate" 1754 | ], 1755 | "support": { 1756 | "issues": "https://github.com/webmozart/assert/issues", 1757 | "source": "https://github.com/webmozart/assert/tree/master" 1758 | }, 1759 | "time": "2020-07-08T17:02:28+00:00" 1760 | } 1761 | ], 1762 | "aliases": [], 1763 | "minimum-stability": "stable", 1764 | "stability-flags": [], 1765 | "prefer-stable": false, 1766 | "prefer-lowest": false, 1767 | "platform": { 1768 | "php": ">=5.5" 1769 | }, 1770 | "platform-dev": [], 1771 | "plugin-api-version": "2.0.0" 1772 | } 1773 | -------------------------------------------------------------------------------- /src/udokmeci/yii2beanstalk/Beanstalk.php: -------------------------------------------------------------------------------- 1 | _beanstalk = new Pheanstalk($this->host, $this->port, $this->connectTimeout); 41 | } catch (ConnectionException $e) { 42 | Yii::error($e); 43 | } 44 | } 45 | 46 | private function isJson($string) 47 | { 48 | json_decode($string); 49 | return (json_last_error() == JSON_ERROR_NONE); 50 | } 51 | 52 | /** 53 | * {@inheritDoc} 54 | */ 55 | public function put( 56 | $data, 57 | $priority = PheanstalkInterface::DEFAULT_PRIORITY, 58 | $delay = PheanstalkInterface::DEFAULT_DELAY, 59 | $ttr = PheanstalkInterface::DEFAULT_TTR 60 | ) 61 | { 62 | try { 63 | if (!is_string($data)) { 64 | $data = json_encode($data); 65 | } 66 | return $this->_beanstalk->put($data, $priority, $delay, $ttr); 67 | } catch (ConnectionException $e) { 68 | Yii::error($e); 69 | return false; 70 | } 71 | } 72 | 73 | /** 74 | * {@inheritDoc} 75 | */ 76 | public function putInTube( 77 | $tube, 78 | $data, 79 | $priority = PheanstalkInterface::DEFAULT_PRIORITY, 80 | $delay = PheanstalkInterface::DEFAULT_DELAY, 81 | $ttr = PheanstalkInterface::DEFAULT_TTR 82 | ) { 83 | 84 | try { 85 | $this->_beanstalk->useTube($tube); 86 | return $this->put($data, $priority, $delay, $ttr); 87 | } catch (ConnectionException $e) { 88 | Yii::error($e); 89 | return false; 90 | } 91 | } 92 | 93 | public function __call($method, $args) 94 | { 95 | 96 | try { 97 | $result = call_user_func_array(array($this->_beanstalk, $method), $args); 98 | 99 | //Chaining. 100 | if ($result instanceof Pheanstalk) { 101 | return $this; 102 | } 103 | 104 | //Check for json data. 105 | if ($result instanceof Job) { 106 | if ($this->isJson($result->getData())) { 107 | $result = new Job($result->getId(), json_decode($result->getData())); 108 | } 109 | } 110 | return $result; 111 | 112 | } catch (ConnectionException $e) { 113 | Yii::error($e); 114 | return false; 115 | } catch (ServerException $e) { 116 | Yii::error($e); 117 | return false; 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/udokmeci/yii2beanstalk/BeanstalkController.php: -------------------------------------------------------------------------------- 1 | beanstalk)) { 69 | $this->beanstalk = Yii::$app->get($this->beanstalk); 70 | } 71 | if (!$this->beanstalk instanceof Beanstalk) { 72 | throw new InvalidConfigException("Controller beanstalk must extend from \\udokmeci\\yii2beanstalk\\Beanstalk."); 73 | } 74 | try { 75 | if (!isset(Yii::$app->getI18n()->translations['udokmeci.beanstalkd'])) { 76 | Yii::$app->getI18n()->translations['udokmeci.beanstalkd'] = [ 77 | 'class' => 'yii\i18n\PhpMessageSource', 78 | 'basePath' => '@app/messages', // if advanced application, set @frontend/messages 79 | 'sourceLanguage' => 'en', 80 | 'fileMap' => [ 81 | //'main' => 'main.php', 82 | ], 83 | ]; 84 | } 85 | } catch (ConnectionException $e) { 86 | Yii::error($e); 87 | } 88 | return parent::init(); 89 | } 90 | 91 | /** 92 | * Returns the matching action method for the job. 93 | * 94 | * @param object $statsJob stats-job response from deamon. 95 | * @return string Method name proper to yii2 matching to tube name 96 | */ 97 | public function getTubeAction($statsJob) 98 | { 99 | 100 | return isset($this->tubeActions[$statsJob->tube]) ? $this->tubeActions[$statsJob->tube] : false; 101 | } 102 | 103 | /** 104 | * Discovers tubes from deamon and merge them with user forced ones. 105 | * 106 | * @return array Collection of tube names. 107 | */ 108 | public function getTubes() 109 | { 110 | return array_unique(array_merge((array)$this->beanstalk->listTubes(), $this->listenTubes())); 111 | } 112 | 113 | public function getDb() 114 | { 115 | return Yii::$app->db; 116 | } 117 | 118 | /** 119 | * {@inheritDoc} 120 | */ 121 | public function actionIndex() 122 | { 123 | } 124 | 125 | public function setDBSessionTimeout() 126 | { 127 | try { 128 | $this->mysqlSessionTimeout(); 129 | } catch (\Exception $e) { 130 | Yii::error(Yii::t('udokmeci.beanstalkd', "DB wait timeout did not succeeded.")); 131 | } 132 | } 133 | 134 | /** 135 | * 136 | */ 137 | public function mysqlSessionTimeout() 138 | { 139 | try { 140 | $command = $this->getDb()->createCommand('SET @@session.wait_timeout = 31536000'); 141 | $command->execute(); 142 | } catch (\Exception $e) { 143 | Yii::error(Yii::t('udokmeci.beanstalkd', "Mysql session.wait_timeout command did not succeeded.")); 144 | } 145 | } 146 | 147 | /** 148 | * Decay a job with a fixed delay 149 | * 150 | * @param $job 151 | */ 152 | public function decayJob($job) 153 | { 154 | $jobStats = $this->beanstalk->statsJob($job); 155 | $delay_job = $jobStats->releases + $jobStats->delay + static::DELAY_TIME; 156 | if ($jobStats->releases >= static::DELAY_MAX) { 157 | $this->beanstalk->delete($job); 158 | $this->stderr(Yii::t('udokmeci.beanstalkd', 'Decaying Job Deleted!') . "\n", Console::FG_RED); 159 | } else { 160 | $this->beanstalk->release($job, static::DELAY_PRIORITY, $delay_job); 161 | } 162 | } 163 | 164 | /** 165 | * Retry a job using exponential back off delay strategy 166 | * 167 | * @param $job 168 | */ 169 | public function retryJobExponential($job) 170 | { 171 | $jobStats = $this->beanstalk->statsJob($job); 172 | 173 | if ($jobStats->releases == static::DELAY_RETRIES) { 174 | $this->beanstalk->delete($job); 175 | $this->stderr(Yii::t('udokmeci.beanstalkd', 176 | 'Retrying Job Deleted on retry ' . $jobStats->releases . '!') . "\n", Console::FG_RED); 177 | } else { 178 | $this->beanstalk->release( 179 | $job, 180 | static::DELAY_PRIORITY, 181 | intval( static::DELAY_TIME << $jobStats->releases + static::DELAY_TIME * rand(0, 1) ) 182 | ); 183 | } 184 | } 185 | 186 | /** 187 | * @return bool 188 | */ 189 | public function registerSignalHandler() 190 | { 191 | if (!extension_loaded('pcntl')) { 192 | $this->stdout(Yii::t('udokmeci.beanstalkd', 193 | "Warning: Process Control Extension is not loaded. Signal Handling Disabled! If process is interrupted, the reserved jobs will be hung. You may lose the job data.") . "\n", 194 | Console::FG_YELLOW); 195 | return null; 196 | } 197 | declare (ticks = 1); 198 | pcntl_signal(SIGTERM, [$this, 'signalHandler']); 199 | pcntl_signal(SIGINT, [$this, 'signalHandler']); 200 | pcntl_signal(SIGHUP, [$this, 'signalHandler']); 201 | $this->stdout(Yii::t('udokmeci.beanstalkd', 202 | "Process Control Extension is loaded. Signal Handling Registered!") . "\n", Console::FG_GREEN); 203 | return true; 204 | } 205 | 206 | /** 207 | * @param $signal 208 | * 209 | * @return bool 210 | */ 211 | public function signalHandler($signal) 212 | { 213 | $this->stdout(Yii::t('udokmeci.beanstalkd', "Received signal {signal}.", 214 | ['signal' => $signal]) . "\n", Console::FG_YELLOW); 215 | 216 | switch ($signal) { 217 | case SIGTERM: 218 | case SIGINT: 219 | case SIGHUP: 220 | $this->stdout(Yii::t('udokmeci.beanstalkd', "Exiting") . "...\n", Console::FG_RED); 221 | if (!$this->_inProgress) { 222 | return $this->end(); 223 | } 224 | $this->terminate(); 225 | break; 226 | default: 227 | break; 228 | } 229 | 230 | return null; 231 | } 232 | 233 | /** 234 | * Terminate job 235 | */ 236 | public function terminate() 237 | { 238 | $this->_willTerminate = true; 239 | } 240 | 241 | /** 242 | * Start test mode 243 | * 244 | * @return bool 245 | */ 246 | public function setTestMode() 247 | { 248 | return $this->_test = true; 249 | } 250 | 251 | /** 252 | * End job 253 | * 254 | * @param int $status 255 | * @return bool 256 | * @throws \yii\base\ExitException 257 | */ 258 | public function end($status = 0) 259 | { 260 | if ($this->_test) { 261 | return false; 262 | } 263 | return Yii::$app->end($status); 264 | } 265 | 266 | /** 267 | * Setup job before action 268 | * 269 | * @param \yii\base\Action $action 270 | * 271 | * @return bool 272 | * @throws \yii\base\InvalidConfigException 273 | */ 274 | public function beforeAction($action) 275 | { 276 | if ($action->id == "index") { 277 | try { 278 | $this->registerSignalHandler(); 279 | foreach ($this->getTubes() as $key => $tube) { 280 | $methodName = 'action' . str_replace(' ', '', ucwords(implode(' ', explode('-', $tube)))); 281 | if ($this->hasMethod($methodName)) { 282 | $this->tubeActions[$tube] = $methodName; 283 | $this->stdout(Yii::t('udokmeci.beanstalkd', "Listening {tube} tube.", 284 | ["tube" => $tube]) . "\n", Console::FG_GREEN); 285 | $bean = $this->beanstalk->watch($tube); 286 | if (!$bean) { 287 | $this->stderr("Check beanstalkd!" . "\n", Console::FG_RED); 288 | } 289 | } else { 290 | $this->stdout(Yii::t('udokmeci.beanstalkd', 291 | "Not Listening {tube} tube since there is no action defined. {methodName}", 292 | ["tube" => $tube, "methodName" => $methodName]) . "\n", Console::FG_YELLOW); 293 | } 294 | } 295 | 296 | if (count($this->tubeActions) == 0) { 297 | $this->stderr(Yii::t('udokmeci.beanstalkd', "No tube found to listen!") . "\n", 298 | Console::FG_RED); 299 | return $this->end(Controller::EXIT_CODE_ERROR); 300 | } 301 | 302 | if (isset($bean)) { 303 | while (!$this->_willTerminate) { 304 | try { 305 | if ($this->_lasttimereconnect == null) { 306 | $this->_lasttimereconnect = time(); 307 | $this->setDBSessionTimeout(); 308 | } 309 | 310 | if (time() - $this->_lasttimereconnect > 60 * 60) { 311 | $this->getDb()->close(); 312 | $this->getDb()->open(); 313 | Yii::info(Yii::t('udokmeci.beanstalkd', "Reconnecting to the DB")); 314 | $this->setDBSessionTimeout(); 315 | $this->_lasttimereconnect = time(); 316 | } 317 | 318 | $job = $bean->reserve($this->beanstalk->reserveTimeout); 319 | if (!$job) { 320 | if ($this->beanstalk->sleep) { 321 | usleep($this->beanstalk->sleep); 322 | } 323 | continue; 324 | } 325 | 326 | $jobStats = $bean->statsJob($job); 327 | $methodName = $this->getTubeAction($jobStats); 328 | 329 | if (!$methodName) { 330 | $this->stderr(Yii::t('udokmeci.beanstalkd', 331 | "No method found for job's tube!") . "\n", Console::FG_RED); 332 | break; 333 | } 334 | $this->_inProgress = true; 335 | $this->trigger(self::EVENT_BEFORE_JOB, new Event); 336 | $this->executeJob($methodName, $job); 337 | } catch (Yii\db\Exception $e) { 338 | if (isset($job)) { 339 | $this->decayJob($job); 340 | } 341 | $this->stderr($e->getMessage() . "\n", Console::FG_RED); 342 | $this->stderr(Yii::t('udokmeci.beanstalkd', 'DB Error job is decaying.') . "\n", 343 | Console::FG_RED); 344 | } catch (Yii\base\ErrorException $e) { 345 | $this->stderr($e->getMessage() . "\n", Console::FG_RED); 346 | } 347 | $this->_inProgress = false; 348 | $this->trigger(self::EVENT_AFTER_JOB, new Event); 349 | if ($this->beanstalk->sleep) { 350 | usleep($this->beanstalk->sleep); 351 | } 352 | } 353 | } 354 | } catch (ServerException $e) { 355 | $this->trigger(self::EVENT_AFTER_JOB, new Event); 356 | $this->stderr($e . "\n", Console::FG_RED); 357 | } 358 | 359 | return $this->end(Controller::EXIT_CODE_NORMAL); 360 | } 361 | 362 | return true; 363 | } 364 | 365 | /** 366 | * Execute job and handle outcome 367 | * 368 | * @param $methodName 369 | * @param $job 370 | */ 371 | protected function executeJob($methodName, $job) 372 | { 373 | switch (call_user_func_array( 374 | [$this, $methodName], 375 | ["job" => $job] 376 | ) 377 | ) { 378 | case self::NO_ACTION: 379 | break; 380 | case self::RELEASE: 381 | $this->beanstalk->release($job); 382 | break; 383 | case self::BURY: 384 | $this->beanstalk->bury($job); 385 | break; 386 | case self::DECAY: 387 | $this->decayJob($job); 388 | break; 389 | case self::DELETE: 390 | $this->beanstalk->delete($job); 391 | break; 392 | case self::DELAY: 393 | $this->beanstalk->release($job, static::DELAY_PRIORITY, static::DELAY_TIME); 394 | break; 395 | case self::DELAY_EXPONENTIAL: 396 | $this->retryJobExponential($job); 397 | break; 398 | default: 399 | $this->beanstalk->bury($job); 400 | break; 401 | } 402 | 403 | } 404 | } 405 | -------------------------------------------------------------------------------- /test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | sudo pkill beanstalkd 3 | beanstalkd & 4 | phpunit 5 | --------------------------------------------------------------------------------