diff --git a/.php_cs b/.php_cs new file mode 100644 index 0000000..e010b16 --- /dev/null +++ b/.php_cs @@ -0,0 +1,36 @@ +in('./custom/project/') + ->in('./repository/') +; + +return PhpCsFixer\Config::create() + ->setRules([ + '@PSR2' => true, + 'single_quote' => true, + 'function_typehint_space' => true, + 'hash_to_slash_comment' => true, + 'method_separation' => true, + 'no_blank_lines_after_phpdoc' => true, + 'no_blank_lines_before_namespace' => true, + 'no_unused_imports' => true, + 'no_useless_else' => true, + 'phpdoc_align' => true, + 'phpdoc_order' => true, + 'phpdoc_scalar' => true, + 'pre_increment' => true, + 'short_scalar_cast' => true, + 'space_after_semicolon' => true, + 'ternary_operator_spaces' => true, + 'trailing_comma_in_multiline_array' => true, + 'semicolon_after_instruction' => true, + 'trim_array_spaces' => true, + 'whitespace_after_comma_in_array' => true, + 'phpdoc_add_missing_param_annotation' => true, + 'binary_operator_spaces' => ['align_equals' => false, 'align_double_arrow' => true], + 'concat_space' => ['spacing' => 'one'], + 'array_syntax' => ['syntax' => 'short'], + ]) + ->setFinder($finder) +; diff --git a/Components/SentryClient.php b/Components/SentryClient.php deleted file mode 100644 index eb1acce..0000000 --- a/Components/SentryClient.php +++ /dev/null @@ -1,113 +0,0 @@ -container = $container; - $this->skipCapture = $container->getParameter('shopware.sentry')['skip_capture']; - } - - /** - * @param \Exception $exception - * @param array|null $data - * @param LoggerInterface|null $logger - * @param array|null $vars - * @return mixed - */ - public function captureException($exception, $data = null, $logger = null, $vars = null) - { - if ($this->shouldExceptionCaptureBeSkipped($exception)) { - return false; - } - - $this->tags_context([ - 'php_version' => phpversion() - ]); - if ($this->container) { - if ($this->container->initialized('session') && !$this->contextSet) { - // Frontend user is logged in - $userId = $this->container->get('session')->get('sUserId'); - if (!empty($userId)) { - $userData = Shopware()->Modules()->Admin()->sGetUserData(); - $this->user_context([ - 'id' => $userId, - 'email' => $userData['additional']['user']['email'] - ]); - $this->extra_context($userData); - $this->contextSet = true; - } - } else { - // Probably backend user - try { - $auth = Shopware()->Container()->get('Auth'); - // Workaround due to interface violation of \Zend_Auth_Adapter_Interface - if (method_exists($auth->getBaseAdapter(), 'refresh')) { - $auth = Shopware()->Plugins()->Backend()->Auth()->checkAuth(); - } - - if ($auth) { - $backendUser = $auth->getIdentity(); - - $this->user_context([ - 'id' => $backendUser->id, - 'username' => $backendUser->username, - 'email' => $backendUser->email - ]); - $this->contextSet = true; - - } - } catch (\Exception $e) { - } - } - if ($this->container->initialized('front')) { - $request = $this->container->get('front')->Request(); - $this->tags_context([ - 'module' => $request->getModuleName(), - 'controller' => $request->getControllerName(), - 'action' => $request->getActionName(), - ]); - } - } - return parent::captureException($exception, $data, $logger, $vars); - } - - /** - * @param \Exception $exception - * @return bool - */ - private function shouldExceptionCaptureBeSkipped(\Exception $exception) - { - foreach ($this->skipCapture as $className) { - if ($exception instanceof $className) { - return true; - } - } - - return false; - } - -} diff --git a/Components/SentryCompilerPass.php b/Components/SentryCompilerPass.php index 4d2043a..4aa95b5 100644 --- a/Components/SentryCompilerPass.php +++ b/Components/SentryCompilerPass.php @@ -5,10 +5,8 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ - namespace OdSentry\Components; - use Enlight_Controller_Exception; use Symfony\Component\Console\Exception\CommandNotFoundException; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; @@ -26,8 +24,8 @@ class SentryCompilerPass implements CompilerPassInterface private $defaultConfiguration = [ 'skip_capture' => [ CommandNotFoundException::class, - Enlight_Controller_Exception::class - ] + Enlight_Controller_Exception::class, + ], ]; /** @@ -41,4 +39,4 @@ public function process(ContainerBuilder $container) $container->setParameter('shopware.sentry', $this->defaultConfiguration); } } -} \ No newline at end of file +} diff --git a/OdSentry.php b/OdSentry.php index 0584046..1e90aab 100644 --- a/OdSentry.php +++ b/OdSentry.php @@ -5,43 +5,17 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ - namespace OdSentry; -use Doctrine\Common\Collections\ArrayCollection; -use Enlight_Event_EventArgs; -use OdSentry\Components\SentryClient; use OdSentry\Components\SentryCompilerPass; use Shopware\Components\Plugin; use Shopware\Components\Plugin\Context\ActivateContext; use Shopware\Components\Plugin\Context\InstallContext; -use Shopware\Components\Theme\LessDefinition; use Symfony\Component\DependencyInjection\ContainerBuilder; class OdSentry extends Plugin { - /** - * @var SentryClient - */ - protected $sentryClient; - - /** - * @return array - */ - public static function getSubscribedEvents() - { - return [ - 'Enlight_Controller_Front_StartDispatch' => 'onStartDispatch', - 'Enlight_Controller_Action_PreDispatch_Frontend_Error' => 'onPreDispatchError', - 'Enlight_Controller_Action_PreDispatch_Backend_Error' => 'onPreDispatchBackendError', - 'Theme_Compiler_Collect_Plugin_Javascript' => 'addJsFiles', - 'Theme_Compiler_Collect_Plugin_Less' => 'addLessFiles', - 'Theme_Compiler_Collect_Javascript_Files_FilterResult' => 'sortJs', - 'Enlight_Controller_Action_PostDispatch_Frontend' => 'onPostDispatchFrontend', - 'Enlight_Controller_Front_DispatchLoopShutdown' => 'onDispatchLoopShutdown', - 'Shopware_Console_Add_Command' => 'onStartDispatch' - ]; - } + const PLUGIN_NAME = 'OdSentry'; /** * Theme must be recompiled to include JS @@ -61,165 +35,4 @@ public function build(ContainerBuilder $container) parent::build($container); $container->addCompilerPass(new SentryCompilerPass()); } - - - /** - * Use the autoloader from the Raven library to load all necessary classes - */ - public function onStartDispatch() - { - if (file_exists(__DIR__ . '/vendor/autoload.php')) { - require_once __DIR__ . '/vendor/autoload.php'; - } - - if (Shopware()->Config()->getByNamespace('OdSentry', 'sentryLogPhp')) { - $privateDsn = Shopware()->Config()->getByNamespace('OdSentry', 'sentryPrivateDsn'); - $this->sentryClient = new SentryClient($privateDsn, [ - 'release' => \Shopware::VERSION, - 'environment' => $this->container->getParameter('kernel.environment'), - 'install_default_breadcrumb_handlers' => false - ]); - $this->sentryClient->setContainer($this->container); - - // Register global error handler - $errorHandler = new \Raven_ErrorHandler($this->sentryClient); - $errorHandler->registerExceptionHandler(); - $errorHandler->registerShutdownFunction(); - // Restore Shopware default error handler - restore_error_handler(); - restore_exception_handler(); - } - } - - /** - * @param Enlight_Event_EventArgs $args - * - * @return void - */ - public function onPreDispatchBackendError(Enlight_Event_EventArgs $args) - { - /** @var \Shopware_Controllers_Frontend_Error $subject */ - $subject = $args->getSubject(); - if ($this->sentryClient) { - $error = $subject->Request()->getParam('error_handler'); - if ($error && $error->exception) { - $this->sentryClient->captureException($error->exception); - } - } - } - - /** - * @param Enlight_Event_EventArgs $args - * - * @return void - */ - public function onPreDispatchError(Enlight_Event_EventArgs $args) - { - /** @var \Shopware_Controllers_Frontend_Error $subject */ - $subject = $args->getSubject(); - if ($this->sentryClient) { - $error = $subject->Request()->getParam('error_handler'); - if ($error && $error->exception) { - $id = $this->sentryClient->captureException($error->exception); - if (!Shopware()->Config()->getByNamespace('OdSentry', 'sentryUserfeedback')) { - return; - } - $this->container->get('template')->assignGlobal('sentryId', $id); - $this->container->get('template')->addTemplateDir($this->getPath() . '/Resources/views/'); - } - } - } - - /** - * Add the raven-js library to the compiled JS. - * It will we reordered by the sortJs function to be included - * before the bootstrapping of most JS to track these errors too. - * - * @return ArrayCollection - */ - public function addJsFiles() - { - $jsFiles = []; - $jsDir = __DIR__ . '/Resources/views/frontend/_public/src/js/'; - if (Shopware()->Config()->getByNamespace('OdSentry', 'sentryLogJs') || Shopware()->Config()->getByNamespace('OdSentry', 'sentryUserfeedback')) { - $jsFiles[] = $jsDir . 'vendor/raven.min.js'; - } - return new ArrayCollection($jsFiles); - } - - /** - * @return ArrayCollection - */ - public function addLessFiles() - { - $less = new LessDefinition( - [], - [__DIR__ . '/Resources/views/frontend/_public/src/less/all.less'], - __DIR__ - ); - - return new ArrayCollection([$less]); - } - - /** - * Sort the raven-js library to the front of the JS compilation pipeline - * so that it can track errors in the initialization of other JS libraries. - * - * @param Enlight_Event_EventArgs $args - * @return array - */ - public function sortJs(\Enlight_Event_EventArgs $args) - { - $files = $args->getReturn(); - $fileIdx = -1; - foreach ($files as $idx => $file) { - if (strpos($file, 'raven.min.js') !== false && strpos($file, 'OdSentry') !== false) { - $fileIdx = $idx; - break; - } - } - if ($fileIdx > -1) { - $tmp = array_splice($files, $fileIdx, 1); - // the 5th position is usually after the vendor libraries - array_splice($files, 5, 0, $tmp); - } - return $files; - } - - /** - * Like the \Shopware_Plugins_Core_ErrorHandler_Bootstrap we want to catch all errors - * that occured during a request and send them to Sentry - * - * @param \Enlight_Controller_EventArgs $args - */ - public function onDispatchLoopShutdown(\Enlight_Controller_EventArgs $args) - { - $response = $args->getSubject()->Response(); - $exceptions = $response->getException(); - if (empty($exceptions) || !$this->sentryClient) { - return; - } - foreach ($exceptions as $exception) { - $this->sentryClient->captureException($exception); - } - } - - /** - * We add templates from our plugin to include raven-js initialization after the JS libs - * - * @param \Enlight_Event_EventArgs $args - */ - public function onPostDispatchFrontend(\Enlight_Event_EventArgs $args) - { - /** @var \Enlight_Controller_Action $controller */ - $controller = $args->get('subject'); - $request = $controller->Request(); - $response = $controller->Response(); - $view = $controller->View(); - - if (!$request->isDispatched() || $response->isException() || $request->getModuleName() !== 'frontend' || !$view->hasTemplate()) { - return; - } - $view->addTemplateDir($this->getPath() . '/Resources/views/'); - } } diff --git a/README.md b/README.md index 2294d08..4f0db04 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# OdSentry plugin for Shopware 5.2 +# OdSentry plugin for Shopware 5.5 ## What is Sentry [Sentry](https://sentry.io) is a modern error tracking platform. You can log and trace errors in Sentry and collect directly feedback from user. @@ -32,15 +32,18 @@ If you enable it and a catchable error occurs, the user will be asked to provide ## Installation +**Requires PHP >= 7.1 !!** + ### Load plugin -#### Composer (Shopware 5.4+) +#### Composer (Shopware 5.5+) * Install via composer `composer require onedrop/shopware-sentry` #### Git Version * Checkout plugin in `git clone https://github.com/1drop/shopware-sentry.git custom/plugins/OdSentry` +* Install dependencies `composer install` #### Shopware plugin store diff --git a/Resources/config.xml b/Resources/config.xml index faff0e8..399c21b 100644 --- a/Resources/config.xml +++ b/Resources/config.xml @@ -7,12 +7,6 @@ false - - sentryPrivateDsn - - - - sentryLogJs diff --git a/Resources/services.xml b/Resources/services.xml new file mode 100644 index 0000000..58fee3d --- /dev/null +++ b/Resources/services.xml @@ -0,0 +1,17 @@ + + + + + + + %od_sentry.plugin_dir% + + + + + + + + diff --git a/Resources/views/frontend/_public/src/js/vendor/raven.min.js b/Resources/views/frontend/_public/src/js/vendor/raven.min.js index 8d1d51e..619c432 100644 --- a/Resources/views/frontend/_public/src/js/vendor/raven.min.js +++ b/Resources/views/frontend/_public/src/js/vendor/raven.min.js @@ -1,4 +1,4 @@ -/*! Raven.js 3.26.4 (409f3b4) | github.com/getsentry/raven-js */ -!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.Raven=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;gthis.k.maxBreadcrumbs&&this.u.shift(),this},addPlugin:function(a){var b=[].slice.call(arguments,1);return this.r.push([a,b]),this.n&&this.F(),this},setUserContext:function(a){return this.j.user=a,this},setExtraContext:function(a){return this.Z("extra",a),this},setTagsContext:function(a){return this.Z("tags",a),this},clearContext:function(){return this.j={},this},getContext:function(){return JSON.parse(h(this.j))},setEnvironment:function(a){return this.k.environment=a,this},setRelease:function(a){return this.k.release=a,this},setDataCallback:function(a){var b=this.k.dataCallback;return this.k.dataCallback=e(b,a),this},setBreadcrumbCallback:function(a){var b=this.k.breadcrumbCallback;return this.k.breadcrumbCallback=e(b,a),this},setShouldSendCallback:function(a){var b=this.k.shouldSendCallback;return this.k.shouldSendCallback=e(b,a),this},setTransport:function(a){return this.k.transport=a,this},lastException:function(){return this.d},lastEventId:function(){return this.f},isSetup:function(){return!!this.a&&(!!this.g||(this.ravenNotConfiguredError||(this.ravenNotConfiguredError=!0,this.z("error","Error: Raven has not been configured.")),!1))},afterLoad:function(){var a=R.RavenConfig;a&&this.config(a.dsn,a.config).install()},showReportDialog:function(a){if(S){if(a=Object.assign({eventId:this.lastEventId(),dsn:this.H,user:this.j.user||{}},a),!a.eventId)throw new j("Missing eventId");if(!a.dsn)throw new j("Missing DSN");var b=encodeURIComponent,c=[];for(var d in a)if("user"===d){var e=a.user;e.name&&c.push("name="+b(e.name)),e.email&&c.push("email="+b(e.email))}else c.push(b(d)+"="+b(a[d]));var f=this.J(this.G(a.dsn)),g=S.createElement("script");g.async=!0,g.src=f+"/api/embed/error-page/?"+c.join("&"),(S.head||S.body).appendChild(g)}},L:function(){var a=this;this.m+=1,setTimeout(function(){a.m-=1})},$:function(a,b){var c,d;if(this.b){b=b||{},a="raven"+a.substr(0,1).toUpperCase()+a.substr(1),S.createEvent?(c=S.createEvent("HTMLEvents"),c.initEvent(a,!0,!0)):(c=S.createEventObject(),c.eventType=a);for(d in b)A(b,d)&&(c[d]=b[d]);if(S.createEvent)S.dispatchEvent(c);else try{S.fireEvent("on"+c.eventType.toLowerCase(),c)}catch(e){}}},_:function(a){var b=this;return function(c){if(b.aa=null,b.v!==c){b.v=c;var d;try{d=E(c.target)}catch(e){d=""}b.captureBreadcrumb({category:"ui."+a,message:d})}}},ba:function(){var a=this,b=1e3;return function(c){var d;try{d=c.target}catch(e){return}var f=d&&d.tagName;if(f&&("INPUT"===f||"TEXTAREA"===f||d.isContentEditable)){var g=a.aa;g||a._("input")(c),clearTimeout(g),a.aa=setTimeout(function(){a.aa=null},b)}}},ca:function(a,b){var c=H(this.w.href),d=H(b),e=H(a);this.x=b,c.protocol===d.protocol&&c.host===d.host&&(b=d.relative),c.protocol===e.protocol&&c.host===e.host&&(a=e.relative),this.captureBreadcrumb({category:"navigation",data:{to:b,from:a}})},C:function(){var a=this;a.da=Function.prototype.toString,Function.prototype.toString=function(){return"function"==typeof this&&this.M?a.da.apply(this.O,arguments):a.da.apply(this,arguments)}},Q:function(){this.da&&(Function.prototype.toString=this.da)},D:function(){function a(a){return function(b,d){for(var e=new Array(arguments.length),f=0;f"}}},g)),a.apply?a.apply(this,e):a(e[0],e[1])}}function b(a){var b=R[a]&&R[a].prototype;b&&b.hasOwnProperty&&b.hasOwnProperty("addEventListener")&&(I(b,"addEventListener",function(b){return function(d,f,g,h){try{f&&f.handleEvent&&(f.handleEvent=c.wrap({mechanism:{type:"instrument",data:{target:a,"function":"handleEvent",handler:f&&f.name||""}}},f.handleEvent))}catch(i){}var j,k,l;return e&&e.dom&&("EventTarget"===a||"Node"===a)&&(k=c._("click"),l=c.ba(),j=function(a){if(a){var b;try{b=a.type}catch(c){return}return"click"===b?k(a):"keypress"===b?l(a):void 0}}),b.call(this,d,c.wrap({mechanism:{type:"instrument",data:{target:a,"function":"addEventListener",handler:f&&f.name||""}}},f,j),g,h)}},d),I(b,"removeEventListener",function(a){return function(b,c,d,e){try{c=c&&(c.N?c.N:c)}catch(f){}return a.call(this,b,c,d,e)}},d))}var c=this,d=c.t,e=this.k.autoBreadcrumbs;I(R,"setTimeout",a,d),I(R,"setInterval",a,d),R.requestAnimationFrame&&I(R,"requestAnimationFrame",function(a){return function(b){return a(c.wrap({mechanism:{type:"instrument",data:{"function":"requestAnimationFrame",handler:a&&a.name||""}}},b))}},d);for(var f=["EventTarget","Window","Node","ApplicationCache","AudioTrackList","ChannelMergerNode","CryptoOperation","EventSource","FileReader","HTMLUnknownElement","IDBDatabase","IDBRequest","IDBTransaction","KeyOperation","MediaController","MessagePort","ModalWindow","Notification","SVGElementInstance","Screen","TextTrack","TextTrackCue","TextTrackList","WebSocket","WebSocketWorker","Worker","XMLHttpRequest","XMLHttpRequestEventTarget","XMLHttpRequestUpload"],g=0;g"}}},c)})}var b=this,c=this.k.autoBreadcrumbs,d=b.t;if(c.xhr&&"XMLHttpRequest"in R){var e=R.XMLHttpRequest&&R.XMLHttpRequest.prototype;I(e,"open",function(a){return function(c,d){return t(d)&&d.indexOf(b.h)===-1&&(this.ea={method:c,url:d,status_code:null}),a.apply(this,arguments)}},d),I(e,"send",function(c){return function(){function d(){if(e.ea&&4===e.readyState){try{e.ea.status_code=e.status}catch(a){}b.captureBreadcrumb({type:"http",category:"xhr",data:e.ea})}}for(var e=this,f=["onload","onerror","onprogress"],g=0;g"}}},a,d)}):e.onreadystatechange=d,c.apply(this,arguments)}},d)}c.xhr&&J()&&I(R,"fetch",function(a){return function(){for(var c=new Array(arguments.length),d=0;d2?arguments[2]:void 0;return c&&b.ca(b.x,c+""),a.apply(this,arguments)}};I(R.history,"pushState",j,d),I(R.history,"replaceState",j,d)}if(c.console&&"console"in R&&console.log){var k=function(a,c){b.captureBreadcrumb({message:a,level:c.level,category:"console"})};w(["debug","info","warn","error","log"],function(a,b){O(console,b,k)})}},R:function(){for(var a;this.t.length;){a=this.t.shift();var b=a[0],c=a[1],d=a[2];b[c]=d}},S:function(){for(var a in this.q)this.p[a]=this.q[a]},F:function(){var a=this;w(this.r,function(b,c){var d=c[0],e=c[1];d.apply(a,[a].concat(e))})},G:function(a){var b=Q.exec(a),c={},d=7;try{for(;d--;)c[P[d]]=b[d]||""}catch(e){throw new j("Invalid DSN: "+a)}if(c.pass&&!this.k.allowSecretKey)throw new j("Do not specify your secret key in the DSN. See: http://bit.ly/raven-secret-key");return c},J:function(a){var b="//"+a.host+(a.port?":"+a.port:"");return a.protocol&&(b=a.protocol+":"+b),b},A:function(a,b){b=b||{},b.mechanism=b.mechanism||{type:"onerror",handled:!1},this.m||this.V(a,b)},V:function(a,b){var c=this.X(a,b);this.$("handle",{stackInfo:a,options:b}),this.fa(a.name,a.message,a.url,a.lineno,c,b)},X:function(a,b){var c=this,d=[];if(a.stack&&a.stack.length&&(w(a.stack,function(b,e){var f=c.ga(e,a.url);f&&d.push(f)}),b&&b.trimHeadFrames))for(var e=0;e0&&(a.breadcrumbs={values:[].slice.call(this.u,0)}),this.j.user&&(a.user=this.j.user),b.environment&&(a.environment=b.environment),b.release&&(a.release=b.release),b.serverName&&(a.server_name=b.serverName),a=this.pa(a),Object.keys(a).forEach(function(b){(null==a[b]||""===a[b]||v(a[b]))&&delete a[b]}),s(b.dataCallback)&&(a=b.dataCallback(a)||a),a&&!v(a)&&(!s(b.shouldSendCallback)||b.shouldSendCallback(a)))return this.ma()?void this.z("warn","Raven dropped error due to backoff: ",a):void("number"==typeof b.sampleRate?Math.random() ",i=h.length;a&&f++1&&g+e.length*i+b.length>=d));)e.push(b),g+=b.length,a=a.parentNode;return e.reverse().join(h)}function F(a){var b,c,d,e,f,g=[];if(!a||!a.tagName)return"";if(g.push(a.tagName.toLowerCase()),a.id&&g.push("#"+a.id),b=a.className,b&&l(b))for(c=b.split(/\s+/),f=0;fc?Q(a,b-1):d}function R(a,b){if("number"==typeof a||"string"==typeof a)return a.toString();if(!Array.isArray(a))return"";if(a=a.filter(function(a){return"string"==typeof a}),0===a.length)return"[object has no keys]";if(b="number"!=typeof b?X:b,a[0].length>=b)return a[0];for(var c=a.length;c>0;c--){var d=a.slice(0,c).join(", ");if(!(d.length>b))return c===a.length?d:d+"…"}return""}function S(a,b){function c(a){return m(a)?a.map(function(a){return c(a)}):k(a)?Object.keys(a).reduce(function(b,d){return b[d]=e.test(d)?f:c(a[d]),b},{}):a}if(!m(b)||m(b)&&0===b.length)return a;var d,e=A(b),f="********";try{d=JSON.parse(T(a))}catch(g){return a}return c(d)}var T=a(7),U="undefined"!=typeof window?window:"undefined"!=typeof c?c:"undefined"!=typeof self?self:{},V=3,W=51200,X=40;b.exports={isObject:d,isError:e,isErrorEvent:f,isDOMError:g,isDOMException:h,isUndefined:i,isFunction:j,isPlainObject:k,isString:l,isArray:m,isEmptyObject:n,supportsErrorEvent:o,supportsDOMError:p,supportsDOMException:q,supportsFetch:r,supportsReferrerPolicy:s,supportsPromiseRejectionEvent:t,wrappedCallback:u,each:v,objectMerge:w,truncate:y,objectFrozen:x,hasKey:z,joinRegExp:A,urlencode:B,uuid4:D,htmlTreeAsString:E,htmlElementAsString:F,isSameException:I,isSameStacktrace:J,parseUrl:C,fill:K,safeJoin:L,serializeException:Q,serializeKeysForMessage:R,sanitize:S}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{7:7}],6:[function(a,b,c){(function(c){function d(){return"undefined"==typeof document||null==document.location?"":document.location.href}function e(){return"undefined"==typeof document||null==document.location?"":document.location.origin?document.location.origin:document.location.protocol+"//"+document.location.hostname+(document.location.port?":"+document.location.port:"")}var f=a(5),g={collectWindowErrors:!0,debug:!1},h="undefined"!=typeof window?window:"undefined"!=typeof c?c:"undefined"!=typeof self?self:{},i=[].slice,j="?",k=/^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/;g.report=function(){function a(a){m(),s.push(a)}function b(a){for(var b=s.length-1;b>=0;--b)s[b]===a&&s.splice(b,1)}function c(){n(),s=[]}function e(a,b){var c=null;if(!b||g.collectWindowErrors){for(var d in s)if(s.hasOwnProperty(d))try{s[d].apply(null,[a].concat(i.call(arguments,2)))}catch(e){c=e}if(c)throw c}}function l(a,b,c,h,i){var l=null,m=f.isErrorEvent(i)?i.error:i,n=f.isErrorEvent(a)?a.message:a;if(v)g.computeStackTrace.augmentStackTraceWithInitialElement(v,b,c,n),o();else if(m&&f.isError(m))l=g.computeStackTrace(m),e(l,!0);else{var p,r={url:b,line:c,column:h},s=void 0;if("[object String]"==={}.toString.call(n)){var p=n.match(k);p&&(s=p[1],n=p[2])}r.func=j,l={name:s,message:n,url:d(),stack:[r]},e(l,!0)}return!!q&&q.apply(this,arguments)}function m(){r||(q=h.onerror,h.onerror=l,r=!0)}function n(){r&&(h.onerror=q,r=!1,q=void 0)}function o(){var a=v,b=t;t=null,v=null,u=null,e.apply(null,[a,!1].concat(b))}function p(a,b){var c=i.call(arguments,1);if(v){if(u===a)return;o()}var d=g.computeStackTrace(a);if(v=d,u=a,t=c,setTimeout(function(){u===a&&o()},d.incomplete?2e3:0),b!==!1)throw a}var q,r,s=[],t=null,u=null,v=null;return p.subscribe=a,p.unsubscribe=b,p.uninstall=c,p}(),g.computeStackTrace=function(){function a(a){if("undefined"!=typeof a.stack&&a.stack){for(var b,c,f,g=/^\s*at (?:(.*?) ?\()?((?:file|https?|blob|chrome-extension|native|eval|webpack||[a-z]:|\/).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i,h=/^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx(?:-web)|https?|webpack|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i,i=/^\s*(.*?)(?:\((.*?)\))?(?:^|@)((?:file|https?|blob|chrome|webpack|resource|moz-extension).*?:\/.*?|\[native code\]|[^@]*bundle)(?::(\d+))?(?::(\d+))?\s*$/i,k=/(\S+) line (\d+)(?: > eval line \d+)* > eval/i,l=/\((\S*)(?::(\d+))(?::(\d+))\)/,m=a.stack.split("\n"),n=[],o=(/^(.*) is undefined$/.exec(a.message),0),p=m.length;o eval")>-1;r&&(b=k.exec(c[3]))?(c[3]=b[1],c[4]=b[2],c[5]=null):0!==o||c[5]||"undefined"==typeof a.columnNumber||(n[0].column=a.columnNumber+1),f={url:c[3],func:c[1]||j,args:c[2]?c[2].split(","):[],line:c[4]?+c[4]:null,column:c[5]?+c[5]:null}}if(!f.func&&f.line&&(f.func=j),f.url&&"blob:"===f.url.substr(0,5)){var s=new XMLHttpRequest;if(s.open("GET",f.url,!1),s.send(null),200===s.status){var t=s.responseText||"";t=t.slice(-300);var u=t.match(/\/\/# sourceMappingURL=(.*)$/);if(u){var v=u[1];"~"===v.charAt(0)&&(v=e()+v.slice(1)),f.url=v.slice(0,-4)}}}n.push(f)}return n.length?{name:a.name,message:a.message,url:d(),stack:n}:null}}function b(a,b,c,d){var e={url:b,line:c};if(e.url&&e.line){if(a.incomplete=!1,e.func||(e.func=j),a.stack.length>0&&a.stack[0].url===e.url){if(a.stack[0].line===e.line)return!1;if(!a.stack[0].line&&a.stack[0].func===e.func)return a.stack[0].line=e.line, +/*! Raven.js 3.27.0 (7ea4d0dd) | github.com/getsentry/raven-js */ +!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.Raven=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;gthis.k.maxBreadcrumbs&&this.u.shift(),this},addPlugin:function(a){var b=[].slice.call(arguments,1);return this.r.push([a,b]),this.n&&this.F(),this},setUserContext:function(a){return this.j.user=a,this},setExtraContext:function(a){return this.Z("extra",a),this},setTagsContext:function(a){return this.Z("tags",a),this},clearContext:function(){return this.j={},this},getContext:function(){return JSON.parse(h(this.j))},setEnvironment:function(a){return this.k.environment=a,this},setRelease:function(a){return this.k.release=a,this},setDataCallback:function(a){var b=this.k.dataCallback;return this.k.dataCallback=e(b,a),this},setBreadcrumbCallback:function(a){var b=this.k.breadcrumbCallback;return this.k.breadcrumbCallback=e(b,a),this},setShouldSendCallback:function(a){var b=this.k.shouldSendCallback;return this.k.shouldSendCallback=e(b,a),this},setTransport:function(a){return this.k.transport=a,this},lastException:function(){return this.d},lastEventId:function(){return this.f},isSetup:function(){return!!this.a&&(!!this.g||(this.ravenNotConfiguredError||(this.ravenNotConfiguredError=!0,this.z("error","Error: Raven has not been configured.")),!1))},afterLoad:function(){var a=R.RavenConfig;a&&this.config(a.dsn,a.config).install()},showReportDialog:function(a){if(S){if(a=x({eventId:this.lastEventId(),dsn:this.H,user:this.j.user||{}},a),!a.eventId)throw new j("Missing eventId");if(!a.dsn)throw new j("Missing DSN");var b=encodeURIComponent,c=[];for(var d in a)if("user"===d){var e=a.user;e.name&&c.push("name="+b(e.name)),e.email&&c.push("email="+b(e.email))}else c.push(b(d)+"="+b(a[d]));var f=this.J(this.G(a.dsn)),g=S.createElement("script");g.async=!0,g.src=f+"/api/embed/error-page/?"+c.join("&"),(S.head||S.body).appendChild(g)}},L:function(){var a=this;this.m+=1,setTimeout(function(){a.m-=1})},$:function(a,b){var c,d;if(this.b){b=b||{},a="raven"+a.substr(0,1).toUpperCase()+a.substr(1),S.createEvent?(c=S.createEvent("HTMLEvents"),c.initEvent(a,!0,!0)):(c=S.createEventObject(),c.eventType=a);for(d in b)A(b,d)&&(c[d]=b[d]);if(S.createEvent)S.dispatchEvent(c);else try{S.fireEvent("on"+c.eventType.toLowerCase(),c)}catch(e){}}},_:function(a){var b=this;return function(c){if(b.aa=null,b.v!==c){b.v=c;var d;try{d=E(c.target)}catch(e){d=""}b.captureBreadcrumb({category:"ui."+a,message:d})}}},ba:function(){var a=this,b=1e3;return function(c){var d;try{d=c.target}catch(e){return}var f=d&&d.tagName;if(f&&("INPUT"===f||"TEXTAREA"===f||d.isContentEditable)){var g=a.aa;g||a._("input")(c),clearTimeout(g),a.aa=setTimeout(function(){a.aa=null},b)}}},ca:function(a,b){var c=H(this.w.href),d=H(b),e=H(a);this.x=b,c.protocol===d.protocol&&c.host===d.host&&(b=d.relative),c.protocol===e.protocol&&c.host===e.host&&(a=e.relative),this.captureBreadcrumb({category:"navigation",data:{to:b,from:a}})},C:function(){var a=this;a.da=Function.prototype.toString,Function.prototype.toString=function(){return"function"==typeof this&&this.M?a.da.apply(this.O,arguments):a.da.apply(this,arguments)}},Q:function(){this.da&&(Function.prototype.toString=this.da)},D:function(){function a(a){return function(b,d){for(var e=new Array(arguments.length),f=0;f"}}},g)),a.apply?a.apply(this,e):a(e[0],e[1])}}function b(a){var b=R[a]&&R[a].prototype;b&&b.hasOwnProperty&&b.hasOwnProperty("addEventListener")&&(I(b,"addEventListener",function(b){return function(d,f,g,h){try{f&&f.handleEvent&&(f.handleEvent=c.wrap({mechanism:{type:"instrument",data:{target:a,"function":"handleEvent",handler:f&&f.name||""}}},f.handleEvent))}catch(i){}var j,k,l;return e&&e.dom&&("EventTarget"===a||"Node"===a)&&(k=c._("click"),l=c.ba(),j=function(a){if(a){var b;try{b=a.type}catch(c){return}return"click"===b?k(a):"keypress"===b?l(a):void 0}}),b.call(this,d,c.wrap({mechanism:{type:"instrument",data:{target:a,"function":"addEventListener",handler:f&&f.name||""}}},f,j),g,h)}},d),I(b,"removeEventListener",function(a){return function(b,c,d,e){try{c=c&&(c.N?c.N:c)}catch(f){}return a.call(this,b,c,d,e)}},d))}var c=this,d=c.t,e=this.k.autoBreadcrumbs;I(R,"setTimeout",a,d),I(R,"setInterval",a,d),R.requestAnimationFrame&&I(R,"requestAnimationFrame",function(a){return function(b){return a(c.wrap({mechanism:{type:"instrument",data:{"function":"requestAnimationFrame",handler:a&&a.name||""}}},b))}},d);for(var f=["EventTarget","Window","Node","ApplicationCache","AudioTrackList","ChannelMergerNode","CryptoOperation","EventSource","FileReader","HTMLUnknownElement","IDBDatabase","IDBRequest","IDBTransaction","KeyOperation","MediaController","MessagePort","ModalWindow","Notification","SVGElementInstance","Screen","TextTrack","TextTrackCue","TextTrackList","WebSocket","WebSocketWorker","Worker","XMLHttpRequest","XMLHttpRequestEventTarget","XMLHttpRequestUpload"],g=0;g"}}},c)})}var b=this,c=this.k.autoBreadcrumbs,d=b.t;if(c.xhr&&"XMLHttpRequest"in R){var e=R.XMLHttpRequest&&R.XMLHttpRequest.prototype;I(e,"open",function(a){return function(c,d){return t(d)&&d.indexOf(b.h)===-1&&(this.ea={method:c,url:d,status_code:null}),a.apply(this,arguments)}},d),I(e,"send",function(c){return function(){function d(){if(e.ea&&4===e.readyState){try{e.ea.status_code=e.status}catch(a){}b.captureBreadcrumb({type:"http",category:"xhr",data:e.ea})}}for(var e=this,f=["onload","onerror","onprogress"],g=0;g"}}},a,d)}):e.onreadystatechange=d,c.apply(this,arguments)}},d)}c.xhr&&J()&&I(R,"fetch",function(a){return function(){for(var c=new Array(arguments.length),d=0;d2?arguments[2]:void 0;return c&&b.ca(b.x,c+""),a.apply(this,arguments)}};I(R.history,"pushState",j,d),I(R.history,"replaceState",j,d)}if(c.console&&"console"in R&&console.log){var k=function(a,c){b.captureBreadcrumb({message:a,level:c.level,category:"console"})};w(["debug","info","warn","error","log"],function(a,b){O(console,b,k)})}},R:function(){for(var a;this.t.length;){a=this.t.shift();var b=a[0],c=a[1],d=a[2];b[c]=d}},S:function(){for(var a in this.q)this.p[a]=this.q[a]},F:function(){var a=this;w(this.r,function(b,c){var d=c[0],e=c[1];d.apply(a,[a].concat(e))})},G:function(a){var b=Q.exec(a),c={},d=7;try{for(;d--;)c[P[d]]=b[d]||""}catch(e){throw new j("Invalid DSN: "+a)}if(c.pass&&!this.k.allowSecretKey)throw new j("Do not specify your secret key in the DSN. See: http://bit.ly/raven-secret-key");return c},J:function(a){var b="//"+a.host+(a.port?":"+a.port:"");return a.protocol&&(b=a.protocol+":"+b),b},A:function(a,b){b=b||{},b.mechanism=b.mechanism||{type:"onerror",handled:!1},this.m||this.V(a,b)},V:function(a,b){var c=this.X(a,b);this.$("handle",{stackInfo:a,options:b}),this.fa(a.name,a.message,a.url,a.lineno,c,b)},X:function(a,b){var c=this,d=[];if(a.stack&&a.stack.length&&(w(a.stack,function(b,e){var f=c.ga(e,a.url);f&&d.push(f)}),b&&b.trimHeadFrames))for(var e=0;e0&&(a.breadcrumbs={values:[].slice.call(this.u,0)}),this.j.user&&(a.user=this.j.user),b.environment&&(a.environment=b.environment),b.release&&(a.release=b.release),b.serverName&&(a.server_name=b.serverName),a=this.pa(a),Object.keys(a).forEach(function(b){(null==a[b]||""===a[b]||v(a[b]))&&delete a[b]}),s(b.dataCallback)&&(a=b.dataCallback(a)||a),a&&!v(a)&&(!s(b.shouldSendCallback)||b.shouldSendCallback(a)))return this.ma()?void this.z("warn","Raven dropped error due to backoff: ",a):void("number"==typeof b.sampleRate?Math.random() ",i=h.length;a&&f++1&&g+e.length*i+b.length>=d));)e.push(b),g+=b.length,a=a.parentNode;return e.reverse().join(h)}function F(a){var b,c,d,e,f,g=[];if(!a||!a.tagName)return"";if(g.push(a.tagName.toLowerCase()),a.id&&g.push("#"+a.id),b=a.className,b&&l(b))for(c=b.split(/\s+/),f=0;fc?Q(a,b-1):d}function R(a,b){if("number"==typeof a||"string"==typeof a)return a.toString();if(!Array.isArray(a))return"";if(a=a.filter(function(a){return"string"==typeof a}),0===a.length)return"[object has no keys]";if(b="number"!=typeof b?X:b,a[0].length>=b)return a[0];for(var c=a.length;c>0;c--){var d=a.slice(0,c).join(", ");if(!(d.length>b))return c===a.length?d:d+"…"}return""}function S(a,b){function c(a){return m(a)?a.map(function(a){return c(a)}):k(a)?Object.keys(a).reduce(function(b,d){return b[d]=e.test(d)?f:c(a[d]),b},{}):a}if(!m(b)||m(b)&&0===b.length)return a;var d,e=A(b),f="********";try{d=JSON.parse(T(a))}catch(g){return a}return c(d)}var T=a(7),U="undefined"!=typeof window?window:"undefined"!=typeof c?c:"undefined"!=typeof self?self:{},V=3,W=51200,X=40;b.exports={isObject:d,isError:e,isErrorEvent:f,isDOMError:g,isDOMException:h,isUndefined:i,isFunction:j,isPlainObject:k,isString:l,isArray:m,isEmptyObject:n,supportsErrorEvent:o,supportsDOMError:p,supportsDOMException:q,supportsFetch:r,supportsReferrerPolicy:s,supportsPromiseRejectionEvent:t,wrappedCallback:u,each:v,objectMerge:w,truncate:y,objectFrozen:x,hasKey:z,joinRegExp:A,urlencode:B,uuid4:D,htmlTreeAsString:E,htmlElementAsString:F,isSameException:I,isSameStacktrace:J,parseUrl:C,fill:K,safeJoin:L,serializeException:Q,serializeKeysForMessage:R,sanitize:S}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{7:7}],6:[function(a,b,c){(function(c){function d(){return"undefined"==typeof document||null==document.location?"":document.location.href}function e(){return"undefined"==typeof document||null==document.location?"":document.location.origin?document.location.origin:document.location.protocol+"//"+document.location.hostname+(document.location.port?":"+document.location.port:"")}var f=a(5),g={collectWindowErrors:!0,debug:!1},h="undefined"!=typeof window?window:"undefined"!=typeof c?c:"undefined"!=typeof self?self:{},i=[].slice,j="?",k=/^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/;g.report=function(){function a(a){m(),s.push(a)}function b(a){for(var b=s.length-1;b>=0;--b)s[b]===a&&s.splice(b,1)}function c(){n(),s=[]}function e(a,b){var c=null;if(!b||g.collectWindowErrors){for(var d in s)if(s.hasOwnProperty(d))try{s[d].apply(null,[a].concat(i.call(arguments,2)))}catch(e){c=e}if(c)throw c}}function l(a,b,c,h,i){var l=null,m=f.isErrorEvent(i)?i.error:i,n=f.isErrorEvent(a)?a.message:a;if(v)g.computeStackTrace.augmentStackTraceWithInitialElement(v,b,c,n),o();else if(m&&f.isError(m))l=g.computeStackTrace(m),e(l,!0);else{var p,r={url:b,line:c,column:h},s=void 0;if("[object String]"==={}.toString.call(n)){var p=n.match(k);p&&(s=p[1],n=p[2])}r.func=j,l={name:s,message:n,url:d(),stack:[r]},e(l,!0)}return!!q&&q.apply(this,arguments)}function m(){r||(q=h.onerror,h.onerror=l,r=!0)}function n(){r&&(h.onerror=q,r=!1,q=void 0)}function o(){var a=v,b=t;t=null,v=null,u=null,e.apply(null,[a,!1].concat(b))}function p(a,b){var c=i.call(arguments,1);if(v){if(u===a)return;o()}var d=g.computeStackTrace(a);if(v=d,u=a,t=c,setTimeout(function(){u===a&&o()},d.incomplete?2e3:0),b!==!1)throw a}var q,r,s=[],t=null,u=null,v=null;return p.subscribe=a,p.unsubscribe=b,p.uninstall=c,p}(),g.computeStackTrace=function(){function a(a){if("undefined"!=typeof a.stack&&a.stack){for(var b,c,f,g=/^\s*at (?:(.*?) ?\()?((?:file|https?|blob|chrome-extension|native|eval|webpack||[a-z]:|\/).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i,h=/^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx(?:-web)|https?|webpack|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i,i=/^\s*(.*?)(?:\((.*?)\))?(?:^|@)((?:file|https?|blob|chrome|webpack|resource|moz-extension).*?:\/.*?|\[native code\]|[^@]*bundle)(?::(\d+))?(?::(\d+))?\s*$/i,k=/(\S+) line (\d+)(?: > eval line \d+)* > eval/i,l=/\((\S*)(?::(\d+))(?::(\d+))\)/,m=a.stack.split("\n"),n=[],o=(/^(.*) is undefined$/.exec(a.message),0),p=m.length;o eval")>-1;r&&(b=k.exec(c[3]))?(c[3]=b[1],c[4]=b[2],c[5]=null):0!==o||c[5]||"undefined"==typeof a.columnNumber||(n[0].column=a.columnNumber+1),f={url:c[3],func:c[1]||j,args:c[2]?c[2].split(","):[],line:c[4]?+c[4]:null,column:c[5]?+c[5]:null}}if(!f.func&&f.line&&(f.func=j),f.url&&"blob:"===f.url.substr(0,5)){var s=new XMLHttpRequest;if(s.open("GET",f.url,!1),s.send(null),200===s.status){var t=s.responseText||"";t=t.slice(-300);var u=t.match(/\/\/# sourceMappingURL=(.*)$/);if(u){var v=u[1];"~"===v.charAt(0)&&(v=e()+v.slice(1)),f.url=v.slice(0,-4)}}}n.push(f)}return n.length?{name:a.name,message:a.message,url:d(),stack:n}:null}}function b(a,b,c,d){var e={url:b,line:c};if(e.url&&e.line){if(a.incomplete=!1,e.func||(e.func=j),a.stack.length>0&&a.stack[0].url===e.url){if(a.stack[0].line===e.line)return!1;if(!a.stack[0].line&&a.stack[0].func===e.func)return a.stack[0].line=e.line, !1}return a.stack.unshift(e),a.partial=!0,!0}return a.incomplete=!0,!1}function c(a,e){for(var h,i,k=/function\s+([_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*)?\s*\(/i,l=[],m={},n=!1,o=c.caller;o&&!n;o=o.caller)if(o!==f&&o!==g.report){if(i={url:null,func:j,line:null,column:null},o.name?i.func=o.name:(h=k.exec(o.toString()))&&(i.func=h[1]),"undefined"==typeof i.func)try{i.func=h.input.substring(0,h.input.indexOf("{"))}catch(p){}m[""+o]?n=!0:m[""+o]=!0,l.push(i)}e&&l.splice(0,e);var q={name:a.name,message:a.message,url:d(),stack:l};return b(q,a.sourceURL||a.fileName,a.line||a.lineNumber,a.message||a.description),q}function f(b,e){var f=null;e=null==e?0:+e;try{if(f=a(b))return f}catch(h){if(g.debug)throw h}try{if(f=c(b,e+1))return f}catch(h){if(g.debug)throw h}return{name:b.name,message:b.message,url:d()}}return f.augmentStackTraceWithInitialElement=b,f.computeStackTraceFromStackProp=a,f}(),b.exports=g}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{5:5}],7:[function(a,b,c){function d(a,b){for(var c=0;c0){var i=d(c,this);~i?c.splice(i+1):c.push(this),~i?e.splice(i,1/0,g):e.push(g),~d(c,h)&&(h=b.call(this,g,h))}else c.push(h);return null==a?h instanceof Error?f(h):h:a.call(this,g,h)}}c=b.exports=e,c.getSerialize=g},{}],8:[function(a,b,c){function d(a,b){var c=(65535&a)+(65535&b),d=(a>>16)+(b>>16)+(c>>16);return d<<16|65535&c}function e(a,b){return a<>>32-b}function f(a,b,c,f,g,h){return d(e(d(d(b,a),d(f,h)),g),c)}function g(a,b,c,d,e,g,h){return f(b&c|~b&d,a,b,e,g,h)}function h(a,b,c,d,e,g,h){return f(b&d|c&~d,a,b,e,g,h)}function i(a,b,c,d,e,g,h){return f(b^c^d,a,b,e,g,h)}function j(a,b,c,d,e,g,h){return f(c^(b|~d),a,b,e,g,h)}function k(a,b){a[b>>5]|=128<>>9<<4)+14]=b;var c,e,f,k,l,m=1732584193,n=-271733879,o=-1732584194,p=271733878;for(c=0;c>5]>>>b%32&255);return c}function m(a){var b,c=[];for(c[(a.length>>2)-1]=void 0,b=0;b>5]|=(255&a.charCodeAt(b/8))<16&&(e=k(e,8*a.length)),c=0;c<16;c+=1)f[c]=909522486^e[c],g[c]=1549556828^e[c];return d=k(f.concat(m(b)),512+8*b.length),l(k(g.concat(d),640))}function p(a){var b,c,d="0123456789abcdef",e="";for(c=0;c>>4&15)+d.charAt(15&b);return e}function q(a){return unescape(encodeURIComponent(a))}function r(a){return n(q(a))}function s(a){return p(r(a))}function t(a,b){return o(q(a),q(b))}function u(a,b){return p(t(a,b))}function v(a,b,c){return b?c?t(b,a):u(b,a):c?r(a):s(a)}b.exports=v},{}]},{},[4])(4)}); //# sourceMappingURL=raven.min.js.map \ No newline at end of file diff --git a/Subscriber/ErrorHandler.php b/Subscriber/ErrorHandler.php new file mode 100644 index 0000000..2b969f1 --- /dev/null +++ b/Subscriber/ErrorHandler.php @@ -0,0 +1,234 @@ + + * All rights reserved + ***************************************************************/ +namespace OdSentry\Subscriber; + +use Enlight\Event\SubscriberInterface; +use Enlight_Event_EventArgs; +use OdSentry\OdSentry; +use Sentry\State\Hub; +use Sentry\State\Scope; +use Shopware\Components\DependencyInjection\Container; +use Symfony\Component\DependencyInjection\ContainerInterface; +use function Sentry\captureException; +use function Sentry\configureScope; +use function Sentry\init as initSentry; +use Throwable; + +class ErrorHandler implements SubscriberInterface +{ + /** + * @var bool + */ + private $sentryEnabled = false; + /** + * @var string + */ + private $pluginDirectory; + /** + * @var Container + */ + private $container; + + /** + * ErrorHandler constructor. + * + * @param ContainerInterface $container + */ + public function __construct(ContainerInterface $container) + { + $this->pluginDirectory = $container->getParameter('od_sentry.plugin_dir'); + // Use composer autoloader if dependencies are bundles within the plugin (non-composer mode) + if (file_exists($this->pluginDirectory . '/vendor/autoload.php')) { + require_once $this->pluginDirectory . '/vendor/autoload.php'; + } + $this->container = $container; + } + + /** + * @inheritDoc + */ + public static function getSubscribedEvents() + { + return [ + 'Enlight_Controller_Front_StartDispatch' => 'onStartDispatch', + 'Enlight_Controller_Action_PreDispatch_Frontend_Error' => 'onPreDispatchError', + 'Enlight_Controller_Action_PreDispatch_Backend_Error' => 'onPreDispatchBackendError', + 'Enlight_Controller_Front_DispatchLoopShutdown' => 'onDispatchLoopShutdown', + 'Shopware_Console_Add_Command' => 'onStartDispatch', + ]; + } + + /** + * Initialize Sentry error handling + */ + private function initSentry() + { + $publicDsn = $this->container->get('config')->getByNamespace(OdSentry::PLUGIN_NAME, 'sentryPublicDsn'); + initSentry(['dsn' => $publicDsn]); + $options = Hub::getCurrent()->getClient()->getOptions(); + $options->setEnvironment($this->container->getParameter('kernel.environment')); + if ($this->container->has('shopware.release')) { + $options->setRelease( + sprintf( + '%s-%s', + $this->container->get('shopware.release')->getVersion(), + $this->container->get('shopware.release')->getRevision() + ) + ); + } else { + $options->setRelease(sprintf('%s-%s@%s', getenv('SHOPWARE_VERSION'), getenv('SHOPWARE_REVISION'), getenv('SHOPWARE_VERSION_TEXT'))); + } + // Restore Shopware default error handler + restore_error_handler(); + restore_exception_handler(); + } + + /** + * @param Throwable $exception + * @return bool + */ + private function shouldExceptionCaptureBeSkipped(Throwable $exception) + { + $sentryConfig = $this->container->getParameter('shopware.sentry'); + foreach ($sentryConfig['skip_capture'] as $className) { + if ($exception instanceof $className) { + return true; + } + } + return false; + } + + /** + * @param Throwable $exception + * @return bool + */ + private function captureException(Throwable $exception) + { + if ($this->shouldExceptionCaptureBeSkipped($exception)) { + return false; + } + $serviceContainer = $this->container; + configureScope(function (Scope $scope) use ($serviceContainer) { + $scope->setTag('php_version', phpversion()); + // Frontend request + if ($serviceContainer->initialized('front')) { + /** @var \Enlight_Controller_Request_Request $request */ + $request = $serviceContainer->get('front')->Request(); + $scope->setTag('module', $request->getModuleName()); + $scope->setTag('controller', $request->getControllerName()); + $scope->setTag('action', $request->getActionName()); + } + // Frontend user is logged in + if ($serviceContainer->initialized('session')) { + $userId = $serviceContainer->get('session')->get('sUserId'); + if (!empty($userId)) { + $userData = $serviceContainer->get('modules')->Admin()->sGetUserData(); + $scope->setUser([ + 'id' => $userId, + 'email' => $userData['additional']['user']['email'], + ]); + $scope->setExtra('userData', $userData); + } + } + // Check for backend request + try { + $auth = $serviceContainer->get('Auth'); + // Workaround due to interface violation of \Zend_Auth_Adapter_Interface + if (method_exists($auth->getBaseAdapter(), 'refresh')) { + $auth = $serviceContainer->get('plugin_manager')->Backend()->Auth()->checkAuth(); + } + if ($auth) { + $backendUser = $auth->getIdentity(); + $scope->setUser([ + 'id' => $backendUser->id, + 'username' => $backendUser->username, + 'email' => $backendUser->email, + ]); + } + } catch (\Exception $e) { + } + }); + captureException($exception); + } + + /** + * Use the autoloader from the Raven library to load all necessary classes + */ + public function onStartDispatch() + { + if ($this->container->get('config')->getByNamespace(OdSentry::PLUGIN_NAME, 'sentryLogPhp')) { + $this->sentryEnabled = true; + $this->initSentry(); + } + } + + /** + * @param Enlight_Event_EventArgs $args + * + * @return void + */ + public function onPreDispatchBackendError(Enlight_Event_EventArgs $args) + { + if (!$this->sentryEnabled) { + return; + } + /** @var \Shopware_Controllers_Backend_Error $subject */ + $subject = $args->getSubject(); + $error = $subject->Request()->getParam('error_handler'); + if ($error && $error->exception) { + $this->captureException($error->exception); + } + } + + /** + * @param Enlight_Event_EventArgs $args + * + * @return void + */ + public function onPreDispatchError(Enlight_Event_EventArgs $args) + { + if (!$this->sentryEnabled) { + return; + } + /** @var \Shopware_Controllers_Frontend_Error $subject */ + $subject = $args->getSubject(); + $error = $subject->Request()->getParam('error_handler'); + if (!($error && $error->exception)) { + return; + } + $id = $this->captureException($error->exception); + if (!$this->container->get('config')->getByNamespace(OdSentry::PLUGIN_NAME, 'sentryUserfeedback')) { + return; + } + $templateManager = $this->container->get('template'); + $templateManager->assignGlobal('sentryId', $id); + $templateManager->addTemplateDir($this->pluginDirectory . '/Resources/views/'); + } + + /** + * Like the \Shopware_Plugins_Core_ErrorHandler_Bootstrap we want to catch all errors + * that occured during a request and send them to Sentry + * + * @param \Enlight_Controller_EventArgs $args + */ + public function onDispatchLoopShutdown(\Enlight_Controller_EventArgs $args) + { + if (!$this->sentryEnabled) { + return; + } + $response = $args->getSubject()->Response(); + $exceptions = $response->getException(); + if (empty($exceptions)) { + return; + } + foreach ($exceptions as $exception) { + $this->captureException($exception); + } + } +} diff --git a/Subscriber/TemplateRegistration.php b/Subscriber/TemplateRegistration.php new file mode 100644 index 0000000..eead722 --- /dev/null +++ b/Subscriber/TemplateRegistration.php @@ -0,0 +1,131 @@ + + * All rights reserved + ***************************************************************/ +namespace OdSentry\Subscriber; + +use Doctrine\Common\Collections\ArrayCollection; +use Enlight\Event\SubscriberInterface; +use Enlight_Event_EventArgs; +use OdSentry\OdSentry; +use Shopware\Components\Theme\LessDefinition; + +class TemplateRegistration implements SubscriberInterface +{ + /** + * @var string + */ + private $pluginDirectory; + /** + * @var \Enlight_Template_Manager + */ + private $templateManager; + + /** + * TemplateRegistration constructor. + * + * @param \Enlight_Template_Manager $templateManager + * @param $pluginDirectory + */ + public function __construct(\Enlight_Template_Manager $templateManager, string $pluginDirectory) + { + $this->pluginDirectory = $pluginDirectory; + $this->templateManager = $templateManager; + } + + /** + * @inheritDoc + */ + public static function getSubscribedEvents() + { + return [ + 'Enlight_Controller_Action_PreDispatch' => 'onPreDispatch', + 'Enlight_Controller_Action_PostDispatchSecure_Frontend' => 'onPostDispatchFrontend', + 'Theme_Compiler_Collect_Plugin_Javascript' => 'addJsFiles', + 'Theme_Compiler_Collect_Plugin_Less' => 'addLessFiles', + 'Theme_Compiler_Collect_Javascript_Files_FilterResult' => 'sortJs', + ]; + } + + /** + * Include templates + */ + public function onPreDispatch() + { + $this->templateManager->addTemplateDir($this->pluginDirectory . '/Resources/views'); + } + + /** + * We add templates from our plugin to include raven-js initialization after the JS libs + * + * @param \Enlight_Event_EventArgs $args + */ + public function onPostDispatchFrontend(\Enlight_Event_EventArgs $args) + { + /** @var \Enlight_Controller_Action $controller */ + $controller = $args->get('subject'); + $controller->View()->addTemplateDir($this->pluginDirectory . '/Resources/views/'); + } + + /** + * Add the raven-js library to the compiled JS. + * It will we reordered by the sortJs function to be included + * before the bootstrapping of most JS to track these errors too. + * + * @return ArrayCollection + */ + public function addJsFiles() + { + $jsFiles = []; + $jsDir = $this->pluginDirectory . '/Resources/views/frontend/_public/src/js/'; + if (Shopware()->Config()->getByNamespace( + OdSentry::PLUGIN_NAME, + 'sentryLogJs' + ) || Shopware()->Config()->getByNamespace(OdSentry::PLUGIN_NAME, 'sentryUserfeedback')) { + $jsFiles[] = $jsDir . 'vendor/raven.min.js'; + } + return new ArrayCollection($jsFiles); + } + + /** + * @return ArrayCollection + */ + public function addLessFiles() + { + $less = new LessDefinition( + [], + [$this->pluginDirectory . '/Resources/views/frontend/_public/src/less/all.less'] + ); + + return new ArrayCollection([$less]); + } + + /** + * Sort the raven-js library to the front of the JS compilation pipeline + * so that it can track errors in the initialization of other JS libraries. + * + * @param Enlight_Event_EventArgs $args + * @return array + */ + public function sortJs(Enlight_Event_EventArgs $args) + { + $files = $args->getReturn(); + $fileIdx = -1; + foreach ($files as $idx => $file) { + if (strpos($file, 'raven.min.js') !== false && strpos($file, OdSentry::PLUGIN_NAME) !== false) { + $fileIdx = $idx; + break; + } + } + if ($fileIdx > -1) { + $tmp = array_splice($files, $fileIdx, 1); + // the 5th position is usually after the vendor libraries + array_splice($files, 5, 0, $tmp); + } + return $files; + } +} diff --git a/composer.json b/composer.json index 2862fc0..10a3029 100644 --- a/composer.json +++ b/composer.json @@ -1,10 +1,8 @@ { "name": "onedrop/shopware-sentry", - "license": "MIT", "type": "shopware-plugin", - "extra": { - "installer-name": "OdSentry" - }, + "description": "Sentry integration for Shopware", + "license": "MIT", "authors": [ { "name": "Hans Höchtl", @@ -16,8 +14,11 @@ } ], "require": { - "sentry/sentry": "^1.10", - "composer/installers": "~1.0" + "composer/installers": "~1.6", + "sentry/sdk": "^2.0" + }, + "extra": { + "installer-name": "OdSentry" }, "scripts": { "test": "phpunit -c tests/" diff --git a/composer.lock b/composer.lock index 31f6a05..75f5701 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,60 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "a93e7775d268b78aef9b40f49f6cef00", + "content-hash": "0089bbab33a81eeb7bada5b0f9cae3e4", "packages": [ + { + "name": "clue/stream-filter", + "version": "v1.4.1", + "source": { + "type": "git", + "url": "https://github.com/clue/php-stream-filter.git", + "reference": "5a58cc30a8bd6a4eb8f856adf61dd3e013f53f71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/clue/php-stream-filter/zipball/5a58cc30a8bd6a4eb8f856adf61dd3e013f53f71", + "reference": "5a58cc30a8bd6a4eb8f856adf61dd3e013f53f71", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "require-dev": { + "phpunit/phpunit": "^5.0 || ^4.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Clue\\StreamFilter\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@lueck.tv" + } + ], + "description": "A simple and modern approach to stream filtering in PHP", + "homepage": "https://github.com/clue/php-stream-filter", + "keywords": [ + "bucket brigade", + "callback", + "filter", + "php_user_filter", + "stream", + "stream_filter_append", + "stream_filter_register" + ], + "time": "2019-04-09T12:31:48+00:00" + }, { "name": "composer/installers", "version": "v1.6.0", @@ -127,68 +179,1258 @@ "time": "2018-08-27T06:10:37+00:00" }, { - "name": "sentry/sentry", - "version": "1.10.0", + "name": "guzzlehttp/psr7", + "version": "1.6.1", "source": { "type": "git", - "url": "https://github.com/getsentry/sentry-php.git", - "reference": "b2b8ffe1560b9fb0110b02993594a4b04a511959" + "url": "https://github.com/guzzle/psr7.git", + "reference": "239400de7a173fe9901b9ac7c06497751f00727a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/239400de7a173fe9901b9ac7c06497751f00727a", + "reference": "239400de7a173fe9901b9ac7c06497751f00727a", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0", + "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "ext-zlib": "*", + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8" + }, + "suggest": { + "zendframework/zend-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Schultze", + "homepage": "https://github.com/Tobion" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "time": "2019-07-01T23:21:34+00:00" + }, + { + "name": "http-interop/http-factory-guzzle", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/http-interop/http-factory-guzzle.git", + "reference": "34861658efb9899a6618cef03de46e2a52c80fc0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/http-interop/http-factory-guzzle/zipball/34861658efb9899a6618cef03de46e2a52c80fc0", + "reference": "34861658efb9899a6618cef03de46e2a52c80fc0", + "shasum": "" + }, + "require": { + "guzzlehttp/psr7": "^1.4.2", + "psr/http-factory": "^1.0" + }, + "provide": { + "psr/http-factory-implementation": "^1.0" + }, + "require-dev": { + "http-interop/http-factory-tests": "^0.5", + "phpunit/phpunit": "^6.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Http\\Factory\\Guzzle\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "An HTTP Factory using Guzzle PSR7", + "keywords": [ + "factory", + "http", + "psr-17", + "psr-7" + ], + "time": "2018-07-31T19:32:56+00:00" + }, + { + "name": "jean85/pretty-package-versions", + "version": "1.2", + "source": { + "type": "git", + "url": "https://github.com/Jean85/pretty-package-versions.git", + "reference": "75c7effcf3f77501d0e0caa75111aff4daa0dd48" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/75c7effcf3f77501d0e0caa75111aff4daa0dd48", + "reference": "75c7effcf3f77501d0e0caa75111aff4daa0dd48", + "shasum": "" + }, + "require": { + "ocramius/package-versions": "^1.2.0", + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Jean85\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alessandro Lai", + "email": "alessandro.lai85@gmail.com" + } + ], + "description": "A wrapper for ocramius/package-versions to get pretty versions strings", + "keywords": [ + "composer", + "package", + "release", + "versions" + ], + "time": "2018-06-13T13:22:40+00:00" + }, + { + "name": "ocramius/package-versions", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/Ocramius/PackageVersions.git", + "reference": "a4d4b60d0e60da2487bd21a2c6ac089f85570dbb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Ocramius/PackageVersions/zipball/a4d4b60d0e60da2487bd21a2c6ac089f85570dbb", + "reference": "a4d4b60d0e60da2487bd21a2c6ac089f85570dbb", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0.0", + "php": "^7.1.0" + }, + "require-dev": { + "composer/composer": "^1.6.3", + "doctrine/coding-standard": "^5.0.1", + "ext-zip": "*", + "infection/infection": "^0.7.1", + "phpunit/phpunit": "^7.0.0" + }, + "type": "composer-plugin", + "extra": { + "class": "PackageVersions\\Installer", + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "PackageVersions\\": "src/PackageVersions" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", + "time": "2019-02-21T12:16:21+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v9.99.99", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", + "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", + "shasum": "" + }, + "require": { + "php": "^7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "time": "2018-07-02T15:55:56+00:00" + }, + { + "name": "php-http/client-common", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/client-common.git", + "reference": "2b8aa3c4910afc21146a9c8f96adb266e869517a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/client-common/zipball/2b8aa3c4910afc21146a9c8f96adb266e869517a", + "reference": "2b8aa3c4910afc21146a9c8f96adb266e869517a", + "shasum": "" + }, + "require": { + "php": "^7.1", + "php-http/httplug": "^2.0", + "php-http/message": "^1.6", + "php-http/message-factory": "^1.0", + "symfony/options-resolver": " ^3.4.20 || ^4.0.15 || ^4.1.9 || ^4.2.1" + }, + "require-dev": { + "doctrine/instantiator": "^1.1", + "guzzlehttp/psr7": "^1.4", + "phpspec/phpspec": "^5.1", + "phpspec/prophecy": "^1.8", + "sebastian/comparator": "^3.0" + }, + "suggest": { + "ext-json": "To detect JSON responses with the ContentTypePlugin", + "ext-libxml": "To detect XML responses with the ContentTypePlugin", + "php-http/cache-plugin": "PSR-6 Cache plugin", + "php-http/logger-plugin": "PSR-3 Logger plugin", + "php-http/stopwatch-plugin": "Symfony Stopwatch plugin" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Client\\Common\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Common HTTP Client implementations and tools for HTTPlug", + "homepage": "http://httplug.io", + "keywords": [ + "client", + "common", + "http", + "httplug" + ], + "time": "2019-02-03T16:49:09+00:00" + }, + { + "name": "php-http/curl-client", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/curl-client.git", + "reference": "e7a2a5ebcce1ff7d75eaf02b7c85634a6fac00da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/getsentry/sentry-php/zipball/b2b8ffe1560b9fb0110b02993594a4b04a511959", - "reference": "b2b8ffe1560b9fb0110b02993594a4b04a511959", + "url": "https://api.github.com/repos/php-http/curl-client/zipball/e7a2a5ebcce1ff7d75eaf02b7c85634a6fac00da", + "reference": "e7a2a5ebcce1ff7d75eaf02b7c85634a6fac00da", "shasum": "" }, "require": { "ext-curl": "*", - "php": "^5.3|^7.0" + "php": "^7.1", + "php-http/discovery": "^1.6", + "php-http/httplug": "^2.0", + "php-http/message": "^1.2", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0", + "symfony/options-resolver": "^3.4 || ^4.0" + }, + "provide": { + "php-http/async-client-implementation": "1.0", + "php-http/client-implementation": "1.0" + }, + "require-dev": { + "guzzlehttp/psr7": "^1.0", + "php-http/client-integration-tests": "^2.0", + "phpunit/phpunit": "^7.5", + "zendframework/zend-diactoros": "^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Client\\Curl\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Михаил Красильников", + "email": "m.krasilnikov@yandex.ru" + } + ], + "description": "PSR-18 and HTTPlug Async client with cURL", + "homepage": "http://php-http.org", + "keywords": [ + "curl", + "http", + "psr-18" + ], + "time": "2019-03-05T19:59:23+00:00" + }, + { + "name": "php-http/discovery", + "version": "1.7.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/discovery.git", + "reference": "e822f86a6983790aa17ab13aa7e69631e86806b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/discovery/zipball/e822f86a6983790aa17ab13aa7e69631e86806b6", + "reference": "e822f86a6983790aa17ab13aa7e69631e86806b6", + "shasum": "" + }, + "require": { + "php": "^7.1" }, "conflict": { - "raven/raven": "*" + "nyholm/psr7": "<1.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^1.8.0", - "monolog/monolog": "*", - "phpunit/phpunit": "^4.8.35 || ^5.7" + "akeneo/phpspec-skip-example-extension": "^4.0", + "php-http/httplug": "^1.0 || ^2.0", + "php-http/message-factory": "^1.0", + "phpspec/phpspec": "^5.1", + "puli/composer-plugin": "1.0.0-beta10" }, "suggest": { - "ext-hash": "*", - "ext-json": "*", - "ext-mbstring": "*", - "monolog/monolog": "Automatically capture Monolog events as breadcrumbs" + "php-http/message": "Allow to use Guzzle, Diactoros or Slim Framework factories", + "puli/composer-plugin": "Sets up Puli which is recommended for Discovery to work. Check http://docs.php-http.org/en/latest/discovery.html for more details." }, - "bin": [ - "bin/sentry" - ], "type": "library", "extra": { "branch-alias": { - "dev-master": "1.10.x-dev" + "dev-master": "1.7-dev" } }, "autoload": { - "psr-0": { - "Raven_": "lib/" + "psr-4": { + "Http\\Discovery\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "David Cramer", - "email": "dcramer@gmail.com" + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" } ], - "description": "A PHP client for Sentry (http://getsentry.com)", - "homepage": "http://getsentry.com", + "description": "Finds installed HTTPlug implementations and PSR-7 message factories", + "homepage": "http://php-http.org", "keywords": [ - "log", - "logging" + "adapter", + "client", + "discovery", + "factory", + "http", + "message", + "psr7" + ], + "time": "2019-06-30T09:04:27+00:00" + }, + { + "name": "php-http/httplug", + "version": "v2.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/httplug.git", + "reference": "b3842537338c949f2469557ef4ad4bdc47b58603" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/httplug/zipball/b3842537338c949f2469557ef4ad4bdc47b58603", + "reference": "b3842537338c949f2469557ef4ad4bdc47b58603", + "shasum": "" + }, + "require": { + "php": "^7.0", + "php-http/promise": "^1.0", + "psr/http-client": "^1.0", + "psr/http-message": "^1.0" + }, + "require-dev": { + "henrikbjorn/phpspec-code-coverage": "^1.0", + "phpspec/phpspec": "^2.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eric GELOEN", + "email": "geloen.eric@gmail.com" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "HTTPlug, the HTTP client abstraction for PHP", + "homepage": "http://httplug.io", + "keywords": [ + "client", + "http" + ], + "time": "2018-10-31T09:14:44+00:00" + }, + { + "name": "php-http/message", + "version": "1.7.2", + "source": { + "type": "git", + "url": "https://github.com/php-http/message.git", + "reference": "b159ffe570dffd335e22ef0b91a946eacb182fa1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/message/zipball/b159ffe570dffd335e22ef0b91a946eacb182fa1", + "reference": "b159ffe570dffd335e22ef0b91a946eacb182fa1", + "shasum": "" + }, + "require": { + "clue/stream-filter": "^1.4", + "php": "^5.4 || ^7.0", + "php-http/message-factory": "^1.0.2", + "psr/http-message": "^1.0" + }, + "provide": { + "php-http/message-factory-implementation": "1.0" + }, + "require-dev": { + "akeneo/phpspec-skip-example-extension": "^1.0", + "coduo/phpspec-data-provider-extension": "^1.0", + "ext-zlib": "*", + "guzzlehttp/psr7": "^1.0", + "henrikbjorn/phpspec-code-coverage": "^1.0", + "phpspec/phpspec": "^2.4", + "slim/slim": "^3.0", + "zendframework/zend-diactoros": "^1.0" + }, + "suggest": { + "ext-zlib": "Used with compressor/decompressor streams", + "guzzlehttp/psr7": "Used with Guzzle PSR-7 Factories", + "slim/slim": "Used with Slim Framework PSR-7 implementation", + "zendframework/zend-diactoros": "Used with Diactoros Factories" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Message\\": "src/" + }, + "files": [ + "src/filters.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "HTTP Message related tools", + "homepage": "http://php-http.org", + "keywords": [ + "http", + "message", + "psr-7" + ], + "time": "2018-11-01T09:32:41+00:00" + }, + { + "name": "php-http/message-factory", + "version": "v1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-http/message-factory.git", + "reference": "a478cb11f66a6ac48d8954216cfed9aa06a501a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/message-factory/zipball/a478cb11f66a6ac48d8954216cfed9aa06a501a1", + "reference": "a478cb11f66a6ac48d8954216cfed9aa06a501a1", + "shasum": "" + }, + "require": { + "php": ">=5.4", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Factory interfaces for PSR-7 HTTP Message", + "homepage": "http://php-http.org", + "keywords": [ + "factory", + "http", + "message", + "stream", + "uri" + ], + "time": "2015-12-19T14:08:53+00:00" + }, + { + "name": "php-http/promise", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/promise.git", + "reference": "dc494cdc9d7160b9a09bd5573272195242ce7980" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/promise/zipball/dc494cdc9d7160b9a09bd5573272195242ce7980", + "reference": "dc494cdc9d7160b9a09bd5573272195242ce7980", + "shasum": "" + }, + "require-dev": { + "henrikbjorn/phpspec-code-coverage": "^1.0", + "phpspec/phpspec": "^2.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + }, + { + "name": "Joel Wurtz", + "email": "joel.wurtz@gmail.com" + } + ], + "description": "Promise used for asynchronous HTTP requests", + "homepage": "http://httplug.io", + "keywords": [ + "promise" + ], + "time": "2016-01-26T13:27:02+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "496a823ef742b632934724bf769560c2a5c7c44e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/496a823ef742b632934724bf769560c2a5c7c44e", + "reference": "496a823ef742b632934724bf769560c2a5c7c44e", + "shasum": "" + }, + "require": { + "php": "^7.0", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "time": "2018-10-30T23:29:13+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "shasum": "" + }, + "require": { + "php": ">=7.0.0", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "time": "2019-04-30T12:38:16+00:00" + }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2016-08-06T14:39:51+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "ramsey/uuid", + "version": "3.8.0", + "source": { + "type": "git", + "url": "https://github.com/ramsey/uuid.git", + "reference": "d09ea80159c1929d75b3f9c60504d613aeb4a1e3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/d09ea80159c1929d75b3f9c60504d613aeb4a1e3", + "reference": "d09ea80159c1929d75b3f9c60504d613aeb4a1e3", + "shasum": "" + }, + "require": { + "paragonie/random_compat": "^1.0|^2.0|9.99.99", + "php": "^5.4 || ^7.0", + "symfony/polyfill-ctype": "^1.8" + }, + "replace": { + "rhumsaa/uuid": "self.version" + }, + "require-dev": { + "codeception/aspect-mock": "^1.0 | ~2.0.0", + "doctrine/annotations": "~1.2.0", + "goaop/framework": "1.0.0-alpha.2 | ^1.0 | ~2.1.0", + "ircmaxell/random-lib": "^1.1", + "jakub-onderka/php-parallel-lint": "^0.9.0", + "mockery/mockery": "^0.9.9", + "moontoast/math": "^1.1", + "php-mock/php-mock-phpunit": "^0.3|^1.1", + "phpunit/phpunit": "^4.7|^5.0|^6.5", + "squizlabs/php_codesniffer": "^2.3" + }, + "suggest": { + "ext-ctype": "Provides support for PHP Ctype functions", + "ext-libsodium": "Provides the PECL libsodium extension for use with the SodiumRandomGenerator", + "ext-uuid": "Provides the PECL UUID extension for use with the PeclUuidTimeGenerator and PeclUuidRandomGenerator", + "ircmaxell/random-lib": "Provides RandomLib for use with the RandomLibAdapter", + "moontoast/math": "Provides support for converting UUID to 128-bit integer (in string form).", + "ramsey/uuid-console": "A console application for generating UUIDs with ramsey/uuid", + "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Ramsey\\Uuid\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marijn Huizendveld", + "email": "marijn.huizendveld@gmail.com" + }, + { + "name": "Thibaud Fabre", + "email": "thibaud@aztech.io" + }, + { + "name": "Ben Ramsey", + "email": "ben@benramsey.com", + "homepage": "https://benramsey.com" + } + ], + "description": "Formerly rhumsaa/uuid. A PHP 5.4+ library for generating RFC 4122 version 1, 3, 4, and 5 universally unique identifiers (UUID).", + "homepage": "https://github.com/ramsey/uuid", + "keywords": [ + "guid", + "identifier", + "uuid" + ], + "time": "2018-07-19T23:38:55+00:00" + }, + { + "name": "sentry/sdk", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/getsentry/sentry-php-sdk.git", + "reference": "91c36aec83e4c1c5801b64ef4927b78a5aa8ce7f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/getsentry/sentry-php-sdk/zipball/91c36aec83e4c1c5801b64ef4927b78a5aa8ce7f", + "reference": "91c36aec83e4c1c5801b64ef4927b78a5aa8ce7f", + "shasum": "" + }, + "require": { + "http-interop/http-factory-guzzle": "^1.0", + "php-http/curl-client": "^1.0|^2.0", + "sentry/sentry": "^2.0.1" + }, + "type": "metapackage", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sentry", + "email": "accounts@sentry.io" + } + ], + "description": "This is a metapackage shipping sentry/sentry with a recommended http client.", + "time": "2019-04-08T07:21:45+00:00" + }, + { + "name": "sentry/sentry", + "version": "2.1.1", + "source": { + "type": "git", + "url": "https://github.com/getsentry/sentry-php.git", + "reference": "8e27e6c5fcf6f01fc2e5235dd14cc0b2b347d793" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/getsentry/sentry-php/zipball/8e27e6c5fcf6f01fc2e5235dd14cc0b2b347d793", + "reference": "8e27e6c5fcf6f01fc2e5235dd14cc0b2b347d793", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-mbstring": "*", + "jean85/pretty-package-versions": "^1.2", + "php": "^7.1", + "php-http/async-client-implementation": "^1.0", + "php-http/client-common": "^1.5|^2.0", + "php-http/discovery": "^1.6.1", + "php-http/httplug": "^1.1|^2.0", + "php-http/message": "^1.5", + "psr/http-message-implementation": "^1.0", + "ramsey/uuid": "^3.3", + "symfony/options-resolver": "^2.7|^3.0|^4.0", + "zendframework/zend-diactoros": "^1.4|^2.0" + }, + "conflict": { + "php-http/client-common": "1.8.0", + "raven/raven": "*" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.13", + "monolog/monolog": "^1.3|^2.0", + "php-http/mock-client": "^1.0", + "phpstan/phpstan": "^0.10.3", + "phpstan/phpstan-phpunit": "^0.10", + "phpunit/phpunit": "^7.0", + "symfony/phpunit-bridge": "^4.1.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "files": [ + "src/Sdk.php" + ], + "psr-4": { + "Sentry\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sentry", + "email": "accounts@sentry.io" + } + ], + "description": "A PHP SDK for Sentry (http://sentry.io)", + "homepage": "http://sentry.io", + "keywords": [ + "crash-reporting", + "crash-reports", + "error-handler", + "error-monitoring", + "log", + "logging", + "sentry" + ], + "time": "2019-06-13T11:27:23+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v4.3.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "40762ead607c8f792ee4516881369ffa553fee6f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/40762ead607c8f792ee4516881369ffa553fee6f", + "reference": "40762ead607c8f792ee4516881369ffa553fee6f", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.3-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony OptionsResolver Component", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "time": "2019-06-13T11:01:17+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.11.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "82ebae02209c21113908c229e9883c419720738a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/82ebae02209c21113908c229e9883c419720738a", + "reference": "82ebae02209c21113908c229e9883c419720738a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.11-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + }, + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "time": "2019-02-06T07:57:58+00:00" + }, + { + "name": "zendframework/zend-diactoros", + "version": "2.1.3", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-diactoros.git", + "reference": "279723778c40164bcf984a2df12ff2c6ec5e61c1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/279723778c40164bcf984a2df12ff2c6ec5e61c1", + "reference": "279723778c40164bcf984a2df12ff2c6ec5e61c1", + "shasum": "" + }, + "require": { + "php": "^7.1", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "ext-dom": "*", + "ext-libxml": "*", + "http-interop/http-factory-tests": "^0.5.0", + "php-http/psr7-integration-tests": "dev-master", + "phpunit/phpunit": "^7.0.2", + "zendframework/zend-coding-standard": "~1.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1.x-dev", + "dev-develop": "2.2.x-dev", + "dev-release-1.8": "1.8.x-dev" + } + }, + "autoload": { + "files": [ + "src/functions/create_uploaded_file.php", + "src/functions/marshal_headers_from_sapi.php", + "src/functions/marshal_method_from_sapi.php", + "src/functions/marshal_protocol_version_from_sapi.php", + "src/functions/marshal_uri_from_sapi.php", + "src/functions/normalize_server.php", + "src/functions/normalize_uploaded_files.php", + "src/functions/parse_cookie_header.php" + ], + "psr-4": { + "Zend\\Diactoros\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "PSR HTTP Message implementations", + "keywords": [ + "http", + "psr", + "psr-7" ], - "time": "2018-08-18T19:41:03+00:00" + "time": "2019-07-10T16:13:25+00:00" } ], "packages-dev": [], diff --git a/plugin.png b/plugin.png index 4429f49..1b604c3 100644 Binary files a/plugin.png and b/plugin.png differ diff --git a/plugin.xml b/plugin.xml index a790bb8..c87a4c8 100644 --- a/plugin.xml +++ b/plugin.xml @@ -3,10 +3,10 @@ - 1.2.2 + 2.0.0 Onedrop GmbH & Co. KG (c) by Onedrop GmbH & Co. KG MIT https://1drop.de - +