diff --git a/.editorconfig b/.editorconfig
index a45bfa8c4b42..52065f8fe269 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -11,5 +11,5 @@ indent_style = space
indent_size = 4
trim_trailing_whitespace = true
-[{package.json,*.yml}]
+[{*.json,*.yml}]
indent_size = 2
diff --git a/.env.example b/.env.example
index c68962a3b059..0ed277fe8322 100644
--- a/.env.example
+++ b/.env.example
@@ -1,10 +1,13 @@
APP_ENV=production
APP_DEBUG=false
APP_URL=http://localhost
-APP_KEY=SomeRandomString
+APP_TIMEZONE=UTC
+APP_KEY=
+DEBUGBAR_ENABLED=false
DB_DRIVER=mysql
DB_HOST=localhost
+DB_UNIX_SOCKET=null
DB_DATABASE=cachet
DB_USERNAME=homestead
DB_PASSWORD=secret
@@ -17,10 +20,11 @@ QUEUE_DRIVER=sync
CACHET_BEACON=true
CACHET_EMOJI=false
+CACHET_AUTO_TWITTER=true
-MAIL_DRIVER=smtp
-MAIL_HOST=mailtrap.io
-MAIL_PORT=2525
+MAIL_DRIVER=log
+MAIL_HOST=null
+MAIL_PORT=null
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ADDRESS=null
@@ -32,3 +36,9 @@ REDIS_DATABASE=null
REDIS_PORT=null
GITHUB_TOKEN=null
+
+NEXMO_KEY=null
+NEXMO_SECRET=null
+NEXMO_SMS_FROM=Cachet
+
+TRUSTED_PROXIES=
diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md
new file mode 100644
index 000000000000..98caa82825ca
--- /dev/null
+++ b/.github/CODE_OF_CONDUCT.md
@@ -0,0 +1,46 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at james@alt-three.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
+
+[homepage]: http://contributor-covenant.org
+[version]: http://contributor-covenant.org/version/1/4/
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
new file mode 100644
index 000000000000..ccf9365d7aad
--- /dev/null
+++ b/.github/CONTRIBUTING.md
@@ -0,0 +1,94 @@
+# Contribution Guidelines
+
+## Thank you
+
+Firstly, thank you for taking an interest in Cachet and for reading this guide.
+
+## Creating issues
+
+We track feature requests and bug reports on the [issue tracker](https://github.com/cachethq/Cachet/issues). Please send support requests to our support email; [support@alt-three.com](mailto:support@alt-three.com?subject=Cachet%20Support).
+
+**Always be respectful.** Organisation members reserve the right to lock topics if they feel necessary.
+
+## Languages
+
+This project accepts **English translations** only. Translations will be updated automatically through the [CrowdIn](https://translate.cachethq.io) integration.
+
+Please submit alternative translations to the [Cachet CrowdIn](https://translate.cachethq.io) project. CrowdIn will automatically send a Pull Request with your updates in.
+
+## Coding Standards
+
+Please try to follow existing coding standards. [StyleCI](https://styleci.io) will analyse and fix any discrepancies in coding standards.
+
+## Introduction into Git and GitHub
+
+If you are new to Git, GitHub and the whole open source software community, welcome! Here are some resources for getting started and understanding what it's all about.
+
+- [Try Git](https://try.github.io/levels/1/challenges/1) by Code School
+- [GitHub Help](https://help.github.com)
+
+If you're not fond of the command line, you can get one of GitHub's free GUI desktop apps:
+
+- [GitHub for Mac](https://github.com/blog/1510-installing-git-from-github-for-mac)
+- [GitHub for Windows](https://github.com/blog/1127-github-for-windows)
+
+If you're feeling adventurous, you can become a Git & GitHub master with the [Git Path on Code School](https://www.codeschool.com/paths/git).
+
+## .editorconfig
+
+You should also make use of the [.editorconfig](/.editorconfig) file found within the root of the repository. It'll make sure that your editor is setup with the same file settings.
+
+## Ways to help:
+
+Start by becoming familiar with Cachet. If you're already using Cachet, that's a great head start. If not, check out the latest [demo](https://dev.cachethq.io) and have a play. You can also download and install Cachet locally to familiarise yourself that way.
+
+You don't have to be a developer to help improve Cachet, infact there are lots of ways that you can help us.
+
+### Spread the word
+
+There are a lot of people who don't know about Cachet or what a status page is and how important it can be. [Tweet about Cachet](https://twitter.com/CachetHQ). Write blog posts about your success (or failures, we're not perfect) with Cachet and share what you took away from it.
+
+### Help with Documentation
+
+Cachet is in use around the world. Cachet speaks multiple languages. Our documentation doesn't and can be hard to understand for non-English speaking people. Documentation should be easy to understand and we need your help to make this possible. Check out [CachetHQ/Docs](https://github.com/CachetHQ/Docs) to contribute to our documentation.
+
+### As a non-developer/non-designer
+
+We're always looking for new [translations](#translations).
+
+Of course bug reports, feature requests and [documentation](https://docs.cachethq.io) are always appreciated.
+
+### As a designer
+
+As Cachet gains new features, the design and ideas that were once a perfect fit need updating and in some cases designing from scratch. This is where you come in! Fancy giving Cachet a lick of paint? Sweet!
+
+You'll need to install Node.js with NPM or Yarn.
+
+To get started you can do the following:
+
+1. Install Node.js and our dev dependencies.
+2. Run `npm run dev`
+3. Make your changes to the SCSS files in `./resources/assets/sass/`
+
+If you're making a lot of changes, you'll find that running `npm run watch` will make life easier for you!
+
+When you're happy with your changes, please run `npm run prod` to minify the assets.
+
+### As a developer
+
+Built using [Laravel](https://laravel.com).
+
+We use these extra dependencies to develop Cachet:
+
+- Node.js
+- NPM or Yarn
+- Composer
+- Git
+
+Once cloned to your local machine, you'll need some demo data! Run `php artisan cachet:seed` to get the demo installation ready for action.
+
+### #YOLO JUST SUBMIT A PR
+
+_A great idea taken from https://github.com/metabase/metabase/blob/master/docs/contributing.md#yolo-just-submit-a-pr._
+
+> If you come up with something really cool, and want to share it with us, just submit a PR. If it hasn't gone through the above process, we probably won't merge it as is, but if it's compelling, we're more than willing to help you via code review, design review and generally OCD nitpicking so that it fits into the rest of our codebase.
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 000000000000..cb0cea613ced
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,5 @@
+# These are supported funding model platforms
+
+github:
+ - jbrooksuk
+ - cachethq
diff --git a/.gitignore b/.gitignore
index 51669198babc..96cbe1660fda 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,12 @@
+/node_modules
+/public/hot
+/public/storage
+/storage/*.key
+/vendor
+/.idea
+/.vagrant
+Homestead.json
+Homestead.yaml
+npm-debug.log
.env
-node_modules
-phpunit.xml
-vendor
+package-lock.json
diff --git a/.travis.yml b/.travis.yml
index f1491a3ce403..8d0b77fd6958 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,18 +1,38 @@
language: php
-
-php:
- - 5.5.9
- - 5.5
- - 5.6
- - 7.0
- - 7.1
-
+dist: trusty
sudo: false
+branches:
+ except:
+ - l10n_2.3
+ - l10n_2.4
+
before_install:
- cp .env.example .env
- - if [[ $TRAVIS_PHP_VERSION != 7.1 ]] ; then phpenv config-rm xdebug.ini; fi
-install: travis_retry composer install --no-interaction --no-scripts --prefer-source --no-suggest
+install:
+ - travis_retry composer install --no-interaction --no-suggest
-script: vendor/bin/phpunit
+jobs:
+ include:
+# - stage: Security check
+# script:
+# - phpenv config-rm xdebug.ini || true
+# - wget https://get.sensiolabs.org/security-checker.phar
+# - php security-checker.phar security:check ./composer.lock
+# php: 7.1
+ - stage: Unit tests
+ script:
+ - phpenv config-rm xdebug.ini || true
+ - vendor/bin/phpunit
+ php: 7.1
+ - stage: Unit tests
+ script:
+ - phpenv config-rm xdebug.ini || true
+ - vendor/bin/phpunit
+ php: 7.2
+ - stage: Unit tests
+ script:
+ - phpenv config-rm xdebug.ini || true
+ - vendor/bin/phpunit
+ php: 7.3
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
deleted file mode 100644
index 452151f214e9..000000000000
--- a/CONTRIBUTING.md
+++ /dev/null
@@ -1,76 +0,0 @@
-# Contribution Guidelines
-
-## Creating issues
-
-Feature requests and bug reports should be made by using the [issue tracker](https://github.com/cachethq/Cachet/issues). Support questions should be directed to our support email; [support@alt-three.com](mailto:support@alt-three.com?subject=Cachet Support).
-
-**Always be respectful.** Organization members reserve the right to lock topics if they feel necessary.
-
-## Languages
-
-Any non-English translations must be made on the [Cachet CrowdIn](https://translate.cachethq.io) project. This makes syncing translations much easier.
-
-## Coding Standards
-
-Please follow existing coding standards:
-
-```php
-
+
+
+
+
+
-[](https://styleci.io/repos/26730195/)
-[](https://travis-ci.org/CachetHQ/Cachet)
-[](LICENSE)
-[](http://translate.cachethq.io/project/cachet)
-[](https://github.com/CachetHQ/Cachet/releases)
+Cachet, the open-source status page system.
-
+## Cachet 3.x Announcement
-Cachet is a beautiful and powerful open source status page system.
+We are shifting our attention and resources to Cachet 3.x and will no longer be supporting the 2.x version.
+
+For more information on the Cachet rebuild and our plans for 3.x, you can read the announcement [here](https://github.com/CachetHQ/Cachet/discussions/4342).
## Features
-- List your services components
-- Log incidents
-- Apply custom CSS to the status page
+- List your service components
+- Report incidents
+- Customise the look of your status page
- Markdown support for incident messages
-- JSON API
-- Translated into eleven languages
+- A powerful JSON API
- Metrics
-- Cross-database support: MySQL, PostgreSQL and SQLite
-- Subscriber notifications via Email
-- Two factor authentication using Google Authenticator
+- Multi-lingual
+- Subscriber notifications via email
+- Two factor authentication
## Requirements
-- PHP 5.5.9+ or newer
-- HTTP server with PHP support (eg: Apache, Nginx, Caddy)
+- PHP 7.1.3 – 7.3
+- HTTP server with PHP support (e.g.: Apache, Nginx, Caddy)
- [Composer](https://getcomposer.org)
-
-## I'm looking to contribute to this awesome project!
-
-Sweet, we're always looking for contributions that improve Cachet! It's easy to get started and you don't even need to know how to write a single line of code!
-
-### Contributing as a non-developer/non-designer
-
-We're always looking for new [translations](#translations).
-
-Of course bug reports, feature requests and [documentation](https://docs.cachethq.io) are always appreciated.
-
-### Contributing as a designer
-
-As Cachet gains new features, the design and ideas that were once a perfect fit need updating and in some cases designing from scratch. This is where you come in! Fancy giving Cachet a lick of paint? Sweet!
-
-You'll need to install Node.js, Bower and Gulp.
-
-To get started you can do the following:
-
-1. Install Node.js and our dev dependencies.
-2. Make your changes to the SCSS files in `./resources/assets/sass/`
-3. Run `gulp`
-
-If you're making a lot of changes, you'll find that running `gulp watch` will make life easier for you!
-
-### Contributing as a developer
-
-Built using [Laravel](https://laravel.com).
-
-We use these extra dependencies to develop Cachet:
-
-- Node.js
-- Gulp
-- Git
-
-Once cloned to your local machine, you'll need some demo data! Run `php artisan cachet:seed` to get the demo installation ready for action.
+- A supported database: MariaDB, MySQL, PostgreSQL or SQLite
## Installation, Upgrades and Documentation
-Documentation is found at [https://docs.cachethq.io](https://docs.cachethq.io).
+You can find documentation at [https://docs.cachethq.io](https://docs.cachethq.io).
Here are some useful quick links:
-- [Installing Cachet](https://docs.cachethq.io/docs/installing-cachet)
-- [Getting started with Docker](https://docs.cachethq.io/docs/get-started-with-docker)
+- [Installing Cachet](https://docs.cachethq.io/installation/)
+- [Getting started with Docker](https://docs.cachethq.io/installation/docker)
-### Demo Account
+### Demo
-To test out the demo, you may login to the [Dashboard](https://demo.cachethq.io/dashboard) with the following:
+To test out the demo, you can log in to the [Cachet dashboard](https://demo.cachethq.io/dashboard) with the following credentials:
-- **Username:** `test` or `test@test.com`
+- **Username:** `test` or `test@example.com`
- **Password:** `test123`
-The demo is reset every half hour.
-
-## Translations
-
-If you'd like to contribute translations, please check out our [CrowdIn project](https://crowdin.com/project/cachet).
-
-> Thank you to our [translators](https://crowdin.com/project/cachet/activity_stream), who have allowed us to share Cachet with the world!
-
-## Show your support
-
-Cachet is a BSD-3-licensed open source project. If you'd like to support future development, check out the [Patreon campaign](https://patreon.com/jbrooksuk).
-
-## Professional Installation Service
-
-We offer a professional installation service. To find out more, email us at [support@alt-three.com](mailto:support@alt-three.com?Cachet Installation)
+> **Note**
+> The demo will automatically reset every 30 minutes.
## Security Vulnerabilities
-If you discover a security vulnerability within Cachet, please send an e-mail to us at support@alt-three.com. We handle all security vulnerabilities on a case-by-case basis.
+If you discover a security vulnerability within Cachet, please send an e-mail to [support@cachethq.io](mailto:support@cachethq.io?Cachet%20Security%20Vulnerability). All security vulnerabilities are reviewed on a case-by-case basis.
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 000000000000..5459a341d897
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,17 @@
+# Security Policy
+
+**PLEASE DON'T DISCLOSE SECURITY-RELATED ISSUES PUBLICLY, [SEE BELOW](#reporting-a-vulnerability).**
+
+## Supported Versions
+
+Use this section to tell people about which versions of your project are
+currently being supported with security updates.
+
+| Version | Supported |
+| ------- | ------------------ |
+| 2.4 | :white_check_mark: |
+| < 2.4 | :x: |
+
+## Reporting a Vulnerability
+
+If you discover a security vulnerability within Cachet, please email James Brooks at james@cachethq.io. All security vulnerabilities will be promptly addressed.
diff --git a/VERSION b/VERSION
index a724a9cd9094..005119baaa06 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.4.0-dev
+2.4.1
diff --git a/app/Bus/Commands/Component/AddComponentCommand.php b/app/Bus/Commands/Component/CreateComponentCommand.php
similarity index 57%
rename from app/Bus/Commands/Component/AddComponentCommand.php
rename to app/Bus/Commands/Component/CreateComponentCommand.php
index a50e725d79db..4244f42cbc61 100644
--- a/app/Bus/Commands/Component/AddComponentCommand.php
+++ b/app/Bus/Commands/Component/CreateComponentCommand.php
@@ -11,7 +11,12 @@
namespace CachetHQ\Cachet\Bus\Commands\Component;
-final class AddComponentCommand
+/**
+ * This is the create component command class.
+ *
+ * @author James Brooks
+ */
+final class CreateComponentCommand
{
/**
* The component name.
@@ -62,6 +67,20 @@ final class AddComponentCommand
*/
public $enabled;
+ /**
+ * JSON meta data for the component.
+ *
+ * @var array|null
+ */
+ public $meta;
+
+ /**
+ * Tags string.
+ *
+ * @var string
+ */
+ public $tags;
+
/**
* The validation rules.
*
@@ -69,28 +88,32 @@ final class AddComponentCommand
*/
public $rules = [
'name' => 'required|string',
- 'description' => 'string',
- 'status' => 'int|min:1|max:4',
- 'link' => 'url',
- 'order' => 'int',
- 'group_id' => 'int',
- 'enabled' => 'bool',
+ 'description' => 'nullable|string',
+ 'status' => 'required|int|min:0|max:4',
+ 'link' => 'nullable|url',
+ 'order' => 'nullable|int',
+ 'group_id' => 'nullable|int',
+ 'enabled' => 'nullable|bool',
+ 'meta' => 'nullable|array',
+ 'tags' => 'nullable|string',
];
/**
* Create a new add component command instance.
*
- * @param string $name
- * @param string $description
- * @param int $status
- * @param string $link
- * @param int $order
- * @param int $group_id
- * @param bool $enabled
+ * @param string $name
+ * @param string $description
+ * @param int $status
+ * @param string $link
+ * @param int $order
+ * @param int $group_id
+ * @param bool $enabled
+ * @param array|null $meta
+ * @param string|null $tags
*
* @return void
*/
- public function __construct($name, $description, $status, $link, $order, $group_id, $enabled)
+ public function __construct($name, $description, $status, $link, $order, $group_id, $enabled, $meta, $tags = null)
{
$this->name = $name;
$this->description = $description;
@@ -99,5 +122,7 @@ public function __construct($name, $description, $status, $link, $order, $group_
$this->order = $order;
$this->group_id = $group_id;
$this->enabled = $enabled;
+ $this->meta = $meta;
+ $this->tags = $tags;
}
}
diff --git a/app/Bus/Commands/Component/UpdateComponentCommand.php b/app/Bus/Commands/Component/UpdateComponentCommand.php
index 17c5d12c4897..9909339754c1 100644
--- a/app/Bus/Commands/Component/UpdateComponentCommand.php
+++ b/app/Bus/Commands/Component/UpdateComponentCommand.php
@@ -25,90 +25,120 @@ final class UpdateComponentCommand
/**
* The component name.
*
- * @var string
+ * @var string|null
*/
public $name;
/**
* The component description.
*
- * @var string
+ * @var string|null
*/
public $description;
/**
* The component status.
*
- * @var int
+ * @var int|null
*/
public $status;
/**
* The component link.
*
- * @var string
+ * @var string|null
*/
public $link;
/**
* The component order.
*
- * @var int
+ * @var int|null
*/
public $order;
/**
* The component group.
*
- * @var int
+ * @var int|null
*/
public $group_id;
/**
* Is the component enabled?
*
- * @var bool
+ * @var bool|null
*/
public $enabled;
+ /**
+ * JSON meta data for the component.
+ *
+ * @var array|null
+ */
+ public $meta;
+
+ /**
+ * The tags.
+ *
+ * @var string|null
+ */
+ public $tags;
+
+ /**
+ * If this is true, we won't notify subscribers of the change.
+ *
+ * @var bool
+ */
+ public $silent;
+
/**
* The validation rules.
*
* @var string[]
*/
public $rules = [
- 'name' => 'string',
- 'description' => 'string',
- 'status' => 'int|min:1|max:4',
- 'link' => 'url',
- 'order' => 'int',
- 'group_id' => 'int',
- 'enabled' => 'bool',
+ 'name' => 'nullable|string',
+ 'description' => 'nullable|string',
+ 'status' => 'nullable|int|min:0|max:4',
+ 'link' => 'nullable|url',
+ 'order' => 'nullable|int',
+ 'group_id' => 'nullable|int',
+ 'enabled' => 'nullable|bool',
+ 'meta' => 'nullable|array',
+ 'silent' => 'nullable|bool',
];
/**
* Create a new update component command instance.
*
* @param \CachetHQ\Cachet\Models\Component $component
- * @param string $name
- * @param string $description
- * @param int $status
- * @param string $link
- * @param int $order
- * @param int $group_id
- * @param bool $enabled
+ * @param string|null $name
+ * @param string|null $description
+ * @param int|null $status
+ * @param string|null $link
+ * @param int|null $order
+ * @param int|null $group_id
+ * @param bool|null $enabled
+ * @param array|null $meta
+ * @param string|null $tags
+ * @param bool $silent
*
* @return void
*/
- public function __construct(Component $component, $name, $description, $status, $link, $order, $group_id, $enabled)
+ public function __construct(Component $component, $name = null, $description = null, $status = null, $link = null, $order = null, $group_id = null, $enabled = null, $meta = null, $tags = null, $silent = null)
{
$this->component = $component;
$this->name = $name;
$this->description = $description;
- $this->status = (int) $status;
+ $this->status = $status;
$this->link = $link;
$this->order = $order;
$this->group_id = $group_id;
$this->enabled = $enabled;
+ $this->meta = $meta;
+ $this->tags = $tags;
+ $this->silent = $silent;
+ $this->tags = $tags;
}
}
diff --git a/app/Bus/Commands/ComponentGroup/AddComponentGroupCommand.php b/app/Bus/Commands/ComponentGroup/CreateComponentGroupCommand.php
similarity index 70%
rename from app/Bus/Commands/ComponentGroup/AddComponentGroupCommand.php
rename to app/Bus/Commands/ComponentGroup/CreateComponentGroupCommand.php
index e68f24fd09d8..7bec1b5d666c 100644
--- a/app/Bus/Commands/ComponentGroup/AddComponentGroupCommand.php
+++ b/app/Bus/Commands/ComponentGroup/CreateComponentGroupCommand.php
@@ -12,11 +12,11 @@
namespace CachetHQ\Cachet\Bus\Commands\ComponentGroup;
/**
- * This is the add component group command.
+ * This is the create component group command.
*
* @author James Brooks
*/
-final class AddComponentGroupCommand
+final class CreateComponentGroupCommand
{
/**
* The component group name.
@@ -39,6 +39,13 @@ final class AddComponentGroupCommand
*/
public $collapsed;
+ /**
+ * Is the component visible to public?
+ *
+ * @var int
+ */
+ public $visible;
+
/**
* The validation rules.
*
@@ -46,8 +53,9 @@ final class AddComponentGroupCommand
*/
public $rules = [
'name' => 'required|string',
- 'order' => 'int',
- 'collapsed' => 'int|between:0,3',
+ 'order' => 'required|int',
+ 'collapsed' => 'required|int|between:0,4',
+ 'visible' => 'required|bool',
];
/**
@@ -56,13 +64,15 @@ final class AddComponentGroupCommand
* @param string $name
* @param int $order
* @param int $collapsed
+ * @param int $visible
*
* @return void
*/
- public function __construct($name, $order, $collapsed)
+ public function __construct($name, $order, $collapsed, $visible)
{
$this->name = $name;
$this->order = (int) $order;
$this->collapsed = $collapsed;
+ $this->visible = (int) $visible;
}
}
diff --git a/app/Bus/Commands/ComponentGroup/UpdateComponentGroupCommand.php b/app/Bus/Commands/ComponentGroup/UpdateComponentGroupCommand.php
index a20c49448557..1067ef22fc0c 100644
--- a/app/Bus/Commands/ComponentGroup/UpdateComponentGroupCommand.php
+++ b/app/Bus/Commands/ComponentGroup/UpdateComponentGroupCommand.php
@@ -48,15 +48,23 @@ final class UpdateComponentGroupCommand
*/
public $collapsed;
+ /**
+ * Is the component visible to public?
+ *
+ * @var int
+ */
+ public $visible;
+
/**
* The validation rules.
*
* @var string[]
*/
public $rules = [
- 'name' => 'string',
- 'order' => 'int',
- 'collapsed' => 'int|between:0,3',
+ 'name' => 'nullable|string',
+ 'order' => 'nullable|int',
+ 'collapsed' => 'nullable|int|between:0,4',
+ 'visible' => 'nullable|bool',
];
/**
@@ -66,14 +74,16 @@ final class UpdateComponentGroupCommand
* @param string $name
* @param int $order
* @param int $collapsed
+ * @param int $visible
*
* @return void
*/
- public function __construct(ComponentGroup $group, $name, $order, $collapsed)
+ public function __construct(ComponentGroup $group, $name, $order, $collapsed, $visible)
{
$this->group = $group;
$this->name = $name;
$this->order = (int) $order;
$this->collapsed = $collapsed;
+ $this->visible = (int) $visible;
}
}
diff --git a/app/Bus/Commands/Incident/ReportIncidentCommand.php b/app/Bus/Commands/Incident/CreateIncidentCommand.php
similarity index 66%
rename from app/Bus/Commands/Incident/ReportIncidentCommand.php
rename to app/Bus/Commands/Incident/CreateIncidentCommand.php
index 67158bfc9aa1..4f94f2f890d6 100644
--- a/app/Bus/Commands/Incident/ReportIncidentCommand.php
+++ b/app/Bus/Commands/Incident/CreateIncidentCommand.php
@@ -11,7 +11,13 @@
namespace CachetHQ\Cachet\Bus\Commands\Incident;
-final class ReportIncidentCommand
+/**
+ * This is the create incident command.
+ *
+ * @author Joseph Cohen
+ * @author James Brooks
+ */
+final class CreateIncidentCommand
{
/**
* The incident name.
@@ -70,11 +76,11 @@ final class ReportIncidentCommand
public $stickied;
/**
- * The date at which the incident occurred.
+ * The date at which the incident occurred at.
*
* @var string|null
*/
- public $incident_date;
+ public $occurred_at;
/**
* A given incident template.
@@ -90,6 +96,13 @@ final class ReportIncidentCommand
*/
public $template_vars;
+ /**
+ * Meta key/value pairs.
+ *
+ * @var array
+ */
+ public $meta = [];
+
/**
* The validation rules.
*
@@ -98,18 +111,19 @@ final class ReportIncidentCommand
public $rules = [
'name' => 'required|string',
'status' => 'required|int|min:0|max:4',
- 'message' => 'string',
- 'visible' => 'bool',
- 'component_id' => 'int|required_with:component_status',
- 'component_status' => 'int|min:1|max:4|required_with:component_id',
- 'notify' => 'bool',
- 'stickied' => 'bool',
- 'incident_date' => 'string',
- 'template' => 'string',
+ 'message' => 'nullable|string',
+ 'visible' => 'nullable|bool',
+ 'component_id' => 'nullable|required_with:component_status|int',
+ 'component_status' => 'nullable|required_with:component_id|int|min:0|max:4',
+ 'notify' => 'nullable|bool',
+ 'stickied' => 'required|bool',
+ 'occurred_at' => 'nullable|string',
+ 'template' => 'nullable|string',
+ 'meta' => 'nullable|array',
];
/**
- * Create a new report incident command instance.
+ * Create a new create incident command instance.
*
* @param string $name
* @param int $status
@@ -119,13 +133,14 @@ final class ReportIncidentCommand
* @param int $component_status
* @param bool $notify
* @param bool $stickied
- * @param string|null $incident_date
+ * @param string|null $occurred_at
* @param string|null $template
- * @param array|null $template_vars
+ * @param array $template_vars
+ * @param array $meta
*
* @return void
*/
- public function __construct($name, $status, $message, $visible, $component_id, $component_status, $notify, $stickied, $incident_date, $template, array $template_vars = null)
+ public function __construct($name, $status, $message, $visible, $component_id, $component_status, $notify, $stickied, $occurred_at, $template, array $template_vars = [], array $meta = [])
{
$this->name = $name;
$this->status = $status;
@@ -135,8 +150,9 @@ public function __construct($name, $status, $message, $visible, $component_id, $
$this->component_status = $component_status;
$this->notify = $notify;
$this->stickied = $stickied;
- $this->incident_date = $incident_date;
+ $this->occurred_at = $occurred_at;
$this->template = $template;
$this->template_vars = $template_vars;
+ $this->meta = $meta;
}
}
diff --git a/app/Bus/Commands/Incident/ReportMaintenanceCommand.php b/app/Bus/Commands/Incident/ReportMaintenanceCommand.php
deleted file mode 100644
index 3b44aa106948..000000000000
--- a/app/Bus/Commands/Incident/ReportMaintenanceCommand.php
+++ /dev/null
@@ -1,73 +0,0 @@
- 'required|string',
- 'message' => 'string',
- 'notify' => 'bool',
- 'timestamp' => 'string',
- ];
-
- /**
- * Create a new report maintenance command instance.
- *
- * @param string $name
- * @param string $message
- * @param bool $notify
- * @param string $timestamp
- *
- * @return void
- */
- public function __construct($name, $message, $notify, $timestamp)
- {
- $this->name = $name;
- $this->message = $message;
- $this->notify = $notify;
- $this->timestamp = $timestamp;
- }
-}
diff --git a/app/Bus/Commands/Incident/UpdateIncidentCommand.php b/app/Bus/Commands/Incident/UpdateIncidentCommand.php
index 928e037a1e44..1328b37ca91a 100644
--- a/app/Bus/Commands/Incident/UpdateIncidentCommand.php
+++ b/app/Bus/Commands/Incident/UpdateIncidentCommand.php
@@ -13,6 +13,13 @@
use CachetHQ\Cachet\Models\Incident;
+/**
+ * This is the update incident command.
+ *
+ * @author James Brooks
+ * @author Joseph Cohem
+ * @author Graham Campbell
+ */
final class UpdateIncidentCommand
{
/**
@@ -79,11 +86,11 @@ final class UpdateIncidentCommand
public $stickied;
/**
- * The date that the incident occurred on.
+ * The timestamp that the incident occurred at.
*
- * @var string
+ * @var string|null
*/
- public $incident_date;
+ public $occurred_at;
/**
* A given incident template.
@@ -99,21 +106,30 @@ final class UpdateIncidentCommand
*/
public $template_vars;
+ /**
+ * Meta key/value pairs.
+ *
+ * @var array
+ */
+ public $meta = [];
+
/**
* The validation rules.
*
* @var string[]
*/
public $rules = [
- 'name' => 'string',
- 'status' => 'int|min:0|max:4',
- 'message' => 'string',
- 'visible' => 'bool',
- 'component_id' => 'int',
- 'component_status' => 'int|min:1|max:4|required_with:component_id',
- 'notify' => 'bool',
- 'stickied' => 'bool',
- 'template' => 'string',
+ 'name' => 'nullable|string',
+ 'status' => 'nullable|int|min:0|max:4',
+ 'message' => 'nullable|string',
+ 'visible' => 'nullable|bool',
+ 'component_id' => 'nullable|int',
+ 'component_status' => 'nullable|int|min:0|max:4|required_with:component_id',
+ 'notify' => 'nullable|bool',
+ 'stickied' => 'nullable|bool',
+ 'occurred_at' => 'nullable|string',
+ 'template' => 'nullable|string',
+ 'meta' => 'nullable|array',
];
/**
@@ -128,13 +144,14 @@ final class UpdateIncidentCommand
* @param int $component_status
* @param bool $notify
* @param bool $stickied
- * @param string|null $incident_date
+ * @param string|null $occurred_at
* @param string|null $template
- * @param array|null $template_vars
+ * @param array $template_vars
+ * @param array $meta
*
* @return void
*/
- public function __construct(Incident $incident, $name, $status, $message, $visible, $component_id, $component_status, $notify, $stickied, $incident_date, $template, array $template_vars = null)
+ public function __construct(Incident $incident, $name, $status, $message, $visible, $component_id, $component_status, $notify, $stickied, $occurred_at, $template, array $template_vars = [], array $meta = [])
{
$this->incident = $incident;
$this->name = $name;
@@ -145,8 +162,9 @@ public function __construct(Incident $incident, $name, $status, $message, $visib
$this->component_status = $component_status;
$this->notify = $notify;
$this->stickied = $stickied;
- $this->incident_date = $incident_date;
+ $this->occurred_at = $occurred_at;
$this->template = $template;
$this->template_vars = $template_vars;
+ $this->meta = $meta;
}
}
diff --git a/app/Bus/Commands/IncidentUpdate/CreateIncidentUpdateCommand.php b/app/Bus/Commands/IncidentUpdate/CreateIncidentUpdateCommand.php
new file mode 100644
index 000000000000..caa65a757975
--- /dev/null
+++ b/app/Bus/Commands/IncidentUpdate/CreateIncidentUpdateCommand.php
@@ -0,0 +1,97 @@
+
+ */
+final class CreateIncidentUpdateCommand
+{
+ /**
+ * The incident.
+ *
+ * @var \CachetHQ\Cachet\Models\Incident
+ */
+ public $incident;
+
+ /**
+ * The incident status.
+ *
+ * @var int
+ */
+ public $status;
+
+ /**
+ * The incident message.
+ *
+ * @var string
+ */
+ public $message;
+ /**
+ * The incident component.
+ *
+ * @var int
+ */
+ public $component_id;
+
+ /**
+ * The component status.
+ *
+ * @var int
+ */
+ public $component_status;
+ /**
+ * The user.
+ *
+ * @var \CachetHQ\Cachet\Models\User
+ */
+ public $user;
+
+ /**
+ * The validation rules.
+ *
+ * @var string[]
+ */
+ public $rules = [
+ 'incident' => 'required',
+ 'status' => 'required|int|min:1|max:4',
+ 'message' => 'required|string',
+ 'component_id' => 'nullable|required_with:component_status|int',
+ 'component_status' => 'nullable|required_with:component_id|int|min:0|max:4',
+ 'user' => 'required',
+ ];
+
+ /**
+ * Create a new report incident update command instance.
+ *
+ * @param \CachetHQ\Cachet\Models\Incident $incident
+ * @param string $status
+ * @param string $message
+ * @param \CachetHQ\Cachet\Models\User $user
+ *
+ * @return void
+ */
+ public function __construct(Incident $incident, $status, $message, $component_id, $component_status, User $user)
+ {
+ $this->incident = $incident;
+ $this->status = $status;
+ $this->message = $message;
+ $this->component_id = $component_id;
+ $this->component_status = $component_status;
+ $this->user = $user;
+ }
+}
diff --git a/app/Bus/Commands/IncidentUpdate/RemoveIncidentUpdateCommand.php b/app/Bus/Commands/IncidentUpdate/RemoveIncidentUpdateCommand.php
new file mode 100644
index 000000000000..7440e3529dd1
--- /dev/null
+++ b/app/Bus/Commands/IncidentUpdate/RemoveIncidentUpdateCommand.php
@@ -0,0 +1,41 @@
+
+ */
+final class RemoveIncidentUpdateCommand
+{
+ /**
+ * The incident update to remove.
+ *
+ * @var \CachetHQ\Cachet\Models\IncidentUpdate
+ */
+ public $incidentUpdate;
+
+ /**
+ * Create a new remove incident update command instance.
+ *
+ * @param \CachetHQ\Cachet\Models\IncidentUpdate $incidentUpdate
+ *
+ * @return void
+ */
+ public function __construct(IncidentUpdate $incidentUpdate)
+ {
+ $this->incidentUpdate = $incidentUpdate;
+ }
+}
diff --git a/app/Bus/Commands/IncidentUpdate/UpdateIncidentUpdateCommand.php b/app/Bus/Commands/IncidentUpdate/UpdateIncidentUpdateCommand.php
new file mode 100644
index 000000000000..12d363ad17ed
--- /dev/null
+++ b/app/Bus/Commands/IncidentUpdate/UpdateIncidentUpdateCommand.php
@@ -0,0 +1,79 @@
+
+ */
+final class UpdateIncidentUpdateCommand
+{
+ /**
+ * The incident update.
+ *
+ * @var \CachetHQ\Cachet\Models\IncidentUpdate
+ */
+ public $update;
+
+ /**
+ * The incident status.
+ *
+ * @var int
+ */
+ public $status;
+
+ /**
+ * The incident message.
+ *
+ * @var string
+ */
+ public $message;
+
+ /**
+ * The user.
+ *
+ * @var \CachetHQ\Cachet\Models\User
+ */
+ public $user;
+
+ /**
+ * The validation rules.
+ *
+ * @var string[]
+ */
+ public $rules = [
+ 'status' => 'nullable|int|min:1|max:4',
+ 'message' => 'nullable|string',
+ ];
+
+ /**
+ * Create a new update incident update command instance.
+ *
+ * @param \CachetHQ\Cachet\Models\IncidentUpdate $update
+ * @param string $status
+ * @param string $message
+ * @param \CachetHQ\Cachet\Models\User $user
+ *
+ * @return void
+ */
+ public function __construct(IncidentUpdate $update, $status, $message, User $user)
+ {
+ $this->update = $update;
+ $this->status = $status;
+ $this->message = $message;
+ $this->user = $user;
+ }
+}
diff --git a/app/Bus/Commands/Metric/AddMetricCommand.php b/app/Bus/Commands/Metric/CreateMetricCommand.php
similarity index 74%
rename from app/Bus/Commands/Metric/AddMetricCommand.php
rename to app/Bus/Commands/Metric/CreateMetricCommand.php
index d1dd254696d8..01e31ed39016 100644
--- a/app/Bus/Commands/Metric/AddMetricCommand.php
+++ b/app/Bus/Commands/Metric/CreateMetricCommand.php
@@ -11,7 +11,13 @@
namespace CachetHQ\Cachet\Bus\Commands\Metric;
-final class AddMetricCommand
+/**
+ * This is the create metric command class.
+ *
+ * @author Joseph Cohen
+ * @author James Brooks
+ */
+final class CreateMetricCommand
{
/**
* The metric name.
@@ -83,6 +89,13 @@ final class AddMetricCommand
*/
public $order;
+ /**
+ * The visibility of the metric.
+ *
+ * @var int
+ */
+ public $visible;
+
/**
* The validation rules.
*
@@ -91,15 +104,15 @@ final class AddMetricCommand
public $rules = [
'name' => 'required|string',
'suffix' => 'required|string',
- 'description' => 'string',
- 'display_chart' => 'bool',
- 'default_value' => 'int',
- 'calc_type' => 'int',
- 'display_chart' => 'int',
- 'places' => 'int|between:0,4',
- 'default_view' => 'int|between:0,3',
- 'threshold' => 'numeric|between:0,10',
- 'order' => 'int',
+ 'description' => 'nullable|string',
+ 'default_value' => 'required|int',
+ 'calc_type' => 'required|int',
+ 'display_chart' => 'nullable|int',
+ 'places' => 'nullable|int|between:0,4',
+ 'default_view' => 'required|int|between:0,3',
+ 'threshold' => 'required|int',
+ 'order' => 'nullable|int',
+ 'visible' => 'required|int|between:0,2',
];
/**
@@ -115,10 +128,11 @@ final class AddMetricCommand
* @param int $default_view
* @param int $threshold
* @param int $order
+ * @param int $visible
*
* @return void
*/
- public function __construct($name, $suffix, $description, $default_value, $calc_type, $display_chart, $places, $default_view, $threshold, $order = 0)
+ public function __construct($name, $suffix, $description, $default_value, $calc_type, $display_chart, $places, $default_view, $threshold, $order = 0, $visible = 1)
{
$this->name = $name;
$this->suffix = $suffix;
@@ -130,5 +144,6 @@ public function __construct($name, $suffix, $description, $default_value, $calc_
$this->default_view = $default_view;
$this->threshold = $threshold;
$this->order = $order;
+ $this->visible = $visible;
}
}
diff --git a/app/Bus/Commands/Metric/AddMetricPointCommand.php b/app/Bus/Commands/Metric/CreateMetricPointCommand.php
similarity index 75%
rename from app/Bus/Commands/Metric/AddMetricPointCommand.php
rename to app/Bus/Commands/Metric/CreateMetricPointCommand.php
index ae339585ba30..3555f1945dab 100644
--- a/app/Bus/Commands/Metric/AddMetricPointCommand.php
+++ b/app/Bus/Commands/Metric/CreateMetricPointCommand.php
@@ -13,7 +13,13 @@
use CachetHQ\Cachet\Models\Metric;
-final class AddMetricPointCommand
+/**
+ * This is the create metric point command class.
+ *
+ * @author Joseph Cohen
+ * @author James Brooks
+ */
+final class CreateMetricPointCommand
{
/**
* The metric to add.
@@ -32,7 +38,7 @@ final class AddMetricPointCommand
/**
* The metric point created at.
*
- * @var string
+ * @var int
*/
public $created_at;
@@ -42,8 +48,8 @@ final class AddMetricPointCommand
* @var string[]
*/
public $rules = [
- 'value' => 'numeric',
- 'created_at' => 'string',
+ 'value' => 'required|numeric',
+ 'created_at' => 'nullable|int',
];
/**
@@ -51,7 +57,7 @@ final class AddMetricPointCommand
*
* @param \CachetHQ\Cachet\Models\Metric $metric
* @param int $value
- * @param string $created_at
+ * @param int $created_at
*
* @return void
*/
diff --git a/app/Bus/Commands/Metric/UpdateMetricCommand.php b/app/Bus/Commands/Metric/UpdateMetricCommand.php
index 1bf6cd268813..535837f4ad23 100644
--- a/app/Bus/Commands/Metric/UpdateMetricCommand.php
+++ b/app/Bus/Commands/Metric/UpdateMetricCommand.php
@@ -92,23 +92,30 @@ final class UpdateMetricCommand
*/
public $order;
+ /**
+ * The visibility of the metric.
+ *
+ * @var int
+ */
+ public $visible;
+
/**
* The validation rules.
*
* @var string[]
*/
public $rules = [
- 'name' => 'string',
- 'suffix' => 'string',
- 'description' => 'string',
- 'display_chart' => 'bool',
- 'default_value' => 'numeric',
- 'calc_type' => 'int|in:0,1',
- 'display_chart' => 'int',
- 'places' => 'numeric|between:0,4',
- 'default_view' => 'numeric|between:0,4',
- 'threshold' => 'numeric|between:0,10',
- 'order' => 'int',
+ 'name' => 'nullable|string',
+ 'suffix' => 'nullable|string',
+ 'description' => 'nullable|string',
+ 'default_value' => 'nullable|numeric',
+ 'calc_type' => 'nullable|int|in:0,1',
+ 'display_chart' => 'nullable|int',
+ 'places' => 'nullable|numeric|between:0,4',
+ 'default_view' => 'nullable|numeric|between:0,4',
+ 'threshold' => 'nullable|int',
+ 'order' => 'nullable|int',
+ 'visible' => 'nullable|int|between:0,2',
];
/**
@@ -125,10 +132,11 @@ final class UpdateMetricCommand
* @param int $default_view
* @param int $threshold
* @param int|null $order
+ * @param int $visible
*
* @return void
*/
- public function __construct(Metric $metric, $name, $suffix, $description, $default_value, $calc_type, $display_chart, $places, $default_view, $threshold, $order = null)
+ public function __construct(Metric $metric, $name, $suffix, $description, $default_value, $calc_type, $display_chart, $places, $default_view, $threshold, $order = null, $visible = null)
{
$this->metric = $metric;
$this->name = $name;
@@ -141,5 +149,6 @@ public function __construct(Metric $metric, $name, $suffix, $description, $defau
$this->default_view = $default_view;
$this->threshold = $threshold;
$this->order = $order;
+ $this->visible = $visible;
}
}
diff --git a/app/Bus/Commands/Metric/UpdateMetricPointCommand.php b/app/Bus/Commands/Metric/UpdateMetricPointCommand.php
index 34bff77270ca..0d976df94c7f 100644
--- a/app/Bus/Commands/Metric/UpdateMetricPointCommand.php
+++ b/app/Bus/Commands/Metric/UpdateMetricPointCommand.php
@@ -55,8 +55,8 @@ final class UpdateMetricPointCommand
* @var string[]
*/
public $rules = [
- 'value' => 'numeric',
- 'created_at' => 'string',
+ 'value' => 'nullable|numeric',
+ 'created_at' => 'nullable|string',
];
/**
diff --git a/app/Bus/Commands/Schedule/CreateScheduleCommand.php b/app/Bus/Commands/Schedule/CreateScheduleCommand.php
new file mode 100644
index 000000000000..d40d68df1489
--- /dev/null
+++ b/app/Bus/Commands/Schedule/CreateScheduleCommand.php
@@ -0,0 +1,108 @@
+
+ */
+final class CreateScheduleCommand
+{
+ /**
+ * The schedule name.
+ *
+ * @var string
+ */
+ public $name;
+
+ /**
+ * The schedule message.
+ *
+ * @var string
+ */
+ public $message;
+
+ /**
+ * The schedule status.
+ *
+ * @var int
+ */
+ public $status;
+
+ /**
+ * The schedule date.
+ *
+ * @var string
+ */
+ public $scheduled_at;
+
+ /**
+ * The completed at date.
+ *
+ * @var string
+ */
+ public $completed_at;
+
+ /**
+ * The components affected by the schedule.
+ *
+ * @var array
+ */
+ public $components;
+
+ /**
+ * Whether to notify that the incident was reported.
+ *
+ * @var bool
+ */
+ public $notify;
+
+ /**
+ * The validation rules.
+ *
+ * @var string[]
+ */
+ public $rules = [
+ 'name' => 'required|string',
+ 'message' => 'nullable|string',
+ 'status' => 'required|int|min:0|max:2',
+ 'scheduled_at' => 'required|string',
+ 'completed_at' => 'nullable|string',
+ 'components' => 'nullable|array',
+ 'notify' => 'nullable|bool',
+ ];
+
+ /**
+ * Create a new create schedule command instance.
+ *
+ * @param string $name
+ * @param string $message
+ * @param int $status
+ * @param string $scheduled_at
+ * @param string $completed_at
+ * @param array $components
+ * @param bool $notify
+ *
+ * @return void
+ */
+ public function __construct($name, $message, $status, $scheduled_at, $completed_at, $components, $notify)
+ {
+ $this->name = $name;
+ $this->message = $message;
+ $this->status = $status;
+ $this->scheduled_at = $scheduled_at;
+ $this->completed_at = $completed_at;
+ $this->components = $components;
+ $this->notify = $notify;
+ }
+}
diff --git a/app/Bus/Commands/Schedule/DeleteScheduleCommand.php b/app/Bus/Commands/Schedule/DeleteScheduleCommand.php
new file mode 100644
index 000000000000..572dcf52d805
--- /dev/null
+++ b/app/Bus/Commands/Schedule/DeleteScheduleCommand.php
@@ -0,0 +1,50 @@
+
+ */
+final class DeleteScheduleCommand
+{
+ /**
+ * The schedule to delete.
+ *
+ * @var \CachetHQ\Cachet\Models\Schedule
+ */
+ public $schedule;
+
+ /**
+ * The validation rules.
+ *
+ * @var string[]
+ */
+ public $rules = [
+ 'schedule' => 'required',
+ ];
+
+ /**
+ * Create a new delete schedule command instance.
+ *
+ * @param \CachetHQ\Cachet\Models\Schedule $schedule
+ *
+ * @return void
+ */
+ public function __construct(Schedule $schedule)
+ {
+ $this->schedule = $schedule;
+ }
+}
diff --git a/app/Bus/Commands/Schedule/UpdateScheduleCommand.php b/app/Bus/Commands/Schedule/UpdateScheduleCommand.php
new file mode 100644
index 000000000000..bfe100d47a80
--- /dev/null
+++ b/app/Bus/Commands/Schedule/UpdateScheduleCommand.php
@@ -0,0 +1,110 @@
+
+ */
+final class UpdateScheduleCommand
+{
+ /**
+ * The schedule to update.
+ *
+ * @param \CachetHQ\Cachet\Models\Schedule
+ */
+ public $schedule;
+
+ /**
+ * The schedule name.
+ *
+ * @var string
+ */
+ public $name;
+
+ /**
+ * The schedule message.
+ *
+ * @var string
+ */
+ public $message;
+
+ /**
+ * The schedule status.
+ *
+ * @var int
+ */
+ public $status;
+
+ /**
+ * The schedule date.
+ *
+ * @var string
+ */
+ public $scheduled_at;
+
+ /**
+ * The completed at date.
+ *
+ * @var string
+ */
+ public $completed_at;
+
+ /**
+ * The components affected by the schedule.
+ *
+ * @var array
+ */
+ public $components;
+
+ /**
+ * The validation rules.
+ *
+ * @var string[]
+ */
+ public $rules = [
+ 'schedule' => 'required',
+ 'name' => 'nullable|string',
+ 'message' => 'nullable|string',
+ 'status' => 'nullable|int|min:0|max:2',
+ 'scheduled_at' => 'nullable|string',
+ 'completed_at' => 'nullable|string',
+ 'components' => 'nullable|array',
+ ];
+
+ /**
+ * Create a new update schedule command instance.
+ *
+ * @param \CachetHQ\Cachet\Models\Schedule $schedule
+ * @param string $name
+ * @param string $message
+ * @param int $status
+ * @param string $scheduled_at
+ * @param string $completed_at
+ * @param array $components
+ *
+ * @return void
+ */
+ public function __construct(Schedule $schedule, $name, $message, $status, $scheduled_at, $completed_at, array $components = [])
+ {
+ $this->schedule = $schedule;
+ $this->name = $name;
+ $this->message = $message;
+ $this->status = $status;
+ $this->scheduled_at = $scheduled_at;
+ $this->completed_at = $completed_at;
+ $this->components = $components;
+ }
+}
diff --git a/app/Bus/Commands/System/Config/UpdateConfigCommand.php b/app/Bus/Commands/System/Config/UpdateConfigCommand.php
new file mode 100644
index 000000000000..9fb21610e1d3
--- /dev/null
+++ b/app/Bus/Commands/System/Config/UpdateConfigCommand.php
@@ -0,0 +1,39 @@
+
+ */
+final class UpdateConfigCommand
+{
+ /**
+ * This is the config key/values array.
+ *
+ * @var array
+ */
+ public $values;
+
+ /**
+ * Create a new update config command instance.
+ *
+ * @param array $values
+ *
+ * @return void
+ */
+ public function __construct($values)
+ {
+ $this->values = $values;
+ }
+}
diff --git a/app/Bus/Commands/User/AddUserCommand.php b/app/Bus/Commands/User/CreateUserCommand.php
similarity index 89%
rename from app/Bus/Commands/User/AddUserCommand.php
rename to app/Bus/Commands/User/CreateUserCommand.php
index a99ed99f9922..fad590d3baf4 100644
--- a/app/Bus/Commands/User/AddUserCommand.php
+++ b/app/Bus/Commands/User/CreateUserCommand.php
@@ -12,11 +12,11 @@
namespace CachetHQ\Cachet\Bus\Commands\User;
/**
- * This is the add user command.
+ * This is the create user command.
*
* @author James Brooks
*/
-final class AddUserCommand
+final class CreateUserCommand
{
/**
* The user username.
@@ -53,8 +53,8 @@ final class AddUserCommand
*/
public $rules = [
'username' => 'required|string',
- 'password' => 'string',
- 'level' => 'int',
+ 'password' => 'required|string',
+ 'level' => 'required|int',
];
/**
diff --git a/app/Bus/Commands/User/InviteUserCommand.php b/app/Bus/Commands/User/InviteUserCommand.php
index 2585f09518e5..49f16d9a615e 100644
--- a/app/Bus/Commands/User/InviteUserCommand.php
+++ b/app/Bus/Commands/User/InviteUserCommand.php
@@ -31,7 +31,7 @@ final class InviteUserCommand
* @var string[]
*/
public $rules = [
- 'emails' => 'required|array|email',
+ 'emails.*' => 'required|email',
];
/**
diff --git a/app/Bus/Commands/User/SignupUserCommand.php b/app/Bus/Commands/User/SignupUserCommand.php
index 7cbf782c63c4..cfba31f5d60d 100644
--- a/app/Bus/Commands/User/SignupUserCommand.php
+++ b/app/Bus/Commands/User/SignupUserCommand.php
@@ -48,9 +48,9 @@ final class SignupUserCommand
*/
public $rules = [
'username' => 'required|string',
- 'password' => 'string',
+ 'password' => 'required|string',
'email' => 'required|string|email',
- 'level' => 'int',
+ 'level' => 'required|int',
];
/**
diff --git a/tests/Foundation/Providers/RouteServiceProviderTest.php b/app/Bus/Events/ActionInterface.php
similarity index 50%
rename from tests/Foundation/Providers/RouteServiceProviderTest.php
rename to app/Bus/Events/ActionInterface.php
index 911c6f083fa7..ae1bc1c8a543 100644
--- a/tests/Foundation/Providers/RouteServiceProviderTest.php
+++ b/app/Bus/Events/ActionInterface.php
@@ -9,17 +9,20 @@
* file that was distributed with this source code.
*/
-namespace CachetHQ\Tests\Cachet\Foundation\Providers;
-
-use AltThree\TestBench\ServiceProviderTrait;
-use CachetHQ\Tests\Cachet\AbstractTestCase;
+namespace CachetHQ\Cachet\Bus\Events;
/**
- * This is the route service provider test class.
+ * This is the action interface.
*
* @author Graham Campbell
+ * @author James Brooks
*/
-class RouteServiceProviderTest extends AbstractTestCase
+interface ActionInterface
{
- use ServiceProviderTrait;
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction();
}
diff --git a/app/Bus/Events/Beacon/BeaconFailedToSendEvent.php b/app/Bus/Events/Beacon/BeaconFailedToSendEvent.php
index 53ed3eefe5c1..932dab30d9d1 100644
--- a/app/Bus/Events/Beacon/BeaconFailedToSendEvent.php
+++ b/app/Bus/Events/Beacon/BeaconFailedToSendEvent.php
@@ -18,5 +18,13 @@
*/
final class BeaconFailedToSendEvent implements BeaconEventInterface
{
- //
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'Beacon failed to send.';
+ }
}
diff --git a/app/Bus/Events/Beacon/BeaconWasSentEvent.php b/app/Bus/Events/Beacon/BeaconWasSentEvent.php
index 1d485328be71..919f338f9c97 100644
--- a/app/Bus/Events/Beacon/BeaconWasSentEvent.php
+++ b/app/Bus/Events/Beacon/BeaconWasSentEvent.php
@@ -18,5 +18,13 @@
*/
final class BeaconWasSentEvent implements BeaconEventInterface
{
- //
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'Beacon was sent.';
+ }
}
diff --git a/app/Bus/Events/Component/ComponentEventInterface.php b/app/Bus/Events/Component/ComponentEventInterface.php
index 147c999c043a..281a811f7904 100644
--- a/app/Bus/Events/Component/ComponentEventInterface.php
+++ b/app/Bus/Events/Component/ComponentEventInterface.php
@@ -13,6 +13,12 @@
use CachetHQ\Cachet\Bus\Events\EventInterface;
+/**
+ * This is the component event interface.
+ *
+ * @author Graham Campbell
+ * @author James Brooks
+ */
interface ComponentEventInterface extends EventInterface
{
//
diff --git a/app/Bus/Events/Component/ComponentStatusWasChangedEvent.php b/app/Bus/Events/Component/ComponentStatusWasChangedEvent.php
new file mode 100644
index 000000000000..4c987409b653
--- /dev/null
+++ b/app/Bus/Events/Component/ComponentStatusWasChangedEvent.php
@@ -0,0 +1,102 @@
+
+ */
+final class ComponentStatusWasChangedEvent implements ActionInterface, ComponentEventInterface
+{
+ /**
+ * The user who changed the component.
+ *
+ * @var \CachetHQ\Cachet\Models\User
+ */
+ public $user;
+
+ /**
+ * The component that was changed.
+ *
+ * @var \CachetHQ\Cachet\Models\Component
+ */
+ public $component;
+
+ /**
+ * The original status of the component.
+ *
+ * @var int
+ */
+ public $original_status;
+
+ /**
+ * The new status of the component.
+ *
+ * @var int
+ */
+ public $new_status;
+
+ /**
+ * If silent, we won't notify.
+ *
+ * @var bool
+ */
+ public $silent;
+
+ /**
+ * Create a new component was updated event instance.
+ *
+ * @param \CachetHQ\Cachet\Models\User $user
+ * @param \CachetHQ\Cachet\Models\Component $component
+ * @param int $original_status
+ * @param int $new_status
+ * @param bool $silent
+ *
+ * @return void
+ */
+ public function __construct(User $user, Component $component, $original_status, $new_status, $silent)
+ {
+ $this->user = $user;
+ $this->component = $component;
+ $this->original_status = $original_status;
+ $this->new_status = $new_status;
+ $this->silent = $silent;
+ }
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'Component status was changed.';
+ }
+
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction()
+ {
+ return [
+ 'user' => $this->user,
+ 'description' => (string) $this,
+ ];
+ }
+}
diff --git a/app/Bus/Events/Component/ComponentStatusWasUpdatedEvent.php b/app/Bus/Events/Component/ComponentStatusWasUpdatedEvent.php
deleted file mode 100644
index 446463a572f6..000000000000
--- a/app/Bus/Events/Component/ComponentStatusWasUpdatedEvent.php
+++ /dev/null
@@ -1,59 +0,0 @@
-
- */
-final class ComponentStatusWasUpdatedEvent implements ComponentEventInterface
-{
- /**
- * The component that was updated.
- *
- * @var \CachetHQ\Cachet\Models\Component
- */
- public $component;
-
- /**
- * The original status of the component.
- *
- * @var int
- */
- public $original_status;
-
- /**
- * The new status of the component.
- *
- * @var int
- */
- public $new_status;
-
- /**
- * Create a new component was updated event instance.
- *
- * @param \CachetHQ\Cachet\Models\Component $component
- * @param int $original_status
- * @param int $new_status
- *
- * @return void
- */
- public function __construct(Component $component, $original_status, $new_status)
- {
- $this->component = $component;
- $this->original_status = $original_status;
- $this->new_status = $new_status;
- }
-}
diff --git a/app/Bus/Events/Component/ComponentWasAddedEvent.php b/app/Bus/Events/Component/ComponentWasAddedEvent.php
deleted file mode 100644
index 7c892a78f83d..000000000000
--- a/app/Bus/Events/Component/ComponentWasAddedEvent.php
+++ /dev/null
@@ -1,36 +0,0 @@
-component = $component;
- }
-}
diff --git a/app/Bus/Events/Component/ComponentWasCreatedEvent.php b/app/Bus/Events/Component/ComponentWasCreatedEvent.php
new file mode 100644
index 000000000000..29b00da5950d
--- /dev/null
+++ b/app/Bus/Events/Component/ComponentWasCreatedEvent.php
@@ -0,0 +1,75 @@
+
+ */
+final class ComponentWasCreatedEvent implements ActionInterface, ComponentEventInterface
+{
+ /**
+ * The user who added the component.
+ *
+ * @var \CachetHQ\Cachet\Models\User
+ */
+ public $user;
+
+ /**
+ * The component that was added.
+ *
+ * @var \CachetHQ\Cachet\Models\Component
+ */
+ public $component;
+
+ /**
+ * Create a new component was added event instance.
+ *
+ * @param \CachetHQ\Cachet\Models\User $user
+ * @param \CachetHQ\Cachet\Models\Component $component
+ *
+ * @return void
+ */
+ public function __construct(User $user, Component $component)
+ {
+ $this->user = $user;
+ $this->component = $component;
+ }
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'Component was added.';
+ }
+
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction()
+ {
+ return [
+ 'user' => $this->user,
+ 'description' => (string) $this,
+ ];
+ }
+}
diff --git a/app/Bus/Events/Component/ComponentWasRemovedEvent.php b/app/Bus/Events/Component/ComponentWasRemovedEvent.php
index f44839d347a8..02dc3e64910a 100644
--- a/app/Bus/Events/Component/ComponentWasRemovedEvent.php
+++ b/app/Bus/Events/Component/ComponentWasRemovedEvent.php
@@ -11,10 +11,24 @@
namespace CachetHQ\Cachet\Bus\Events\Component;
+use CachetHQ\Cachet\Bus\Events\ActionInterface;
use CachetHQ\Cachet\Models\Component;
+use CachetHQ\Cachet\Models\User;
-final class ComponentWasRemovedEvent implements ComponentEventInterface
+/**
+ * This is the component was removed event class.
+ *
+ * @author James Brooks
+ */
+final class ComponentWasRemovedEvent implements ActionInterface, ComponentEventInterface
{
+ /**
+ * The user who removed the component.
+ *
+ * @var \CachetHQ\Cachet\Models\User
+ */
+ public $user;
+
/**
* The component that was removed.
*
@@ -25,12 +39,37 @@ final class ComponentWasRemovedEvent implements ComponentEventInterface
/**
* Create a new component was removed event instance.
*
+ * @param \CachetHQ\Cachet\Models\User $user
* @param \CachetHQ\Cachet\Models\Component $component
*
* @return void
*/
- public function __construct(Component $component)
+ public function __construct(User $user, Component $component)
{
+ $this->user = $user;
$this->component = $component;
}
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'Component was removed.';
+ }
+
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction()
+ {
+ return [
+ 'user' => $this->user,
+ 'description' => (string) $this,
+ ];
+ }
}
diff --git a/app/Bus/Events/Component/ComponentWasUpdatedEvent.php b/app/Bus/Events/Component/ComponentWasUpdatedEvent.php
index b58572513421..3349e4642fc0 100644
--- a/app/Bus/Events/Component/ComponentWasUpdatedEvent.php
+++ b/app/Bus/Events/Component/ComponentWasUpdatedEvent.php
@@ -11,10 +11,25 @@
namespace CachetHQ\Cachet\Bus\Events\Component;
+use CachetHQ\Cachet\Bus\Events\ActionInterface;
use CachetHQ\Cachet\Models\Component;
+use CachetHQ\Cachet\Models\User;
-final class ComponentWasUpdatedEvent implements ComponentEventInterface
+/**
+ * This is the component was updated event class.
+ *
+ * @author James Brooks
+ * @author Graham Campbell
+ */
+final class ComponentWasUpdatedEvent implements ActionInterface, ComponentEventInterface
{
+ /**
+ * The user who updated the component.
+ *
+ * @var \CachetHQ\Cachet\Models\User
+ */
+ public $user;
+
/**
* The component that was updated.
*
@@ -25,12 +40,37 @@ final class ComponentWasUpdatedEvent implements ComponentEventInterface
/**
* Create a new component was updated event instance.
*
+ * @param \CachetHQ\Cachet\Models\User $user
* @param \CachetHQ\Cachet\Models\Component $component
*
* @return void
*/
- public function __construct(Component $component)
+ public function __construct(User $user, Component $component)
{
+ $this->user = $user;
$this->component = $component;
}
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'Component was updated.';
+ }
+
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction()
+ {
+ return [
+ 'user' => $this->user,
+ 'description' => (string) $this,
+ ];
+ }
}
diff --git a/app/Bus/Events/ComponentGroup/ComponentGroupEventInterface.php b/app/Bus/Events/ComponentGroup/ComponentGroupEventInterface.php
index 99d92b77dc8c..6e40f0ee24cf 100644
--- a/app/Bus/Events/ComponentGroup/ComponentGroupEventInterface.php
+++ b/app/Bus/Events/ComponentGroup/ComponentGroupEventInterface.php
@@ -13,6 +13,12 @@
use CachetHQ\Cachet\Bus\Events\EventInterface;
+/**
+ * This is the component group event interface.
+ *
+ * @author Graham Campbell
+ * @author James Brooks
+ */
interface ComponentGroupEventInterface extends EventInterface
{
//
diff --git a/app/Bus/Events/ComponentGroup/ComponentGroupWasAddedEvent.php b/app/Bus/Events/ComponentGroup/ComponentGroupWasAddedEvent.php
deleted file mode 100644
index 2d8479fe3f1b..000000000000
--- a/app/Bus/Events/ComponentGroup/ComponentGroupWasAddedEvent.php
+++ /dev/null
@@ -1,36 +0,0 @@
-group = $group;
- }
-}
diff --git a/app/Bus/Events/ComponentGroup/ComponentGroupWasCreatedEvent.php b/app/Bus/Events/ComponentGroup/ComponentGroupWasCreatedEvent.php
new file mode 100644
index 000000000000..97ad605786e2
--- /dev/null
+++ b/app/Bus/Events/ComponentGroup/ComponentGroupWasCreatedEvent.php
@@ -0,0 +1,75 @@
+
+ */
+final class ComponentGroupWasCreatedEvent implements ActionInterface, ComponentGroupEventInterface
+{
+ /**
+ * The user who added the component group.
+ *
+ * @var \CachetHQ\Cachet\Models\User
+ */
+ public $user;
+
+ /**
+ * The component group that was added.
+ *
+ * @var \CachetHQ\Cachet\Models\ComponentGroup
+ */
+ public $group;
+
+ /**
+ * Create a new component group was added event instance.
+ *
+ * @param \CachetHQ\Cachet\Models\User $group
+ * @param \CachetHQ\Cachet\Models\ComponentGroup $group
+ *
+ * @return void
+ */
+ public function __construct(User $user, ComponentGroup $group)
+ {
+ $this->user = $user;
+ $this->group = $group;
+ }
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'Component Group was added.';
+ }
+
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction()
+ {
+ return [
+ 'user' => $this->user,
+ 'description' => (string) $this,
+ ];
+ }
+}
diff --git a/app/Bus/Events/ComponentGroup/ComponentGroupWasRemovedEvent.php b/app/Bus/Events/ComponentGroup/ComponentGroupWasRemovedEvent.php
index 275449cef38f..1bf33fb08620 100644
--- a/app/Bus/Events/ComponentGroup/ComponentGroupWasRemovedEvent.php
+++ b/app/Bus/Events/ComponentGroup/ComponentGroupWasRemovedEvent.php
@@ -11,10 +11,19 @@
namespace CachetHQ\Cachet\Bus\Events\ComponentGroup;
+use CachetHQ\Cachet\Bus\Events\ActionInterface;
use CachetHQ\Cachet\Models\ComponentGroup;
+use CachetHQ\Cachet\Models\User;
-final class ComponentGroupWasRemovedEvent implements ComponentGroupEventInterface
+final class ComponentGroupWasRemovedEvent implements ActionInterface, ComponentGroupEventInterface
{
+ /**
+ * The user who removed the component group.
+ *
+ * @var \CachetHQ\Cachet\Models\User
+ */
+ public $user;
+
/**
* The component group that was removed.
*
@@ -25,12 +34,37 @@ final class ComponentGroupWasRemovedEvent implements ComponentGroupEventInterfac
/**
* Create a new component group was removed event instance.
*
+ * @param \CachetHQ\Cachet\Models\User $user
* @param \CachetHQ\Cachet\Models\ComponentGroup $group
*
* @return void
*/
- public function __construct(ComponentGroup $group)
+ public function __construct(User $user, ComponentGroup $group)
{
+ $this->user = $user;
$this->group = $group;
}
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'Component Group was removed.';
+ }
+
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction()
+ {
+ return [
+ 'user' => $this->user,
+ 'description' => (string) $this,
+ ];
+ }
}
diff --git a/app/Bus/Events/ComponentGroup/ComponentGroupWasUpdatedEvent.php b/app/Bus/Events/ComponentGroup/ComponentGroupWasUpdatedEvent.php
index 19138f75c5bc..5942f00c8b8e 100644
--- a/app/Bus/Events/ComponentGroup/ComponentGroupWasUpdatedEvent.php
+++ b/app/Bus/Events/ComponentGroup/ComponentGroupWasUpdatedEvent.php
@@ -11,10 +11,19 @@
namespace CachetHQ\Cachet\Bus\Events\ComponentGroup;
+use CachetHQ\Cachet\Bus\Events\ActionInterface;
use CachetHQ\Cachet\Models\ComponentGroup;
+use CachetHQ\Cachet\Models\User;
-final class ComponentGroupWasUpdatedEvent implements ComponentGroupEventInterface
+final class ComponentGroupWasUpdatedEvent implements ActionInterface, ComponentGroupEventInterface
{
+ /**
+ * The user who updated the component group.
+ *
+ * @var \CachetHQ\Cachet\Models\User
+ */
+ public $user;
+
/**
* The component group that was updated.
*
@@ -25,12 +34,37 @@ final class ComponentGroupWasUpdatedEvent implements ComponentGroupEventInterfac
/**
* Create a new component group was updated event instance.
*
+ * @param \CachetHQ\Cachet\Models\User $user
* @param \CachetHQ\Cachet\Models\ComponentGroup $group
*
* @return void
*/
- public function __construct(ComponentGroup $group)
+ public function __construct(User $user, ComponentGroup $group)
{
+ $this->user = $user;
$this->group = $group;
}
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'Component Group was updated.';
+ }
+
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction()
+ {
+ return [
+ 'user' => $this->user,
+ 'description' => (string) $this,
+ ];
+ }
}
diff --git a/app/Bus/Events/EventInterface.php b/app/Bus/Events/EventInterface.php
index 53013dfdb3a6..41a58b735b76 100644
--- a/app/Bus/Events/EventInterface.php
+++ b/app/Bus/Events/EventInterface.php
@@ -11,6 +11,12 @@
namespace CachetHQ\Cachet\Bus\Events;
+/**
+ * This is the event interface.
+ *
+ * @author Graham Campbell
+ * @author James Brooks
+ */
interface EventInterface
{
//
diff --git a/app/Bus/Events/Incident/IncidentEventInterface.php b/app/Bus/Events/Incident/IncidentEventInterface.php
index a4cb6054f88b..31418b55781c 100644
--- a/app/Bus/Events/Incident/IncidentEventInterface.php
+++ b/app/Bus/Events/Incident/IncidentEventInterface.php
@@ -13,6 +13,12 @@
use CachetHQ\Cachet\Bus\Events\EventInterface;
+/**
+ * This is the incident event interface.
+ *
+ * @author Graham Campbell
+ * @author James Brooks
+ */
interface IncidentEventInterface extends EventInterface
{
//
diff --git a/app/Bus/Events/Incident/IncidentWasCreatedEvent.php b/app/Bus/Events/Incident/IncidentWasCreatedEvent.php
new file mode 100644
index 000000000000..c43d672b0c66
--- /dev/null
+++ b/app/Bus/Events/Incident/IncidentWasCreatedEvent.php
@@ -0,0 +1,79 @@
+user = $user;
+ $this->incident = $incident;
+ $this->notify = $notify;
+ }
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'Incident was reported.';
+ }
+
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction()
+ {
+ return [
+ 'user' => $this->user,
+ 'description' => (string) $this,
+ ];
+ }
+}
diff --git a/app/Bus/Events/Incident/IncidentWasRemovedEvent.php b/app/Bus/Events/Incident/IncidentWasRemovedEvent.php
index ef6890b03ed9..78a95f76127f 100644
--- a/app/Bus/Events/Incident/IncidentWasRemovedEvent.php
+++ b/app/Bus/Events/Incident/IncidentWasRemovedEvent.php
@@ -11,10 +11,19 @@
namespace CachetHQ\Cachet\Bus\Events\Incident;
+use CachetHQ\Cachet\Bus\Events\ActionInterface;
use CachetHQ\Cachet\Models\Incident;
+use CachetHQ\Cachet\Models\User;
-final class IncidentWasRemovedEvent implements IncidentEventInterface
+final class IncidentWasRemovedEvent implements ActionInterface, IncidentEventInterface
{
+ /**
+ * The user who removed the event.
+ *
+ * @var \CachetHQ\Cachet\Models\User
+ */
+ public $user;
+
/**
* The incident that has been removed.
*
@@ -25,12 +34,37 @@ final class IncidentWasRemovedEvent implements IncidentEventInterface
/**
* Create a new incident was removed event instance.
*
+ * @param \CachetHQ\Cachet\Models\User $user
* @param \CachetHQ\Cachet\Models\Incident $incident
*
* @return void
*/
- public function __construct(Incident $incident)
+ public function __construct(User $user, Incident $incident)
{
+ $this->user = $user;
$this->incident = $incident;
}
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'Incident was removed.';
+ }
+
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction()
+ {
+ return [
+ 'user' => $this->user,
+ 'description' => (string) $this,
+ ];
+ }
}
diff --git a/app/Bus/Events/Incident/IncidentWasReportedEvent.php b/app/Bus/Events/Incident/IncidentWasReportedEvent.php
deleted file mode 100644
index a93e7b02a291..000000000000
--- a/app/Bus/Events/Incident/IncidentWasReportedEvent.php
+++ /dev/null
@@ -1,36 +0,0 @@
-incident = $incident;
- }
-}
diff --git a/app/Bus/Events/Incident/IncidentWasUpdatedEvent.php b/app/Bus/Events/Incident/IncidentWasUpdatedEvent.php
index 251bc781bebe..7aa11322af1a 100644
--- a/app/Bus/Events/Incident/IncidentWasUpdatedEvent.php
+++ b/app/Bus/Events/Incident/IncidentWasUpdatedEvent.php
@@ -11,10 +11,19 @@
namespace CachetHQ\Cachet\Bus\Events\Incident;
+use CachetHQ\Cachet\Bus\Events\ActionInterface;
use CachetHQ\Cachet\Models\Incident;
+use CachetHQ\Cachet\Models\User;
-final class IncidentWasUpdatedEvent implements IncidentEventInterface
+final class IncidentWasUpdatedEvent implements ActionInterface, IncidentEventInterface
{
+ /**
+ * The user who updated the event.
+ *
+ * @var \CachetHQ\Cachet\Models\User
+ */
+ public $user;
+
/**
* The incident that has been updated.
*
@@ -25,12 +34,37 @@ final class IncidentWasUpdatedEvent implements IncidentEventInterface
/**
* Create a new incident has updated event instance.
*
+ * @param \CachetHQ\Cachet\Models\User $user
* @param \CachetHQ\Cachet\Models\Incident $incident
*
* @return void
*/
- public function __construct(Incident $incident)
+ public function __construct(User $user, Incident $incident)
{
+ $this->user = $user;
$this->incident = $incident;
}
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'Incident was updated.';
+ }
+
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction()
+ {
+ return [
+ 'user' => $this->user,
+ 'description' => (string) $this,
+ ];
+ }
}
diff --git a/app/Bus/Events/Incident/MaintenanceWasScheduledEvent.php b/app/Bus/Events/Incident/MaintenanceWasScheduledEvent.php
deleted file mode 100644
index 2bf293817628..000000000000
--- a/app/Bus/Events/Incident/MaintenanceWasScheduledEvent.php
+++ /dev/null
@@ -1,36 +0,0 @@
-incident = $incident;
- }
-}
diff --git a/app/Bus/Events/IncidentUpdate/IncidentUpdateEventInterface.php b/app/Bus/Events/IncidentUpdate/IncidentUpdateEventInterface.php
new file mode 100644
index 000000000000..9f1687afccbc
--- /dev/null
+++ b/app/Bus/Events/IncidentUpdate/IncidentUpdateEventInterface.php
@@ -0,0 +1,24 @@
+
+ */
+interface IncidentUpdateEventInterface extends EventInterface
+{
+ //
+}
diff --git a/app/Bus/Events/IncidentUpdate/IncidentUpdateWasRemovedEvent.php b/app/Bus/Events/IncidentUpdate/IncidentUpdateWasRemovedEvent.php
new file mode 100644
index 000000000000..8618457fac23
--- /dev/null
+++ b/app/Bus/Events/IncidentUpdate/IncidentUpdateWasRemovedEvent.php
@@ -0,0 +1,75 @@
+
+ */
+final class IncidentUpdateWasRemovedEvent implements ActionInterface, IncidentUpdateEventInterface
+{
+ /**
+ * The user who removed the incident update.
+ *
+ * @var \CachetHQ\Cachet\Models\User
+ */
+ public $user;
+
+ /**
+ * The incident update that has been removed.
+ *
+ * @var \CachetHQ\Cachet\Models\IncidentUpdate
+ */
+ public $update;
+
+ /**
+ * Create a new incident update was removed event instance.
+ *
+ * @param \CachetHQ\Cachet\Models\User $user
+ * @param \CachetHQ\Cachet\Models\IncidentUpdate $update
+ *
+ * @return void
+ */
+ public function __construct(User $user, IncidentUpdate $update)
+ {
+ $this->user = $user;
+ $this->update = $update;
+ }
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'Incident Update was removed.';
+ }
+
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction()
+ {
+ return [
+ 'user' => $this->user,
+ 'description' => (string) $this,
+ ];
+ }
+}
diff --git a/app/Bus/Events/IncidentUpdate/IncidentUpdateWasReportedEvent.php b/app/Bus/Events/IncidentUpdate/IncidentUpdateWasReportedEvent.php
new file mode 100644
index 000000000000..52dadf881029
--- /dev/null
+++ b/app/Bus/Events/IncidentUpdate/IncidentUpdateWasReportedEvent.php
@@ -0,0 +1,75 @@
+
+ */
+final class IncidentUpdateWasReportedEvent implements ActionInterface, IncidentUpdateEventInterface
+{
+ /**
+ * The user who reported the incident update.
+ *
+ * @var \CachetHQ\Cachet\Models\User
+ */
+ public $user;
+
+ /**
+ * The incident update that has been reported.
+ *
+ * @var \CachetHQ\Cachet\Models\IncidentUpdate
+ */
+ public $update;
+
+ /**
+ * Create a new incident update was reported event instance.
+ *
+ * @param \CachetHQ\Cachet\Models\User $user
+ * @param \CachetHQ\Cachet\Models\IncidentUpdate $update
+ *
+ * @return void
+ */
+ public function __construct(User $user, IncidentUpdate $update)
+ {
+ $this->user = $user;
+ $this->update = $update;
+ }
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'Incident Update was reported.';
+ }
+
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction()
+ {
+ return [
+ 'user' => $this->user,
+ 'description' => (string) $this,
+ ];
+ }
+}
diff --git a/app/Bus/Events/IncidentUpdate/IncidentUpdateWasUpdatedEvent.php b/app/Bus/Events/IncidentUpdate/IncidentUpdateWasUpdatedEvent.php
new file mode 100644
index 000000000000..20e3782d73e0
--- /dev/null
+++ b/app/Bus/Events/IncidentUpdate/IncidentUpdateWasUpdatedEvent.php
@@ -0,0 +1,74 @@
+
+ */
+final class IncidentUpdateWasUpdatedEvent implements ActionInterface, IncidentUpdateEventInterface
+{
+ /**
+ * The user who updated the incident update.
+ *
+ * @var \CachetHQ\Cachet\Models\User
+ */
+ public $user;
+
+ /**
+ * The incident update that has been updated.
+ *
+ * @var \CachetHQ\Cachet\Models\IncidentUpdate
+ */
+ public $update;
+
+ /**
+ * Create a new incident update was updated event instance.
+ *
+ * @param \CachetHQ\Cachet\Models\IncidentUpdate $update
+ *
+ * @return void
+ */
+ public function __construct(User $user, IncidentUpdate $update)
+ {
+ $this->user = $user;
+ $this->update = $update;
+ }
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'Incident Update was updated.';
+ }
+
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction()
+ {
+ return [
+ 'user' => $this->user,
+ 'description' => (string) $this,
+ ];
+ }
+}
diff --git a/app/Bus/Events/Invite/InviteEventInterface.php b/app/Bus/Events/Invite/InviteEventInterface.php
index 35ccfc44ac69..63c199706b55 100644
--- a/app/Bus/Events/Invite/InviteEventInterface.php
+++ b/app/Bus/Events/Invite/InviteEventInterface.php
@@ -13,6 +13,12 @@
use CachetHQ\Cachet\Bus\Events\EventInterface;
+/**
+ * This is the invite event interface.
+ *
+ * @author Graham Campbell
+ * @author James Brooks
+ */
interface InviteEventInterface extends EventInterface
{
//
diff --git a/app/Bus/Events/Invite/InviteWasClaimedEvent.php b/app/Bus/Events/Invite/InviteWasClaimedEvent.php
index b8a3c77d246a..02f950ee52df 100644
--- a/app/Bus/Events/Invite/InviteWasClaimedEvent.php
+++ b/app/Bus/Events/Invite/InviteWasClaimedEvent.php
@@ -31,4 +31,14 @@ public function __construct(Invite $invite)
{
$this->invite = $invite;
}
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'Invite was claimed.';
+ }
}
diff --git a/app/Bus/Events/Metric/MetricEventInterface.php b/app/Bus/Events/Metric/MetricEventInterface.php
index 104a381a37e6..631b45492089 100644
--- a/app/Bus/Events/Metric/MetricEventInterface.php
+++ b/app/Bus/Events/Metric/MetricEventInterface.php
@@ -13,6 +13,12 @@
use CachetHQ\Cachet\Bus\Events\EventInterface;
+/**
+ * This is the metric event interface.
+ *
+ * @author Graham Campbell
+ * @author James Brooks
+ */
interface MetricEventInterface extends EventInterface
{
//
diff --git a/app/Bus/Events/Metric/MetricPointWasAddedEvent.php b/app/Bus/Events/Metric/MetricPointWasAddedEvent.php
deleted file mode 100644
index 7de09cf24fb7..000000000000
--- a/app/Bus/Events/Metric/MetricPointWasAddedEvent.php
+++ /dev/null
@@ -1,36 +0,0 @@
-metricPoint = $metricPoint;
- }
-}
diff --git a/app/Bus/Events/Metric/MetricPointWasCreatedEvent.php b/app/Bus/Events/Metric/MetricPointWasCreatedEvent.php
new file mode 100644
index 000000000000..7137b8c119ce
--- /dev/null
+++ b/app/Bus/Events/Metric/MetricPointWasCreatedEvent.php
@@ -0,0 +1,75 @@
+
+ */
+final class MetricPointWasCreatedEvent implements ActionInterface, MetricEventInterface
+{
+ /**
+ * The user who added the metric point.
+ *
+ * @var \CachetHQ\Cachet\Models\User
+ */
+ public $user;
+
+ /**
+ * The metric point that was added.
+ *
+ * @var \CachetHQ\Cachet\Models\MetricPoint
+ */
+ public $metricPoint;
+
+ /**
+ * Create a new metric point was added event instance.
+ *
+ * @param \CachetHQ\Cachet\Models\User $user
+ * @param \CachetHQ\Cachet\Models\MetricPoint $metricPoint
+ *
+ * @return void
+ */
+ public function __construct(User $user, MetricPoint $metricPoint)
+ {
+ $this->user = $user;
+ $this->metricPoint = $metricPoint;
+ }
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'Metric Point was added.';
+ }
+
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction()
+ {
+ return [
+ 'user' => $this->user,
+ 'description' => (string) $this,
+ ];
+ }
+}
diff --git a/app/Bus/Events/Metric/MetricPointWasRemovedEvent.php b/app/Bus/Events/Metric/MetricPointWasRemovedEvent.php
index 2d0b76ee341b..85718a41d5da 100644
--- a/app/Bus/Events/Metric/MetricPointWasRemovedEvent.php
+++ b/app/Bus/Events/Metric/MetricPointWasRemovedEvent.php
@@ -11,10 +11,19 @@
namespace CachetHQ\Cachet\Bus\Events\Metric;
+use CachetHQ\Cachet\Bus\Events\ActionInterface;
use CachetHQ\Cachet\Models\MetricPoint;
+use CachetHQ\Cachet\Models\User;
-final class MetricPointWasRemovedEvent implements MetricEventInterface
+final class MetricPointWasRemovedEvent implements ActionInterface, MetricEventInterface
{
+ /**
+ * The user who removed the metric point.
+ *
+ * @var \CachetHQ\Cachet\Models\User
+ */
+ public $user;
+
/**
* The metric point that was removed.
*
@@ -25,12 +34,37 @@ final class MetricPointWasRemovedEvent implements MetricEventInterface
/**
* Create a new metric point was removed event instance.
*
+ * @param \CachetHQ\Cachet\Models\User $user
* @param \CachetHQ\Cachet\Models\MetricPoint $memtricPoint
*
* @return void
*/
- public function __construct(MetricPoint $metricPoint)
+ public function __construct(User $user, MetricPoint $metricPoint)
{
+ $this->user = $user;
$this->metricPoint = $metricPoint;
}
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'Metric Point was removed.';
+ }
+
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction()
+ {
+ return [
+ 'user' => $this->user,
+ 'description' => (string) $this,
+ ];
+ }
}
diff --git a/app/Bus/Events/Metric/MetricPointWasUpdatedEvent.php b/app/Bus/Events/Metric/MetricPointWasUpdatedEvent.php
index 35e97f5d543b..b61a595d111c 100644
--- a/app/Bus/Events/Metric/MetricPointWasUpdatedEvent.php
+++ b/app/Bus/Events/Metric/MetricPointWasUpdatedEvent.php
@@ -11,10 +11,19 @@
namespace CachetHQ\Cachet\Bus\Events\Metric;
+use CachetHQ\Cachet\Bus\Events\ActionInterface;
use CachetHQ\Cachet\Models\MetricPoint;
+use CachetHQ\Cachet\Models\User;
-final class MetricPointWasUpdatedEvent implements MetricEventInterface
+final class MetricPointWasUpdatedEvent implements ActionInterface, MetricEventInterface
{
+ /**
+ * The user who updated the metric point.
+ *
+ * @var \CachetHQ\Cachet\Models\User
+ */
+ public $user;
+
/**
* The metric point that was updated.
*
@@ -25,12 +34,37 @@ final class MetricPointWasUpdatedEvent implements MetricEventInterface
/**
* Create a new metric point was updated event instance.
*
+ * @param \CachetHQ\Cachet\Models\User $user
* @param \CachetHQ\Cachet\Models\MetricPoint $metricPoint
*
* @return void
*/
- public function __construct(MetricPoint $metricPoint)
+ public function __construct(User $user, MetricPoint $metricPoint)
{
+ $this->user = $user;
$this->metricPoint = $metricPoint;
}
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'Metric Point was updated.';
+ }
+
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction()
+ {
+ return [
+ 'user' => $this->user,
+ 'description' => (string) $this,
+ ];
+ }
}
diff --git a/app/Bus/Events/Metric/MetricWasAddedEvent.php b/app/Bus/Events/Metric/MetricWasAddedEvent.php
deleted file mode 100644
index 9d495c6eff92..000000000000
--- a/app/Bus/Events/Metric/MetricWasAddedEvent.php
+++ /dev/null
@@ -1,36 +0,0 @@
-metric = $metric;
- }
-}
diff --git a/app/Bus/Events/Metric/MetricWasCreatedEvent.php b/app/Bus/Events/Metric/MetricWasCreatedEvent.php
new file mode 100644
index 000000000000..f3e123b8e5c2
--- /dev/null
+++ b/app/Bus/Events/Metric/MetricWasCreatedEvent.php
@@ -0,0 +1,75 @@
+
+ */
+final class MetricWasCreatedEvent implements ActionInterface, MetricEventInterface
+{
+ /**
+ * The user who added the metric.
+ *
+ * @var \CachetHQ\Cachet\Models\User
+ */
+ public $user;
+
+ /**
+ * The metric that was added.
+ *
+ * @var \CachetHQ\Cachet\Models\Metric
+ */
+ public $metric;
+
+ /**
+ * Create a new metric was added event instance.
+ *
+ * @param \CachetHQ\Cachet\Models\User $user
+ * @param \CachetHQ\Cachet\Models\Metric $metric
+ *
+ * @return void
+ */
+ public function __construct(User $user, Metric $metric)
+ {
+ $this->user = $user;
+ $this->metric = $metric;
+ }
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'Metric was added.';
+ }
+
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction()
+ {
+ return [
+ 'user' => $this->user,
+ 'description' => (string) $this,
+ ];
+ }
+}
diff --git a/app/Bus/Events/Metric/MetricWasRemovedEvent.php b/app/Bus/Events/Metric/MetricWasRemovedEvent.php
index 67061cf11d61..7193f307f957 100644
--- a/app/Bus/Events/Metric/MetricWasRemovedEvent.php
+++ b/app/Bus/Events/Metric/MetricWasRemovedEvent.php
@@ -11,10 +11,19 @@
namespace CachetHQ\Cachet\Bus\Events\Metric;
+use CachetHQ\Cachet\Bus\Events\ActionInterface;
use CachetHQ\Cachet\Models\Metric;
+use CachetHQ\Cachet\Models\User;
-final class MetricWasRemovedEvent implements MetricEventInterface
+final class MetricWasRemovedEvent implements ActionInterface, MetricEventInterface
{
+ /**
+ * The user who removed the metric.
+ *
+ * @var \CachetHQ\Cachet\Models\User
+ */
+ public $user;
+
/**
* The metric that was removed.
*
@@ -25,12 +34,37 @@ final class MetricWasRemovedEvent implements MetricEventInterface
/**
* Create a new metric was removed event instance.
*
+ * @param \CachetHQ\Cachet\Models\User $user
* @param \CachetHQ\Cachet\Models\Metric $metric
*
* @return void
*/
- public function __construct(Metric $metric)
+ public function __construct(User $user, Metric $metric)
{
+ $this->user = $user;
$this->metric = $metric;
}
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'Metric was removed.';
+ }
+
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction()
+ {
+ return [
+ 'user' => $this->user,
+ 'description' => (string) $this,
+ ];
+ }
}
diff --git a/app/Bus/Events/Metric/MetricWasUpdatedEvent.php b/app/Bus/Events/Metric/MetricWasUpdatedEvent.php
index dd400eb33af9..48b1dc9cc6a7 100644
--- a/app/Bus/Events/Metric/MetricWasUpdatedEvent.php
+++ b/app/Bus/Events/Metric/MetricWasUpdatedEvent.php
@@ -11,10 +11,19 @@
namespace CachetHQ\Cachet\Bus\Events\Metric;
+use CachetHQ\Cachet\Bus\Events\ActionInterface;
use CachetHQ\Cachet\Models\Metric;
+use CachetHQ\Cachet\Models\User;
-final class MetricWasUpdatedEvent implements MetricEventInterface
+final class MetricWasUpdatedEvent implements ActionInterface, MetricEventInterface
{
+ /**
+ * The user who update the metric.
+ *
+ * @var \CachetHQ\Cachet\Models\User
+ */
+ public $user;
+
/**
* The metric that was updated.
*
@@ -25,12 +34,37 @@ final class MetricWasUpdatedEvent implements MetricEventInterface
/**
* Create a new metric was updated event instance.
*
+ * @param \CachetHQ\Cachet\Models\User $user
* @param \CachetHQ\Cachet\Models\Metric $metric
*
* @return void
*/
- public function __construct(Metric $metric)
+ public function __construct(User $user, Metric $metric)
{
+ $this->user = $user;
$this->metric = $metric;
}
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'Metric was updated.';
+ }
+
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction()
+ {
+ return [
+ 'user' => $this->user,
+ 'description' => (string) $this,
+ ];
+ }
}
diff --git a/app/Bus/Events/Schedule/ScheduleEventInterface.php b/app/Bus/Events/Schedule/ScheduleEventInterface.php
new file mode 100644
index 000000000000..cd23ed511bc6
--- /dev/null
+++ b/app/Bus/Events/Schedule/ScheduleEventInterface.php
@@ -0,0 +1,24 @@
+
+ */
+interface ScheduleEventInterface extends EventInterface
+{
+ //
+}
diff --git a/app/Bus/Events/Schedule/ScheduleWasCreatedEvent.php b/app/Bus/Events/Schedule/ScheduleWasCreatedEvent.php
new file mode 100644
index 000000000000..2438658d71be
--- /dev/null
+++ b/app/Bus/Events/Schedule/ScheduleWasCreatedEvent.php
@@ -0,0 +1,84 @@
+
+ */
+final class ScheduleWasCreatedEvent implements ActionInterface, ScheduleEventInterface
+{
+ /**
+ * The user that created the schedule.
+ *
+ * @var \CachetHQ\Cachet\Models\User
+ */
+ public $user;
+
+ /**
+ * The schedule that has been created.
+ *
+ * @var \CachetHQ\Cachet\Models\Schedule
+ */
+ public $schedule;
+
+ /**
+ * Whether to notify that the incident was reported.
+ *
+ * @var bool
+ */
+ public $notify;
+
+ /**
+ * Create a new schedule was created event instance.
+ *
+ * @param \CachetHQ\Cachet\Models\User $user
+ * @param \CachetHQ\Cachet\Models\Schedule $schedule
+ * @param bool notify
+ *
+ * @return void
+ */
+ public function __construct(User $user, Schedule $schedule, $notify = false)
+ {
+ $this->user = $user;
+ $this->schedule = $schedule;
+ $this->notify = $notify;
+ }
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'Schedule was created.';
+ }
+
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction()
+ {
+ return [
+ 'user' => $this->user,
+ 'description' => (string) $this,
+ ];
+ }
+}
diff --git a/app/Bus/Events/Schedule/ScheduleWasRemovedEvent.php b/app/Bus/Events/Schedule/ScheduleWasRemovedEvent.php
new file mode 100644
index 000000000000..525c77f79598
--- /dev/null
+++ b/app/Bus/Events/Schedule/ScheduleWasRemovedEvent.php
@@ -0,0 +1,75 @@
+
+ */
+final class ScheduleWasRemovedEvent implements ActionInterface, ScheduleEventInterface
+{
+ /**
+ * The user that removed the schedule.
+ *
+ * @var \CachetHQ\Cachet\Models\User
+ */
+ public $user;
+
+ /**
+ * The schedule that has been removed.
+ *
+ * @var \CachetHQ\Cachet\Models\Schedule
+ */
+ public $schedule;
+
+ /**
+ * Create a new schedule was removed event instance.
+ *
+ * @param \CachetHQ\Cachet\Models\User $user
+ * @param \CachetHQ\Cachet\Models\Schedule $schedule
+ *
+ * @return void
+ */
+ public function __construct(User $user, Schedule $schedule)
+ {
+ $this->user = $user;
+ $this->schedule = $schedule;
+ }
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'Schedule was removed.';
+ }
+
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction()
+ {
+ return [
+ 'user' => $this->user,
+ 'description' => (string) $this,
+ ];
+ }
+}
diff --git a/app/Bus/Events/Schedule/ScheduleWasUpdatedEvent.php b/app/Bus/Events/Schedule/ScheduleWasUpdatedEvent.php
new file mode 100644
index 000000000000..18fc46aaf5dc
--- /dev/null
+++ b/app/Bus/Events/Schedule/ScheduleWasUpdatedEvent.php
@@ -0,0 +1,75 @@
+
+ */
+final class ScheduleWasUpdatedEvent implements ActionInterface, ScheduleEventInterface
+{
+ /**
+ * The user that created the schedule.
+ *
+ * @var \CachetHQ\Cachet\Models\User
+ */
+ public $user;
+
+ /**
+ * The schedule that has been updated.
+ *
+ * @var \CachetHQ\Cachet\Models\Schedule
+ */
+ public $schedule;
+
+ /**
+ * Create a new schedule was updated event instance.
+ *
+ * @param \CachetHQ\Cachet\Models\User $user
+ * @param \CachetHQ\Cachet\Models\Schedule $schedule
+ *
+ * @return void
+ */
+ public function __construct(User $user, Schedule $schedule)
+ {
+ $this->user = $user;
+ $this->schedule = $schedule;
+ }
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'Schedule was updated.';
+ }
+
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction()
+ {
+ return [
+ 'user' => $this->user,
+ 'description' => (string) $this,
+ ];
+ }
+}
diff --git a/app/Bus/Events/Subscriber/SubscriberEventInterface.php b/app/Bus/Events/Subscriber/SubscriberEventInterface.php
index 24ed5b5af6d7..d8ec141182ee 100644
--- a/app/Bus/Events/Subscriber/SubscriberEventInterface.php
+++ b/app/Bus/Events/Subscriber/SubscriberEventInterface.php
@@ -13,6 +13,12 @@
use CachetHQ\Cachet\Bus\Events\EventInterface;
+/**
+ * This is the subscriber event interface.
+ *
+ * @author Graham Campbell
+ * @author James Brooks
+ */
interface SubscriberEventInterface extends EventInterface
{
//
diff --git a/app/Bus/Events/Subscriber/SubscriberHasSubscribedEvent.php b/app/Bus/Events/Subscriber/SubscriberHasSubscribedEvent.php
index c48668f53e68..2dc68624d195 100644
--- a/app/Bus/Events/Subscriber/SubscriberHasSubscribedEvent.php
+++ b/app/Bus/Events/Subscriber/SubscriberHasSubscribedEvent.php
@@ -33,4 +33,14 @@ public function __construct(Subscriber $subscriber)
{
$this->subscriber = $subscriber;
}
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'Subscriber has subscribed.';
+ }
}
diff --git a/app/Bus/Events/Subscriber/SubscriberHasUnsubscribedEvent.php b/app/Bus/Events/Subscriber/SubscriberHasUnsubscribedEvent.php
index 2d35fc2a3ee0..4e67f5c88837 100644
--- a/app/Bus/Events/Subscriber/SubscriberHasUnsubscribedEvent.php
+++ b/app/Bus/Events/Subscriber/SubscriberHasUnsubscribedEvent.php
@@ -33,4 +33,14 @@ public function __construct(Subscriber $subscriber)
{
$this->subscriber = $subscriber;
}
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'Subscriber has unsubscribed.';
+ }
}
diff --git a/app/Bus/Events/Subscriber/SubscriberHasUpdatedSubscriptionsEvent.php b/app/Bus/Events/Subscriber/SubscriberHasUpdatedSubscriptionsEvent.php
index 12f6e1ec195f..8f6c71b8bd47 100644
--- a/app/Bus/Events/Subscriber/SubscriberHasUpdatedSubscriptionsEvent.php
+++ b/app/Bus/Events/Subscriber/SubscriberHasUpdatedSubscriptionsEvent.php
@@ -38,4 +38,14 @@ public function __construct(Subscriber $subscriber)
{
$this->subscriber = $subscriber;
}
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'Subscriber has updated subscription.';
+ }
}
diff --git a/app/Bus/Events/Subscriber/SubscriberHasVerifiedEvent.php b/app/Bus/Events/Subscriber/SubscriberHasVerifiedEvent.php
index b0ed5a7d26ee..b621dda139fc 100644
--- a/app/Bus/Events/Subscriber/SubscriberHasVerifiedEvent.php
+++ b/app/Bus/Events/Subscriber/SubscriberHasVerifiedEvent.php
@@ -33,4 +33,14 @@ public function __construct(Subscriber $subscriber)
{
$this->subscriber = $subscriber;
}
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'Subscriber has verified.';
+ }
}
diff --git a/app/Bus/Events/System/SystemCheckedForUpdatesEvent.php b/app/Bus/Events/System/SystemCheckedForUpdatesEvent.php
index e8da9d00504e..98481777d9ef 100644
--- a/app/Bus/Events/System/SystemCheckedForUpdatesEvent.php
+++ b/app/Bus/Events/System/SystemCheckedForUpdatesEvent.php
@@ -18,5 +18,13 @@
*/
final class SystemCheckedForUpdatesEvent implements SystemEventInterface
{
- //
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'System checked for updated.';
+ }
}
diff --git a/app/Bus/Events/System/SystemWasInstalledEvent.php b/app/Bus/Events/System/SystemWasInstalledEvent.php
index 6f333f7c27d9..cfc47ea2fc00 100644
--- a/app/Bus/Events/System/SystemWasInstalledEvent.php
+++ b/app/Bus/Events/System/SystemWasInstalledEvent.php
@@ -18,5 +18,13 @@
*/
final class SystemWasInstalledEvent implements SystemEventInterface
{
- //
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'System was installed.';
+ }
}
diff --git a/app/Bus/Events/System/SystemWasResetEvent.php b/app/Bus/Events/System/SystemWasResetEvent.php
index a2146c88b727..b96763f401fd 100644
--- a/app/Bus/Events/System/SystemWasResetEvent.php
+++ b/app/Bus/Events/System/SystemWasResetEvent.php
@@ -18,5 +18,13 @@
*/
final class SystemWasResetEvent implements SystemEventInterface
{
- //
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'System was reset.';
+ }
}
diff --git a/app/Bus/Events/System/SystemWasUpdatedEvent.php b/app/Bus/Events/System/SystemWasUpdatedEvent.php
index 5157288819d2..faf0cf07e1a5 100644
--- a/app/Bus/Events/System/SystemWasUpdatedEvent.php
+++ b/app/Bus/Events/System/SystemWasUpdatedEvent.php
@@ -18,5 +18,13 @@
*/
final class SystemWasUpdatedEvent implements SystemEventInterface
{
- //
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'System was updated.';
+ }
}
diff --git a/app/Bus/Events/User/UserAcceptedInviteEvent.php b/app/Bus/Events/User/UserAcceptedInviteEvent.php
new file mode 100644
index 000000000000..6148c3dc62d8
--- /dev/null
+++ b/app/Bus/Events/User/UserAcceptedInviteEvent.php
@@ -0,0 +1,75 @@
+
+ */
+final class UserAcceptedInviteEvent implements ActionInterface, UserEventInterface
+{
+ /**
+ * The user that accepted the invite.
+ *
+ * @var \CachetHQ\Cachet\Models\User
+ */
+ public $user;
+
+ /**
+ * The invite that the user accepted.
+ *
+ * @var \CachetHQ\Cachet\Models\Invite
+ */
+ public $invite;
+
+ /**
+ * Create a new user accepted invite event class.
+ *
+ * @param \CachetHQ\Cachet\Models\User $user
+ * @param \CachetHQ\Cachet\Models\Invite $invite
+ *
+ * @return void
+ */
+ public function __construct(User $user, Invite $invite)
+ {
+ $this->user = $user;
+ $this->invite = $invite;
+ }
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'User accepted invite.';
+ }
+
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction()
+ {
+ return [
+ 'user' => $this->user,
+ 'description' => (string) $this,
+ ];
+ }
+}
diff --git a/app/Bus/Events/User/UserDisabledTwoAuthEvent.php b/app/Bus/Events/User/UserDisabledTwoAuthEvent.php
index 22316bdac13d..a7646dbaae78 100644
--- a/app/Bus/Events/User/UserDisabledTwoAuthEvent.php
+++ b/app/Bus/Events/User/UserDisabledTwoAuthEvent.php
@@ -11,6 +11,7 @@
namespace CachetHQ\Cachet\Bus\Events\User;
+use CachetHQ\Cachet\Bus\Events\ActionInterface;
use CachetHQ\Cachet\Models\User;
/**
@@ -18,7 +19,7 @@
*
* @author James Brooks
*/
-final class UserDisabledTwoAuthEvent implements UserEventInterface
+final class UserDisabledTwoAuthEvent implements ActionInterface, UserEventInterface
{
/**
* The user that disabled two auth.
@@ -38,4 +39,27 @@ public function __construct(User $user)
{
$this->user = $user;
}
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'User disabled two-factor authentication.';
+ }
+
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction()
+ {
+ return [
+ 'user' => $this->user,
+ 'description' => (string) $this,
+ ];
+ }
}
diff --git a/app/Bus/Events/User/UserEnabledTwoAuthEvent.php b/app/Bus/Events/User/UserEnabledTwoAuthEvent.php
index ad3a56b77d37..9a13d045d303 100644
--- a/app/Bus/Events/User/UserEnabledTwoAuthEvent.php
+++ b/app/Bus/Events/User/UserEnabledTwoAuthEvent.php
@@ -11,6 +11,7 @@
namespace CachetHQ\Cachet\Bus\Events\User;
+use CachetHQ\Cachet\Bus\Events\ActionInterface;
use CachetHQ\Cachet\Models\User;
/**
@@ -18,7 +19,7 @@
*
* @author James Brooks
*/
-final class UserEnabledTwoAuthEvent implements UserEventInterface
+final class UserEnabledTwoAuthEvent implements ActionInterface, UserEventInterface
{
/**
* The user that enabled two auth.
@@ -38,4 +39,27 @@ public function __construct(User $user)
{
$this->user = $user;
}
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'User enabled two-factor authentication.';
+ }
+
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction()
+ {
+ return [
+ 'user' => $this->user,
+ 'description' => (string) $this,
+ ];
+ }
}
diff --git a/app/Bus/Events/User/UserEventInterface.php b/app/Bus/Events/User/UserEventInterface.php
index f36a4819a54f..be886a83430c 100644
--- a/app/Bus/Events/User/UserEventInterface.php
+++ b/app/Bus/Events/User/UserEventInterface.php
@@ -13,6 +13,12 @@
use CachetHQ\Cachet\Bus\Events\EventInterface;
+/**
+ * This is the user event interface.
+ *
+ * @author Graham Campbell
+ * @author James Brooks
+ */
interface UserEventInterface extends EventInterface
{
//
diff --git a/app/Bus/Events/User/UserFailedTwoAuthEvent.php b/app/Bus/Events/User/UserFailedTwoAuthEvent.php
index c416e317e175..6fa1b015375c 100644
--- a/app/Bus/Events/User/UserFailedTwoAuthEvent.php
+++ b/app/Bus/Events/User/UserFailedTwoAuthEvent.php
@@ -11,6 +11,7 @@
namespace CachetHQ\Cachet\Bus\Events\User;
+use CachetHQ\Cachet\Bus\Events\ActionInterface;
use CachetHQ\Cachet\Models\User;
/**
@@ -18,7 +19,7 @@
*
* @author James Brooks
*/
-final class UserFailedTwoAuthEvent implements UserEventInterface
+final class UserFailedTwoAuthEvent implements ActionInterface, UserEventInterface
{
/**
* The user that failed two auth.
@@ -38,4 +39,27 @@ public function __construct(User $user)
{
$this->user = $user;
}
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'User failed two-factor authentication.';
+ }
+
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction()
+ {
+ return [
+ 'user' => $this->user,
+ 'description' => (string) $this,
+ ];
+ }
}
diff --git a/app/Bus/Events/User/UserLoggedInEvent.php b/app/Bus/Events/User/UserLoggedInEvent.php
index a10d1547881a..06aafe4419dc 100644
--- a/app/Bus/Events/User/UserLoggedInEvent.php
+++ b/app/Bus/Events/User/UserLoggedInEvent.php
@@ -11,6 +11,7 @@
namespace CachetHQ\Cachet\Bus\Events\User;
+use CachetHQ\Cachet\Bus\Events\ActionInterface;
use CachetHQ\Cachet\Models\User;
/**
@@ -18,7 +19,7 @@
*
* @author James Brooks
*/
-final class UserLoggedInEvent implements UserEventInterface
+final class UserLoggedInEvent implements ActionInterface, UserEventInterface
{
/**
* The user that logged in.
@@ -38,4 +39,27 @@ public function __construct(User $user)
{
$this->user = $user;
}
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'User logged in.';
+ }
+
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction()
+ {
+ return [
+ 'user' => $this->user,
+ 'description' => (string) $this,
+ ];
+ }
}
diff --git a/app/Bus/Events/User/UserLoggedOutEvent.php b/app/Bus/Events/User/UserLoggedOutEvent.php
index 9c51c6e3fd03..98370606befb 100644
--- a/app/Bus/Events/User/UserLoggedOutEvent.php
+++ b/app/Bus/Events/User/UserLoggedOutEvent.php
@@ -11,6 +11,7 @@
namespace CachetHQ\Cachet\Bus\Events\User;
+use CachetHQ\Cachet\Bus\Events\ActionInterface;
use CachetHQ\Cachet\Models\User;
/**
@@ -18,7 +19,7 @@
*
* @author James Brooks
*/
-final class UserLoggedOutEvent implements UserEventInterface
+final class UserLoggedOutEvent implements ActionInterface, UserEventInterface
{
/**
* The user that logged out.
@@ -38,4 +39,27 @@ public function __construct(User $user)
{
$this->user = $user;
}
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'User logged out.';
+ }
+
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction()
+ {
+ return [
+ 'user' => $this->user,
+ 'description' => (string) $this,
+ ];
+ }
}
diff --git a/app/Bus/Events/User/UserPassedTwoAuthEvent.php b/app/Bus/Events/User/UserPassedTwoAuthEvent.php
index be775510e277..640938e5a682 100644
--- a/app/Bus/Events/User/UserPassedTwoAuthEvent.php
+++ b/app/Bus/Events/User/UserPassedTwoAuthEvent.php
@@ -11,6 +11,7 @@
namespace CachetHQ\Cachet\Bus\Events\User;
+use CachetHQ\Cachet\Bus\Events\ActionInterface;
use CachetHQ\Cachet\Models\User;
/**
@@ -18,7 +19,7 @@
*
* @author James Brooks
*/
-final class UserPassedTwoAuthEvent implements UserEventInterface
+final class UserPassedTwoAuthEvent implements ActionInterface, UserEventInterface
{
/**
* The user that passed two auth.
@@ -38,4 +39,27 @@ public function __construct(User $user)
{
$this->user = $user;
}
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'User passed two-factor authentication.';
+ }
+
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction()
+ {
+ return [
+ 'user' => $this->user,
+ 'description' => (string) $this,
+ ];
+ }
}
diff --git a/app/Bus/Events/User/UserRegeneratedApiTokenEvent.php b/app/Bus/Events/User/UserRegeneratedApiTokenEvent.php
index 4797608f33c9..6dee91094fcd 100644
--- a/app/Bus/Events/User/UserRegeneratedApiTokenEvent.php
+++ b/app/Bus/Events/User/UserRegeneratedApiTokenEvent.php
@@ -11,6 +11,7 @@
namespace CachetHQ\Cachet\Bus\Events\User;
+use CachetHQ\Cachet\Bus\Events\ActionInterface;
use CachetHQ\Cachet\Models\User;
/**
@@ -18,7 +19,7 @@
*
* @author James Brooks
*/
-final class UserRegeneratedApiTokenEvent implements UserEventInterface
+final class UserRegeneratedApiTokenEvent implements ActionInterface, UserEventInterface
{
/**
* The user that regenerated their api token.
@@ -38,4 +39,27 @@ public function __construct(User $user)
{
$this->user = $user;
}
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'User regenerated api token.';
+ }
+
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction()
+ {
+ return [
+ 'user' => $this->user,
+ 'description' => (string) $this,
+ ];
+ }
}
diff --git a/app/Bus/Events/User/UserWasAddedEvent.php b/app/Bus/Events/User/UserWasCreatedEvent.php
similarity index 51%
rename from app/Bus/Events/User/UserWasAddedEvent.php
rename to app/Bus/Events/User/UserWasCreatedEvent.php
index fffe48fb7cef..a013352a583b 100644
--- a/app/Bus/Events/User/UserWasAddedEvent.php
+++ b/app/Bus/Events/User/UserWasCreatedEvent.php
@@ -11,9 +11,15 @@
namespace CachetHQ\Cachet\Bus\Events\User;
+use CachetHQ\Cachet\Bus\Events\ActionInterface;
use CachetHQ\Cachet\Models\User;
-final class UserWasAddedEvent implements UserEventInterface
+/**
+ * This is the user was created event class.
+ *
+ * @author James Brooks
+ */
+final class UserWasCreatedEvent implements ActionInterface, UserEventInterface
{
/**
* The user that has been added.
@@ -33,4 +39,27 @@ public function __construct(User $user)
{
$this->user = $user;
}
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'User was created.';
+ }
+
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction()
+ {
+ return [
+ 'user' => $this->user,
+ 'description' => (string) $this,
+ ];
+ }
}
diff --git a/app/Bus/Events/User/UserWasInvitedEvent.php b/app/Bus/Events/User/UserWasInvitedEvent.php
index 4bcada2f5d6d..c2a65db9c181 100644
--- a/app/Bus/Events/User/UserWasInvitedEvent.php
+++ b/app/Bus/Events/User/UserWasInvitedEvent.php
@@ -13,10 +13,17 @@
use CachetHQ\Cachet\Models\Invite;
+/**
+ * This is the user was invited event class.
+ *
+ * @author Joseph Cohen
+ * @author Graham Campbell
+ * @author James Brooks
+ */
final class UserWasInvitedEvent implements UserEventInterface
{
/**
- * The invite that has been added.
+ * The invite that has been created.
*
* @var \CachetHQ\Cachet\Models\Invite
*/
@@ -33,4 +40,14 @@ public function __construct(Invite $invite)
{
$this->invite = $invite;
}
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'User was invited.';
+ }
}
diff --git a/app/Bus/Events/User/UserWasRemovedEvent.php b/app/Bus/Events/User/UserWasRemovedEvent.php
index d7504e495efd..d44213403e51 100644
--- a/app/Bus/Events/User/UserWasRemovedEvent.php
+++ b/app/Bus/Events/User/UserWasRemovedEvent.php
@@ -11,9 +11,10 @@
namespace CachetHQ\Cachet\Bus\Events\User;
+use CachetHQ\Cachet\Bus\Events\ActionInterface;
use CachetHQ\Cachet\Models\User;
-final class UserWasRemovedEvent implements UserEventInterface
+final class UserWasRemovedEvent implements ActionInterface, UserEventInterface
{
/**
* The user that has been removed.
@@ -33,4 +34,27 @@ public function __construct(User $user)
{
$this->user = $user;
}
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'User was removed.';
+ }
+
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction()
+ {
+ return [
+ 'user' => $this->user,
+ 'description' => (string) $this,
+ ];
+ }
}
diff --git a/app/Bus/Events/User/UserWasWelcomedEvent.php b/app/Bus/Events/User/UserWasWelcomedEvent.php
index a2f052d7a021..3f163cc5b6a1 100644
--- a/app/Bus/Events/User/UserWasWelcomedEvent.php
+++ b/app/Bus/Events/User/UserWasWelcomedEvent.php
@@ -11,6 +11,7 @@
namespace CachetHQ\Cachet\Bus\Events\User;
+use CachetHQ\Cachet\Bus\Events\ActionInterface;
use CachetHQ\Cachet\Models\User;
/**
@@ -18,7 +19,7 @@
*
* @author James Brooks
*/
-final class UserWasWelcomedEvent implements UserEventInterface
+final class UserWasWelcomedEvent implements ActionInterface, UserEventInterface
{
/**
* The user.
@@ -38,4 +39,27 @@ public function __construct(User $user)
{
$this->user = $user;
}
+
+ /**
+ * Get the event description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'User was welcomed.';
+ }
+
+ /**
+ * Get the event action.
+ *
+ * @return array
+ */
+ public function getAction()
+ {
+ return [
+ 'user' => $this->user,
+ 'description' => (string) $this,
+ ];
+ }
}
diff --git a/app/Bus/Exceptions/Component/ComponentExceptionInterface.php b/app/Bus/Exceptions/Component/ComponentExceptionInterface.php
new file mode 100644
index 000000000000..211d81f7a71b
--- /dev/null
+++ b/app/Bus/Exceptions/Component/ComponentExceptionInterface.php
@@ -0,0 +1,24 @@
+
+ */
+interface ComponentExceptionInterface extends ExceptionInterface
+{
+ //
+}
diff --git a/app/Bus/Exceptions/ComponentGroup/ComponentGroup.php b/app/Bus/Exceptions/ComponentGroup/ComponentGroup.php
new file mode 100644
index 000000000000..8ca6edd05ee2
--- /dev/null
+++ b/app/Bus/Exceptions/ComponentGroup/ComponentGroup.php
@@ -0,0 +1,24 @@
+
+ */
+interface ComponentGroup extends ExceptionInterface
+{
+ //
+}
diff --git a/app/Bus/Exceptions/Incident/IncidentExceptionInterface.php b/app/Bus/Exceptions/Incident/IncidentExceptionInterface.php
new file mode 100644
index 000000000000..f6aa9be71dac
--- /dev/null
+++ b/app/Bus/Exceptions/Incident/IncidentExceptionInterface.php
@@ -0,0 +1,24 @@
+
+ */
+interface IncidentExceptionInterface extends ExceptionInterface
+{
+ //
+}
diff --git a/app/Bus/Exceptions/Incident/InvalidIncidentTimestampException.php b/app/Bus/Exceptions/Incident/InvalidIncidentTimestampException.php
new file mode 100644
index 000000000000..8d5d8708cd03
--- /dev/null
+++ b/app/Bus/Exceptions/Incident/InvalidIncidentTimestampException.php
@@ -0,0 +1,24 @@
+
+ */
+class InvalidIncidentTimestampException extends Exception implements IncidentExceptionInterface
+{
+ //
+}
diff --git a/app/Bus/Exceptions/IncidentUpdate/IncidentUpdateExceptionInterface.php b/app/Bus/Exceptions/IncidentUpdate/IncidentUpdateExceptionInterface.php
new file mode 100644
index 000000000000..3abb87db89f2
--- /dev/null
+++ b/app/Bus/Exceptions/IncidentUpdate/IncidentUpdateExceptionInterface.php
@@ -0,0 +1,24 @@
+
+ */
+interface IncidentUpdateExceptionInterface extends ExceptionInterface
+{
+ //
+}
diff --git a/app/Bus/Exceptions/Metric/MetricExceptionInterface.php b/app/Bus/Exceptions/Metric/MetricExceptionInterface.php
new file mode 100644
index 000000000000..51dd0f448601
--- /dev/null
+++ b/app/Bus/Exceptions/Metric/MetricExceptionInterface.php
@@ -0,0 +1,24 @@
+
+ */
+interface MetricExceptionInterface extends ExceptionInterface
+{
+ //
+}
diff --git a/app/Bus/Exceptions/MetricPoint/MetricPointExceptionInterface.php b/app/Bus/Exceptions/MetricPoint/MetricPointExceptionInterface.php
new file mode 100644
index 000000000000..a0fe628cfa0f
--- /dev/null
+++ b/app/Bus/Exceptions/MetricPoint/MetricPointExceptionInterface.php
@@ -0,0 +1,24 @@
+
+ */
+interface MetricPointExceptionInterface extends ExceptionInterface
+{
+ //
+}
diff --git a/app/Bus/Exceptions/Schedule/ScheduleExceptionInterface.php b/app/Bus/Exceptions/Schedule/ScheduleExceptionInterface.php
new file mode 100644
index 000000000000..61059820f368
--- /dev/null
+++ b/app/Bus/Exceptions/Schedule/ScheduleExceptionInterface.php
@@ -0,0 +1,24 @@
+
+ */
+interface ScheduleExceptionInterface extends ExceptionInterface
+{
+ //
+}
diff --git a/app/Bus/Exceptions/Subscriber/SubscriberExceptionInterface.php b/app/Bus/Exceptions/Subscriber/SubscriberExceptionInterface.php
new file mode 100644
index 000000000000..afee3735b88e
--- /dev/null
+++ b/app/Bus/Exceptions/Subscriber/SubscriberExceptionInterface.php
@@ -0,0 +1,24 @@
+
+ */
+interface SubscriberExceptionInterface extends ExceptionInterface
+{
+ //
+}
diff --git a/app/Bus/Exceptions/User/UserExceptionInterface.php b/app/Bus/Exceptions/User/UserExceptionInterface.php
new file mode 100644
index 000000000000..e0b3d8aed1cf
--- /dev/null
+++ b/app/Bus/Exceptions/User/UserExceptionInterface.php
@@ -0,0 +1,24 @@
+
+ */
+interface UserExceptionInterface extends ExceptionInterface
+{
+ //
+}
diff --git a/app/Bus/Handlers/Commands/Component/AddComponentCommandHandler.php b/app/Bus/Handlers/Commands/Component/AddComponentCommandHandler.php
deleted file mode 100644
index 538d6391912e..000000000000
--- a/app/Bus/Handlers/Commands/Component/AddComponentCommandHandler.php
+++ /dev/null
@@ -1,59 +0,0 @@
-filter($command));
-
- event(new ComponentWasAddedEvent($component));
-
- return $component;
- }
-
- /**
- * Filter the command data.
- *
- * @param \CachetHQ\Cachet\Bus\Commands\Incident\AddComponentCommand $command
- *
- * @return array
- */
- protected function filter(AddComponentCommand $command)
- {
- $params = [
- 'name' => $command->name,
- 'description' => $command->description,
- 'link' => $command->link,
- 'status' => $command->status,
- 'enabled' => $command->enabled,
- 'order' => $command->order,
- 'group_id' => $command->group_id,
- ];
-
- return array_filter($params, function ($val) {
- return $val !== null;
- });
- }
-}
diff --git a/app/Bus/Handlers/Commands/Component/CreateComponentCommandHandler.php b/app/Bus/Handlers/Commands/Component/CreateComponentCommandHandler.php
new file mode 100644
index 000000000000..867f49fbeaa4
--- /dev/null
+++ b/app/Bus/Handlers/Commands/Component/CreateComponentCommandHandler.php
@@ -0,0 +1,94 @@
+
+ */
+class CreateComponentCommandHandler
+{
+ /**
+ * The authentication guard instance.
+ *
+ * @var \Illuminate\Contracts\Auth\Guard
+ */
+ protected $auth;
+
+ /**
+ * Create a new remove component command handler instance.
+ *
+ * @param \Illuminate\Contracts\Auth\Guard $auth
+ *
+ * @return void
+ */
+ public function __construct(Guard $auth)
+ {
+ $this->auth = $auth;
+ }
+
+ /**
+ * Handle the add component command.
+ *
+ * @param \CachetHQ\Cachet\Bus\Commands\Component\CreateComponentCommand $command
+ *
+ * @return \CachetHQ\Cachet\Models\Component
+ */
+ public function handle(CreateComponentCommand $command)
+ {
+ $component = Component::create($this->filter($command));
+
+ // Sync the tags into the component.
+ if ($command->tags) {
+ collect(preg_split('/ ?, ?/', $command->tags))->filter()->map(function ($tag) {
+ return trim($tag);
+ })->pipe(function ($tags) use ($component) {
+ $component->attachTags($tags);
+ });
+ }
+
+ event(new ComponentWasCreatedEvent($this->auth->user(), $component));
+
+ return $component;
+ }
+
+ /**
+ * Filter the command data.
+ *
+ * @param \CachetHQ\Cachet\Bus\Commands\Component\CreateComponentCommand $command
+ *
+ * @return array
+ */
+ protected function filter(CreateComponentCommand $command)
+ {
+ $params = [
+ 'name' => $command->name,
+ 'description' => $command->description,
+ 'link' => $command->link,
+ 'status' => $command->status,
+ 'enabled' => $command->enabled,
+ 'order' => $command->order,
+ 'group_id' => $command->group_id,
+ 'meta' => $command->meta,
+ ];
+
+ return array_filter($params, function ($val) {
+ return $val !== null;
+ });
+ }
+}
diff --git a/app/Bus/Handlers/Commands/Component/RemoveComponentCommandHandler.php b/app/Bus/Handlers/Commands/Component/RemoveComponentCommandHandler.php
index 80451e2753d3..78e0acd71911 100644
--- a/app/Bus/Handlers/Commands/Component/RemoveComponentCommandHandler.php
+++ b/app/Bus/Handlers/Commands/Component/RemoveComponentCommandHandler.php
@@ -13,9 +13,29 @@
use CachetHQ\Cachet\Bus\Commands\Component\RemoveComponentCommand;
use CachetHQ\Cachet\Bus\Events\Component\ComponentWasRemovedEvent;
+use Illuminate\Contracts\Auth\Guard;
class RemoveComponentCommandHandler
{
+ /**
+ * The authentication guard instance.
+ *
+ * @var \Illuminate\Contracts\Auth\Guard
+ */
+ protected $auth;
+
+ /**
+ * Create a new remove component command handler instance.
+ *
+ * @param \Illuminate\Contracts\Auth\Guard $auth
+ *
+ * @return void
+ */
+ public function __construct(Guard $auth)
+ {
+ $this->auth = $auth;
+ }
+
/**
* Handle the remove component command.
*
@@ -27,7 +47,7 @@ public function handle(RemoveComponentCommand $command)
{
$component = $command->component;
- event(new ComponentWasRemovedEvent($component));
+ event(new ComponentWasRemovedEvent($this->auth->user(), $component));
$component->delete();
}
diff --git a/app/Bus/Handlers/Commands/Component/UpdateComponentCommandHandler.php b/app/Bus/Handlers/Commands/Component/UpdateComponentCommandHandler.php
index bdead38f39c5..f0ad1e44faab 100644
--- a/app/Bus/Handlers/Commands/Component/UpdateComponentCommandHandler.php
+++ b/app/Bus/Handlers/Commands/Component/UpdateComponentCommandHandler.php
@@ -12,12 +12,32 @@
namespace CachetHQ\Cachet\Bus\Handlers\Commands\Component;
use CachetHQ\Cachet\Bus\Commands\Component\UpdateComponentCommand;
-use CachetHQ\Cachet\Bus\Events\Component\ComponentStatusWasUpdatedEvent;
+use CachetHQ\Cachet\Bus\Events\Component\ComponentStatusWasChangedEvent;
use CachetHQ\Cachet\Bus\Events\Component\ComponentWasUpdatedEvent;
use CachetHQ\Cachet\Models\Component;
+use Illuminate\Contracts\Auth\Guard;
class UpdateComponentCommandHandler
{
+ /**
+ * The authentication guard instance.
+ *
+ * @var \Illuminate\Contracts\Auth\Guard
+ */
+ protected $auth;
+
+ /**
+ * Create a new update component command handler instance.
+ *
+ * @param \Illuminate\Contracts\Auth\Guard $auth
+ *
+ * @return void
+ */
+ public function __construct(Guard $auth)
+ {
+ $this->auth = $auth;
+ }
+
/**
* Handle the update component command.
*
@@ -28,14 +48,24 @@ class UpdateComponentCommandHandler
public function handle(UpdateComponentCommand $command)
{
$component = $command->component;
+ $originalStatus = $component->status;
- if ($command->status && $component->status !== $command->status) {
- event(new ComponentStatusWasUpdatedEvent($component, $component->status, $command->status));
+ if ($command->status && (int) $originalStatus !== (int) $command->status) {
+ event(new ComponentStatusWasChangedEvent($this->auth->user(), $component, $originalStatus, $command->status, $command->silent));
}
$component->update($this->filter($command));
- event(new ComponentWasUpdatedEvent($component));
+ // Sync the tags into the component.
+ if ($command->tags) {
+ collect(preg_split('/ ?, ?/', $command->tags))->filter()->map(function ($tag) {
+ return trim($tag);
+ })->pipe(function ($tags) use ($component) {
+ $component->syncTags($tags);
+ });
+ }
+
+ event(new ComponentWasUpdatedEvent($this->auth->user(), $component));
return $component;
}
@@ -43,7 +73,7 @@ public function handle(UpdateComponentCommand $command)
/**
* Filter the command data.
*
- * @param \CachetHQ\Cachet\Bus\Commands\Incident\UpdateComponentCommand $command
+ * @param \CachetHQ\Cachet\Bus\Commands\Component\UpdateComponentCommand $command
*
* @return array
*/
@@ -57,6 +87,7 @@ protected function filter(UpdateComponentCommand $command)
'enabled' => $command->enabled,
'order' => $command->order,
'group_id' => $command->group_id,
+ 'meta' => $command->meta,
];
return array_filter($params, function ($val) {
diff --git a/app/Bus/Handlers/Commands/ComponentGroup/AddComponentGroupCommandHandler.php b/app/Bus/Handlers/Commands/ComponentGroup/AddComponentGroupCommandHandler.php
deleted file mode 100644
index 9066df512436..000000000000
--- a/app/Bus/Handlers/Commands/ComponentGroup/AddComponentGroupCommandHandler.php
+++ /dev/null
@@ -1,39 +0,0 @@
- $command->name,
- 'order' => $command->order,
- 'collapsed' => $command->collapsed,
- ]);
-
- event(new ComponentGroupWasAddedEvent($group));
-
- return $group;
- }
-}
diff --git a/app/Bus/Handlers/Commands/ComponentGroup/CreateComponentGroupCommandHandler.php b/app/Bus/Handlers/Commands/ComponentGroup/CreateComponentGroupCommandHandler.php
new file mode 100644
index 000000000000..2169025baab7
--- /dev/null
+++ b/app/Bus/Handlers/Commands/ComponentGroup/CreateComponentGroupCommandHandler.php
@@ -0,0 +1,60 @@
+auth = $auth;
+ }
+
+ /**
+ * Handle the create component group command.
+ *
+ * @param \CachetHQ\Cachet\Bus\Commands\ComponentGroup\CreateComponentGroupCommand $command
+ *
+ * @return \CachetHQ\Cachet\Models\ComponentGroup
+ */
+ public function handle(CreateComponentGroupCommand $command)
+ {
+ $group = ComponentGroup::create([
+ 'name' => $command->name,
+ 'order' => $command->order,
+ 'collapsed' => $command->collapsed,
+ 'visible' => $command->visible,
+ ]);
+
+ event(new ComponentGroupWasCreatedEvent($this->auth->user(), $group));
+
+ return $group;
+ }
+}
diff --git a/app/Bus/Handlers/Commands/ComponentGroup/RemoveComponentGroupCommandHandler.php b/app/Bus/Handlers/Commands/ComponentGroup/RemoveComponentGroupCommandHandler.php
index d74301494f5e..eef3b14e9304 100644
--- a/app/Bus/Handlers/Commands/ComponentGroup/RemoveComponentGroupCommandHandler.php
+++ b/app/Bus/Handlers/Commands/ComponentGroup/RemoveComponentGroupCommandHandler.php
@@ -13,9 +13,29 @@
use CachetHQ\Cachet\Bus\Commands\ComponentGroup\RemoveComponentGroupCommand;
use CachetHQ\Cachet\Bus\Events\ComponentGroup\ComponentGroupWasRemovedEvent;
+use Illuminate\Contracts\Auth\Guard;
class RemoveComponentGroupCommandHandler
{
+ /**
+ * The authentication guard instance.
+ *
+ * @var \Illuminate\Contracts\Auth\Guard
+ */
+ protected $auth;
+
+ /**
+ * Create a new remove component group command handler instance.
+ *
+ * @param \Illuminate\Contracts\Auth\Guard $auth
+ *
+ * @return void
+ */
+ public function __construct(Guard $auth)
+ {
+ $this->auth = $auth;
+ }
+
/**
* Handle the remove component group command.
*
@@ -27,7 +47,7 @@ public function handle(RemoveComponentGroupCommand $command)
{
$group = $command->group;
- event(new ComponentGroupWasRemovedEvent($group));
+ event(new ComponentGroupWasRemovedEvent($this->auth->user(), $group));
// Remove the group id from all component.
$group->components->map(function ($component) {
diff --git a/app/Bus/Handlers/Commands/ComponentGroup/UpdateComponentGroupCommandHandler.php b/app/Bus/Handlers/Commands/ComponentGroup/UpdateComponentGroupCommandHandler.php
index 4ea401869f49..394b73c93400 100644
--- a/app/Bus/Handlers/Commands/ComponentGroup/UpdateComponentGroupCommandHandler.php
+++ b/app/Bus/Handlers/Commands/ComponentGroup/UpdateComponentGroupCommandHandler.php
@@ -13,9 +13,29 @@
use CachetHQ\Cachet\Bus\Commands\ComponentGroup\UpdateComponentGroupCommand;
use CachetHQ\Cachet\Bus\Events\ComponentGroup\ComponentGroupWasUpdatedEvent;
+use Illuminate\Contracts\Auth\Guard;
class UpdateComponentGroupCommandHandler
{
+ /**
+ * The authentication guard instance.
+ *
+ * @var \Illuminate\Contracts\Auth\Guard
+ */
+ protected $auth;
+
+ /**
+ * Create a new update component command handler instance.
+ *
+ * @param \Illuminate\Contracts\Auth\Guard $auth
+ *
+ * @return void
+ */
+ public function __construct(Guard $auth)
+ {
+ $this->auth = $auth;
+ }
+
/**
* Handle the update component group command.
*
@@ -28,7 +48,7 @@ public function handle(UpdateComponentGroupCommand $command)
$group = $command->group;
$group->update($this->filter($command));
- event(new ComponentGroupWasUpdatedEvent($group));
+ event(new ComponentGroupWasUpdatedEvent($this->auth->user(), $group));
return $group;
}
@@ -46,6 +66,7 @@ protected function filter(UpdateComponentGroupCommand $command)
'name' => $command->name,
'order' => $command->order,
'collapsed' => $command->collapsed,
+ 'visible' => $command->visible,
];
return array_filter($params, function ($val) {
diff --git a/app/Bus/Handlers/Commands/Incident/CreateIncidentCommandHandler.php b/app/Bus/Handlers/Commands/Incident/CreateIncidentCommandHandler.php
new file mode 100644
index 000000000000..2b3bcf77b8be
--- /dev/null
+++ b/app/Bus/Handlers/Commands/Incident/CreateIncidentCommandHandler.php
@@ -0,0 +1,198 @@
+
+ */
+class CreateIncidentCommandHandler
+{
+ use StoresMeta;
+
+ /**
+ * The authentication guard instance.
+ *
+ * @var \Illuminate\Contracts\Auth\Guard
+ */
+ protected $auth;
+
+ /**
+ * The date factory instance.
+ *
+ * @var \CachetHQ\Cachet\Services\Dates\DateFactory
+ */
+ protected $dates;
+
+ protected $twigConfig;
+
+ /**
+ * Create a new create incident command handler instance.
+ *
+ * @param \Illuminate\Contracts\Auth\Guard $auth
+ * @param \CachetHQ\Cachet\Services\Dates\DateFactory $dates
+ *
+ * @return void
+ */
+ public function __construct(Guard $auth, DateFactory $dates)
+ {
+ $this->auth = $auth;
+ $this->dates = $dates;
+
+ $this->twigConfig = config('cachet.twig');
+ }
+
+ /**
+ * Handle the create incident command.
+ *
+ * @param \CachetHQ\Cachet\Bus\Commands\Incident\CreateIncidentCommand $command
+ *
+ * @return \CachetHQ\Cachet\Models\Incident
+ */
+ public function handle(CreateIncidentCommand $command)
+ {
+ $data = [
+ 'user_id' => $this->auth->user()->id,
+ 'name' => $command->name,
+ 'status' => $command->status,
+ 'visible' => $command->visible,
+ 'stickied' => $command->stickied,
+ ];
+
+ if ($template = IncidentTemplate::where('slug', '=', $command->template)->first()) {
+ $data['message'] = $this->parseTemplate($template, $command);
+ } else {
+ $data['message'] = $command->message;
+ }
+
+ // Link with the component.
+ if ($command->component_id) {
+ $data['component_id'] = $command->component_id;
+ }
+
+ // The incident occurred at a different time.
+ if ($occurredAt = $command->occurred_at) {
+ if ($date = $this->dates->create('Y-m-d H:i', $occurredAt)) {
+ $data['occurred_at'] = $date;
+ } else {
+ throw new InvalidIncidentTimestampException("Unable to pass timestamp {$occurredAt}");
+ }
+ } else {
+ $data['occurred_at'] = Carbon::now();
+ }
+
+ // Create the incident
+ $incident = Incident::create($data);
+
+ // Store any meta?
+ if ($meta = $command->meta) {
+ $this->storeMeta($command->meta, 'incidents', $incident->id);
+ }
+
+ // Update the component.
+ if ($component = Component::find($command->component_id)) {
+ execute(new UpdateComponentCommand(
+ Component::find($command->component_id),
+ null,
+ null,
+ $command->component_status,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ true // Silent mode
+ ));
+ }
+
+ event(new IncidentWasCreatedEvent($this->auth->user(), $incident, (bool) $command->notify));
+
+ return $incident;
+ }
+
+ protected function sandboxedTwigTemplateData(string $templateData)
+ {
+ if (!$templateData) {
+ return '';
+ }
+
+ $policy = new \Twig\Sandbox\SecurityPolicy(
+ $this->twigConfig['tags'],
+ $this->twigConfig['filters'],
+ $this->twigConfig['methods'],
+ $this->twigConfig['props'],
+ $this->twigConfig['functions']
+ );
+
+ $sandbox = new \Twig\Extension\SandboxExtension($policy);
+
+ $templateBasicLoader = new Twig_Loader_Array([
+ 'firstStageLoader' => $templateData,
+ ]);
+
+ $sandBoxBasicLoader = new Twig_Loader_Array([
+ 'secondStageLoader' => '{% sandbox %}{% include "firstStageLoader" %} {% endsandbox %}',
+ ]);
+
+ $hardenedLoader = new \Twig\Loader\ChainLoader([$templateBasicLoader, $sandBoxBasicLoader]);
+ $twig = new Twig_Environment($hardenedLoader);
+ $twig->addExtension($sandbox);
+
+ return $twig;
+ }
+
+ /**
+ * Compiles an incident template into an incident message.
+ *
+ * @param \CachetHQ\Cachet\Models\IncidentTemplate $template
+ * @param \CachetHQ\Cachet\Bus\Commands\Incident\CreateIncidentCommand $command
+ *
+ * @return string
+ */
+ protected function parseTemplate(IncidentTemplate $template, CreateIncidentCommand $command)
+ {
+ $template = $this->sandboxedTwigTemplateData($template->template);
+
+ $vars = array_merge($command->template_vars, [
+ 'incident' => [
+ 'name' => $command->name,
+ 'status' => $command->status,
+ 'message' => $command->message,
+ 'visible' => $command->visible,
+ 'notify' => $command->notify,
+ 'stickied' => $command->stickied,
+ 'occurred_at' => $command->occurred_at,
+ 'component' => Component::find($command->component_id) ?: null,
+ 'component_status' => $command->component_status,
+ ],
+ ]);
+
+ return $template->render('secondStageLoader', $vars);
+ }
+}
diff --git a/app/Bus/Handlers/Commands/Incident/RemoveIncidentCommandHandler.php b/app/Bus/Handlers/Commands/Incident/RemoveIncidentCommandHandler.php
index 38196c666fac..5fa7fbf3730a 100644
--- a/app/Bus/Handlers/Commands/Incident/RemoveIncidentCommandHandler.php
+++ b/app/Bus/Handlers/Commands/Incident/RemoveIncidentCommandHandler.php
@@ -13,9 +13,29 @@
use CachetHQ\Cachet\Bus\Commands\Incident\RemoveIncidentCommand;
use CachetHQ\Cachet\Bus\Events\Incident\IncidentWasRemovedEvent;
+use Illuminate\Contracts\Auth\Guard;
class RemoveIncidentCommandHandler
{
+ /**
+ * The authentication guard instance.
+ *
+ * @var \Illuminate\Contracts\Auth\Guard
+ */
+ protected $auth;
+
+ /**
+ * Create a new remove incident command handler instance.
+ *
+ * @param \Illuminate\Contracts\Auth\Guard $auth
+ *
+ * @return void
+ */
+ public function __construct(Guard $auth)
+ {
+ $this->auth = $auth;
+ }
+
/**
* Handle the remove incident command.
*
@@ -27,7 +47,7 @@ public function handle(RemoveIncidentCommand $command)
{
$incident = $command->incident;
- event(new IncidentWasRemovedEvent($incident));
+ event(new IncidentWasRemovedEvent($this->auth->user(), $incident));
$incident->delete();
}
diff --git a/app/Bus/Handlers/Commands/Incident/ReportIncidentCommandHandler.php b/app/Bus/Handlers/Commands/Incident/ReportIncidentCommandHandler.php
deleted file mode 100644
index cae916339456..000000000000
--- a/app/Bus/Handlers/Commands/Incident/ReportIncidentCommandHandler.php
+++ /dev/null
@@ -1,129 +0,0 @@
-
- */
-class ReportIncidentCommandHandler
-{
- /**
- * The date factory instance.
- *
- * @var \CachetHQ\Cachet\Dates\DateFactory
- */
- protected $dates;
-
- /**
- * The twig bridge instance.
- *
- * @var \TwigBridge\Bridge
- */
- protected $twig;
-
- /**
- * Create a new report incident command handler instance.
- *
- * @param \CachetHQ\Cachet\Dates\DateFactory $dates
- * @param \TwigBridge\Bridge $twig
- *
- * @return void
- */
- public function __construct(DateFactory $dates, Bridge $twig)
- {
- $this->dates = $dates;
- $this->twig = $twig;
- }
-
- /**
- * Handle the report incident command.
- *
- * @param \CachetHQ\Cachet\Bus\Commands\Incident\ReportIncidentCommand $command
- *
- * @return \CachetHQ\Cachet\Models\Incident
- */
- public function handle(ReportIncidentCommand $command)
- {
- $data = [
- 'name' => $command->name,
- 'status' => $command->status,
- 'visible' => $command->visible,
- 'stickied' => $command->stickied,
- ];
-
- if ($command->template) {
- $data['message'] = $this->parseIncidentTemplate($command->template, $command->template_vars);
- } else {
- $data['message'] = $command->message;
- }
-
- // Link with the component.
- if ($command->component_id) {
- $data['component_id'] = $command->component_id;
- }
-
- // The incident occurred at a different time.
- if ($command->incident_date) {
- $incidentDate = $this->dates->create('d/m/Y H:i', $command->incident_date);
-
- $data['created_at'] = $incidentDate;
- $data['updated_at'] = $incidentDate;
- }
-
- // Create the incident
- $incident = Incident::create($data);
-
- // Update the component.
- if ($command->component_id) {
- Component::find($command->component_id)->update([
- 'status' => $command->component_status,
- ]);
- }
-
- $incident->notify = (bool) $command->notify;
-
- event(new IncidentWasReportedEvent($incident));
-
- return $incident;
- }
-
- /**
- * Compiles an incident template into an incident message.
- *
- * @param string $templateSlug
- * @param array $vars
- *
- * @return string
- */
- protected function parseIncidentTemplate($templateSlug, $vars)
- {
- if ($vars === null) {
- $vars = [];
- }
-
- $this->twig->setLoader(new Twig_Loader_String());
- $template = IncidentTemplate::forSlug($templateSlug)->first();
-
- return $this->twig->render($template->template, $vars);
- }
-}
diff --git a/app/Bus/Handlers/Commands/Incident/ReportMaintenanceCommandHandler.php b/app/Bus/Handlers/Commands/Incident/ReportMaintenanceCommandHandler.php
deleted file mode 100644
index b63b767ac4f8..000000000000
--- a/app/Bus/Handlers/Commands/Incident/ReportMaintenanceCommandHandler.php
+++ /dev/null
@@ -1,66 +0,0 @@
-dates = $dates;
- }
-
- /**
- * Handle the report maintenance command.
- *
- * @param \CachetHQ\Cachet\Bus\Commands\Incident\ReportMaintenanceCommand $command
- *
- * @return \CachetHQ\Cachet\Models\Incident
- */
- public function handle(ReportMaintenanceCommand $command)
- {
- $scheduledAt = $this->dates->create('d/m/Y H:i', $command->timestamp);
-
- $maintenanceEvent = Incident::create([
- 'name' => $command->name,
- 'message' => $command->message,
- 'scheduled_at' => $scheduledAt,
- 'status' => 0,
- 'visible' => 1,
- 'stickied' => false,
- ]);
-
- $maintenanceEvent->notify = (bool) $command->notify;
-
- event(new MaintenanceWasScheduledEvent($maintenanceEvent));
-
- return $maintenanceEvent;
- }
-}
diff --git a/app/Bus/Handlers/Commands/Incident/UpdateIncidentCommandHandler.php b/app/Bus/Handlers/Commands/Incident/UpdateIncidentCommandHandler.php
index 8001cf6ae14d..c85920253832 100644
--- a/app/Bus/Handlers/Commands/Incident/UpdateIncidentCommandHandler.php
+++ b/app/Bus/Handlers/Commands/Incident/UpdateIncidentCommandHandler.php
@@ -11,14 +11,16 @@
namespace CachetHQ\Cachet\Bus\Handlers\Commands\Incident;
+use CachetHQ\Cachet\Bus\Commands\Component\UpdateComponentCommand;
use CachetHQ\Cachet\Bus\Commands\Incident\UpdateIncidentCommand;
use CachetHQ\Cachet\Bus\Events\Incident\IncidentWasUpdatedEvent;
-use CachetHQ\Cachet\Dates\DateFactory;
+use CachetHQ\Cachet\Bus\Exceptions\Incident\InvalidIncidentTimestampException;
+use CachetHQ\Cachet\Bus\Handlers\Traits\StoresMeta;
use CachetHQ\Cachet\Models\Component;
use CachetHQ\Cachet\Models\Incident;
use CachetHQ\Cachet\Models\IncidentTemplate;
-use Twig_Loader_String;
-use TwigBridge\Bridge;
+use CachetHQ\Cachet\Services\Dates\DateFactory;
+use Illuminate\Contracts\Auth\Guard;
/**
* This is the update incident command handler.
@@ -27,32 +29,41 @@
*/
class UpdateIncidentCommandHandler
{
+ use StoresMeta;
+
+ /**
+ * The authentication guard instance.
+ *
+ * @var \Illuminate\Contracts\Auth\Guard
+ */
+ protected $auth;
+
/**
* The date factory instance.
*
- * @var \CachetHQ\Cachet\Dates\DateFactory
+ * @var \CachetHQ\Cachet\Services\Dates\DateFactory
*/
protected $dates;
/**
- * The twig bridge instance.
- *
- * @var \TwigBridge\Bridge
+ * Twig configuration array.
*/
- protected $twig;
+ protected $twigConfig;
/**
* Create a new update incident command handler instance.
*
- * @param \CachetHQ\Cachet\Dates\DateFactory $dates
- * @param \TwigBridge\Bridge $twig
+ * @param \Illuminate\Contracts\Auth\Guard $auth
+ * @param \CachetHQ\Cachet\Services\Dates\DateFactory $dates
*
* @return void
*/
- public function __construct(DateFactory $dates, Bridge $twig)
+ public function __construct(Guard $auth, DateFactory $dates)
{
+ $this->auth = $auth;
$this->dates = $dates;
- $this->twig = $twig;
+
+ $this->twigConfig = $twigConfig = config('cachet.twig');
}
/**
@@ -64,31 +75,48 @@ public function __construct(DateFactory $dates, Bridge $twig)
*/
public function handle(UpdateIncidentCommand $command)
{
- if ($command->template) {
- $command->message = $this->parseIncidentTemplate($command->template, $command->template_vars);
+ if ($template = IncidentTemplate::where('slug', '=', $command->template)->first()) {
+ $command->message = $this->parseTemplate($template, $command);
}
$incident = $command->incident;
- $incident->update($this->filter($command));
+ $incident->fill($this->filter($command));
// The incident occurred at a different time.
- if ($command->incident_date) {
- $incidentDate = $this->dates->create('d/m/Y H:i', $command->incident_date);
+ if ($occurredAt = $command->occurred_at) {
+ if ($date = $this->dates->create('Y-m-d H:i', $occurredAt)) {
+ $incident->fill(['occurred_at' => $date]);
+ } else {
+ throw new InvalidIncidentTimestampException("Unable to pass timestamp {$occurredAt}");
+ }
+ }
+
+ // Rather than making lots of updates, just fill and save.
+ $incident->save();
- $incident->update([
- 'created_at' => $incidentDate,
- 'updated_at' => $incidentDate,
- ]);
+ // Store any meta?
+ if ($meta = $command->meta) {
+ $this->storeMeta($command->meta, 'incidents', $incident->id);
}
// Update the component.
- if ($command->component_id) {
- Component::find($command->component_id)->update([
- 'status' => $command->component_status,
- ]);
+ if ($component = Component::find($command->component_id)) {
+ execute(new UpdateComponentCommand(
+ Component::find($command->component_id),
+ null,
+ null,
+ $command->component_status,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ true // Silent mode
+ ));
}
- event(new IncidentWasUpdatedEvent($incident));
+ event(new IncidentWasUpdatedEvent($this->auth->user(), $incident));
return $incident;
}
@@ -118,19 +146,58 @@ protected function filter(UpdateIncidentCommand $command)
});
}
+ protected function sandboxedTwigTemplateData(string $templateData)
+ {
+ $policy = new \Twig\Sandbox\SecurityPolicy(
+ $this->twigConfig['tags'],
+ $this->twigConfig['filters'],
+ $this->twigConfig['methods'],
+ $this->twigConfig['props'],
+ $this->twigConfig['functions']
+ );
+ $sandbox = new \Twig\Extension\SandboxExtension($policy);
+
+ $templateBasicLoader = new \Twig\Loader\ArrayLoader([
+ 'firstStageLoader' => $templateData,
+ ]);
+
+ $sandBoxBasicLoader = new \Twig\Loader\ArrayLoader([
+ 'secondStageLoader' => '{% sandbox %}{% include "firstStageLoader" %} {% endsandbox %}',
+ ]);
+
+ $hardenedLoader = new \Twig\Loader\ChainLoader([$templateBasicLoader, $sandBoxBasicLoader]);
+ $twig = new \Twig\Environment($hardenedLoader);
+ $twig->addExtension($sandbox);
+
+ return $twig;
+ }
+
/**
* Compiles an incident template into an incident message.
*
- * @param string $templateSlug
- * @param array $vars
+ * @param \CachetHQ\Cachet\Models\IncidentTemplate $template
+ * @param \CachetHQ\Cachet\Bus\Commands\Incident\UpdateIncidentCommand $command
*
* @return string
*/
- protected function parseIncidentTemplate($templateSlug, $vars)
+ protected function parseTemplate(IncidentTemplate $template, UpdateIncidentCommand $command)
{
- $this->twig->setLoader(new Twig_Loader_String());
- $template = IncidentTemplate::forSlug($templateSlug)->first();
-
- return $this->twig->render($template->template, $vars);
+ $template = $this->sandboxedTwigTemplateData($template->template);
+
+ $vars = array_merge($command->template_vars, [
+ 'incident' => [
+ 'name' => $command->name,
+ 'status' => $command->status,
+ 'message' => $command->message,
+ 'visible' => $command->visible,
+ 'notify' => $command->notify,
+ 'stickied' => $command->stickied,
+ 'occurred_at' => $command->occurred_at,
+ 'component' => Component::find($command->component_id) ?: null,
+ 'component_status' => $command->component_status,
+ ],
+ ]);
+
+ return $template->render('secondStageLoader', $vars);
}
}
diff --git a/app/Bus/Handlers/Commands/IncidentUpdate/CreateIncidentUpdateCommandHandler.php b/app/Bus/Handlers/Commands/IncidentUpdate/CreateIncidentUpdateCommandHandler.php
new file mode 100644
index 000000000000..20dd2c84a933
--- /dev/null
+++ b/app/Bus/Handlers/Commands/IncidentUpdate/CreateIncidentUpdateCommandHandler.php
@@ -0,0 +1,85 @@
+
+ */
+class CreateIncidentUpdateCommandHandler
+{
+ /**
+ * The authentication guard instance.
+ *
+ * @var \Illuminate\Contracts\Auth\Guard
+ */
+ protected $auth;
+
+ /**
+ * Create a new report incident update command handler instance.
+ *
+ * @param \Illuminate\Contracts\Auth\Guard $auth
+ *
+ * @return void
+ */
+ public function __construct(Guard $auth)
+ {
+ $this->auth = $auth;
+ }
+
+ /**
+ * Handle the report incident command.
+ *
+ * @param \CachetHQ\Cachet\Bus\Commands\IncidentUpdate\CreateIncidentUpdateCommand $command
+ *
+ * @return \CachetHQ\Cachet\Models\IncidentUpdate
+ */
+ public function handle(CreateIncidentUpdateCommand $command)
+ {
+ $data = [
+ 'incident_id' => $command->incident->id,
+ 'status' => $command->status,
+ 'message' => $command->message,
+ 'user_id' => $command->user->id,
+ ];
+
+ // Create the incident update.
+ $update = IncidentUpdate::create($data);
+
+ // Update the original incident with the new status.
+ execute(new UpdateIncidentCommand(
+ $command->incident,
+ null,
+ $command->status,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ []
+ ));
+
+ event(new IncidentUpdateWasReportedEvent($this->auth->user(), $update));
+
+ return $update;
+ }
+}
diff --git a/app/Bus/Handlers/Commands/IncidentUpdate/RemoveIncidentUpdateCommandHandler.php b/app/Bus/Handlers/Commands/IncidentUpdate/RemoveIncidentUpdateCommandHandler.php
new file mode 100644
index 000000000000..ee5cc5b7894e
--- /dev/null
+++ b/app/Bus/Handlers/Commands/IncidentUpdate/RemoveIncidentUpdateCommandHandler.php
@@ -0,0 +1,59 @@
+
+ */
+class RemoveIncidentUpdateCommandHandler
+{
+ /**
+ * The authentication guard instance.
+ *
+ * @var \Illuminate\Contracts\Auth\Guard
+ */
+ protected $auth;
+
+ /**
+ * Create a new remove incident update command handler instance.
+ *
+ * @param \Illuminate\Contracts\Auth\Guard $auth
+ *
+ * @return void
+ */
+ public function __construct(Guard $auth)
+ {
+ $this->auth = $auth;
+ }
+
+ /**
+ * Handle the remove incident update command.
+ *
+ * @param \CachetHQ\Cachet\Bus\Commands\IncidentUpdate\RemoveIncidentUpdateCommand $command
+ *
+ * @return void
+ */
+ public function handle(RemoveIncidentUpdateCommand $command)
+ {
+ $update = $command->incidentUpdate;
+
+ event(new IncidentUpdateWasRemovedEvent($this->auth->user(), $update));
+
+ $update->delete();
+ }
+}
diff --git a/app/Bus/Handlers/Commands/IncidentUpdate/UpdateIncidentUpdateCommandHandler.php b/app/Bus/Handlers/Commands/IncidentUpdate/UpdateIncidentUpdateCommandHandler.php
new file mode 100644
index 000000000000..c3086ea7d747
--- /dev/null
+++ b/app/Bus/Handlers/Commands/IncidentUpdate/UpdateIncidentUpdateCommandHandler.php
@@ -0,0 +1,79 @@
+
+ */
+class UpdateIncidentUpdateCommandHandler
+{
+ /**
+ * The authentication guard instance.
+ *
+ * @var \Illuminate\Contracts\Auth\Guard
+ */
+ protected $auth;
+
+ /**
+ * Create a new update incident update command handler instance.
+ *
+ * @param \Illuminate\Contracts\Auth\Guard $auth
+ *
+ * @return void
+ */
+ public function __construct(Guard $auth)
+ {
+ $this->auth = $auth;
+ }
+
+ /**
+ * Handle the update incident update command.
+ *
+ * @param \CachetHQ\Cachet\Bus\Commands\IncidentUpdate\UpdateIncidentUpdateCommand $command
+ *
+ * @return \CachetHQ\Cachet\Models\IncidentUpdate
+ */
+ public function handle(UpdateIncidentUpdateCommand $command)
+ {
+ $command->update->update($this->filter($command));
+
+ event(new IncidentUpdateWasUpdatedEvent($this->auth->user(), $command->update));
+
+ return $command->update;
+ }
+
+ /**
+ * Filter the command data.
+ *
+ * @param \CachetHQ\Cachet\Bus\Commands\IncidentUpdate\UpdateIncidentUpdateCommand $command
+ *
+ * @return array
+ */
+ protected function filter(UpdateIncidentUpdateCommand $command)
+ {
+ $params = [
+ 'status' => $command->status,
+ 'message' => $command->message,
+ 'user_id' => $command->user->id,
+ ];
+
+ return array_filter($params, function ($val) {
+ return $val !== null;
+ });
+ }
+}
diff --git a/app/Bus/Handlers/Commands/Invite/ClaimInviteCommandHandler.php b/app/Bus/Handlers/Commands/Invite/ClaimInviteCommandHandler.php
index ba669a8ff4f4..bd2603bebbd0 100644
--- a/app/Bus/Handlers/Commands/Invite/ClaimInviteCommandHandler.php
+++ b/app/Bus/Handlers/Commands/Invite/ClaimInviteCommandHandler.php
@@ -20,7 +20,7 @@ class ClaimInviteCommandHandler
/**
* Handle the claim invite command.
*
- * @param \CachetHQ\Cachet\Bus\Commands\User\ClaimInviteCommand $command
+ * @param \CachetHQ\Cachet\Bus\Commands\Invite\ClaimInviteCommand $command
*
* @return void
*/
@@ -28,8 +28,7 @@ public function handle(ClaimInviteCommand $command)
{
$invite = $command->invite;
- $invite->claimed_at = Carbon::now();
- $invite->save();
+ $invite->update(['claimed_at' => Carbon::now()]);
event(new InviteWasClaimedEvent($invite));
}
diff --git a/app/Bus/Handlers/Commands/Metric/AddMetricCommandHandler.php b/app/Bus/Handlers/Commands/Metric/CreateMetricCommandHandler.php
similarity index 55%
rename from app/Bus/Handlers/Commands/Metric/AddMetricCommandHandler.php
rename to app/Bus/Handlers/Commands/Metric/CreateMetricCommandHandler.php
index a5733b280be1..cc410ce0b242 100644
--- a/app/Bus/Handlers/Commands/Metric/AddMetricCommandHandler.php
+++ b/app/Bus/Handlers/Commands/Metric/CreateMetricCommandHandler.php
@@ -11,20 +11,40 @@
namespace CachetHQ\Cachet\Bus\Handlers\Commands\Metric;
-use CachetHQ\Cachet\Bus\Commands\Metric\AddMetricCommand;
-use CachetHQ\Cachet\Bus\Events\Metric\MetricWasAddedEvent;
+use CachetHQ\Cachet\Bus\Commands\Metric\CreateMetricCommand;
+use CachetHQ\Cachet\Bus\Events\Metric\MetricWasCreatedEvent;
use CachetHQ\Cachet\Models\Metric;
+use Illuminate\Contracts\Auth\Guard;
-class AddMetricCommandHandler
+class CreateMetricCommandHandler
{
+ /**
+ * The authentication guard instance.
+ *
+ * @var \Illuminate\Contracts\Auth\Guard
+ */
+ protected $auth;
+
+ /**
+ * Create a new add metric command handler instance.
+ *
+ * @param \Illuminate\Contracts\Auth\Guard $auth
+ *
+ * @return void
+ */
+ public function __construct(Guard $auth)
+ {
+ $this->auth = $auth;
+ }
+
/**
* Handle the add metric command.
*
- * @param \CachetHQ\Cachet\Bus\Commands\Metric\AddMetricCommand $command
+ * @param \CachetHQ\Cachet\Bus\Commands\Metric\CreateMetricCommand $command
*
* @return \CachetHQ\Cachet\Models\Metric
*/
- public function handle(AddMetricCommand $command)
+ public function handle(CreateMetricCommand $command)
{
$metric = Metric::create([
'name' => $command->name,
@@ -37,9 +57,10 @@ public function handle(AddMetricCommand $command)
'default_view' => $command->default_view,
'threshold' => $command->threshold,
'order' => $command->order,
+ 'visible' => $command->visible,
]);
- event(new MetricWasAddedEvent($metric));
+ event(new MetricWasCreatedEvent($this->auth->user(), $metric));
return $metric;
}
diff --git a/app/Bus/Handlers/Commands/Metric/AddMetricPointCommandHandler.php b/app/Bus/Handlers/Commands/Metric/CreateMetricPointCommandHandler.php
similarity index 51%
rename from app/Bus/Handlers/Commands/Metric/AddMetricPointCommandHandler.php
rename to app/Bus/Handlers/Commands/Metric/CreateMetricPointCommandHandler.php
index 17b6dadea897..8fdbe1ca21c6 100644
--- a/app/Bus/Handlers/Commands/Metric/AddMetricPointCommandHandler.php
+++ b/app/Bus/Handlers/Commands/Metric/CreateMetricPointCommandHandler.php
@@ -11,41 +11,51 @@
namespace CachetHQ\Cachet\Bus\Handlers\Commands\Metric;
-use CachetHQ\Cachet\Bus\Commands\Metric\AddMetricPointCommand;
-use CachetHQ\Cachet\Bus\Events\Metric\MetricPointWasAddedEvent;
-use CachetHQ\Cachet\Dates\DateFactory;
+use CachetHQ\Cachet\Bus\Commands\Metric\CreateMetricPointCommand;
+use CachetHQ\Cachet\Bus\Events\Metric\MetricPointWasCreatedEvent;
use CachetHQ\Cachet\Models\MetricPoint;
+use CachetHQ\Cachet\Services\Dates\DateFactory;
use Carbon\Carbon;
+use Illuminate\Contracts\Auth\Guard;
-class AddMetricPointCommandHandler
+class CreateMetricPointCommandHandler
{
+ /**
+ * The authentication guard instance.
+ *
+ * @var \Illuminate\Contracts\Auth\Guard
+ */
+ protected $auth;
+
/**
* The date factory instance.
*
- * @var \CachetHQ\Cachet\Dates\DateFactory
+ * @var \CachetHQ\Cachet\Services\Dates\DateFactory
*/
protected $dates;
/**
* Create a new add metric point command handler instance.
*
- * @param \CachetHQ\Cachet\Dates\DateFactory $dates
+ * @param \Illuminate\Contracts\Auth\Guard $auth
+ * @param \CachetHQ\Cachet\Services\Dates\DateFactory $dates
*
* @return void
*/
- public function __construct(DateFactory $dates)
+ public function __construct(Guard $auth, DateFactory $dates)
{
+ $this->auth = $auth;
$this->dates = $dates;
}
/**
* Handle the add metric point command.
*
- * @param \CachetHQ\Cachet\Bus\Commands\Metric\AddMetricPointCommand $command
+ * @param \CachetHQ\Cachet\Bus\Commands\Metric\CreateMetricPointCommand $command
*
* @return \CachetHQ\Cachet\Models\MetricPoint
*/
- public function handle(AddMetricPointCommand $command)
+ public function handle(CreateMetricPointCommand $command)
{
$metric = $command->metric;
$createdAt = $command->created_at;
@@ -55,17 +65,23 @@ public function handle(AddMetricPointCommand $command)
$point->increment('counter', 1);
- event(new MetricPointWasAddedEvent($point));
+ event(new MetricPointWasCreatedEvent($this->auth->user(), $point));
return $point;
}
- protected function findOrCreatePoint(AddMetricPointCommand $command)
+ /**
+ * Find or create a metric point.
+ *
+ * @param \CachetHQ\Cachet\Bus\Commands\Metric\CreateMetricPointCommand $command
+ *
+ * @return \CachetHQ\Cachet\Models\MetricPoint
+ */
+ protected function findOrCreatePoint(CreateMetricPointCommand $command)
{
- $buffer = Carbon::now()->subMinutes($command->metric->threshold);
- $point = MetricPoint::where('metric_id', $command->metric->id)->where('value', $command->value)->where('created_at', '>=', $buffer)->first();
+ $buffer = Carbon::now()->subMinutes($command->metric->threshold - 1)->startOfMinute();
- if ($point) {
+ if ($point = MetricPoint::where('metric_id', '=', $command->metric->id)->where('value', '=', $command->value)->where('created_at', '>=', $buffer)->first()) {
return $point;
}
diff --git a/app/Bus/Handlers/Commands/Metric/RemoveMetricCommandHandler.php b/app/Bus/Handlers/Commands/Metric/RemoveMetricCommandHandler.php
index cd15e0ebf5de..478d29523bce 100644
--- a/app/Bus/Handlers/Commands/Metric/RemoveMetricCommandHandler.php
+++ b/app/Bus/Handlers/Commands/Metric/RemoveMetricCommandHandler.php
@@ -14,9 +14,29 @@
use CachetHQ\Cachet\Bus\Commands\Metric\RemoveMetricCommand;
use CachetHQ\Cachet\Bus\Events\Metric\MetricWasRemovedEvent;
use CachetHQ\Cachet\Models\Metric;
+use Illuminate\Contracts\Auth\Guard;
class RemoveMetricCommandHandler
{
+ /**
+ * The authentication guard instance.
+ *
+ * @var \Illuminate\Contracts\Auth\Guard
+ */
+ protected $auth;
+
+ /**
+ * Create a new remove metric command handler instance.
+ *
+ * @param \Illuminate\Contracts\Auth\Guard $auth
+ *
+ * @return void
+ */
+ public function __construct(Guard $auth)
+ {
+ $this->auth = $auth;
+ }
+
/**
* Handle the remove metric command.
*
@@ -28,7 +48,7 @@ public function handle(RemoveMetricCommand $command)
{
$metric = $command->metric;
- event(new MetricWasRemovedEvent($metric));
+ event(new MetricWasRemovedEvent($this->auth->user(), $metric));
$metric->delete();
}
diff --git a/app/Bus/Handlers/Commands/Metric/RemoveMetricPointCommandHandler.php b/app/Bus/Handlers/Commands/Metric/RemoveMetricPointCommandHandler.php
index f7d6f6d7a26d..7679942ee5b5 100644
--- a/app/Bus/Handlers/Commands/Metric/RemoveMetricPointCommandHandler.php
+++ b/app/Bus/Handlers/Commands/Metric/RemoveMetricPointCommandHandler.php
@@ -14,9 +14,29 @@
use CachetHQ\Cachet\Bus\Commands\Metric\RemoveMetricPointCommand;
use CachetHQ\Cachet\Bus\Events\Metric\MetricPointWasRemovedEvent;
use CachetHQ\Cachet\Models\Metric;
+use Illuminate\Contracts\Auth\Guard;
class RemoveMetricPointCommandHandler
{
+ /**
+ * The authentication guard instance.
+ *
+ * @var \Illuminate\Contracts\Auth\Guard
+ */
+ protected $auth;
+
+ /**
+ * Create a new remove metric point command handler instance.
+ *
+ * @param \Illuminate\Contracts\Auth\Guard $auth
+ *
+ * @return void
+ */
+ public function __construct(Guard $auth)
+ {
+ $this->auth = $auth;
+ }
+
/**
* Handle the remove metric point command.
*
@@ -28,7 +48,7 @@ public function handle(RemoveMetricPointCommand $command)
{
$metricPoint = $command->metricPoint;
- event(new MetricPointWasRemovedEvent($metricPoint));
+ event(new MetricPointWasRemovedEvent($this->auth->user(), $metricPoint));
$metricPoint->delete();
}
diff --git a/app/Bus/Handlers/Commands/Metric/UpdateMetricCommandHandler.php b/app/Bus/Handlers/Commands/Metric/UpdateMetricCommandHandler.php
index e8abda242818..1ba3636be28d 100644
--- a/app/Bus/Handlers/Commands/Metric/UpdateMetricCommandHandler.php
+++ b/app/Bus/Handlers/Commands/Metric/UpdateMetricCommandHandler.php
@@ -14,9 +14,29 @@
use CachetHQ\Cachet\Bus\Commands\Metric\UpdateMetricCommand;
use CachetHQ\Cachet\Bus\Events\Metric\MetricWasUpdatedEvent;
use CachetHQ\Cachet\Models\Metric;
+use Illuminate\Contracts\Auth\Guard;
class UpdateMetricCommandHandler
{
+ /**
+ * The authentication guard instance.
+ *
+ * @var \Illuminate\Contracts\Auth\Guard
+ */
+ protected $auth;
+
+ /**
+ * Create a new update metric command handler instance.
+ *
+ * @param \Illuminate\Contracts\Auth\Guard $auth
+ *
+ * @return void
+ */
+ public function __construct(Guard $auth)
+ {
+ $this->auth = $auth;
+ }
+
/**
* Handle the update metric command.
*
@@ -30,7 +50,7 @@ public function handle(UpdateMetricCommand $command)
$metric->update($this->filter($command));
- event(new MetricWasUpdatedEvent($metric));
+ event(new MetricWasUpdatedEvent($this->auth->user(), $metric));
return $metric;
}
@@ -55,6 +75,7 @@ protected function filter(UpdateMetricCommand $command)
'default_view' => $command->default_view,
'threshold' => $command->threshold,
'order' => $command->order,
+ 'visible' => $command->visible,
];
return array_filter($params, function ($val) {
diff --git a/app/Bus/Handlers/Commands/Metric/UpdateMetricPointCommandHandler.php b/app/Bus/Handlers/Commands/Metric/UpdateMetricPointCommandHandler.php
index aec34b631012..f61e1733375e 100644
--- a/app/Bus/Handlers/Commands/Metric/UpdateMetricPointCommandHandler.php
+++ b/app/Bus/Handlers/Commands/Metric/UpdateMetricPointCommandHandler.php
@@ -13,26 +13,36 @@
use CachetHQ\Cachet\Bus\Commands\Metric\UpdateMetricPointCommand;
use CachetHQ\Cachet\Bus\Events\Metric\MetricPointWasUpdatedEvent;
-use CachetHQ\Cachet\Dates\DateFactory;
+use CachetHQ\Cachet\Services\Dates\DateFactory;
+use Illuminate\Contracts\Auth\Guard;
class UpdateMetricPointCommandHandler
{
+ /**
+ * The authentication guard instance.
+ *
+ * @var \Illuminate\Contracts\Auth\Guard
+ */
+ protected $auth;
+
/**
* The date factory instance.
*
- * @var \CachetHQ\Cachet\Dates\DateFactory
+ * @var \CachetHQ\Cachet\Services\Dates\DateFactory
*/
protected $dates;
/**
* Create a new update metric point command handler instance.
*
- * @param \CachetHQ\Cachet\Dates\DateFactory $dates
+ * @param \Illuminate\Contracts\Auth\Guard $auth
+ * @param \CachetHQ\Cachet\Services\Dates\DateFactory $dates
*
* @return void
*/
- public function __construct(DateFactory $dates)
+ public function __construct(Guard $auth, DateFactory $dates)
{
+ $this->auth = $auth;
$this->dates = $dates;
}
@@ -60,7 +70,7 @@ public function handle(UpdateMetricPointCommand $command)
$point->update($data);
- event(new MetricPointWasUpdatedEvent($point));
+ event(new MetricPointWasUpdatedEvent($this->auth->user(), $point));
return $point;
}
diff --git a/app/Bus/Handlers/Commands/Schedule/CreateScheduleCommandHandler.php b/app/Bus/Handlers/Commands/Schedule/CreateScheduleCommandHandler.php
new file mode 100644
index 000000000000..9069eadb9c01
--- /dev/null
+++ b/app/Bus/Handlers/Commands/Schedule/CreateScheduleCommandHandler.php
@@ -0,0 +1,107 @@
+
+ */
+class CreateScheduleCommandHandler
+{
+ /**
+ * The authentication guard instance.
+ *
+ * @var \Illuminate\Contracts\Auth\Guard
+ */
+ protected $auth;
+
+ /**
+ * The date factory instance.
+ *
+ * @var \CachetHQ\Cachet\Services\Dates\DateFactory
+ */
+ protected $dates;
+
+ /**
+ * Create a new update schedule command handler instance.
+ *
+ * @param \Illuminate\Contracts\Auth\Guard $auth
+ * @param \CachetHQ\Cachet\Services\Dates\DateFactory $dates
+ *
+ * @return void
+ */
+ public function __construct(Guard $auth, DateFactory $dates)
+ {
+ $this->auth = $auth;
+ $this->dates = $dates;
+ }
+
+ /**
+ * Handle the create schedule command.
+ *
+ * @param \CachetHQ\Cachet\Bus\Commands\Schedule\CreateScheduleCommand $command
+ *
+ * @return \CachetHQ\Cachet\Models\Schedule
+ */
+ public function handle(CreateScheduleCommand $command)
+ {
+ try {
+ $schedule = Schedule::create($this->filter($command));
+ event(new ScheduleWasCreatedEvent($this->auth->user(), $schedule, (bool) $command->notify));
+ } catch (InvalidArgumentException $e) {
+ throw new ValidationException(new MessageBag([$e->getMessage()]));
+ }
+
+ return $schedule;
+ }
+
+ /**
+ * Filter the command data.
+ *
+ * @param \CachetHQ\Cachet\Bus\Commands\Schedule\CreateScheduleCommand $command
+ *
+ * @return array
+ */
+ protected function filter(CreateScheduleCommand $command)
+ {
+ $scheduledAt = $this->dates->create('Y-m-d H:i', $command->scheduled_at);
+
+ if ($completedAt = $command->completed_at) {
+ $completedAt = $this->dates->create('Y-m-d H:i', $command->completed_at);
+ }
+
+ $params = [
+ 'name' => $command->name,
+ 'message' => $command->message,
+ 'status' => $command->status,
+ 'scheduled_at' => $scheduledAt,
+ 'completed_at' => $completedAt,
+ 'notify' => $command->notify,
+ ];
+
+ $availableParams = array_filter($params, function ($val) {
+ return $val !== null && $val !== '';
+ });
+
+ return $availableParams;
+ }
+}
diff --git a/app/Bus/Handlers/Commands/Schedule/DeleteScheduleCommandHandler.php b/app/Bus/Handlers/Commands/Schedule/DeleteScheduleCommandHandler.php
new file mode 100644
index 000000000000..cf5f62278a54
--- /dev/null
+++ b/app/Bus/Handlers/Commands/Schedule/DeleteScheduleCommandHandler.php
@@ -0,0 +1,59 @@
+
+ */
+class DeleteScheduleCommandHandler
+{
+ /**
+ * The authentication guard instance.
+ *
+ * @var \Illuminate\Contracts\Auth\Guard
+ */
+ protected $auth;
+
+ /**
+ * Create a new delete schedule command handler instance.
+ *
+ * @param \Illuminate\Contracts\Auth\Guard $auth
+ *
+ * @return void
+ */
+ public function __construct(Guard $auth)
+ {
+ $this->auth = $auth;
+ }
+
+ /**
+ * Handle the delete schedule command.
+ *
+ * @param \CachetHQ\Cachet\Bus\Commands\Schedule\DeleteScheduleCommand $command
+ *
+ * @return void
+ */
+ public function handle(DeleteScheduleCommand $command)
+ {
+ $schedule = $command->schedule;
+
+ event(new ScheduleWasRemovedEvent($this->auth->user(), $schedule));
+
+ $schedule->delete();
+ }
+}
diff --git a/app/Bus/Handlers/Commands/Schedule/UpdateScheduleCommandHandler.php b/app/Bus/Handlers/Commands/Schedule/UpdateScheduleCommandHandler.php
new file mode 100644
index 000000000000..72f743280104
--- /dev/null
+++ b/app/Bus/Handlers/Commands/Schedule/UpdateScheduleCommandHandler.php
@@ -0,0 +1,102 @@
+
+ */
+class UpdateScheduleCommandHandler
+{
+ /**
+ * The authentication guard instance.
+ *
+ * @var \Illuminate\Contracts\Auth\Guard
+ */
+ protected $auth;
+
+ /**
+ * The date factory instance.
+ *
+ * @var \CachetHQ\Cachet\Services\Dates\DateFactory
+ */
+ protected $dates;
+
+ /**
+ * Create a new update schedule command handler instance.
+ *
+ * @param \Illuminate\Contracts\Auth\Guard $auth
+ * @param \CachetHQ\Cachet\Services\Dates\DateFactory $dates
+ *
+ * @return void
+ */
+ public function __construct(Guard $auth, DateFactory $dates)
+ {
+ $this->auth = $auth;
+ $this->dates = $dates;
+ }
+
+ /**
+ * Handle the update schedule command.
+ *
+ * @param \CachetHQ\Cachet\Bus\Commands\Schedule\UpdateScheduleCommand $command
+ *
+ * @return \CachetHQ\Cachet\Models\Schedule
+ */
+ public function handle(UpdateScheduleCommand $command)
+ {
+ $schedule = $command->schedule;
+
+ $schedule->update($this->filter($command));
+
+ event(new ScheduleWasUpdatedEvent($this->auth->user(), $schedule));
+
+ return $schedule;
+ }
+
+ /**
+ * Filter the command data.
+ *
+ * @param \CachetHQ\Cachet\Bus\Commands\Schedule\UpdateScheduleCommand $command
+ *
+ * @return array
+ */
+ protected function filter(UpdateScheduleCommand $command)
+ {
+ $params = [
+ 'name' => $command->name,
+ 'message' => $command->message,
+ 'status' => $command->status,
+ ];
+
+ if ($scheduledAt = $command->scheduled_at) {
+ $params['scheduled_at'] = $this->dates->create('Y-m-d H:i', $scheduledAt);
+ }
+
+ if ($completedAt = $command->completed_at) {
+ $params['completed_at'] = $this->dates->create('Y-m-d H:i', $completedAt);
+ }
+
+ $availableParams = array_filter($params, function ($val) {
+ return $val !== null;
+ });
+
+ return $availableParams;
+ }
+}
diff --git a/app/Bus/Handlers/Commands/Subscriber/SubscribeSubscriberCommandHandler.php b/app/Bus/Handlers/Commands/Subscriber/SubscribeSubscriberCommandHandler.php
index a4554210e719..1dde43da4a84 100644
--- a/app/Bus/Handlers/Commands/Subscriber/SubscribeSubscriberCommandHandler.php
+++ b/app/Bus/Handlers/Commands/Subscriber/SubscribeSubscriberCommandHandler.php
@@ -17,12 +17,13 @@
use CachetHQ\Cachet\Models\Component;
use CachetHQ\Cachet\Models\Subscriber;
use CachetHQ\Cachet\Models\Subscription;
+use CachetHQ\Cachet\Notifications\Subscriber\VerifySubscriptionNotification;
/**
* This is the subscribe subscriber command handler.
*
* @author James Brooks
- * @author Joe Cohen
+ * @author Joseph Cohen
* @author Graham Campbell
*/
class SubscribeSubscriberCommandHandler
@@ -36,7 +37,7 @@ class SubscribeSubscriberCommandHandler
*/
public function handle(SubscribeSubscriberCommand $command)
{
- if ($subscriber = Subscriber::where('email', $command->email)->first()) {
+ if ($subscriber = Subscriber::where('email', '=', $command->email)->first()) {
return $subscriber;
}
@@ -44,24 +45,28 @@ public function handle(SubscribeSubscriberCommand $command)
// Decide what to subscribe the subscriber to.
if ($subscriptions = $command->subscriptions) {
- $subscriptions = Component::whereIn('id', $subscriptions);
+ $components = Component::whereIn('id', $subscriptions)->get();
} else {
- $subscriptions = Component::all();
+ $components = Component::all();
}
- foreach ($subscriptions as $component) {
+ $components->each(function ($component) use ($subscriber) {
Subscription::create([
'subscriber_id' => $subscriber->id,
'component_id' => $component->id,
]);
- }
+ });
if ($command->verified) {
- dispatch(new VerifySubscriberCommand($subscriber));
+ execute(new VerifySubscriberCommand($subscriber));
} else {
- event(new SubscriberHasSubscribedEvent($subscriber));
+ $subscriber->notify(new VerifySubscriptionNotification());
}
+ event(new SubscriberHasSubscribedEvent($subscriber));
+
+ $subscriber->load('subscriptions');
+
return $subscriber;
}
}
diff --git a/app/Bus/Handlers/Commands/Subscriber/UnsubscribeSubscriberCommandHandler.php b/app/Bus/Handlers/Commands/Subscriber/UnsubscribeSubscriberCommandHandler.php
index 7dac8828fdd6..be0dd0217528 100644
--- a/app/Bus/Handlers/Commands/Subscriber/UnsubscribeSubscriberCommandHandler.php
+++ b/app/Bus/Handlers/Commands/Subscriber/UnsubscribeSubscriberCommandHandler.php
@@ -13,8 +13,14 @@
use CachetHQ\Cachet\Bus\Commands\Subscriber\UnsubscribeSubscriberCommand;
use CachetHQ\Cachet\Bus\Events\Subscriber\SubscriberHasUnsubscribedEvent;
-use CachetHQ\Cachet\Models\Subscriber;
+/**
+ * This is the unsubscribe subscriber command class.
+ *
+ * @author Joseph Cohem
+ * @author Graham Campbell
+ * @author James Brooks
+ */
class UnsubscribeSubscriberCommandHandler
{
/**
@@ -28,8 +34,12 @@ public function handle(UnsubscribeSubscriberCommand $command)
{
$subscriber = $command->subscriber;
+ // First remove subscriptions.
+ $subscriber->subscriptions()->delete();
+
event(new SubscriberHasUnsubscribedEvent($subscriber));
+ // Then remove the subscriber.
$subscriber->delete();
}
}
diff --git a/app/Bus/Handlers/Commands/Subscriber/UpdateSubscriberSubscriptionCommandHandler.php b/app/Bus/Handlers/Commands/Subscriber/UpdateSubscriberSubscriptionCommandHandler.php
index 6ac9d2c0b02b..5e8a1dd5a8c7 100644
--- a/app/Bus/Handlers/Commands/Subscriber/UpdateSubscriberSubscriptionCommandHandler.php
+++ b/app/Bus/Handlers/Commands/Subscriber/UpdateSubscriberSubscriptionCommandHandler.php
@@ -36,7 +36,7 @@ public function handle(UpdateSubscriberSubscriptionCommand $command)
$subscriber = $command->subscriber;
$subscriptions = $command->subscriptions ?: [];
- $components = Component::all();
+ $components = Component::enabled()->get();
$updateSubscriptions = $components->filter(function ($item) use ($subscriptions) {
return in_array($item->id, $subscriptions);
@@ -47,12 +47,12 @@ public function handle(UpdateSubscriberSubscriptionCommand $command)
$subscriber->subscriptions()->delete();
if (!$updateSubscriptions->isEmpty()) {
- foreach ($updateSubscriptions as $subscription) {
+ $updateSubscriptions->each(function ($subscription) use ($subscriber) {
Subscription::firstOrCreate([
'subscriber_id' => $subscriber->id,
'component_id' => $subscription->id,
]);
- }
+ });
}
$subscriber->save();
diff --git a/app/Bus/Handlers/Commands/Subscriber/VerifySubscriberCommandHandler.php b/app/Bus/Handlers/Commands/Subscriber/VerifySubscriberCommandHandler.php
index b5c104f681bb..d56f928f5450 100644
--- a/app/Bus/Handlers/Commands/Subscriber/VerifySubscriberCommandHandler.php
+++ b/app/Bus/Handlers/Commands/Subscriber/VerifySubscriberCommandHandler.php
@@ -30,8 +30,7 @@ public function handle(VerifySubscriberCommand $command)
$subscriber = $command->subscriber;
// Mark the subscriber as verified.
- $subscriber->verified_at = Carbon::now();
- $subscriber->save();
+ $subscriber->update(['verified_at' => Carbon::now()]);
event(new SubscriberHasVerifiedEvent($subscriber));
}
diff --git a/app/Bus/Handlers/Commands/System/Config/UpdateConfigCommandHandler.php b/app/Bus/Handlers/Commands/System/Config/UpdateConfigCommandHandler.php
new file mode 100644
index 000000000000..ff7d1f4e101e
--- /dev/null
+++ b/app/Bus/Handlers/Commands/System/Config/UpdateConfigCommandHandler.php
@@ -0,0 +1,68 @@
+
+ */
+class UpdateConfigCommandHandler
+{
+ /**
+ * Handle update config command handler instance.
+ *
+ * @param \CachetHQ\Cachet\Bus\Commands\System\Config\UpdateConfigCommand $command
+ *
+ * @return void
+ */
+ public function handle(UpdateConfigCommand $command)
+ {
+ foreach ($command->values as $setting => $value) {
+ $this->writeEnv($setting, $value);
+ }
+ }
+
+ /**
+ * Writes to the .env file with given parameters.
+ *
+ * @param string $key
+ * @param mixed $value
+ *
+ * @return void
+ */
+ protected function writeEnv($key, $value)
+ {
+ $dir = app()->environmentPath();
+ $file = app()->environmentFile();
+ $path = "{$dir}/{$file}";
+
+ try {
+ (new Dotenv($dir, $file))->load();
+
+ $envKey = strtoupper($key);
+ $envValue = env($envKey) ?: 'null';
+
+ file_put_contents($path, str_replace(
+ "{$envKey}={$envValue}",
+ "{$envKey}={$value}",
+ file_get_contents($path)
+ ));
+ } catch (InvalidPathException $e) {
+ throw $e;
+ }
+ }
+}
diff --git a/app/Bus/Handlers/Commands/User/AddUserCommandHandler.php b/app/Bus/Handlers/Commands/User/CreateUserCommandHandler.php
similarity index 66%
rename from app/Bus/Handlers/Commands/User/AddUserCommandHandler.php
rename to app/Bus/Handlers/Commands/User/CreateUserCommandHandler.php
index 856e33bbb0d7..9ae22e67b846 100644
--- a/app/Bus/Handlers/Commands/User/AddUserCommandHandler.php
+++ b/app/Bus/Handlers/Commands/User/CreateUserCommandHandler.php
@@ -11,25 +11,25 @@
namespace CachetHQ\Cachet\Bus\Handlers\Commands\User;
-use CachetHQ\Cachet\Bus\Commands\User\AddUserCommand;
-use CachetHQ\Cachet\Bus\Events\User\UserWasAddedEvent;
+use CachetHQ\Cachet\Bus\Commands\User\CreateUserCommand;
+use CachetHQ\Cachet\Bus\Events\User\UserWasCreatedEvent;
use CachetHQ\Cachet\Models\User;
/**
- * This is the add user command handler.
+ * This is the create user command handler.
*
* @author James Brooks
*/
-class AddUserCommandHandler
+class CreateUserCommandHandler
{
/**
* Handle the add user command.
*
- * @param \CachetHQ\Cachet\Bus\Commands\User\AddUserCommand $command
+ * @param \CachetHQ\Cachet\Bus\Commands\User\CreateUserCommand $command
*
* @return \CachetHQ\Cachet\Models\User
*/
- public function handle(AddUserCommand $command)
+ public function handle(CreateUserCommand $command)
{
$user = User::create([
'username' => $command->username,
@@ -38,7 +38,7 @@ public function handle(AddUserCommand $command)
'level' => $command->level,
]);
- event(new UserWasAddedEvent($user));
+ event(new UserWasCreatedEvent($user));
return $user;
}
diff --git a/app/Bus/Handlers/Commands/User/GenerateApiTokenCommandHandler.php b/app/Bus/Handlers/Commands/User/GenerateApiTokenCommandHandler.php
index 99efbe41e3a3..f7b8ab539092 100644
--- a/app/Bus/Handlers/Commands/User/GenerateApiTokenCommandHandler.php
+++ b/app/Bus/Handlers/Commands/User/GenerateApiTokenCommandHandler.php
@@ -12,6 +12,7 @@
namespace CachetHQ\Cachet\Bus\Handlers\Commands\User;
use CachetHQ\Cachet\Bus\Commands\User\GenerateApiTokenCommand;
+use CachetHQ\Cachet\Bus\Events\User\UserRegeneratedApiTokenEvent;
use CachetHQ\Cachet\Models\User;
class GenerateApiTokenCommandHandler
@@ -27,9 +28,8 @@ public function handle(GenerateApiTokenCommand $command)
{
$user = $command->user;
- $user->api_key = User::generateApiKey();
- $user->save();
+ $user->update(['api_key' => User::generateApiKey()]);
- //event(new GeneratedApiTokenEvent($user));
+ event(new UserRegeneratedApiTokenEvent($user));
}
}
diff --git a/app/Bus/Handlers/Commands/User/InviteUserCommandHandler.php b/app/Bus/Handlers/Commands/User/InviteUserCommandHandler.php
index fc515d5e6c1c..164a4220308b 100644
--- a/app/Bus/Handlers/Commands/User/InviteUserCommandHandler.php
+++ b/app/Bus/Handlers/Commands/User/InviteUserCommandHandler.php
@@ -14,6 +14,7 @@
use CachetHQ\Cachet\Bus\Commands\User\InviteUserCommand;
use CachetHQ\Cachet\Bus\Events\User\UserWasInvitedEvent;
use CachetHQ\Cachet\Models\Invite;
+use CachetHQ\Cachet\Notifications\User\InviteUserNotification;
/**
* This is the invite user command handler.
@@ -36,6 +37,8 @@ public function handle(InviteUserCommand $command)
'email' => $email,
]);
+ $invite->notify(new InviteUserNotification());
+
event(new UserWasInvitedEvent($invite));
}
}
diff --git a/app/Bus/Handlers/Commands/User/SignupUserCommandHandler.php b/app/Bus/Handlers/Commands/User/SignupUserCommandHandler.php
index 740b8a4c0eab..bb274a2faac0 100644
--- a/app/Bus/Handlers/Commands/User/SignupUserCommandHandler.php
+++ b/app/Bus/Handlers/Commands/User/SignupUserCommandHandler.php
@@ -12,7 +12,7 @@
namespace CachetHQ\Cachet\Bus\Handlers\Commands\User;
use CachetHQ\Cachet\Bus\Commands\User\SignupUserCommand;
-use CachetHQ\Cachet\Bus\Events\User\UserWasAddedEvent;
+use CachetHQ\Cachet\Bus\Events\User\UserWasCreatedEvent;
use CachetHQ\Cachet\Models\User;
class SignupUserCommandHandler
@@ -33,7 +33,7 @@ public function handle(SignupUserCommand $command)
'level' => User::LEVEL_USER,
]);
- event(new UserWasAddedEvent($user));
+ event(new UserWasCreatedEvent($user));
return $user;
}
diff --git a/app/Bus/Handlers/Events/ActionStorageHandler.php b/app/Bus/Handlers/Events/ActionStorageHandler.php
new file mode 100644
index 000000000000..3ccc7a0fbe38
--- /dev/null
+++ b/app/Bus/Handlers/Events/ActionStorageHandler.php
@@ -0,0 +1,49 @@
+
+ * @author James Brooks
+ */
+class ActionStorageHandler
+{
+ /**
+ * Handle the any actions that need storing.
+ *
+ * @param \CachetHQ\Cachet\Bus\Events\ActionInterface $event
+ *
+ * @return void
+ */
+ public function handle(ActionInterface $event)
+ {
+ $data = $event->getAction();
+
+ $action = [
+ 'class_name' => get_class($event),
+ 'user_id' => $data['user']->id,
+ 'username' => $data['user']->username,
+ 'description' => $data['description'],
+ ];
+
+ if (isset($data['information'])) {
+ $action['information'] = $data['information'];
+ }
+
+ Action::create($action);
+ }
+}
diff --git a/app/Bus/Handlers/Events/Beacon/LogBeaconFailedHandler.php b/app/Bus/Handlers/Events/Beacon/LogBeaconFailedHandler.php
new file mode 100644
index 000000000000..f69cf49f2c0a
--- /dev/null
+++ b/app/Bus/Handlers/Events/Beacon/LogBeaconFailedHandler.php
@@ -0,0 +1,34 @@
+
+ */
+class LogBeaconFailedHandler
+{
+ /**
+ * Handle the event.
+ *
+ * @param \CachetHQ\Cachet\Bus\Events\Beacon\BeaconFailedToSendEvent $event
+ *
+ * @return void
+ */
+ public function handle(BeaconFailedToSendEvent $event)
+ {
+ logger('Beacon failed.');
+ }
+}
diff --git a/app/Bus/Handlers/Events/Component/SendComponentUpdateEmailNotificationHandler.php b/app/Bus/Handlers/Events/Component/SendComponentUpdateEmailNotificationHandler.php
index 6d0b747d1e35..6ecdbfca3a0f 100644
--- a/app/Bus/Handlers/Events/Component/SendComponentUpdateEmailNotificationHandler.php
+++ b/app/Bus/Handlers/Events/Component/SendComponentUpdateEmailNotificationHandler.php
@@ -11,21 +11,20 @@
namespace CachetHQ\Cachet\Bus\Handlers\Events\Component;
-use CachetHQ\Cachet\Bus\Events\Component\ComponentStatusWasUpdatedEvent;
+use CachetHQ\Cachet\Bus\Events\Component\ComponentStatusWasChangedEvent;
+use CachetHQ\Cachet\Integrations\Contracts\System;
use CachetHQ\Cachet\Models\Component;
use CachetHQ\Cachet\Models\Subscriber;
-use Illuminate\Contracts\Mail\MailQueue;
-use Illuminate\Mail\Message;
-use McCool\LaravelAutoPresenter\Facades\AutoPresenter;
+use CachetHQ\Cachet\Notifications\Component\ComponentStatusChangedNotification;
class SendComponentUpdateEmailNotificationHandler
{
/**
- * The mailer instance.
+ * The system instance.
*
- * @var \Illuminate\Contracts\Mail\Mailer
+ * @var \CachetHQ\Cachet\Integrations\Contracts\System
*/
- protected $mailer;
+ protected $system;
/**
* The subscriber instance.
@@ -37,34 +36,43 @@ class SendComponentUpdateEmailNotificationHandler
/**
* Create a new send incident email notification handler.
*
- * @param \Illuminate\Contracts\Mail\Mailer $mailer
* @param \CachetHQ\Cachet\Models\Subscriber $subscriber
*
* @return void
*/
- public function __construct(MailQueue $mailer, Subscriber $subscriber)
+ public function __construct(System $system, Subscriber $subscriber)
{
- $this->mailer = $mailer;
+ $this->system = $system;
$this->subscriber = $subscriber;
}
/**
* Handle the event.
*
- * @param \CachetHQ\Cachet\Bus\Events\Component\ComponentStatusWasUpdatedEvent $event
+ * @param \CachetHQ\Cachet\Bus\Events\Component\ComponentStatusWasChangedEvent $event
*
* @return void
*/
- public function handle(ComponentStatusWasUpdatedEvent $event)
+ public function handle(ComponentStatusWasChangedEvent $event)
{
$component = $event->component;
+ // If we're silent or the notifications are suppressed don't send this.
+ if ($event->silent || !$this->system->canNotifySubscribers()) {
+ return;
+ }
+
+ // Don't email anything if the status hasn't changed.
+ if ($event->original_status === $event->new_status) {
+ return;
+ }
+
// First notify all global subscribers.
$globalSubscribers = $this->subscriber->isVerified()->isGlobal()->get();
- foreach ($globalSubscribers as $subscriber) {
- $this->notify($component, $subscriber);
- }
+ $globalSubscribers->each(function ($subscriber) use ($component, $event) {
+ $subscriber->notify(new ComponentStatusChangedNotification($component, $event->new_status));
+ });
$notified = $globalSubscribers->pluck('id')->all();
@@ -77,37 +85,8 @@ public function handle(ComponentStatusWasUpdatedEvent $event)
return in_array($subscriber->id, $notified);
});
- foreach ($componentSubscribers as $subscriber) {
- $this->notify($component, $subscriber);
- }
- }
-
- /**
- * Send notification to subscriber.
- *
- * @param \CachetHQ\Cachet\Models\Component $component
- * @param \CachetHQ\Cachet\Models\Subscriber $subscriber
- *
- * @return \Illuminate\Database\Eloquent\Collection
- */
- public function notify(Component $component, Subscriber $subscriber)
- {
- $component = AutoPresenter::decorate($component);
-
- $mail = [
- 'subject' => trans('cachet.subscriber.email.component.subject'),
- 'component_name' => $component->name,
- 'component_human_status' => $component->human_status,
- ];
-
- $mail['email'] = $subscriber->email;
- $mail['manage_link'] = route('subscribe.manage', ['code' => $subscriber->verify_code]);
-
- $this->mailer->queue([
- 'html' => 'emails.components.update-html',
- 'text' => 'emails.components.update-text',
- ], $mail, function (Message $message) use ($mail) {
- $message->to($mail['email'])->subject($mail['subject']);
+ $componentSubscribers->each(function ($subscriber) use ($component, $event) {
+ $subscriber->notify(new ComponentStatusChangedNotification($component, $event->new_status));
});
}
}
diff --git a/app/Bus/Handlers/Events/Incident/SendIncidentEmailNotificationHandler.php b/app/Bus/Handlers/Events/Incident/SendIncidentEmailNotificationHandler.php
index 3558ff7ccd31..d30916d10de3 100644
--- a/app/Bus/Handlers/Events/Incident/SendIncidentEmailNotificationHandler.php
+++ b/app/Bus/Handlers/Events/Incident/SendIncidentEmailNotificationHandler.php
@@ -11,20 +11,19 @@
namespace CachetHQ\Cachet\Bus\Handlers\Events\Incident;
-use CachetHQ\Cachet\Bus\Events\Incident\IncidentWasReportedEvent;
+use CachetHQ\Cachet\Bus\Events\Incident\IncidentWasCreatedEvent;
+use CachetHQ\Cachet\Integrations\Contracts\System;
use CachetHQ\Cachet\Models\Subscriber;
-use Illuminate\Contracts\Mail\MailQueue;
-use Illuminate\Mail\Message;
-use McCool\LaravelAutoPresenter\Facades\AutoPresenter;
+use CachetHQ\Cachet\Notifications\Incident\NewIncidentNotification;
class SendIncidentEmailNotificationHandler
{
/**
- * The mailer instance.
+ * The system instance.
*
- * @var \Illuminate\Contracts\Mail\Mailer
+ * @var \CachetHQ\Cachet\Integrations\Contracts\System
*/
- protected $mailer;
+ protected $system;
/**
* The subscriber instance.
@@ -36,43 +35,45 @@ class SendIncidentEmailNotificationHandler
/**
* Create a new send incident email notification handler.
*
- * @param \Illuminate\Contracts\Mail\Mailer $mailer
- * @param \CachetHQ\Cachet\Models\Subscriber $subscriber
+ * @param \CachetHQ\Cachet\Integrations\Contracts\System $system
+ * @param \CachetHQ\Cachet\Models\Subscriber $subscriber
*
* @return void
*/
- public function __construct(MailQueue $mailer, Subscriber $subscriber)
+ public function __construct(System $system, Subscriber $subscriber)
{
- $this->mailer = $mailer;
+ $this->system = $system;
$this->subscriber = $subscriber;
}
/**
* Handle the event.
*
- * @param \CachetHQ\Cachet\Bus\Events\Incident\IncidentWasReportedEvent $event
+ * @param \CachetHQ\Cachet\Bus\Events\Incident\IncidentWasCreatedEvent $event
*
* @return void
*/
- public function handle(IncidentWasReportedEvent $event)
+ public function handle(IncidentWasCreatedEvent $event)
{
- if (!$event->incident->notify) {
+ $incident = $event->incident;
+
+ if (!$event->notify || !$this->system->canNotifySubscribers()) {
return false;
}
// Only send emails for public incidents.
- if ($event->incident->visible === 0) {
+ if (!$incident->visible) {
return;
}
// First notify all global subscribers.
$globalSubscribers = $this->subscriber->isVerified()->isGlobal()->get();
- foreach ($globalSubscribers as $subscriber) {
- $this->notify($event, $subscriber);
- }
+ $globalSubscribers->each(function ($subscriber) use ($incident) {
+ $subscriber->notify(new NewIncidentNotification($incident));
+ });
- if (!$event->incident->component) {
+ if (!$incident->component) {
return;
}
@@ -81,53 +82,12 @@ public function handle(IncidentWasReportedEvent $event)
// Notify the remaining component specific subscribers.
$componentSubscribers = $this->subscriber
->isVerified()
- ->forComponent($event->incident->component->id)
+ ->forComponent($incident->component->id)
->get()
->reject(function ($subscriber) use ($notified) {
return in_array($subscriber->id, $notified);
+ })->each(function ($subscriber) use ($incident) {
+ $subscriber->notify(new NewIncidentNotification($incident));
});
-
- foreach ($componentSubscribers as $subscriber) {
- $this->notify($event, $subscriber);
- }
- }
-
- /**
- * Send notification to subscriber.
- *
- * @param \CachetHQ\Cachet\Bus\Events\IncidentWasReportedEvent $event
- * @param \CachetHQ\Cachet\Models\Subscriber $subscriber
- *
- * @return \Illuminate\Database\Eloquent\Collection
- */
- public function notify(IncidentWasReportedEvent $event, $subscriber)
- {
- $incident = AutoPresenter::decorate($event->incident);
- $component = AutoPresenter::decorate($event->incident->component);
-
- $mail = [
- 'email' => $subscriber->email,
- 'subject' => trans('cachet.subscriber.email.incident.subject', [
- 'status' => $incident->human_status,
- 'name' => $incident->name,
- ]),
- 'has_component' => ($event->incident->component) ? true : false,
- 'component_name' => $component ? $component->name : null,
- 'name' => $incident->name,
- 'timestamp' => $incident->created_at_formatted,
- 'status' => $incident->human_status,
- 'html_content' => $incident->formattedMessage,
- 'text_content' => $incident->message,
- 'token' => $subscriber->token,
- 'manage_link' => route('subscribe.manage', ['code' => $subscriber->verify_code]),
- 'unsubscribe_link' => route('subscribe.unsubscribe', ['code' => $subscriber->verify_code]),
- ];
-
- $this->mailer->queue([
- 'html' => 'emails.incidents.new-html',
- 'text' => 'emails.incidents.new-text',
- ], $mail, function (Message $message) use ($mail) {
- $message->to($mail['email'])->subject($mail['subject']);
- });
}
}
diff --git a/app/Bus/Handlers/Events/Incident/SendMaintenanceEmailNotificationHandler.php b/app/Bus/Handlers/Events/Incident/SendMaintenanceEmailNotificationHandler.php
deleted file mode 100644
index d87abf6a8ae3..000000000000
--- a/app/Bus/Handlers/Events/Incident/SendMaintenanceEmailNotificationHandler.php
+++ /dev/null
@@ -1,132 +0,0 @@
-mailer = $mailer;
- $this->subscriber = $subscriber;
- }
-
- /**
- * Handle the event.
- *
- * @param \CachetHQ\Cachet\Bus\Events\MaintenanceWasScheduledEvent $event
- *
- * @return void
- */
- public function handle(MaintenanceWasScheduledEvent $event)
- {
- if (!$event->incident->notify) {
- return false;
- }
-
- // Only send emails for public incidents.
- if ($event->incident->visible === 0) {
- return;
- }
-
- // First notify all global subscribers.
- $globalSubscribers = $this->subscriber->isVerified()->isGlobal()->get();
-
- foreach ($globalSubscribers as $subscriber) {
- $this->notify($event, $subscriber);
- }
-
- if (!$event->incident->component) {
- return;
- }
-
- $notified = $globalSubscribers->pluck('id')->all();
-
- // Notify the remaining component specific subscribers.
- $componentSubscribers = $this->subscriber
- ->isVerified()
- ->forComponent($event->incident->component->id)
- ->get()
- ->reject(function ($subscriber) use ($notified) {
- return in_array($subscriber->id, $notified);
- });
-
- foreach ($componentSubscribers as $subscriber) {
- $this->notify($event, $subscriber);
- }
- }
-
- /**
- * Send notification to subscriber.
- *
- * @param \CachetHQ\Cachet\Bus\Events\MaintenanceWasScheduledEvent $event
- * @param \CachetHQ\Cachet\Models\Subscriber $subscriber
- *
- * @return \Illuminate\Database\Eloquent\Collection
- */
- public function notify(MaintenanceWasScheduledEvent $event, $subscriber)
- {
- $incident = AutoPresenter::decorate($event->incident);
- $component = AutoPresenter::decorate($event->incident->component);
-
- $mail = [
- 'email' => $subscriber->email,
- 'subject' => trans('cachet.subscriber.email.maintenance.subject', [
- 'name' => $incident->name,
- ]),
- 'has_component' => ($event->incident->component) ? true : false,
- 'component_name' => $component ? $component->name : null,
- 'name' => $incident->name,
- 'timestamp' => $incident->scheduled_at_formatted,
- 'status' => $incident->human_status,
- 'html_content' => $incident->formattedMessage,
- 'text_content' => $incident->message,
- 'token' => $subscriber->token,
- 'manage_link' => route('subscribe.manage', ['code' => $subscriber->verify_code]),
- 'unsubscribe_link' => route('subscribe.unsubscribe', ['code' => $subscriber->verify_code]),
- ];
-
- $this->mailer->queue([
- 'html' => 'emails.incidents.maintenance-html',
- 'text' => 'emails.incidents.maintenance-text',
- ], $mail, function (Message $message) use ($mail) {
- $message->to($mail['email'])->subject($mail['subject']);
- });
- }
-}
diff --git a/app/Bus/Handlers/Events/IncidentUpdate/SendIncidentUpdateEmailNotificationHandler.php b/app/Bus/Handlers/Events/IncidentUpdate/SendIncidentUpdateEmailNotificationHandler.php
new file mode 100644
index 000000000000..447604816e4d
--- /dev/null
+++ b/app/Bus/Handlers/Events/IncidentUpdate/SendIncidentUpdateEmailNotificationHandler.php
@@ -0,0 +1,90 @@
+system = $system;
+ $this->subscriber = $subscriber;
+ }
+
+ /**
+ * Handle the event.
+ *
+ * @param \CachetHQ\Cachet\Bus\Events\IncidentUpdate\IncidentUpdateWasReportedEvent $event
+ *
+ * @return void
+ */
+ public function handle(IncidentUpdateWasReportedEvent $event)
+ {
+ $update = $event->update;
+ $incident = $update->incident;
+
+ // Only send emails for public incidents while the system is not under scheduled maintenance.
+ if (!$incident->visible || !$this->system->canNotifySubscribers()) {
+ return;
+ }
+
+ // First notify all global subscribers.
+ $globalSubscribers = $this->subscriber->isVerified()->isGlobal()->get();
+
+ $globalSubscribers->each(function ($subscriber) use ($update) {
+ $subscriber->notify(new IncidentUpdatedNotification($update));
+ });
+
+ if (!$incident->component) {
+ return;
+ }
+
+ $notified = $globalSubscribers->pluck('id')->all();
+
+ // Notify the remaining component specific subscribers.
+ $componentSubscribers = $this->subscriber
+ ->isVerified()
+ ->forComponent($incident->component->id)
+ ->get()
+ ->reject(function ($subscriber) use ($notified) {
+ return in_array($subscriber->id, $notified);
+ })->each(function ($subscriber) use ($update) {
+ $subscriber->notify(new IncidentUpdatedNotification($update));
+ });
+ }
+}
diff --git a/app/Bus/Handlers/Events/Schedule/SendScheduleEmailNotificationHandler.php b/app/Bus/Handlers/Events/Schedule/SendScheduleEmailNotificationHandler.php
new file mode 100644
index 000000000000..84e9db31d616
--- /dev/null
+++ b/app/Bus/Handlers/Events/Schedule/SendScheduleEmailNotificationHandler.php
@@ -0,0 +1,63 @@
+
+ */
+class SendScheduleEmailNotificationHandler
+{
+ /**
+ * The subscriber instance.
+ *
+ * @var \CachetHQ\Cachet\Models\Subscriber
+ */
+ protected $subscriber;
+
+ /**
+ * Create a new send schedule email notification handler.
+ *
+ * @param \CachetHQ\Cachet\Models\Subscriber $subscriber
+ *
+ * @return void
+ */
+ public function __construct(Subscriber $subscriber)
+ {
+ $this->subscriber = $subscriber;
+ }
+
+ /**
+ * Handle the event.
+ *
+ * @param \CachetHQ\Cachet\Bus\Events\Schedule\ScheduleEventInterface $event
+ *
+ * @return void
+ */
+ public function handle(ScheduleEventInterface $event)
+ {
+ $schedule = $event->schedule;
+ if (!$event->notify) {
+ return false;
+ }
+
+ // First notify all global subscribers.
+ $globalSubscribers = $this->subscriber->isVerified()->isGlobal()->get()->each(function ($subscriber) use ($schedule) {
+ $subscriber->notify(new NewScheduleNotification($schedule));
+ });
+ }
+}
diff --git a/app/Bus/Handlers/Events/Subscriber/SendSubscriberVerificationEmailHandler.php b/app/Bus/Handlers/Events/Subscriber/SendSubscriberVerificationEmailHandler.php
deleted file mode 100644
index 306280dcfc1a..000000000000
--- a/app/Bus/Handlers/Events/Subscriber/SendSubscriberVerificationEmailHandler.php
+++ /dev/null
@@ -1,61 +0,0 @@
-mailer = $mailer;
- }
-
- /**
- * Handle the event.
- *
- * @param \CachetHQ\Cachet\Bus\Events\SubscriberHasSubscribedEvent $event
- *
- * @return void
- */
- public function handle(SubscriberHasSubscribedEvent $event)
- {
- $mail = [
- 'email' => $event->subscriber->email,
- 'subject' => 'Confirm your subscription.',
- 'link' => route('subscribe.verify', ['code' => $event->subscriber->verify_code]),
- ];
-
- $this->mailer->queue([
- 'html' => 'emails.subscribers.verify-html',
- 'text' => 'emails.subscribers.verify-text',
- ], $mail, function (Message $message) use ($mail) {
- $message->to($mail['email'])->subject($mail['subject']);
- });
- }
-}
diff --git a/app/Bus/Handlers/Events/User/SendInviteUserEmailHandler.php b/app/Bus/Handlers/Events/User/SendInviteUserEmailHandler.php
deleted file mode 100644
index 419baa3a9615..000000000000
--- a/app/Bus/Handlers/Events/User/SendInviteUserEmailHandler.php
+++ /dev/null
@@ -1,61 +0,0 @@
-mailer = $mailer;
- }
-
- /**
- * Handle the event.
- *
- * @param \CachetHQ\Cachet\Bus\Events\UserWasInvitedEvent $event
- *
- * @return void
- */
- public function handle(UserWasInvitedEvent $event)
- {
- $mail = [
- 'email' => $event->invite->email,
- 'subject' => 'You have been invited.',
- 'link' => route('signup.invite', ['code' => $event->invite->code]),
- ];
-
- $this->mailer->queue([
- 'html' => 'emails.users.invite-html',
- 'text' => 'emails.users.invite-text',
- ], $mail, function (Message $message) use ($mail) {
- $message->to($mail['email'])->subject($mail['subject']);
- });
- }
-}
diff --git a/app/Bus/Handlers/Jobs/System/SendBeaconJobHandler.php b/app/Bus/Handlers/Jobs/System/SendBeaconJobHandler.php
index 0d3025dc6650..da0eb87d1bb7 100644
--- a/app/Bus/Handlers/Jobs/System/SendBeaconJobHandler.php
+++ b/app/Bus/Handlers/Jobs/System/SendBeaconJobHandler.php
@@ -44,7 +44,7 @@ public function __construct(Beacon $beacon)
/**
* Handle the send beacon job.
*
- * @param \CachetHQ\Cachet\Bus\Jobs\SendBeaconJob $job
+ * @param \CachetHQ\Cachet\Bus\Jobs\System\SendBeaconJob $job
*
* @return void
*/
diff --git a/app/Bus/Handlers/Traits/StoresMeta.php b/app/Bus/Handlers/Traits/StoresMeta.php
new file mode 100644
index 000000000000..e5272ba51b45
--- /dev/null
+++ b/app/Bus/Handlers/Traits/StoresMeta.php
@@ -0,0 +1,81 @@
+ $value) {
+ $modelInstance = call_user_func(
+ [$metaModel, 'firstOrNew'],
+ [
+ 'key' => $key,
+ 'meta_type' => $metaType,
+ 'meta_id' => $metaId,
+ ]
+ );
+
+ $value = $this->removeEmptyValues($value);
+ if (!empty($value)) {
+ $modelInstance->setAttribute('value', $value);
+ $modelInstance->save();
+ continue;
+ }
+
+ // The value is empty, remove the row
+ if ($modelInstance->exists) {
+ $modelInstance->delete();
+ }
+ }
+ }
+
+ /**
+ * Determine if a Value is empty.
+ *
+ * @param mixed $values
+ *
+ * @return array|mixed
+ */
+ protected function removeEmptyValues($values)
+ {
+ if (!is_array($values)) {
+ return empty($values) ? null : $values;
+ }
+
+ foreach ($values as $key => $value) {
+ if (!empty($value)) {
+ continue;
+ }
+ unset($values[$key]);
+ }
+
+ return $values;
+ }
+}
diff --git a/app/Composers/AppComposer.php b/app/Composers/AppComposer.php
index c9b4122cfe1c..822b30f2615a 100644
--- a/app/Composers/AppComposer.php
+++ b/app/Composers/AppComposer.php
@@ -11,17 +11,23 @@
namespace CachetHQ\Cachet\Composers;
-use CachetHQ\Cachet\Dates\DateFactory;
+use CachetHQ\Cachet\Services\Dates\DateFactory;
use GrahamCampbell\Markdown\Facades\Markdown;
use Illuminate\Contracts\Config\Repository;
use Illuminate\Contracts\View\View;
+/**
+ * This is the app composer class.
+ *
+ * @author James Brooks
+ * @author Graham Campbell
+ */
class AppComposer
{
/**
* The date factory instance.
*
- * @var \CachetHQ\Cachet\Dates\DateFactory
+ * @var \CachetHQ\Cachet\Services\Dates\DateFactory
*/
protected $dates;
@@ -35,8 +41,8 @@ class AppComposer
/**
* Create a new app composer instance.
*
- * @param \CachetHQ\Cachet\Dates\DateFactory $dates
- * @param \Illuminate\Contracts\Config\Repository $config
+ * @param \CachetHQ\Cachet\Services\Dates\DateFactory $dates
+ * @param \Illuminate\Contracts\Config\Repository $config
*
* @return void
*/
@@ -55,7 +61,13 @@ public function __construct(DateFactory $dates, Repository $config)
*/
public function compose(View $view)
{
- $view->withAboutApp(Markdown::convertToHtml($this->config->get('setting.app_about')));
+ if ($this->config->get('setting.app_about')) {
+ $about = Markdown::convertToHtml($this->config->get('setting.app_about'));
+ } else {
+ $about = '';
+ }
+
+ $view->withAboutApp($about);
$view->withAppAnalytics($this->config->get('setting.app_analytics'));
$view->withAppAnalyticsGoSquared($this->config->get('setting.app_analytics_gs'));
$view->withAppAnalyticsPiwikUrl($this->config->get('setting.app_analytics_piwik_url'));
@@ -75,8 +87,12 @@ public function compose(View $view)
$view->withAutomaticLocalization($this->config->get('setting.automatic_localization'));
$view->withEnableExternalDependencies($this->config->get('setting.enable_external_dependencies'));
$view->withShowTimezone($this->config->get('setting.show_timezone'));
+ $view->withAppRefreshRate($this->config->get('setting.app_refresh_rate'));
$view->withTimezone($this->dates->getTimezone());
$view->withSiteTitle($this->config->get('setting.app_name'));
$view->withFontSubset($this->config->get('langs.'.$this->config->get('app.locale').'.subset', 'latin'));
+ $view->withOnlyDisruptedDays($this->config->get('setting.only_disrupted_days'));
+ $view->withDashboardLink($this->config->get('setting.dashboard_login_link'));
+ $view->withEnableSubscribers($this->config->get('setting.enable_subscribers'));
}
}
diff --git a/app/Composers/ComponentsComposer.php b/app/Composers/ComponentsComposer.php
new file mode 100644
index 000000000000..1fac9423df71
--- /dev/null
+++ b/app/Composers/ComponentsComposer.php
@@ -0,0 +1,79 @@
+
+ * @author Connor S. Parks
+ */
+class ComponentsComposer
+{
+ /**
+ * The user session object.
+ *
+ * @var \Illuminate\Contracts\Auth\Guard
+ */
+ protected $guard;
+
+ /**
+ * Creates a new components composer instance.
+ *
+ * @param \Illuminate\Contracts\Auth\Guard $guard
+ *
+ * @return void
+ */
+ public function __construct(Guard $guard)
+ {
+ $this->guard = $guard;
+ }
+
+ /**
+ * Bind data to the view.
+ *
+ * @param \Illuminate\Contracts\View\View $view
+ *
+ * @return void
+ */
+ public function compose(View $view)
+ {
+ $componentGroups = $this->getVisibleGroupedComponents();
+ $ungroupedComponents = Component::ungrouped()->orderBy('status', 'desc')->get();
+
+ $view->withComponentGroups($componentGroups)
+ ->withUngroupedComponents($ungroupedComponents);
+ }
+
+ /**
+ * Get visible grouped components.
+ *
+ * @return \Illuminate\Support\Collection
+ */
+ protected function getVisibleGroupedComponents()
+ {
+ $componentGroupsBuilder = ComponentGroup::query();
+ if (!$this->guard->check()) {
+ $componentGroupsBuilder->visible();
+ }
+
+ $usedComponentGroups = Component::grouped()->pluck('group_id');
+
+ return $componentGroupsBuilder->used($usedComponentGroups)
+ ->get();
+ }
+}
diff --git a/app/Composers/CurrentUserComposer.php b/app/Composers/CurrentUserComposer.php
index 7543ad8d2af3..d7afe3b9603d 100644
--- a/app/Composers/CurrentUserComposer.php
+++ b/app/Composers/CurrentUserComposer.php
@@ -13,7 +13,15 @@
use Illuminate\Contracts\View\View;
use Illuminate\Support\Facades\Auth;
+use McCool\LaravelAutoPresenter\Facades\AutoPresenter;
+/**
+ * This is the current user composer class.
+ *
+ * @author Joseph Cohen
+ * @author James Brooks
+ * @author Graham Campbell
+ */
class CurrentUserComposer
{
/**
@@ -25,6 +33,6 @@ class CurrentUserComposer
*/
public function compose(View $view)
{
- $view->withCurrentUser(Auth::user());
+ $view->withCurrentUser(AutoPresenter::decorate(Auth::user()));
}
}
diff --git a/app/Composers/DashboardComposer.php b/app/Composers/DashboardComposer.php
index e36c9fd03ce1..c5ccef937ce1 100644
--- a/app/Composers/DashboardComposer.php
+++ b/app/Composers/DashboardComposer.php
@@ -14,11 +14,81 @@
use CachetHQ\Cachet\Models\Component;
use CachetHQ\Cachet\Models\Incident;
use CachetHQ\Cachet\Models\IncidentTemplate;
+use CachetHQ\Cachet\Models\Schedule;
use CachetHQ\Cachet\Models\Subscriber;
use Illuminate\Contracts\View\View;
+/**
+ * This is the dashboard composer class.
+ *
+ * @author James Brooks
+ * @author Graham Campbell
+ */
class DashboardComposer
{
+ /**
+ * The component count.
+ *
+ * @var int
+ */
+ protected $componentCount;
+
+ /**
+ * The incident count.
+ *
+ * @var int
+ */
+ protected $incidentCount;
+
+ /**
+ * The incident template count.
+ *
+ * @var int
+ */
+ protected $incidentTemplateCount;
+
+ /**
+ * The schedule count.
+ *
+ * @var int
+ */
+ protected $scheduleCount;
+
+ /**
+ * The subscriber count.
+ *
+ * @var int
+ */
+ protected $subscriberCount;
+
+ /**
+ * Create a new dashboard composer instance.
+ *
+ * @return void
+ */
+ public function __construct()
+ {
+ if (is_null($this->componentCount)) {
+ $this->componentCount = Component::count();
+ }
+
+ if (is_null($this->incidentCount)) {
+ $this->incidentCount = Incident::count();
+ }
+
+ if (is_null($this->incidentTemplateCount)) {
+ $this->incidentTemplateCount = IncidentTemplate::count();
+ }
+
+ if (is_null($this->scheduleCount)) {
+ $this->scheduleCount = Schedule::count();
+ }
+
+ if (is_null($this->subscriberCount)) {
+ $this->subscriberCount = Subscriber::isVerified()->count();
+ }
+ }
+
/**
* Bind data to the view.
*
@@ -28,9 +98,11 @@ class DashboardComposer
*/
public function compose(View $view)
{
- $view->withIncidentCount(Incident::notScheduled()->count());
- $view->withIncidentTemplateCount(IncidentTemplate::count());
- $view->withComponentCount(Component::all()->count());
- $view->withSubscriberCount(Subscriber::isVerified()->count());
+ $view->withComponentCount($this->componentCount);
+ $view->withIncidentCount($this->incidentCount);
+ $view->withIncidentTemplateCount($this->incidentTemplateCount);
+ $view->withScheduleCount($this->scheduleCount);
+ $view->withSubscriberCount($this->subscriberCount);
+ $view->withIsWriteable(is_writable(app()->bootstrapPath().'/cachet'));
}
}
diff --git a/app/Composers/MetricsComposer.php b/app/Composers/MetricsComposer.php
new file mode 100644
index 000000000000..e6e32e9f7f19
--- /dev/null
+++ b/app/Composers/MetricsComposer.php
@@ -0,0 +1,92 @@
+
+ * @author Connor S. Parks
+ */
+class MetricsComposer
+{
+ /**
+ * The illuminate config instance.
+ *
+ * @var \Illuminate\Contracts\Config\Repository
+ */
+ protected $config;
+
+ /**
+ * The user session object.
+ *
+ * @var \Illuminate\Contracts\Auth\Guard
+ */
+ protected $guard;
+
+ /**
+ * Create a new metrics composer instance.
+ *
+ * @param \Illuminate\Contracts\Config\Repository $config
+ * @param \Illuminate\Contracts\Auth\Guard $guard
+ *
+ * @return void
+ */
+ public function __construct(Repository $config, Guard $guard)
+ {
+ $this->config = $config;
+ $this->guard = $guard;
+ }
+
+ /**
+ * Bind data to the view.
+ *
+ * @param \Illuminate\Contracts\View\View $view
+ *
+ * @return void
+ */
+ public function compose(View $view)
+ {
+ $displayMetrics = $this->config->get('setting.display_graphs');
+ $metrics = $this->getVisibleMetrics($displayMetrics);
+
+ $view->withDisplayMetrics($displayMetrics)
+ ->withMetrics($metrics);
+ }
+
+ /**
+ * Get visible grouped components.
+ *
+ * @param bool $displayMetrics
+ *
+ * @return \Illuminate\Support\Collection|void
+ */
+ protected function getVisibleMetrics($displayMetrics)
+ {
+ if (!$displayMetrics) {
+ return;
+ }
+
+ $metrics = Metric::displayable();
+
+ if (!$this->guard->check()) {
+ $metrics->visible();
+ }
+
+ return $metrics->orderBy('order')->orderBy('id')->get();
+ }
+}
diff --git a/app/Composers/ModuleComposer.php b/app/Composers/ModuleComposer.php
deleted file mode 100644
index f15c186d9d8d..000000000000
--- a/app/Composers/ModuleComposer.php
+++ /dev/null
@@ -1,71 +0,0 @@
-app = $app;
- $this->manager = $manager;
- }
-
- /**
- * Bind data to the view.
- *
- * @param \Illuminate\Contracts\View\View $view
- *
- * @return void
- */
- public function compose(View $view)
- {
- $key = $view->getName();
-
- $view->with('view', $key);
-
- $modules = "view.modules: {$key}";
- $groups = "view.groups: {$key}";
-
- $modules = $this->app->bound($modules) ? $this->app[$modules] : [];
- $groups = $this->app->bound($groups) ? $this->app[$groups] : [];
-
- $modules = $this->manager->groupModules($modules, $groups);
-
- $view->withModules($modules);
- }
-}
diff --git a/app/Composers/Modules/ComponentsComposer.php b/app/Composers/Modules/ComponentsComposer.php
deleted file mode 100644
index a5df06ba5c11..000000000000
--- a/app/Composers/Modules/ComponentsComposer.php
+++ /dev/null
@@ -1,43 +0,0 @@
-
- * @author Connor S. Parks
- */
-class ComponentsComposer
-{
- /**
- * Index page view composer.
- *
- * @param \Illuminate\Contracts\View\View $view
- *
- * @return void
- */
- public function compose(View $view)
- {
- // Component & Component Group lists.
- $usedComponentGroups = Component::enabled()->where('group_id', '>', 0)->groupBy('group_id')->pluck('group_id');
- $componentGroups = ComponentGroup::whereIn('id', $usedComponentGroups)->orderBy('order')->get();
- $ungroupedComponents = Component::enabled()->where('group_id', 0)->orderBy('order')->orderBy('created_at')->get();
-
- $view->withComponentGroups($componentGroups)
- ->withUngroupedComponents($ungroupedComponents);
- }
-}
diff --git a/app/Composers/Modules/MetricsComposer.php b/app/Composers/Modules/MetricsComposer.php
deleted file mode 100644
index 83870afbae0d..000000000000
--- a/app/Composers/Modules/MetricsComposer.php
+++ /dev/null
@@ -1,56 +0,0 @@
-config = $config;
- }
-
- /**
- * Metrics view composer.
- *
- * @param \Illuminate\Contracts\View\View $view
- *
- * @return void
- */
- public function compose(View $view)
- {
- $metrics = null;
- if ($displayMetrics = $this->config->get('setting.display_graphs')) {
- $metrics = Metric::displayable()->orderBy('order')->orderBy('id')->get();
- }
-
- $view->withDisplayMetrics($displayMetrics)
- ->withMetrics($metrics);
- }
-}
diff --git a/app/Composers/Modules/ScheduledComposer.php b/app/Composers/ScheduledComposer.php
similarity index 71%
rename from app/Composers/Modules/ScheduledComposer.php
rename to app/Composers/ScheduledComposer.php
index 4dac2fe45933..0e65b4a89245 100644
--- a/app/Composers/Modules/ScheduledComposer.php
+++ b/app/Composers/ScheduledComposer.php
@@ -9,13 +9,13 @@
* file that was distributed with this source code.
*/
-namespace CachetHQ\Cachet\Composers\Modules;
+namespace CachetHQ\Cachet\Composers;
-use CachetHQ\Cachet\Models\Incident;
+use CachetHQ\Cachet\Models\Schedule;
use Illuminate\Contracts\View\View;
/**
- * This is the status page composer.
+ * This is the scheduled composer.
*
* @author James Brooks
* @author Connor S. Parks
@@ -23,7 +23,7 @@
class ScheduledComposer
{
/**
- * Index page view composer.
+ * Bind data to the view.
*
* @param \Illuminate\Contracts\View\View $view
*
@@ -31,7 +31,7 @@ class ScheduledComposer
*/
public function compose(View $view)
{
- $scheduledMaintenance = Incident::scheduled()->orderBy('scheduled_at')->get();
+ $scheduledMaintenance = Schedule::uncompleted()->orderBy('scheduled_at')->get();
$view->withScheduledMaintenance($scheduledMaintenance);
}
diff --git a/app/Composers/SettingsComposer.php b/app/Composers/SettingsComposer.php
new file mode 100644
index 000000000000..aa0ff2fac6c3
--- /dev/null
+++ b/app/Composers/SettingsComposer.php
@@ -0,0 +1,80 @@
+
+ */
+class SettingsComposer
+{
+ /**
+ * Array of cache drivers.
+ *
+ * @var string[]
+ */
+ protected $cacheDrivers = [
+ 'apc' => 'APC(u)',
+ 'array' => 'Array',
+ 'database' => 'Database',
+ 'file' => 'File',
+ 'memcached' => 'Memcached',
+ 'redis' => 'Redis',
+ ];
+
+ /**
+ * Array of cache drivers.
+ *
+ * @var string[]
+ */
+ protected $mailDrivers = [
+ 'smtp' => 'SMTP',
+ 'mail' => 'Mail',
+ 'sendmail' => 'Sendmail',
+ 'mailgun' => 'Mailgun',
+ 'mandrill' => 'Mandrill',
+ 'ses' => 'Amazon SES',
+ 'sparkpost' => 'SparkPost',
+ 'log' => 'Log (Testing)',
+ ];
+
+ /**
+ * Array of queue drivers.
+ *
+ * @var string[]
+ */
+ protected $queueDrivers = [
+ 'null' => 'None',
+ 'sync' => 'Synchronous',
+ 'database' => 'Database',
+ 'beanstalkd' => 'Beanstalk',
+ 'sqs' => 'Amazon SQS',
+ 'redis' => 'Redis',
+ ];
+
+ /**
+ * Bind data to the view.
+ *
+ * @param \Illuminate\Contracts\View\View $view
+ *
+ * @return void
+ */
+ public function compose(View $view)
+ {
+ $view->withCacheDrivers($this->cacheDrivers);
+ $view->withMailDrivers($this->mailDrivers);
+ $view->withQueueDrivers($this->queueDrivers);
+ }
+}
diff --git a/app/Composers/Modules/StatusComposer.php b/app/Composers/StatusComposer.php
similarity index 72%
rename from app/Composers/Modules/StatusComposer.php
rename to app/Composers/StatusComposer.php
index f507021e14fd..6b953343e9a7 100644
--- a/app/Composers/Modules/StatusComposer.php
+++ b/app/Composers/StatusComposer.php
@@ -9,13 +9,14 @@
* file that was distributed with this source code.
*/
-namespace CachetHQ\Cachet\Composers\Modules;
+namespace CachetHQ\Cachet\Composers;
use CachetHQ\Cachet\Integrations\Contracts\System;
use Illuminate\Contracts\View\View;
+use Illuminate\Support\Arr;
/**
- * This is the status page composer.
+ * This is the status composer.
*
* @author James Brooks
* @author Connor S. Parks
@@ -30,7 +31,7 @@ class StatusComposer
protected $system;
/**
- * Create a new status page composer instance.
+ * Create a new status composer instance.
*
* @param \CachetHQ\Cachet\Integrations\Contracts\System $system
*
@@ -42,7 +43,7 @@ public function __construct(System $system)
}
/**
- * Index page view composer.
+ * Bind data to the view.
*
* @param \Illuminate\Contracts\View\View $view
*
@@ -50,6 +51,9 @@ public function __construct(System $system)
*/
public function compose(View $view)
{
- $view->with($this->system->getStatus());
+ $status = $this->system->getStatus();
+
+ $view->withSystemStatus(Arr::get($status, 'system_status'));
+ $view->withSystemMessage(Arr::get($status, 'system_message'));
}
}
diff --git a/app/Composers/Modules/StickiedComposer.php b/app/Composers/StickiedComposer.php
similarity index 65%
rename from app/Composers/Modules/StickiedComposer.php
rename to app/Composers/StickiedComposer.php
index dfb186599936..82e357f395e2 100644
--- a/app/Composers/Modules/StickiedComposer.php
+++ b/app/Composers/StickiedComposer.php
@@ -9,14 +9,14 @@
* file that was distributed with this source code.
*/
-namespace CachetHQ\Cachet\Composers\Modules;
+namespace CachetHQ\Cachet\Composers;
-use CachetHQ\Cachet\Dates\DateFactory;
use CachetHQ\Cachet\Models\Incident;
+use CachetHQ\Cachet\Services\Dates\DateFactory;
use Illuminate\Contracts\View\View;
/**
- * This is the status page composer.
+ * This is the stickied composer.
*
* @author James Brooks
* @author Connor S. Parks
@@ -25,7 +25,7 @@
class StickiedComposer
{
/**
- * Index page view composer.
+ * Bind data to the view.
*
* @param \Illuminate\Contracts\View\View $view
*
@@ -33,9 +33,10 @@ class StickiedComposer
*/
public function compose(View $view)
{
- $stickiedIncidents = Incident::stickied()->orderBy('scheduled_at', 'desc')->orderBy('created_at', 'desc')->get()->groupBy(function (Incident $incident) {
- return app(DateFactory::class)->make($incident->is_scheduled ? $incident->scheduled_at : $incident->created_at)->toDateString();
+ $stickiedIncidents = Incident::stickied()->orderBy('occurred_at', 'desc')->get()->groupBy(function (Incident $incident) {
+ return app(DateFactory::class)->make($incident->is_scheduled ? $incident->scheduled_at : $incident->occurred_at)->toDateString();
});
+
$view->withStickiedIncidents($stickiedIncidents);
}
}
diff --git a/app/Composers/ThemeComposer.php b/app/Composers/ThemeComposer.php
index 191b894637c9..0153a35f9d46 100644
--- a/app/Composers/ThemeComposer.php
+++ b/app/Composers/ThemeComposer.php
@@ -14,6 +14,12 @@
use Illuminate\Contracts\Config\Repository;
use Illuminate\Contracts\View\View;
+/**
+ * This is the theme composer class.
+ *
+ * @author James Brooks
+ * @author Graham Campbell
+ */
class ThemeComposer
{
/**
@@ -44,18 +50,18 @@ public function __construct(Repository $config)
*/
public function compose(View $view)
{
- // Theme colors.
$view->withThemeBackgroundColor($this->config->get('setting.style_background_color', '#F0F3F4'));
$view->withThemeBackgroundFills($this->config->get('setting.style_background_fills', '#FFFFFF'));
$view->withThemeBannerBackgroundColor($this->config->get('setting.style_banner_background_color', ''));
$view->withThemeBannerPadding($this->config->get('setting.style_banner_padding', '40px 0'));
$view->withThemeTextColor($this->config->get('setting.style_text_color', '#333333'));
- $view->withThemeReds($this->config->get('setting.style_reds', '#ff6f6f'));
- $view->withThemeBlues($this->config->get('setting.style_blues', '#3498db'));
+ $view->withThemeReds($this->config->get('setting.style_reds', '#FF6F6F'));
+ $view->withThemeBlues($this->config->get('setting.style_blues', '#3498DB'));
$view->withThemeGreens($this->config->get('setting.style_greens', '#7ED321'));
$view->withThemeYellows($this->config->get('setting.style_yellows', '#F7CA18'));
$view->withThemeOranges($this->config->get('setting.style_oranges', '#FF8800'));
- $view->withThemeMetrics($this->config->get('setting.style_metrics', '#0dccc0'));
+ $view->withThemeGreys($this->config->get('setting.style_greys', '#888888'));
+ $view->withThemeMetrics($this->config->get('setting.style_metrics', '#0DCCC0'));
$view->withThemeLinks($this->config->get('setting.style_links', '#7ED321'));
}
}
diff --git a/app/Composers/Modules/TimelineComposer.php b/app/Composers/TimelineComposer.php
similarity index 82%
rename from app/Composers/Modules/TimelineComposer.php
rename to app/Composers/TimelineComposer.php
index b0772c3deee7..0206a2dc7220 100644
--- a/app/Composers/Modules/TimelineComposer.php
+++ b/app/Composers/TimelineComposer.php
@@ -9,12 +9,12 @@
* file that was distributed with this source code.
*/
-namespace CachetHQ\Cachet\Composers\Modules;
+namespace CachetHQ\Cachet\Composers;
use Illuminate\Contracts\View\View;
/**
- * This is the status page composer.
+ * This is the timeline composer.
*
* @author James Brooks
* @author Connor S. Parks
@@ -22,7 +22,7 @@
class TimelineComposer
{
/**
- * Index page view composer.
+ * Bind data to the view.
*
* @param \Illuminate\Contracts\View\View $view
*
diff --git a/app/Composers/TimezoneLocaleComposer.php b/app/Composers/TimezoneLocaleComposer.php
index 799af5606c78..5e3712d8e58a 100644
--- a/app/Composers/TimezoneLocaleComposer.php
+++ b/app/Composers/TimezoneLocaleComposer.php
@@ -15,7 +15,15 @@
use DateTimeZone;
use Illuminate\Contracts\Config\Repository;
use Illuminate\Contracts\View\View;
+use Illuminate\Support\Arr;
+/**
+ * This is the timezone locale composer class.
+ *
+ * @author Joseph Cohen
+ * @author James Brooks
+ * @author Graham Campbell
+ */
class TimezoneLocaleComposer
{
/**
@@ -51,22 +59,26 @@ public function compose(View $view)
$langs = array_map(function ($lang) use ($enabledLangs) {
$locale = basename($lang);
- return [$locale => $enabledLangs[$locale]];
+ return [$locale => Arr::get($enabledLangs, $locale, [
+ 'name' => $locale,
+ 'subset' => null,
+ ])];
}, glob(base_path('resources/lang').'/*'));
$langs = call_user_func_array('array_merge', $langs);
$regions = [
+ 'UTC' => DateTimeZone::UTC,
'Africa' => DateTimeZone::AFRICA,
'America' => DateTimeZone::AMERICA,
'Antarctica' => DateTimeZone::ANTARCTICA,
+ 'Arctic' => DateTimeZone::ARCTIC,
'Asia' => DateTimeZone::ASIA,
'Atlantic' => DateTimeZone::ATLANTIC,
'Australia' => DateTimeZone::AUSTRALIA,
'Europe' => DateTimeZone::EUROPE,
'Indian' => DateTimeZone::INDIAN,
'Pacific' => DateTimeZone::PACIFIC,
- 'UTC' => DateTimeZone::UTC,
];
$timezones = [];
@@ -78,10 +90,12 @@ public function compose(View $view)
// Lets sample the time there right now
$time = new DateTime(null, new DateTimeZone($timezone));
- $ampm = $time->format('H') > 12 ? ' ('.$time->format('g:i a').')' : '';
-
- // Remove region name and add a sample time
- $timezones[$name][$timezone] = substr($timezone, strlen($name) + 1).' - '.$time->format('H:i').$ampm;
+ if ($timezone !== 'UTC') {
+ // Remove region name and add a sample time
+ $timezones[$name][$timezone] = substr($timezone, strlen($name) + 1).' - '.$time->format('H:i');
+ } else {
+ $timezones[$name][$timezone] = 'UTC - '.$time->format('H:i');
+ }
$timezones[$name] = str_replace('_', ' ', $timezones[$name]);
}
diff --git a/app/Console/Commands/AppResetCommand.php b/app/Console/Commands/AppResetCommand.php
new file mode 100644
index 000000000000..3add76aa5c62
--- /dev/null
+++ b/app/Console/Commands/AppResetCommand.php
@@ -0,0 +1,76 @@
+
+ */
+class AppResetCommand extends Command
+{
+ /**
+ * The name and signature of the console command.
+ *
+ * @var string
+ */
+ protected $signature = 'app:reset';
+
+ /**
+ * The console command description.
+ *
+ * @var string
+ */
+ protected $description = 'Resets and installs the application';
+
+ /**
+ * The events instance.
+ *
+ * @var \Illuminate\Contracts\Events\Dispatcher
+ */
+ protected $events;
+
+ /**
+ * Create a new command instance.
+ *
+ * @return void
+ */
+ public function __construct(Dispatcher $events)
+ {
+ $this->events = $events;
+
+ parent::__construct();
+ }
+
+ /**
+ * Execute the console command.
+ *
+ * @return mixed
+ */
+ public function handle()
+ {
+ $this->events->fire('command.resetting', $this);
+ $this->events->fire('command.generatekey', $this);
+ $this->events->fire('command.cacheconfig', $this);
+ $this->events->fire('command.cacheroutes', $this);
+ $this->events->fire('command.publishvendors', $this);
+ $this->events->fire('command.resetmigrations', $this);
+ $this->events->fire('command.runmigrations', $this);
+ $this->events->fire('command.runseeding', $this);
+ $this->events->fire('command.updatecache', $this);
+ $this->events->fire('command.extrastuff', $this);
+ $this->events->fire('command.reset', $this);
+ }
+}
diff --git a/app/Console/Commands/AppUpdateCommand.php b/app/Console/Commands/AppUpdateCommand.php
new file mode 100644
index 000000000000..1aa4bd975eb0
--- /dev/null
+++ b/app/Console/Commands/AppUpdateCommand.php
@@ -0,0 +1,73 @@
+
+ */
+class AppUpdateCommand extends Command
+{
+ /**
+ * The name and signature of the console command.
+ *
+ * @var string
+ */
+ protected $signature = 'app:update';
+
+ /**
+ * The console command description.
+ *
+ * @var string
+ */
+ protected $description = 'Updates the application';
+
+ /**
+ * The events instance.
+ *
+ * @var \Illuminate\Contracts\Events\Dispatcher
+ */
+ protected $events;
+
+ /**
+ * Create a new command instance.
+ *
+ * @return void
+ */
+ public function __construct(Dispatcher $events)
+ {
+ $this->events = $events;
+
+ parent::__construct();
+ }
+
+ /**
+ * Execute the console command.
+ *
+ * @return mixed
+ */
+ public function handle()
+ {
+ $this->events->fire('command.updating', $this);
+ $this->events->fire('command.cacheconfig', $this);
+ $this->events->fire('command.cacheroutes', $this);
+ $this->events->fire('command.publishvendors', $this);
+ $this->events->fire('command.runmigrations', $this);
+ $this->events->fire('command.updatecache', $this);
+ $this->events->fire('command.extrastuff', $this);
+ $this->events->fire('command.updated', $this);
+ }
+}
diff --git a/app/Console/Commands/BeaconCommand.php b/app/Console/Commands/BeaconCommand.php
index 03391eb44bdd..27cad3f06843 100644
--- a/app/Console/Commands/BeaconCommand.php
+++ b/app/Console/Commands/BeaconCommand.php
@@ -33,14 +33,14 @@ class BeaconCommand extends Command
*
* @var string
*/
- protected $description = 'Send a beacon to the Cachet server.';
+ protected $description = 'Communicate with the Cachet Beacon server';
/**
* Execute the console command.
*
* @return void
*/
- public function fire()
+ public function handle()
{
dispatch(new SendBeaconJob());
}
diff --git a/app/Console/Commands/DemoMetricPointSeederCommand.php b/app/Console/Commands/DemoMetricPointSeederCommand.php
index 7c731b6c263e..d4e16235849f 100644
--- a/app/Console/Commands/DemoMetricPointSeederCommand.php
+++ b/app/Console/Commands/DemoMetricPointSeederCommand.php
@@ -12,8 +12,6 @@
namespace CachetHQ\Cachet\Console\Commands;
use CachetHQ\Cachet\Models\MetricPoint;
-use DateInterval;
-use DateTime;
use Illuminate\Console\Command;
use Illuminate\Console\ConfirmableTrait;
use Symfony\Component\Console\Input\InputOption;
@@ -39,14 +37,14 @@ class DemoMetricPointSeederCommand extends Command
*
* @var string
*/
- protected $description = 'Seeds the demo Cachet metric with points.';
+ protected $description = 'Seeds the demo Cachet metrics with points';
/**
* Execute the console command.
*
* @return void
*/
- public function fire()
+ public function handle()
{
if (!$this->confirmToProceed()) {
return;
@@ -66,16 +64,26 @@ protected function seedMetricPoints()
{
MetricPoint::truncate();
- // Generate 11 hours of metric points
- for ($i = 0; $i < 11; $i++) {
- $metricTime = (new DateTime())->sub(new DateInterval('PT'.$i.'H'));
+ $points = [];
- MetricPoint::create([
- 'metric_id' => 1,
- 'value' => random_int(1, 10),
- 'created_at' => $metricTime,
- 'updated_at' => $metricTime,
- ]);
+ // Generate 24 hours of metric points
+ for ($i = 0; $i <= 23; $i++) {
+ for ($j = 0; $j <= 59; $j++) {
+ $this->info("{$i}:{$j}");
+
+ $pointTime = date("Y-m-d {$i}:{$j}:00");
+
+ $points[] = [
+ 'metric_id' => 1,
+ 'value' => random_int(1, 10),
+ 'created_at' => $pointTime,
+ 'updated_at' => $pointTime,
+ ];
+ }
+ }
+
+ foreach (array_chunk($points, 100) as $chunk) {
+ MetricPoint::insert($chunk);
}
}
diff --git a/app/Console/Commands/DemoSeederCommand.php b/app/Console/Commands/DemoSeederCommand.php
index 2eb88353b126..3d496ca06674 100644
--- a/app/Console/Commands/DemoSeederCommand.php
+++ b/app/Console/Commands/DemoSeederCommand.php
@@ -11,15 +11,19 @@
namespace CachetHQ\Cachet\Console\Commands;
+use CachetHQ\Cachet\Models\Action;
use CachetHQ\Cachet\Models\Component;
use CachetHQ\Cachet\Models\ComponentGroup;
use CachetHQ\Cachet\Models\Incident;
use CachetHQ\Cachet\Models\IncidentTemplate;
+use CachetHQ\Cachet\Models\IncidentUpdate;
use CachetHQ\Cachet\Models\Metric;
use CachetHQ\Cachet\Models\MetricPoint;
+use CachetHQ\Cachet\Models\Schedule;
use CachetHQ\Cachet\Models\Subscriber;
use CachetHQ\Cachet\Models\User;
use CachetHQ\Cachet\Settings\Repository;
+use Carbon\Carbon;
use DateInterval;
use DateTime;
use Illuminate\Console\Command;
@@ -47,19 +51,19 @@ class DemoSeederCommand extends Command
*
* @var string
*/
- protected $description = 'Seeds Cachet with demo data.';
+ protected $description = 'Seeds Cachet with demo data';
/**
* The settings repository.
*
- * @var \CachetHQ\Cache\Settings\Repository
+ * @var \CachetHQ\Cachet\Settings\Repository
*/
protected $settings;
/**
* Create a new demo seeder command instance.
*
- * @param \CachetHQ\Cache\Settings\Repository $settings
+ * @param \CachetHQ\Cachet\Settings\Repository $settings
*
* @return void
*/
@@ -75,25 +79,37 @@ public function __construct(Repository $settings)
*
* @return void
*/
- public function fire()
+ public function handle()
{
if (!$this->confirmToProceed()) {
return;
}
+ $this->seedUsers();
+ $this->seedActions();
$this->seedComponentGroups();
$this->seedComponents();
$this->seedIncidents();
$this->seedIncidentTemplates();
$this->seedMetricPoints();
$this->seedMetrics();
+ $this->seedSchedules();
$this->seedSettings();
$this->seedSubscribers();
- $this->seedUsers();
$this->info('Database seeded with demo data successfully!');
}
+ /**
+ * Seed the actions table.
+ *
+ * @return void
+ */
+ protected function seedActions()
+ {
+ Action::truncate();
+ }
+
/**
* Seed the component groups table.
*
@@ -106,10 +122,12 @@ protected function seedComponentGroups()
'name' => 'Websites',
'order' => 1,
'collapsed' => 0,
+ 'visible' => ComponentGroup::VISIBLE_AUTHENTICATED,
], [
- 'name' => 'Alt Three',
+ 'name' => 'Services',
'order' => 2,
'collapsed' => 1,
+ 'visible' => ComponentGroup::VISIBLE_GUEST,
],
];
@@ -150,26 +168,26 @@ protected function seedComponents()
'group_id' => 1,
'link' => 'https://cachethq.io',
], [
- 'name' => 'Blog',
- 'description' => 'The Alt Three Blog.',
+ 'name' => 'Laravel Artisan Cheatsheet',
+ 'description' => 'A searchable, bookmarkable cheatsheet for Laravel\'s Artisan commands.',
'status' => 1,
'order' => 0,
'group_id' => 2,
- 'link' => 'https://blog.alt-three.com',
+ 'link' => 'https://artisan.page',
], [
- 'name' => 'StyleCI',
- 'description' => 'The PHP Coding Style Service.',
+ 'name' => 'Checkmango',
+ 'description' => 'The Full-Stack A/B Testing Platform',
'status' => 1,
'order' => 1,
'group_id' => 2,
- 'link' => 'https://styleci.io',
+ 'link' => 'https://checkmango.com',
], [
- 'name' => 'Patreon Page',
- 'description' => 'Support future development of Cachet.',
+ 'name' => 'GitHub',
+ 'description' => '',
'status' => 1,
'order' => 0,
'group_id' => 0,
- 'link' => 'https://patreon.com/jbrooksuk',
+ 'link' => 'https://github.com/cachethq/cachet',
],
];
@@ -199,74 +217,34 @@ protected function seedIncidents()
$defaultIncidents = [
[
- 'name' => 'Cachet supports Markdown!',
- 'message' => $incidentMessage,
- 'status' => 4,
- 'component_id' => 0,
- 'scheduled_at' => null,
- 'visible' => 1,
- 'stickied' => false,
- ],
- [
- 'name' => 'Awesome',
- 'message' => ':+1: We totally nailed the fix.',
- 'status' => 4,
- 'component_id' => 0,
- 'scheduled_at' => null,
- 'visible' => 1,
- 'stickied' => false,
- ],
- [
- 'name' => 'Monitoring the fix',
- 'message' => ":ship: We've deployed a fix.",
- 'status' => 3,
- 'component_id' => 0,
- 'scheduled_at' => null,
- 'visible' => 1,
- 'stickied' => false,
- ],
- [
- 'name' => 'Update',
- 'message' => "We've identified the problem. Our engineers are currently looking at it.",
- 'status' => 2,
+ 'name' => 'Our monkeys aren\'t performing',
+ 'message' => 'We\'re investigating an issue with our monkeys not performing as they should be.',
+ 'status' => Incident::INVESTIGATING,
'component_id' => 0,
- 'scheduled_at' => null,
'visible' => 1,
'stickied' => false,
+ 'user_id' => 1,
+ 'occurred_at' => Carbon::now(),
],
[
- 'name' => 'Test Incident',
- 'message' => 'Something went wrong, with something or another.',
- 'status' => 1,
+ 'name' => 'This is an unresolved incident',
+ 'message' => 'Unresolved incidents are left without a **Fixed** update.',
+ 'status' => Incident::INVESTIGATING,
'component_id' => 0,
- 'scheduled_at' => null,
- 'visible' => 1,
- 'stickied' => false,
- ],
- [
- 'name' => 'Investigating the API',
- 'message' => ':zap: We\'ve seen high response times from our API. It looks to be fixing itself as time goes on.',
- 'status' => 1,
- 'component_id' => 1,
- 'scheduled_at' => null,
'visible' => 1,
'stickied' => false,
- ],
- [
- 'name' => 'Stickied to the top',
- 'message' => 'Will be forever hanged here.',
- 'status' => 1,
- 'component_id' => 1,
- 'scheduled_at' => null,
- 'visible' => 1,
- 'stickied' => true,
+ 'user_id' => 1,
+ 'occurred_at' => Carbon::now(),
],
];
Incident::truncate();
+ IncidentUpdate::truncate();
- foreach ($defaultIncidents as $incident) {
- Incident::create($incident);
+ foreach ($defaultIncidents as $defaultIncident) {
+ $incident = Incident::create($defaultIncident);
+
+ $this->seedIncidentUpdates($incident);
}
}
@@ -280,6 +258,47 @@ protected function seedIncidentTemplates()
IncidentTemplate::truncate();
}
+ /**
+ * Seed the incident updates table for a given incident.
+ *
+ * @return void
+ */
+ protected function seedIncidentUpdates($incident)
+ {
+ $defaultUpdates = [
+ 1 => [
+ [
+ 'status' => Incident::FIXED,
+ 'message' => 'The monkeys are back and rested!',
+ 'user_id' => 1,
+ ], [
+ 'status' => Incident::WATCHED,
+ 'message' => 'Our monkeys need a break from performing. They\'ll be back after a good rest.',
+ 'user_id' => 1,
+ ], [
+ 'status' => Incident::IDENTIFIED,
+ 'message' => 'We have identified the issue with our lovely performing monkeys.',
+ 'user_id' => 1,
+ ],
+ ],
+ 2 => [
+ [
+ 'status' => Incident::WATCHED,
+ 'message' => 'We\'re actively watching this issue, so it remains unresolved.',
+ 'user_id' => 1,
+ ],
+ ],
+ ];
+
+ $updates = $defaultUpdates[$incident->id];
+
+ foreach ($updates as $updateId => $update) {
+ $update['incident_id'] = $incident->id;
+
+ IncidentUpdate::create($update);
+ }
+ }
+
/**
* Seed the metric points table.
*
@@ -327,6 +346,29 @@ protected function seedMetrics()
}
}
+ /**
+ * Seed the schedules table.
+ *
+ * @return void
+ */
+ protected function seedSchedules()
+ {
+ $defaultSchedules = [
+ [
+ 'name' => 'Demo resets every half hour!',
+ 'message' => 'You can schedule downtime for _your_ service!',
+ 'status' => Schedule::UPCOMING,
+ 'scheduled_at' => (new DateTime())->add(new DateInterval('PT2H')),
+ ],
+ ];
+
+ Schedule::truncate();
+
+ foreach ($defaultSchedules as $schedule) {
+ Schedule::create($schedule);
+ }
+ }
+
/**
* Seed the settings table.
*
@@ -354,20 +396,20 @@ protected function seedSettings()
'key' => 'app_incident_days',
'value' => '7',
], [
- 'key' => 'app_analytics',
- 'value' => 'UA-58442674-3',
- ], [
- 'key' => 'app_analytics_gs',
- 'value' => 'GSN-712462-P',
+ 'key' => 'app_refresh_rate',
+ 'value' => '0',
], [
'key' => 'display_graphs',
'value' => '1',
], [
'key' => 'app_about',
- 'value' => 'This is the demo instance of [Cachet](https://cachethq.io?ref=demo). The open source status page system, for everyone. An [Alt Three](https://alt-three.com) product.',
+ 'value' => 'This is the demo instance of [Cachet](https://cachethq.io?ref=demo). The open-source status page system, for everyone. 3.x is coming soon! [Read the announcement](https://github.com/cachethq/cachet/discussions/4342).',
], [
'key' => 'enable_subscribers',
'value' => '0',
+ ], [
+ 'key' => 'header',
+ 'value' => '',
],
];
@@ -399,7 +441,7 @@ protected function seedUsers()
[
'username' => 'test',
'password' => 'test123',
- 'email' => 'test@test.com',
+ 'email' => 'test@example.com',
'level' => User::LEVEL_ADMIN,
'api_key' => '9yMHsdioQosnyVK4iCVR',
],
diff --git a/app/Console/Commands/InstallCommand.php b/app/Console/Commands/InstallCommand.php
new file mode 100644
index 000000000000..7c71cbc0de2e
--- /dev/null
+++ b/app/Console/Commands/InstallCommand.php
@@ -0,0 +1,448 @@
+
+ */
+class InstallCommand extends Command
+{
+ /**
+ * The console command name.
+ *
+ * @var string
+ */
+ protected $name = 'cachet:install';
+
+ /**
+ * The console command description.
+ *
+ * @var string
+ */
+ protected $description = 'Install Cachet';
+
+ /**
+ * The events instance.
+ *
+ * @var \Illuminate\Contracts\Events\Dispatcher
+ */
+ protected $events;
+
+ /**
+ * Create a new command instance.
+ *
+ * @param Dispatcher $events
+ */
+ public function __construct(Dispatcher $events)
+ {
+ $this->events = $events;
+
+ parent::__construct();
+ }
+
+ /**
+ * Execute the console command.
+ *
+ * @return void
+ */
+ public function handle()
+ {
+ if ($this->confirm('Do you want to configure Cachet before installing?')) {
+ $this->configureEnvironmentFile();
+ $this->configureKey();
+ $this->configureDatabase();
+ $this->configureDrivers();
+ $this->configureMail();
+ $this->configureCachet();
+ $this->configureUser();
+ }
+
+ $this->line('Installing Cachet...');
+
+ $this->events->fire('command.installing', $this);
+ $this->events->fire('command.generatekey', $this);
+ $this->events->fire('command.cacheconfig', $this);
+ $this->events->fire('command.cacheroutes', $this);
+ $this->events->fire('command.publishvendors', $this);
+ $this->events->fire('command.runmigrations', $this);
+ $this->events->fire('command.runseeding', $this);
+ $this->events->fire('command.updatecache', $this);
+ $this->events->fire('command.linkstorage', $this);
+ $this->events->fire('command.extrastuff', $this);
+ $this->events->fire('command.installed', $this);
+
+ $this->info('Cachet is installed ⚡');
+ }
+
+ /**
+ * Copy the environment file.
+ *
+ * @return void
+ */
+ protected function configureEnvironmentFile()
+ {
+ $dir = app()->environmentPath();
+ $file = app()->environmentFile();
+ $path = "{$dir}/{$file}";
+
+ if (file_exists($path)) {
+ $this->line('Environment file already exists. Moving on.');
+
+ return;
+ }
+
+ copy("$path.example", $path);
+ }
+
+ /**
+ * Generate the app key.
+ *
+ * @return void
+ */
+ protected function configureKey()
+ {
+ $this->call('key:generate');
+ }
+
+ /**
+ * Configure the database.
+ *
+ * @param array $default
+ *
+ * @return void
+ */
+ protected function configureDatabase(array $default = [])
+ {
+ $config = array_merge([
+ 'DB_DRIVER' => null,
+ 'DB_HOST' => null,
+ 'DB_DATABASE' => null,
+ 'DB_USERNAME' => null,
+ 'DB_PASSWORD' => null,
+ 'DB_PORT' => null,
+ 'DB_PREFIX' => null,
+ ], $default);
+
+ $config['DB_DRIVER'] = $this->choice('Which database driver do you want to use?', [
+ 'mysql' => 'MySQL',
+ 'pgsql' => 'PostgreSQL',
+ 'sqlite' => 'SQLite',
+ ], $config['DB_DRIVER']);
+
+ if ($config['DB_DRIVER'] === 'sqlite') {
+ $config['DB_DATABASE'] = $this->ask('Please provide the full path to your SQLite file.', $config['DB_DATABASE']);
+ } else {
+ $config['DB_HOST'] = $this->ask("What is the host of your {$config['DB_DRIVER']} database?", $config['DB_HOST']);
+ if ($config['DB_HOST'] === 'localhost' && $config['DB_DRIVER'] === 'mysql') {
+ $this->warn("Using 'localhost' will result in the usage of a local unix socket. Use 127.0.0.1 if you want to connect over TCP");
+ }
+
+ $config['DB_DATABASE'] = $this->ask('What is the name of the database that Cachet should use?', $config['DB_DATABASE']);
+
+ $config['DB_USERNAME'] = $this->ask('What username should we connect with?', $config['DB_USERNAME']);
+
+ $config['DB_PASSWORD'] = $this->secret('What password should we connect with?', $config['DB_PASSWORD']);
+
+ $config['DB_PORT'] = $config['DB_DRIVER'] === 'mysql' ? 3306 : 5432;
+ if ($this->confirm('Is your database listening on a non-standard port number?')) {
+ $config['DB_PORT'] = $this->anticipate('What port number is your database using?', [3306, 5432], $config['DB_PORT']);
+ }
+ }
+
+ if ($this->confirm('Do you want to use a prefix on the table names?')) {
+ $config['DB_PREFIX'] = $this->ask('Please enter the prefix now...', $config['DB_PREFIX']);
+ }
+
+ // Format the settings ready to display them in the table.
+ $this->formatConfigsTable($config);
+
+ if (!$this->confirm('Are these settings correct?')) {
+ return $this->configureDatabase($config);
+ }
+
+ foreach ($config as $setting => $value) {
+ $this->writeEnv($setting, $value);
+ }
+ }
+
+ /**
+ * Configure other drivers.
+ *
+ * @param array $default
+ *
+ * @return void
+ */
+ protected function configureDrivers(array $default = [])
+ {
+ $config = array_merge([
+ 'CACHE_DRIVER' => null,
+ 'SESSION_DRIVER' => null,
+ 'QUEUE_DRIVER' => null,
+ ], $default);
+
+ // Format the settings ready to display them in the table.
+ $this->formatConfigsTable($config);
+
+ $config['CACHE_DRIVER'] = $this->choice('Which cache driver do you want to use?', [
+ 'apc' => 'APC(u)',
+ 'array' => 'Array',
+ 'database' => 'Database',
+ 'file' => 'File',
+ 'memcached' => 'Memcached',
+ 'redis' => 'Redis',
+ ], $config['CACHE_DRIVER']);
+
+ // We need to configure Redis.
+ if ($config['CACHE_DRIVER'] === 'redis') {
+ $this->configureRedis();
+ }
+
+ $config['SESSION_DRIVER'] = $this->choice('Which session driver do you want to use?', [
+ 'apc' => 'APC(u)',
+ 'array' => 'Array',
+ 'database' => 'Database',
+ 'file' => 'File',
+ 'memcached' => 'Memcached',
+ 'redis' => 'Redis',
+ ], $config['SESSION_DRIVER']);
+
+ // We need to configure Redis.
+ if ($config['SESSION_DRIVER'] === 'redis') {
+ $this->configureRedis();
+ }
+
+ $config['QUEUE_DRIVER'] = $this->choice('Which queue driver do you want to use?', [
+ 'null' => 'None',
+ 'sync' => 'Synchronous',
+ 'database' => 'Database',
+ 'beanstalkd' => 'Beanstalk',
+ 'sqs' => 'Amazon SQS',
+ 'redis' => 'Redis',
+ ], $config['QUEUE_DRIVER']);
+
+ // We need to configure Redis, but only if the cache driver wasn't redis.
+ if ($config['QUEUE_DRIVER'] === 'redis' && ($config['SESSION_DRIVER'] !== 'redis' || $config['CACHE_DRIVER'] !== 'redis')) {
+ $this->configureRedis();
+ }
+
+ // Format the settings ready to display them in the table.
+ $this->formatConfigsTable($config);
+
+ if (!$this->confirm('Are these settings correct?')) {
+ return $this->configureDrivers($config);
+ }
+
+ foreach ($config as $setting => $value) {
+ $this->writeEnv($setting, $value);
+ }
+ }
+
+ /**
+ * Configure mail.
+ *
+ * @param array $config
+ *
+ * @return void
+ */
+ protected function configureMail(array $config = [])
+ {
+ $config = array_merge([
+ 'MAIL_DRIVER' => null,
+ 'MAIL_HOST' => null,
+ 'MAIL_PORT' => null,
+ 'MAIL_USERNAME' => null,
+ 'MAIL_PASSWORD' => null,
+ 'MAIL_ADDRESS' => null,
+ 'MAIL_NAME' => null,
+ 'MAIL_ENCRYPTION' => null,
+ ], $config);
+
+ // Don't continue with these settings if we're not interested in notifications.
+ if (!$this->confirm('Do you want Cachet to send mail notifications?')) {
+ return;
+ }
+
+ $config['MAIL_DRIVER'] = $this->choice('What driver do you want to use to send notifications?', [
+ 'smtp' => 'SMTP',
+ 'mail' => 'Mail',
+ 'sendmail' => 'Sendmail',
+ 'mailgun' => 'Mailgun',
+ 'mandrill' => 'Mandrill',
+ 'ses' => 'Amazon SES',
+ 'sparkpost' => 'SparkPost',
+ 'log' => 'Log (Testing)',
+ ]);
+
+ if (!$config['MAIL_DRIVER'] === 'log') {
+ if ($config['MAIL_DRIVER'] === 'smtp') {
+ $config['MAIL_HOST'] = $this->ask('Please supply your mail server host');
+ }
+
+ $config['MAIL_ADDRESS'] = $this->ask('What email address should we send notifications from?');
+ $config['MAIL_USERNAME'] = $this->ask('What username should we connect as?');
+ $config['MAIL_PASSWORD'] = $this->secret('What password should we connect with?');
+ }
+
+ // Format the settings ready to display them in the table.
+ $this->formatConfigsTable($config);
+
+ if (!$this->confirm('Are these settings correct?')) {
+ return $this->configureMail($config);
+ }
+
+ foreach ($config as $setting => $value) {
+ $this->writeEnv($setting, $value);
+ }
+ }
+
+ /**
+ * Configure Cachet.
+ *
+ * @param array $config
+ *
+ * @return void
+ */
+ protected function configureCachet(array $config = [])
+ {
+ $config = [];
+ if ($this->confirm('Do you wish to use Cachet Beacon?')) {
+ $config['CACHET_BEACON'] = 'true';
+ }
+
+ if ($this->confirm('Do you wish to use Emoji? This requires a GitHub oAuth Token!')) {
+ $config['GITHUB_TOKEN'] = $this->ask('Please enter your GitHub oAuth Token');
+ $config['CACHET_EMOJI'] = 'true';
+ }
+
+ foreach ($config as $setting => $value) {
+ $this->writeEnv($setting, $value);
+ }
+ }
+
+ /**
+ * Configure the first user.
+ *
+ * @return void
+ */
+ protected function configureUser()
+ {
+ if (!$this->confirm('Do you want to create an admin user?')) {
+ return;
+ }
+
+ // We need to refresh the config to get access to the newly connected database.
+ $this->getFreshConfiguration();
+
+ // Now we need to install the application.
+ // $this->call('cachet:install');
+
+ $user = [
+ 'username' => $this->ask('Please enter your username'),
+ 'email' => $this->ask('Please enter your email'),
+ 'password' => $this->secret('Please enter your password'),
+ 'level' => User::LEVEL_ADMIN,
+ ];
+
+ User::create($user);
+ }
+
+ /**
+ * Configure the redis connection.
+ *
+ * @return void
+ */
+ protected function configureRedis()
+ {
+ $config = [
+ 'REDIS_HOST' => null,
+ 'REDIS_DATABASE' => null,
+ 'REDIS_PORT' => null,
+ ];
+
+ $config['REDIS_HOST'] = $this->ask('What is the host of your redis server?');
+ $config['REDIS_DATABASE'] = $this->ask('What is the name of the database that Cachet should use?');
+ $config['REDIS_PORT'] = $this->ask('What port should Cachet use?', 6379);
+
+ foreach ($config as $setting => $value) {
+ $this->writeEnv($setting, $value);
+ }
+ }
+
+ /**
+ * Format the configs into a pretty table that we can easily read.
+ *
+ * @param array $config
+ *
+ * @return void
+ */
+ protected function formatConfigsTable(array $config)
+ {
+ $configRows = [];
+
+ foreach ($config as $setting => $value) {
+ $configRows[] = compact('setting', 'value');
+ }
+
+ $this->table(['Setting', 'Value'], $configRows);
+ }
+
+ /**
+ * Boot a fresh copy of the application configuration.
+ *
+ * @return void
+ */
+ protected function getFreshConfiguration()
+ {
+ $app = require $this->laravel->bootstrapPath().'/app.php';
+ $app->make(Kernel::class)->bootstrap();
+ }
+
+ /**
+ * Writes to the .env file with given parameters.
+ *
+ * @param string $key
+ * @param mixed $value
+ *
+ * @return void
+ */
+ protected function writeEnv($key, $value)
+ {
+ $dir = app()->environmentPath();
+ $file = app()->environmentFile();
+ $path = "{$dir}/{$file}";
+
+ try {
+ (new Dotenv($dir, $file))->load();
+
+ $envKey = strtoupper($key);
+ $envValue = env($envKey) ?: 'null';
+
+ $envFileContents = file_get_contents($path);
+ $envFileContents = str_replace("{$envKey}={$envValue}", "{$envKey}={$value}", $envFileContents, $count);
+ if ($count < 1 && $envValue === 'null') {
+ $envFileContents = str_replace("{$envKey}=", "{$envKey}={$value}", $envFileContents);
+ }
+ file_put_contents($path, $envFileContents);
+ } catch (InvalidPathException $e) {
+ throw $e;
+ }
+ }
+}
diff --git a/app/Console/Commands/VersionCommand.php b/app/Console/Commands/VersionCommand.php
new file mode 100644
index 000000000000..e093fe7a07f4
--- /dev/null
+++ b/app/Console/Commands/VersionCommand.php
@@ -0,0 +1,46 @@
+
+ */
+class VersionCommand extends Command
+{
+ /**
+ * The console command name.
+ *
+ * @var string
+ */
+ protected $name = 'cachet:version';
+
+ /**
+ * The console command description.
+ *
+ * @var string
+ */
+ protected $description = 'Display the version of Cachet';
+
+ /**
+ * Execute the console command.
+ *
+ * @return void
+ */
+ public function handle()
+ {
+ $this->info('Cachet '.CACHET_VERSION.' is installed ⚡');
+ }
+}
diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php
index c7a2896cfd32..12bc4a2ab21c 100644
--- a/app/Console/Kernel.php
+++ b/app/Console/Kernel.php
@@ -11,12 +11,23 @@
namespace CachetHQ\Cachet\Console;
+use CachetHQ\Cachet\Console\Commands\AppResetCommand;
+use CachetHQ\Cachet\Console\Commands\AppUpdateCommand;
use CachetHQ\Cachet\Console\Commands\BeaconCommand;
use CachetHQ\Cachet\Console\Commands\DemoMetricPointSeederCommand;
use CachetHQ\Cachet\Console\Commands\DemoSeederCommand;
+use CachetHQ\Cachet\Console\Commands\InstallCommand;
+use CachetHQ\Cachet\Console\Commands\VersionCommand;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
+/**
+ * This is the console kernel class.
+ *
+ * @author Graham Campbell
+ * @author Joseph Cohen
+ * @author James Brooks
+ */
class Kernel extends ConsoleKernel
{
/**
@@ -25,9 +36,13 @@ class Kernel extends ConsoleKernel
* @var array
*/
protected $commands = [
+ AppResetCommand::class,
+ AppUpdateCommand::class,
BeaconCommand::class,
DemoMetricPointSeederCommand::class,
DemoSeederCommand::class,
+ InstallCommand::class,
+ VersionCommand::class,
];
/**
diff --git a/app/Foundation/Exceptions/Displayers/JsonValidationDisplayer.php b/app/Exceptions/Displayers/JsonValidationDisplayer.php
similarity index 90%
rename from app/Foundation/Exceptions/Displayers/JsonValidationDisplayer.php
rename to app/Exceptions/Displayers/JsonValidationDisplayer.php
index 02fd20ad3cba..bb3d0c5014e4 100644
--- a/app/Foundation/Exceptions/Displayers/JsonValidationDisplayer.php
+++ b/app/Exceptions/Displayers/JsonValidationDisplayer.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace CachetHQ\Cachet\Foundation\Exceptions\Displayers;
+namespace CachetHQ\Cachet\Exceptions\Displayers;
use AltThree\Validator\ValidationException;
use Exception;
@@ -29,7 +29,7 @@ class JsonValidationDisplayer extends JsonDisplayer implements DisplayerInterfac
*
* @return \Symfony\Component\HttpFoundation\Response
*/
- public function display(Exception $exception, $id, $code, array $headers)
+ public function display(Exception $exception, string $id, int $code, array $headers)
{
$info = $this->info->generate($exception, $id, 400);
@@ -47,7 +47,7 @@ public function display(Exception $exception, $id, $code, array $headers)
*
* @return bool
*/
- public function canDisplay(Exception $original, Exception $transformed, $code)
+ public function canDisplay(Exception $original, Exception $transformed, int $code)
{
return $transformed instanceof ValidationException;
}
diff --git a/app/Exceptions/Displayers/MaintenanceDisplayer.php b/app/Exceptions/Displayers/MaintenanceDisplayer.php
new file mode 100644
index 000000000000..20b4a16d5e75
--- /dev/null
+++ b/app/Exceptions/Displayers/MaintenanceDisplayer.php
@@ -0,0 +1,104 @@
+
+ */
+class MaintenanceDisplayer implements DisplayerInterface
+{
+ /**
+ * The view factory instance.
+ *
+ * @var \Illuminate\Contracts\View\Factory
+ */
+ protected $view;
+
+ /**
+ * Create a new maintenance displayer instance.
+ *
+ * @param \Illuminate\Contracts\View\Factory $view
+ *
+ * @return void
+ */
+ public function __construct(Factory $view)
+ {
+ $this->view = $view;
+ }
+
+ /**
+ * Get the error response associated with the given exception.
+ *
+ * @param \Exception $exception
+ * @param string $id
+ * @param int $code
+ * @param string[] $headers
+ *
+ * @return \Symfony\Component\HttpFoundation\Response
+ */
+ public function display(Exception $exception, string $id, int $code, array $headers)
+ {
+ return new Response($this->render(), $code, array_merge($headers, ['Content-Type' => $this->contentType()]));
+ }
+
+ /**
+ * Render the page.
+ *
+ * @return string
+ */
+ protected function render()
+ {
+ return $this->view->make('errors.maintenance')->render();
+ }
+
+ /**
+ * Get the supported content type.
+ *
+ * @return string
+ */
+ public function contentType()
+ {
+ return 'text/html';
+ }
+
+ /**
+ * Can we display the exception?
+ *
+ * @param \Exception $original
+ * @param \Exception $transformed
+ * @param int $code
+ *
+ * @return bool
+ */
+ public function canDisplay(Exception $original, Exception $transformed, int $code)
+ {
+ return $transformed instanceof MaintenanceModeException;
+ }
+
+ /**
+ * Do we provide verbose information about the exception?
+ *
+ * @return bool
+ */
+ public function isVerbose()
+ {
+ return false;
+ }
+}
diff --git a/app/Foundation/Exceptions/Displayers/RedirectDisplayer.php b/app/Exceptions/Displayers/RedirectDisplayer.php
similarity index 92%
rename from app/Foundation/Exceptions/Displayers/RedirectDisplayer.php
rename to app/Exceptions/Displayers/RedirectDisplayer.php
index 147a2c97618e..7a1670cbf77f 100644
--- a/app/Foundation/Exceptions/Displayers/RedirectDisplayer.php
+++ b/app/Exceptions/Displayers/RedirectDisplayer.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace CachetHQ\Cachet\Foundation\Exceptions\Displayers;
+namespace CachetHQ\Cachet\Exceptions\Displayers;
use Exception;
use GrahamCampbell\Exceptions\Displayers\DisplayerInterface;
@@ -47,7 +47,7 @@ public function __construct(Request $request)
*
* @return \Symfony\Component\HttpFoundation\Response
*/
- public function display(Exception $exception, $id, $code, array $headers)
+ public function display(Exception $exception, string $id, int $code, array $headers)
{
return redirect()->guest('auth/login');
}
@@ -71,7 +71,7 @@ public function contentType()
*
* @return bool
*/
- public function canDisplay(Exception $original, Exception $transformed, $code)
+ public function canDisplay(Exception $original, Exception $transformed, int $code)
{
$redirect = $transformed instanceof HttpExceptionInterface && $transformed->getStatusCode() === 401;
diff --git a/app/Exceptions/Displayers/SettingsDisplayer.php b/app/Exceptions/Displayers/SettingsDisplayer.php
new file mode 100644
index 000000000000..d3a76d0408a5
--- /dev/null
+++ b/app/Exceptions/Displayers/SettingsDisplayer.php
@@ -0,0 +1,88 @@
+request = $request;
+ }
+
+ /**
+ * Get the error response associated with the given exception.
+ *
+ * @param \Exception $exception
+ * @param string $id
+ * @param int $code
+ * @param string[] $headers
+ *
+ * @return \Symfony\Component\HttpFoundation\Response
+ */
+ public function display(Exception $exception, string $id, int $code, array $headers)
+ {
+ return cachet_redirect('setup');
+ }
+
+ /**
+ * Get the supported content type.
+ *
+ * @return string
+ */
+ public function contentType()
+ {
+ return 'text/html';
+ }
+
+ /**
+ * Can we display the exception?
+ *
+ * @param \Exception $original
+ * @param \Exception $transformed
+ * @param int $code
+ *
+ * @return bool
+ */
+ public function canDisplay(Exception $original, Exception $transformed, int $code)
+ {
+ return ($transformed instanceof ReadException) && !$this->request->is('setup*');
+ }
+
+ /**
+ * Do we provide verbose information about the exception?
+ *
+ * @return bool
+ */
+ public function isVerbose()
+ {
+ return false;
+ }
+}
diff --git a/app/Foundation/Exceptions/Displayers/ThrottleDisplayer.php b/app/Exceptions/Displayers/ThrottleDisplayer.php
similarity index 87%
rename from app/Foundation/Exceptions/Displayers/ThrottleDisplayer.php
rename to app/Exceptions/Displayers/ThrottleDisplayer.php
index f36871db9215..5f1907c7d7db 100644
--- a/app/Foundation/Exceptions/Displayers/ThrottleDisplayer.php
+++ b/app/Exceptions/Displayers/ThrottleDisplayer.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace CachetHQ\Cachet\Foundation\Exceptions\Displayers;
+namespace CachetHQ\Cachet\Exceptions\Displayers;
use Exception;
use GrahamCampbell\Exceptions\Displayers\DisplayerInterface;
@@ -47,9 +47,9 @@ public function __construct(Request $request)
*
* @return \Symfony\Component\HttpFoundation\Response
*/
- public function display(Exception $exception, $id, $code, array $headers)
+ public function display(Exception $exception, string $id, int $code, array $headers)
{
- return redirect()->route('auth.login')->withError(trans('forms.login.rate-limit'));
+ return cachet_redirect('auth.login')->withError(trans('forms.login.rate-limit'));
}
/**
@@ -71,7 +71,7 @@ public function contentType()
*
* @return bool
*/
- public function canDisplay(Exception $original, Exception $transformed, $code)
+ public function canDisplay(Exception $original, Exception $transformed, int $code)
{
return $transformed instanceof TooManyRequestsHttpException && $this->request->is('auth*');
}
diff --git a/app/Foundation/Exceptions/Filters/ApiFilter.php b/app/Exceptions/Filters/ApiFilter.php
similarity index 84%
rename from app/Foundation/Exceptions/Filters/ApiFilter.php
rename to app/Exceptions/Filters/ApiFilter.php
index e824de2a4957..8d12e4dbffc2 100644
--- a/app/Foundation/Exceptions/Filters/ApiFilter.php
+++ b/app/Exceptions/Filters/ApiFilter.php
@@ -9,10 +9,11 @@
* file that was distributed with this source code.
*/
-namespace CachetHQ\Cachet\Foundation\Exceptions\Filters;
+namespace CachetHQ\Cachet\Exceptions\Filters;
use Exception;
use Illuminate\Http\Request;
+use Illuminate\Support\Str;
class ApiFilter
{
@@ -27,11 +28,11 @@ class ApiFilter
*
* @return \GrahamCampbell\Exceptions\Displayers\DisplayerInterface[]
*/
- public function filter(array $displayers, Request $request, Exception $original, Exception $transformed, $code)
+ public function filter(array $displayers, Request $request, Exception $original, Exception $transformed, int $code)
{
if ($request->is('api*')) {
foreach ($displayers as $index => $displayer) {
- if (!str_contains($displayer->contentType(), 'application/')) {
+ if (!Str::contains($displayer->contentType(), 'application/')) {
unset($displayers[$index]);
}
}
diff --git a/app/Foundation/Exceptions/Transformers/BusTransformer.php b/app/Exceptions/Transformers/BusTransformer.php
similarity index 93%
rename from app/Foundation/Exceptions/Transformers/BusTransformer.php
rename to app/Exceptions/Transformers/BusTransformer.php
index 6ffd879a2e96..be0b2fe5cb18 100644
--- a/app/Foundation/Exceptions/Transformers/BusTransformer.php
+++ b/app/Exceptions/Transformers/BusTransformer.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace CachetHQ\Cachet\Foundation\Exceptions\Transformers;
+namespace CachetHQ\Cachet\Exceptions\Transformers;
use CachetHQ\Cachet\Bus\Exceptions\ExceptionInterface;
use Exception;
diff --git a/app/Foundation/Providers/ModuleServiceProvider.php b/app/Foundation/Providers/ModuleServiceProvider.php
deleted file mode 100644
index 895f3d58f175..000000000000
--- a/app/Foundation/Providers/ModuleServiceProvider.php
+++ /dev/null
@@ -1,95 +0,0 @@
- [
- ['group' => 'messages', 'partial' => 'partials.modules.messages'],
- ['group' => 'status', 'partial' => 'partials.modules.status'],
- ['group' => 'components', 'partial' => 'partials.modules.components'],
- ['group' => 'metrics', 'partial' => 'partials.modules.metrics'],
- ['group' => 'stickied', 'partial' => 'partials.modules.stickied'],
- ['group' => 'scheduled', 'partial' => 'partials.modules.scheduled'],
- ['group' => 'timeline', 'partial' => 'partials.modules.timeline'],
- ],
- ];
-
- /**
- * The group definitions.
- *
- * @var array
- */
- protected $groups = [
- 'index' => [
- 'messages' => 10000,
- 'status' => 20000,
- 'components' => 30000,
- 'metrics' => 40000,
- 'scheduled' => 50000,
- 'stickied' => 60000,
- 'timeline' => 70000,
- ],
- ];
-
- /**
- * Boot the service provider.
- *
- * @param \Illuminate\View\Compilers\BladeCompiler $blade
- */
- public function boot(BladeCompiler $blade)
- {
- $blade->directive('modules', function ($group = null) {
- return sprintf(
- 'call(\'%s@%s\', [
- \'factory\' => $__env,
- \'data\' => array_except(get_defined_vars(), array(\'__data\', \'__path\')),
- \'modules\' => $modules,
- \'group\' => %s,
- ]); ?>',
- ModulesRenderer::class,
- 'renderModules',
- $group === null ? 'null' : $group
- );
- });
- }
-
- /**
- * Register the service provider.
- *
- * @return void
- */
- public function register()
- {
- foreach ($this->modules as $key => $modules) {
- $this->app->singleton("view.modules: {$key}", function () use ($modules) {
- return $modules;
- });
- }
-
- foreach ($this->groups as $key => $groups) {
- $this->app->singleton("view.groups: {$key}", function () use ($groups) {
- return $groups;
- });
- }
- }
-}
diff --git a/app/Foundation/Providers/RouteServiceProvider.php b/app/Foundation/Providers/RouteServiceProvider.php
deleted file mode 100644
index 742bdc106fcd..000000000000
--- a/app/Foundation/Providers/RouteServiceProvider.php
+++ /dev/null
@@ -1,82 +0,0 @@
-registerBindings();
- }
-
- /**
- * Register model bindings.
- *
- * @return void
- */
- protected function registerBindings()
- {
- $this->app->router->model('component', 'CachetHQ\Cachet\Models\Component');
- $this->app->router->model('component_group', 'CachetHQ\Cachet\Models\ComponentGroup');
- $this->app->router->model('incident', 'CachetHQ\Cachet\Models\Incident');
- $this->app->router->model('incident_template', 'CachetHQ\Cachet\Models\IncidentTemplate');
- $this->app->router->model('metric', 'CachetHQ\Cachet\Models\Metric');
- $this->app->router->model('metric_point', 'CachetHQ\Cachet\Models\MetricPoint');
- $this->app->router->model('setting', 'CachetHQ\Cachet\Models\Setting');
- $this->app->router->model('subscriber', 'CachetHQ\Cachet\Models\Subscriber');
- $this->app->router->model('subscription', 'CachetHQ\Cachet\Models\Subscription');
- $this->app->router->model('user', 'CachetHQ\Cachet\Models\User');
- }
-
- /**
- * Define the routes for the application.
- *
- * @param \Illuminate\Routing\Router $router
- *
- * @return void
- */
- public function map(Router $router)
- {
- $router->group(['namespace' => $this->namespace], function (Router $router) {
- $path = app_path('Http/Routes');
-
- foreach (glob("{$path}/*{,/*}.php", GLOB_BRACE) as $file) {
- $class = substr($file, strlen($path));
- $class = str_replace('/', '\\', $class);
- $class = substr($class, 0, -4);
-
- $this->app->make("CachetHQ\\Cachet\\Http\\Routes${class}")->map($router);
- }
- });
- }
-}
diff --git a/app/Http/Controllers/Api/AbstractApiController.php b/app/Http/Controllers/Api/AbstractApiController.php
index 4b871c5be28f..10be23db248f 100644
--- a/app/Http/Controllers/Api/AbstractApiController.php
+++ b/app/Http/Controllers/Api/AbstractApiController.php
@@ -141,7 +141,7 @@ protected function paginator(Paginator $paginator, Request $request)
{
foreach ($request->query as $key => $value) {
if ($key != 'page') {
- $paginator->addQuery($key, $value);
+ $paginator->appends($key, $value);
}
}
diff --git a/app/Http/Controllers/Api/ComponentController.php b/app/Http/Controllers/Api/ComponentController.php
index 35c43a8ad13e..9bda7b09cb53 100644
--- a/app/Http/Controllers/Api/ComponentController.php
+++ b/app/Http/Controllers/Api/ComponentController.php
@@ -11,11 +11,10 @@
namespace CachetHQ\Cachet\Http\Controllers\Api;
-use CachetHQ\Cachet\Bus\Commands\Component\AddComponentCommand;
+use CachetHQ\Cachet\Bus\Commands\Component\CreateComponentCommand;
use CachetHQ\Cachet\Bus\Commands\Component\RemoveComponentCommand;
use CachetHQ\Cachet\Bus\Commands\Component\UpdateComponentCommand;
use CachetHQ\Cachet\Models\Component;
-use CachetHQ\Cachet\Models\Tag;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Database\QueryException;
@@ -29,7 +28,7 @@ class ComponentController extends AbstractApiController
*
* @return \Illuminate\Http\JsonResponse
*/
- public function getComponents()
+ public function index()
{
if (app(Guard::class)->check()) {
$components = Component::query();
@@ -37,6 +36,10 @@ public function getComponents()
$components = Component::enabled();
}
+ if ($tags = Binput::get('tags')) {
+ $components->withAnyTags($tags);
+ }
+
$components->search(Binput::except(['sort', 'order', 'per_page']));
if ($sortBy = Binput::get('sort')) {
@@ -57,7 +60,7 @@ public function getComponents()
*
* @return \Illuminate\Http\JsonResponse
*/
- public function getComponent(Component $component)
+ public function show(Component $component)
{
return $this->item($component);
}
@@ -67,36 +70,24 @@ public function getComponent(Component $component)
*
* @return \Illuminate\Http\JsonResponse
*/
- public function postComponents()
+ public function store()
{
try {
- $component = dispatch(new AddComponentCommand(
+ $component = execute(new CreateComponentCommand(
Binput::get('name'),
Binput::get('description'),
Binput::get('status'),
Binput::get('link'),
Binput::get('order'),
Binput::get('group_id'),
- (bool) Binput::get('enabled', true)
+ (bool) Binput::get('enabled', true),
+ Binput::get('meta'),
+ Binput::get('tags')
));
} catch (QueryException $e) {
throw new BadRequestHttpException();
}
- if (Binput::has('tags')) {
- // The component was added successfully, so now let's deal with the tags.
- $tags = preg_split('/ ?, ?/', Binput::get('tags'));
-
- // For every tag, do we need to create it?
- $componentTags = array_map(function ($taggable) use ($component) {
- return Tag::firstOrCreate([
- 'name' => $taggable,
- ])->id;
- }, $tags);
-
- $component->tags()->sync($componentTags);
- }
-
return $this->item($component);
}
@@ -107,10 +98,10 @@ public function postComponents()
*
* @return \Illuminate\Http\JsonResponse
*/
- public function putComponent(Component $component)
+ public function update(Component $component)
{
try {
- dispatch(new UpdateComponentCommand(
+ execute(new UpdateComponentCommand(
$component,
Binput::get('name'),
Binput::get('description'),
@@ -118,23 +109,15 @@ public function putComponent(Component $component)
Binput::get('link'),
Binput::get('order'),
Binput::get('group_id'),
- (bool) Binput::get('enabled', true)
+ Binput::get('enabled', $component->enabled),
+ Binput::get('meta'),
+ Binput::get('tags'),
+ (bool) Binput::get('silent', false)
));
} catch (QueryException $e) {
throw new BadRequestHttpException();
}
- if (Binput::has('tags')) {
- $tags = preg_split('/ ?, ?/', Binput::get('tags'));
-
- // For every tag, do we need to create it?
- $componentTags = array_map(function ($taggable) use ($component) {
- return Tag::firstOrCreate(['name' => $taggable])->id;
- }, $tags);
-
- $component->tags()->sync($componentTags);
- }
-
return $this->item($component);
}
@@ -145,9 +128,9 @@ public function putComponent(Component $component)
*
* @return \Illuminate\Http\JsonResponse
*/
- public function deleteComponent(Component $component)
+ public function destroy(Component $component)
{
- dispatch(new RemoveComponentCommand($component));
+ execute(new RemoveComponentCommand($component));
return $this->noContent();
}
diff --git a/app/Http/Controllers/Api/ComponentGroupController.php b/app/Http/Controllers/Api/ComponentGroupController.php
index 9c424b798233..957106e101d3 100644
--- a/app/Http/Controllers/Api/ComponentGroupController.php
+++ b/app/Http/Controllers/Api/ComponentGroupController.php
@@ -11,11 +11,12 @@
namespace CachetHQ\Cachet\Http\Controllers\Api;
-use CachetHQ\Cachet\Bus\Commands\ComponentGroup\AddComponentGroupCommand;
+use CachetHQ\Cachet\Bus\Commands\ComponentGroup\CreateComponentGroupCommand;
use CachetHQ\Cachet\Bus\Commands\ComponentGroup\RemoveComponentGroupCommand;
use CachetHQ\Cachet\Bus\Commands\ComponentGroup\UpdateComponentGroupCommand;
use CachetHQ\Cachet\Models\ComponentGroup;
use GrahamCampbell\Binput\Facades\Binput;
+use Illuminate\Contracts\Auth\Guard;
use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\Request;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
@@ -25,23 +26,43 @@
*
* @author James Brooks
* @author Graham Campbell
- * @author Joe Cohen
+ * @author Joseph Cohen
*/
class ComponentGroupController extends AbstractApiController
{
+ /**
+ * The user session object.
+ *
+ * @var \Illuminate\Contracts\Auth\Guard
+ */
+ protected $guard;
+
+ /**
+ * Creates a new component group controller instance.
+ *
+ * @param \Illuminate\Contracts\Auth\Guard $guard
+ */
+ public function __construct(Guard $guard)
+ {
+ $this->guard = $guard;
+ }
+
/**
* Get all groups.
*
* @return \Illuminate\Http\JsonResponse
*/
- public function getGroups()
+ public function index()
{
$groups = ComponentGroup::query();
+ if (!$this->guard->check()) {
+ $groups = ComponentGroup::visible();
+ }
$groups->search(Binput::except(['sort', 'order', 'per_page']));
if ($sortBy = Binput::get('sort')) {
- $direction = Binput::has('order') && Binput::get('order') == 'desc';
+ $direction = Binput::get('order', 'asc');
$groups->sort($sortBy, $direction);
}
@@ -58,7 +79,7 @@ public function getGroups()
*
* @return \Illuminate\Http\JsonResponse
*/
- public function getGroup(ComponentGroup $group)
+ public function show(ComponentGroup $group)
{
return $this->item($group);
}
@@ -68,13 +89,14 @@ public function getGroup(ComponentGroup $group)
*
* @return \Illuminate\Http\JsonResponse
*/
- public function postGroups()
+ public function store()
{
try {
- $group = dispatch(new AddComponentGroupCommand(
+ $group = execute(new CreateComponentGroupCommand(
Binput::get('name'),
Binput::get('order', 0),
- Binput::get('collapsed', 0)
+ Binput::get('collapsed', 0),
+ Binput::get('visible', ComponentGroup::VISIBLE_AUTHENTICATED)
));
} catch (QueryException $e) {
throw new BadRequestHttpException();
@@ -90,14 +112,15 @@ public function postGroups()
*
* @return \Illuminate\Http\JsonResponse
*/
- public function putGroup(ComponentGroup $group)
+ public function update(ComponentGroup $group)
{
try {
- $group = dispatch(new UpdateComponentGroupCommand(
+ $group = execute(new UpdateComponentGroupCommand(
$group,
Binput::get('name'),
Binput::get('order'),
- Binput::get('collapsed')
+ Binput::get('collapsed'),
+ Binput::get('visible')
));
} catch (QueryException $e) {
throw new BadRequestHttpException();
@@ -113,9 +136,9 @@ public function putGroup(ComponentGroup $group)
*
* @return \Illuminate\Http\JsonResponse
*/
- public function deleteGroup(ComponentGroup $group)
+ public function destroy(ComponentGroup $group)
{
- dispatch(new RemoveComponentGroupCommand($group));
+ execute(new RemoveComponentGroupCommand($group));
return $this->noContent();
}
diff --git a/app/Http/Controllers/Api/GeneralController.php b/app/Http/Controllers/Api/GeneralController.php
index 2005560e92cc..23ba1fa4485f 100644
--- a/app/Http/Controllers/Api/GeneralController.php
+++ b/app/Http/Controllers/Api/GeneralController.php
@@ -17,7 +17,7 @@
/**
* This is the general api controller.
*
- * @author James Brooks
+ * @author James Brooks
*/
class GeneralController extends AbstractApiController
{
@@ -55,6 +55,9 @@ public function status()
{
$system = app()->make(System::class)->getStatus();
- return $this->item($system['system_message']);
+ return $this->item([
+ 'status' => $system['system_status'],
+ 'message' => $system['system_message'],
+ ]);
}
}
diff --git a/app/Http/Controllers/Api/IncidentController.php b/app/Http/Controllers/Api/IncidentController.php
index 0d7c8993c682..cd705519f588 100644
--- a/app/Http/Controllers/Api/IncidentController.php
+++ b/app/Http/Controllers/Api/IncidentController.php
@@ -11,8 +11,8 @@
namespace CachetHQ\Cachet\Http\Controllers\Api;
+use CachetHQ\Cachet\Bus\Commands\Incident\CreateIncidentCommand;
use CachetHQ\Cachet\Bus\Commands\Incident\RemoveIncidentCommand;
-use CachetHQ\Cachet\Bus\Commands\Incident\ReportIncidentCommand;
use CachetHQ\Cachet\Bus\Commands\Incident\UpdateIncidentCommand;
use CachetHQ\Cachet\Models\Incident;
use GrahamCampbell\Binput\Facades\Binput;
@@ -28,7 +28,7 @@ class IncidentController extends AbstractApiController
*
* @return \Illuminate\Http\JsonResponse
*/
- public function getIncidents()
+ public function index()
{
$incidentVisibility = app(Guard::class)->check() ? 0 : 1;
@@ -54,7 +54,7 @@ public function getIncidents()
*
* @return \Illuminate\Http\JsonResponse
*/
- public function getIncident(Incident $incident)
+ public function show(Incident $incident)
{
return $this->item($incident);
}
@@ -64,21 +64,22 @@ public function getIncident(Incident $incident)
*
* @return \Illuminate\Http\JsonResponse
*/
- public function postIncidents()
+ public function store()
{
try {
- $incident = dispatch(new ReportIncidentCommand(
+ $incident = execute(new CreateIncidentCommand(
Binput::get('name'),
Binput::get('status'),
- Binput::get('message'),
- Binput::get('visible', true),
+ Binput::get('message', null, false, false),
+ (bool) Binput::get('visible', true),
Binput::get('component_id'),
Binput::get('component_status'),
- Binput::get('notify', true),
- Binput::get('stickied', false),
- Binput::get('created_at'),
+ (bool) Binput::get('notify', true),
+ (bool) Binput::get('stickied', false),
+ Binput::get('occurred_at'),
Binput::get('template'),
- Binput::get('vars')
+ Binput::get('vars', []),
+ Binput::get('meta', [])
));
} catch (QueryException $e) {
throw new BadRequestHttpException();
@@ -94,22 +95,22 @@ public function postIncidents()
*
* @return \Illuminate\Http\JsonResponse
*/
- public function putIncident(Incident $incident)
+ public function update(Incident $incident)
{
try {
- $incident = dispatch(new UpdateIncidentCommand(
+ $incident = execute(new UpdateIncidentCommand(
$incident,
Binput::get('name'),
Binput::get('status'),
Binput::get('message'),
- Binput::get('visible', true),
+ (bool) Binput::get('visible', true),
Binput::get('component_id'),
Binput::get('component_status'),
- Binput::get('notify', true),
- Binput::get('stickied', false),
- Binput::get('created_at'),
+ (bool) Binput::get('notify', true),
+ (bool) Binput::get('stickied', false),
+ Binput::get('occurred_at'),
Binput::get('template'),
- Binput::get('vars')
+ Binput::get('vars', [])
));
} catch (QueryException $e) {
throw new BadRequestHttpException();
@@ -125,9 +126,9 @@ public function putIncident(Incident $incident)
*
* @return \Illuminate\Http\JsonResponse
*/
- public function deleteIncident(Incident $incident)
+ public function destroy(Incident $incident)
{
- dispatch(new RemoveIncidentCommand($incident));
+ execute(new RemoveIncidentCommand($incident));
return $this->noContent();
}
diff --git a/app/Http/Controllers/Api/IncidentTemplateController.php b/app/Http/Controllers/Api/IncidentTemplateController.php
new file mode 100644
index 000000000000..3f1ba4183566
--- /dev/null
+++ b/app/Http/Controllers/Api/IncidentTemplateController.php
@@ -0,0 +1,51 @@
+sort($sortBy, $direction);
+ }
+
+ $templates = $templates->paginate(Binput::get('per_page', 20));
+
+ return $this->paginator($templates, Request::instance());
+ }
+
+ /**
+ * Get a single incident templates.
+ *
+ * @param \CachetHQ\Cachet\Models\IncidentTemplate $incidentTemplate
+ *
+ * @return \Illuminate\Http\JsonResponse
+ */
+ public function show(IncidentTemplate $incidentTemplate)
+ {
+ return $this->item($incidentTemplate);
+ }
+}
diff --git a/app/Http/Controllers/Api/IncidentUpdateController.php b/app/Http/Controllers/Api/IncidentUpdateController.php
new file mode 100644
index 000000000000..0c239a6a4310
--- /dev/null
+++ b/app/Http/Controllers/Api/IncidentUpdateController.php
@@ -0,0 +1,134 @@
+
+ */
+class IncidentUpdateController extends AbstractApiController
+{
+ /**
+ * Return all updates on the incident.
+ *
+ * @param \CachetHQ\Cachet\Models\Incident $incident
+ *
+ * @return \Illuminate\Http\JsonResponse
+ */
+ public function index(Incident $incident)
+ {
+ $updates = $incident->updates()->orderBy('created_at', 'desc');
+
+ if ($sortBy = Binput::get('sort')) {
+ $direction = Binput::has('order') && Binput::get('order') == 'desc';
+
+ $updates->sort($sortBy, $direction);
+ }
+
+ $updates = $updates->paginate(Binput::get('per_page', 20));
+
+ return $this->paginator($updates, Request::instance());
+ }
+
+ /**
+ * Return a single incident update.
+ *
+ * @param \CachetHQ\Cachet\Models\Incident $incident
+ * @param \CachetHQ\Cachet\Models\IncidentUpdate $update
+ *
+ * @return \Illuminate\Http\JsonResponse
+ */
+ public function show(Incident $incident, IncidentUpdate $update)
+ {
+ return $this->item($update);
+ }
+
+ /**
+ * Create a new incident update.
+ *
+ * @param \CachetHQ\Cachet\Models\Incident $incident
+ *
+ * @return \Illuminate\Http\JsonResponse
+ */
+ public function store(Incident $incident)
+ {
+ try {
+ $update = execute(new CreateIncidentUpdateCommand(
+ $incident,
+ Binput::get('status'),
+ Binput::get('message'),
+ Binput::get('component_id'),
+ Binput::get('component_status'),
+ Auth::user()
+ ));
+ } catch (QueryException $e) {
+ throw new BadRequestHttpException();
+ }
+
+ return $this->item($update);
+ }
+
+ /**
+ * Update an incident update.
+ *
+ * @param \CachetHQ\Cachet\Models\Incident $incident
+ * @param \CachetHQ\Cachet\Models\IncidentUpdate $update
+ *
+ * @return \Illuminate\Http\JsonResponse
+ */
+ public function update(Incident $incident, IncidentUpdate $update)
+ {
+ try {
+ $update = execute(new UpdateIncidentUpdateCommand(
+ $update,
+ Binput::get('status'),
+ Binput::get('message'),
+ Auth::user()
+ ));
+ } catch (QueryException $e) {
+ throw new BadRequestHttpException();
+ }
+
+ return $this->item($update);
+ }
+
+ /**
+ * Create a new incident update.
+ *
+ * @param \CachetHQ\Cachet\Models\Incident $incident
+ * @param \CachetHQ\Cachet\Models\IncidentUpdate $update
+ *
+ * @return \Illuminate\Http\JsonResponse
+ */
+ public function destroy(Incident $incident, IncidentUpdate $update)
+ {
+ try {
+ execute(new RemoveIncidentUpdateCommand($update));
+ } catch (QueryException $e) {
+ throw new BadRequestHttpException();
+ }
+
+ return $this->noContent();
+ }
+}
diff --git a/app/Http/Controllers/Api/MetricController.php b/app/Http/Controllers/Api/MetricController.php
index d8b931b01bb1..4ef2e1e4fd38 100644
--- a/app/Http/Controllers/Api/MetricController.php
+++ b/app/Http/Controllers/Api/MetricController.php
@@ -11,7 +11,7 @@
namespace CachetHQ\Cachet\Http\Controllers\Api;
-use CachetHQ\Cachet\Bus\Commands\Metric\AddMetricCommand;
+use CachetHQ\Cachet\Bus\Commands\Metric\CreateMetricCommand;
use CachetHQ\Cachet\Bus\Commands\Metric\RemoveMetricCommand;
use CachetHQ\Cachet\Bus\Commands\Metric\UpdateMetricCommand;
use CachetHQ\Cachet\Models\Metric;
@@ -27,7 +27,7 @@ class MetricController extends AbstractApiController
*
* @return \Illuminate\Database\Eloquent\Collection
*/
- public function getMetrics()
+ public function index()
{
$metrics = Metric::query();
@@ -49,34 +49,20 @@ public function getMetrics()
*
* @return \Illuminate\Http\JsonResponse
*/
- public function getMetric(Metric $metric)
+ public function show(Metric $metric)
{
return $this->item($metric);
}
- /**
- * Get all metric points.
- *
- * @param \CachetHQ\Cachet\Models\Metric $metric
- *
- * @return \Illuminate\Database\Eloquent\Collection
- */
- public function getMetricPoints(Metric $metric)
- {
- $points = $metric->points()->paginate(Binput::get('per_page', 20));
-
- return $this->paginator($points, Request::instance());
- }
-
/**
* Create a new metric.
*
* @return \Illuminate\Http\JsonResponse
*/
- public function postMetrics()
+ public function store()
{
try {
- $metric = dispatch(new AddMetricCommand(
+ $metric = execute(new CreateMetricCommand(
Binput::get('name'),
Binput::get('suffix'),
Binput::get('description'),
@@ -86,7 +72,8 @@ public function postMetrics()
Binput::get('places', 2),
Binput::get('default_view', Binput::get('view', 1)),
Binput::get('threshold', 5),
- Binput::get('order', 0)
+ Binput::get('order', 0),
+ Binput::get('visible', 1)
));
} catch (QueryException $e) {
throw new BadRequestHttpException();
@@ -102,10 +89,10 @@ public function postMetrics()
*
* @return \Illuminate\Http\JsonResponse
*/
- public function putMetric(Metric $metric)
+ public function update(Metric $metric)
{
try {
- $metric = dispatch(new UpdateMetricCommand(
+ $metric = execute(new UpdateMetricCommand(
$metric,
Binput::get('name'),
Binput::get('suffix'),
@@ -116,7 +103,8 @@ public function putMetric(Metric $metric)
Binput::get('places'),
Binput::get('default_view', Binput::get('view')),
Binput::get('threshold'),
- Binput::get('order')
+ Binput::get('order'),
+ Binput::get('visible')
));
} catch (QueryException $e) {
throw new BadRequestHttpException();
@@ -132,9 +120,9 @@ public function putMetric(Metric $metric)
*
* @return \Illuminate\Http\JsonResponse
*/
- public function deleteMetric(Metric $metric)
+ public function destroy(Metric $metric)
{
- dispatch(new RemoveMetricCommand($metric));
+ execute(new RemoveMetricCommand($metric));
return $this->noContent();
}
diff --git a/app/Http/Controllers/Api/MetricPointController.php b/app/Http/Controllers/Api/MetricPointController.php
index a84758d93349..8afb5c59ed11 100644
--- a/app/Http/Controllers/Api/MetricPointController.php
+++ b/app/Http/Controllers/Api/MetricPointController.php
@@ -11,13 +11,14 @@
namespace CachetHQ\Cachet\Http\Controllers\Api;
-use CachetHQ\Cachet\Bus\Commands\Metric\AddMetricPointCommand;
+use CachetHQ\Cachet\Bus\Commands\Metric\CreateMetricPointCommand;
use CachetHQ\Cachet\Bus\Commands\Metric\RemoveMetricPointCommand;
use CachetHQ\Cachet\Bus\Commands\Metric\UpdateMetricPointCommand;
use CachetHQ\Cachet\Models\Metric;
use CachetHQ\Cachet\Models\MetricPoint;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Database\QueryException;
+use Illuminate\Support\Facades\Request;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
class MetricPointController extends AbstractApiController
@@ -30,9 +31,11 @@ class MetricPointController extends AbstractApiController
*
* @return \Illuminate\Http\JsonResponse
*/
- public function getMetricPoints(Metric $metric, MetricPoint $metricPoint)
+ public function index(Metric $metric, MetricPoint $metricPoint)
{
- return $this->item($metricPoint);
+ $points = $metric->points()->paginate(Binput::get('per_page', 20));
+
+ return $this->paginator($points, Request::instance());
}
/**
@@ -42,10 +45,10 @@ public function getMetricPoints(Metric $metric, MetricPoint $metricPoint)
*
* @return \Illuminate\Http\JsonResponse
*/
- public function postMetricPoints(Metric $metric)
+ public function store(Metric $metric)
{
try {
- $metricPoint = dispatch(new AddMetricPointCommand(
+ $metricPoint = execute(new CreateMetricPointCommand(
$metric,
Binput::get('value'),
Binput::get('timestamp')
@@ -61,13 +64,13 @@ public function postMetricPoints(Metric $metric)
* Updates a metric point.
*
* @param \CachetHQ\Cachet\Models\Metric $metric
- * @param \CachetHQ\Cachet\Models\MetircPoint $metricPoint
+ * @param \CachetHQ\Cachet\Models\MetricPoint $metricPoint
*
* @return \Illuminate\Http\JsonResponse
*/
- public function putMetricPoint(Metric $metric, MetricPoint $metricPoint)
+ public function update(Metric $metric, MetricPoint $metricPoint)
{
- $metricPoint = dispatch(new UpdateMetricPointCommand(
+ $metricPoint = execute(new UpdateMetricPointCommand(
$metricPoint,
$metric,
Binput::get('value'),
@@ -85,9 +88,9 @@ public function putMetricPoint(Metric $metric, MetricPoint $metricPoint)
*
* @return \Illuminate\Http\JsonResponse
*/
- public function deleteMetricPoint(Metric $metric, MetricPoint $metricPoint)
+ public function destroy(Metric $metric, MetricPoint $metricPoint)
{
- dispatch(new RemoveMetricPointCommand($metricPoint));
+ execute(new RemoveMetricPointCommand($metricPoint));
return $this->noContent();
}
diff --git a/app/Http/Controllers/Api/ScheduleController.php b/app/Http/Controllers/Api/ScheduleController.php
new file mode 100644
index 000000000000..c59f46dbd62c
--- /dev/null
+++ b/app/Http/Controllers/Api/ScheduleController.php
@@ -0,0 +1,129 @@
+
+ */
+class ScheduleController extends AbstractApiController
+{
+ /**
+ * Return all schedules.
+ *
+ * @return \Illuminate\Http\JsonResponse
+ */
+ public function index()
+ {
+ $schedule = Schedule::query();
+
+ if ($sortBy = Binput::get('sort')) {
+ $direction = Binput::has('order') && Binput::get('order') == 'desc';
+
+ $schedule->sort($sortBy, $direction);
+ }
+
+ $schedule = $schedule->paginate(Binput::get('per_page', 20));
+
+ return $this->paginator($schedule, Request::instance());
+ }
+
+ /**
+ * Return a single schedule.
+ *
+ * @param \CachetHQ\Cachet\Models\Schedule $schedule
+ *
+ * @return \Illuminate\Http\JsonResponse
+ */
+ public function show(Schedule $schedule)
+ {
+ return $this->item($schedule);
+ }
+
+ /**
+ * Create a new schedule.
+ *
+ * @return \Illuminate\Http\JsonResponse
+ */
+ public function store()
+ {
+ try {
+ $schedule = execute(new CreateScheduleCommand(
+ Binput::get('name'),
+ Binput::get('message', null, false, false),
+ Binput::get('status'),
+ Binput::get('scheduled_at'),
+ Binput::get('completed_at'),
+ Binput::get('components', []),
+ Binput::get('notify', false)
+ ));
+ } catch (QueryException $e) {
+ throw new BadRequestHttpException();
+ }
+
+ return $this->item($schedule);
+ }
+
+ /**
+ * Update a schedule.
+ *
+ * @param \CachetHQ\Cachet\Models\Schedule $schedule
+ *
+ * @return \Illuminate\Http\JsonResponse
+ */
+ public function update(Schedule $schedule)
+ {
+ try {
+ $schedule = execute(new UpdateScheduleCommand(
+ $schedule,
+ Binput::get('name'),
+ Binput::get('message'),
+ Binput::get('status'),
+ Binput::get('scheduled_at'),
+ Binput::get('completed_at'),
+ Binput::get('components', [])
+ ));
+ } catch (QueryException $e) {
+ throw new BadRequestHttpException();
+ }
+
+ return $this->item($schedule);
+ }
+
+ /**
+ * Delete a schedule.
+ *
+ * @param \CachetHQ\Cachet\Models\Schedule $schedule
+ *
+ * @return \Illuminate\Http\JsonResponse
+ */
+ public function destroy(Schedule $schedule)
+ {
+ try {
+ execute(new DeleteScheduleCommand($schedule));
+ } catch (QueryException $e) {
+ throw new BadRequestHttpException();
+ }
+
+ return $this->noContent();
+ }
+}
diff --git a/app/Http/Controllers/Api/SubscriberController.php b/app/Http/Controllers/Api/SubscriberController.php
index 4d1793deb1a1..621aa06d70bb 100644
--- a/app/Http/Controllers/Api/SubscriberController.php
+++ b/app/Http/Controllers/Api/SubscriberController.php
@@ -13,9 +13,7 @@
use CachetHQ\Cachet\Bus\Commands\Subscriber\SubscribeSubscriberCommand;
use CachetHQ\Cachet\Bus\Commands\Subscriber\UnsubscribeSubscriberCommand;
-use CachetHQ\Cachet\Bus\Commands\Subscriber\UnsubscribeSubscriptionCommand;
use CachetHQ\Cachet\Models\Subscriber;
-use CachetHQ\Cachet\Models\Subscription;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Contracts\Config\Repository;
use Illuminate\Database\QueryException;
@@ -35,7 +33,7 @@ class SubscriberController extends AbstractApiController
*
* @return \Illuminate\Http\JsonResponse
*/
- public function getSubscribers()
+ public function index()
{
$subscribers = Subscriber::paginate(Binput::get('per_page', 20));
@@ -47,12 +45,12 @@ public function getSubscribers()
*
* @return \Illuminate\Http\JsonResponse
*/
- public function postSubscribers()
+ public function store()
{
$verified = Binput::get('verify', app(Repository::class)->get('setting.skip_subscriber_verification'));
try {
- $subscriber = dispatch(new SubscribeSubscriberCommand(Binput::get('email'), $verified, Binput::get('components')));
+ $subscriber = execute(new SubscribeSubscriberCommand(Binput::get('email'), $verified, Binput::get('components', null)));
} catch (QueryException $e) {
throw new BadRequestHttpException();
}
@@ -67,23 +65,9 @@ public function postSubscribers()
*
* @return \Illuminate\Http\JsonResponse
*/
- public function deleteSubscriber(Subscriber $subscriber)
+ public function destroy(Subscriber $subscriber)
{
- dispatch(new UnsubscribeSubscriberCommand($subscriber));
-
- return $this->noContent();
- }
-
- /**
- * Delete a subscriber.
- *
- * @param \CachetHQ\Cachet\Models\Subscriber $subscriber
- *
- * @return \Illuminate\Http\JsonResponse
- */
- public function deleteSubscription(Subscription $subscriber)
- {
- dispatch(new UnsubscribeSubscriptionCommand($subscriber));
+ execute(new UnsubscribeSubscriberCommand($subscriber));
return $this->noContent();
}
diff --git a/app/Http/Controllers/Api/SubscriptionController.php b/app/Http/Controllers/Api/SubscriptionController.php
new file mode 100644
index 000000000000..173a5e0ffc9e
--- /dev/null
+++ b/app/Http/Controllers/Api/SubscriptionController.php
@@ -0,0 +1,37 @@
+
+ */
+class SubscriptionController extends AbstractApiController
+{
+ /**
+ * Delete a subscription.
+ *
+ * @param \CachetHQ\Cachet\Models\Subscription $subscription
+ *
+ * @return \Illuminate\Http\JsonResponse
+ */
+ public function destroy(Subscription $subscription)
+ {
+ execute(new UnsubscribeSubscriptionCommand($subscription));
+
+ return $this->noContent();
+ }
+}
diff --git a/app/Http/Controllers/AuthController.php b/app/Http/Controllers/AuthController.php
index c267ccb4a766..597b9b51893a 100644
--- a/app/Http/Controllers/AuthController.php
+++ b/app/Http/Controllers/AuthController.php
@@ -17,13 +17,12 @@
use CachetHQ\Cachet\Bus\Events\User\UserPassedTwoAuthEvent;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Routing\Controller;
+use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Redirect;
-use Illuminate\Support\Facades\Request;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\View;
-use Illuminate\Support\Str;
-use PragmaRX\Google2FA\Vendor\Laravel\Facade as Google2FA;
+use PragmaRX\Google2FA\Google2FA;
class AuthController extends Controller
{
@@ -45,33 +44,32 @@ public function showLogin()
*/
public function postLogin()
{
- $loginData = Binput::only(['username', 'password']);
+ $loginData = Binput::only(['username', 'password', 'remember_me']);
// Login with username or email.
- $loginKey = Str::contains($loginData['username'], '@') ? 'email' : 'username';
- $loginData[$loginKey] = array_pull($loginData, 'username');
+ $loginKey = filter_var($loginData['username'], FILTER_VALIDATE_EMAIL) ? 'email' : 'username';
+ $loginData[$loginKey] = Arr::pull($loginData, 'username');
+
+ $rememberUser = Arr::pull($loginData, 'remember_me') === '1';
// Validate login credentials.
if (Auth::validate($loginData)) {
- // Log the user in for one request.
Auth::once($loginData);
- // Do we have Two Factor Auth enabled?
+
if (Auth::user()->hasTwoFactor) {
- // Temporarily store the user.
Session::put('2fa_id', Auth::user()->id);
- return Redirect::route('auth.two-factor');
+ return cachet_redirect('auth.two-factor');
}
- // We probably want to add support for "Remember me" here.
- Auth::attempt($loginData);
+ Auth::attempt($loginData, $rememberUser);
event(new UserLoggedInEvent(Auth::user()));
- return Redirect::intended('dashboard');
+ return Redirect::intended(cachet_route('dashboard'));
}
- return Redirect::route('auth.login')
+ return cachet_redirect('auth.login')
->withInput(Binput::except('password'))
->withError(trans('forms.login.invalid'));
}
@@ -91,36 +89,43 @@ public function showTwoFactorAuth()
*
* This feels very hacky, but we have to juggle authentication and codes.
*
+ * @throws \PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException
+ * @throws \PragmaRX\Google2FA\Exceptions\InvalidCharactersException
+ * @throws \PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException
+ *
* @return \Illuminate\Http\RedirectResponse
*/
public function postTwoFactor()
{
// Check that we have a session.
if ($userId = Session::pull('2fa_id')) {
- $code = Binput::get('code');
+ $code = str_replace(' ', '', Binput::get('code'));
// Maybe a temp login here.
Auth::loginUsingId($userId);
- $valid = Google2FA::verifyKey(Auth::user()->google_2fa_secret, $code);
+ $user = Auth::user();
+
+ $google2fa = new Google2FA();
+ $valid = $google2fa->verifyKey($user->google_2fa_secret, $code);
if ($valid) {
- event(new UserPassedTwoAuthEvent(Auth::user()));
+ event(new UserPassedTwoAuthEvent($user));
- event(new UserLoggedInEvent(Auth::user()));
+ event(new UserLoggedInEvent($user));
return Redirect::intended('dashboard');
} else {
- event(new UserFailedTwoAuthEvent(Auth::user()));
+ event(new UserFailedTwoAuthEvent($user));
// Failed login, log back out.
Auth::logout();
- return Redirect::route('auth.login')->withError(trans('forms.login.invalid-token'));
+ return cachet_redirect('auth.login')->withError(trans('forms.login.invalid-token'));
}
}
- return Redirect::route('auth.login')->withError(trans('forms.login.invalid-token'));
+ return cachet_redirect('auth.login')->withError(trans('forms.login.invalid-token'));
}
/**
@@ -134,6 +139,6 @@ public function logoutAction()
Auth::logout();
- return Redirect::to('/');
+ return cachet_redirect('status-page');
}
}
diff --git a/app/Http/Controllers/Dashboard/ApiController.php b/app/Http/Controllers/Dashboard/ApiController.php
index 42a437fe5704..4e59a7a40c17 100644
--- a/app/Http/Controllers/Dashboard/ApiController.php
+++ b/app/Http/Controllers/Dashboard/ApiController.php
@@ -36,7 +36,7 @@ class ApiController extends AbstractApiController
public function postUpdateComponent(Component $component)
{
try {
- dispatch(new UpdateComponentCommand(
+ execute(new UpdateComponentCommand(
$component,
$component->name,
$component->description,
@@ -44,7 +44,10 @@ public function postUpdateComponent(Component $component)
$component->link,
$component->order,
$component->group_id,
- $component->enabled
+ $component->enabled,
+ $component->meta,
+ $component->tags,
+ true // Silent mode
));
} catch (QueryException $e) {
throw new BadRequestHttpException();
@@ -66,7 +69,7 @@ public function postUpdateComponentOrder()
try {
$component = Component::find($componentId);
- dispatch(new UpdateComponentCommand(
+ execute(new UpdateComponentCommand(
$component,
$component->name,
$component->description,
@@ -74,7 +77,10 @@ public function postUpdateComponentOrder()
$component->link,
$order + 1,
$component->group_id,
- $component->enabled
+ $component->enabled,
+ $component->meta,
+ $component->tags,
+ true // Silent mode
));
} catch (QueryException $e) {
throw new BadRequestHttpException();
@@ -96,11 +102,12 @@ public function postUpdateComponentGroupOrder()
foreach ($groupData as $order => $groupId) {
$group = ComponentGroup::find($groupId);
- dispatch(new UpdateComponentGroupCommand(
+ execute(new UpdateComponentGroupCommand(
$group,
$group->name,
$order + 1,
- $group->collapsed
+ $group->collapsed,
+ $group->visible
));
}
@@ -118,7 +125,7 @@ public function getIncidentTemplate()
{
$templateSlug = Binput::get('slug');
- if ($template = IncidentTemplate::where('slug', $templateSlug)->first()) {
+ if ($template = IncidentTemplate::where('slug', '=', $templateSlug)->first()) {
return $template;
}
diff --git a/app/Http/Controllers/Dashboard/ComponentController.php b/app/Http/Controllers/Dashboard/ComponentController.php
index 38a021f453cd..c9c8e6792e1e 100644
--- a/app/Http/Controllers/Dashboard/ComponentController.php
+++ b/app/Http/Controllers/Dashboard/ComponentController.php
@@ -12,20 +12,20 @@
namespace CachetHQ\Cachet\Http\Controllers\Dashboard;
use AltThree\Validator\ValidationException;
-use CachetHQ\Cachet\Bus\Commands\Component\AddComponentCommand;
+use CachetHQ\Cachet\Bus\Commands\Component\CreateComponentCommand;
use CachetHQ\Cachet\Bus\Commands\Component\RemoveComponentCommand;
use CachetHQ\Cachet\Bus\Commands\Component\UpdateComponentCommand;
-use CachetHQ\Cachet\Bus\Commands\ComponentGroup\AddComponentGroupCommand;
-use CachetHQ\Cachet\Bus\Commands\ComponentGroup\RemoveComponentGroupCommand;
-use CachetHQ\Cachet\Bus\Commands\ComponentGroup\UpdateComponentGroupCommand;
use CachetHQ\Cachet\Models\Component;
use CachetHQ\Cachet\Models\ComponentGroup;
-use CachetHQ\Cachet\Models\Tag;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Routing\Controller;
-use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\View;
+/**
+ * This is the component controller class.
+ *
+ * @author James Brooks
+ */
class ComponentController extends Controller
{
/**
@@ -45,21 +45,21 @@ public function __construct()
$this->subMenu = [
'components' => [
'title' => trans('dashboard.components.components'),
- 'url' => route('dashboard.components.index'),
+ 'url' => cachet_route('dashboard.components'),
'icon' => 'ion-ios-browsers',
'active' => false,
],
'groups' => [
'title' => trans_choice('dashboard.components.groups.groups', 2),
- 'url' => route('dashboard.components.groups'),
+ 'url' => cachet_route('dashboard.components.groups'),
'icon' => 'ion-folder',
'active' => false,
],
];
View::share([
- 'sub_menu' => $this->subMenu,
- 'sub_title' => trans_choice('dashboard.components.components', 2),
+ 'subMenu' => $this->subMenu,
+ 'subTitle' => trans_choice('dashboard.components.components', 2),
]);
}
@@ -70,7 +70,7 @@ public function __construct()
*/
public function showComponents()
{
- $components = Component::orderBy('order')->orderBy('created_at')->get();
+ $components = Component::with('group')->orderBy('order')->orderBy('created_at')->get();
$this->subMenu['components']['active'] = true;
@@ -80,21 +80,6 @@ public function showComponents()
->withSubMenu($this->subMenu);
}
- /**
- * Shows the component groups view.
- *
- * @return \Illuminate\View\View
- */
- public function showComponentGroups()
- {
- $this->subMenu['groups']['active'] = true;
-
- return View::make('dashboard.components.groups.index')
- ->withPageTitle(trans_choice('dashboard.components.groups.groups', 2).' - '.trans('dashboard.dashboard'))
- ->withGroups(ComponentGroup::orderBy('order')->get())
- ->withSubMenu($this->subMenu);
- }
-
/**
* Shows the edit component view.
*
@@ -124,10 +109,9 @@ public function showEditComponent(Component $component)
public function updateComponentAction(Component $component)
{
$componentData = Binput::get('component');
- $tags = array_pull($componentData, 'tags');
try {
- $component = dispatch(new UpdateComponentCommand(
+ $component = execute(new UpdateComponentCommand(
$component,
$componentData['name'],
$componentData['description'],
@@ -135,26 +119,19 @@ public function updateComponentAction(Component $component)
$componentData['link'],
$componentData['order'],
$componentData['group_id'],
- $componentData['enabled']
+ $componentData['enabled'],
+ null, // Meta data cannot be supplied through the dashboard yet.
+ $componentData['tags'], // Meta data cannot be supplied through the dashboard yet.
+ true // Silent since we're not really making changes to the component (this should be optional)
));
} catch (ValidationException $e) {
- return Redirect::route('dashboard.components.edit', ['id' => $component->id])
+ return cachet_redirect('dashboard.components.edit', [$component->id])
->withInput(Binput::all())
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.components.edit.failure')))
->withErrors($e->getMessageBag());
}
- // The component was added successfully, so now let's deal with the tags.
- $tags = preg_split('/ ?, ?/', $tags);
-
- // For every tag, do we need to create it?
- $componentTags = array_map(function ($taggable) use ($component) {
- return Tag::firstOrCreate(['name' => $taggable])->id;
- }, $tags);
-
- $component->tags()->sync($componentTags);
-
- return Redirect::route('dashboard.components.edit', ['id' => $component->id])
+ return cachet_redirect('dashboard.components.edit', [$component->id])
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.components.edit.success')));
}
@@ -178,36 +155,27 @@ public function showAddComponent()
public function createComponentAction()
{
$componentData = Binput::get('component');
- $tags = array_pull($componentData, 'tags');
try {
- $component = dispatch(new AddComponentCommand(
+ $component = execute(new CreateComponentCommand(
$componentData['name'],
$componentData['description'],
$componentData['status'],
$componentData['link'],
$componentData['order'],
$componentData['group_id'],
- $componentData['enabled']
+ $componentData['enabled'],
+ null, // Meta data cannot be supplied through the dashboard yet.
+ $componentData['tags']
));
} catch (ValidationException $e) {
- return Redirect::route('dashboard.components.add')
+ return cachet_redirect('dashboard.components.create')
->withInput(Binput::all())
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.components.add.failure')))
->withErrors($e->getMessageBag());
}
- // The component was added successfully, so now let's deal with the tags.
- $tags = preg_split('/ ?, ?/', $tags);
-
- // For every tag, do we need to create it?
- $componentTags = array_map(function ($taggable) use ($component) {
- return Tag::firstOrCreate(['name' => $taggable])->id;
- }, $tags);
-
- $component->tags()->sync($componentTags);
-
- return Redirect::route('dashboard.components.index')
+ return cachet_redirect('dashboard.components')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.components.add.success')));
}
@@ -220,100 +188,9 @@ public function createComponentAction()
*/
public function deleteComponentAction(Component $component)
{
- dispatch(new RemoveComponentCommand($component));
-
- return Redirect::route('dashboard.components.index')
- ->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.components.delete.success')));
- }
-
- /**
- * Deletes a given component group.
- *
- * @param \CachetHQ\Cachet\Models\ComponentGroup $group
- *
- * @return \Illuminate\Http\RedirectResponse
- */
- public function deleteComponentGroupAction(ComponentGroup $group)
- {
- dispatch(new RemoveComponentGroupCommand($group));
+ execute(new RemoveComponentCommand($component));
- return Redirect::route('dashboard.components.index')
+ return cachet_redirect('dashboard.components')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.components.delete.success')));
}
-
- /**
- * Shows the add component group view.
- *
- * @return \Illuminate\View\View
- */
- public function showAddComponentGroup()
- {
- return View::make('dashboard.components.groups.add')
- ->withPageTitle(trans('dashboard.components.groups.add.title').' - '.trans('dashboard.dashboard'));
- }
-
- /**
- * Shows the edit component group view.
- *
- * @param \CachetHQ\Cachet\Models\ComponentGroup $group
- *
- * @return \Illuminate\View\View
- */
- public function showEditComponentGroup(ComponentGroup $group)
- {
- return View::make('dashboard.components.groups.edit')
- ->withPageTitle(trans('dashboard.components.groups.edit.title').' - '.trans('dashboard.dashboard'))
- ->withGroup($group);
- }
-
- /**
- * Creates a new component.
- *
- * @return \Illuminate\Http\RedirectResponse
- */
- public function postAddComponentGroup()
- {
- try {
- $group = dispatch(new AddComponentGroupCommand(
- Binput::get('name'),
- Binput::get('order', 0),
- Binput::get('collapsed')
- ));
- } catch (ValidationException $e) {
- return Redirect::route('dashboard.components.groups.add')
- ->withInput(Binput::all())
- ->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.components.groups.add.failure')))
- ->withErrors($e->getMessageBag());
- }
-
- return Redirect::route('dashboard.components.groups')
- ->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.components.groups.add.success')));
- }
-
- /**
- * Updates a component group.
- *
- * @param \CachetHQ\Cachet\Models\ComponentGroup $group
- *
- * @return \Illuminate\Http\RedirectResponse
- */
- public function updateComponentGroupAction(ComponentGroup $group)
- {
- try {
- $group = dispatch(new UpdateComponentGroupCommand(
- $group,
- Binput::get('name'),
- $group->order,
- Binput::get('collapsed')
- ));
- } catch (ValidationException $e) {
- return Redirect::route('dashboard.components.groups.edit', ['id' => $group->id])
- ->withInput(Binput::all())
- ->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.components.groups.edit.failure')))
- ->withErrors($e->getMessageBag());
- }
-
- return Redirect::route('dashboard.components.groups.edit', ['id' => $group->id])
- ->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.components.groups.edit.success')));
- }
}
diff --git a/app/Http/Controllers/Dashboard/ComponentGroupController.php b/app/Http/Controllers/Dashboard/ComponentGroupController.php
new file mode 100644
index 000000000000..ad81afc9f00e
--- /dev/null
+++ b/app/Http/Controllers/Dashboard/ComponentGroupController.php
@@ -0,0 +1,173 @@
+
+ */
+class ComponentGroupController extends Controller
+{
+ /**
+ * Array of sub-menu items.
+ *
+ * @var array
+ */
+ protected $subMenu = [];
+
+ /**
+ * Creates a new component controller instance.
+ *
+ * @return void
+ */
+ public function __construct()
+ {
+ $this->subMenu = [
+ 'components' => [
+ 'title' => trans('dashboard.components.components'),
+ 'url' => cachet_route('dashboard.components'),
+ 'icon' => 'ion-ios-browsers',
+ 'active' => false,
+ ],
+ 'groups' => [
+ 'title' => trans_choice('dashboard.components.groups.groups', 2),
+ 'url' => cachet_route('dashboard.components.groups'),
+ 'icon' => 'ion-folder',
+ 'active' => false,
+ ],
+ ];
+
+ View::share([
+ 'sub_menu' => $this->subMenu,
+ 'subTitle' => trans_choice('dashboard.components.components', 2),
+ ]);
+ }
+
+ /**
+ * Shows the component groups view.
+ *
+ * @return \Illuminate\View\View
+ */
+ public function showComponentGroups()
+ {
+ $this->subMenu['groups']['active'] = true;
+
+ return View::make('dashboard.components.groups.index')
+ ->withPageTitle(trans_choice('dashboard.components.groups.groups', 2).' - '.trans('dashboard.dashboard'))
+ ->withGroups(ComponentGroup::orderBy('order')->get())
+ ->withSubMenu($this->subMenu);
+ }
+
+ /**
+ * Deletes a given component group.
+ *
+ * @param \CachetHQ\Cachet\Models\ComponentGroup $group
+ *
+ * @return \Illuminate\Http\RedirectResponse
+ */
+ public function deleteComponentGroupAction(ComponentGroup $group)
+ {
+ execute(new RemoveComponentGroupCommand($group));
+
+ return cachet_redirect('dashboard.components.groups')
+ ->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.components.delete.success')));
+ }
+
+ /**
+ * Shows the add component group view.
+ *
+ * @return \Illuminate\View\View
+ */
+ public function showAddComponentGroup()
+ {
+ return View::make('dashboard.components.groups.add')
+ ->withPageTitle(trans('dashboard.components.groups.add.title').' - '.trans('dashboard.dashboard'));
+ }
+
+ /**
+ * Shows the edit component group view.
+ *
+ * @param \CachetHQ\Cachet\Models\ComponentGroup $group
+ *
+ * @return \Illuminate\View\View
+ */
+ public function showEditComponentGroup(ComponentGroup $group)
+ {
+ return View::make('dashboard.components.groups.edit')
+ ->withPageTitle(trans('dashboard.components.groups.edit.title').' - '.trans('dashboard.dashboard'))
+ ->withGroup($group);
+ }
+
+ /**
+ * Creates a new component.
+ *
+ * @return \Illuminate\Http\RedirectResponse
+ */
+ public function postAddComponentGroup()
+ {
+ try {
+ $group = execute(new CreateComponentGroupCommand(
+ Binput::get('name'),
+ Binput::get('order', 0),
+ Binput::get('collapsed'),
+ Binput::get('visible')
+ ));
+ } catch (ValidationException $e) {
+ return cachet_redirect('dashboard.components.groups.create')
+ ->withInput(Binput::all())
+ ->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.components.groups.add.failure')))
+ ->withErrors($e->getMessageBag());
+ }
+
+ return cachet_redirect('dashboard.components.groups')
+ ->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.components.groups.add.success')));
+ }
+
+ /**
+ * Updates a component group.
+ *
+ * @param \CachetHQ\Cachet\Models\ComponentGroup $group
+ *
+ * @return \Illuminate\Http\RedirectResponse
+ */
+ public function updateComponentGroupAction(ComponentGroup $group)
+ {
+ try {
+ $group = execute(new UpdateComponentGroupCommand(
+ $group,
+ Binput::get('name'),
+ $group->order,
+ Binput::get('collapsed'),
+ Binput::get('visible')
+ ));
+ } catch (ValidationException $e) {
+ return cachet_redirect('dashboard.components.groups.edit', [$group->id])
+ ->withInput(Binput::all())
+ ->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.components.groups.edit.failure')))
+ ->withErrors($e->getMessageBag());
+ }
+
+ return cachet_redirect('dashboard.components.groups.edit', [$group->id])
+ ->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.components.groups.edit.success')));
+ }
+}
diff --git a/app/Http/Controllers/Dashboard/DashboardController.php b/app/Http/Controllers/Dashboard/DashboardController.php
index 9d2d2c1746a2..2d5281a19e85 100644
--- a/app/Http/Controllers/Dashboard/DashboardController.php
+++ b/app/Http/Controllers/Dashboard/DashboardController.php
@@ -17,10 +17,10 @@
use CachetHQ\Cachet\Models\ComponentGroup;
use CachetHQ\Cachet\Models\Incident;
use CachetHQ\Cachet\Models\Subscriber;
+use Illuminate\Contracts\Auth\Guard;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Config;
-use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\View;
use Jenssegers\Date\Date;
@@ -48,20 +48,29 @@ class DashboardController extends Controller
/**
* The feed integration.
*
- * @var \CachetHQ\Cachet\Integrations\Feed
+ * @var \CachetHQ\Cachet\Integrations\Contracts\Feed
*/
protected $feed;
+ /**
+ * The user session object.
+ *
+ * @var \Illuminate\Contracts\Auth\Guard
+ */
+ protected $guard;
+
/**
* Creates a new dashboard controller instance.
*
- * @param \CachetHQ\Cachet\Integrations\Feed $feed
+ * @param \CachetHQ\Cachet\Integrations\Contracts\Feed $feed
+ * @param \Illuminate\Contracts\Auth\Guard $guard
*
* @return void
*/
- public function __construct(Feed $feed)
+ public function __construct(Feed $feed, Guard $guard)
{
$this->feed = $feed;
+ $this->guard = $guard;
$this->startDate = new Date();
$this->dateTimeZone = Config::get('cachet.timezone');
}
@@ -73,7 +82,7 @@ public function __construct(Feed $feed)
*/
public function redirectAdmin()
{
- return Redirect::route('dashboard.index');
+ return cachet_redirect('dashboard');
}
/**
@@ -86,18 +95,20 @@ public function showDashboard()
$components = Component::orderBy('order')->get();
$incidents = $this->getIncidents();
$subscribers = $this->getSubscribers();
- $usedComponentGroups = Component::enabled()->where('group_id', '>', 0)->groupBy('group_id')->pluck('group_id');
- $componentGroups = ComponentGroup::whereIn('id', $usedComponentGroups)->orderBy('order')->get();
- $ungroupedComponents = Component::enabled()->where('group_id', 0)->orderBy('order')->orderBy('created_at')->get();
+
+ $componentGroups = $this->getVisibleGroupedComponents();
+ $ungroupedComponents = Component::ungrouped()->get();
$welcomeUser = !Auth::user()->welcomed;
if ($welcomeUser) {
- dispatch(new WelcomeUserCommand(Auth::user()));
+ execute(new WelcomeUserCommand(Auth::user()));
}
$entries = null;
- if ($feed = $this->feed->latest()) {
- $entries = array_slice($feed->channel->item, 0, 5);
+ if ($feed = $this->feed->latest() !== 1) {
+ if (is_object($feed)) {
+ $entries = array_slice($feed->channel->item, 0, 5);
+ }
}
return View::make('dashboard.index')
@@ -118,11 +129,11 @@ public function showDashboard()
*/
protected function getIncidents()
{
- $allIncidents = Incident::notScheduled()->whereBetween('created_at', [
+ $allIncidents = Incident::whereBetween('occurred_at', [
$this->startDate->copy()->subDays(30)->format('Y-m-d').' 00:00:00',
$this->startDate->format('Y-m-d').' 23:59:59',
- ])->orderBy('created_at', 'desc')->get()->groupBy(function (Incident $incident) {
- return (new Date($incident->created_at))
+ ])->orderBy('occurred_at', 'desc')->get()->groupBy(function (Incident $incident) {
+ return (new Date($incident->occurred_at))
->setTimezone($this->dateTimeZone)->toDateString();
});
@@ -174,4 +185,22 @@ protected function getSubscribers()
return $allSubscribers;
}
+
+ /**
+ * Get visible grouped components.
+ *
+ * @return \Illuminate\Support\Collection
+ */
+ protected function getVisibleGroupedComponents()
+ {
+ $componentGroupsBuilder = ComponentGroup::query();
+ if (!$this->guard->check()) {
+ $componentGroupsBuilder = ComponentGroup::visible();
+ }
+
+ $usedComponentGroups = Component::grouped()->pluck('group_id');
+
+ return $componentGroupsBuilder->used($usedComponentGroups)
+ ->get();
+ }
}
diff --git a/app/Http/Controllers/Dashboard/IncidentController.php b/app/Http/Controllers/Dashboard/IncidentController.php
index 5a1284c86296..f5555aa0bb9c 100644
--- a/app/Http/Controllers/Dashboard/IncidentController.php
+++ b/app/Http/Controllers/Dashboard/IncidentController.php
@@ -12,18 +12,24 @@
namespace CachetHQ\Cachet\Http\Controllers\Dashboard;
use AltThree\Validator\ValidationException;
+use CachetHQ\Cachet\Bus\Commands\Incident\CreateIncidentCommand;
use CachetHQ\Cachet\Bus\Commands\Incident\RemoveIncidentCommand;
-use CachetHQ\Cachet\Bus\Commands\Incident\ReportIncidentCommand;
use CachetHQ\Cachet\Bus\Commands\Incident\UpdateIncidentCommand;
+use CachetHQ\Cachet\Integrations\Contracts\System;
use CachetHQ\Cachet\Models\Component;
use CachetHQ\Cachet\Models\ComponentGroup;
use CachetHQ\Cachet\Models\Incident;
use CachetHQ\Cachet\Models\IncidentTemplate;
use GrahamCampbell\Binput\Facades\Binput;
+use Illuminate\Contracts\Auth\Guard;
use Illuminate\Routing\Controller;
-use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\View;
+/**
+ * This is the incident controller.
+ *
+ * @author James Brooks
+ */
class IncidentController extends Controller
{
/**
@@ -33,30 +39,33 @@ class IncidentController extends Controller
*/
protected $subMenu = [];
+ /**
+ * The guard instance.
+ *
+ * @var \Illuminate\Contracts\Auth\Guard
+ */
+ protected $auth;
+
+ /**
+ * The system instance.
+ *
+ * @var \CachetHQ\Cachet\Integrations\Contracts\System
+ */
+ protected $system;
+
/**
* Creates a new incident controller instance.
*
+ * @param \Illuminate\Contracts\Auth\Guard $auth
+ *
* @return void
*/
- public function __construct()
+ public function __construct(Guard $auth, System $system)
{
- $this->subMenu = [
- 'incidents' => [
- 'title' => trans('dashboard.incidents.incidents'),
- 'url' => route('dashboard.incidents.index'),
- 'icon' => 'ion-android-checkmark-circle',
- 'active' => true,
- ],
- 'schedule' => [
- 'title' => trans('dashboard.schedule.schedule'),
- 'url' => route('dashboard.schedule.index'),
- 'icon' => 'ion-android-calendar',
- 'active' => false,
- ],
- ];
+ $this->auth = $auth;
+ $this->system = $system;
- View::share('sub_menu', $this->subMenu);
- View::share('sub_title', trans('dashboard.incidents.title'));
+ View::share('subTitle', trans('dashboard.incidents.title'));
}
/**
@@ -66,7 +75,7 @@ public function __construct()
*/
public function showIncidents()
{
- $incidents = Incident::notScheduled()->orderBy('created_at', 'desc')->get();
+ $incidents = Incident::with('user')->orderBy('created_at', 'desc')->get();
return View::make('dashboard.incidents.index')
->withPageTitle(trans('dashboard.incidents.incidents').' - '.trans('dashboard.dashboard'))
@@ -83,7 +92,8 @@ public function showAddIncident()
return View::make('dashboard.incidents.add')
->withPageTitle(trans('dashboard.incidents.add.title').' - '.trans('dashboard.dashboard'))
->withComponentsInGroups(ComponentGroup::with('components')->get())
- ->withComponentsOutGroups(Component::where('group_id', 0)->get())
+ ->withComponentsOutGroups(Component::where('group_id', '=', 0)->get())
+ ->withNotificationsEnabled($this->system->canNotifySubscribers())
->withIncidentTemplates(IncidentTemplate::all());
}
@@ -107,27 +117,28 @@ public function showTemplates()
public function createIncidentAction()
{
try {
- $incident = dispatch(new ReportIncidentCommand(
+ $incident = execute(new CreateIncidentCommand(
Binput::get('name'),
Binput::get('status'),
- Binput::get('message'),
+ Binput::get('message', null, false, false),
Binput::get('visible', true),
Binput::get('component_id'),
Binput::get('component_status'),
Binput::get('notify', false),
Binput::get('stickied', false),
- Binput::get('created_at'),
+ Binput::get('occurred_at'),
null,
- null
+ [],
+ ['seo' => Binput::get('seo', [])]
));
} catch (ValidationException $e) {
- return Redirect::route('dashboard.incidents.add')
+ return cachet_redirect('dashboard.incidents.create')
->withInput(Binput::all())
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.incidents.add.failure')))
->withErrors($e->getMessageBag());
}
- return Redirect::route('dashboard.incidents.index')
+ return cachet_redirect('dashboard.incidents')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.incidents.add.success')));
}
@@ -167,7 +178,7 @@ public function deleteTemplateAction(IncidentTemplate $template)
{
$template->delete();
- return Redirect::route('dashboard.templates.index')
+ return cachet_redirect('dashboard.templates')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.incidents.templates.delete.success')));
}
@@ -179,15 +190,18 @@ public function deleteTemplateAction(IncidentTemplate $template)
public function createIncidentTemplateAction()
{
try {
- IncidentTemplate::create(Binput::get('template'));
+ IncidentTemplate::create([
+ 'name' => Binput::get('name'),
+ 'template' => Binput::get('template', null, false, false),
+ ]);
} catch (ValidationException $e) {
- return Redirect::route('dashboard.templates.add')
+ return cachet_redirect('dashboard.templates.create')
->withInput(Binput::all())
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.incidents.templates.add.failure')))
->withErrors($e->getMessageBag());
}
- return Redirect::route('dashboard.templates.index')
+ return cachet_redirect('dashboard.templates')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.incidents.templates.add.success')));
}
@@ -200,9 +214,9 @@ public function createIncidentTemplateAction()
*/
public function deleteIncidentAction(Incident $incident)
{
- dispatch(new RemoveIncidentCommand($incident));
+ execute(new RemoveIncidentCommand($incident));
- return Redirect::route('dashboard.incidents.index')
+ return cachet_redirect('dashboard.incidents')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.incidents.delete.success')));
}
@@ -219,7 +233,8 @@ public function showEditIncidentAction(Incident $incident)
->withPageTitle(trans('dashboard.incidents.edit.title').' - '.trans('dashboard.dashboard'))
->withIncident($incident)
->withComponentsInGroups(ComponentGroup::with('components')->get())
- ->withComponentsOutGroups(Component::where('group_id', 0)->get());
+ ->withComponentsOutGroups(Component::where('group_id', '=', 0)->get())
+ ->withNotificationsEnabled($this->system->canNotifySubscribers());
}
/**
@@ -232,7 +247,7 @@ public function showEditIncidentAction(Incident $incident)
public function editIncidentAction(Incident $incident)
{
try {
- $incident = dispatch(new UpdateIncidentCommand(
+ $incident = execute(new UpdateIncidentCommand(
$incident,
Binput::get('name'),
Binput::get('status'),
@@ -242,12 +257,13 @@ public function editIncidentAction(Incident $incident)
Binput::get('component_status'),
Binput::get('notify', true),
Binput::get('stickied', false),
- Binput::get('created_at'),
+ Binput::get('occurred_at'),
null,
- null
+ [],
+ ['seo' => Binput::get('seo', [])]
));
} catch (ValidationException $e) {
- return Redirect::route('dashboard.incidents.edit', ['id' => $incident->id])
+ return cachet_redirect('dashboard.incidents.edit', ['id' => $incident->id])
->withInput(Binput::all())
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.incidents.templates.edit.failure')))
->withErrors($e->getMessageBag());
@@ -257,7 +273,7 @@ public function editIncidentAction(Incident $incident)
$incident->component->update(['status' => Binput::get('component_status')]);
}
- return Redirect::route('dashboard.incidents.edit', ['id' => $incident->id])
+ return cachet_redirect('dashboard.incidents.edit', ['id' => $incident->id])
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.incidents.edit.success')));
}
@@ -273,12 +289,12 @@ public function editTemplateAction(IncidentTemplate $template)
try {
$template->update(Binput::get('template'));
} catch (ValidationException $e) {
- return Redirect::route('dashboard.templates.edit', ['id' => $template->id])
+ return cachet_redirect('dashboard.templates.edit', ['id' => $template->id])
->withUpdatedTemplate($template)
->withTemplateErrors($e->getMessageBag()->getErrors());
}
- return Redirect::route('dashboard.templates.edit', ['id' => $template->id])
+ return cachet_redirect('dashboard.templates.edit', ['id' => $template->id])
->withUpdatedTemplate($template);
}
}
diff --git a/app/Http/Controllers/Dashboard/IncidentTemplateController.php b/app/Http/Controllers/Dashboard/IncidentTemplateController.php
new file mode 100644
index 000000000000..853b5b2baec1
--- /dev/null
+++ b/app/Http/Controllers/Dashboard/IncidentTemplateController.php
@@ -0,0 +1,161 @@
+
+ */
+class IncidentTemplateController extends Controller
+{
+ /**
+ * Stores the sub-sidebar tree list.
+ *
+ * @var array
+ */
+ protected $subMenu = [];
+
+ /**
+ * The guard instance.
+ *
+ * @var \Illuminate\Contracts\Auth\Guard
+ */
+ protected $auth;
+
+ /**
+ * The system instance.
+ *
+ * @var \CachetHQ\Cachet\Integrations\Contracts\System
+ */
+ protected $system;
+
+ /**
+ * Creates a new incident controller instance.
+ *
+ * @param \Illuminate\Contracts\Auth\Guard $auth
+ *
+ * @return void
+ */
+ public function __construct(Guard $auth, System $system)
+ {
+ $this->auth = $auth;
+ $this->system = $system;
+
+ View::share('sub_title', trans('dashboard.incidents.title'));
+ }
+
+ /**
+ * Shows the incident templates.
+ *
+ * @return \Illuminate\View\View
+ */
+ public function showTemplates()
+ {
+ return View::make('dashboard.templates.index')
+ ->withPageTitle(trans('dashboard.incidents.templates.title').' - '.trans('dashboard.dashboard'))
+ ->withIncidentTemplates(IncidentTemplate::all());
+ }
+
+ /**
+ * Shows the add incident template view.
+ *
+ * @return \Illuminate\View\View
+ */
+ public function showAddIncidentTemplate()
+ {
+ return View::make('dashboard.templates.add')
+ ->withPageTitle(trans('dashboard.incidents.templates.add.title').' - '.trans('dashboard.dashboard'));
+ }
+
+ /**
+ * Shows the edit incident template view.
+ *
+ * @param \CachetHQ\Cachet\Models\IncidentTemplate $template
+ *
+ * @return \Illuminate\View\View
+ */
+ public function showEditTemplateAction(IncidentTemplate $template)
+ {
+ return View::make('dashboard.templates.edit')
+ ->withPageTitle(trans('dashboard.incidents.templates.edit.title').' - '.trans('dashboard.dashboard'))
+ ->withTemplate($template);
+ }
+
+ /**
+ * Deletes an incident template.
+ *
+ * @param \CachetHQ\Cachet\Models\IncidentTemplate $template
+ *
+ * @return \Illuminate\Http\RedirectResponse
+ */
+ public function deleteTemplateAction(IncidentTemplate $template)
+ {
+ $template->delete();
+
+ return cachet_redirect('dashboard.templates')
+ ->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.incidents.templates.delete.success')));
+ }
+
+ /**
+ * Creates a new incident template.
+ *
+ * @return \Illuminate\Http\RedirectResponse
+ */
+ public function createIncidentTemplateAction()
+ {
+ try {
+ IncidentTemplate::create([
+ 'name' => Binput::get('name'),
+ 'template' => Binput::get('template', null, false, false),
+ ]);
+ } catch (ValidationException $e) {
+ return cachet_redirect('dashboard.templates.create')
+ ->withInput(Binput::all())
+ ->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.incidents.templates.add.failure')))
+ ->withErrors($e->getMessageBag());
+ }
+
+ return cachet_redirect('dashboard.templates')
+ ->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.incidents.templates.add.success')));
+ }
+
+ /**
+ * Edit an incident template.
+ *
+ * @param \CachetHQ\Cachet\Models\IncidentTemplate $template
+ *
+ * @return \Illuminate\Http\RedirectResponse
+ */
+ public function editTemplateAction(IncidentTemplate $template)
+ {
+ try {
+ $template->update(Binput::get('template'));
+ } catch (ValidationException $e) {
+ return cachet_redirect('dashboard.templates.edit', ['id' => $template->id])
+ ->withUpdatedTemplate($template)
+ ->withTemplateErrors($e->getMessageBag()->getErrors());
+ }
+
+ return cachet_redirect('dashboard.templates.edit', ['id' => $template->id])
+ ->withUpdatedTemplate($template);
+ }
+}
diff --git a/app/Http/Controllers/Dashboard/IncidentUpdateController.php b/app/Http/Controllers/Dashboard/IncidentUpdateController.php
new file mode 100644
index 000000000000..092809e374dc
--- /dev/null
+++ b/app/Http/Controllers/Dashboard/IncidentUpdateController.php
@@ -0,0 +1,172 @@
+
+ */
+class IncidentUpdateController extends Controller
+{
+ /**
+ * Stores the sub-sidebar tree list.
+ *
+ * @var array
+ */
+ protected $subMenu = [];
+
+ /**
+ * The guard instance.
+ *
+ * @var \Illuminate\Contracts\Auth\Guard
+ */
+ protected $auth;
+
+ /**
+ * The system instance.
+ *
+ * @var \CachetHQ\Cachet\Integrations\Contracts\System
+ */
+ protected $system;
+
+ /**
+ * Creates a new incident controller instance.
+ *
+ * @param \Illuminate\Contracts\Auth\Guard $auth
+ *
+ * @return void
+ */
+ public function __construct(Guard $auth, System $system)
+ {
+ $this->auth = $auth;
+ $this->system = $system;
+
+ View::share('sub_title', trans('dashboard.incidents.title'));
+ }
+
+ /**
+ * Shows the incident update form.
+ *
+ * @param \CachetHQ\Cachet\Models\Incident $incident
+ *
+ * @return \Illuminate\View\View
+ */
+ public function showIncidentUpdates(Incident $incident)
+ {
+ return View::make('dashboard.incidents.updates.index')->withIncident($incident);
+ }
+
+ /**
+ * Shows the incident update form.
+ *
+ * @param \CachetHQ\Cachet\Models\Incident $incident
+ *
+ * @return \Illuminate\View\View
+ */
+ public function showCreateIncidentUpdateAction(Incident $incident)
+ {
+ return View::make('dashboard.incidents.updates.add')
+ ->withIncident($incident)
+ ->withIncidentTemplates(IncidentTemplate::all())
+ ->withNotificationsEnabled($this->system->canNotifySubscribers());
+ }
+
+ /**
+ * Creates a new incident update.
+ *
+ * @param \CachetHQ\Cachet\Models\Incident $incident
+ *
+ * @return \Illuminate\Http\RedirectResponse
+ */
+ public function createIncidentUpdateAction(Incident $incident)
+ {
+ try {
+ $incidentUpdate = execute(new CreateIncidentUpdateCommand(
+ $incident,
+ Binput::get('status'),
+ Binput::get('message'),
+ Binput::get('component_id'),
+ Binput::get('component_status'),
+ $this->auth->user()
+ ));
+ } catch (ValidationException $e) {
+ return cachet_redirect('dashboard.incidents.updates.create', ['id' => $incident->id])
+ ->withInput(Binput::all())
+ ->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.incidents.updates.add.failure')))
+ ->withErrors($e->getMessageBag());
+ }
+
+ if ($incident->component) {
+ $incident->component->update(['status' => Binput::get('component_status')]);
+ }
+
+ return cachet_redirect('dashboard.incidents')
+ ->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.incidents.updates.success')));
+ }
+
+ /**
+ * Shows the edit incident view.
+ *
+ * @param \CachetHQ\Cachet\Models\Incident $incident
+ * @param \CachetHQ\Cachet\Models\IncidentUpdate $incidentUpdate
+ *
+ * @return \Illuminate\View\View
+ */
+ public function showEditIncidentUpdateAction(Incident $incident, IncidentUpdate $incidentUpdate)
+ {
+ return View::make('dashboard.incidents.updates.edit')
+ ->withIncident($incident)
+ ->withUpdate($incidentUpdate)
+ ->withNotificationsEnabled($this->system->canNotifySubscribers());
+ }
+
+ /**
+ * Edit an incident update.
+ *
+ * @param \CachetHQ\Cachet\Models\Incident $incident
+ * @param \CachetHQ\Cachet\Models\IncidentUpdate $incidentUpdate
+ *
+ * @return \Illuminate\Http\RedirectResponse
+ */
+ public function editIncidentUpdateAction(Incident $incident, IncidentUpdate $incidentUpdate)
+ {
+ try {
+ $incidentUpdate = execute(new UpdateIncidentUpdateCommand(
+ $incidentUpdate,
+ Binput::get('status'),
+ Binput::get('message'),
+ $this->auth->user()
+ ));
+ } catch (ValidationException $e) {
+ return cachet_redirect('dashboard.incidents.updates.edit', ['incident' => $incident->id, 'incident_update' => $incidentUpdate->id])
+ ->withInput(Binput::all())
+ ->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.incidents.updates.edit.failure')))
+ ->withErrors($e->getMessageBag());
+ }
+
+ return cachet_redirect('dashboard.incidents.updates', ['incident' => $incident->id])
+ ->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.incidents.updates.edit.success')));
+ }
+}
diff --git a/app/Http/Controllers/Dashboard/MetricController.php b/app/Http/Controllers/Dashboard/MetricController.php
index 447e9fedbed6..1a0b601c7458 100644
--- a/app/Http/Controllers/Dashboard/MetricController.php
+++ b/app/Http/Controllers/Dashboard/MetricController.php
@@ -12,14 +12,13 @@
namespace CachetHQ\Cachet\Http\Controllers\Dashboard;
use AltThree\Validator\ValidationException;
-use CachetHQ\Cachet\Bus\Commands\Metric\AddMetricCommand;
+use CachetHQ\Cachet\Bus\Commands\Metric\CreateMetricCommand;
use CachetHQ\Cachet\Bus\Commands\Metric\RemoveMetricCommand;
use CachetHQ\Cachet\Bus\Commands\Metric\UpdateMetricCommand;
use CachetHQ\Cachet\Models\Metric;
use CachetHQ\Cachet\Models\MetricPoint;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Routing\Controller;
-use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\View;
class MetricController extends Controller
@@ -71,7 +70,7 @@ public function createMetricAction()
$metricData = Binput::get('metric');
try {
- dispatch(new AddMetricCommand(
+ execute(new CreateMetricCommand(
$metricData['name'],
$metricData['suffix'],
$metricData['description'],
@@ -80,16 +79,18 @@ public function createMetricAction()
$metricData['display_chart'],
$metricData['places'],
$metricData['default_view'],
- $metricData['threshold']
+ $metricData['threshold'],
+ 0, // Default order
+ $metricData['visible']
));
} catch (ValidationException $e) {
- return Redirect::route('dashboard.metrics.add')
+ return cachet_redirect('dashboard.metrics.create')
->withInput(Binput::all())
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.metrics.add.failure')))
->withErrors($e->getMessageBag());
}
- return Redirect::route('dashboard.metrics.index')
+ return cachet_redirect('dashboard.metrics')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.metrics.add.success')));
}
@@ -113,9 +114,9 @@ public function showAddMetricPoint()
*/
public function deleteMetricAction(Metric $metric)
{
- dispatch(new RemoveMetricCommand($metric));
+ execute(new RemoveMetricCommand($metric));
- return Redirect::route('dashboard.metrics.index')
+ return cachet_redirect('dashboard.metrics')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.metrics.delete.success')));
}
@@ -143,7 +144,7 @@ public function showEditMetricAction(Metric $metric)
public function editMetricAction(Metric $metric)
{
try {
- dispatch(new UpdateMetricCommand(
+ execute(new UpdateMetricCommand(
$metric,
Binput::get('name', null, false),
Binput::get('suffix', null, false),
@@ -153,16 +154,18 @@ public function editMetricAction(Metric $metric)
Binput::get('display_chart', null, false),
Binput::get('places', null, false),
Binput::get('default_view', null, false),
- Binput::get('threshold', null, false)
+ Binput::get('threshold', null, false),
+ null,
+ Binput::get('visible', null, false)
));
} catch (ValidationException $e) {
- return Redirect::route('dashboard.metrics.edit', ['id' => $metric->id])
+ return cachet_redirect('dashboard.metrics.edit', [$metric->id])
->withInput(Binput::all())
->withTitle(sprintf('%s ', trans('dashboard.notifications.whoops')))
->withErrors($e->getMessageBag());
}
- return Redirect::route('dashboard.metrics.edit', ['id' => $metric->id])
+ return cachet_redirect('dashboard.metrics.edit', [$metric->id])
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.metrics.edit.success')));
}
}
diff --git a/app/Http/Controllers/Dashboard/ScheduleController.php b/app/Http/Controllers/Dashboard/ScheduleController.php
index bead6cfd3d62..c06216a916f6 100644
--- a/app/Http/Controllers/Dashboard/ScheduleController.php
+++ b/app/Http/Controllers/Dashboard/ScheduleController.php
@@ -12,17 +12,21 @@
namespace CachetHQ\Cachet\Http\Controllers\Dashboard;
use AltThree\Validator\ValidationException;
-use CachetHQ\Cachet\Bus\Commands\Incident\ReportMaintenanceCommand;
-use CachetHQ\Cachet\Dates\DateFactory;
-use CachetHQ\Cachet\Models\Incident;
+use CachetHQ\Cachet\Bus\Commands\Schedule\CreateScheduleCommand;
+use CachetHQ\Cachet\Bus\Commands\Schedule\DeleteScheduleCommand;
+use CachetHQ\Cachet\Bus\Commands\Schedule\UpdateScheduleCommand;
+use CachetHQ\Cachet\Integrations\Contracts\System;
use CachetHQ\Cachet\Models\IncidentTemplate;
+use CachetHQ\Cachet\Models\Schedule;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Routing\Controller;
-use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\View;
-use Illuminate\Support\MessageBag;
-use Jenssegers\Date\Date;
+/**
+ * This is the schedule controller class.
+ *
+ * @author James Brooks
+ */
class ScheduleController extends Controller
{
/**
@@ -32,30 +36,22 @@ class ScheduleController extends Controller
*/
protected $subMenu = [];
+ /**
+ * The system instance.
+ *
+ * @var \CachetHQ\Cachet\Integrations\Contracts\System
+ */
+ protected $system;
+
/**
* Creates a new schedule controller instance.
*
* @return void
*/
- public function __construct()
+ public function __construct(System $system)
{
- $this->subMenu = [
- 'incidents' => [
- 'title' => trans('dashboard.incidents.incidents'),
- 'url' => route('dashboard.incidents.index'),
- 'icon' => 'ion-android-checkmark-circle',
- 'active' => false,
- ],
- 'schedule' => [
- 'title' => trans('dashboard.schedule.schedule'),
- 'url' => route('dashboard.schedule.index'),
- 'icon' => 'ion-android-calendar',
- 'active' => true,
- ],
- ];
-
- View::share('sub_menu', $this->subMenu);
- View::share('sub_title', trans('dashboard.incidents.title'));
+ $this->system = $system;
+ View::share('subTitle', trans('dashboard.schedule.title'));
}
/**
@@ -65,9 +61,9 @@ public function __construct()
*/
public function showIndex()
{
- $schedule = Incident::scheduled()->orderBy('created_at')->get();
+ $schedule = Schedule::orderBy('created_at')->get();
- return View::make('dashboard.schedule.index')
+ return View::make('dashboard.maintenance.index')
->withPageTitle(trans('dashboard.schedule.schedule').' - '.trans('dashboard.dashboard'))
->withSchedule($schedule);
}
@@ -81,48 +77,52 @@ public function showAddSchedule()
{
$incidentTemplates = IncidentTemplate::all();
- return View::make('dashboard.schedule.add')
+ return View::make('dashboard.maintenance.add')
->withPageTitle(trans('dashboard.schedule.add.title').' - '.trans('dashboard.dashboard'))
- ->withIncidentTemplates($incidentTemplates);
+ ->withIncidentTemplates($incidentTemplates)
+ ->withNotificationsEnabled($this->system->canNotifySubscribers());
}
/**
- * Creates a new scheduled maintenance "incident".
+ * Creates a new scheduled maintenance.
*
* @return \Illuminate\Http\RedirectResponse
*/
public function addScheduleAction()
{
try {
- $incident = dispatch(new ReportMaintenanceCommand(
+ execute(new CreateScheduleCommand(
Binput::get('name'),
- Binput::get('message'),
- Binput::get('notify'),
- Binput::get('scheduled_at')
+ Binput::get('message', null, false, false),
+ Binput::get('status', Schedule::UPCOMING),
+ Binput::get('scheduled_at'),
+ Binput::get('completed_at'),
+ Binput::get('components', []),
+ Binput::get('notify', false)
));
} catch (ValidationException $e) {
- return Redirect::route('dashboard.schedule.add')
+ return cachet_redirect('dashboard.schedule.create')
->withInput(Binput::all())
- ->withSuccess(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.schedule.add.failure')))
+ ->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.schedule.edit.failure')))
->withErrors($e->getMessageBag());
}
- return Redirect::route('dashboard.schedule.index')
+ return cachet_redirect('dashboard.schedule')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.schedule.add.success')));
}
/**
* Shows the edit schedule maintenance form.
*
- * @param \CachetHQ\Cachet\Models\Incident $schedule
+ * @param \CachetHQ\Cachet\Models\Schedule $schedule
*
* @return \Illuminate\View\View
*/
- public function showEditSchedule(Incident $schedule)
+ public function showEditSchedule(Schedule $schedule)
{
$incidentTemplates = IncidentTemplate::all();
- return View::make('dashboard.schedule.edit')
+ return View::make('dashboard.maintenance.edit')
->withPageTitle(trans('dashboard.schedule.edit.title').' - '.trans('dashboard.dashboard'))
->withIncidentTemplates($incidentTemplates)
->withSchedule($schedule);
@@ -131,53 +131,45 @@ public function showEditSchedule(Incident $schedule)
/**
* Updates the given incident.
*
- * @param \CachetHQ\Cachet\Models\Incident $schedule
+ * @param \CachetHQ\Cachet\Models\Schedule $schedule
*
* @return \Illuminate\Http\RedirectResponse
*/
- public function editScheduleAction(Incident $schedule)
+ public function editScheduleAction(Schedule $schedule)
{
- $scheduleData = Binput::get('incident');
-
- // Parse the schedule date.
- $scheduledAt = app(DateFactory::class)->create('d/m/Y H:i', $scheduleData['scheduled_at']);
-
- if ($scheduledAt->isPast()) {
- $messageBag = new MessageBag();
- $messageBag->add('scheduled_at', trans('validation.date', ['attribute' => 'scheduled time you supplied']));
-
- return Redirect::route('dashboard.schedule.edit', ['id' => $schedule->id])->withErrors($messageBag);
- }
-
- $scheduleData['scheduled_at'] = $scheduledAt;
- // Bypass the incident.status field.
- $scheduleData['status'] = 0;
-
try {
- $schedule->update($scheduleData);
+ $schedule = execute(new UpdateScheduleCommand(
+ $schedule,
+ Binput::get('name', null),
+ Binput::get('message', null),
+ Binput::get('status', null),
+ Binput::get('scheduled_at', null),
+ Binput::get('completed_at', null),
+ Binput::get('components', [])
+ ));
} catch (ValidationException $e) {
- return Redirect::route('dashboard.schedule.edit', ['id' => $schedule->id])
+ return cachet_redirect('dashboard.schedule.edit', [$schedule->id])
->withInput(Binput::all())
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.schedule.edit.failure')))
->withErrors($e->getMessageBag());
}
- return Redirect::route('dashboard.schedule.edit', ['id' => $schedule->id])
+ return cachet_redirect('dashboard.schedule.edit', [$schedule->id])
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.schedule.edit.success')));
}
/**
* Deletes a given schedule.
*
- * @param \CachetHQ\Cachet\Models\Incident $schedule
+ * @param \CachetHQ\Cachet\Models\Schedule $schedule
*
* @return \Illuminate\Http\RedirectResponse
*/
- public function deleteScheduleAction(Incident $schedule)
+ public function deleteScheduleAction(Schedule $schedule)
{
- $schedule->delete();
+ execute(new DeleteScheduleCommand($schedule));
- return Redirect::route('dashboard.schedule.index')
+ return cachet_redirect('dashboard.schedule')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.schedule.delete.success')));
}
}
diff --git a/app/Http/Controllers/Dashboard/SettingsController.php b/app/Http/Controllers/Dashboard/SettingsController.php
index d4a31250d901..f128e22711e1 100644
--- a/app/Http/Controllers/Dashboard/SettingsController.php
+++ b/app/Http/Controllers/Dashboard/SettingsController.php
@@ -11,12 +11,16 @@
namespace CachetHQ\Cachet\Http\Controllers\Dashboard;
+use CachetHQ\Cachet\Bus\Commands\System\Config\UpdateConfigCommand;
use CachetHQ\Cachet\Integrations\Contracts\Credits;
use CachetHQ\Cachet\Models\User;
+use CachetHQ\Cachet\Notifications\System\SystemTestNotification;
use CachetHQ\Cachet\Settings\Repository;
use Exception;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Routing\Controller;
+use Illuminate\Support\Facades\Artisan;
+use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Lang;
use Illuminate\Support\Facades\Log;
@@ -24,6 +28,7 @@
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\View;
use Illuminate\Support\Str;
+use Monolog\Handler\SyslogHandler;
class SettingsController extends Controller
{
@@ -44,58 +49,64 @@ public function __construct()
$this->subMenu = [
'setup' => [
'title' => trans('dashboard.settings.app-setup.app-setup'),
- 'url' => route('dashboard.settings.setup'),
+ 'url' => cachet_route('dashboard.settings.setup'),
'icon' => 'ion-gear-b',
'active' => false,
],
'theme' => [
'title' => trans('dashboard.settings.theme.theme'),
- 'url' => route('dashboard.settings.theme'),
+ 'url' => cachet_route('dashboard.settings.theme'),
'icon' => 'ion-paintbrush',
'active' => false,
],
'stylesheet' => [
'title' => trans('dashboard.settings.stylesheet.stylesheet'),
- 'url' => route('dashboard.settings.stylesheet'),
+ 'url' => cachet_route('dashboard.settings.stylesheet'),
'icon' => 'ion-paintbucket',
'active' => false,
],
'customization' => [
'title' => trans('dashboard.settings.customization.customization'),
- 'url' => route('dashboard.settings.customization'),
+ 'url' => cachet_route('dashboard.settings.customization'),
'icon' => 'ion-wand',
'active' => false,
],
'localization' => [
'title' => trans('dashboard.settings.localization.localization'),
- 'url' => route('dashboard.settings.localization'),
+ 'url' => cachet_route('dashboard.settings.localization'),
'icon' => 'ion-earth',
'active' => false,
],
'security' => [
'title' => trans('dashboard.settings.security.security'),
- 'url' => route('dashboard.settings.security'),
+ 'url' => cachet_route('dashboard.settings.security'),
'icon' => 'ion-lock-combination',
'active' => false,
],
'analytics' => [
'title' => trans('dashboard.settings.analytics.analytics'),
- 'url' => route('dashboard.settings.analytics'),
+ 'url' => cachet_route('dashboard.settings.analytics'),
'icon' => 'ion-stats-bars',
'active' => false,
],
'log' => [
'title' => trans('dashboard.settings.log.log'),
- 'url' => route('dashboard.settings.log'),
+ 'url' => cachet_route('dashboard.settings.log'),
'icon' => 'ion-document-text',
'active' => false,
],
'credits' => [
'title' => trans('dashboard.settings.credits.credits'),
- 'url' => route('dashboard.settings.credits'),
+ 'url' => cachet_route('dashboard.settings.credits'),
'icon' => 'ion-ios-list',
'active' => false,
],
+ 'mail' => [
+ 'title' => trans('dashboard.settings.mail.mail'),
+ 'url' => cachet_route('dashboard.settings.mail'),
+ 'icon' => 'ion-paper-airplane',
+ 'active' => false,
+ ],
'about' => [
'title' => CACHET_VERSION,
'url' => 'javascript: void(0);',
@@ -105,8 +116,8 @@ public function __construct()
];
View::share([
- 'sub_title' => trans('dashboard.settings.settings'),
- 'sub_menu' => $this->subMenu,
+ 'subTitle' => trans('dashboard.settings.settings'),
+ 'subMenu' => $this->subMenu,
]);
}
@@ -200,7 +211,7 @@ public function showSecurityView()
{
$this->subMenu['security']['active'] = true;
- $unsecureUsers = User::whereNull('google_2fa_secret')->orWhere('google_2fa_secret', '')->get();
+ $unsecureUsers = User::whereNull('google_2fa_secret')->orWhere('google_2fa_secret', '=', '')->get();
Session::flash('redirect_to', $this->subMenu['security']['url']);
@@ -259,13 +270,62 @@ public function showLogView()
{
$this->subMenu['log']['active'] = true;
- $log = Log::getMonolog();
+ $log = Log::getLogger();
- $logContents = file_get_contents($log->getHandlers()[0]->getUrl());
+ $logContents = '';
+
+ collect($log->getHandlers())->reject(function ($handler) {
+ return $handler instanceof SyslogHandler;
+ })->each(function ($handler) use (&$logContents, $log) {
+ if (file_exists($path = $log->getHandlers()[0]->getUrl())) {
+ $logContents = file_get_contents($path);
+ }
+ });
return View::make('dashboard.settings.log')->withLog($logContents)->withSubMenu($this->subMenu);
}
+ /**
+ * Show the mail settings view.
+ *
+ * @return \Illuminate\View\View
+ */
+ public function showMailView()
+ {
+ $this->subMenu['mail']['active'] = true;
+
+ return View::make('dashboard.settings.mail')->withConfig(Config::get('mail'));
+ }
+
+ /**
+ * Test the mail config.
+ *
+ * @return \Illuminate\Http\RedirectResponse
+ */
+ public function testMail()
+ {
+ Auth::user()->notify(new SystemTestNotification());
+
+ return cachet_redirect('dashboard.settings.mail')
+ ->withSuccess(trans('dashboard.notifications.awesome'));
+ }
+
+ /**
+ * Handle updating of the settings.
+ *
+ * @return \Illuminate\Http\RedirectResponse
+ */
+ public function postMail()
+ {
+ $config = Binput::get('config');
+
+ execute(new UpdateConfigCommand($config));
+
+ return cachet_redirect('dashboard.settings.mail')
+ ->withInput(Binput::all())
+ ->withSuccess(trans('dashboard.notifications.awesome'));
+ }
+
/**
* Updates the status page settings.
*
@@ -297,6 +357,14 @@ public function postSettings()
}
}
+ if (isset($parameters['stylesheet'])) {
+ if ($stylesheet = Binput::get('stylesheet', null, false, false)) {
+ $setting->set('stylesheet', $stylesheet);
+ } else {
+ $setting->delete('stylesheet');
+ }
+ }
+
if (Binput::hasFile('app_banner')) {
$this->handleUpdateBanner($setting);
}
@@ -307,6 +375,7 @@ public function postSettings()
'remove_banner',
'header',
'footer',
+ 'stylesheet',
];
try {
@@ -325,6 +394,10 @@ public function postSettings()
Lang::setLocale(Binput::get('app_locale'));
}
+ if (Binput::has('always_authenticate')) {
+ Artisan::call('route:clear');
+ }
+
return Redirect::back()->withSuccess(trans('dashboard.settings.edit.success'));
}
@@ -338,6 +411,7 @@ public function postSettings()
protected function handleUpdateBanner(Repository $setting)
{
$file = Binput::file('app_banner');
+ $redirectUrl = $this->subMenu['theme']['url'];
// Image Validation.
// Image size in bytes.
diff --git a/app/Http/Controllers/Dashboard/SubscriberController.php b/app/Http/Controllers/Dashboard/SubscriberController.php
index 9e1e6185d85b..17de83eb4a2d 100644
--- a/app/Http/Controllers/Dashboard/SubscriberController.php
+++ b/app/Http/Controllers/Dashboard/SubscriberController.php
@@ -18,7 +18,6 @@
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Contracts\Config\Repository;
use Illuminate\Routing\Controller;
-use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\View;
class SubscriberController extends Controller
@@ -32,7 +31,7 @@ public function showSubscribers()
{
return View::make('dashboard.subscribers.index')
->withPageTitle(trans('dashboard.subscribers.subscribers').' - '.trans('dashboard.dashboard'))
- ->withSubscribers(Subscriber::all());
+ ->withSubscribers(Subscriber::with('subscriptions.component')->get());
}
/**
@@ -59,16 +58,16 @@ public function createSubscriberAction()
$subscribers = preg_split("/\r\n|\n|\r/", Binput::get('email'));
foreach ($subscribers as $subscriber) {
- dispatch(new SubscribeSubscriberCommand($subscriber, $verified));
+ execute(new SubscribeSubscriberCommand($subscriber, $verified));
}
} catch (ValidationException $e) {
- return Redirect::route('dashboard.subscribers.add')
+ return cachet_redirect('dashboard.subscribers.create')
->withInput(Binput::all())
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.subscribers.add.failure')))
->withErrors($e->getMessageBag());
}
- return Redirect::route('dashboard.subscribers.add')
+ return cachet_redirect('dashboard.subscribers.create')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.subscribers.add.success')));
}
@@ -83,8 +82,8 @@ public function createSubscriberAction()
*/
public function deleteSubscriberAction(Subscriber $subscriber)
{
- dispatch(new UnsubscribeSubscriberCommand($subscriber));
+ execute(new UnsubscribeSubscriberCommand($subscriber));
- return Redirect::route('dashboard.subscribers.index');
+ return cachet_redirect('dashboard.subscribers');
}
}
diff --git a/app/Http/Controllers/Dashboard/TeamController.php b/app/Http/Controllers/Dashboard/TeamController.php
index 86715dd8f59e..b762161907f8 100644
--- a/app/Http/Controllers/Dashboard/TeamController.php
+++ b/app/Http/Controllers/Dashboard/TeamController.php
@@ -12,13 +12,12 @@
namespace CachetHQ\Cachet\Http\Controllers\Dashboard;
use AltThree\Validator\ValidationException;
-use CachetHQ\Cachet\Bus\Commands\User\AddUserCommand;
+use CachetHQ\Cachet\Bus\Commands\User\CreateUserCommand;
use CachetHQ\Cachet\Bus\Commands\User\InviteUserCommand;
use CachetHQ\Cachet\Bus\Commands\User\RemoveUserCommand;
use CachetHQ\Cachet\Models\User;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Routing\Controller;
-use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\View;
class TeamController extends Controller
@@ -81,20 +80,20 @@ public function showInviteTeamMemberView()
public function postAddUser()
{
try {
- dispatch(new AddUserCommand(
+ execute(new CreateUserCommand(
Binput::get('username'),
Binput::get('password'),
Binput::get('email'),
Binput::get('level')
));
} catch (ValidationException $e) {
- return Redirect::route('dashboard.team.add')
+ return cachet_redirect('dashboard.team.create')
->withInput(Binput::except('password'))
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.team.add.failure')))
->withErrors($e->getMessageBag());
}
- return Redirect::route('dashboard.team.add')
+ return cachet_redirect('dashboard.team.create')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.team.add.success')));
}
@@ -112,13 +111,13 @@ public function postUpdateUser(User $user)
try {
$user->update($userData);
} catch (ValidationException $e) {
- return Redirect::route('dashboard.team.edit', ['id' => $user->id])
+ return cachet_redirect('dashboard.team.edit', [$user->id])
->withInput($userData)
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.team.edit.failure')))
->withErrors($e->getMessageBag());
}
- return Redirect::route('dashboard.team.edit', ['id' => $user->id])
+ return cachet_redirect('dashboard.team.edit', [$user->id])
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.team.edit.success')));
}
@@ -130,17 +129,17 @@ public function postUpdateUser(User $user)
public function postInviteUser()
{
try {
- dispatch(new InviteUserCommand(
+ execute(new InviteUserCommand(
array_unique(array_filter((array) Binput::get('emails')))
));
} catch (ValidationException $e) {
- return Redirect::route('dashboard.team.invite')
+ return cachet_redirect('dashboard.team.invite')
->withInput(Binput::except('password'))
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.team.invite.failure')))
->withErrors($e->getMessageBag());
}
- return Redirect::route('dashboard.team.invite')
+ return cachet_redirect('dashboard.team.invite')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.team.invite.success')));
}
@@ -153,9 +152,9 @@ public function postInviteUser()
*/
public function deleteUser(User $user)
{
- dispatch(new RemoveUserCommand($user));
+ execute(new RemoveUserCommand($user));
- return Redirect::route('dashboard.team.index')
+ return cachet_redirect('dashboard.team')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.team.delete.success')));
}
}
diff --git a/app/Http/Controllers/Dashboard/UserController.php b/app/Http/Controllers/Dashboard/UserController.php
index d665346e730c..ba01e862b6d3 100644
--- a/app/Http/Controllers/Dashboard/UserController.php
+++ b/app/Http/Controllers/Dashboard/UserController.php
@@ -18,10 +18,10 @@
use CachetHQ\Cachet\Models\User;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Routing\Controller;
+use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
-use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\View;
-use PragmaRX\Google2FA\Vendor\Laravel\Facade as Google2FA;
+use PragmaRX\Google2FA\Google2FA;
class UserController extends Controller
{
@@ -39,18 +39,22 @@ public function showUser()
/**
* Updates the current user.
*
+ * @throws \PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException
+ * @throws \PragmaRX\Google2FA\Exceptions\InvalidCharactersException
+ *
* @return \Illuminate\View\View
*/
public function postUser()
{
$userData = array_filter(Binput::only(['username', 'email', 'password', 'google2fa']));
- $enable2FA = (bool) array_pull($userData, 'google2fa');
+ $enable2FA = (bool) Arr::pull($userData, 'google2fa');
// Let's enable/disable auth
if ($enable2FA && !Auth::user()->hasTwoFactor) {
event(new UserEnabledTwoAuthEvent(Auth::user()));
- $userData['google_2fa_secret'] = Google2FA::generateSecretKey();
+ $google2fa = new Google2FA();
+ $userData['google_2fa_secret'] = $google2fa->generateSecretKey();
} elseif (!$enable2FA) {
event(new UserDisabledTwoAuthEvent(Auth::user()));
$userData['google_2fa_secret'] = '';
@@ -59,13 +63,13 @@ public function postUser()
try {
Auth::user()->update($userData);
} catch (ValidationException $e) {
- return Redirect::route('dashboard.user')
+ return cachet_redirect('dashboard.user')
->withInput($userData)
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('dashboard.team.edit.failure')))
->withErrors($e->getMessageBag());
}
- return Redirect::route('dashboard.user')
+ return cachet_redirect('dashboard.user')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.team.edit.success')));
}
@@ -83,6 +87,6 @@ public function regenerateApiKey(User $user)
event(new UserRegeneratedApiTokenEvent($user));
- return Redirect::route('dashboard.user');
+ return cachet_redirect('dashboard.user');
}
}
diff --git a/app/Http/Controllers/FeedController.php b/app/Http/Controllers/FeedController.php
deleted file mode 100644
index e9510fd94e58..000000000000
--- a/app/Http/Controllers/FeedController.php
+++ /dev/null
@@ -1,112 +0,0 @@
-feed = app('feed');
- $this->feed->title = Config::get('setting.app_name');
- $this->feed->description = trans('cachet.feed');
- $this->feed->link = Str::canonicalize(Config::get('setting.app_domain'));
- $this->feed->ctype = 'text/xml';
- $this->feed->setDateFormat('datetime');
- }
-
- /**
- * Generates an Atom feed of all incidents.
- *
- * @param \CachetHQ\Cachet\Models\ComponentGroup|null $group
- *
- * @return \Illuminate\Http\Response
- */
- public function atomAction(ComponentGroup $group = null)
- {
- return $this->feedAction($group, false);
- }
-
- /**
- * Generates a Rss feed of all incidents.
- *
- * @param \CachetHQ\Cachet\Models\ComponentGroup|null $group
- *
- * @return \Illuminate\Http\Response
- */
- public function rssAction(ComponentGroup $group = null)
- {
- $this->feed->lang = Config::get('setting.app_locale');
-
- return $this->feedAction($group, true);
- }
-
- /**
- * Generates a Rss feed of all incidents.
- *
- * @param \CachetHQ\Cachet\Models\ComponentGroup|null $group
- * @param bool $isRss
- *
- * @return \Illuminate\Http\Response
- */
- private function feedAction(ComponentGroup &$group, $isRss)
- {
- if ($group->exists) {
- $group->components->map(function ($component) use ($isRss) {
- $component->incidents()->visible()->orderBy('created_at', 'desc')->get()->map(function ($incident) use ($isRss) {
- $this->feedAddItem($incident, $isRss);
- });
- });
- } else {
- Incident::visible()->orderBy('created_at', 'desc')->get()->map(function ($incident) use ($isRss) {
- $this->feedAddItem($incident, $isRss);
- });
- }
-
- return $this->feed->render($isRss ? 'rss' : 'atom');
- }
-
- /**
- * Adds an item to the feed.
- *
- * @param \CachetHQ\Cachet\Models\Incident $incident
- * @param bool $isRss
- */
- private function feedAddItem(Incident $incident, $isRss)
- {
- $this->feed->add(
- $incident->name,
- Config::get('setting.app_name'),
- Str::canonicalize(route('incident', ['id' => $incident->id])),
- $isRss ? $incident->created_at->toRssString() : $incident->created_at->toAtomString(),
- $isRss ? $incident->message : Markdown::convertToHtml($incident->message)
- );
- }
-}
diff --git a/app/Http/Controllers/SetupController.php b/app/Http/Controllers/SetupController.php
index b4f56a9305a0..52bf51f7a3bd 100644
--- a/app/Http/Controllers/SetupController.php
+++ b/app/Http/Controllers/SetupController.php
@@ -11,20 +11,26 @@
namespace CachetHQ\Cachet\Http\Controllers;
+use CachetHQ\Cachet\Bus\Commands\System\Config\UpdateConfigCommand;
use CachetHQ\Cachet\Models\User;
use CachetHQ\Cachet\Settings\Repository;
-use Dotenv\Dotenv;
-use Dotenv\Exception\InvalidPathException;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Routing\Controller;
+use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Config;
-use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Request;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\View;
+/**
+ * This is the setup controller.
+ *
+ * @author James Brooks
+ * @author Graham Campbell
+ * @author Joseph Cohen
+ */
class SetupController extends Controller
{
/**
@@ -47,16 +53,30 @@ class SetupController extends Controller
* @var string[]
*/
protected $mailDrivers = [
- 'smtp' => 'SMTP',
- 'mail' => 'Mail',
- 'sendmail' => 'Sendmail',
- 'mailgun' => 'Mailgun',
- 'mandrill' => 'Mandrill',
- // 'ses' => 'Amazon SES', this will be available only if aws/aws-sdk-php is installed
+ 'smtp' => 'SMTP',
+ 'mail' => 'Mail',
+ 'sendmail' => 'Sendmail',
+ 'mailgun' => 'Mailgun',
+ 'mandrill' => 'Mandrill',
+ 'ses' => 'Amazon SES',
'sparkpost' => 'SparkPost',
'log' => 'Log (Testing)',
];
+ /**
+ * Array of queue drivers.
+ *
+ * @var string[]
+ */
+ protected $queueDrivers = [
+ 'null' => 'None',
+ 'sync' => 'Synchronous',
+ 'database' => 'Database',
+ 'beanstalkd' => 'Beanstalk',
+ 'sqs' => 'Amazon SQS',
+ 'redis' => 'Redis',
+ ];
+
/**
* Array of step1 rules.
*
@@ -88,6 +108,7 @@ public function __construct()
$this->rulesStep1 = [
'env.cache_driver' => 'required|in:'.implode(',', array_keys($this->cacheDrivers)),
'env.session_driver' => 'required|in:'.implode(',', array_keys($this->cacheDrivers)),
+ 'env.queue_driver' => 'required|in:'.implode(',', array_keys($this->queueDrivers)),
'env.mail_driver' => 'required|in:'.implode(',', array_keys($this->mailDrivers)),
];
@@ -113,24 +134,53 @@ public function __construct()
*/
public function getIndex()
{
- $supportedLanguages = Request::getLanguages();
+ $requestedLanguages = Request::getLanguages();
$userLanguage = Config::get('app.locale');
+ $langs = Config::get('langs');
- foreach ($supportedLanguages as $language) {
+ foreach ($requestedLanguages as $language) {
$language = str_replace('_', '-', $language);
- if (isset($this->langs[$language])) {
+ if (isset($langs[$language])) {
$userLanguage = $language;
break;
}
}
- return View::make('setup')
+ app('translator')->setLocale($userLanguage);
+
+ // Since .env may already be configured, we should show that data!
+ $cacheConfig = [
+ 'driver' => Config::get('cache.default'),
+ ];
+
+ $sessionConfig = [
+ 'driver' => Config::get('session.driver'),
+ ];
+
+ $queueConfig = [
+ 'driver' => Config::get('queue.default'),
+ ];
+
+ $mailConfig = [
+ 'driver' => Config::get('mail.driver'),
+ 'host' => Config::get('mail.host'),
+ 'from' => Config::get('mail.from'),
+ 'username' => Config::get('mail.username'),
+ 'password' => Config::get('mail.password'),
+ ];
+
+ return View::make('setup.index')
->withPageTitle(trans('setup.setup'))
->withCacheDrivers($this->cacheDrivers)
+ ->withQueueDrivers($this->queueDrivers)
->withMailDrivers($this->mailDrivers)
->withUserLanguage($userLanguage)
- ->withAppUrl(Request::root());
+ ->withAppUrl(Request::root())
+ ->withCacheConfig($cacheConfig)
+ ->withSessionConfig($sessionConfig)
+ ->withQueueConfig($queueConfig)
+ ->withMailConfig($mailConfig);
}
/**
@@ -145,11 +195,15 @@ public function postStep1()
$v = Validator::make($postData, $this->rulesStep1);
$v->sometimes('env.mail_host', 'required', function ($input) {
- return $input->mail_driver === 'smtp';
+ return $input->env['mail_driver'] === 'smtp';
+ });
+
+ $v->sometimes(['env.mail_address', 'env.mail_password'], 'required', function ($input) {
+ return !in_array($input->env['mail_driver'], ['log', 'smtp']);
});
- $v->sometimes(['env.mail_address', 'env.mail_username', 'env.mail_password'], 'required', function ($input) {
- return $input->mail_driver !== 'log';
+ $v->sometimes(['env.mail_username'], 'required', function ($input) {
+ return !in_array($input->env['mail_driver'], ['sendmail', 'log']);
});
if ($v->passes()) {
@@ -190,7 +244,7 @@ public function postStep3()
if ($v->passes()) {
// Pull the user details out.
- $userDetails = array_pull($postData, 'user');
+ $userDetails = Arr::pull($postData, 'user');
$user = User::create([
'username' => $userDetails['username'],
@@ -203,58 +257,28 @@ public function postStep3()
$setting = app(Repository::class);
- $settings = array_pull($postData, 'settings');
+ $settings = Arr::pull($postData, 'settings');
foreach ($settings as $settingName => $settingValue) {
$setting->set($settingName, $settingValue);
}
- $envData = array_pull($postData, 'env');
+ $envData = Arr::pull($postData, 'env');
// Write the env to the .env file.
- foreach ($envData as $envKey => $envValue) {
- $this->writeEnv($envKey, $envValue);
- }
+ execute(new UpdateConfigCommand($envData));
if (Request::ajax()) {
return Response::json(['status' => 1]);
}
- return Redirect::to('dashboard');
+ return cachet_redirect('dashboard');
}
if (Request::ajax()) {
return Response::json(['errors' => $v->getMessageBag()], 400);
}
- return Redirect::route('setup.index')->withInput()->withErrors($v->getMessageBag());
- }
-
- /**
- * Writes to the .env file with given parameters.
- *
- * @param string $key
- * @param mixed $value
- *
- * @return void
- */
- protected function writeEnv($key, $value)
- {
- $dir = app()->environmentPath();
- $file = app()->environmentFile();
- $path = "{$dir}/{$file}";
-
- try {
- (new Dotenv($dir, $file))->load();
-
- $envKey = strtoupper($key);
- $envValue = env($envKey) ?: 'null';
-
- file_put_contents($path, str_replace(
- $envKey.'='.$envValue, $envKey.'='.$value, file_get_contents($path)
- ));
- } catch (InvalidPathException $e) {
- //
- }
+ return cachet_redirect('setup')->withInput()->withErrors($v->getMessageBag());
}
}
diff --git a/app/Http/Controllers/SignupController.php b/app/Http/Controllers/SignupController.php
index 2eda8d87a7ab..6c7db1522d49 100644
--- a/app/Http/Controllers/SignupController.php
+++ b/app/Http/Controllers/SignupController.php
@@ -18,7 +18,6 @@
use CachetHQ\Cachet\Models\User;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Routing\Controller;
-use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\View;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
@@ -70,22 +69,22 @@ public function postSignup($code = null)
}
try {
- dispatch(new SignupUserCommand(
+ execute(new SignupUserCommand(
Binput::get('username'),
Binput::get('password'),
Binput::get('email'),
User::LEVEL_USER
));
} catch (ValidationException $e) {
- return Redirect::route('signup.invite', ['code' => $invite->code])
+ return cachet_redirect('signup.invite', [$invite->code])
->withInput(Binput::except('password'))
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('cachet.signup.failure')))
->withErrors($e->getMessageBag());
}
- dispatch(new ClaimInviteCommand($invite));
+ execute(new ClaimInviteCommand($invite));
- return Redirect::route('status-page')
+ return cachet_redirect('status-page')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('cachet.signup.success')));
}
}
diff --git a/app/Http/Controllers/StatusPageController.php b/app/Http/Controllers/StatusPageController.php
index 782d8a08d795..12766de5af0b 100644
--- a/app/Http/Controllers/StatusPageController.php
+++ b/app/Http/Controllers/StatusPageController.php
@@ -11,14 +11,14 @@
namespace CachetHQ\Cachet\Http\Controllers;
-use AltThree\Badger\Facades\Badger;
-use CachetHQ\Cachet\Dates\DateFactory;
+use CachetHQ\Badger\Facades\Badger;
use CachetHQ\Cachet\Http\Controllers\Api\AbstractApiController;
use CachetHQ\Cachet\Models\Component;
use CachetHQ\Cachet\Models\Incident;
use CachetHQ\Cachet\Models\Metric;
+use CachetHQ\Cachet\Models\Schedule;
use CachetHQ\Cachet\Repositories\Metric\MetricRepository;
-use Exception;
+use CachetHQ\Cachet\Services\Dates\DateFactory;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Auth;
@@ -28,25 +28,15 @@
use Jenssegers\Date\Date;
use McCool\LaravelAutoPresenter\Facades\AutoPresenter;
+/**
+ * This is the status page controller class.
+ *
+ * @author James Brooks
+ * @author Graham Campbell
+ * @author Joseph Cohen
+ */
class StatusPageController extends AbstractApiController
{
- /**
- * @var \CachetHQ\Cachet\Repositories\Metric\MetricRepository
- */
- protected $metricRepository;
-
- /**
- * Construct a new status page controller instance.
- *
- * @param \CachetHQ\Cachet\Repositories\Metric\MetricRepository $metricRepository
- *
- * @return void
- */
- public function __construct(MetricRepository $metricRepository)
- {
- $this->metricRepository = $metricRepository;
- }
-
/**
* Displays the status page.
*
@@ -54,62 +44,91 @@ public function __construct(MetricRepository $metricRepository)
*/
public function showIndex()
{
- $today = Date::now();
- $startDate = Date::now();
-
- // Check if we have another starting date
- if (Binput::has('start_date')) {
- try {
- // If date provided is valid
- $oldDate = Date::createFromFormat('Y-m-d', Binput::get('start_date'));
-
- // If trying to get a future date fallback to today
- if ($today->gt($oldDate)) {
- $startDate = $oldDate;
- }
- } catch (Exception $e) {
- // Fallback to today
+ $onlyDisruptedDays = Config::get('setting.only_disrupted_days');
+ $appIncidentDays = (int) Config::get('setting.app_incident_days', 1);
+
+ $startDate = Date::createFromFormat('Y-m-d', Binput::get('start_date', Date::now()->toDateString()));
+ $endDate = $startDate->copy()->subDays($appIncidentDays);
+
+ $canPageForward = false;
+ $canPageBackward = false;
+ $previousDate = null;
+ $nextDate = null;
+
+ if ($onlyDisruptedDays) {
+ // In this case, start_date GET parameter means the page
+ $page = (int) Binput::get('start_date', 0);
+
+ $allIncidentDays = Incident::where('visible', '>=', (int) !Auth::check())
+ ->select('occurred_at')
+ ->whereBetween('occurred_at', [
+ $endDate->format('Y-m-d').' 00:00:00',
+ $startDate->format('Y-m-d').' 23:59:59',
+ ])
+ ->distinct()
+ ->orderBy('occurred_at', 'desc')
+ ->get()
+ ->map(function (Incident $incident) {
+ return app(DateFactory::class)->make($incident->occurred_at)->toDateString();
+ })->unique()
+ ->values();
+
+ $numIncidentDays = count($allIncidentDays);
+ $numPages = round($numIncidentDays / max($appIncidentDays, 1));
+
+ $selectedDays = $allIncidentDays->slice($page * $appIncidentDays, $appIncidentDays)->all();
+
+ if (count($selectedDays) > 0) {
+ $startDate = Date::createFromFormat('Y-m-d', array_values($selectedDays)[0]);
+ $endDate = Date::createFromFormat('Y-m-d', array_values(array_slice($selectedDays, -1))[0]);
}
- }
- $daysToShow = Config::get('setting.app_incident_days', 0) - 1;
- if ($daysToShow < 0) {
- $daysToShow = 0;
- $incidentDays = [];
+ $canPageForward = $page > 0;
+ $canPageBackward = ($page + 1) < $numPages;
+ $previousDate = $page + 1;
+ $nextDate = $page - 1;
} else {
- $incidentDays = range(0, $daysToShow);
+ $date = Date::now();
+
+ $canPageForward = (bool) $startDate->lt($date->sub('1 day'));
+ $canPageBackward = Incident::where('occurred_at', '<', $date->format('Y-m-d'))->count() > 0;
+ $previousDate = $startDate->copy()->subDays($appIncidentDays)->toDateString();
+ $nextDate = $startDate->copy()->addDays($appIncidentDays)->toDateString();
}
- $incidentVisibility = Auth::check() ? 0 : 1;
+ $allIncidents = Incident::with('component', 'updates.incident')
+ ->where('visible', '>=', (int) !Auth::check())->whereBetween('occurred_at', [
+ $endDate->format('Y-m-d').' 00:00:00',
+ $startDate->format('Y-m-d').' 23:59:59',
+ ])->orderBy('occurred_at', 'desc')->get()->groupBy(function (Incident $incident) {
+ return app(DateFactory::class)->make($incident->occurred_at)->toDateString();
+ });
- $allIncidents = Incident::notScheduled()->where('visible', '>=', $incidentVisibility)->whereBetween('created_at', [
- $startDate->copy()->subDays($daysToShow)->format('Y-m-d').' 00:00:00',
- $startDate->format('Y-m-d').' 23:59:59',
- ])->orderBy('scheduled_at', 'desc')->orderBy('created_at', 'desc')->get()->groupBy(function (Incident $incident) {
- return app(DateFactory::class)->make($incident->is_scheduled ? $incident->scheduled_at : $incident->created_at)->toDateString();
- });
+ if (!$onlyDisruptedDays) {
+ $incidentDays = array_pad([], $appIncidentDays, null);
- // Add in days that have no incidents
- foreach ($incidentDays as $i) {
- $date = app(DateFactory::class)->make($startDate)->subDays($i);
+ // Add in days that have no incidents
+ foreach ($incidentDays as $i => $day) {
+ $date = app(DateFactory::class)->make($startDate)->subDays($i);
- if (!isset($allIncidents[$date->toDateString()])) {
- $allIncidents[$date->toDateString()] = [];
+ if (!isset($allIncidents[$date->toDateString()])) {
+ $allIncidents[$date->toDateString()] = [];
+ }
}
}
// Sort the array so it takes into account the added days
$allIncidents = $allIncidents->sortBy(function ($value, $key) {
return strtotime($key);
- }, SORT_REGULAR, true)->all();
+ }, SORT_REGULAR, true);
return View::make('index')
- ->withDaysToShow($daysToShow)
+ ->withDaysToShow($appIncidentDays)
->withAllIncidents($allIncidents)
- ->withCanPageForward((bool) $today->gt($startDate))
- ->withCanPageBackward(Incident::notScheduled()->where('created_at', '<', $startDate->format('Y-m-d'))->count() > 0)
- ->withPreviousDate($startDate->copy()->subDays($daysToShow)->toDateString())
- ->withNextDate($startDate->copy()->addDays($daysToShow)->toDateString());
+ ->withCanPageForward($canPageForward)
+ ->withCanPageBackward($canPageBackward)
+ ->withPreviousDate($previousDate)
+ ->withNextDate($nextDate);
}
/**
@@ -121,8 +140,19 @@ public function showIndex()
*/
public function showIncident(Incident $incident)
{
- return View::make('single-incident')
- ->withIncident($incident);
+ return View::make('single-incident')->withIncident($incident);
+ }
+
+ /**
+ * Show a single schedule.
+ *
+ * @param \CachetHQ\Cachet\Models\Schedule $schedule
+ *
+ * @return \Illuminate\View\View
+ */
+ public function showSchedule(Schedule $schedule)
+ {
+ return View::make('single-schedule')->withSchedule($schedule);
}
/**
@@ -134,22 +164,19 @@ public function showIncident(Incident $incident)
*/
public function getMetrics(Metric $metric)
{
- $metricData = [];
- $type = Binput::get('filter', 'last_hour');
+ $type = Binput::get('filter', AutoPresenter::decorate($metric)->view_name);
+ $metrics = app(MetricRepository::class);
switch ($type) {
- case 'last_hour':
- $metricData = $this->metricRepository->listPointsLastHour($metric);
+ case 'last_hour': $metricData = $metrics->listPointsLastHour($metric);
break;
- case 'today':
- $metricData = $this->metricRepository->listPointsToday($metric);
+ case 'today': $metricData = $metrics->listPointsToday($metric);
break;
- case 'week':
- $metricData = $this->metricRepository->listPointsForWeek($metric);
+ case 'week': $metricData = $metrics->listPointsForWeek($metric);
break;
- case 'month':
- $metricData = $this->metricRepository->listPointsForMonth($metric);
+ case 'month': $metricData = $metrics->listPointsForMonth($metric);
break;
+ default: $metricData = [];
}
return $this->item([
@@ -168,21 +195,17 @@ public function getMetrics(Metric $metric)
public function showComponentBadge(Component $component)
{
$component = AutoPresenter::decorate($component);
- $color = null;
switch ($component->status_color) {
- case 'reds':
- $color = Config::get('setting.style_reds', '#ff6f6f');
+ case 'reds': $color = Config::get('setting.style_reds', '#FF6F6F');
break;
- case 'blues':
- $color = Config::get('setting.style_blues', '#3498db');
+ case 'blues': $color = Config::get('setting.style_blues', '#3498DB');
break;
- case 'greens':
- $color = Config::get('setting.style_greens', '#7ED321');
+ case 'greens': $color = Config::get('setting.style_greens', '#7ED321');
break;
- case 'yellows':
- $color = Config::get('setting.style_yellows', '#F7CA18');
+ case 'yellows': $color = Config::get('setting.style_yellows', '#F7CA18');
break;
+ default: $color = null;
}
$badge = Badger::generate(
diff --git a/app/Http/Controllers/SubscribeController.php b/app/Http/Controllers/SubscribeController.php
index f8926c3c7251..afa866a9610e 100644
--- a/app/Http/Controllers/SubscribeController.php
+++ b/app/Http/Controllers/SubscribeController.php
@@ -21,12 +21,14 @@
use CachetHQ\Cachet\Models\ComponentGroup;
use CachetHQ\Cachet\Models\Subscriber;
use CachetHQ\Cachet\Models\Subscription;
+use CachetHQ\Cachet\Notifications\Subscriber\ManageSubscriptionNotification;
use GrahamCampbell\Binput\Facades\Binput;
use GrahamCampbell\Markdown\Facades\Markdown;
+use Illuminate\Contracts\Auth\Guard;
use Illuminate\Contracts\Config\Repository;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Config;
-use Illuminate\Support\Facades\Redirect;
+use Illuminate\Support\Facades\URL;
use Illuminate\Support\Facades\View;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
@@ -38,6 +40,25 @@
*/
class SubscribeController extends Controller
{
+ /**
+ * The illuminate guard instance.
+ *
+ * @var \Illuminate\Contracts\Auth\Guard
+ */
+ protected $auth;
+
+ /**
+ * Create a new subscribe controller instance.
+ *
+ * @param \Illuminate\Contracts\Auth\Guard $auth
+ *
+ * @return void
+ */
+ public function __construct(Guard $auth)
+ {
+ $this->auth = $auth;
+ }
+
/**
* Show the subscribe by email page.
*
@@ -61,20 +82,24 @@ public function postSubscribe()
$verified = app(Repository::class)->get('setting.skip_subscriber_verification');
try {
- $subscription = dispatch(new SubscribeSubscriberCommand($email, $verified));
+ $subscription = execute(new SubscribeSubscriberCommand($email, $verified));
} catch (ValidationException $e) {
- return Redirect::route('status-page')
+ return cachet_redirect('status-page')
->withInput(Binput::all())
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('cachet.subscriber.email.failure')))
->withErrors($e->getMessageBag());
}
- if ($subscription->is_verified) {
- return Redirect::route('status-page')->withSuccess(trans('cachet.subscriber.email.already-subscribed', ['email' => $email]));
- }
+ // Send the subscriber a link to manage their subscription.
+ $subscription->notify(new ManageSubscriptionNotification());
- return Redirect::route('subscribe.manage', $subscription->verify_code)
- ->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('cachet.subscriber.email.subscribed')));
+ return redirect()->back()->withSuccess(
+ sprintf(
+ '%s %s',
+ trans('dashboard.notifications.awesome'),
+ trans('cachet.subscriber.email.manage_subscription')
+ )
+ );
}
/**
@@ -90,18 +115,18 @@ public function getVerify($code = null)
throw new NotFoundHttpException();
}
- $subscriber = Subscriber::where('verify_code', $code)->first();
+ $subscriber = Subscriber::where('verify_code', '=', $code)->first();
if (!$subscriber) {
throw new BadRequestHttpException();
}
if (!$subscriber->is_verified) {
- dispatch(new VerifySubscriberCommand($subscriber));
+ execute(new VerifySubscriberCommand($subscriber));
}
- return Redirect::route('status-page')
- ->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('cachet.subscriber.email.verified')));
+ return redirect()->to(URL::signedRoute(cachet_route_generator('subscribe.manage'), ['code' => $code]))
+ ->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('cachet.subscriber.email.subscribed')));
}
/**
@@ -125,12 +150,12 @@ public function getUnsubscribe($code = null, $subscription = null)
}
if ($subscription) {
- dispatch(new UnsubscribeSubscriptionCommand(Subscription::forSubscriber($subscriber->id)->firstOrFail()));
+ execute(new UnsubscribeSubscriptionCommand(Subscription::forSubscriber($subscriber->id)->firstOrFail()));
} else {
- dispatch(new UnsubscribeSubscriberCommand($subscriber, $subscription));
+ execute(new UnsubscribeSubscriberCommand($subscriber));
}
- return Redirect::route('status-page')
+ return cachet_redirect('status-page')
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('cachet.subscriber.email.unsubscribed')));
}
@@ -147,10 +172,12 @@ public function showManage($code = null)
throw new NotFoundHttpException();
}
+ $includePrivate = $this->auth->check();
+
$subscriber = Subscriber::where('verify_code', '=', $code)->first();
- $usedComponentGroups = Component::enabled()->where('group_id', '>', 0)->groupBy('group_id')->pluck('group_id');
+ $usedComponentGroups = Component::enabled()->authenticated($includePrivate)->where('group_id', '>', 0)->groupBy('group_id')->pluck('group_id');
$componentGroups = ComponentGroup::whereIn('id', $usedComponentGroups)->orderBy('order')->get();
- $ungroupedComponents = Component::enabled()->where('group_id', 0)->orderBy('order')->orderBy('created_at')->get();
+ $ungroupedComponents = Component::enabled()->authenticated($includePrivate)->where('group_id', '=', 0)->orderBy('order')->orderBy('created_at')->get();
if (!$subscriber) {
throw new BadRequestHttpException();
@@ -183,15 +210,15 @@ public function postManage($code = null)
}
try {
- dispatch(new UpdateSubscriberSubscriptionCommand($subscriber, Binput::get('subscriptions')));
+ execute(new UpdateSubscriberSubscriptionCommand($subscriber, Binput::get('subscriptions')));
} catch (ValidationException $e) {
- return Redirect::route('subscribe.manage', $subscriber->verify_code)
+ return redirect()->to(URL::signedRoute(cachet_route_generator('subscribe.manage'), ['code' => $subscriber->verify_code]))
->withInput(Binput::all())
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('cachet.subscriber.email.failure')))
->withErrors($e->getMessageBag());
}
- return Redirect::route('subscribe.manage', $subscriber->verify_code)
- ->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('cachet.subscriber.email.subscribed')));
+ return redirect()->to(URL::signedRoute(cachet_route_generator('subscribe.manage'), ['code' => $subscriber->verify_code]))
+ ->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('cachet.subscriber.email.updated-subscribe')));
}
}
diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php
index 9e0da573e602..ee7e3b40aa96 100644
--- a/app/Http/Kernel.php
+++ b/app/Http/Kernel.php
@@ -11,7 +11,23 @@
namespace CachetHQ\Cachet\Http;
+use Barryvdh\Cors\HandleCors;
+use CachetHQ\Cachet\Http\Middleware\Admin;
+use CachetHQ\Cachet\Http\Middleware\ApiAuthentication;
+use CachetHQ\Cachet\Http\Middleware\Authenticate;
+use CachetHQ\Cachet\Http\Middleware\CacheControl;
+use CachetHQ\Cachet\Http\Middleware\Localize;
+use CachetHQ\Cachet\Http\Middleware\ReadyForUse;
+use CachetHQ\Cachet\Http\Middleware\RedirectIfAuthenticated;
+use CachetHQ\Cachet\Http\Middleware\RemoteUserAuthenticate;
+use CachetHQ\Cachet\Http\Middleware\SetupAlreadyCompleted;
+use CachetHQ\Cachet\Http\Middleware\SubscribersConfigured;
+use CachetHQ\Cachet\Http\Middleware\Throttler;
+use CachetHQ\Cachet\Http\Middleware\TrustProxies;
+use Illuminate\Auth\Middleware\Authorize;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
+use Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode;
+use Illuminate\Routing\Middleware\ValidateSignature;
class Kernel extends HttpKernel
{
@@ -21,28 +37,8 @@ class Kernel extends HttpKernel
* @var array
*/
protected $middleware = [
- 'Fideloper\Proxy\TrustProxies',
- 'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode',
- ];
-
- /**
- * The application's route middleware groups.
- *
- * @var array
- */
- protected $middlewareGroups = [
- 'web' => [
- 'Illuminate\Cookie\Middleware\EncryptCookies',
- 'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse',
- 'Illuminate\Session\Middleware\StartSession',
- 'Illuminate\View\Middleware\ShareErrorsFromSession',
- 'Illuminate\Foundation\Http\Middleware\VerifyCsrfToken',
- ],
- 'api' => [
- 'Barryvdh\Cors\HandleCors',
- 'CachetHQ\Cachet\Http\Middleware\Acceptable',
- 'CachetHQ\Cachet\Http\Middleware\Timezone',
- ],
+ TrustProxies::class,
+ CheckForMaintenanceMode::class,
];
/**
@@ -51,14 +47,19 @@ class Kernel extends HttpKernel
* @var array
*/
protected $routeMiddleware = [
- 'admin' => 'CachetHQ\Cachet\Http\Middleware\Admin',
- 'auth' => 'CachetHQ\Cachet\Http\Middleware\Authenticate',
- 'auth.api' => 'CachetHQ\Cachet\Http\Middleware\ApiAuthentication',
- 'guest' => 'CachetHQ\Cachet\Http\Middleware\RedirectIfAuthenticated',
- 'localize' => 'CachetHQ\Cachet\Http\Middleware\Localize',
- 'ready' => 'CachetHQ\Cachet\Http\Middleware\ReadyForUse',
- 'setup' => 'CachetHQ\Cachet\Http\Middleware\SetupAlreadyCompleted',
- 'subscribers' => 'CachetHQ\Cachet\Http\Middleware\SubscribersConfigured',
- 'throttle' => 'AltThree\Throttle\ThrottlingMiddleware',
+ 'admin' => Admin::class,
+ 'auth.api' => ApiAuthentication::class,
+ 'auth.remoteuser' => RemoteUserAuthenticate::class,
+ 'auth' => Authenticate::class,
+ 'cache' => CacheControl::class,
+ 'can' => Authorize::class,
+ 'cors' => HandleCors::class,
+ 'guest' => RedirectIfAuthenticated::class,
+ 'localize' => Localize::class,
+ 'ready' => ReadyForUse::class,
+ 'setup' => SetupAlreadyCompleted::class,
+ 'signed' => ValidateSignature::class,
+ 'subscribers' => SubscribersConfigured::class,
+ 'throttle' => Throttler::class,
];
}
diff --git a/app/Http/Middleware/Acceptable.php b/app/Http/Middleware/Acceptable.php
index 2c22a6a21e26..97974fa72b64 100644
--- a/app/Http/Middleware/Acceptable.php
+++ b/app/Http/Middleware/Acceptable.php
@@ -15,6 +15,12 @@
use Illuminate\Http\Request;
use Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException;
+/**
+ * This is the acceptable middleware class.
+ *
+ * @author Graham Campbell
+ * @author James Brooks
+ */
class Acceptable
{
/**
diff --git a/app/Http/Middleware/Admin.php b/app/Http/Middleware/Admin.php
index 5088b091ac20..4180c3665d1a 100644
--- a/app/Http/Middleware/Admin.php
+++ b/app/Http/Middleware/Admin.php
@@ -16,6 +16,13 @@
use Illuminate\Http\Request;
use Symfony\Component\HttpKernel\Exception\HttpException;
+/**
+ * This is the admin middleware class.
+ *
+ * @author Joseph Cohen
+ * @author Graham Campbell
+ * @author James Brooks
+ */
class Admin
{
/**
diff --git a/app/Http/Middleware/ApiAuthentication.php b/app/Http/Middleware/ApiAuthentication.php
index f4c10611d6f4..c02b6c089c5e 100644
--- a/app/Http/Middleware/ApiAuthentication.php
+++ b/app/Http/Middleware/ApiAuthentication.php
@@ -18,6 +18,13 @@
use Illuminate\Http\Request;
use Symfony\Component\HttpKernel\Exception\HttpException;
+/**
+ * This is the api authentication middleware class.
+ *
+ * @author Joseph Cohen
+ * @author Graham Campbell
+ * @author James Brooks
+ */
class ApiAuthentication
{
/**
diff --git a/app/Http/Middleware/Authenticate.php b/app/Http/Middleware/Authenticate.php
index 0400413194c2..9b5562cb3173 100644
--- a/app/Http/Middleware/Authenticate.php
+++ b/app/Http/Middleware/Authenticate.php
@@ -16,6 +16,13 @@
use Illuminate\Http\Request;
use Symfony\Component\HttpKernel\Exception\HttpException;
+/**
+ * This is the authenticate middleware class.
+ *
+ * @author Joseph Cohen
+ * @author Graham Campbell
+ * @author James Brooks
+ */
class Authenticate
{
/**
diff --git a/app/Http/Middleware/CacheControl.php b/app/Http/Middleware/CacheControl.php
new file mode 100644
index 000000000000..fa54dfe094f0
--- /dev/null
+++ b/app/Http/Middleware/CacheControl.php
@@ -0,0 +1,37 @@
+header('Cache-Control', 'public,max-age='.$maxAge);
+
+ return $response;
+ }
+}
diff --git a/app/Http/Middleware/Localize.php b/app/Http/Middleware/Localize.php
index 718e2ddb74d2..52469c41515b 100644
--- a/app/Http/Middleware/Localize.php
+++ b/app/Http/Middleware/Localize.php
@@ -11,38 +11,47 @@
namespace CachetHQ\Cachet\Http\Middleware;
+use CachetHQ\Cachet\Settings\Repository as SettingsRepository;
use Closure;
-use Illuminate\Config\Repository;
+use Illuminate\Contracts\Config\Repository as ConfigRepository;
use Illuminate\Http\Request;
use Jenssegers\Date\Date;
+/**
+ * This is the localize middleware class.
+ *
+ * @author James Brooks
+ * @author Joseph Cohen
+ * @author Graham Campbell
+ */
class Localize
{
/**
- * Array of languages Cachet can use.
+ * The config repository instance.
*
- * @var array
+ * @var \Illuminate\Contracts\Config\Repository
*/
- protected $langs;
+ protected $config;
/**
- * The config repository instance.
+ * The settings repository instance.
*
- * @var \Illuminate\Config\Repository
+ * @var \CachetHQ\Cachet\Settings\Repository
*/
- protected $config;
+ protected $settings;
/**
* Constructs a new localize middleware instance.
*
- * @param \Illuminate\Config\Repository $config
+ * @param \Illuminate\Contracts\Config\Repository $config
+ * @param \CachetHQ\Cachet\Settings\Repository $settings
*
* @return void
*/
- public function __construct(Repository $config)
+ public function __construct(ConfigRepository $config, SettingsRepository $settings)
{
$this->config = $config;
- $this->langs = $config->get('langs');
+ $this->settings = $settings;
}
/**
@@ -55,17 +64,18 @@ public function __construct(Repository $config)
*/
public function handle(Request $request, Closure $next)
{
- if (!(bool) $this->config->get('setting.automatic_localization')) {
+ if (!(bool) $this->settings->get('automatic_localization')) {
return $next($request);
}
- $supportedLanguages = $request->getLanguages();
+ $requestedLanguages = $request->getLanguages();
$userLanguage = $this->config->get('app.locale');
+ $langs = $this->config->get('langs');
- foreach ($supportedLanguages as $language) {
+ foreach ($requestedLanguages as $language) {
$language = str_replace('_', '-', $language);
- if (isset($this->langs[$language])) {
+ if (isset($langs[$language])) {
$userLanguage = $language;
break;
}
diff --git a/app/Http/Middleware/ReadyForUse.php b/app/Http/Middleware/ReadyForUse.php
index 364c7f42a50d..11b1afbbb808 100644
--- a/app/Http/Middleware/ReadyForUse.php
+++ b/app/Http/Middleware/ReadyForUse.php
@@ -11,14 +11,38 @@
namespace CachetHQ\Cachet\Http\Middleware;
+use CachetHQ\Cachet\Settings\Repository;
use Closure;
-use Exception;
use Illuminate\Http\Request;
-use Illuminate\Support\Facades\Config;
-use Illuminate\Support\Facades\Redirect;
+/**
+ * This is the ready for use middleware class.
+ *
+ * @author Graham Campbell
+ * @author James Brooks
+ * @author Joseph Cohen
+ */
class ReadyForUse
{
+ /**
+ * The settings repository instance.
+ *
+ * @var \CachetHQ\Cachet\Settings\Repository
+ */
+ protected $settings;
+
+ /**
+ * Creates a new setup already completed middleware instance.
+ *
+ * @param \CachetHQ\Cachet\Settings\Repository $settings
+ *
+ * @return void
+ */
+ public function __construct(Repository $settings)
+ {
+ $this->settings = $settings;
+ }
+
/**
* Handle an incoming request.
*
@@ -29,12 +53,8 @@ class ReadyForUse
*/
public function handle(Request $request, Closure $next)
{
- try {
- if (!Config::get('setting.app_name')) {
- return Redirect::to('setup');
- }
- } catch (Exception $e) {
- return Redirect::to('setup');
+ if (!$request->is('setup*') && !$this->settings->get('app_name')) {
+ return cachet_redirect('setup');
}
return $next($request);
diff --git a/app/Http/Middleware/RedirectIfAuthenticated.php b/app/Http/Middleware/RedirectIfAuthenticated.php
index 7b79128b3a20..b8c956485445 100644
--- a/app/Http/Middleware/RedirectIfAuthenticated.php
+++ b/app/Http/Middleware/RedirectIfAuthenticated.php
@@ -13,9 +13,15 @@
use Closure;
use Illuminate\Contracts\Auth\Guard;
-use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
+/**
+ * This is the redirect if authenticated middleware class.
+ *
+ * @author Graham Campbell
+ * @author Joseph Cohen
+ * @author James Brooks
+ */
class RedirectIfAuthenticated
{
/**
@@ -48,7 +54,7 @@ public function __construct(Guard $auth)
public function handle(Request $request, Closure $next)
{
if ($this->auth->check()) {
- return new RedirectResponse(route('dashboard.index'));
+ return cachet_redirect('dashboard');
}
return $next($request);
diff --git a/app/Http/Middleware/RemoteUserAuthenticate.php b/app/Http/Middleware/RemoteUserAuthenticate.php
new file mode 100644
index 000000000000..075c0c4a13a7
--- /dev/null
+++ b/app/Http/Middleware/RemoteUserAuthenticate.php
@@ -0,0 +1,53 @@
+auth = $auth;
+ }
+
+ /**
+ * Handle an incoming request.
+ *
+ * @param \Illuminate\Http\Request $request
+ * @param \Closure $next
+ *
+ * @return mixed
+ */
+ public function handle(Request $request, Closure $next)
+ {
+ if ($remoteUser = $request->server('REMOTE_USER')) {
+ $user = User::where('email', '=', $remoteUser)->first();
+
+ if ($user instanceof User && $this->auth->guest()) {
+ $this->auth->login($user);
+ }
+ }
+
+ return $next($request);
+ }
+}
diff --git a/app/Http/Middleware/SetupAlreadyCompleted.php b/app/Http/Middleware/SetupAlreadyCompleted.php
index 96db9729f5f3..e0df0c8f5ed8 100644
--- a/app/Http/Middleware/SetupAlreadyCompleted.php
+++ b/app/Http/Middleware/SetupAlreadyCompleted.php
@@ -11,13 +11,39 @@
namespace CachetHQ\Cachet\Http\Middleware;
+use CachetHQ\Cachet\Settings\ReadException;
+use CachetHQ\Cachet\Settings\Repository;
use Closure;
use Illuminate\Http\Request;
-use Illuminate\Support\Facades\Config;
-use Illuminate\Support\Facades\Redirect;
+/**
+ * This is the setup already completed middelware class.
+ *
+ * @author Graham Campbell
+ * @author James Brooks
+ * @author Joseph Cohen
+ */
class SetupAlreadyCompleted
{
+ /**
+ * The settings repository instance.
+ *
+ * @var \CachetHQ\Cachet\Settings\Repository
+ */
+ protected $settings;
+
+ /**
+ * Creates a new setup already completed middleware instance.
+ *
+ * @param \CachetHQ\Cachet\Settings\Repository $settings
+ *
+ * @return void
+ */
+ public function __construct(Repository $settings)
+ {
+ $this->settings = $settings;
+ }
+
/**
* Handle an incoming request.
*
@@ -28,8 +54,12 @@ class SetupAlreadyCompleted
*/
public function handle(Request $request, Closure $next)
{
- if (Config::get('setting.app_name')) {
- return Redirect::to('dashboard');
+ try {
+ if ($this->settings->get('app_name')) {
+ return cachet_redirect('dashboard');
+ }
+ } catch (ReadException $e) {
+ // not setup then!
}
return $next($request);
diff --git a/app/Http/Middleware/SubscribersConfigured.php b/app/Http/Middleware/SubscribersConfigured.php
index 50cdeedb6edf..116b20a57177 100644
--- a/app/Http/Middleware/SubscribersConfigured.php
+++ b/app/Http/Middleware/SubscribersConfigured.php
@@ -12,11 +12,36 @@
namespace CachetHQ\Cachet\Http\Middleware;
use Closure;
+use Illuminate\Contracts\Config\Repository;
use Illuminate\Http\Request;
-use Illuminate\Support\Facades\Redirect;
+/**
+ * This is the subscribers configured middleware class.
+ *
+ * @author James Brooks
+ * @author Graham Campbell
+ */
class SubscribersConfigured
{
+ /**
+ * The config repository instance.
+ *
+ * @var \Illuminate\Contracts\Config\Repository
+ */
+ protected $config;
+
+ /**
+ * Creates a subscribers configured middleware instance.
+ *
+ * @param \Illuminate\Contracts\Config\Repository $config
+ *
+ * @return void
+ */
+ public function __construct(Repository $config)
+ {
+ $this->config = $config;
+ }
+
/**
* Handle an incoming request.
*
@@ -27,10 +52,6 @@ class SubscribersConfigured
*/
public function handle(Request $request, Closure $next)
{
- if (!subscribers_enabled()) {
- return Redirect::route('status-page');
- }
-
return $next($request);
}
}
diff --git a/app/Http/Middleware/Throttler.php b/app/Http/Middleware/Throttler.php
new file mode 100644
index 000000000000..c83149633883
--- /dev/null
+++ b/app/Http/Middleware/Throttler.php
@@ -0,0 +1,125 @@
+
+ */
+class Throttler
+{
+ /**
+ * The rate limiter instance.
+ *
+ * @var \Illuminate\Cache\RateLimiter
+ */
+ protected $limiter;
+
+ /**
+ * Create a new throttler middleware instance.
+ *
+ * @param \Illuminate\Cache\RateLimiter $limiter
+ *
+ * @return void
+ */
+ public function __construct(RateLimiter $limiter)
+ {
+ $this->limiter = $limiter;
+ }
+
+ /**
+ * Handle an incoming request.
+ *
+ * @param \Illuminate\Http\Request $request
+ * @param \Closure $next
+ * @param int|string $limit
+ * @param int|string $decay
+ *
+ * @throws \Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException
+ *
+ * @return mixed
+ */
+ public function handle(Request $request, Closure $next, $limit = 60, $decay = 1)
+ {
+ return $this->safeHandle($request, $next, (int) $limit, (int) $decay);
+ }
+
+ /**
+ * Handle an incoming request, with correct types.
+ *
+ * @param \Illuminate\Http\Request $request
+ * @param \Closure $next
+ * @param int $limit
+ * @param int $decay
+ *
+ * @throws \Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException
+ *
+ * @return mixed
+ */
+ protected function safeHandle(Request $request, Closure $next, int $limit, int $decay)
+ {
+ $key = $request->fingerprint();
+
+ if ($this->limiter->tooManyAttempts($key, $limit, $decay)) {
+ throw $this->buildException($key, $limit);
+ }
+
+ $this->limiter->hit($key, $decay);
+
+ $response = $next($request);
+
+ $response->headers->add($this->getHeaders($key, $limit));
+
+ return $response;
+ }
+
+ /**
+ * Create a too many requests http exception.
+ *
+ * @param string $key
+ * @param int $limit
+ *
+ * @return \Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException
+ */
+ protected function buildException(string $key, int $limit)
+ {
+ $after = $this->limiter->availableIn($key);
+ $exception = new TooManyRequestsHttpException($after, 'Rate limit exceeded.');
+ $exception->setHeaders($this->getHeaders($key, $limit, $after, $exception->getHeaders()));
+
+ return $exception;
+ }
+
+ /**
+ * Get the limit header information.
+ *
+ * @param string $key
+ * @param int $limit
+ * @param int|null $after
+ * @param array $merge
+ *
+ * @return array
+ */
+ protected function getHeaders(string $key, int $limit, int $after = null, array $merge = [])
+ {
+ $remaining = $after === null ? $this->limiter->retriesLeft($key, $limit) : 0;
+ $headers = ['X-RateLimit-Limit' => $limit, 'X-RateLimit-Remaining' => $remaining];
+
+ return array_merge($headers, $merge);
+ }
+}
diff --git a/app/Http/Middleware/Timezone.php b/app/Http/Middleware/Timezone.php
index 8b56ddbbdbee..e0700714af92 100644
--- a/app/Http/Middleware/Timezone.php
+++ b/app/Http/Middleware/Timezone.php
@@ -15,6 +15,12 @@
use Illuminate\Contracts\Config\Repository;
use Illuminate\Http\Request;
+/**
+ * This is the timezone middleware class.
+ *
+ * @author James Brooks
+ * @author Graham Campbell
+ */
class Timezone
{
/**
diff --git a/app/Http/Middleware/TrustProxies.php b/app/Http/Middleware/TrustProxies.php
new file mode 100644
index 000000000000..83a86c5e6ff3
--- /dev/null
+++ b/app/Http/Middleware/TrustProxies.php
@@ -0,0 +1,50 @@
+
+ */
+class TrustProxies extends Middleware
+{
+ /**
+ * The trusted proxies for this application.
+ *
+ * @var array
+ */
+ protected $proxies;
+
+ /**
+ * The headers that should be used to detect proxies.
+ *
+ * @var int
+ */
+ protected $headers = Request::HEADER_X_FORWARDED_ALL;
+
+ /**
+ * Create new trust proxies instance.
+ *
+ * @return void
+ */
+ public function __construct()
+ {
+ $proxies = Config::get('trustedproxies.proxies');
+
+ $this->proxies = empty($proxies) ? '*' : explode(',', trim($proxies));
+ }
+}
diff --git a/app/Http/Middleware/VerifyCsrfToken.php b/app/Http/Middleware/VerifyCsrfToken.php
new file mode 100644
index 000000000000..cfd2fc055a5d
--- /dev/null
+++ b/app/Http/Middleware/VerifyCsrfToken.php
@@ -0,0 +1,38 @@
+
+ */
+class VerifyCsrfToken extends Middleware
+{
+ /**
+ * Indicates whether the XSRF-TOKEN cookie should be set on the response.
+ *
+ * @var bool
+ */
+ protected $addHttpCookie = true;
+
+ /**
+ * The URIs that should be excluded from CSRF verification.
+ *
+ * @var array
+ */
+ protected $except = [
+ '/api/*',
+ ];
+}
diff --git a/app/Http/Routes/ApiRoutes.php b/app/Http/Routes/ApiRoutes.php
index c288b96bc410..b56902d3635b 100644
--- a/app/Http/Routes/ApiRoutes.php
+++ b/app/Http/Routes/ApiRoutes.php
@@ -20,6 +20,13 @@
*/
class ApiRoutes
{
+ /**
+ * Defines if these routes are for the browser.
+ *
+ * @var bool
+ */
+ public static $browser = false;
+
/**
* Define the api routes.
*
@@ -29,48 +36,62 @@ class ApiRoutes
*/
public function map(Registrar $router)
{
- $router->group(['namespace' => 'Api', 'prefix' => 'api/v1', 'middleware' => ['api']], function (Registrar $router) {
- $router->group(['middleware' => ['auth.api']], function (Registrar $router) {
- $router->get('ping', 'GeneralController@ping');
- $router->get('version', 'GeneralController@version');
- $router->get('status', 'GeneralController@status');
+ $router->group([
+ 'namespace' => 'Api',
+ 'prefix' => 'api/v1',
+ ], function (Registrar $router) {
+ $router->group(['middleware' => ['auth.api', 'cors']], function (Registrar $router) {
+ $router->get('components', 'ComponentController@index');
+ $router->get('components/groups', 'ComponentGroupController@index');
+ $router->get('components/groups/{component_group}', 'ComponentGroupController@show');
+ $router->get('components/{component}', 'ComponentController@show');
+
+ $router->get('incidents', 'IncidentController@index');
+
+ $router->get('incidents/templates', 'IncidentTemplateController@index');
+ $router->get('incidents/templates/{incident_template}', 'IncidentTemplateController@show');
- $router->get('components', 'ComponentController@getComponents');
- $router->get('components/groups', 'ComponentGroupController@getGroups');
- $router->get('components/groups/{component_group}', 'ComponentGroupController@getGroup');
- $router->get('components/{component}', 'ComponentController@getComponent');
+ $router->get('incidents/{incident}', 'IncidentController@show');
+ $router->get('incidents/{incident}/updates', 'IncidentUpdateController@index');
+ $router->get('incidents/{incident}/updates/{update}', 'IncidentUpdateController@show');
- $router->get('incidents', 'IncidentController@getIncidents');
- $router->get('incidents/{incident}', 'IncidentController@getIncident');
+ $router->get('metrics', 'MetricController@index');
+ $router->get('metrics/{metric}', 'MetricController@show');
+ $router->get('metrics/{metric}/points', 'MetricPointController@index');
- $router->get('metrics', 'MetricController@getMetrics');
- $router->get('metrics/{metric}', 'MetricController@getMetric');
- $router->get('metrics/{metric}/points', 'MetricController@getMetricPoints');
+ $router->get('schedules', 'ScheduleController@index');
+ $router->get('schedules/{schedule}', 'ScheduleController@show');
});
$router->group(['middleware' => ['auth.api:true']], function (Registrar $router) {
- $router->get('subscribers', 'SubscriberController@getSubscribers');
+ $router->get('subscribers', 'SubscriberController@index');
- $router->post('components', 'ComponentController@postComponents');
- $router->post('components/groups', 'ComponentGroupController@postGroups');
- $router->post('incidents', 'IncidentController@postIncidents');
- $router->post('metrics', 'MetricController@postMetrics');
- $router->post('metrics/{metric}/points', 'MetricPointController@postMetricPoints');
- $router->post('subscribers', 'SubscriberController@postSubscribers');
+ $router->post('components', 'ComponentController@store');
+ $router->post('components/groups', 'ComponentGroupController@store');
+ $router->post('incidents', 'IncidentController@store');
+ $router->post('incidents/{incident}/updates', 'IncidentUpdateController@store');
+ $router->post('metrics', 'MetricController@store');
+ $router->post('metrics/{metric}/points', 'MetricPointController@store');
+ $router->post('schedules', 'ScheduleController@store');
+ $router->post('subscribers', 'SubscriberController@store');
- $router->put('components/groups/{component_group}', 'ComponentGroupController@putGroup');
- $router->put('components/{component}', 'ComponentController@putComponent');
- $router->put('incidents/{incident}', 'IncidentController@putIncident');
- $router->put('metrics/{metric}', 'MetricController@putMetric');
- $router->put('metrics/{metric}/points/{metric_point}', 'MetricPointController@putMetricPoint');
+ $router->put('components/groups/{component_group}', 'ComponentGroupController@update');
+ $router->put('components/{component}', 'ComponentController@update');
+ $router->put('incidents/{incident}', 'IncidentController@update');
+ $router->put('incidents/{incident}/updates/{update}', 'IncidentUpdateController@update');
+ $router->put('metrics/{metric}', 'MetricController@update');
+ $router->put('metrics/{metric}/points/{metric_point}', 'MetricPointController@update');
+ $router->put('schedules/{schedule}', 'ScheduleController@update');
- $router->delete('components/groups/{component_group}', 'ComponentGroupController@deleteGroup');
- $router->delete('components/{component}', 'ComponentController@deleteComponent');
- $router->delete('incidents/{incident}', 'IncidentController@deleteIncident');
- $router->delete('metrics/{metric}', 'MetricController@deleteMetric');
- $router->delete('metrics/{metric}/points/{metric_point}', 'MetricPointController@deleteMetricPoint');
- $router->delete('subscribers/{subscriber}', 'SubscriberController@deleteSubscriber');
- $router->delete('subscriptions/{subscription}', 'SubscriberController@deleteSubscription');
+ $router->delete('components/groups/{component_group}', 'ComponentGroupController@destroy');
+ $router->delete('components/{component}', 'ComponentController@destroy');
+ $router->delete('incidents/{incident}', 'IncidentController@destroy');
+ $router->delete('incidents/{incident}/updates/{update}', 'IncidentUpdateController@destroy');
+ $router->delete('metrics/{metric}', 'MetricController@destroy');
+ $router->delete('metrics/{metric}/points/{metric_point}', 'MetricPointController@destroy');
+ $router->delete('schedules/{schedule}', 'ScheduleController@destroy');
+ $router->delete('subscribers/{subscriber}', 'SubscriberController@destroy');
+ $router->delete('subscriptions/{subscription}', 'SubscriptionController@destroy');
});
});
}
diff --git a/app/Http/Routes/ApiSystemRoutes.php b/app/Http/Routes/ApiSystemRoutes.php
new file mode 100644
index 000000000000..92a7aa2e31a8
--- /dev/null
+++ b/app/Http/Routes/ApiSystemRoutes.php
@@ -0,0 +1,50 @@
+
+ */
+class ApiSystemRoutes
+{
+ /**
+ * Defines if these routes are for the browser.
+ *
+ * @var bool
+ */
+ public static $browser = false;
+
+ /**
+ * Define the api routes for the system status, ping and version.
+ *
+ * @param \Illuminate\Contracts\Routing\Registrar $router
+ *
+ * @return void
+ */
+ public function map(Registrar $router)
+ {
+ $router->group([
+ 'namespace' => 'Api',
+ 'prefix' => 'api/v1',
+ ], function (Registrar $router) {
+ $router->group(['middleware' => ['auth.api']], function (Registrar $router) {
+ $router->get('ping', 'GeneralController@ping');
+ $router->get('version', 'GeneralController@version');
+ $router->get('status', ['uses' => 'GeneralController@status', 'middleware' => ['cache']]);
+ });
+ });
+ }
+}
diff --git a/app/Http/Routes/AuthRoutes.php b/app/Http/Routes/AuthRoutes.php
index f61477788e25..f1dd7fa96bd9 100644
--- a/app/Http/Routes/AuthRoutes.php
+++ b/app/Http/Routes/AuthRoutes.php
@@ -20,6 +20,13 @@
*/
class AuthRoutes
{
+ /**
+ * Defines if these routes are for the browser.
+ *
+ * @var bool
+ */
+ public static $browser = true;
+
/**
* Define the auth routes.
*
@@ -29,30 +36,35 @@ class AuthRoutes
*/
public function map(Registrar $router)
{
- $router->group(['as' => 'auth.', 'middleware' => ['web', 'ready'], 'prefix' => 'auth'], function (Registrar $router) {
+ $router->group([
+ 'middleware' => ['ready'],
+ 'prefix' => 'auth',
+ ], function (Registrar $router) {
$router->get('login', [
+ 'as' => 'get:auth.login',
'middleware' => 'guest',
- 'as' => 'login',
'uses' => 'AuthController@showLogin',
]);
$router->post('login', [
+ 'as' => 'post:auth.login',
'middleware' => ['guest', 'throttle:10,10'],
'uses' => 'AuthController@postLogin',
]);
$router->get('2fa', [
- 'as' => 'two-factor',
+ 'as' => 'get:auth.two-factor',
'uses' => 'AuthController@showTwoFactorAuth',
]);
$router->post('2fa', [
+ 'as' => 'post:auth.two-factor',
'middleware' => ['throttle:10,10'],
'uses' => 'AuthController@postTwoFactor',
]);
$router->get('logout', [
- 'as' => 'logout',
+ 'as' => 'get:auth.logout',
'uses' => 'AuthController@logoutAction',
'middleware' => 'auth',
]);
diff --git a/app/Http/Routes/Dashboard/ApiRoutes.php b/app/Http/Routes/Dashboard/ApiRoutes.php
index 5aeeb4b5672b..46d186dc2bb9 100644
--- a/app/Http/Routes/Dashboard/ApiRoutes.php
+++ b/app/Http/Routes/Dashboard/ApiRoutes.php
@@ -21,6 +21,13 @@
*/
class ApiRoutes
{
+ /**
+ * Defines if these routes are for the browser.
+ *
+ * @var bool
+ */
+ public static $browser = true;
+
/**
* Define the dashboard api routes.
*
@@ -31,15 +38,14 @@ class ApiRoutes
public function map(Registrar $router)
{
$router->group([
- 'middleware' => ['web', 'auth'],
+ 'middleware' => ['auth'],
'namespace' => 'Dashboard',
- 'as' => 'dashboard.api.',
'prefix' => 'dashboard/api',
], function (Registrar $router) {
$router->get('incidents/templates', 'ApiController@getIncidentTemplate');
$router->post('components/groups/order', 'ApiController@postUpdateComponentGroupOrder');
$router->post('components/order', 'ApiController@postUpdateComponentOrder');
- $router->post('components/{component}', 'ApiController@postUpdateComponent');
+ $router->any('components/{component}', 'ApiController@postUpdateComponent');
});
}
}
diff --git a/app/Http/Routes/Dashboard/BaseRoutes.php b/app/Http/Routes/Dashboard/BaseRoutes.php
index 0b82d944e9bc..61d7e742d8cf 100644
--- a/app/Http/Routes/Dashboard/BaseRoutes.php
+++ b/app/Http/Routes/Dashboard/BaseRoutes.php
@@ -21,6 +21,13 @@
*/
class BaseRoutes
{
+ /**
+ * Defines if these routes are for the browser.
+ *
+ * @var bool
+ */
+ public static $browser = true;
+
/**
* Define the dashboard base routes.
*
@@ -30,12 +37,15 @@ class BaseRoutes
*/
public function map(Registrar $router)
{
- $router->group(['middleware' => ['web', 'auth'], 'namespace' => 'Dashboard'], function (Registrar $router) {
+ $router->group([
+ 'middleware' => ['auth'],
+ 'namespace' => 'Dashboard',
+ ], function (Registrar $router) {
$router->get('admin', 'DashboardController@redirectAdmin');
- $router->group(['prefix' => 'dashboard', 'as' => 'dashboard.'], function (Registrar $router) {
+ $router->group(['prefix' => 'dashboard'], function (Registrar $router) {
$router->get('/', [
- 'as' => 'index',
+ 'as' => 'get:dashboard',
'uses' => 'DashboardController@showDashboard',
]);
});
diff --git a/app/Http/Routes/Dashboard/ComponentRoutes.php b/app/Http/Routes/Dashboard/ComponentRoutes.php
index 21b6bbe04b8b..aa7852f827e2 100644
--- a/app/Http/Routes/Dashboard/ComponentRoutes.php
+++ b/app/Http/Routes/Dashboard/ComponentRoutes.php
@@ -21,6 +21,13 @@
*/
class ComponentRoutes
{
+ /**
+ * Defines if these routes are for the browser.
+ *
+ * @var bool
+ */
+ public static $browser = true;
+
/**
* Define the dashboard component routes.
*
@@ -31,41 +38,63 @@ class ComponentRoutes
public function map(Registrar $router)
{
$router->group([
- 'middleware' => ['web', 'auth'],
+ 'middleware' => ['auth'],
'namespace' => 'Dashboard',
- 'as' => 'dashboard.components.',
'prefix' => 'dashboard/components',
], function (Registrar $router) {
$router->get('/', [
- 'as' => 'index',
+ 'as' => 'get:dashboard.components',
'uses' => 'ComponentController@showComponents',
]);
- $router->get('add', [
- 'as' => 'add',
+
+ $router->get('create', [
+ 'as' => 'get:dashboard.components.create',
'uses' => 'ComponentController@showAddComponent',
]);
- $router->post('add', 'ComponentController@createComponentAction');
+ $router->post('create', [
+ 'as' => 'post:dashboard.components.create',
+ 'uses' => 'ComponentController@createComponentAction',
+ ]);
+
$router->get('groups', [
- 'as' => 'groups',
- 'uses' => 'ComponentController@showComponentGroups',
+ 'as' => 'get:dashboard.components.groups',
+ 'uses' => 'ComponentGroupController@showComponentGroups',
]);
- $router->get('groups/add', [
- 'as' => 'groups.add',
- 'uses' => 'ComponentController@showAddComponentGroup',
+
+ $router->get('groups/create', [
+ 'as' => 'get:dashboard.components.groups.create',
+ 'uses' => 'ComponentGroupController@showAddComponentGroup',
]);
- $router->get('groups/edit/{component_group}', [
- 'as' => 'groups.edit',
- 'uses' => 'ComponentController@showEditComponentGroup',
+ $router->post('groups/create', [
+ 'as' => 'post:dashboard.components.groups.create',
+ 'uses' => 'ComponentGroupController@postAddComponentGroup',
]);
- $router->post('groups/edit/{component_group}', 'ComponentController@updateComponentGroupAction');
- $router->delete('groups/{component_group}/delete', 'ComponentController@deleteComponentGroupAction');
- $router->post('groups/add', 'ComponentController@postAddComponentGroup');
- $router->get('{component}/edit', [
- 'as' => 'edit',
+
+ $router->get('groups/{component_group}', [
+ 'as' => 'get:dashboard.components.groups.edit',
+ 'uses' => 'ComponentGroupController@showEditComponentGroup',
+ ]);
+ $router->post('groups/{component_group}', [
+ 'as' => 'post:dashboard.components.groups.edit',
+ 'uses' => 'ComponentGroupController@updateComponentGroupAction',
+ ]);
+ $router->delete('groups/{component_group}', [
+ 'as' => 'delete:dashboard.components.groups.delete',
+ 'uses' => 'ComponentGroupController@deleteComponentGroupAction',
+ ]);
+
+ $router->get('{component}', [
+ 'as' => 'get:dashboard.components.edit',
'uses' => 'ComponentController@showEditComponent',
]);
- $router->delete('{component}/delete', 'ComponentController@deleteComponentAction');
- $router->post('{component}/edit', 'ComponentController@updateComponentAction');
+ $router->post('{component}', [
+ 'as' => 'post:dashboard.components.edit',
+ 'uses' => 'ComponentController@updateComponentAction',
+ ]);
+ $router->delete('{component}', [
+ 'as' => 'delete:dashboard.components.delete',
+ 'uses' => 'ComponentController@deleteComponentAction',
+ ]);
});
}
}
diff --git a/app/Http/Routes/Dashboard/IncidentRoutes.php b/app/Http/Routes/Dashboard/IncidentRoutes.php
index d63ab4e6bbcc..4eee1e5e8e7e 100644
--- a/app/Http/Routes/Dashboard/IncidentRoutes.php
+++ b/app/Http/Routes/Dashboard/IncidentRoutes.php
@@ -21,6 +21,13 @@
*/
class IncidentRoutes
{
+ /**
+ * Defines if these routes are for the browser.
+ *
+ * @var bool
+ */
+ public static $browser = true;
+
/**
* Define the dashboard incident routes.
*
@@ -31,29 +38,57 @@ class IncidentRoutes
public function map(Registrar $router)
{
$router->group([
- 'middleware' => ['web', 'auth'],
+ 'middleware' => ['auth'],
'namespace' => 'Dashboard',
- 'as' => 'dashboard.incidents.',
'prefix' => 'dashboard/incidents',
], function (Registrar $router) {
$router->get('/', [
- 'as' => 'index',
+ 'as' => 'get:dashboard.incidents',
'uses' => 'IncidentController@showIncidents',
]);
- $router->get('add', [
- 'as' => 'add',
+
+ $router->get('create', [
+ 'as' => 'get:dashboard.incidents.create',
'uses' => 'IncidentController@showAddIncident',
]);
- $router->post('add', 'IncidentController@createIncidentAction');
- $router->delete('{incident}/delete', [
- 'as' => 'delete',
- 'uses' => 'IncidentController@deleteIncidentAction',
+ $router->post('create', [
+ 'as' => 'post:dashboard.incidents.create',
+ 'uses' => 'IncidentController@createIncidentAction',
]);
- $router->get('{incident}/edit', [
- 'as' => 'edit',
+
+ $router->get('{incident}', [
+ 'as' => 'get:dashboard.incidents.edit',
'uses' => 'IncidentController@showEditIncidentAction',
]);
- $router->post('{incident}/edit', 'IncidentController@editIncidentAction');
+ $router->post('{incident}', [
+ 'as' => 'post:dashboard.incidents.edit',
+ 'uses' => 'IncidentController@editIncidentAction',
+ ]);
+ $router->delete('{incident}', [
+ 'as' => 'delete:dashboard.incidents.delete',
+ 'uses' => 'IncidentController@deleteIncidentAction',
+ ]);
+
+ $router->get('{incident}/updates', [
+ 'as' => 'get:dashboard.incidents.updates',
+ 'uses' => 'IncidentUpdateController@showIncidentUpdates',
+ ]);
+ $router->get('{incident}/updates/create', [
+ 'as' => 'get:dashboard.incidents.updates.create',
+ 'uses' => 'IncidentUpdateController@showCreateIncidentUpdateAction',
+ ]);
+ $router->post('{incident}/updates/create', [
+ 'as' => 'post:dashboard.incidents.updates.create',
+ 'uses' => 'IncidentUpdateController@createIncidentUpdateAction',
+ ]);
+ $router->get('{incident}/updates/{incident_update}', [
+ 'as' => 'get:dashboard.incidents.updates.edit',
+ 'uses' => 'IncidentUpdateController@showEditIncidentUpdateAction',
+ ]);
+ $router->post('{incident}/updates/{incident_update}', [
+ 'as' => 'post:dashboard.incidents.updates.edit',
+ 'uses' => 'IncidentUpdateController@editIncidentUpdateAction',
+ ]);
});
}
}
diff --git a/app/Http/Routes/Dashboard/MetricRoutes.php b/app/Http/Routes/Dashboard/MetricRoutes.php
index 295a51c574c4..3f28899d8664 100644
--- a/app/Http/Routes/Dashboard/MetricRoutes.php
+++ b/app/Http/Routes/Dashboard/MetricRoutes.php
@@ -21,6 +21,13 @@
*/
class MetricRoutes
{
+ /**
+ * Defines if these routes are for the browser.
+ *
+ * @var bool
+ */
+ public static $browser = true;
+
/**
* Define the dashboard metric routes.
*
@@ -31,26 +38,36 @@ class MetricRoutes
public function map(Registrar $router)
{
$router->group([
- 'middleware' => ['web', 'auth'],
+ 'middleware' => ['auth'],
'namespace' => 'Dashboard',
- 'as' => 'dashboard.metrics.',
'prefix' => 'dashboard/metrics',
], function (Registrar $router) {
$router->get('/', [
- 'as' => 'index',
+ 'as' => 'get:dashboard.metrics',
'uses' => 'MetricController@showMetrics',
]);
- $router->get('add', [
- 'as' => 'add',
+
+ $router->get('create', [
+ 'as' => 'get:dashboard.metrics.create',
'uses' => 'MetricController@showAddMetric',
]);
- $router->post('add', 'MetricController@createMetricAction');
- $router->delete('{metric}/delete', 'MetricController@deleteMetricAction');
- $router->get('{metric}/edit', [
- 'as' => 'edit',
+ $router->post('create', [
+ 'as' => 'post:dashboard.metrics.create',
+ 'uses' => 'MetricController@createMetricAction',
+ ]);
+
+ $router->get('{metric}', [
+ 'as' => 'get:dashboard.metrics.edit',
'uses' => 'MetricController@showEditMetricAction',
]);
- $router->post('{metric}/edit', 'MetricController@editMetricAction');
+ $router->post('{metric}', [
+ 'as' => 'post:dashboard.metrics.edit',
+ 'uses' => 'MetricController@editMetricAction',
+ ]);
+ $router->delete('{metric}', [
+ 'as' => 'delete:dashboard.metrics.delete',
+ 'uses' => 'MetricController@deleteMetricAction',
+ ]);
});
}
}
diff --git a/app/Http/Routes/Dashboard/ScheduleRoutes.php b/app/Http/Routes/Dashboard/ScheduleRoutes.php
index 4eb29c65a0f8..8591d1500c95 100644
--- a/app/Http/Routes/Dashboard/ScheduleRoutes.php
+++ b/app/Http/Routes/Dashboard/ScheduleRoutes.php
@@ -21,6 +21,13 @@
*/
class ScheduleRoutes
{
+ /**
+ * Defines if these routes are for the browser.
+ *
+ * @var bool
+ */
+ public static $browser = true;
+
/**
* Define the dashboard schedule routes.
*
@@ -31,27 +38,34 @@ class ScheduleRoutes
public function map(Registrar $router)
{
$router->group([
- 'middleware' => ['web', 'auth'],
+ 'middleware' => ['auth'],
'namespace' => 'Dashboard',
- 'as' => 'dashboard.schedule.',
'prefix' => 'dashboard/schedule',
], function (Registrar $router) {
$router->get('/', [
- 'as' => 'index',
+ 'as' => 'get:dashboard.schedule',
'uses' => 'ScheduleController@showIndex',
]);
- $router->get('add', [
- 'as' => 'add',
+
+ $router->get('create', [
+ 'as' => 'get:dashboard.schedule.create',
'uses' => 'ScheduleController@showAddSchedule',
]);
- $router->post('add', 'ScheduleController@addScheduleAction');
- $router->get('{incident}/edit', [
- 'as' => 'edit',
+ $router->post('create', [
+ 'as' => 'post:dashboard.schedule.create',
+ 'uses' => 'ScheduleController@addScheduleAction',
+ ]);
+
+ $router->get('{schedule}', [
+ 'as' => 'get:dashboard.schedule.edit',
'uses' => 'ScheduleController@showEditSchedule',
]);
- $router->post('{incident}/edit', 'ScheduleController@editScheduleAction');
- $router->delete('{incident}/delete', [
- 'as' => 'delete',
+ $router->post('{schedule}', [
+ 'as' => 'post:dashboard.schedule.edit',
+ 'uses' => 'ScheduleController@editScheduleAction',
+ ]);
+ $router->delete('{schedule}', [
+ 'as' => 'delete:dashboard.schedule.delete',
'uses' => 'ScheduleController@deleteScheduleAction',
]);
});
diff --git a/app/Http/Routes/Dashboard/SettingRoutes.php b/app/Http/Routes/Dashboard/SettingRoutes.php
index a48002f11846..a963470d7214 100644
--- a/app/Http/Routes/Dashboard/SettingRoutes.php
+++ b/app/Http/Routes/Dashboard/SettingRoutes.php
@@ -21,6 +21,13 @@
*/
class SettingRoutes
{
+ /**
+ * Defines if these routes are for the browser.
+ *
+ * @var bool
+ */
+ public static $browser = true;
+
/**
* Define the dashboard setting routes.
*
@@ -31,48 +38,63 @@ class SettingRoutes
public function map(Registrar $router)
{
$router->group([
- 'middleware' => ['web', 'auth'],
+ 'middleware' => ['auth'],
'namespace' => 'Dashboard',
- 'as' => 'dashboard.settings.',
'prefix' => 'dashboard/settings',
], function (Registrar $router) {
$router->get('setup', [
- 'as' => 'setup',
+ 'as' => 'get:dashboard.settings.setup',
'uses' => 'SettingsController@showSetupView',
]);
$router->get('analytics', [
- 'as' => 'analytics',
+ 'as' => 'get:dashboard.settings.analytics',
'uses' => 'SettingsController@showAnalyticsView',
]);
$router->get('localization', [
- 'as' => 'localization',
+ 'as' => 'get:dashboard.settings.localization',
'uses' => 'SettingsController@showLocalizationView',
]);
$router->get('security', [
- 'as' => 'security',
+ 'as' => 'get:dashboard.settings.security',
'uses' => 'SettingsController@showSecurityView',
]);
$router->get('theme', [
- 'as' => 'theme',
+ 'as' => 'get:dashboard.settings.theme',
'uses' => 'SettingsController@showThemeView',
]);
$router->get('stylesheet', [
- 'as' => 'stylesheet',
+ 'as' => 'get:dashboard.settings.stylesheet',
'uses' => 'SettingsController@showStylesheetView',
]);
$router->get('customization', [
- 'as' => 'customization',
+ 'as' => 'get:dashboard.settings.customization',
'uses' => 'SettingsController@showCustomizationView',
]);
$router->get('credits', [
- 'as' => 'credits',
+ 'as' => 'get:dashboard.settings.credits',
'uses' => 'SettingsController@showCreditsView',
]);
$router->get('log', [
- 'as' => 'log',
+ 'as' => 'get:dashboard.settings.log',
'uses' => 'SettingsController@showLogView',
]);
- $router->post('/', 'SettingsController@postSettings');
+ $router->get('mail', [
+ 'as' => 'get:dashboard.settings.mail',
+ 'uses' => 'SettingsController@showMailView',
+ ]);
+ $router->post('mail', [
+ 'as' => 'post:dashboard.settings.mail',
+ 'uses' => 'SettingsController@postMail',
+ ]);
+ $router->post('mail/test', [
+ 'as' => 'post:dashboard.settings.mail.test',
+ 'uses' => 'SettingsController@testMail',
+ ]);
+
+ $router->post('/', [
+ 'as' => 'post:dashboard.settings',
+ 'uses' => 'SettingsController@postSettings',
+ ]);
});
}
}
diff --git a/app/Http/Routes/Dashboard/SubscriberRoutes.php b/app/Http/Routes/Dashboard/SubscriberRoutes.php
index d2e804e0df35..129d786f8bd8 100644
--- a/app/Http/Routes/Dashboard/SubscriberRoutes.php
+++ b/app/Http/Routes/Dashboard/SubscriberRoutes.php
@@ -21,6 +21,13 @@
*/
class SubscriberRoutes
{
+ /**
+ * Defines if these routes are for the browser.
+ *
+ * @var bool
+ */
+ public static $browser = true;
+
/**
* Define the dashboard subscriber routes.
*
@@ -31,21 +38,28 @@ class SubscriberRoutes
public function map(Registrar $router)
{
$router->group([
- 'middleware' => ['web', 'auth'],
+ 'middleware' => ['auth'],
'namespace' => 'Dashboard',
- 'as' => 'dashboard.subscribers.',
'prefix' => 'dashboard/subscribers',
], function (Registrar $router) {
$router->get('/', [
- 'as' => 'index',
+ 'as' => 'get:dashboard.subscribers',
'uses' => 'SubscriberController@showSubscribers',
]);
- $router->get('add', [
- 'as' => 'add',
+
+ $router->get('create', [
+ 'as' => 'get:dashboard.subscribers.create',
'uses' => 'SubscriberController@showAddSubscriber',
]);
- $router->post('add', 'SubscriberController@createSubscriberAction');
- $router->delete('{subscriber}/delete', 'SubscriberController@deleteSubscriberAction');
+ $router->post('create', [
+ 'as' => 'post:dashboard.subscribers.create',
+ 'uses' => 'SubscriberController@createSubscriberAction',
+ ]);
+
+ $router->delete('{subscriber}/delete', [
+ 'as' => 'delete:dashboard.subscribers.delete',
+ 'uses' => 'SubscriberController@deleteSubscriberAction',
+ ]);
});
}
}
diff --git a/app/Http/Routes/Dashboard/TeamRoutes.php b/app/Http/Routes/Dashboard/TeamRoutes.php
index c7580501b189..8872859227a9 100644
--- a/app/Http/Routes/Dashboard/TeamRoutes.php
+++ b/app/Http/Routes/Dashboard/TeamRoutes.php
@@ -21,6 +21,13 @@
*/
class TeamRoutes
{
+ /**
+ * Defines if these routes are for the browser.
+ *
+ * @var bool
+ */
+ public static $browser = true;
+
/**
* Define the dashboard team routes.
*
@@ -31,30 +38,46 @@ class TeamRoutes
public function map(Registrar $router)
{
$router->group([
- 'middleware' => ['web', 'auth'],
+ 'middleware' => ['auth'],
'namespace' => 'Dashboard',
- 'as' => 'dashboard.team.',
'prefix' => 'dashboard/team',
], function (Registrar $router) {
$router->get('/', [
- 'as' => 'index',
+ 'as' => 'get:dashboard.team',
'uses' => 'TeamController@showTeamView',
]);
$router->group(['middleware' => 'admin'], function (Registrar $router) {
- $router->get('add', [
- 'as' => 'add',
+ $router->get('create', [
+ 'as' => 'get:dashboard.team.create',
'uses' => 'TeamController@showAddTeamMemberView',
]);
+ $router->post('create', [
+ 'as' => 'post:dashboard.team.create',
+ 'uses' => 'TeamController@postAddUser',
+ ]);
+
$router->get('invite', [
- 'as' => 'invite',
+ 'as' => 'get:dashboard.team.invite',
'uses' => 'TeamController@showInviteTeamMemberView',
]);
- $router->get('{user}', ['as' => 'edit', 'uses' => 'TeamController@showTeamMemberView']);
- $router->post('add', 'TeamController@postAddUser');
- $router->post('invite', 'TeamController@postInviteUser');
- $router->post('{user}', 'TeamController@postUpdateUser');
- $router->delete('{user}/delete', 'TeamController@deleteUser');
+ $router->post('invite', [
+ 'as' => 'post:dashboard.team.invite',
+ 'uses' => 'TeamController@postInviteUser',
+ ]);
+
+ $router->get('{user}', [
+ 'as' => 'get:dashboard.team.edit',
+ 'uses' => 'TeamController@showTeamMemberView',
+ ]);
+ $router->post('{user}', [
+ 'as' => 'post::dashboard.team.edit',
+ 'uses' => 'TeamController@postUpdateUser',
+ ]);
+ $router->delete('{user}', [
+ 'as' => 'delete:dashboard.team.delete',
+ 'uses' => 'TeamController@deleteUser',
+ ]);
});
});
}
diff --git a/app/Http/Routes/Dashboard/TemplateRoutes.php b/app/Http/Routes/Dashboard/TemplateRoutes.php
index 41abd4845c6f..ee4ed5df2699 100644
--- a/app/Http/Routes/Dashboard/TemplateRoutes.php
+++ b/app/Http/Routes/Dashboard/TemplateRoutes.php
@@ -21,6 +21,13 @@
*/
class TemplateRoutes
{
+ /**
+ * Defines if these routes are for the browser.
+ *
+ * @var bool
+ */
+ public static $browser = true;
+
/**
* Define the dashboard template routes.
*
@@ -31,26 +38,36 @@ class TemplateRoutes
public function map(Registrar $router)
{
$router->group([
- 'middleware' => ['web', 'auth'],
+ 'middleware' => ['auth'],
'namespace' => 'Dashboard',
- 'as' => 'dashboard.templates.',
'prefix' => 'dashboard/templates',
], function (Registrar $router) {
$router->get('/', [
- 'as' => 'index',
- 'uses' => 'IncidentController@showTemplates',
+ 'as' => 'get:dashboard.templates',
+ 'uses' => 'IncidentTemplateController@showTemplates',
+ ]);
+
+ $router->get('create', [
+ 'as' => 'get:dashboard.templates.create',
+ 'uses' => 'IncidentTemplateController@showAddIncidentTemplate',
+ ]);
+ $router->post('create', [
+ 'as' => 'post:dashboard.templates.create',
+ 'uses' => 'IncidentTemplateController@createIncidentTemplateAction',
+ ]);
+
+ $router->get('{incident_template}', [
+ 'as' => 'get:dashboard.templates.edit',
+ 'uses' => 'IncidentTemplateController@showEditTemplateAction',
]);
- $router->get('add', [
- 'as' => 'add',
- 'uses' => 'IncidentController@showAddIncidentTemplate',
+ $router->post('{incident_template}', [
+ 'as' => 'post:dashboard.templates.edit',
+ 'uses' => 'IncidentTemplateController@editTemplateAction',
]);
- $router->post('add', 'IncidentController@createIncidentTemplateAction');
- $router->get('{incident_template}/edit', [
- 'as' => 'edit',
- 'uses' => 'IncidentController@showEditTemplateAction',
+ $router->delete('{incident_template}', [
+ 'as' => 'delete:dashboard.templates.delete',
+ 'uses' => 'IncidentTemplateController@deleteTemplateAction',
]);
- $router->post('{incident_template}/edit', 'IncidentController@editTemplateAction');
- $router->delete('{incident_template}/delete', 'IncidentController@deleteTemplateAction');
});
}
}
diff --git a/app/Http/Routes/Dashboard/UserRoutes.php b/app/Http/Routes/Dashboard/UserRoutes.php
index c54a2ea6e574..15720a464461 100644
--- a/app/Http/Routes/Dashboard/UserRoutes.php
+++ b/app/Http/Routes/Dashboard/UserRoutes.php
@@ -21,6 +21,13 @@
*/
class UserRoutes
{
+ /**
+ * Defines if these routes are for the browser.
+ *
+ * @var bool
+ */
+ public static $browser = true;
+
/**
* Define the dashboard user routes.
*
@@ -31,17 +38,23 @@ class UserRoutes
public function map(Registrar $router)
{
$router->group([
- 'middleware' => ['web', 'auth'],
+ 'middleware' => ['auth'],
'namespace' => 'Dashboard',
- 'as' => 'dashboard.user.',
'prefix' => 'dashboard/user',
], function (Registrar $router) {
$router->get('/', [
- 'as' => 'user',
+ 'as' => 'get:dashboard.user',
'uses' => 'UserController@showUser',
]);
- $router->post('/', 'UserController@postUser');
- $router->get('{user}/api/regen', 'UserController@regenerateApiKey');
+ $router->post('/', [
+ 'as' => 'post:dashboard.user',
+ 'uses' => 'UserController@postUser',
+ ]);
+
+ $router->get('{user}/api/regen', [
+ 'as' => 'get:dashboard.user.api.regen',
+ 'uses' => 'UserController@regenerateApiKey',
+ ]);
});
}
}
diff --git a/app/Http/Routes/FeedRoutes.php b/app/Http/Routes/FeedRoutes.php
deleted file mode 100644
index f5d1f3ee6a5b..000000000000
--- a/app/Http/Routes/FeedRoutes.php
+++ /dev/null
@@ -1,43 +0,0 @@
-
- */
-class FeedRoutes
-{
- /**
- * Define the status page routes.
- *
- * @param \Illuminate\Contracts\Routing\Registrar $router
- *
- * @return void
- */
- public function map(Registrar $router)
- {
- $router->group(['middleware' => ['web', 'ready']], function (Registrar $router) {
- $router->get('/atom/{component_group?}', [
- 'as' => 'feed.atom',
- 'uses' => 'FeedController@atomAction',
- ]);
- $router->get('/rss/{component_group?}', [
- 'as' => 'feed.rss',
- 'uses' => 'FeedController@rssAction',
- ]);
- });
- }
-}
diff --git a/app/Http/Routes/Setup/ApiRoutes.php b/app/Http/Routes/Setup/ApiRoutes.php
new file mode 100644
index 000000000000..8a3a3897779c
--- /dev/null
+++ b/app/Http/Routes/Setup/ApiRoutes.php
@@ -0,0 +1,59 @@
+
+ */
+class ApiRoutes
+{
+ /**
+ * Defines if these routes are for the browser.
+ *
+ * @var bool
+ */
+ public static $browser = false;
+
+ /**
+ * Define the setup routes.
+ *
+ * @param \Illuminate\Contracts\Routing\Registrar $router
+ *
+ * @return void
+ */
+ public function map(Registrar $router)
+ {
+ $router->group([
+ 'middleware' => ['setup'],
+ 'prefix' => 'setup',
+ ], function (Registrar $router) {
+ $router->post('step1', [
+ 'as' => 'post:setup.step1',
+ 'uses' => 'SetupController@postStep1',
+ ]);
+
+ $router->post('step2', [
+ 'as' => 'post:setup.step2',
+ 'uses' => 'SetupController@postStep2',
+ ]);
+
+ $router->post('step3', [
+ 'as' => 'post:setup.step3',
+ 'uses' => 'SetupController@postStep3',
+ ]);
+ });
+ }
+}
diff --git a/app/Http/Routes/SetupRoutes.php b/app/Http/Routes/SetupRoutes.php
index d2a33515476b..eb1319546bda 100644
--- a/app/Http/Routes/SetupRoutes.php
+++ b/app/Http/Routes/SetupRoutes.php
@@ -21,6 +21,13 @@
*/
class SetupRoutes
{
+ /**
+ * Defines if these routes are for the browser.
+ *
+ * @var bool
+ */
+ public static $browser = true;
+
/**
* Define the setup routes.
*
@@ -30,11 +37,14 @@ class SetupRoutes
*/
public function map(Registrar $router)
{
- $router->group(['middleware' => ['web', 'setup']], function (Registrar $router) {
- $router->get('setup', 'SetupController@getIndex');
- $router->post('setup/step1', 'SetupController@postStep1');
- $router->post('setup/step2', 'SetupController@postStep2');
- $router->post('setup/step3', 'SetupController@postStep3');
+ $router->group([
+ 'middleware' => ['setup'],
+ 'prefix' => 'setup',
+ ], function (Registrar $router) {
+ $router->get('/', [
+ 'as' => 'get:setup',
+ 'uses' => 'SetupController@getIndex',
+ ]);
});
}
}
diff --git a/app/Http/Routes/SignupRoutes.php b/app/Http/Routes/SignupRoutes.php
index 8e9d7f466c21..8530726175a5 100644
--- a/app/Http/Routes/SignupRoutes.php
+++ b/app/Http/Routes/SignupRoutes.php
@@ -20,6 +20,13 @@
*/
class SignupRoutes
{
+ /**
+ * Defines if these routes are for the browser.
+ *
+ * @var bool
+ */
+ public static $browser = true;
+
/**
* Define the signup routes.
*
@@ -29,13 +36,17 @@ class SignupRoutes
*/
public function map(Registrar $router)
{
- $router->group(['middleware' => ['web', 'ready', 'guest'], 'as' => 'signup.'], function (Registrar $router) {
- $router->get('signup/invite/{code}', [
- 'as' => 'invite',
+ $router->group([
+ 'middleware' => ['ready', 'guest'],
+ 'prefix' => 'signup',
+ ], function (Registrar $router) {
+ $router->get('invite/{code}', [
+ 'as' => 'get:signup.invite',
'uses' => 'SignupController@getSignup',
]);
- $router->post('signup/invite/{code}', [
+ $router->post('invite/{code}', [
+ 'as' => 'post:signup.invite',
'uses' => 'SignupController@postSignup',
]);
});
diff --git a/app/Http/Routes/StatusPageRoutes.php b/app/Http/Routes/StatusPageRoutes.php
index ede2b7e1b695..20bd69089af8 100644
--- a/app/Http/Routes/StatusPageRoutes.php
+++ b/app/Http/Routes/StatusPageRoutes.php
@@ -20,6 +20,13 @@
*/
class StatusPageRoutes
{
+ /**
+ * Defines if these routes are for the browser.
+ *
+ * @var bool
+ */
+ public static $browser = true;
+
/**
* Define the status page routes.
*
@@ -29,23 +36,33 @@ class StatusPageRoutes
*/
public function map(Registrar $router)
{
- $router->group(['middleware' => ['web', 'ready', 'localize']], function (Registrar $router) {
+ $router->group([
+ 'middleware' => ['ready', 'localize'],
+ ], function (Registrar $router) {
$router->get('/', [
- 'as' => 'status-page',
+ 'as' => 'get:status-page',
'uses' => 'StatusPageController@showIndex',
]);
- $router->get('incident/{incident}', [
- 'as' => 'incident',
+ $router->get('incidents/{incident}', [
+ 'as' => 'get:incident',
'uses' => 'StatusPageController@showIncident',
]);
+ $router->get('schedules/{schedule}', [
+ 'as' => 'get:schedule',
+ 'uses' => 'StatusPageController@showSchedule',
+ ]);
+
$router->get('metrics/{metric}', [
- 'as' => 'metrics',
+ 'as' => 'get:metric',
'uses' => 'StatusPageController@getMetrics',
]);
- $router->get('component/{component}/shield', 'StatusPageController@showComponentBadge');
+ $router->get('component/{component}/shield', [
+ 'as' => 'get:component_shield',
+ 'uses' => 'StatusPageController@showComponentBadge',
+ ]);
});
}
}
diff --git a/app/Http/Routes/SubscribeRoutes.php b/app/Http/Routes/SubscribeRoutes.php
index cc0dc0f2aaef..8c5279d43e98 100644
--- a/app/Http/Routes/SubscribeRoutes.php
+++ b/app/Http/Routes/SubscribeRoutes.php
@@ -20,6 +20,13 @@
*/
class SubscribeRoutes
{
+ /**
+ * Defines if these routes are for the browser.
+ *
+ * @var bool
+ */
+ public static $browser = true;
+
/**
* Define the subscribe routes.
*
@@ -29,33 +36,36 @@ class SubscribeRoutes
*/
public function map(Registrar $router)
{
- $router->group(['middleware' => ['web', 'ready', 'localize', 'subscribers'], 'as' => 'subscribe.'], function (Registrar $router) {
+ $router->group([
+ 'middleware' => ['ready', 'localize', 'subscribers'],
+ ], function (Registrar $router) {
$router->get('subscribe', [
- 'as' => 'subscribe',
+ 'as' => 'get:subscribe',
'uses' => 'SubscribeController@showSubscribe',
]);
-
$router->post('subscribe', [
+ 'as' => 'post:subscribe',
'uses' => 'SubscribeController@postSubscribe',
]);
$router->get('subscribe/manage/{code}', [
- 'as' => 'manage',
- 'uses' => 'SubscribeController@showManage',
+ 'as' => 'get:subscribe.manage',
+ 'middleware' => ['signed'],
+ 'uses' => 'SubscribeController@showManage',
]);
-
$router->post('subscribe/manage/{code}', [
- 'as' => 'manage',
+ 'as' => 'post:subscribe.manage',
'uses' => 'SubscribeController@postManage',
]);
$router->get('subscribe/verify/{code}', [
- 'as' => 'verify',
- 'uses' => 'SubscribeController@getVerify',
+ 'as' => 'get:subscribe.verify',
+ 'middleware' => ['signed'],
+ 'uses' => 'SubscribeController@getVerify',
]);
$router->get('unsubscribe/{code}/{subscription?}', [
- 'as' => 'unsubscribe',
+ 'as' => 'get:subscribe.unsubscribe',
'uses' => 'SubscribeController@getUnsubscribe',
]);
});
diff --git a/app/Integrations/Contracts/System.php b/app/Integrations/Contracts/System.php
index e64f42627b40..a064e71065f1 100644
--- a/app/Integrations/Contracts/System.php
+++ b/app/Integrations/Contracts/System.php
@@ -25,10 +25,24 @@ interface System
*/
public function getStatus();
+ /**
+ * Determine if Cachet is allowed to send notifications to users, subscribers or third party tools.
+ *
+ * @return bool
+ */
+ public function canNotifySubscribers();
+
/**
* Get the cachet version.
*
* @return string
*/
public function getVersion();
+
+ /**
+ * Get the table prefix.
+ *
+ * @return string
+ */
+ public function getTablePrefix();
}
diff --git a/app/Integrations/Core/Beacon.php b/app/Integrations/Core/Beacon.php
index f3aba9b5282a..f4a283ab8354 100644
--- a/app/Integrations/Core/Beacon.php
+++ b/app/Integrations/Core/Beacon.php
@@ -14,14 +14,18 @@
use CachetHQ\Cachet\Bus\Events\Beacon\BeaconFailedToSendEvent;
use CachetHQ\Cachet\Bus\Events\Beacon\BeaconWasSentEvent;
use CachetHQ\Cachet\Integrations\Contracts\Beacon as BeaconContract;
+use CachetHQ\Cachet\Models\Action;
use CachetHQ\Cachet\Models\Component;
use CachetHQ\Cachet\Models\Incident;
use CachetHQ\Cachet\Models\Metric;
+use CachetHQ\Cachet\Models\Schedule;
+use CachetHQ\Cachet\Models\Tag;
use CachetHQ\Cachet\Models\User;
use CachetHQ\Cachet\Settings\Repository as Setting;
use Exception;
use GuzzleHttp\Client;
use Illuminate\Contracts\Config\Repository;
+use Illuminate\Support\Str;
/**
* This is the beacon class.
@@ -78,29 +82,27 @@ public function send()
return;
}
- if (!($contactEmail = User::admins()->active()->first()->email)) {
- $contactEmail = null;
- }
-
$setting = app(Setting::class);
if (!$installId = $setting->get('install_id', null)) {
- $installId = sha1(str_random(20));
+ $installId = sha1(Str::random(20));
$setting->set('install_id', $installId);
}
$payload = [
- 'install_id' => $installId,
- 'version' => CACHET_VERSION,
- 'docker' => $this->config->get('cachet.is_docker'),
- 'database' => $this->config->get('database.default'),
- 'contact_email' => $contactEmail,
- 'data' => [
+ 'install_id' => $installId,
+ 'version' => CACHET_VERSION,
+ 'docker' => $this->config->get('cachet.is_docker'),
+ 'database' => $this->config->get('database.default'),
+ 'data' => [
'components' => Component::all()->count(),
'incidents' => Incident::all()->count(),
'metrics' => Metric::all()->count(),
'users' => User::all()->count(),
+ 'actions' => Action::all()->count(),
+ 'tags' => Tag::all()->count(),
+ 'schedules' => Schedule::all()->count(),
],
];
@@ -111,7 +113,6 @@ public function send()
'json' => $payload,
]);
} catch (Exception $e) {
- // TODO: Log a warning that the beacon could not be sent.
event(new BeaconFailedToSendEvent());
return;
diff --git a/app/Integrations/Core/Credits.php b/app/Integrations/Core/Credits.php
index f962606244d0..e821c3b6f29b 100644
--- a/app/Integrations/Core/Credits.php
+++ b/app/Integrations/Core/Credits.php
@@ -16,6 +16,12 @@
use GuzzleHttp\Client;
use Illuminate\Contracts\Cache\Repository;
+/**
+ * This is the credits class.
+ *
+ * @author Graham Campbell
+ * @author James Brooks
+ */
class Credits implements CreditsContract
{
/**
diff --git a/app/Integrations/Core/Feed.php b/app/Integrations/Core/Feed.php
index 824bdb20f052..1ab93c4d02d4 100644
--- a/app/Integrations/Core/Feed.php
+++ b/app/Integrations/Core/Feed.php
@@ -28,7 +28,7 @@ class Feed implements FeedContract
*
* @var string
*/
- const URL = 'https://blog.alt-three.com/tag/cachet/rss';
+ const URL = 'https://alt-three.com/tag/cachet/rss';
/**
* The failed status indicator.
diff --git a/app/Integrations/Core/System.php b/app/Integrations/Core/System.php
index 77c55e5776c4..b1f7183c1e70 100644
--- a/app/Integrations/Core/System.php
+++ b/app/Integrations/Core/System.php
@@ -14,6 +14,9 @@
use CachetHQ\Cachet\Integrations\Contracts\System as SystemContract;
use CachetHQ\Cachet\Models\Component;
use CachetHQ\Cachet\Models\Incident;
+use CachetHQ\Cachet\Models\Schedule;
+use Illuminate\Contracts\Auth\Guard;
+use Illuminate\Contracts\Config\Repository;
/**
* This is the core system class.
@@ -22,6 +25,34 @@
*/
class System implements SystemContract
{
+ /**
+ * The illuminate config instance.
+ *
+ * @var \Illuminate\Contracts\Config\Repository
+ */
+ protected $config;
+
+ /**
+ * The illuminate guard instance.
+ *
+ * @var \Illuminate\Contracts\Auth\Guard
+ */
+ protected $auth;
+
+ /**
+ * Create a new system instance.
+ *
+ * @param \Illuminate\Contracts\Config\Repository $config
+ * @param \Illuminate\Contracts\Auth\Guard $auth
+ *
+ * @return void
+ */
+ public function __construct(Repository $config, Guard $auth)
+ {
+ $this->config = $config;
+ $this->auth = $auth;
+ }
+
/**
* Get the entire system status.
*
@@ -29,10 +60,12 @@ class System implements SystemContract
*/
public function getStatus()
{
- $enabledScope = Component::enabled();
- $totalComponents = $enabledScope->count();
- $majorOutages = $enabledScope->status(4)->count();
- $isMajorOutage = $totalComponents ? ($majorOutages / $totalComponents) >= 0.5 : false;
+ $includePrivate = $this->auth->check();
+
+ $totalComponents = Component::enabled()->authenticated($includePrivate)->count();
+ $majorOutages = Component::enabled()->authenticated($includePrivate)->status(4)->count();
+ $majorOutageRate = (int) $this->config->get('setting.major_outage_rate', '50');
+ $isMajorOutage = $totalComponents ? ($majorOutages / $totalComponents) * 100 >= $majorOutageRate : false;
// Default data
$status = [
@@ -47,27 +80,45 @@ public function getStatus()
'system_message' => trans_choice('cachet.service.major', $totalComponents),
'favicon' => 'favicon-high-alert',
];
- } elseif ($enabledScope->notStatus(1)->count() === 0) {
+ } elseif (Component::enabled()->authenticated($includePrivate)->notStatus(1)->count() === 0) {
// If all our components are ok, do we have any non-fixed incidents?
- $incidents = Incident::notScheduled()->orderBy('created_at', 'desc')->get()->filter(function ($incident) {
- return $incident->status > 0;
+ $incidents = Incident::orderBy('occurred_at', 'desc')->get()->filter(function ($incident) {
+ return $incident->status !== Incident::FIXED;
});
$incidentCount = $incidents->count();
+ $unresolvedCount = $incidents->filter(function ($incident) {
+ return !$incident->is_resolved;
+ })->count();
- if ($incidentCount === 0 || ($incidentCount >= 1 && (int) $incidents->first()->status === 4)) {
+ if ($incidentCount === 0 || ($incidentCount >= 1 && $unresolvedCount === 0)) {
$status = [
'system_status' => 'success',
'system_message' => trans_choice('cachet.service.good', $totalComponents),
'favicon' => 'favicon',
];
}
- } elseif ($enabledScope->whereIn('status', [2, 3])->count() > 0) {
+ } elseif (Component::enabled()->authenticated($includePrivate)->whereIn('status', [2, 3])->count() > 0) {
$status['favicon'] = 'favicon-medium-alert';
}
return $status;
}
+ /**
+ * Determine if Cachet is allowed to send notifications to users, subscribers or third party tools.
+ *
+ * @return bool
+ */
+ public function canNotifySubscribers()
+ {
+ $maintenancePeriods = Schedule::inProgress()->count();
+ if ($maintenancePeriods === 0) {
+ return true;
+ }
+
+ return !$this->config->get('setting.suppress_notifications_in_maintenance');
+ }
+
/**
* Get the cachet version.
*
@@ -77,4 +128,16 @@ public function getVersion()
{
return CACHET_VERSION;
}
+
+ /**
+ * Get the table prefix.
+ *
+ * @return string
+ */
+ public function getTablePrefix()
+ {
+ $driver = $this->config->get('database.default');
+
+ return $this->config->get("database.connections.{$driver}.prefix");
+ }
}
diff --git a/app/Models/Action.php b/app/Models/Action.php
new file mode 100644
index 000000000000..be9cfcc1de63
--- /dev/null
+++ b/app/Models/Action.php
@@ -0,0 +1,78 @@
+
+ * @author James Brooks
+ */
+class Action extends Model
+{
+ use ValidatingTrait;
+
+ /**
+ * The attributes that should be casted to native types.
+ *
+ * @var string[]
+ */
+ protected $casts = [
+ 'id' => 'int',
+ 'class_name' => 'string',
+ 'user_id' => 'int',
+ 'username' => 'string',
+ 'information' => 'string',
+ 'description' => 'string',
+ ];
+
+ /**
+ * A list of methods protected from mass assignment.
+ *
+ * @var string[]
+ */
+ protected $guarded = ['_token', '_method'];
+
+ /**
+ * The validation rules.
+ *
+ * @var string[]
+ */
+ public $rules = [
+ 'id' => 'nullable|int|min:1',
+ 'class_name' => 'required|string',
+ 'user_id' => 'required|int|min:1',
+ 'username' => 'required|string',
+ 'information' => 'nullable|string',
+ 'description' => 'required|string',
+ ];
+
+ /**
+ * The relations to eager load on every query.
+ *
+ * @var string[]
+ */
+ protected $with = ['user'];
+
+ /**
+ * Get the user relation.
+ *
+ * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
+ */
+ public function user()
+ {
+ return $this->belongsTo(User::class);
+ }
+}
diff --git a/app/Models/Component.php b/app/Models/Component.php
index dd87b64639d7..08da71576620 100644
--- a/app/Models/Component.php
+++ b/app/Models/Component.php
@@ -12,6 +12,8 @@
namespace CachetHQ\Cachet\Models;
use AltThree\Validator\ValidatingTrait;
+use CachetHQ\Cachet\Models\Traits\HasMeta;
+use CachetHQ\Cachet\Models\Traits\HasTags;
use CachetHQ\Cachet\Models\Traits\SearchableTrait;
use CachetHQ\Cachet\Models\Traits\SortableTrait;
use CachetHQ\Cachet\Presenters\ComponentPresenter;
@@ -22,7 +24,12 @@
class Component extends Model implements HasPresenter
{
- use SearchableTrait, SoftDeletes, SortableTrait, ValidatingTrait;
+ use HasTags;
+ use HasMeta;
+ use SearchableTrait;
+ use SoftDeletes;
+ use SortableTrait;
+ use ValidatingTrait;
/**
* List of attributes that have default values.
@@ -35,6 +42,7 @@ class Component extends Model implements HasPresenter
'description' => '',
'link' => '',
'enabled' => true,
+ 'meta' => null,
];
/**
@@ -50,6 +58,7 @@ class Component extends Model implements HasPresenter
'link' => 'string',
'group_id' => 'int',
'enabled' => 'bool',
+ 'meta' => 'json',
'deleted_at' => 'date',
];
@@ -62,11 +71,11 @@ class Component extends Model implements HasPresenter
'name',
'description',
'status',
- 'tags',
'link',
'order',
'group_id',
'enabled',
+ 'meta',
];
/**
@@ -75,9 +84,12 @@ class Component extends Model implements HasPresenter
* @var string[]
*/
public $rules = [
- 'name' => 'required|string',
- 'status' => 'int|required',
- 'link' => 'url',
+ 'name' => 'required|string',
+ 'status' => 'required|int',
+ 'order' => 'nullable|int',
+ 'group_id' => 'nullable|int',
+ 'link' => 'nullable|url',
+ 'enabled' => 'required|bool',
];
/**
@@ -128,16 +140,6 @@ public function incidents()
return $this->hasMany(Incident::class, 'component_id', 'id');
}
- /**
- * Get the tags relation.
- *
- * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
- */
- public function tags()
- {
- return $this->belongsToMany(Tag::class);
- }
-
/**
* Finds all components by status.
*
@@ -148,7 +150,7 @@ public function tags()
*/
public function scopeStatus(Builder $query, $status)
{
- return $query->where('status', $status);
+ return $query->where('status', '=', $status);
}
/**
@@ -173,7 +175,24 @@ public function scopeNotStatus(Builder $query, $status)
*/
public function scopeEnabled(Builder $query)
{
- return $query->where('enabled', true);
+ return $query->where('enabled', '=', true);
+ }
+
+ /**
+ * Find all components which are within visible groups.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $query
+ * @param bool $authenticated
+ *
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ public function scopeAuthenticated(Builder $query, $authenticated)
+ {
+ return $query->when(!$authenticated, function (Builder $query) {
+ return $query->whereDoesntHave('group', function (Builder $query) {
+ $query->where('visible', ComponentGroup::VISIBLE_AUTHENTICATED);
+ });
+ });
}
/**
@@ -185,21 +204,36 @@ public function scopeEnabled(Builder $query)
*/
public function scopeDisabled(Builder $query)
{
- return $query->where('enabled', false);
+ return $query->where('enabled', '=', false);
}
/**
- * Returns all of the tags on this component.
+ * Finds all ungrouped components.
*
- * @return string
+ * @param \Illuminate\Database\Eloquent\Builder $query
+ *
+ * @return \Illuminate\Database\Eloquent\Builder
*/
- public function getTagsListAttribute()
+ public function scopeUngrouped(Builder $query)
{
- $tags = $this->tags->map(function ($tag) {
- return $tag->name;
- });
+ return $query->enabled()
+ ->where('group_id', '=', 0)
+ ->orderBy('order')
+ ->orderBy('created_at');
+ }
- return implode(', ', $tags->toArray());
+ /**
+ * Finds all grouped components.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $query
+ *
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ public function scopeGrouped(Builder $query)
+ {
+ return $query->enabled()
+ ->where('group_id', '>', 0)
+ ->groupBy('group_id');
}
/**
diff --git a/app/Models/ComponentGroup.php b/app/Models/ComponentGroup.php
index 345f22101be5..f5a8af8ded56 100644
--- a/app/Models/ComponentGroup.php
+++ b/app/Models/ComponentGroup.php
@@ -15,12 +15,34 @@
use CachetHQ\Cachet\Models\Traits\SearchableTrait;
use CachetHQ\Cachet\Models\Traits\SortableTrait;
use CachetHQ\Cachet\Presenters\ComponentGroupPresenter;
+use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
+use Illuminate\Support\Collection;
use McCool\LaravelAutoPresenter\HasPresenter;
+/**
+ * This is the component group model class.
+ *
+ * @author James Brooks
+ */
class ComponentGroup extends Model implements HasPresenter
{
- use SearchableTrait, SortableTrait, ValidatingTrait;
+ use SearchableTrait;
+ use SortableTrait;
+ use ValidatingTrait;
+ /**
+ * Viewable only authenticated users.
+ *
+ * @var int
+ */
+ const VISIBLE_AUTHENTICATED = 0;
+
+ /**
+ * Viewable by public.
+ *
+ * @var int
+ */
+ const VISIBLE_GUEST = 1;
/**
* The model's attributes.
@@ -30,6 +52,7 @@ class ComponentGroup extends Model implements HasPresenter
protected $attributes = [
'order' => 0,
'collapsed' => 0,
+ 'visible' => 0,
];
/**
@@ -41,6 +64,7 @@ class ComponentGroup extends Model implements HasPresenter
'name' => 'string',
'order' => 'int',
'collapsed' => 'int',
+ 'visible' => 'int',
];
/**
@@ -48,7 +72,7 @@ class ComponentGroup extends Model implements HasPresenter
*
* @var string[]
*/
- protected $fillable = ['name', 'order', 'collapsed'];
+ protected $fillable = ['name', 'order', 'collapsed', 'visible'];
/**
* The validation rules.
@@ -57,8 +81,9 @@ class ComponentGroup extends Model implements HasPresenter
*/
public $rules = [
'name' => 'required|string',
- 'order' => 'int',
- 'collapsed' => 'int',
+ 'order' => 'required|int',
+ 'collapsed' => 'required|int|between:0,4',
+ 'visible' => 'required|bool',
];
/**
@@ -71,6 +96,7 @@ class ComponentGroup extends Model implements HasPresenter
'name',
'order',
'collapsed',
+ 'visible',
];
/**
@@ -83,6 +109,7 @@ class ComponentGroup extends Model implements HasPresenter
'name',
'order',
'collapsed',
+ 'visible',
];
/**
@@ -99,7 +126,7 @@ class ComponentGroup extends Model implements HasPresenter
*/
public function components()
{
- return $this->hasMany(Component::class, 'group_id', 'id')->orderBy('order');
+ return $this->hasMany(Component::class, 'group_id', 'id');
}
/**
@@ -119,7 +146,7 @@ public function incidents()
*/
public function enabled_components()
{
- return $this->components()->enabled();
+ return $this->components()->enabled()->orderBy('order');
}
/**
@@ -141,4 +168,30 @@ public function getPresenterClass()
{
return ComponentGroupPresenter::class;
}
+
+ /**
+ * Finds all component groups which are visible to public.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $query
+ *
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ public function scopeVisible(Builder $query)
+ {
+ return $query->where('visible', '=', self::VISIBLE_GUEST);
+ }
+
+ /**
+ * Finds all used component groups.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $query
+ * @param \Illuminate\Support\Collection $usedComponentGroups
+ *
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ public function scopeUsed(Builder $query, Collection $usedComponentGroups)
+ {
+ return $query->whereIn('id', $usedComponentGroups)
+ ->orderBy('order');
+ }
}
diff --git a/app/Models/Incident.php b/app/Models/Incident.php
index e89364c29f5f..b1ddb58c06a9 100644
--- a/app/Models/Incident.php
+++ b/app/Models/Incident.php
@@ -12,18 +12,78 @@
namespace CachetHQ\Cachet\Models;
use AltThree\Validator\ValidatingTrait;
+use CachetHQ\Cachet\Models\Traits\HasMeta;
+use CachetHQ\Cachet\Models\Traits\HasTags;
use CachetHQ\Cachet\Models\Traits\SearchableTrait;
use CachetHQ\Cachet\Models\Traits\SortableTrait;
use CachetHQ\Cachet\Presenters\IncidentPresenter;
-use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use McCool\LaravelAutoPresenter\HasPresenter;
+/**
+ * This is the incident model.
+ *
+ * @author James Brooks
+ * @author Joseph Cohen
+ * @author Graham Campbell
+ */
class Incident extends Model implements HasPresenter
{
- use SearchableTrait, SoftDeletes, SortableTrait, ValidatingTrait;
+ use HasMeta;
+ use HasTags;
+ use SearchableTrait;
+ use SoftDeletes;
+ use SortableTrait;
+ use ValidatingTrait;
+
+ /**
+ * Status for incident being investigated.
+ *
+ * @var int
+ */
+ const INVESTIGATING = 1;
+
+ /**
+ * Status for incident having been identified.
+ *
+ * @var int
+ */
+ const IDENTIFIED = 2;
+
+ /**
+ * Status for incident being watched.
+ *
+ * @var int
+ */
+ const WATCHED = 3;
+
+ /**
+ * Status for incident now being fixed.
+ *
+ * @var int
+ */
+ const FIXED = 4;
+
+ /**
+ * The accessors to append to the model's array form.
+ *
+ * @var string[]
+ */
+ protected $appends = [
+ 'is_resolved',
+ ];
+
+ /**
+ * The model's attributes.
+ *
+ * @var string[]
+ */
+ protected $attributes = [
+ 'stickied' => false,
+ 'notifications' => false,
+ ];
/**
* The attributes that should be casted to native types.
@@ -31,10 +91,14 @@ class Incident extends Model implements HasPresenter
* @var string[]
*/
protected $casts = [
- 'visible' => 'int',
- 'stickied' => 'int',
- 'scheduled_at' => 'date',
- 'deleted_at' => 'date',
+ 'component_id' => 'int',
+ 'status' => 'int',
+ 'user_id' => 'int',
+ 'visible' => 'int',
+ 'stickied' => 'bool',
+ 'notifications' => 'bool',
+ 'occurred_at' => 'datetime',
+ 'deleted_at' => 'date',
];
/**
@@ -43,13 +107,15 @@ class Incident extends Model implements HasPresenter
* @var string[]
*/
protected $fillable = [
+ 'user_id',
'component_id',
'name',
'status',
'visible',
'stickied',
+ 'notifications',
'message',
- 'scheduled_at',
+ 'occurred_at',
'created_at',
'updated_at',
];
@@ -60,12 +126,14 @@ class Incident extends Model implements HasPresenter
* @var string[]
*/
public $rules = [
- 'component_id' => 'int',
- 'name' => 'required',
- 'status' => 'required|int',
- 'visible' => 'required|bool',
- 'stickied' => 'bool',
- 'message' => 'required',
+ 'user_id' => 'nullable|int',
+ 'component_id' => 'nullable|int',
+ 'name' => 'required|string',
+ 'status' => 'required|int',
+ 'visible' => 'required|bool',
+ 'stickied' => 'required|bool',
+ 'notifications' => 'nullable|bool',
+ 'message' => 'required|string',
];
/**
@@ -75,6 +143,7 @@ class Incident extends Model implements HasPresenter
*/
protected $searchable = [
'id',
+ 'user_id',
'component_id',
'name',
'status',
@@ -89,11 +158,23 @@ class Incident extends Model implements HasPresenter
*/
protected $sortable = [
'id',
+ 'user_id',
'name',
'status',
'visible',
'stickied',
'message',
+ 'occurred_at',
+ ];
+
+ /**
+ * The relations to eager load on every query.
+ *
+ * @var string[]
+ */
+ protected $with = [
+ 'meta',
+ 'updates',
];
/**
@@ -107,65 +188,61 @@ public function component()
}
/**
- * Finds all visible incidents.
- *
- * @param \Illuminate\Database\Eloquent\Builder $query
+ * Get the updates relation.
*
- * @return \Illuminate\Database\Eloquent\Builder
+ * @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
- public function scopeVisible(Builder $query)
+ public function updates()
{
- return $query->where('visible', 1);
+ return $this->hasMany(IncidentUpdate::class)->orderBy('created_at', 'desc');
}
/**
- * Finds all stickied incidents.
+ * Get the user relation.
*
- * @param \Illuminate\Database\Eloquent\Builder $query
- *
- * @return \Illuminate\Database\Eloquent\Builder
+ * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
- public function scopeStickied(Builder $query)
+ public function user()
{
- return $query->where('stickied', true);
+ return $this->belongsTo(User::class);
}
/**
- * Finds all scheduled incidents (maintenance).
+ * Finds all visible incidents.
*
* @param \Illuminate\Database\Eloquent\Builder $query
*
* @return \Illuminate\Database\Eloquent\Builder
*/
- public function scopeScheduled(Builder $query)
+ public function scopeVisible(Builder $query)
{
- return $query->where('status', 0)->where('scheduled_at', '>=', Carbon::now()->toDateTimeString());
+ return $query->where('visible', '=', 1);
}
/**
- * Finds all non-scheduled incidents.
+ * Finds all stickied incidents.
*
* @param \Illuminate\Database\Eloquent\Builder $query
*
* @return \Illuminate\Database\Eloquent\Builder
*/
- public function scopeNotScheduled(Builder $query)
+ public function scopeStickied(Builder $query)
{
- return $query->where('status', '>', 0)->orWhere(function ($query) {
- $query->where('status', 0)->where(function ($query) {
- $query->whereNull('scheduled_at')->orWhere('scheduled_at', '<=', Carbon::now()->toDateTimeString());
- });
- });
+ return $query->where('stickied', '=', true);
}
/**
- * Returns whether the "incident" is scheduled or not.
+ * Is the incident resolved?
*
* @return bool
*/
- public function getIsScheduledAttribute()
+ public function getIsResolvedAttribute()
{
- return $this->getOriginal('scheduled_at') !== null;
+ if ($updates = $this->updates->first()) {
+ return (int) $updates->status === self::FIXED;
+ }
+
+ return (int) $this->status === self::FIXED;
}
/**
diff --git a/app/Models/IncidentComponent.php b/app/Models/IncidentComponent.php
new file mode 100644
index 000000000000..13218d152062
--- /dev/null
+++ b/app/Models/IncidentComponent.php
@@ -0,0 +1,78 @@
+
+ */
+class IncidentComponent extends Model
+{
+ use ValidatingTrait;
+
+ /**
+ * The attributes that should be casted to native types.
+ *
+ * @var string[]
+ */
+ protected $casts = [
+ 'incident_id' => 'int',
+ 'component_id' => 'int',
+ 'status_id' => 'int',
+ ];
+
+ /**
+ * The fillable properties.
+ *
+ * @var string[]
+ */
+ protected $fillable = [
+ 'incident_id',
+ 'component_id',
+ 'status_id',
+ ];
+
+ /**
+ * The validation rules.
+ *
+ * @var string[]
+ */
+ public $rules = [
+ 'incident_id' => 'required|int',
+ 'component_id' => 'required|int',
+ 'status_id' => 'required|int',
+ ];
+
+ /**
+ * Get the incident relation.
+ *
+ * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
+ */
+ public function incident()
+ {
+ return $this->belongsTo(Incident::class);
+ }
+
+ /**
+ * Get the component relation.
+ *
+ * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
+ */
+ public function component()
+ {
+ return $this->belongsTo(Component::class);
+ }
+}
diff --git a/app/Models/IncidentTemplate.php b/app/Models/IncidentTemplate.php
index bec5d4d34a32..88b833d3bd14 100644
--- a/app/Models/IncidentTemplate.php
+++ b/app/Models/IncidentTemplate.php
@@ -12,7 +12,6 @@
namespace CachetHQ\Cachet\Models;
use AltThree\Validator\ValidatingTrait;
-use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
@@ -27,6 +26,7 @@ class IncidentTemplate extends Model
*/
protected $casts = [
'name' => 'string',
+ 'slug' => 'string',
'template' => 'string',
];
@@ -35,7 +35,7 @@ class IncidentTemplate extends Model
*
* @var string[]
*/
- protected $fillable = ['name', 'template'];
+ protected $fillable = ['name', 'slug', 'template'];
/**
* The validation rules.
@@ -43,32 +43,38 @@ class IncidentTemplate extends Model
* @var string[]
*/
public $rules = [
- 'name' => 'required',
- 'template' => 'required',
+ 'name' => 'required|string',
+ 'template' => 'required|string',
];
/**
* Overrides the models boot method.
+ *
+ * @return void
*/
public static function boot()
{
parent::boot();
self::saving(function ($template) {
- $template->slug = Str::slug($template->name);
+ if (!$template->slug) {
+ $template->slug = Str::slug($template->name);
+ }
});
}
/**
* Finds a template by the slug.
*
- * @param \Illuminate\Database\Query\Builder $query
- * @param string $slug
+ * @param string $slug
+ * @param string[] $columns
*
* @return \Illuminate\Database\Query\Builder
*/
- public function scopeForSlug(Builder $query, $slug)
+ public static function forSlug($slug, $columns = ['*'])
{
- return $query->where('slug', $slug);
+ $template = static::where('slug', '=', $slug)->firstOrFail($columns);
+
+ return $template;
}
}
diff --git a/app/Models/IncidentUpdate.php b/app/Models/IncidentUpdate.php
new file mode 100644
index 000000000000..0591a248562a
--- /dev/null
+++ b/app/Models/IncidentUpdate.php
@@ -0,0 +1,106 @@
+
+ */
+class IncidentUpdate extends Model implements HasPresenter
+{
+ use SortableTrait;
+ use ValidatingTrait;
+
+ /**
+ * The attributes that should be casted to native types.
+ *
+ * @var string[]
+ */
+ protected $casts = [
+ 'incident_id' => 'int',
+ 'status' => 'int',
+ 'message' => 'string',
+ 'user_id' => 'int',
+ ];
+
+ /**
+ * The fillable properties.
+ *
+ * @var string[]
+ */
+ protected $fillable = [
+ 'incident_id',
+ 'status',
+ 'message',
+ 'user_id',
+ ];
+
+ /**
+ * The validation rules.
+ *
+ * @var string[]
+ */
+ public $rules = [
+ 'incident_id' => 'required|int',
+ 'status' => 'required|int',
+ 'message' => 'required|string',
+ 'user_id' => 'required|int',
+ ];
+
+ /**
+ * The sortable fields.
+ *
+ * @var string[]
+ */
+ protected $sortable = [
+ 'id',
+ 'status',
+ 'user_id',
+ ];
+
+ /**
+ * Get the incident relation.
+ *
+ * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
+ */
+ public function incident()
+ {
+ return $this->belongsTo(Incident::class);
+ }
+
+ /**
+ * Get the user relation.
+ *
+ * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
+ */
+ public function user()
+ {
+ return $this->belongsTo(User::class);
+ }
+
+ /**
+ * Get the presenter class.
+ *
+ * @return string
+ */
+ public function getPresenterClass()
+ {
+ return IncidentUpdatePresenter::class;
+ }
+}
diff --git a/app/Models/Invite.php b/app/Models/Invite.php
index a77bb4848e6d..292735c58495 100644
--- a/app/Models/Invite.php
+++ b/app/Models/Invite.php
@@ -12,9 +12,19 @@
namespace CachetHQ\Cachet\Models;
use Illuminate\Database\Eloquent\Model;
+use Illuminate\Notifications\Notifiable;
+use Illuminate\Support\Str;
+/**
+ * This is the invite class.
+ *
+ * @author Joseph Cohen
+ * @author James Brooks
+ */
class Invite extends Model
{
+ use Notifiable;
+
/**
* The attributes that should be casted to native types.
*
@@ -33,6 +43,8 @@ class Invite extends Model
/**
* Overrides the models boot method.
+ *
+ * @return void
*/
public static function boot()
{
@@ -40,21 +52,11 @@ public static function boot()
self::creating(function ($invite) {
if (!$invite->code) {
- $invite->code = self::generateInviteCode();
+ $invite->code = Str::random(20);
}
});
}
- /**
- * Returns an invite code.
- *
- * @return string
- */
- public static function generateInviteCode()
- {
- return str_random(20);
- }
-
/**
* Determines if the invite was claimed.
*
diff --git a/app/Models/Meta.php b/app/Models/Meta.php
new file mode 100644
index 000000000000..6c391d200ee2
--- /dev/null
+++ b/app/Models/Meta.php
@@ -0,0 +1,80 @@
+
+ */
+class Meta extends Model
+{
+ use ValidatingTrait;
+
+ /**
+ * The attributes that should be casted to native types.
+ *
+ * @var string[]
+ */
+ protected $casts = [
+ 'id' => 'int',
+ 'key' => 'string',
+ 'value' => 'json',
+ 'meta_id' => 'int',
+ 'meta_type' => 'string',
+ ];
+
+ /**
+ * The fillable properties.
+ *
+ * @var string[]
+ */
+ protected $fillable = [
+ 'key',
+ 'value',
+ 'meta_id',
+ 'meta_type',
+ ];
+
+ /**
+ * The validation rules.
+ *
+ * @var string[]
+ */
+ public $rules = [
+ 'id' => 'nullable|int|min:1',
+ 'key' => 'required|string',
+ 'value' => 'nullable',
+ 'meta_id' => 'required|int',
+ 'meta_type' => 'required|string',
+ ];
+
+ /**
+ * The table associated with the model.
+ *
+ * @var string
+ */
+ protected $table = 'meta';
+
+ /**
+ * Get all of the owning meta models.
+ *
+ * @return \Illuminate\Database\Eloquent\Relations\MorphTo
+ */
+ public function meta()
+ {
+ return $this->morphTo();
+ }
+}
diff --git a/app/Models/Metric.php b/app/Models/Metric.php
index db594c358d13..c3e6483ecfbd 100644
--- a/app/Models/Metric.php
+++ b/app/Models/Metric.php
@@ -12,15 +12,20 @@
namespace CachetHQ\Cachet\Models;
use AltThree\Validator\ValidatingTrait;
+use AltThree\Validator\ValidationException;
+use CachetHQ\Cachet\Models\Traits\HasMeta;
use CachetHQ\Cachet\Models\Traits\SortableTrait;
use CachetHQ\Cachet\Presenters\MetricPresenter;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
+use Illuminate\Support\MessageBag;
use McCool\LaravelAutoPresenter\HasPresenter;
class Metric extends Model implements HasPresenter
{
- use SortableTrait, ValidatingTrait;
+ use HasMeta;
+ use SortableTrait;
+ use ValidatingTrait;
/**
* The calculation type of sum.
@@ -36,6 +41,27 @@ class Metric extends Model implements HasPresenter
*/
const CALC_AVG = 1;
+ /**
+ * Viewable only authenticated users.
+ *
+ * @var int
+ */
+ const VISIBLE_AUTHENTICATED = 0;
+
+ /**
+ * Viewable by public.
+ *
+ * @var int
+ */
+ const VISIBLE_GUEST = 1;
+
+ /**
+ * Viewable by nobody.
+ *
+ * @var int
+ */
+ const VISIBLE_HIDDEN = 2;
+
/**
* The model's attributes.
*
@@ -50,6 +76,7 @@ class Metric extends Model implements HasPresenter
'default_view' => 1,
'threshold' => 5,
'order' => 0,
+ 'visible' => 1,
];
/**
@@ -66,6 +93,7 @@ class Metric extends Model implements HasPresenter
'default_view' => 'int',
'threshold' => 'int',
'order' => 'int',
+ 'visible' => 'int',
];
/**
@@ -84,6 +112,7 @@ class Metric extends Model implements HasPresenter
'default_view',
'threshold',
'order',
+ 'visible',
];
/**
@@ -94,12 +123,11 @@ class Metric extends Model implements HasPresenter
public $rules = [
'name' => 'required',
'suffix' => 'required',
- 'display_chart' => 'bool',
- 'default_value' => 'numeric',
- 'places' => 'numeric|between:0,4',
- 'default_view' => 'numeric|between:0,3',
- 'threshold' => 'numeric|between:0,10',
- 'threshold' => 'int',
+ 'display_chart' => 'required|bool',
+ 'default_value' => 'required|numeric',
+ 'places' => 'required|numeric|between:0,4',
+ 'default_view' => 'required|numeric|between:0,3',
+ 'visible' => 'required|numeric|between:0,2',
];
/**
@@ -114,8 +142,24 @@ class Metric extends Model implements HasPresenter
'default_value',
'calc_type',
'order',
+ 'visible',
];
+ /**
+ * Overrides the models boot method.
+ *
+ * @return void
+ */
+ public static function boot()
+ {
+ parent::boot();
+
+ // When deleting a metric, delete the points too.
+ self::deleting(function ($model) {
+ $model->points()->delete();
+ });
+ }
+
/**
* Get the points relation.
*
@@ -123,7 +167,7 @@ class Metric extends Model implements HasPresenter
*/
public function points()
{
- return $this->hasMany(MetricPoint::class, 'metric_id', 'id');
+ return $this->hasMany(MetricPoint::class, 'metric_id', 'id')->latest();
}
/**
@@ -135,7 +179,19 @@ public function points()
*/
public function scopeDisplayable(Builder $query)
{
- return $query->where('display_chart', 1);
+ return $query->where('display_chart', '=', true)->where('visible', '<>', self::VISIBLE_HIDDEN);
+ }
+
+ /**
+ * Finds all metrics which are visible to public.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $query
+ *
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ public function scopeVisible(Builder $query)
+ {
+ return $query->where('visible', '=', self::VISIBLE_GUEST);
}
/**
@@ -145,7 +201,27 @@ public function scopeDisplayable(Builder $query)
*/
public function getShouldDisplayAttribute()
{
- return $this->display_chart === 1;
+ return $this->display_chart;
+ }
+
+ /**
+ * Validate the model before save.
+ *
+ * @throws \AltThree\Validator\ValidationException
+ *
+ * @return void
+ */
+ public function validate()
+ {
+ $messages = [];
+
+ if (60 % $this->threshold !== 0) {
+ $messages[] = 'Threshold must divide by 60.';
+ }
+
+ if ($messages) {
+ throw new ValidationException(new MessageBag($messages));
+ }
}
/**
diff --git a/app/Models/MetricPoint.php b/app/Models/MetricPoint.php
index 2fbd024825ba..6e64940036ab 100644
--- a/app/Models/MetricPoint.php
+++ b/app/Models/MetricPoint.php
@@ -13,13 +13,31 @@
use AltThree\Validator\ValidatingTrait;
use CachetHQ\Cachet\Presenters\MetricPointPresenter;
+use Carbon\Carbon;
+use DateTime;
use Illuminate\Database\Eloquent\Model;
use McCool\LaravelAutoPresenter\HasPresenter;
+/**
+ * This is the metric point model class.
+ *
+ * @author James Brooks
+ * @author Joseph Cohen
+ * @author Graham Campbell
+ */
class MetricPoint extends Model implements HasPresenter
{
use ValidatingTrait;
+ /**
+ * The accessors to append to the model's array form.
+ *
+ * @var string[]
+ */
+ protected $appends = [
+ 'calculated_value',
+ ];
+
/**
* The model's attributes.
*
@@ -59,7 +77,7 @@ class MetricPoint extends Model implements HasPresenter
* @var string[]
*/
public $rules = [
- 'value' => 'numeric|required',
+ 'value' => 'required|numeric',
];
/**
@@ -73,21 +91,40 @@ public function metric()
}
/**
- * Override the value attribute.
+ * Show the actual calculated value; as per (value * counter).
*
- * @param mixed $value
+ * @return int
+ */
+ public function getCalculatedValueAttribute()
+ {
+ return $this->value * $this->counter;
+ }
+
+ /**
+ * Round the created at value into intervals of 30 seconds.
*
- * @return float
+ * @param string $createdAt
+ *
+ * @return string|void
*/
- public function getActiveValueAttribute($value)
+ public function setCreatedAtAttribute($createdAt)
{
- if ($this->metric->calc_type === Metric::CALC_SUM) {
- return round((float) $value * $this->counter, $this->metric->places);
- } elseif ($this->metric->calc_type === Metric::CALC_AVG) {
- return round((float) $value * $this->counter, $this->metric->places);
+ if (!$createdAt) {
+ return;
}
- return round((float) $value, $this->metric->places);
+ if (!$createdAt instanceof DateTime) {
+ $createdAt = Carbon::parse($createdAt);
+ }
+
+ $timestamp = $createdAt->format('U');
+ $timestamp = 30 * round($timestamp / 30);
+
+ $date = Carbon::createFromFormat('U', $timestamp)->toDateTimeString();
+
+ $this->attributes['created_at'] = $date;
+
+ return $date;
}
/**
diff --git a/app/Models/Schedule.php b/app/Models/Schedule.php
new file mode 100644
index 000000000000..93a7e3bbdf05
--- /dev/null
+++ b/app/Models/Schedule.php
@@ -0,0 +1,219 @@
+ self::UPCOMING,
+ 'completed_at' => null,
+ ];
+
+ /**
+ * The attributes that should be casted to native types.
+ *
+ * @var string[]
+ */
+ protected $casts = [
+ 'name' => 'string',
+ 'message' => 'string',
+ 'status' => 'int',
+ 'scheduled_at' => 'datetime',
+ 'completed_at' => 'datetime',
+ ];
+
+ /**
+ * The fillable properties.
+ *
+ * @var string[]
+ */
+ protected $fillable = [
+ 'name',
+ 'message',
+ 'status',
+ 'scheduled_at',
+ 'completed_at',
+ 'created_at',
+ 'updated_at',
+ ];
+
+ /**
+ * The validation rules.
+ *
+ * @var string[]
+ */
+ public $rules = [
+ 'name' => 'required|string',
+ 'message' => 'nullable|string',
+ 'status' => 'required|int|between:0,2',
+ ];
+
+ /**
+ * The searchable fields.
+ *
+ * @var string[]
+ */
+ protected $searchable = [
+ 'id',
+ 'name',
+ 'status',
+ ];
+
+ /**
+ * The sortable fields.
+ *
+ * @var string[]
+ */
+ protected $sortable = [
+ 'id',
+ 'name',
+ 'status',
+ 'scheduled_at',
+ 'completed_at',
+ 'created_at',
+ 'updated_at',
+ ];
+
+ /**
+ * The relations to eager load on every query.
+ *
+ * @var string[]
+ */
+ protected $with = ['components'];
+
+ /**
+ * Get the components relation.
+ *
+ * @return \Illuminate\Database\Eloquent\Relations\HasMany
+ */
+ public function components()
+ {
+ return $this->hasMany(ScheduleComponent::class);
+ }
+
+ /**
+ * Scope schedules that are uncompleted.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $query
+ *
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ public function scopeUncompleted(Builder $query)
+ {
+ return $query->whereIn('status', [self::UPCOMING, self::IN_PROGRESS])->where(function (Builder $query) {
+ return $query->whereNull('completed_at');
+ });
+ }
+
+ /**
+ * Scope schedules that are in progress.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $query
+ *
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ public function scopeInProgress(Builder $query)
+ {
+ return $query->where('scheduled_at', '<=', Carbon::now())->where('status', '<>', self::COMPLETE)->where(function ($query) {
+ $query->whereNull('completed_at');
+ });
+ }
+
+ /**
+ * Scopes schedules to those in the future.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $query
+ *
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ public function scopeScheduledInFuture($query)
+ {
+ return $query->whereIn('status', [self::UPCOMING, self::IN_PROGRESS])->where('scheduled_at', '>=', Carbon::now());
+ }
+
+ /**
+ * Scopes schedules to those scheduled in the past.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $query
+ *
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ public function scopeScheduledInPast($query)
+ {
+ return $query->whereIn('status', [self::UPCOMING, self::IN_PROGRESS])->where('scheduled_at', '<=', Carbon::now());
+ }
+
+ /**
+ * Scopes schedules to those completed in the past.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $query
+ *
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ public function scopeCompletedInPast($query)
+ {
+ return $query->where('status', '=', self::COMPLETE)->where('completed_at', '<=', Carbon::now());
+ }
+
+ /**
+ * Get the presenter class.
+ *
+ * @return string
+ */
+ public function getPresenterClass()
+ {
+ return SchedulePresenter::class;
+ }
+}
diff --git a/app/Models/ScheduleComponent.php b/app/Models/ScheduleComponent.php
new file mode 100644
index 000000000000..a77abcd27810
--- /dev/null
+++ b/app/Models/ScheduleComponent.php
@@ -0,0 +1,73 @@
+ 'int',
+ 'component_id' => 'int',
+ 'component_status' => 'int',
+ ];
+
+ /**
+ * The fillable properties.
+ *
+ * @var string[]
+ */
+ protected $fillable = [
+ 'schedule_id',
+ 'component_id',
+ 'component_status',
+ ];
+
+ /**
+ * The validation rules.
+ *
+ * @var string[]
+ */
+ public $rules = [
+ 'schedule_id' => 'required|int',
+ 'component_id' => 'required|int',
+ 'component_status' => 'required|int',
+ ];
+
+ /**
+ * Get the schedule relation.
+ *
+ * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
+ */
+ public function schedule()
+ {
+ return $this->belongsTo(Schedule::class);
+ }
+
+ /**
+ * Get the component relation.
+ *
+ * @return \Illuminate\Database\Eloquent\Relations\HasOne
+ */
+ public function component()
+ {
+ return $this->hasOne(Component::class);
+ }
+}
diff --git a/app/Models/Setting.php b/app/Models/Setting.php
index 0ea02148e129..54ea2b77a139 100644
--- a/app/Models/Setting.php
+++ b/app/Models/Setting.php
@@ -15,6 +15,13 @@
class Setting extends Model
{
+ /**
+ * List of attributes that have default values.
+ *
+ * @var string[]
+ */
+ protected $attributes = ['value' => ''];
+
/**
* The attributes that should be casted to native types.
*
@@ -31,11 +38,4 @@ class Setting extends Model
* @var string[]
*/
protected $fillable = ['name', 'value'];
-
- /**
- * List of attributes that have default values.
- *
- * @var string[]
- */
- protected $attributes = ['value' => ''];
}
diff --git a/app/Models/Subscriber.php b/app/Models/Subscriber.php
index e2f3fe4bc4d5..e10a093b16a1 100644
--- a/app/Models/Subscriber.php
+++ b/app/Models/Subscriber.php
@@ -12,13 +12,25 @@
namespace CachetHQ\Cachet\Models;
use AltThree\Validator\ValidatingTrait;
+use CachetHQ\Cachet\Models\Traits\HasMeta;
use CachetHQ\Cachet\Presenters\SubscriberPresenter;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
+use Illuminate\Notifications\Notifiable;
+use Illuminate\Support\Str;
use McCool\LaravelAutoPresenter\HasPresenter;
+/**
+ * This is the subscriber model.
+ *
+ * @author Joseph Cohen
+ * @author James Brooks
+ * @author Graham Campbell
+ */
class Subscriber extends Model implements HasPresenter
{
+ use HasMeta;
+ use Notifiable;
use ValidatingTrait;
/**
@@ -27,10 +39,12 @@ class Subscriber extends Model implements HasPresenter
* @var string[]
*/
protected $casts = [
- 'email' => 'string',
- 'verify_code' => 'string',
- 'verified_at' => 'date',
- 'global' => 'bool',
+ 'email' => 'string',
+ 'phone_number' => 'string',
+ 'slack_webhook_url' => 'string',
+ 'verify_code' => 'string',
+ 'verified_at' => 'date',
+ 'global' => 'bool',
];
/**
@@ -38,7 +52,13 @@ class Subscriber extends Model implements HasPresenter
*
* @var string[]
*/
- protected $fillable = ['email'];
+ protected $fillable = [
+ 'email',
+ 'phone_number',
+ 'slack_webhook_url',
+ 'verified_at',
+ 'global',
+ ];
/**
* The validation rules.
@@ -46,7 +66,9 @@ class Subscriber extends Model implements HasPresenter
* @var string[]
*/
public $rules = [
- 'email' => 'required|email',
+ 'email' => 'nullable|email',
+ 'phone_number' => 'nullable|string',
+ 'slack_webhook_url' => 'nullable|url',
];
/**
@@ -58,6 +80,8 @@ class Subscriber extends Model implements HasPresenter
/**
* Overrides the models boot method.
+ *
+ * @return void
*/
public static function boot()
{
@@ -101,7 +125,7 @@ public function scopeIsVerified(Builder $query)
*/
public function scopeIsGlobal(Builder $query)
{
- return $query->where('global', true);
+ return $query->where('global', '=', true);
}
/**
@@ -116,7 +140,7 @@ public function scopeForComponent(Builder $query, $component_id)
{
return $query->select('subscribers.*')
->join('subscriptions', 'subscribers.id', '=', 'subscriptions.subscriber_id')
- ->where('subscriptions.component_id', $component_id);
+ ->where('subscriptions.component_id', '=', $component_id);
}
/**
@@ -136,7 +160,27 @@ public function getIsVerifiedAttribute()
*/
public static function generateVerifyCode()
{
- return str_random(42);
+ return Str::random(42);
+ }
+
+ /**
+ * Route notifications for the Nexmo channel.
+ *
+ * @return string
+ */
+ public function routeNotificationForNexmo()
+ {
+ return $this->phone_number;
+ }
+
+ /**
+ * Route notifications for the Slack channel.
+ *
+ * @return string
+ */
+ public function routeNotificationForSlack()
+ {
+ return $this->slack_webhook_url;
}
/**
diff --git a/app/Models/Subscription.php b/app/Models/Subscription.php
index fb7872a3bcaa..c878c3c2add2 100644
--- a/app/Models/Subscription.php
+++ b/app/Models/Subscription.php
@@ -45,8 +45,8 @@ class Subscription extends Model
* @var string[]
*/
public $rules = [
- 'subscriber_id' => 'int|required',
- 'component_id' => 'int',
+ 'subscriber_id' => 'required|int',
+ 'component_id' => 'nullable|int',
];
/**
@@ -79,7 +79,7 @@ public function component()
*/
public function scopeForSubscriber(Builder $query, $subscriber_id)
{
- return $query->where('subscriber_id', $subscriber_id);
+ return $query->where('subscriber_id', '=', $subscriber_id);
}
/**
@@ -92,7 +92,7 @@ public function scopeForSubscriber(Builder $query, $subscriber_id)
*/
public function scopeForComponent(Builder $query, $component_id)
{
- return $query->where('component_id', $component_id);
+ return $query->where('component_id', '=', $component_id);
}
/**
@@ -108,7 +108,7 @@ public function scopeIsVerifiedForComponent(Builder $query, $component_id)
return $query->select('subscriptions.*')
->join('subscribers', 'subscriptions.subscriber_id', '=', 'subscribers.id')
->where(function ($query) {
- $query->where('subscriptions.component_id', $component_id)
+ $query->where('subscriptions.component_id', '=', $component_id)
->orWhere('subscribers.global');
})
->whereNotNull('subscribers.verified_at');
diff --git a/app/Models/Tag.php b/app/Models/Tag.php
index 3c85dfc341bd..022ceb8c528f 100644
--- a/app/Models/Tag.php
+++ b/app/Models/Tag.php
@@ -34,6 +34,8 @@ class Tag extends Model
/**
* Overrides the models boot method.
+ *
+ * @return void
*/
public static function boot()
{
@@ -53,4 +55,31 @@ public function components()
{
return $this->belongsToMany(Component::class);
}
+
+ /**
+ * @param array|\ArrayAccess $values
+ *
+ * @return \CachetHQ\Cachet\Models\Tag|static
+ */
+ public static function findOrCreate($values)
+ {
+ $tags = collect($values)->map(function ($value) {
+ if ($value instanceof self) {
+ return $value;
+ }
+
+ $tag = static::where('name', '=', $value)->first();
+
+ if (!$tag instanceof self) {
+ $tag = static::create([
+ 'name' => $value,
+ 'slug' => Str::slug($value),
+ ]);
+ }
+
+ return $tag;
+ });
+
+ return is_string($values) ? $tags->first() : $tags;
+ }
}
diff --git a/app/Models/Traits/HasMeta.php b/app/Models/Traits/HasMeta.php
new file mode 100644
index 000000000000..3571cf0a7e65
--- /dev/null
+++ b/app/Models/Traits/HasMeta.php
@@ -0,0 +1,32 @@
+
+ */
+trait HasMeta
+{
+ /**
+ * Get the meta relation.
+ *
+ * @return \Illuminate\Database\Eloquent\Relations\MorphMany
+ */
+ public function meta()
+ {
+ return $this->morphMany(Meta::class, 'meta');
+ }
+}
diff --git a/app/Models/Traits/HasTags.php b/app/Models/Traits/HasTags.php
new file mode 100644
index 000000000000..b707e050ff79
--- /dev/null
+++ b/app/Models/Traits/HasTags.php
@@ -0,0 +1,196 @@
+
+ */
+trait HasTags
+{
+ /**
+ * @var array
+ */
+ protected $queuedTags = [];
+
+ /**
+ * Boot the trait.
+ *
+ * @return void
+ */
+ public static function bootHasTags()
+ {
+ static::created(function (Model $taggableModel) {
+ if (count($taggableModel->queuedTags) > 0) {
+ $taggableModel->attachTags($taggableModel->queuedTags);
+
+ $taggableModel->queuedTags = [];
+ }
+ });
+
+ static::deleted(function (Model $deletedModel) {
+ $tags = $deletedModel->tags()->get();
+
+ $deletedModel->detachTags($tags);
+ });
+ }
+
+ /**
+ * Get the tags relation.
+ *
+ * @return \Illuminate\Database\Eloquent\Relations\MorphToMany
+ */
+ public function tags()
+ {
+ return $this->morphToMany(Tag::class, 'taggable');
+ }
+
+ /**
+ * @param string|array|\ArrayAccess|\CachetHQ\Cachet\Models\Tag $tags
+ */
+ public function setTagsAttribute($tags)
+ {
+ if (!$this->exists) {
+ $this->queuedTags = $tags;
+
+ return;
+ }
+
+ $this->attachTags($tags);
+ }
+
+ /**
+ * @param \Illuminate\Database\Eloquent\Builder $query
+ * @param array|\ArrayAccess $tags
+ *
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ public function scopeWithAllTags(Builder $query, $tags)
+ {
+ $tags = static::convertToTags($tags);
+
+ $tags->each(function ($tag) use ($query) {
+ $query->whereHas('tags', function (Builder $query) use ($tag) {
+ return $query->where('tags.id', $tag ? $tag->id : 0);
+ });
+ });
+
+ return $query;
+ }
+
+ /**
+ * @param \Illuminate\Database\Eloquent\Builder $query
+ * @param array|\ArrayAccess $tags
+ *
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ public function scopeWithAnyTags(Builder $query, $tags)
+ {
+ $tags = static::convertToTags($tags);
+
+ return $query->whereHas('tags', function (Builder $query) use ($tags) {
+ $tagIds = collect($tags)->pluck('id');
+
+ $query->whereIn('tags.id', $tagIds);
+ });
+ }
+
+ /**
+ * @param array|\ArrayAccess|\CachetHQ\Cachet\Models\Tag $tags
+ *
+ * @return $this
+ */
+ public function attachTags($tags)
+ {
+ $tags = collect(Tag::findOrCreate($tags));
+
+ $this->tags()->syncWithoutDetaching($tags->pluck('id')->toArray());
+
+ return $this;
+ }
+
+ /**
+ * @param string|\CachetHQ\Cachet\Models\Tag $tag
+ *
+ * @return $this
+ */
+ public function attachTag($tag)
+ {
+ return $this->attachTags([$tag]);
+ }
+
+ /**
+ * @param array|\ArrayAccess $tags
+ *
+ * @return $this
+ */
+ public function detachTags($tags)
+ {
+ $tags = static::convertToTags($tags);
+
+ collect($tags)
+ ->filter()
+ ->each(function (Tag $tag) {
+ $this->tags()->detach($tag);
+ });
+
+ return $this;
+ }
+
+ /**
+ * @param string|\CachetHQ\Cachet\Models\Tag $tag
+ *
+ * @return $this
+ */
+ public function detachTag($tag)
+ {
+ return $this->detachTags([$tag]);
+ }
+
+ /**
+ * @param array|\ArrayAccess $tags
+ *
+ * @return $this
+ */
+ public function syncTags($tags)
+ {
+ $tags = collect(Tag::findOrCreate($tags));
+
+ $this->tags()->sync($tags->pluck('id')->toArray());
+
+ return $this;
+ }
+
+ /**
+ * Convert a list of tags into a collection of \CachetHQ\Cachet\Models\Tag.
+ *
+ * @param array|\ArrayAccess $values
+ *
+ * @return \Illuminate\Support\Collection
+ */
+ protected static function convertToTags($values)
+ {
+ return collect($values)->map(function ($value) {
+ if ($value instanceof Tag) {
+ return $value;
+ }
+
+ return Tag::where('slug', '=', $value)->first();
+ });
+ }
+}
diff --git a/app/Models/User.php b/app/Models/User.php
index 89d88321cd0b..7e568bd05108 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -12,24 +12,22 @@
namespace CachetHQ\Cachet\Models;
use AltThree\Validator\ValidatingTrait;
-use Illuminate\Auth\Authenticatable;
-use Illuminate\Auth\Passwords\CanResetPassword;
-use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
-use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
-use Illuminate\Database\Eloquent\ModelNotFoundException;
+use Illuminate\Foundation\Auth\User as Authenticatable;
+use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Facades\Hash;
+use Illuminate\Support\Str;
/**
* This is the user model.
*
* @author James Brooks
*/
-class User extends Model implements AuthenticatableContract, CanResetPasswordContract
+class User extends Authenticatable
{
- use Authenticatable, CanResetPassword, ValidatingTrait;
-
+ use Notifiable;
+ use ValidatingTrait;
/**
* The admin level of user.
*
@@ -113,6 +111,8 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
/**
* Overrides the models boot method.
+ *
+ * @return void
*/
public static function boot()
{
@@ -134,7 +134,7 @@ public static function boot()
*/
public function scopeAdmins(Builder $query)
{
- return $query->where('level', self::LEVEL_ADMIN);
+ return $query->where('level', '=', self::LEVEL_ADMIN);
}
/**
@@ -146,7 +146,7 @@ public function scopeAdmins(Builder $query)
*/
public function scopeActive(Builder $query)
{
- return $query->where('active', true);
+ return $query->where('active', '=', true);
}
/**
@@ -163,18 +163,6 @@ public function setPasswordAttribute($password)
return $this;
}
- /**
- * Returns a Gravatar URL for the users email address.
- *
- * @param int $size
- *
- * @return string
- */
- public function getGravatarAttribute($size = 200)
- {
- return sprintf('https://www.gravatar.com/avatar/%s?size=%d', md5($this->email), $size);
- }
-
/**
* Find by api_key, or throw an exception.
*
@@ -187,11 +175,7 @@ public function getGravatarAttribute($size = 200)
*/
public static function findByApiToken($token, $columns = ['*'])
{
- $user = static::where('api_key', $token)->first($columns);
-
- if (!$user) {
- throw new ModelNotFoundException();
- }
+ $user = static::where('api_key', $token)->firstOrFail($columns);
return $user;
}
@@ -203,7 +187,7 @@ public static function findByApiToken($token, $columns = ['*'])
*/
public static function generateApiKey()
{
- return str_random(20);
+ return Str::random(20);
}
/**
diff --git a/app/Notifications/Component/ComponentStatusChangedNotification.php b/app/Notifications/Component/ComponentStatusChangedNotification.php
new file mode 100644
index 000000000000..02d02d4ac3a4
--- /dev/null
+++ b/app/Notifications/Component/ComponentStatusChangedNotification.php
@@ -0,0 +1,155 @@
+
+ */
+class ComponentStatusChangedNotification extends Notification
+{
+ use Queueable;
+
+ /**
+ * The component that changed.
+ *
+ * @var \CachetHQ\Cachet\Models\Component
+ */
+ protected $component;
+
+ /**
+ * The component status we're now at.
+ *
+ * @var int
+ */
+ protected $status;
+
+ /**
+ * Create a new notification instance.
+ *
+ * @param \CachetHQ\Cachet\Models\Component $component
+ * @param int $status
+ *
+ * @return void
+ */
+ public function __construct(Component $component, $status)
+ {
+ $this->component = AutoPresenter::decorate($component);
+ $this->status = $status;
+ }
+
+ /**
+ * Get the notification's delivery channels.
+ *
+ * @param mixed $notifiable
+ *
+ * @return string[]
+ */
+ public function via($notifiable)
+ {
+ return ['mail', 'nexmo', 'slack'];
+ }
+
+ /**
+ * Get the mail representation of the notification.
+ *
+ * @param mixed $notifiable
+ *
+ * @return \Illuminate\Notifications\Messages\MailMessage
+ */
+ public function toMail($notifiable)
+ {
+ $content = trans('notifications.component.status_update.mail.content', [
+ 'name' => $this->component->name,
+ 'old_status' => $this->component->human_status,
+ 'new_status' => trans("cachet.components.status.{$this->status}"),
+ ]);
+
+ return (new MailMessage())
+ ->subject(trans('notifications.component.status_update.mail.subject'))
+ ->markdown('notifications.component.update', [
+ 'componentName' => $this->component->name,
+ 'content' => $content,
+ 'unsubscribeText' => trans('cachet.subscriber.unsubscribe'),
+ 'unsubscribeUrl' => cachet_route('subscribe.unsubscribe', $notifiable->verify_code),
+ 'manageSubscriptionText' => trans('cachet.subscriber.manage_subscription'),
+ 'manageSubscriptionUrl' => cachet_route('subscribe.manage', $notifiable->verify_code),
+ ]);
+ }
+
+ /**
+ * Get the Nexmo / SMS representation of the notification.
+ *
+ * @param mixed $notifiable
+ *
+ * @return \Illuminate\Notifications\Messages\NexmoMessage
+ */
+ public function toNexmo($notifiable)
+ {
+ $content = trans('notifications.component.status_update.sms.content', [
+ 'name' => $this->component->name,
+ 'old_status' => $this->component->human_status,
+ 'new_status' => trans("cachet.components.status.{$this->status}"),
+ ]);
+
+ return (new NexmoMessage())->content($content);
+ }
+
+ /**
+ * Get the Slack representation of the notification.
+ *
+ * @param mixed $notifiable
+ *
+ * @return \Illuminate\Notifications\Messages\SlackMessage
+ */
+ public function toSlack($notifiable)
+ {
+ $content = trans('notifications.component.status_update.slack.content', [
+ 'name' => $this->component->name,
+ 'old_status' => $this->component->human_status,
+ 'new_status' => trans("cachet.components.status.{$this->status}"),
+ ]);
+
+ $status = 'info';
+
+ if ($this->status <= 1) {
+ $status = 'success';
+ } elseif ($this->status === 2) {
+ $status = 'warning';
+ } elseif ($this->status >= 3) {
+ $status = 'error';
+ }
+
+ return (new SlackMessage())
+ ->$status()
+ ->content(trans('notifications.component.status_update.slack.title'))
+ ->attachment(function ($attachment) use ($content, $notifiable) {
+ $attachment->title($content, cachet_route('status-page'))
+ ->fields(array_filter([
+ 'Component' => $this->component->name,
+ 'Old Status' => $this->component->human_status,
+ 'New Status' => trans("cachet.components.status.{$this->status}"),
+ 'Link' => $this->component->link,
+ ]))
+ ->footer(trans('cachet.subscriber.unsubscribe', ['link' => cachet_route('subscribe.unsubscribe', $notifiable->verify_code)]));
+ });
+ }
+}
diff --git a/app/Notifications/Incident/NewIncidentNotification.php b/app/Notifications/Incident/NewIncidentNotification.php
new file mode 100644
index 000000000000..ac56c9dea95a
--- /dev/null
+++ b/app/Notifications/Incident/NewIncidentNotification.php
@@ -0,0 +1,139 @@
+
+ */
+class NewIncidentNotification extends Notification
+{
+ use Queueable;
+
+ /**
+ * The incident.
+ *
+ * @var \CachetHQ\Cachet\Models\Incident
+ */
+ protected $incident;
+
+ /**
+ * Create a new notification instance.
+ *
+ * @param \CachetHQ\Cachet\Models\Incident $incident
+ *
+ * @return void
+ */
+ public function __construct(Incident $incident)
+ {
+ $this->incident = AutoPresenter::decorate($incident);
+ }
+
+ /**
+ * Get the notification's delivery channels.
+ *
+ * @param mixed $notifiable
+ *
+ * @return string[]
+ */
+ public function via($notifiable)
+ {
+ return ['mail', 'nexmo', 'slack'];
+ }
+
+ /**
+ * Get the mail representation of the notification.
+ *
+ * @param mixed $notifiable
+ *
+ * @return \Illuminate\Notifications\Messages\MailMessage
+ */
+ public function toMail($notifiable)
+ {
+ $content = trans('notifications.incident.new.mail.content', [
+ 'name' => $this->incident->name,
+ ]);
+
+ return (new MailMessage())
+ ->subject(trans('notifications.incident.new.mail.subject'))
+ ->markdown('notifications.incident.new', [
+ 'incident' => $this->incident,
+ 'content' => $content,
+ 'actionText' => trans('notifications.incident.new.mail.action'),
+ 'actionUrl' => cachet_route('incident', [$this->incident]),
+ 'unsubscribeText' => trans('cachet.subscriber.unsubscribe'),
+ 'unsubscribeUrl' => cachet_route('subscribe.unsubscribe', $notifiable->verify_code),
+ 'manageSubscriptionText' => trans('cachet.subscriber.manage_subscription'),
+ 'manageSubscriptionUrl' => cachet_route('subscribe.manage', $notifiable->verify_code),
+ ]);
+ }
+
+ /**
+ * Get the Nexmo / SMS representation of the notification.
+ *
+ * @param mixed $notifiable
+ *
+ * @return \Illuminate\Notifications\Messages\NexmoMessage
+ */
+ public function toNexmo($notifiable)
+ {
+ return (new NexmoMessage())->content(trans('notifications.incident.new.sms.content', [
+ 'name' => $this->incident->name,
+ ]));
+ }
+
+ /**
+ * Get the Slack representation of the notification.
+ *
+ * @param mixed $notifiable
+ *
+ * @return \Illuminate\Notifications\Messages\SlackMessage
+ */
+ public function toSlack($notifiable)
+ {
+ $content = trans('notifications.incident.new.slack.content', [
+ 'app_name' => Config::get('setting.app_name'),
+ ]);
+
+ $status = 'info';
+
+ if ($this->incident->status === Incident::FIXED) {
+ $status = 'success';
+ } elseif ($this->incident->status === Incident::WATCHED) {
+ $status = 'warning';
+ } else {
+ $status = 'error';
+ }
+
+ return (new SlackMessage())
+ ->$status()
+ ->content($content)
+ ->attachment(function ($attachment) {
+ $attachment->title(trans('notifications.incident.new.slack.title', ['name' => $this->incident->name]))
+ ->timestamp($this->incident->getWrappedObject()->occurred_at)
+ ->fields(array_filter([
+ 'ID' => "#{$this->incident->id}",
+ 'Link' => $this->incident->permalink,
+ ]));
+ });
+ }
+}
diff --git a/app/Notifications/IncidentUpdate/IncidentUpdatedNotification.php b/app/Notifications/IncidentUpdate/IncidentUpdatedNotification.php
new file mode 100644
index 000000000000..6c88b40370cb
--- /dev/null
+++ b/app/Notifications/IncidentUpdate/IncidentUpdatedNotification.php
@@ -0,0 +1,150 @@
+
+ */
+class IncidentUpdatedNotification extends Notification
+{
+ use Queueable;
+
+ /**
+ * The incident update.
+ *
+ * @var \CachetHQ\Cachet\Models\IncidentUpdate
+ */
+ protected $update;
+
+ /**
+ * Create a new notification instance.
+ *
+ * @param \CachetHQ\Cachet\Models\IncidentUpdate $update
+ *
+ * @return void
+ */
+ public function __construct(IncidentUpdate $update)
+ {
+ $this->update = AutoPresenter::decorate($update);
+ }
+
+ /**
+ * Get the notification's delivery channels.
+ *
+ * @param mixed $notifiable
+ *
+ * @return string[]
+ */
+ public function via($notifiable)
+ {
+ return ['mail', 'nexmo', 'slack'];
+ }
+
+ /**
+ * Get the mail representation of the notification.
+ *
+ * @param mixed $notifiable
+ *
+ * @return \Illuminate\Notifications\Messages\MailMessage
+ */
+ public function toMail($notifiable)
+ {
+ $content = trans('notifications.incident.update.mail.content', [
+ 'name' => $this->update->incident->name,
+ 'time' => $this->update->created_at_diff,
+ ]);
+
+ return (new MailMessage())
+ ->subject(trans('notifications.incident.update.mail.subject'))
+ ->markdown('notifications.incident.update', [
+ 'incident' => $this->update->incident,
+ 'update' => $this->update,
+ 'content' => $content,
+ 'actionText' => trans('notifications.incident.new.mail.action'),
+ 'actionUrl' => cachet_route('incident', [$this->update->incident]),
+ 'incidentName' => $this->update->incident->name,
+ 'newStatus' => $this->update->human_status,
+ 'unsubscribeText' => trans('cachet.subscriber.unsubscribe'),
+ 'unsubscribeUrl' => cachet_route('subscribe.unsubscribe', $notifiable->verify_code),
+ 'manageSubscriptionText' => trans('cachet.subscriber.manage_subscription'),
+ 'manageSubscriptionUrl' => cachet_route('subscribe.manage', $notifiable->verify_code),
+ ]);
+ }
+
+ /**
+ * Get the Nexmo / SMS representation of the notification.
+ *
+ * @param mixed $notifiable
+ *
+ * @return \Illuminate\Notifications\Messages\NexmoMessage
+ */
+ public function toNexmo($notifiable)
+ {
+ $content = trans('notifications.incident.update.sms.content', [
+ 'name' => $this->update->incident->name,
+ ]);
+
+ return (new NexmoMessage())->content($content);
+ }
+
+ /**
+ * Get the Slack representation of the notification.
+ *
+ * @param mixed $notifiable
+ *
+ * @return \Illuminate\Notifications\Messages\SlackMessage
+ */
+ public function toSlack($notifiable)
+ {
+ $content = trans('notifications.incident.update.slack.content', [
+ 'name' => $this->update->incident->name,
+ 'new_status' => $this->update->human_status,
+ ]);
+
+ $status = 'info';
+
+ if ($this->update->status === Incident::FIXED) {
+ $status = 'success';
+ } elseif ($this->update->status === Incident::WATCHED) {
+ $status = 'warning';
+ } else {
+ $status = 'error';
+ }
+
+ return (new SlackMessage())
+ ->$status()
+ ->content($content)
+ ->attachment(function ($attachment) use ($notifiable) {
+ $attachment->title(trans('notifications.incident.update.slack.title', [
+ 'name' => $this->update->incident->name,
+ 'new_status' => $this->update->human_status,
+ ]))
+ ->timestamp($this->update->getWrappedObject()->created_at)
+ ->fields(array_filter([
+ 'ID' => "#{$this->update->id}",
+ 'Link' => $this->update->permalink,
+ ]))
+ ->footer(trans('cachet.subscriber.unsubscribe', ['link' => cachet_route('subscribe.unsubscribe', $notifiable->verify_code)]));
+ });
+ }
+}
diff --git a/app/Notifications/Schedule/NewScheduleNotification.php b/app/Notifications/Schedule/NewScheduleNotification.php
new file mode 100644
index 000000000000..3b04bc679f6c
--- /dev/null
+++ b/app/Notifications/Schedule/NewScheduleNotification.php
@@ -0,0 +1,130 @@
+
+ */
+class NewScheduleNotification extends Notification implements ShouldQueue
+{
+ use Queueable;
+
+ /**
+ * The schedule.
+ *
+ * @var \CachetHQ\Cachet\Models\Schedule
+ */
+ protected $schedule;
+
+ /**
+ * Create a new notification instance.
+ *
+ * @param \CachetHQ\Cachet\Models\Schedule $schedule
+ *
+ * @return void
+ */
+ public function __construct(Schedule $schedule)
+ {
+ $this->schedule = AutoPresenter::decorate($schedule);
+ }
+
+ /**
+ * Get the notification's delivery channels.
+ *
+ * @param mixed $notifiable
+ *
+ * @return string[]
+ */
+ public function via($notifiable)
+ {
+ return ['mail', 'nexmo', 'slack'];
+ }
+
+ /**
+ * Get the mail representation of the notification.
+ *
+ * @param mixed $notifiable
+ *
+ * @return \Illuminate\Notifications\Messages\MailMessage
+ */
+ public function toMail($notifiable)
+ {
+ $content = trans('notifications.schedule.new.mail.content', [
+ 'name' => $this->schedule->name,
+ 'date' => $this->schedule->scheduled_at_formatted,
+ ]);
+
+ return (new MailMessage())
+ ->subject(trans('notifications.schedule.new.mail.subject'))
+ ->markdown('notifications.schedule.new', [
+ 'content' => $content,
+ 'unsubscribeText' => trans('cachet.subscriber.unsubscribe'),
+ 'unsubscribeUrl' => cachet_route('subscribe.unsubscribe', $notifiable->verify_code),
+ 'manageSubscriptionText' => trans('cachet.subscriber.manage_subscription'),
+ 'manageSubscriptionUrl' => cachet_route('subscribe.manage', $notifiable->verify_code),
+ ]);
+ }
+
+ /**
+ * Get the Nexmo / SMS representation of the notification.
+ *
+ * @param mixed $notifiable
+ *
+ * @return \Illuminate\Notifications\Messages\NexmoMessage
+ */
+ public function toNexmo($notifiable)
+ {
+ $content = trans('notifications.schedule.new.sms.content', [
+ 'name' => $this->schedule->name,
+ 'date' => $this->schedule->scheduled_at_formatted,
+ ]);
+
+ return (new NexmoMessage())->content($content);
+ }
+
+ /**
+ * Get the Slack representation of the notification.
+ *
+ * @param mixed $notifiable
+ *
+ * @return \Illuminate\Notifications\Messages\SlackMessage
+ */
+ public function toSlack($notifiable)
+ {
+ $content = trans('notifications.schedule.new.slack.content', [
+ 'name' => $this->schedule->name,
+ 'date' => $this->schedule->scheduled_at_formatted,
+ ]);
+
+ return (new SlackMessage())
+ ->content(trans('notifications.schedule.new.slack.title'))
+ ->attachment(function ($attachment) use ($content) {
+ $attachment->title($content)
+ ->timestamp($this->schedule->getWrappedObject()->scheduled_at)
+ ->fields(array_filter([
+ 'ID' => "#{$this->schedule->id}",
+ 'Status' => $this->schedule->human_status,
+ ]));
+ });
+ }
+}
diff --git a/app/Notifications/Subscriber/ManageSubscriptionNotification.php b/app/Notifications/Subscriber/ManageSubscriptionNotification.php
new file mode 100644
index 000000000000..e8f883980f69
--- /dev/null
+++ b/app/Notifications/Subscriber/ManageSubscriptionNotification.php
@@ -0,0 +1,52 @@
+ $notifiable->verify_code]);
+
+ return (new MailMessage())
+ ->subject(trans('notifications.subscriber.manage.mail.subject'))
+ ->greeting(trans('notifications.subscriber.manage.mail.title', ['app_name' => setting('app_name')]))
+ ->action(trans('notifications.subscriber.manage.mail.action'), $route)
+ ->line(trans('notifications.subscriber.manage.mail.content', ['app_name' => setting('app_name')]));
+ }
+}
diff --git a/app/Notifications/Subscriber/VerifySubscriptionNotification.php b/app/Notifications/Subscriber/VerifySubscriptionNotification.php
new file mode 100644
index 000000000000..76da5dab2368
--- /dev/null
+++ b/app/Notifications/Subscriber/VerifySubscriptionNotification.php
@@ -0,0 +1,58 @@
+
+ */
+class VerifySubscriptionNotification extends Notification
+{
+ use Queueable;
+
+ /**
+ * Get the notification's delivery channels.
+ *
+ * @param mixed $notifiable
+ *
+ * @return string[]
+ */
+ public function via($notifiable)
+ {
+ return ['mail'];
+ }
+
+ /**
+ * Get the mail representation of the notification.
+ *
+ * @param mixed $notifiable
+ *
+ * @return \Illuminate\Notifications\Messages\MailMessage
+ */
+ public function toMail($notifiable)
+ {
+ $route = URL::signedRoute(cachet_route_generator('subscribe.verify'), ['code' => $notifiable->verify_code]);
+
+ return (new MailMessage())
+ ->subject(trans('notifications.subscriber.verify.mail.subject'))
+ ->greeting(trans('notifications.subscriber.verify.mail.title', ['app_name' => Config::get('setting.app_name')]))
+ ->action(trans('notifications.subscriber.verify.mail.action'), $route)
+ ->line(trans('notifications.subscriber.verify.mail.content', ['app_name' => Config::get('setting.app_name')]));
+ }
+}
diff --git a/app/Notifications/System/SystemTestNotification.php b/app/Notifications/System/SystemTestNotification.php
new file mode 100644
index 000000000000..941ff8b9af0a
--- /dev/null
+++ b/app/Notifications/System/SystemTestNotification.php
@@ -0,0 +1,53 @@
+
+ */
+class SystemTestNotification extends Notification
+{
+ use Queueable;
+
+ /**
+ * Get the notification's delivery channels.
+ *
+ * @param mixed $notifiable
+ *
+ * @return string[]
+ */
+ public function via($notifiable)
+ {
+ return ['mail'];
+ }
+
+ /**
+ * Get the mail representation of the notification.
+ *
+ * @param mixed $notifiable
+ *
+ * @return \Illuminate\Notifications\Messages\MailMessage
+ */
+ public function toMail($notifiable)
+ {
+ return (new MailMessage())
+ ->subject(trans('notifications.system.test.mail.subject'))
+ ->greeting(trans('notifications.system.test.mail.title'))
+ ->line(trans('notifications.system.test.mail.content'));
+ }
+}
diff --git a/app/Notifications/User/InviteUserNotification.php b/app/Notifications/User/InviteUserNotification.php
new file mode 100644
index 000000000000..0ebb906e3ce4
--- /dev/null
+++ b/app/Notifications/User/InviteUserNotification.php
@@ -0,0 +1,55 @@
+
+ */
+class InviteUserNotification extends Notification
+{
+ use Queueable;
+
+ /**
+ * Get the notification's delivery channels.
+ *
+ * @param mixed $notifiable
+ *
+ * @return string[]
+ */
+ public function via($notifiable)
+ {
+ return ['mail'];
+ }
+
+ /**
+ * Get the mail representation of the notification.
+ *
+ * @param mixed $notifiable
+ *
+ * @return \Illuminate\Notifications\Messages\MailMessage
+ */
+ public function toMail($notifiable)
+ {
+ return (new MailMessage())
+ ->subject(trans('notifications.user.invite.mail.subject'))
+ ->greeting(trans('notifications.user.invite.mail.title', ['app_name' => Config::get('setting.app_name')]))
+ ->action(trans('notifications.user.invite.mail.action'), cachet_route('signup.invite', [$notifiable->code]))
+ ->line(trans('notifications.user.invite.mail.content', ['app_name' => Config::get('setting.app_name')]));
+ }
+}
diff --git a/app/Presenters/ComponentGroupPresenter.php b/app/Presenters/ComponentGroupPresenter.php
index 8cfb857520ab..456831a4ddd7 100644
--- a/app/Presenters/ComponentGroupPresenter.php
+++ b/app/Presenters/ComponentGroupPresenter.php
@@ -20,6 +20,13 @@ class ComponentGroupPresenter extends BasePresenter implements Arrayable
{
use TimestampsTrait;
+ /**
+ * Flag for the enabled_components_lowest function.
+ *
+ * @var bool
+ */
+ protected $enabledComponentsLowest = false;
+
/**
* Returns the lowest component status.
*
@@ -27,7 +34,7 @@ class ComponentGroupPresenter extends BasePresenter implements Arrayable
*/
public function lowest_status()
{
- if ($component = $this->wrappedObject->enabled_components_lowest()->first()) {
+ if ($component = $this->enabled_components_lowest()) {
return AutoPresenter::decorate($component)->status;
}
}
@@ -39,7 +46,7 @@ public function lowest_status()
*/
public function lowest_human_status()
{
- if ($component = $this->wrappedObject->enabled_components_lowest()->first()) {
+ if ($component = $this->enabled_components_lowest()) {
return AutoPresenter::decorate($component)->human_status;
}
}
@@ -51,11 +58,25 @@ public function lowest_human_status()
*/
public function lowest_status_color()
{
- if ($component = $this->wrappedObject->enabled_components_lowest()->first()) {
+ if ($component = $this->enabled_components_lowest()) {
return AutoPresenter::decorate($component)->status_color;
}
}
+ /**
+ * Return the enabled components from the wrapped object, and cache it if need be.
+ *
+ * @return bool
+ */
+ public function enabled_components_lowest()
+ {
+ if (is_bool($this->enabledComponentsLowest)) {
+ $this->enabledComponentsLowest = $this->wrappedObject->enabled_components_lowest()->first();
+ }
+
+ return $this->enabledComponentsLowest;
+ }
+
/**
* Determine the class for collapsed/uncollapsed groups.
*
@@ -81,7 +102,7 @@ public function is_collapsed()
return $this->wrappedObject->components->filter(function ($component) {
return $component->status > 1;
- })->count() === 0;
+ })->isEmpty();
}
/**
diff --git a/app/Presenters/ComponentPresenter.php b/app/Presenters/ComponentPresenter.php
index af56214c5a4d..07a2458ea5cb 100644
--- a/app/Presenters/ComponentPresenter.php
+++ b/app/Presenters/ComponentPresenter.php
@@ -11,10 +11,9 @@
namespace CachetHQ\Cachet\Presenters;
-use CachetHQ\Cachet\Dates\DateFactory;
use CachetHQ\Cachet\Presenters\Traits\TimestampsTrait;
+use CachetHQ\Cachet\Services\Dates\DateFactory;
use Illuminate\Contracts\Support\Arrayable;
-use Illuminate\Support\Facades\Config;
use McCool\LaravelAutoPresenter\BasePresenter;
class ComponentPresenter extends BasePresenter implements Arrayable
@@ -29,6 +28,7 @@ class ComponentPresenter extends BasePresenter implements Arrayable
public function status_color()
{
switch ($this->wrappedObject->status) {
+ case 0: return 'greys';
case 1: return 'greens';
case 2: return 'blues';
case 3: return 'yellows';
@@ -63,7 +63,7 @@ public function tags()
*/
public function updated_at_formatted()
{
- return ucfirst(app(DateFactory::class)->make($this->wrappedObject->updated_at)->format(Config::get('setting.incident_date_format', 'l jS F Y H:i:s')));
+ return ucfirst(app(DateFactory::class)->make($this->wrappedObject->updated_at)->format($this->incidentDateFormat()));
}
/**
diff --git a/app/Presenters/IncidentPresenter.php b/app/Presenters/IncidentPresenter.php
index 655be27ccd7d..0a8e8a65df98 100644
--- a/app/Presenters/IncidentPresenter.php
+++ b/app/Presenters/IncidentPresenter.php
@@ -11,55 +11,95 @@
namespace CachetHQ\Cachet\Presenters;
-use CachetHQ\Cachet\Dates\DateFactory;
+use CachetHQ\Cachet\Models\Incident;
use CachetHQ\Cachet\Presenters\Traits\TimestampsTrait;
+use CachetHQ\Cachet\Services\Dates\DateFactory;
use GrahamCampbell\Markdown\Facades\Markdown;
use Illuminate\Contracts\Support\Arrayable;
-use Illuminate\Support\Facades\Config;
use McCool\LaravelAutoPresenter\BasePresenter;
class IncidentPresenter extends BasePresenter implements Arrayable
{
use TimestampsTrait;
+ /**
+ * The date factory instance.
+ *
+ * @var \CachetHQ\Cachet\Services\Dates\DateFactory
+ */
+ protected $dates;
+
+ /**
+ * Flag for the latest function.
+ *
+ * @var bool
+ */
+ protected $latest = false;
+
+ /**
+ * Incident icon lookup.
+ *
+ * @var array
+ */
+ protected $icons = [
+ 0 => 'icon ion-android-calendar', // Scheduled
+ 1 => 'icon ion-flag oranges', // Investigating
+ 2 => 'icon ion-alert yellows', // Identified
+ 3 => 'icon ion-eye blues', // Watching
+ 4 => 'icon ion-checkmark greens', // Fixed
+ ];
+
+ /**
+ * Create a new presenter.
+ *
+ * @param \CachetHQ\Cachet\Services\Dates\DateFactory $dates
+ * @param \CachetHQ\Cachet\Models\Incident $resource
+ *
+ * @return void
+ */
+ public function __construct(DateFactory $dates, Incident $resource)
+ {
+ $this->dates = $dates;
+ }
+
/**
* Renders the message from Markdown into HTML.
*
* @return string
*/
- public function formattedMessage()
+ public function formatted_message()
{
return Markdown::convertToHtml($this->wrappedObject->message);
}
/**
- * Present diff for humans date time.
+ * Return the raw text of the message, even without Markdown.
*
* @return string
*/
- public function created_at_diff()
+ public function raw_message()
{
- return app(DateFactory::class)->make($this->wrappedObject->created_at)->diffForHumans();
+ return strip_tags($this->formatted_message());
}
/**
- * Present formatted date time.
+ * Present formatted occurred_at date time.
*
* @return string
*/
- public function created_at_formatted()
+ public function occurred_at()
{
- return ucfirst(app(DateFactory::class)->make($this->wrappedObject->created_at)->format(Config::get('setting.incident_date_format', 'l jS F Y H:i:s')));
+ return $this->dates->make($this->wrappedObject->occurred_at)->toDateTimeString();
}
/**
- * Formats the created_at time ready to be used by bootstrap-datetimepicker.
+ * Present diff for humans date time.
*
* @return string
*/
- public function created_at_datetimepicker()
+ public function occurred_at_diff()
{
- return app(DateFactory::class)->make($this->wrappedObject->created_at)->format('d/m/Y H:i');
+ return $this->dates->make($this->wrappedObject->occurred_at)->diffForHumans();
}
/**
@@ -67,39 +107,39 @@ public function created_at_datetimepicker()
*
* @return string
*/
- public function created_at_iso()
+ public function occurred_at_formatted()
{
- return app(DateFactory::class)->make($this->wrappedObject->created_at)->toISO8601String();
+ return ucfirst($this->dates->make($this->wrappedObject->occurred_at)->format($this->incidentDateFormat()));
}
/**
- * Present formatted date time.
+ * Formats the occurred_at time ready to be used by bootstrap-datetimepicker.
*
* @return string
*/
- public function scheduled_at()
+ public function occurred_at_datetimepicker()
{
- return app(DateFactory::class)->make($this->wrappedObject->scheduled_at)->toDateTimeString();
+ return $this->dates->make($this->wrappedObject->occurred_at)->format('Y-m-d H:i');
}
/**
- * Present diff for humans date time.
+ * Present formatted date time.
*
* @return string
*/
- public function scheduled_at_diff()
+ public function occurred_at_iso()
{
- return app(DateFactory::class)->make($this->wrappedObject->scheduled_at)->diffForHumans();
+ return $this->dates->make($this->wrappedObject->occurred_at)->toISO8601String();
}
/**
- * Present formatted date time.
+ * Present diff for humans date time.
*
* @return string
*/
- public function scheduled_at_formatted()
+ public function created_at_diff()
{
- return ucfirst(app(DateFactory::class)->make($this->wrappedObject->scheduled_at)->format(Config::get('setting.incident_date_format', 'l jS F Y H:i:s')));
+ return $this->dates->make($this->wrappedObject->created_at)->diffForHumans();
}
/**
@@ -107,19 +147,19 @@ public function scheduled_at_formatted()
*
* @return string
*/
- public function scheduled_at_iso()
+ public function created_at_formatted()
{
- return app(DateFactory::class)->make($this->wrappedObject->scheduled_at)->toISO8601String();
+ return ucfirst($this->dates->make($this->wrappedObject->created_at)->format($this->incidentDateFormat()));
}
/**
- * Formats the scheduled_at time ready to be used by bootstrap-datetimepicker.
+ * Present formatted date time.
*
* @return string
*/
- public function scheduled_at_datetimepicker()
+ public function created_at_iso()
{
- return app(DateFactory::class)->make($this->wrappedObject->scheduled_at)->format('d/m/Y H:i');
+ return $this->dates->make($this->wrappedObject->created_at)->toISO8601String();
}
/**
@@ -129,11 +169,7 @@ public function scheduled_at_datetimepicker()
*/
public function timestamp_formatted()
{
- if ($this->wrappedObject->is_scheduled) {
- return $this->scheduled_at_formatted;
- }
-
- return $this->created_at_formatted;
+ return $this->occurred_at_formatted;
}
/**
@@ -143,11 +179,7 @@ public function timestamp_formatted()
*/
public function timestamp_iso()
{
- if ($this->wrappedObject->is_scheduled) {
- return $this->scheduled_at_iso;
- }
-
- return $this->created_at_iso;
+ return $this->occurred_at_iso;
}
/**
@@ -157,19 +189,8 @@ public function timestamp_iso()
*/
public function icon()
{
- switch ($this->wrappedObject->status) {
- case 0: // Scheduled
- return 'icon ion-android-calendar';
- case 1: // Investigating
- return 'icon ion-flag oranges';
- case 2: // Identified
- return 'icon ion-alert yellows';
- case 3: // Watching
- return 'icon ion-eye blues';
- case 4: // Fixed
- return 'icon ion-checkmark greens';
- default: // Something actually broke, this shouldn't happen.
- return '';
+ if (isset($this->icons[$this->wrappedObject->status])) {
+ return $this->icons[$this->wrappedObject->status];
}
}
@@ -183,6 +204,98 @@ public function human_status()
return trans('cachet.incidents.status.'.$this->wrappedObject->status);
}
+ /**
+ * Returns the latest update.
+ *
+ * @return int|null
+ */
+ public function latest_status()
+ {
+ if ($update = $this->latest()) {
+ return $update->status;
+ }
+
+ return $this->wrappedObject->status;
+ }
+
+ /**
+ * Returns the latest update.
+ *
+ * @return string|null
+ */
+ public function latest_human_status()
+ {
+ if ($update = $this->latest()) {
+ return trans('cachet.incidents.status.'.$update->status);
+ }
+
+ return $this->human_status();
+ }
+
+ /**
+ * Present the latest icon.
+ *
+ * @return string
+ */
+ public function latest_icon()
+ {
+ if ($update = $this->latest()) {
+ if (isset($this->icons[$update->status])) {
+ return $this->icons[$update->status];
+ }
+ }
+
+ return $this->icon();
+ }
+
+ /**
+ * Fetch the latest incident update.
+ *
+ * @return \CachetHQ\Cachet\Models\IncidentUpdate|void
+ */
+ public function latest()
+ {
+ if (is_bool($this->latest)) {
+ $this->latest = $this->wrappedObject->updates()->first();
+ }
+
+ return $this->latest;
+ }
+
+ /**
+ * Get the incident permalink.
+ *
+ * @return string
+ */
+ public function permalink()
+ {
+ return cachet_route('incident', [$this->wrappedObject->id]);
+ }
+
+ /**
+ * The duration since the last update (in seconds).
+ *
+ * @return int
+ */
+ public function duration()
+ {
+ if ($update = $this->latest()) {
+ return $this->wrappedObject->created_at->diffInSeconds($update->occurred_at);
+ }
+
+ return 0;
+ }
+
+ /**
+ * Return the meta in a key value pair.
+ *
+ * @return array
+ */
+ public function meta()
+ {
+ return $this->wrappedObject->meta->pluck('value', 'key')->all();
+ }
+
/**
* Convert the presenter instance to an array.
*
@@ -191,10 +304,17 @@ public function human_status()
public function toArray()
{
return array_merge($this->wrappedObject->toArray(), [
- 'human_status' => $this->human_status(),
- 'scheduled_at' => $this->scheduled_at(),
- 'created_at' => $this->created_at(),
- 'updated_at' => $this->updated_at(),
+ 'human_status' => $this->human_status(),
+ 'latest_update_id' => $this->latest() ? $this->latest()->id : null,
+ 'latest_status' => $this->latest_status(),
+ 'latest_human_status' => $this->latest_human_status(),
+ 'latest_icon' => $this->latest_icon(),
+ 'permalink' => $this->permalink(),
+ 'duration' => $this->duration(),
+ 'meta' => $this->meta(),
+ 'occurred_at' => $this->occurred_at(),
+ 'created_at' => $this->created_at(),
+ 'updated_at' => $this->updated_at(),
]);
}
}
diff --git a/app/Presenters/IncidentUpdatePresenter.php b/app/Presenters/IncidentUpdatePresenter.php
new file mode 100644
index 000000000000..abbcbbc8d173
--- /dev/null
+++ b/app/Presenters/IncidentUpdatePresenter.php
@@ -0,0 +1,177 @@
+
+ */
+class IncidentUpdatePresenter extends BasePresenter implements Arrayable
+{
+ use TimestampsTrait;
+
+ /**
+ * Renders the message from Markdown into HTML.
+ *
+ * @return string
+ */
+ public function formatted_message()
+ {
+ return Markdown::convertToHtml($this->wrappedObject->message);
+ }
+
+ /**
+ * Return the raw text of the message, even without Markdown.
+ *
+ * @return string
+ */
+ public function raw_message()
+ {
+ return strip_tags($this->formatted_message());
+ }
+
+ /**
+ * Present diff for humans date time.
+ *
+ * @return string
+ */
+ public function created_at_diff()
+ {
+ return app(DateFactory::class)->make($this->wrappedObject->created_at)->diffForHumans();
+ }
+
+ /**
+ * Present formatted date time.
+ *
+ * @return string
+ */
+ public function created_at_formatted()
+ {
+ return ucfirst(app(DateFactory::class)->make($this->wrappedObject->created_at)->format($this->incidentDateFormat()));
+ }
+
+ /**
+ * Formats the created_at time ready to be used by bootstrap-datetimepicker.
+ *
+ * @return string
+ */
+ public function created_at_datetimepicker()
+ {
+ return app(DateFactory::class)->make($this->wrappedObject->created_at)->format('d/m/Y H:i');
+ }
+
+ /**
+ * Present formatted date time.
+ *
+ * @return string
+ */
+ public function created_at_iso()
+ {
+ return app(DateFactory::class)->make($this->wrappedObject->created_at)->toISO8601String();
+ }
+
+ /**
+ * Returns a formatted timestamp for use within the timeline.
+ *
+ * @return string
+ */
+ public function timestamp_formatted()
+ {
+ if ($this->wrappedObject->is_scheduled) {
+ return $this->scheduled_at_formatted;
+ }
+
+ return $this->created_at_formatted;
+ }
+
+ /**
+ * Return the iso timestamp for use within the timeline.
+ *
+ * @return string
+ */
+ public function timestamp_iso()
+ {
+ if ($this->wrappedObject->is_scheduled) {
+ return $this->scheduled_at_iso;
+ }
+
+ return $this->created_at_iso;
+ }
+
+ /**
+ * Present the status with an icon.
+ *
+ * @return string
+ */
+ public function icon()
+ {
+ switch ($this->wrappedObject->status) {
+ case 1: // Investigating
+
+ return 'icon ion-flag oranges';
+ case 2: // Identified
+
+ return 'icon ion-alert yellows';
+ case 3: // Watching
+
+ return 'icon ion-eye blues';
+ case 4: // Fixed
+
+ return 'icon ion-checkmark greens';
+ default: // Something actually broke, this shouldn't happen.
+
+ return '';
+ }
+ }
+
+ /**
+ * Returns a human readable version of the status.
+ *
+ * @return string
+ */
+ public function human_status()
+ {
+ return trans('cachet.incidents.status.'.$this->wrappedObject->status);
+ }
+
+ /**
+ * Generate a permalink to the incident update.
+ *
+ * @return string
+ */
+ public function permalink()
+ {
+ return cachet_route('incident', [$this->wrappedObject->incident]).'#update-'.$this->wrappedObject->id;
+ }
+
+ /**
+ * Convert the presenter instance to an array.
+ *
+ * @return string[]
+ */
+ public function toArray()
+ {
+ return array_merge($this->wrappedObject->toArray(), [
+ 'human_status' => $this->human_status(),
+ 'permalink' => $this->permalink(),
+ 'created_at' => $this->created_at(),
+ 'updated_at' => $this->updated_at(),
+ ]);
+ }
+}
diff --git a/app/Presenters/MetricPointPresenter.php b/app/Presenters/MetricPointPresenter.php
index 388ef816d390..5cbfdd60817a 100644
--- a/app/Presenters/MetricPointPresenter.php
+++ b/app/Presenters/MetricPointPresenter.php
@@ -19,16 +19,6 @@ class MetricPointPresenter extends BasePresenter implements Arrayable
{
use TimestampsTrait;
- /**
- * Show the actual calculated value; as per (value * counter).
- *
- * @return int
- */
- public function calculated_value()
- {
- return $this->wrappedObject->value * $this->wrappedObject->counter;
- }
-
/**
* Convert the presenter instance to an array.
*
@@ -37,9 +27,8 @@ public function calculated_value()
public function toArray()
{
return array_merge($this->wrappedObject->toArray(), [
- 'created_at' => $this->created_at(),
- 'updated_at' => $this->updated_at(),
- 'calculated_value' => $this->calculated_value(),
+ 'created_at' => $this->created_at(),
+ 'updated_at' => $this->updated_at(),
]);
}
}
diff --git a/app/Presenters/MetricPresenter.php b/app/Presenters/MetricPresenter.php
index 3a76abdd9ca6..4a4ef6607e90 100644
--- a/app/Presenters/MetricPresenter.php
+++ b/app/Presenters/MetricPresenter.php
@@ -13,9 +13,10 @@
use CachetHQ\Cachet\Presenters\Traits\TimestampsTrait;
use Illuminate\Contracts\Support\Arrayable;
+use Illuminate\Contracts\Support\Jsonable;
use McCool\LaravelAutoPresenter\BasePresenter;
-class MetricPresenter extends BasePresenter implements Arrayable
+class MetricPresenter extends BasePresenter implements Arrayable, Jsonable
{
use TimestampsTrait;
@@ -72,4 +73,18 @@ public function toArray()
'default_view_name' => $this->default_view_name(),
]);
}
+
+ /**
+ * Convert the object to its JSON representation.
+ *
+ * @param int $options
+ *
+ * @return string
+ */
+ public function toJson($options = 0)
+ {
+ $json = json_encode($this->toArray(), $options);
+
+ return $json;
+ }
}
diff --git a/app/Presenters/SchedulePresenter.php b/app/Presenters/SchedulePresenter.php
new file mode 100644
index 000000000000..ddf0c04ffd1e
--- /dev/null
+++ b/app/Presenters/SchedulePresenter.php
@@ -0,0 +1,261 @@
+
+ */
+class SchedulePresenter extends BasePresenter implements Arrayable
+{
+ use TimestampsTrait;
+
+ /**
+ * The date factory instance.
+ *
+ * @var \CachetHQ\Cachet\Services\Dates\DateFactory
+ */
+ protected $dates;
+
+ /**
+ * Create a new presenter.
+ *
+ * @param \CachetHQ\Cachet\Services\Dates\DateFactory $dates
+ * @param \CachetHQ\Cachet\Models\Schedule $resource
+ *
+ * @return void
+ */
+ public function __construct(DateFactory $dates, Schedule $resource)
+ {
+ $this->dates = $dates;
+ }
+
+ /**
+ * Renders the message from Markdown into HTML.
+ *
+ * @return string
+ */
+ public function formatted_message()
+ {
+ return Markdown::convertToHtml($this->wrappedObject->message);
+ }
+
+ /**
+ * Present diff for humans date time.
+ *
+ * @return string
+ */
+ public function created_at_diff()
+ {
+ return $this->dates->make($this->wrappedObject->created_at)->diffForHumans();
+ }
+
+ /**
+ * Present formatted date time.
+ *
+ * @return string
+ */
+ public function created_at_formatted()
+ {
+ return ucfirst($this->dates->make($this->wrappedObject->created_at)->format($this->incidentDateFormat()));
+ }
+
+ /**
+ * Formats the created_at time ready to be used by bootstrap-datetimepicker.
+ *
+ * @return string
+ */
+ public function created_at_datetimepicker()
+ {
+ return $this->dates->make($this->wrappedObject->created_at)->format('Y-m-d H:i');
+ }
+
+ /**
+ * Present formatted date time.
+ *
+ * @return string
+ */
+ public function created_at_iso()
+ {
+ return $this->dates->make($this->wrappedObject->created_at)->toISO8601String();
+ }
+
+ /**
+ * Present formatted date time.
+ *
+ * @return string
+ */
+ public function scheduled_at()
+ {
+ return $this->dates->make($this->wrappedObject->scheduled_at)->toDateTimeString();
+ }
+
+ /**
+ * Present diff for humans date time.
+ *
+ * @return string
+ */
+ public function scheduled_at_diff()
+ {
+ return $this->dates->make($this->wrappedObject->scheduled_at)->diffForHumans();
+ }
+
+ /**
+ * Present formatted date time.
+ *
+ * @return string
+ */
+ public function scheduled_at_formatted()
+ {
+ return ucfirst($this->dates->make($this->wrappedObject->scheduled_at)->format($this->incidentDateFormat()));
+ }
+
+ /**
+ * Present formatted date time.
+ *
+ * @return string
+ */
+ public function scheduled_at_iso()
+ {
+ return $this->dates->make($this->wrappedObject->scheduled_at)->toISO8601String();
+ }
+
+ /**
+ * Formats the scheduled_at time ready to be used by bootstrap-datetimepicker.
+ *
+ * @return string
+ */
+ public function scheduled_at_datetimepicker()
+ {
+ return $this->dates->make($this->wrappedObject->scheduled_at)->format('Y-m-d H:i');
+ }
+
+ /**
+ * Returns a formatted timestamp for use within the timeline.
+ *
+ * @return string
+ */
+ public function timestamp_formatted()
+ {
+ if ($this->wrappedObject->is_scheduled) {
+ return $this->scheduled_at_formatted;
+ }
+
+ return $this->created_at_formatted;
+ }
+
+ /**
+ * Present formatted date time.
+ *
+ * @return string
+ */
+ public function completed_at()
+ {
+ return $this->dates->make($this->wrappedObject->completed_at)->toDateTimeString();
+ }
+
+ /**
+ * Present diff for humans date time.
+ *
+ * @return string
+ */
+ public function completed_at_diff()
+ {
+ return $this->dates->make($this->wrappedObject->completed_at)->diffForHumans();
+ }
+
+ /**
+ * Present formatted date time.
+ *
+ * @return string
+ */
+ public function completed_at_formatted()
+ {
+ return ucfirst($this->dates->make($this->wrappedObject->completed_at)->format($this->incidentDateFormat()));
+ }
+
+ /**
+ * Present formatted date time.
+ *
+ * @return string
+ */
+ public function completed_at_iso()
+ {
+ return $this->dates->make($this->wrappedObject->completed_at)->toISO8601String();
+ }
+
+ /**
+ * Formats the completed_at time ready to be used by bootstrap-datetimepicker.
+ *
+ * @return string|void
+ */
+ public function completed_at_datetimepicker()
+ {
+ if ($this->wrappedObject->completed_at) {
+ return $this->dates->make($this->wrappedObject->completed_at)->format('Y-m-d H:i');
+ }
+ }
+
+ /**
+ * Return the iso timestamp for use within the timeline.
+ *
+ * @return string
+ */
+ public function timestamp_iso()
+ {
+ if ($this->wrappedObject->is_scheduled) {
+ return $this->scheduled_at_iso;
+ }
+
+ return $this->completed_at_iso;
+ }
+
+ /**
+ * Returns a human readable version of the status.
+ *
+ * @return string
+ */
+ public function human_status()
+ {
+ // return trans('cachet.incidents.status.'.$this->wrappedObject->status);
+ // TODO: Refactor into translations.
+ switch ($this->wrappedObject->status) {
+ case 0: return 'Upcoming';
+ case 1: return 'In Progress';
+ case 2: return 'Complete';
+ }
+ }
+
+ /**
+ * Convert the presenter instance to an array.
+ *
+ * @return string[]
+ */
+ public function toArray()
+ {
+ return array_merge($this->wrappedObject->toArray(), [
+ 'human_status' => $this->human_status(),
+ 'scheduled_at' => $this->scheduled_at(),
+ 'completed_at' => $this->completed_at(),
+ 'created_at' => $this->created_at(),
+ 'updated_at' => $this->updated_at(),
+ ]);
+ }
+}
diff --git a/app/Presenters/SubscriberPresenter.php b/app/Presenters/SubscriberPresenter.php
index 2da85041d989..71c2112614e1 100644
--- a/app/Presenters/SubscriberPresenter.php
+++ b/app/Presenters/SubscriberPresenter.php
@@ -11,10 +11,9 @@
namespace CachetHQ\Cachet\Presenters;
-use CachetHQ\Cachet\Dates\DateFactory;
use CachetHQ\Cachet\Presenters\Traits\TimestampsTrait;
+use CachetHQ\Cachet\Services\Dates\DateFactory;
use Illuminate\Contracts\Support\Arrayable;
-use Illuminate\Support\Facades\Config;
use McCool\LaravelAutoPresenter\BasePresenter;
class SubscriberPresenter extends BasePresenter implements Arrayable
@@ -28,7 +27,7 @@ class SubscriberPresenter extends BasePresenter implements Arrayable
*/
public function verified_at()
{
- return ucfirst(app(DateFactory::class)->make($this->wrappedObject->verified_at)->format(Config::get('setting.incident_date_format', 'l jS F Y H:i:s')));
+ return ucfirst(app(DateFactory::class)->make($this->wrappedObject->verified_at)->format($this->incidentDateFormat()));
}
/**
diff --git a/app/Presenters/Traits/TimestampsTrait.php b/app/Presenters/Traits/TimestampsTrait.php
index eba58b2abdb9..8642ac7ac625 100644
--- a/app/Presenters/Traits/TimestampsTrait.php
+++ b/app/Presenters/Traits/TimestampsTrait.php
@@ -11,8 +11,16 @@
namespace CachetHQ\Cachet\Presenters\Traits;
-use CachetHQ\Cachet\Dates\DateFactory;
+use CachetHQ\Cachet\Services\Dates\DateFactory;
+use Illuminate\Support\Facades\Config;
+/**
+ * This is the timestamps trait.
+ *
+ * @author Joseph Cohen
+ * @author Graham Campbell
+ * @author James Brooks
+ */
trait TimestampsTrait
{
/**
@@ -44,4 +52,14 @@ public function deleted_at()
{
return app(DateFactory::class)->make($this->wrappedObject->deleted_at)->toDateTimeString();
}
+
+ /**
+ * Get the incident date format setting, or fallback to a sane default.
+ *
+ * @return string
+ */
+ protected function incidentDateFormat()
+ {
+ return Config::get('setting.incident_date_format', 'l jS F Y H:i:s');
+ }
}
diff --git a/app/Foundation/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php
similarity index 67%
rename from app/Foundation/Providers/AppServiceProvider.php
rename to app/Providers/AppServiceProvider.php
index 9f3a0c214ef0..007a271ca4fe 100644
--- a/app/Foundation/Providers/AppServiceProvider.php
+++ b/app/Providers/AppServiceProvider.php
@@ -9,11 +9,14 @@
* file that was distributed with this source code.
*/
-namespace CachetHQ\Cachet\Foundation\Providers;
+namespace CachetHQ\Cachet\Providers;
use AltThree\Bus\Dispatcher;
+use AltThree\Validator\ValidatingMiddleware;
use CachetHQ\Cachet\Bus\Middleware\UseDatabaseTransactions;
-use CachetHQ\Cachet\Dates\DateFactory;
+use CachetHQ\Cachet\Services\Dates\DateFactory;
+use Illuminate\Database\Eloquent\Relations\Relation;
+use Illuminate\Support\Facades\Schema;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Str;
@@ -21,7 +24,7 @@
* This is the app service provider.
*
* @author James Brooks
- * @author Joe Cohen
+ * @author Joseph Cohen
* @author Graham Campbell
*/
class AppServiceProvider extends ServiceProvider
@@ -30,18 +33,31 @@ class AppServiceProvider extends ServiceProvider
* Boot the service provider.
*
* @param \AltThree\Bus\Dispatcher $dispatcher
+ *
+ * @return void
*/
public function boot(Dispatcher $dispatcher)
{
+ Schema::defaultStringLength(191);
+
$dispatcher->mapUsing(function ($command) {
return Dispatcher::simpleMapping($command, 'CachetHQ\Cachet\Bus', 'CachetHQ\Cachet\Bus\Handlers');
});
- $dispatcher->pipeThrough([UseDatabaseTransactions::class]);
+ $dispatcher->pipeThrough([UseDatabaseTransactions::class, ValidatingMiddleware::class]);
Str::macro('canonicalize', function ($url) {
return preg_replace('/([^\/])$/', '$1/', $url);
});
+
+ Relation::morphMap([
+ 'components' => \CachetHQ\Cachet\Models\Component::class,
+ 'incidents' => \CachetHQ\Cachet\Models\Incident::class,
+ 'metrics' => \CachetHQ\Cachet\Models\Metric::class,
+ 'schedules' => \CachetHQ\Cachet\Models\Schedule::class,
+ 'subscriber' => \CachetHQ\Cachet\Models\Subscriber::class,
+ 'tags' => \CachetHQ\Cachet\Models\Tag::class,
+ ]);
}
/**
diff --git a/app/Foundation/Providers/ComposerServiceProvider.php b/app/Providers/ComposerServiceProvider.php
similarity index 55%
rename from app/Foundation/Providers/ComposerServiceProvider.php
rename to app/Providers/ComposerServiceProvider.php
index 445d2e08a787..d3a23d62c4c1 100644
--- a/app/Foundation/Providers/ComposerServiceProvider.php
+++ b/app/Providers/ComposerServiceProvider.php
@@ -9,19 +9,19 @@
* file that was distributed with this source code.
*/
-namespace CachetHQ\Cachet\Foundation\Providers;
+namespace CachetHQ\Cachet\Providers;
use CachetHQ\Cachet\Composers\AppComposer;
+use CachetHQ\Cachet\Composers\ComponentsComposer;
use CachetHQ\Cachet\Composers\CurrentUserComposer;
use CachetHQ\Cachet\Composers\DashboardComposer;
-use CachetHQ\Cachet\Composers\ModuleComposer;
-use CachetHQ\Cachet\Composers\Modules\ComponentsComposer as ComponentsModuleComposer;
-use CachetHQ\Cachet\Composers\Modules\MetricsComposer as MetricsModuleComposer;
-use CachetHQ\Cachet\Composers\Modules\ScheduledComposer as ScheduledModuleComposer;
-use CachetHQ\Cachet\Composers\Modules\StatusComposer as StatusModuleComposer;
-use CachetHQ\Cachet\Composers\Modules\StickiedComposer as StickiedModuleComposer;
-use CachetHQ\Cachet\Composers\Modules\TimelineComposer as TimelineModuleComposer;
+use CachetHQ\Cachet\Composers\MetricsComposer;
+use CachetHQ\Cachet\Composers\ScheduledComposer;
+use CachetHQ\Cachet\Composers\SettingsComposer;
+use CachetHQ\Cachet\Composers\StatusComposer;
+use CachetHQ\Cachet\Composers\StickiedComposer;
use CachetHQ\Cachet\Composers\ThemeComposer;
+use CachetHQ\Cachet\Composers\TimelineComposer;
use CachetHQ\Cachet\Composers\TimezoneLocaleComposer;
use Illuminate\Contracts\View\Factory;
use Illuminate\Support\ServiceProvider;
@@ -37,17 +37,17 @@ public function boot(Factory $factory)
{
$factory->composer('*', AppComposer::class);
$factory->composer('*', CurrentUserComposer::class);
- $factory->composer(['index', 'single-incident', 'subscribe.*', 'signup', 'dashboard.settings.theme', 'emails.*'], ThemeComposer::class);
+ $factory->composer(['index', 'single-incident', 'subscribe.*', 'signup', 'dashboard.settings.theme', 'notifications::email', 'single-schedule', 'errors.*'], ThemeComposer::class);
$factory->composer('dashboard.*', DashboardComposer::class);
- $factory->composer(['setup', 'dashboard.settings.localization'], TimezoneLocaleComposer::class);
+ $factory->composer(['setup.*', 'dashboard.settings.localization'], TimezoneLocaleComposer::class);
- $factory->composer('*', ModuleComposer::class);
- $factory->composer('partials.modules.components', ComponentsModuleComposer::class);
- $factory->composer('partials.modules.metrics', MetricsModuleComposer::class);
- $factory->composer('partials.modules.stickied', StickiedModuleComposer::class);
- $factory->composer('partials.modules.scheduled', ScheduledModuleComposer::class);
- $factory->composer('partials.modules.status', StatusModuleComposer::class);
- $factory->composer('partials.modules.timeline', TimelineModuleComposer::class);
+ $factory->composer('partials.modules.components', ComponentsComposer::class);
+ $factory->composer('partials.modules.metrics', MetricsComposer::class);
+ $factory->composer('partials.modules.stickied', StickiedComposer::class);
+ $factory->composer('partials.modules.scheduled', ScheduledComposer::class);
+ $factory->composer('partials.modules.status', StatusComposer::class);
+ $factory->composer('partials.modules.timeline', TimelineComposer::class);
+ $factory->composer(['dashboard.settings.mail', 'setup.*'], SettingsComposer::class);
}
/**
@@ -57,6 +57,6 @@ public function boot(Factory $factory)
*/
public function register()
{
- //
+ $this->app->singleton(DashboardComposer::class);
}
}
diff --git a/app/Foundation/Providers/ConfigServiceProvider.php b/app/Providers/ConfigServiceProvider.php
similarity index 78%
rename from app/Foundation/Providers/ConfigServiceProvider.php
rename to app/Providers/ConfigServiceProvider.php
index ee4763563726..7390f720d778 100644
--- a/app/Foundation/Providers/ConfigServiceProvider.php
+++ b/app/Providers/ConfigServiceProvider.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace CachetHQ\Cachet\Foundation\Providers;
+namespace CachetHQ\Cachet\Providers;
use CachetHQ\Cachet\Models\Setting as SettingModel;
use CachetHQ\Cachet\Settings\Cache;
@@ -23,7 +23,7 @@
*
* @author James Brooks
* @author Graham Campbell
- * @author Joe Cohen
+ * @author Joseph Cohen
*/
class ConfigServiceProvider extends ServiceProvider
{
@@ -58,20 +58,24 @@ public function boot()
//
}
+ // Set the app url.
if ($appDomain = $this->app->config->get('setting.app_domain')) {
$this->app->config->set('app.url', $appDomain);
}
+ // Set the locale.
if ($appLocale = $this->app->config->get('setting.app_locale')) {
$this->app->config->set('app.locale', $appLocale);
$this->app->translator->setLocale($appLocale);
Date::setLocale($appLocale);
}
+ // Set the timezone.
if ($appTimezone = $this->app->config->get('setting.app_timezone')) {
$this->app->config->set('cachet.timezone', $appTimezone);
}
+ // Set allowed domains for CORS.
$allowedOrigins = $this->app->config->get('cors.defaults.allowedOrigins');
if ($allowedDomains = $this->app->config->get('setting.allowed_domains')) {
@@ -84,6 +88,23 @@ public function boot()
}
$this->app->config->set('cors.paths.api/v1/*.allowedOrigins', $allowedOrigins);
+
+ // Set the mail from address.
+ if (!$this->app->config->get('mail.from.address')) {
+ $url = parse_url($appDomain);
+
+ if (isset($url['host'])) {
+ $this->app->config->set('mail.from.address', "notify@{$url['host']}");
+ }
+ }
+
+ // Set the mail from name.
+ if (!$this->app->config->get('mail.from.name')) {
+ $this->app->config->set(
+ 'mail.from.name',
+ $this->app->config->get('setting.app_name', $this->app->config->get('app.name'))
+ );
+ }
}
/**
diff --git a/app/Foundation/Providers/ConsoleServiceProvider.php b/app/Providers/ConsoleServiceProvider.php
similarity index 94%
rename from app/Foundation/Providers/ConsoleServiceProvider.php
rename to app/Providers/ConsoleServiceProvider.php
index 54d2b92b9835..6976453b5c82 100644
--- a/app/Foundation/Providers/ConsoleServiceProvider.php
+++ b/app/Providers/ConsoleServiceProvider.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace CachetHQ\Cachet\Foundation\Providers;
+namespace CachetHQ\Cachet\Providers;
use CachetHQ\Cachet\Subscribers\CommandSubscriber;
use Illuminate\Support\ServiceProvider;
diff --git a/app/Foundation/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php
similarity index 72%
rename from app/Foundation/Providers/EventServiceProvider.php
rename to app/Providers/EventServiceProvider.php
index b0f970da4b3b..792e2b8bbf7c 100644
--- a/app/Foundation/Providers/EventServiceProvider.php
+++ b/app/Providers/EventServiceProvider.php
@@ -9,25 +9,28 @@
* file that was distributed with this source code.
*/
-namespace CachetHQ\Cachet\Foundation\Providers;
+namespace CachetHQ\Cachet\Providers;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
/**
- * The event handler mappings for the application.
+ * The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
+ 'CachetHQ\Cachet\Bus\Events\ActionInterface' => [
+ 'CachetHQ\Cachet\Bus\Handlers\Events\ActionStorageHandler',
+ ],
'CachetHQ\Cachet\Bus\Events\Beacon\BeaconFailedToSendEvent' => [
- //
+ 'CachetHQ\Cachet\Bus\Handlers\Events\Beacon\LogBeaconFailedHandler',
],
'CachetHQ\Cachet\Bus\Events\Beacon\BeaconWasSentEvent' => [
//
],
- 'CachetHQ\Cachet\Bus\Events\ComponentGroup\ComponentGroupWasAddedEvent' => [
+ 'CachetHQ\Cachet\Bus\Events\ComponentGroup\ComponentGroupWasCreatedEvent' => [
//
],
'CachetHQ\Cachet\Bus\Events\ComponentGroup\ComponentGroupWasRemovedEvent' => [
@@ -36,10 +39,10 @@ class EventServiceProvider extends ServiceProvider
'CachetHQ\Cachet\Bus\Events\ComponentGroup\ComponentGroupWasUpdatedEvent' => [
//
],
- 'CachetHQ\Cachet\Bus\Events\Component\ComponentStatusWasUpdatedEvent' => [
+ 'CachetHQ\Cachet\Bus\Events\Component\ComponentStatusWasChangedEvent' => [
'CachetHQ\Cachet\Bus\Handlers\Events\Component\SendComponentUpdateEmailNotificationHandler',
],
- 'CachetHQ\Cachet\Bus\Events\Component\ComponentWasAddedEvent' => [
+ 'CachetHQ\Cachet\Bus\Events\Component\ComponentWasCreatedEvent' => [
//
],
'CachetHQ\Cachet\Bus\Events\Component\ComponentWasRemovedEvent' => [
@@ -48,25 +51,28 @@ class EventServiceProvider extends ServiceProvider
'CachetHQ\Cachet\Bus\Events\Component\ComponentWasUpdatedEvent' => [
//
],
- 'CachetHQ\Cachet\Bus\Events\Incident\IncidentWasRemovedEvent' => [
+ 'CachetHQ\Cachet\Bus\Events\IncidentUpdate\IncidentUpdateWasRemovedEvent' => [
//
],
- 'CachetHQ\Cachet\Bus\Events\Incident\IncidentWasReportedEvent' => [
- 'CachetHQ\Cachet\Bus\Handlers\Events\Incident\SendIncidentEmailNotificationHandler',
+ 'CachetHQ\Cachet\Bus\Events\IncidentUpdate\IncidentUpdateWasReportedEvent' => [
+ 'CachetHQ\Cachet\Bus\Handlers\Events\IncidentUpdate\SendIncidentUpdateEmailNotificationHandler',
],
- 'CachetHQ\Cachet\Bus\Events\Incident\IncidentWasUpdatedEvent' => [
+ 'CachetHQ\Cachet\Bus\Events\IncidentUpdate\IncidentUpdateWasUpdatedEvent' => [
//
],
+ 'CachetHQ\Cachet\Bus\Events\Incident\IncidentWasCreatedEvent' => [
+ 'CachetHQ\Cachet\Bus\Handlers\Events\Incident\SendIncidentEmailNotificationHandler',
+ ],
'CachetHQ\Cachet\Bus\Events\Incident\IncidentWasRemovedEvent' => [
//
],
- 'CachetHQ\Cachet\Bus\Events\Incident\MaintenanceWasScheduledEvent' => [
- 'CachetHQ\Cachet\Bus\Handlers\Events\Incident\SendMaintenanceEmailNotificationHandler',
+ 'CachetHQ\Cachet\Bus\Events\Incident\IncidentWasUpdatedEvent' => [
+ //
],
'CachetHQ\Cachet\Bus\Events\Invite\InviteWasClaimedEvent' => [
//
],
- 'CachetHQ\Cachet\Bus\Events\Metric\MetricPointWasAddedEvent' => [
+ 'CachetHQ\Cachet\Bus\Events\Metric\MetricPointWasCreatedEvent' => [
//
],
'CachetHQ\Cachet\Bus\Events\Metric\MetricPointWasRemovedEvent' => [
@@ -75,7 +81,7 @@ class EventServiceProvider extends ServiceProvider
'CachetHQ\Cachet\Bus\Events\Metric\MetricPointWasUpdatedEvent' => [
//
],
- 'CachetHQ\Cachet\Bus\Events\Metric\MetricWasAddedEvent' => [
+ 'CachetHQ\Cachet\Bus\Events\Metric\MetricWasCreatedEvent' => [
//
],
'CachetHQ\Cachet\Bus\Events\Metric\MetricWasRemovedEvent' => [
@@ -84,8 +90,17 @@ class EventServiceProvider extends ServiceProvider
'CachetHQ\Cachet\Bus\Events\Metric\MetricWasUpdatedEvent' => [
//
],
+ 'CachetHQ\Cachet\Bus\Events\Schedule\ScheduleWasCreatedEvent' => [
+ 'CachetHQ\Cachet\Bus\Handlers\Events\Schedule\SendScheduleEmailNotificationHandler',
+ ],
+ 'CachetHQ\Cachet\Bus\Events\Schedule\ScheduleWasRemovedEvent' => [
+ //
+ ],
+ 'CachetHQ\Cachet\Bus\Events\Schedule\ScheduleWasUpdatedEvent' => [
+ //
+ ],
'CachetHQ\Cachet\Bus\Events\Subscriber\SubscriberHasSubscribedEvent' => [
- 'CachetHQ\Cachet\Bus\Handlers\Events\Subscriber\SendSubscriberVerificationEmailHandler',
+ //
],
'CachetHQ\Cachet\Bus\Events\Subscriber\SubscriberHasUnsubscribedEvent' => [
//
@@ -108,6 +123,9 @@ class EventServiceProvider extends ServiceProvider
'CachetHQ\Cachet\Bus\Events\System\SystemWasUpdatedEvent' => [
//
],
+ 'CachetHQ\Cachet\Bus\Events\User\UserAcceptedInviteEvent' => [
+ //
+ ],
'CachetHQ\Cachet\Bus\Events\User\UserDisabledTwoAuthEvent' => [
//
],
@@ -129,11 +147,11 @@ class EventServiceProvider extends ServiceProvider
'CachetHQ\Cachet\Bus\Events\User\UserRegeneratedApiTokenEvent' => [
//
],
- 'CachetHQ\Cachet\Bus\Events\User\UserWasAddedEvent' => [
+ 'CachetHQ\Cachet\Bus\Events\User\UserWasCreatedEvent' => [
//
],
'CachetHQ\Cachet\Bus\Events\User\UserWasInvitedEvent' => [
- 'CachetHQ\Cachet\Bus\Handlers\Events\User\SendInviteUserEmailHandler',
+ //
],
'CachetHQ\Cachet\Bus\Events\User\UserWasRemovedEvent' => [
//
diff --git a/app/Foundation/Providers/IntegrationServiceProvider.php b/app/Providers/IntegrationServiceProvider.php
similarity index 94%
rename from app/Foundation/Providers/IntegrationServiceProvider.php
rename to app/Providers/IntegrationServiceProvider.php
index 4f4ba9e0ab31..57d27523cdab 100644
--- a/app/Foundation/Providers/IntegrationServiceProvider.php
+++ b/app/Providers/IntegrationServiceProvider.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace CachetHQ\Cachet\Foundation\Providers;
+namespace CachetHQ\Cachet\Providers;
use CachetHQ\Cachet\Integrations\Contracts\Beacon as BeaconContract;
use CachetHQ\Cachet\Integrations\Contracts\Credits as CreditsContract;
@@ -96,7 +96,10 @@ protected function registerFeed()
protected function registerSystem()
{
$this->app->singleton(SystemContract::class, function (Container $app) {
- return new System();
+ $config = $app['config'];
+ $auth = $app['auth.driver'];
+
+ return new System($config, $auth);
});
}
diff --git a/app/Foundation/Providers/RepositoryServiceProvider.php b/app/Providers/RepositoryServiceProvider.php
similarity index 62%
rename from app/Foundation/Providers/RepositoryServiceProvider.php
rename to app/Providers/RepositoryServiceProvider.php
index 56afc6a1656a..550aa17f1b35 100644
--- a/app/Foundation/Providers/RepositoryServiceProvider.php
+++ b/app/Providers/RepositoryServiceProvider.php
@@ -9,13 +9,13 @@
* file that was distributed with this source code.
*/
-namespace CachetHQ\Cachet\Foundation\Providers;
+namespace CachetHQ\Cachet\Providers;
-use CachetHQ\Cachet\Dates\DateFactory;
use CachetHQ\Cachet\Repositories\Metric\MetricRepository;
-use CachetHQ\Cachet\Repositories\Metric\MySqlRepository as MetricMySqlRepository;
-use CachetHQ\Cachet\Repositories\Metric\PgSqlRepository as MetricPgSqlRepository;
-use CachetHQ\Cachet\Repositories\Metric\SqliteRepository as MetricSqliteRepository;
+use CachetHQ\Cachet\Repositories\Metric\MySqlRepository;
+use CachetHQ\Cachet\Repositories\Metric\PgSqlRepository;
+use CachetHQ\Cachet\Repositories\Metric\SqliteRepository;
+use CachetHQ\Cachet\Services\Dates\DateFactory;
use Illuminate\Contracts\Config\Repository as ConfigRepository;
use Illuminate\Contracts\Container\Container;
use Illuminate\Support\ServiceProvider;
@@ -46,14 +46,14 @@ protected function registerMetricRepository()
{
$this->app->singleton(MetricRepository::class, function (Container $app) {
$config = $app->make(ConfigRepository::class);
- $driver = $config->get('database.default');
- if ($driver == 'mysql') {
- $repository = new MetricMySqlRepository($config);
- } elseif ($driver == 'pgsql') {
- $repository = new MetricPgSqlRepository($config);
- } elseif ($driver == 'sqlite') {
- $repository = new MetricSqliteRepository($config);
+ switch ($config->get('database.default')) {
+ case 'mysql': $repository = new MySqlRepository($config);
+ break;
+ case 'pgsql': $repository = new PgSqlRepository($config);
+ break;
+ case 'sqlite': $repository = new SqliteRepository($config);
+ break;
}
$dates = $app->make(DateFactory::class);
diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php
new file mode 100644
index 000000000000..f23d7a023da4
--- /dev/null
+++ b/app/Providers/RouteServiceProvider.php
@@ -0,0 +1,207 @@
+
+ * @author Joseph Cohen
+ * @author Graham Campbell
+ */
+class RouteServiceProvider extends ServiceProvider
+{
+ /**
+ * This namespace is applied to your controller routes.
+ *
+ * In addition, it is set as the URL generator's root namespace.
+ *
+ * @var string
+ */
+ protected $namespace = 'CachetHQ\Cachet\Http\Controllers';
+
+ /**
+ * These are the route files that should always be available anonymously.
+ *
+ * When applying the always_authenticate feature, these routes will be skipped.
+ *
+ * @var string[]
+ */
+ protected $whitelistedAuthRoutes = [
+ AuthRoutes::class,
+ SetupRoutes::class,
+ SignupRoutes::class,
+ ApiSystemRoutes::class,
+ ApiSetupRoutes::class,
+ ];
+
+ /**
+ * Define the route model bindings, pattern filters, etc.
+ *
+ * @return void
+ */
+ public function boot()
+ {
+ parent::boot();
+
+ $this->app->call([$this, 'bind']);
+ }
+
+ /**
+ * Define the bindings for the application.
+ *
+ * @param \Illuminate\Routing\Router $router
+ *
+ * @return void
+ */
+ public function bind(Router $router)
+ {
+ $router->model('component', 'CachetHQ\Cachet\Models\Component');
+ $router->model('component_group', 'CachetHQ\Cachet\Models\ComponentGroup');
+ $router->model('incident', 'CachetHQ\Cachet\Models\Incident');
+ $router->model('incident_template', 'CachetHQ\Cachet\Models\IncidentTemplate');
+ $router->model('incident_update', 'CachetHQ\Cachet\Models\IncidentUpdate');
+ $router->model('metric', 'CachetHQ\Cachet\Models\Metric');
+ $router->model('metric_point', 'CachetHQ\Cachet\Models\MetricPoint');
+ $router->model('schedule', 'CachetHQ\Cachet\Models\Schedule');
+ $router->model('setting', 'CachetHQ\Cachet\Models\Setting');
+ $router->model('subscriber', 'CachetHQ\Cachet\Models\Subscriber');
+ $router->model('subscription', 'CachetHQ\Cachet\Models\Subscription');
+ $router->model('tag', 'CachetHQ\Cachet\Models\Tag');
+ $router->model('user', 'CachetHQ\Cachet\Models\User');
+ }
+
+ /**
+ * Define the routes for the application.
+ *
+ * @param \Illuminate\Routing\Router $router
+ *
+ * @return void
+ */
+ public function map(Router $router)
+ {
+ $router->group(['namespace' => $this->namespace, 'as' => 'core::'], function (Router $router) {
+ $path = app_path('Http/Routes');
+
+ $applyAlwaysAuthenticate = $this->app['config']->get('setting.always_authenticate', false);
+ $AllFileIterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path));
+ $PhpFileIterator = new \RegexIterator($AllFileIterator, '/^.+\.php$/i', \RecursiveRegexIterator::GET_MATCH);
+
+ foreach ($PhpFileIterator as $file => $object) {
+ $class = substr($file, strlen($path));
+ $class = str_replace('/', '\\', $class);
+ $class = substr($class, 0, -4);
+
+ $routes = $this->app->make("CachetHQ\\Cachet\\Http\\Routes${class}");
+
+ if ($routes::$browser) {
+ $this->mapForBrowser($router, $routes, $applyAlwaysAuthenticate);
+ } else {
+ $this->mapOtherwise($router, $routes, $applyAlwaysAuthenticate);
+ }
+ }
+ });
+ }
+
+ /**
+ * Wrap the routes in the browser specific middleware.
+ *
+ * @param \Illuminate\Routing\Router $router
+ * @param object $routes
+ * @param bool $applyAlwaysAuthenticate
+ *
+ * @return void
+ */
+ protected function mapForBrowser(Router $router, $routes, $applyAlwaysAuthenticate)
+ {
+ $middleware = [
+ EncryptCookies::class,
+ AddQueuedCookiesToResponse::class,
+ StartSession::class,
+ ShareErrorsFromSession::class,
+ VerifyCsrfToken::class,
+ SubstituteBindings::class,
+ ];
+
+ if ($applyAlwaysAuthenticate && !$this->isWhiteListedAuthRoute($routes)) {
+ $middleware[] = RemoteUserAuthenticate::class;
+ $middleware[] = Authenticate::class;
+ }
+
+ $router->group(['middleware' => $middleware], function (Router $router) use ($routes) {
+ $routes->map($router);
+ });
+ }
+
+ /**
+ * Wrap the routes in the basic middleware.
+ *
+ * @param \Illuminate\Routing\Router $router
+ * @param object $routes
+ * @param bool $applyAlwaysAuthenticate
+ *
+ * @return void
+ */
+ protected function mapOtherwise(Router $router, $routes, $applyAlwaysAuthenticate)
+ {
+ $middleware = [
+ SubstituteBindings::class,
+ Acceptable::class,
+ Timezone::class,
+ ];
+
+ if ($applyAlwaysAuthenticate && !$this->isWhiteListedAuthRoute($routes)) {
+ $middleware[] = 'auth.api:true';
+ }
+
+ $router->group(['middleware' => $middleware], function (Router $router) use ($routes) {
+ $routes->map($router);
+ });
+ }
+
+ /**
+ * Validates if the route object is an instance of the whitelisted routes.
+ * A small workaround since we cant use multiple classes in a `instanceof` comparison.
+ *
+ * @param object $routes
+ *
+ * @return bool
+ */
+ private function isWhiteListedAuthRoute($routes)
+ {
+ foreach ($this->whitelistedAuthRoutes as $whitelistedRoute) {
+ if (is_a($routes, $whitelistedRoute)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/app/Repositories/Metric/AbstractMetricRepository.php b/app/Repositories/Metric/AbstractMetricRepository.php
index c781d281a398..566827e66619 100644
--- a/app/Repositories/Metric/AbstractMetricRepository.php
+++ b/app/Repositories/Metric/AbstractMetricRepository.php
@@ -11,8 +11,10 @@
namespace CachetHQ\Cachet\Repositories\Metric;
+use CachetHQ\Cachet\Integrations\Contracts\System;
use CachetHQ\Cachet\Models\Metric;
use Illuminate\Contracts\Config\Repository;
+use Illuminate\Support\Collection;
/**
* This is the abstract metric repository class.
@@ -52,12 +54,67 @@ public function __construct(Repository $config)
*
* @return string
*/
- protected function getTableName()
+ protected function getMetricsTable()
{
- $driver = $this->config->get('database.default');
- $connection = $this->config->get('database.connections.'.$driver);
- $prefix = $connection['prefix'];
+ $prefix = app(System::class)->getTablePrefix();
return $prefix.'metrics';
}
+
+ /**
+ * Get the metric points table name.
+ *
+ * @return string
+ */
+ protected function getMetricPointsTable()
+ {
+ $prefix = app(System::class)->getTablePrefix();
+
+ return $prefix.'metric_points';
+ }
+
+ /**
+ * Return the query type.
+ *
+ * @param \CachetHQ\Cachet\Models\Metric $metric
+ *
+ * @return string
+ */
+ protected function getQueryType(Metric $metric)
+ {
+ if (!isset($metric->calc_type) || $metric->calc_type == Metric::CALC_SUM) {
+ return "sum({$this->getMetricPointsTable()}.value * {$this->getMetricPointsTable()}.counter) AS value";
+ } elseif ($metric->calc_type == Metric::CALC_AVG) {
+ return "avg({$this->getMetricPointsTable()}.value) AS value";
+ } else {
+ return "sum({$this->getMetricPointsTable()}.value * {$this->getMetricPointsTable()}.counter) AS value";
+ }
+ }
+
+ /**
+ * Map the result set.
+ *
+ * @param \CachetHQ\Cachet\Models\Metric $metric
+ * @param array $results
+ *
+ * @return \Illuminate\Support\Collection
+ */
+ protected function mapResults(Metric $metric, array $results)
+ {
+ $results = Collection::make($results);
+
+ return $results->map(function ($point) use ($metric) {
+ if (!$point->value) {
+ $point->value = $metric->default_value;
+ }
+
+ if ($point->value === 0 && $metric->default_value != $point->value) {
+ $point->value = $metric->default_value;
+ }
+
+ $point->value = round($point->value, $metric->places);
+
+ return $point;
+ });
+ }
}
diff --git a/app/Repositories/Metric/MetricInterface.php b/app/Repositories/Metric/MetricInterface.php
index b355192f4c34..ec0cb1634527 100644
--- a/app/Repositories/Metric/MetricInterface.php
+++ b/app/Repositories/Metric/MetricInterface.php
@@ -13,36 +13,40 @@
use CachetHQ\Cachet\Models\Metric;
+/**
+ * This is the metric interface.
+ *
+ * @author James Brooks
+ */
interface MetricInterface
{
/**
- * Returns metrics for the last hour.
+ * Returns metrics since given minutes.
*
* @param \CachetHQ\Cachet\Models\Metric $metric
- * @param int $hour
- * @param int $minute
+ * @param int $minutes
*
- * @return int
+ * @return \Illuminate\Support\Collection
*/
- public function getPointsLastHour(Metric $metric, $hour, $minute);
+ public function getPointsSinceMinutes(Metric $metric, $minutes);
/**
- * Returns metrics for a given hour.
+ * Returns metrics since given hour.
*
* @param \CachetHQ\Cachet\Models\Metric $metric
* @param int $hour
*
- * @return int
+ * @return \Illuminate\Support\Collection
*/
- public function getPointsByHour(Metric $metric, $hour);
+ public function getPointsSinceHour(Metric $metric, $hour);
/**
- * Returns metrics for the week.
+ * Returns metrics since given day.
*
* @param \CachetHQ\Cachet\Models\Metric $metric
* @param int $day
*
- * @return int
+ * @return \Illuminate\Support\Collection
*/
- public function getPointsForDayInWeek(Metric $metric, $day);
+ public function getPointsSinceDay(Metric $metric, $day);
}
diff --git a/app/Repositories/Metric/MetricRepository.php b/app/Repositories/Metric/MetricRepository.php
index 315ffc6e2280..c424336b19cd 100644
--- a/app/Repositories/Metric/MetricRepository.php
+++ b/app/Repositories/Metric/MetricRepository.php
@@ -11,10 +11,15 @@
namespace CachetHQ\Cachet\Repositories\Metric;
-use CachetHQ\Cachet\Dates\DateFactory;
use CachetHQ\Cachet\Models\Metric;
+use CachetHQ\Cachet\Services\Dates\DateFactory;
use DateInterval;
+/**
+ * This is the metric repository class.
+ *
+ * @author James Brooks
+ */
class MetricRepository
{
/**
@@ -27,7 +32,7 @@ class MetricRepository
/**
* The date factory instance.
*
- * @var \CachetHQ\Cachet\Dates\DateFactory
+ * @var \CachetHQ\Cachet\Services\Dates\DateFactory
*/
protected $dates;
@@ -35,7 +40,7 @@ class MetricRepository
* Create a new metric repository class.
*
* @param \CachetHQ\Cachet\Repositories\Metric\MetricInterface $repository
- * @param \CachetHQ\Cachet\Dates\DateFactory $dates
+ * @param \CachetHQ\Cachet\Services\Dates\DateFactory $dates
*
* @return void
*/
@@ -50,22 +55,41 @@ public function __construct(MetricInterface $repository, DateFactory $dates)
*
* @param \CachetHQ\Cachet\Models\Metric $metric
*
- * @return array
+ * @return \Illuminate\Support\Collection
*/
public function listPointsLastHour(Metric $metric)
{
$dateTime = $this->dates->make();
-
- $points = [];
-
- $pointKey = $dateTime->format('H:i');
-
- for ($i = 0; $i <= 60; $i++) {
- $points[$pointKey] = $this->repository->getPointsLastHour($metric, 0, $i);
- $pointKey = $dateTime->sub(new DateInterval('PT1M'))->format('H:i');
+ $pointKey = $dateTime->format('Y-m-d H:i');
+ $nrOfMinutes = 61;
+ $points = $this->repository->getPointsSinceMinutes($metric, $nrOfMinutes + $metric->threshold)->pluck('value', 'key')->take(-$nrOfMinutes);
+
+ $timeframe = $nrOfMinutes;
+
+ //Settings counter for minutes without data
+ $minutesWithNoData = 0;
+
+ for ($i = 0; $i < $timeframe; $i++) {
+ if (!$points->has($pointKey)) {
+ if ($i >= $metric->threshold) {
+ $points->put($pointKey, $metric->default_value);
+ //We put default value as metric, so we can reset counter for minutes without data
+ $minutesWithNoData = 0;
+ } else {
+ //We didn't find any data, but threshold is not meet yet so we just adding to counter
+ $minutesWithNoData++;
+ }
+ } else {
+ //We found data within this threshold, zeroing counter
+ $minutesWithNoData = 0;
+ }
+
+ $pointKey = $dateTime->sub(new DateInterval('PT1M'))->format('Y-m-d H:i');
}
- return array_reverse($points);
+ return $points->sortBy(function ($point, $key) {
+ return $key;
+ });
}
/**
@@ -79,17 +103,20 @@ public function listPointsLastHour(Metric $metric)
public function listPointsToday(Metric $metric, $hours = 12)
{
$dateTime = $this->dates->make();
+ $pointKey = $dateTime->format('Y-m-d H:00');
+ $points = $this->repository->getPointsSinceHour($metric, $hours)->pluck('value', 'key');
- $points = [];
-
- $pointKey = $dateTime->format('H:00');
+ for ($i = 0; $i < $hours; $i++) {
+ if (!$points->has($pointKey)) {
+ $points->put($pointKey, $metric->default_value);
+ }
- for ($i = 0; $i <= $hours; $i++) {
- $points[$pointKey] = $this->repository->getPointsByHour($metric, $i);
- $pointKey = $dateTime->sub(new DateInterval('PT1H'))->format('H:00');
+ $pointKey = $dateTime->sub(new DateInterval('PT1H'))->format('Y-m-d H:00');
}
- return array_reverse($points);
+ return $points->sortBy(function ($point, $key) {
+ return $key;
+ });
}
/**
@@ -102,17 +129,20 @@ public function listPointsToday(Metric $metric, $hours = 12)
public function listPointsForWeek(Metric $metric)
{
$dateTime = $this->dates->make();
-
- $points = [];
-
- $pointKey = $dateTime->format('D jS M');
+ $pointKey = $dateTime->format('Y-m-d');
+ $points = $this->repository->getPointsSinceDay($metric, 7)->pluck('value', 'key');
for ($i = 0; $i <= 7; $i++) {
- $points[$pointKey] = $this->repository->getPointsForDayInWeek($metric, $i);
- $pointKey = $dateTime->sub(new DateInterval('P1D'))->format('D jS M');
+ if (!$points->has($pointKey)) {
+ $points->put($pointKey, $metric->default_value);
+ }
+
+ $pointKey = $dateTime->sub(new DateInterval('P1D'))->format('Y-m-d');
}
- return array_reverse($points);
+ return $points->sortBy(function ($point, $key) {
+ return $key;
+ });
}
/**
@@ -125,18 +155,20 @@ public function listPointsForWeek(Metric $metric)
public function listPointsForMonth(Metric $metric)
{
$dateTime = $this->dates->make();
-
+ $pointKey = $dateTime->format('Y-m-d');
$daysInMonth = $dateTime->format('t');
-
- $points = [];
-
- $pointKey = $dateTime->format('jS M');
+ $points = $this->repository->getPointsSinceDay($metric, $daysInMonth)->pluck('value', 'key');
for ($i = 0; $i <= $daysInMonth; $i++) {
- $points[$pointKey] = $this->repository->getPointsForDayInWeek($metric, $i);
- $pointKey = $dateTime->sub(new DateInterval('P1D'))->format('jS M');
+ if (!$points->has($pointKey)) {
+ $points->put($pointKey, $metric->default_value);
+ }
+
+ $pointKey = $dateTime->sub(new DateInterval('P1D'))->format('Y-m-d');
}
- return array_reverse($points);
+ return $points->sortBy(function ($point, $key) {
+ return $key;
+ });
}
}
diff --git a/app/Repositories/Metric/MySqlRepository.php b/app/Repositories/Metric/MySqlRepository.php
index a9cca0861a83..3d5e37159dd8 100644
--- a/app/Repositories/Metric/MySqlRepository.php
+++ b/app/Repositories/Metric/MySqlRepository.php
@@ -12,9 +12,7 @@
namespace CachetHQ\Cachet\Repositories\Metric;
use CachetHQ\Cachet\Models\Metric;
-use DateInterval;
use Illuminate\Support\Facades\DB;
-use Jenssegers\Date\Date;
/**
* This is the mysql repository class.
@@ -24,112 +22,76 @@
class MySqlRepository extends AbstractMetricRepository implements MetricInterface
{
/**
- * Returns metrics for the last hour.
+ * Returns metrics since given minutes.
*
* @param \CachetHQ\Cachet\Models\Metric $metric
- * @param int $hour
- * @param int $minute
+ * @param int $minutes
*
- * @return int
+ * @return \Illuminate\Support\Collection
*/
- public function getPointsLastHour(Metric $metric, $hour, $minute)
+ public function getPointsSinceMinutes(Metric $metric, $minutes)
{
- $dateTime = (new Date())->sub(new DateInterval('PT'.$hour.'H'))->sub(new DateInterval('PT'.$minute.'M'));
- $timeInterval = $dateTime->format('YmdHi');
-
- if (!isset($metric->calc_type) || $metric->calc_type == Metric::CALC_SUM) {
- $queryType = 'SUM(mp.`value` * mp.`counter`) AS `value`';
- } elseif ($metric->calc_type == Metric::CALC_AVG) {
- $queryType = 'AVG(mp.`value` * mp.`counter`) AS `value`';
- }
-
- $value = 0;
-
- $points = DB::select("SELECT {$queryType} FROM {$this->getTableName()} m INNER JOIN metric_points mp ON m.id = mp.metric_id WHERE m.id = :metricId AND DATE_FORMAT(mp.`created_at`, '%Y%m%d%H%i') = :timeInterval GROUP BY HOUR(mp.`created_at`), MINUTE(mp.`created_at`)", [
- 'metricId' => $metric->id,
- 'timeInterval' => $timeInterval,
- ]);
-
- if (isset($points[0]) && !($value = $points[0]->value)) {
- $value = 0;
- }
-
- if ($value === 0 && $metric->default_value != $value) {
- return $metric->default_value;
- }
-
- return round($value, $metric->places);
+ $queryType = $this->getQueryType($metric);
+
+ $points = DB::select("SELECT DATE_FORMAT({$this->getMetricPointsTable()}.`created_at`, '%Y-%m-%d %H:%i') AS `key`, {$queryType} ".
+ "FROM {$this->getMetricsTable()} INNER JOIN {$this->getMetricPointsTable()} ON {$this->getMetricsTable()}.id = {$this->getMetricPointsTable()}.metric_id ".
+ "WHERE {$this->getMetricsTable()}.id = :metricId ".
+ "AND {$this->getMetricPointsTable()}.`created_at` >= DATE_SUB(NOW(), INTERVAL :minutes MINUTE) ".
+ "AND {$this->getMetricPointsTable()}.`created_at` <= NOW() ".
+ "GROUP BY HOUR({$this->getMetricPointsTable()}.`created_at`), MINUTE({$this->getMetricPointsTable()}.`created_at`) ORDER BY {$this->getMetricPointsTable()}.`created_at`", [
+ 'metricId' => $metric->id,
+ 'minutes' => $minutes,
+ ]);
+
+ return $this->mapResults($metric, $points);
}
/**
- * Returns metrics for a given hour.
+ * Returns metrics since given hour.
*
* @param \CachetHQ\Cachet\Models\Metric $metric
* @param int $hour
*
- * @return int
+ * @return \Illuminate\Support\Collection
*/
- public function getPointsByHour(Metric $metric, $hour)
+ public function getPointsSinceHour(Metric $metric, $hour)
{
- $dateTime = (new Date())->sub(new DateInterval('PT'.$hour.'H'));
- $hourInterval = $dateTime->format('YmdH');
-
- if (!isset($metric->calc_type) || $metric->calc_type == Metric::CALC_SUM) {
- $queryType = 'SUM(mp.`value` * mp.`counter`) AS `value`';
- } elseif ($metric->calc_type == Metric::CALC_AVG) {
- $queryType = 'AVG(mp.`value` * mp.`counter`) AS `value`';
- }
-
- $value = 0;
-
- $points = DB::select("SELECT {$queryType} FROM {$this->getTableName()} m INNER JOIN metric_points mp ON m.id = mp.metric_id WHERE m.id = :metricId AND DATE_FORMAT(mp.`created_at`, '%Y%m%d%H') = :hourInterval GROUP BY HOUR(mp.`created_at`)", [
- 'metricId' => $metric->id,
- 'hourInterval' => $hourInterval,
- ]);
-
- if (isset($points[0]) && !($value = $points[0]->value)) {
- $value = 0;
- }
-
- if ($value === 0 && $metric->default_value != $value) {
- return $metric->default_value;
- }
-
- return round($value, $metric->places);
+ $queryType = $this->getQueryType($metric);
+ $points = DB::select("SELECT DATE_FORMAT({$this->getMetricPointsTable()}.`created_at`, '%Y-%m-%d %H:00') AS `key`, {$queryType} ".
+ "FROM {$this->getMetricsTable()} INNER JOIN {$this->getMetricPointsTable()} ON {$this->getMetricsTable()}.id = {$this->getMetricPointsTable()}.metric_id ".
+ "WHERE {$this->getMetricsTable()}.id = :metricId ".
+ "AND {$this->getMetricPointsTable()}.`created_at` >= DATE_SUB(NOW(), INTERVAL :hour HOUR) ".
+ "AND {$this->getMetricPointsTable()}.`created_at` <= NOW() ".
+ "GROUP BY HOUR({$this->getMetricPointsTable()}.`created_at`) ".
+ "ORDER BY {$this->getMetricPointsTable()}.`created_at`", [
+ 'metricId' => $metric->id,
+ 'hour' => $hour,
+ ]);
+
+ return $this->mapResults($metric, $points);
}
/**
- * Returns metrics for the week.
+ * Returns metrics since given day.
*
* @param \CachetHQ\Cachet\Models\Metric $metric
+ * @param int $day
*
- * @return int
+ * @return \Illuminate\Support\Collection
*/
- public function getPointsForDayInWeek(Metric $metric, $day)
+ public function getPointsSinceDay(Metric $metric, $day)
{
- $dateTime = (new Date())->sub(new DateInterval('P'.$day.'D'));
-
- if (!isset($metric->calc_type) || $metric->calc_type == Metric::CALC_SUM) {
- $queryType = 'SUM(mp.`value` * mp.`counter`) AS `value`';
- } elseif ($metric->calc_type == Metric::CALC_AVG) {
- $queryType = 'AVG(mp.`value` * mp.`counter`) AS `value`';
- }
-
- $value = 0;
-
- $points = DB::select("SELECT {$queryType} FROM {$this->getTableName()} m INNER JOIN metric_points mp ON m.id = mp.metric_id WHERE m.id = :metricId AND mp.`created_at` BETWEEN DATE_SUB(mp.`created_at`, INTERVAL 1 WEEK) AND DATE_ADD(NOW(), INTERVAL 1 DAY) AND DATE_FORMAT(mp.`created_at`, '%Y%m%d') = :timeInterval GROUP BY DATE_FORMAT(mp.`created_at`, '%Y%m%d')", [
- 'metricId' => $metric->id,
- 'timeInterval' => $dateTime->format('Ymd'),
- ]);
-
- if (isset($points[0]) && !($value = $points[0]->value)) {
- $value = 0;
- }
-
- if ($value === 0 && $metric->default_value != $value) {
- return $metric->default_value;
- }
-
- return round($value, $metric->places);
+ $queryType = $this->getQueryType($metric);
+ $points = DB::select("SELECT DATE_FORMAT({$this->getMetricPointsTable()}.`created_at`, '%Y-%m-%d') AS `key`, {$queryType} ".
+ "FROM {$this->getMetricsTable()} INNER JOIN {$this->getMetricPointsTable()} ON {$this->getMetricsTable()}.id = {$this->getMetricPointsTable()}.metric_id ".
+ "WHERE {$this->getMetricsTable()}.id = :metricId ".
+ "AND {$this->getMetricPointsTable()}.`created_at` >= DATE_SUB(NOW(), INTERVAL :day DAY) ".
+ "AND {$this->getMetricPointsTable()}.`created_at` <= NOW() ".
+ "GROUP BY DATE({$this->getMetricPointsTable()}.`created_at`) ORDER BY {$this->getMetricPointsTable()}.`created_at`", [
+ 'metricId' => $metric->id,
+ 'day' => $day,
+ ]);
+
+ return $this->mapResults($metric, $points);
}
}
diff --git a/app/Repositories/Metric/PgSqlRepository.php b/app/Repositories/Metric/PgSqlRepository.php
index 739c543b0a0e..c8d135c63170 100644
--- a/app/Repositories/Metric/PgSqlRepository.php
+++ b/app/Repositories/Metric/PgSqlRepository.php
@@ -12,9 +12,7 @@
namespace CachetHQ\Cachet\Repositories\Metric;
use CachetHQ\Cachet\Models\Metric;
-use DateInterval;
use Illuminate\Support\Facades\DB;
-use Jenssegers\Date\Date;
/**
* This is the pgsql repository class.
@@ -24,113 +22,74 @@
class PgSqlRepository extends AbstractMetricRepository implements MetricInterface
{
/**
- * Returns metrics for the last hour.
+ * Returns metrics since given minutes.
*
* @param \CachetHQ\Cachet\Models\Metric $metric
- * @param int $hour
- * @param int $minute
+ * @param int $minutes
*
- * @return int
+ * @return \Illuminate\Support\Collection
*/
- public function getPointsLastHour(Metric $metric, $hour, $minute)
+ public function getPointsSinceMinutes(Metric $metric, $minutes)
{
- $dateTime = (new Date())->sub(new DateInterval('PT'.$hour.'H'))->sub(new DateInterval('PT'.$minute.'M'));
-
- // Default metrics calculations.
- if (!isset($metric->calc_type) || $metric->calc_type == Metric::CALC_SUM) {
- $queryType = 'sum(metric_points.value * metric_points.counter)';
- } elseif ($metric->calc_type == Metric::CALC_AVG) {
- $queryType = 'avg(metric_points.value * metric_points.counter)';
- } else {
- $queryType = 'sum(metric_points.value * metric_points.counter)';
- }
-
- $value = 0;
- $query = DB::select("select {$queryType} as value FROM {$this->getTableName()} m JOIN metric_points ON metric_points.metric_id = m.id WHERE m.id = :metricId AND to_char(metric_points.created_at, 'YYYYMMDDHH24MI') = :timeInterval GROUP BY to_char(metric_points.created_at, 'HHMI')", [
- 'metricId' => $metric->id,
- 'timeInterval' => $dateTime->format('YmdHi'),
- ]);
-
- if (isset($query[0])) {
- $value = $query[0]->value;
- }
-
- if ($value === 0 && $metric->default_value != $value) {
- return $metric->default_value;
- }
-
- return round($value, $metric->places);
+ $queryType = $this->getQueryType($metric);
+ $points = DB::select("SELECT to_char({$this->getMetricPointsTable()}.created_at, 'YYYY-MM-DD HH24:MI') AS key, {$queryType} ".
+ "FROM {$this->getMetricsTable()} INNER JOIN {$this->getMetricPointsTable()} ON {$this->getMetricsTable()}.id = {$this->getMetricPointsTable()}.metric_id ".
+ "WHERE {$this->getMetricsTable()}.id = :metricId ".
+ "AND {$this->getMetricPointsTable()}.created_at >= (NOW() - INTERVAL '{$minutes}' MINUTE) ".
+ "AND {$this->getMetricPointsTable()}.created_at <= NOW() ".
+ "GROUP BY to_char({$this->getMetricPointsTable()}.created_at, 'YYYY-MM-DD HH24:MI') ".
+ "ORDER BY to_char({$this->getMetricPointsTable()}.created_at, 'YYYY-MM-DD HH24:MI')", [
+ 'metricId' => $metric->id,
+ ]);
+
+ return $this->mapResults($metric, $points);
}
/**
- * Returns metrics for a given hour.
+ * Returns metrics since given hour.
*
* @param \CachetHQ\Cachet\Models\Metric $metric
* @param int $hour
*
- * @return int
+ * @return \Illuminate\Support\Collection
*/
- public function getPointsByHour(Metric $metric, $hour)
+ public function getPointsSinceHour(Metric $metric, $hour)
{
- $dateTime = (new Date())->sub(new DateInterval('PT'.$hour.'H'));
-
- // Default metrics calculations.
- if (!isset($metric->calc_type) || $metric->calc_type == Metric::CALC_SUM) {
- $queryType = 'sum(metric_points.value * metric_points.counter)';
- } elseif ($metric->calc_type == Metric::CALC_AVG) {
- $queryType = 'avg(metric_points.value * metric_points.counter)';
- } else {
- $queryType = 'sum(metric_points.value * metric_points.counter)';
- }
-
- $value = 0;
- $query = DB::select("select {$queryType} as value FROM {$this->getTableName()} m JOIN metric_points ON metric_points.metric_id = m.id WHERE metric_points.metric_id = :metricId AND to_char(metric_points.created_at, 'YYYYMMDDHH24') = :timeInterval GROUP BY to_char(metric_points.created_at, 'H')", [
- 'metricId' => $metric->id,
- 'timeInterval' => $dateTime->format('YmdH'),
- ]);
-
- if (isset($query[0])) {
- $value = $query[0]->value;
- }
-
- if ($value === 0 && $metric->default_value != $value) {
- return $metric->default_value;
- }
-
- return round($value, $metric->places);
+ $queryType = $this->getQueryType($metric);
+ $points = DB::select("SELECT to_char({$this->getMetricPointsTable()}.created_at, 'YYYY-MM-DD HH24:00') AS key, {$queryType} ".
+ "FROM {$this->getMetricsTable()} INNER JOIN {$this->getMetricPointsTable()} ON {$this->getMetricsTable()}.id = {$this->getMetricPointsTable()}.metric_id ".
+ "WHERE {$this->getMetricsTable()}.id = :metricId ".
+ "AND {$this->getMetricPointsTable()}.created_at >= (NOW() - INTERVAL '{$hour}' HOUR) ".
+ "AND {$this->getMetricPointsTable()}.created_at <= NOW() ".
+ "GROUP BY to_char({$this->getMetricPointsTable()}.created_at, 'YYYY-MM-DD HH24:00') ".
+ "ORDER BY to_char({$this->getMetricPointsTable()}.created_at, 'YYYY-MM-DD HH24:00')", [
+ 'metricId' => $metric->id,
+ ]);
+
+ return $this->mapResults($metric, $points);
}
/**
- * Returns metrics for the week.
+ * Returns metrics since given day.
*
* @param \CachetHQ\Cachet\Models\Metric $metric
+ * @param int $day
*
- * @return int
+ * @return \Illuminate\Support\Collection
*/
- public function getPointsForDayInWeek(Metric $metric, $day)
+ public function getPointsSinceDay(Metric $metric, $day)
{
- $dateTime = (new Date())->sub(new DateInterval('P'.$day.'D'));
-
- if (!isset($metric->calc_type) || $metric->calc_type == Metric::CALC_SUM) {
- $queryType = 'sum(mp.value * mp.counter) AS value';
- } elseif ($metric->calc_type == Metric::CALC_AVG) {
- $queryType = 'avg(mp.value * mp.counter) AS value';
- }
-
- $value = 0;
- $points = DB::select("SELECT {$queryType} FROM {$this->getTableName()} m INNER JOIN metric_points mp ON m.id = mp.metric_id WHERE m.id = :metricId AND mp.created_at BETWEEN (mp.created_at - interval '1 week') AND (now() + interval '1 day') AND to_char(mp.created_at, 'YYYYMMDD') = :timeInterval GROUP BY to_char(mp.created_at, 'YYYYMMDD')", [
- 'metricId' => $metric->id,
- 'timeInterval' => $dateTime->format('Ymd'),
- ]);
-
- if (isset($points[0]) && !($value = $points[0]->value)) {
- $value = 0;
- }
-
- if ($value === 0 && $metric->default_value != $value) {
- return $metric->default_value;
- }
-
- return round($value, $metric->places);
+ $queryType = $this->getQueryType($metric);
+ $points = DB::select("SELECT to_char({$this->getMetricPointsTable()}.created_at, 'YYYY-MM-DD HH24:00') AS key, {$queryType} ".
+ "FROM {$this->getMetricsTable()} INNER JOIN {$this->getMetricPointsTable()} ON {$this->getMetricsTable()}.id = {$this->getMetricPointsTable()}.metric_id ".
+ "WHERE {$this->getMetricsTable()}.id = :metricId ".
+ "AND {$this->getMetricPointsTable()}.created_at >= (DATE(NOW()) - INTERVAL '{$day}' DAY) ".
+ "AND {$this->getMetricPointsTable()}.created_at <= DATE(NOW()) ".
+ "GROUP BY to_char({$this->getMetricPointsTable()}.created_at, 'YYYY-MM-DD HH24:00')".
+ "ORDER BY to_char({$this->getMetricPointsTable()}.created_at, 'YYYY-MM-DD HH24:00')", [
+ 'metricId' => $metric->id,
+ ]);
+
+ return $this->mapResults($metric, $points);
}
}
diff --git a/app/Repositories/Metric/SqliteRepository.php b/app/Repositories/Metric/SqliteRepository.php
index 403d776110af..d979e084ac66 100644
--- a/app/Repositories/Metric/SqliteRepository.php
+++ b/app/Repositories/Metric/SqliteRepository.php
@@ -12,123 +12,84 @@
namespace CachetHQ\Cachet\Repositories\Metric;
use CachetHQ\Cachet\Models\Metric;
-use DateInterval;
use Illuminate\Support\Facades\DB;
-use Jenssegers\Date\Date;
+/**
+ * This is the sqlite repository class.
+ *
+ * @author James Brooks
+ */
class SqliteRepository extends AbstractMetricRepository implements MetricInterface
{
/**
- * Returns metrics for the last hour.
+ * Returns metrics since given minutes.
*
* @param \CachetHQ\Cachet\Models\Metric $metric
- * @param int $hour
- * @param int $minute
+ * @param int $minutes
*
- * @return int
+ * @return \Illuminate\Support\Collection
*/
- public function getPointsLastHour(Metric $metric, $hour, $minute)
+ public function getPointsSinceMinutes(Metric $metric, $minutes)
{
- $dateTime = (new Date())->sub(new DateInterval('PT'.$hour.'H'))->sub(new DateInterval('PT'.$minute.'M'));
-
- // Default metrics calculations.
- if (!isset($metric->calc_type) || $metric->calc_type == Metric::CALC_SUM) {
- $queryType = 'sum(metric_points.value * metric_points.counter)';
- } elseif ($metric->calc_type == Metric::CALC_AVG) {
- $queryType = 'avg(metric_points.value * metric_points.counter)';
- } else {
- $queryType = 'sum(metric_points.value * metric_points.counter)';
- }
-
- $value = 0;
- $query = DB::select("select {$queryType} as value FROM {$this->getTableName()} m JOIN metric_points ON metric_points.metric_id = m.id WHERE m.id = :metricId AND strftime('%Y%m%d%H%M', metric_points.created_at) = :timeInterval GROUP BY strftime('%H%M', metric_points.created_at)", [
- 'metricId' => $metric->id,
- 'timeInterval' => $dateTime->format('YmdHi'),
- ]);
-
- if (isset($query[0])) {
- $value = $query[0]->value;
- }
-
- if ($value === 0 && $metric->default_value != $value) {
- return $metric->default_value;
- }
-
- return round($value, $metric->places);
+ $queryType = $this->getQueryType($metric);
+ $points = DB::select("SELECT strftime('%Y-%m-%d %H:%M', {$this->getMetricPointsTable()}.`created_at`) AS `key`, {$queryType} ".
+ "FROM {$this->getMetricsTable()} ".
+ "INNER JOIN {$this->getMetricPointsTable()} ON {$this->getMetricsTable()}.id = {$this->getMetricPointsTable()}.metric_id ".
+ "WHERE {$this->getMetricsTable()}.id = :metricId ".
+ "AND {$this->getMetricPointsTable()}.`created_at` >= datetime('now', 'localtime', '-{$minutes} minutes') ".
+ "AND {$this->getMetricPointsTable()}.`created_at` <= datetime('now', 'localtime') ".
+ "GROUP BY strftime('%H', {$this->getMetricPointsTable()}.`created_at`), strftime('%M', {$this->getMetricPointsTable()}.`created_at`) ".
+ "ORDER BY {$this->getMetricPointsTable()}.`created_at`", [
+ 'metricId' => $metric->id,
+ ]);
+
+ return $this->mapResults($metric, $points);
}
/**
- * Returns metrics for a given hour.
+ * Returns metrics since given hour.
*
* @param \CachetHQ\Cachet\Models\Metric $metric
* @param int $hour
*
- * @return int
+ * @return \Illuminate\Support\Collection
*/
- public function getPointsByHour(Metric $metric, $hour)
+ public function getPointsSinceHour(Metric $metric, $hour)
{
- $dateTime = (new Date())->sub(new DateInterval('PT'.$hour.'H'));
-
- // Default metrics calculations.
- if (!isset($metric->calc_type) || $metric->calc_type == Metric::CALC_SUM) {
- $queryType = 'sum(metric_points.value * metric_points.counter)';
- } elseif ($metric->calc_type == Metric::CALC_AVG) {
- $queryType = 'avg(metric_points.value * metric_points.counter)';
- } else {
- $queryType = 'sum(metric_points.value * metric_points.counter)';
- }
-
- $value = 0;
- $query = DB::select("select {$queryType} as value FROM {$this->getTableName()} m JOIN metric_points ON metric_points.metric_id = m.id WHERE m.id = :metricId AND strftime('%Y%m%d%H', metric_points.created_at) = :timeInterval GROUP BY strftime('%H', metric_points.created_at)", [
- 'metricId' => $metric->id,
- 'timeInterval' => $dateTime->format('YmdH'),
- ]);
-
- if (isset($query[0])) {
- $value = $query[0]->value;
- }
-
- if ($value === 0 && $metric->default_value != $value) {
- return $metric->default_value;
- }
-
- return round($value, $metric->places);
+ $queryType = $this->getQueryType($metric);
+ $points = DB::select("SELECT strftime('%Y-%m-%d %H:00', {$this->getMetricPointsTable()}.`created_at`) AS `key`, {$queryType} ".
+ "FROM {$this->getMetricsTable()} INNER JOIN {$this->getMetricPointsTable()} ON {$this->getMetricsTable()}.id = {$this->getMetricPointsTable()}.metric_id ".
+ "WHERE {$this->getMetricsTable()}.id = :metricId ".
+ "AND {$this->getMetricPointsTable()}.`created_at` >= datetime('now', 'localtime', '-{$hour} hours') ".
+ "AND {$this->getMetricPointsTable()}.`created_at` <= datetime('now', 'localtime') ".
+ "GROUP BY strftime('%H', {$this->getMetricPointsTable()}.`created_at`) ORDER BY {$this->getMetricPointsTable()}.`created_at`", [
+ 'metricId' => $metric->id,
+ ]);
+
+ return $this->mapResults($metric, $points);
}
/**
- * Returns metrics for the week.
+ * Returns metrics since given day.
*
* @param \CachetHQ\Cachet\Models\Metric $metric
+ * @param int $day
*
- * @return int
+ * @return \Illuminate\Support\Collection
*/
- public function getPointsForDayInWeek(Metric $metric, $day)
+ public function getPointsSinceDay(Metric $metric, $day)
{
- $dateTime = (new Date())->sub(new DateInterval('P'.$day.'D'));
-
- // Default metrics calculations.
- if (!isset($metric->calc_type) || $metric->calc_type == Metric::CALC_SUM) {
- $queryType = 'sum(metric_points.value * metric_points.counter)';
- } elseif ($metric->calc_type == Metric::CALC_AVG) {
- $queryType = 'avg(metric_points.value * metric_points.counter)';
- } else {
- $queryType = 'sum(metric_points.value * metric_points.counter)';
- }
-
- $value = 0;
- $query = DB::select("select {$queryType} as value FROM {$this->getTableName()} m JOIN metric_points ON metric_points.metric_id = m.id WHERE m.id = :metricId AND metric_points.created_at > date('now', '-7 day') AND strftime('%Y%m%d', metric_points.created_at) = :timeInterval GROUP BY strftime('%Y%m%d', metric_points.created_at)", [
- 'metricId' => $metric->id,
- 'timeInterval' => $dateTime->format('Ymd'),
- ]);
-
- if (isset($query[0])) {
- $value = $query[0]->value;
- }
-
- if ($value === 0 && $metric->default_value != $value) {
- return $metric->default_value;
- }
-
- return round($value, $metric->places);
+ $queryType = $this->getQueryType($metric);
+ $points = DB::select("SELECT strftime('%Y-%m-%d', {$this->getMetricPointsTable()}.`created_at`) AS `key`, {$queryType} ".
+ "FROM {$this->getMetricsTable()} INNER JOIN {$this->getMetricPointsTable()} ON {$this->getMetricsTable()}.id = {$this->getMetricPointsTable()}.metric_id ".
+ "WHERE {$this->getMetricsTable()}.id = :metricId ".
+ "AND {$this->getMetricPointsTable()}.`created_at` >= datetime('now', 'localtime', '-{$day} days') ".
+ "AND {$this->getMetricPointsTable()}.`created_at` <= datetime('now', 'localtime') ".
+ "GROUP BY DATE({$this->getMetricPointsTable()}.`created_at`) ".
+ "ORDER BY {$this->getMetricPointsTable()}.`created_at`", [
+ 'metricId' => $metric->id,
+ ]);
+
+ return $this->mapResults($metric, $points);
}
}
diff --git a/app/Dates/DateFactory.php b/app/Services/Dates/DateFactory.php
similarity index 92%
rename from app/Dates/DateFactory.php
rename to app/Services/Dates/DateFactory.php
index a853daaa020f..4ccbcb493d4e 100644
--- a/app/Dates/DateFactory.php
+++ b/app/Services/Dates/DateFactory.php
@@ -9,11 +9,17 @@
* file that was distributed with this source code.
*/
-namespace CachetHQ\Cachet\Dates;
+namespace CachetHQ\Cachet\Services\Dates;
use DateTimeZone;
use Jenssegers\Date\Date;
+/**
+ * This is the date factory class.
+ *
+ * @author Graham Campbell
+ * @author James Brooks
+ */
class DateFactory
{
/**
diff --git a/app/Services/Modules/Manager.php b/app/Services/Modules/Manager.php
deleted file mode 100644
index 61a276c68a2d..000000000000
--- a/app/Services/Modules/Manager.php
+++ /dev/null
@@ -1,80 +0,0 @@
-
- */
-class Manager
-{
- /**
- * Groups the modules.
- *
- * @param array $modules
- * @param array $groups
- *
- * @return array
- */
- public function groupModules(array $modules, array $groups = [])
- {
- $grouped = [];
- $length = count($modules);
- foreach ($modules as $order => $module) {
- if (!is_array($module) || empty($module['group'])) {
- $order = array_get($module, 'order', PHP_INT_MAX - $length + $order);
-
- $grouped[] = [$module, 'order' => $order];
-
- continue;
- }
-
- $group = $module['group'];
- if (empty($grouped[$group])) {
- $grouped[$group] = [$module];
-
- continue;
- }
-
- $grouped[$group][] = $module;
- }
-
- foreach ($groups as $group => $order) {
- if (empty($grouped[$group])) {
- continue;
- }
-
- $grouped[$group]['order'] = $order;
- }
-
- return $grouped;
- }
-
- /**
- * Orders the modules.
- *
- * @param array $modules
- *
- * @return array
- */
- public function orderModules($modules)
- {
- $modules = array_numeric_sort($modules);
-
- foreach ($modules as $group => $subModules) {
- $modules[$group] = array_numeric_sort($subModules);
- }
-
- return $modules;
- }
-}
diff --git a/app/Services/Modules/Renderer.php b/app/Services/Modules/Renderer.php
deleted file mode 100644
index b8fe3df339b9..000000000000
--- a/app/Services/Modules/Renderer.php
+++ /dev/null
@@ -1,75 +0,0 @@
-
- */
-class Renderer
-{
- /**
- * Render the modules.
- *
- * @param \Illuminate\Contracts\View\Factory $factory
- * @param array $data
- * @param array $modules
- * @param string|null $group
- *
- * @return string
- */
- public function renderModules(Factory $factory, array $data, array $modules, $group = null)
- {
- if ($group !== null) {
- if (empty($modules[$group])) {
- return '';
- }
-
- return $this->renderModulesGroup($factory, $data, $modules[$group]);
- }
-
- return array_reduce(
- array_numeric_sort($modules),
- function ($reduce, $module) use ($factory, $data) {
- return $reduce.$this->renderModulesGroup($factory, $data, $module);
- },
- ''
- );
- }
-
- /**
- * Render a group of modules.
- *
- * @param \Illuminate\Contracts\View\Factory $factory
- * @param array $data
- * @param array $modules
- *
- * @return string
- */
- protected function renderModulesGroup(Factory $factory, array $data, array $modules)
- {
- return array_reduce(
- array_numeric_sort($modules),
- function ($reduce, $module) use ($factory, $data) {
- if (empty($module['partial'])) {
- return $reduce;
- }
-
- return $reduce.$factory->make($module['partial'], $data)->render();
- },
- ''
- );
- }
-}
diff --git a/app/Settings/ReadException.php b/app/Settings/ReadException.php
new file mode 100644
index 000000000000..86de0ae3f9e1
--- /dev/null
+++ b/app/Settings/ReadException.php
@@ -0,0 +1,34 @@
+
+ */
+class ReadException extends SettingsException
+{
+ /**
+ * Create a new read exception instance.
+ *
+ * @param \Exception $e
+ *
+ * @return void
+ */
+ public function __construct(Exception $e)
+ {
+ parent::__construct('Unable to read Cachet settings', $e);
+ }
+}
diff --git a/app/Settings/Repository.php b/app/Settings/Repository.php
index 9b44173a3b86..e6d54038ee3f 100644
--- a/app/Settings/Repository.php
+++ b/app/Settings/Repository.php
@@ -12,6 +12,7 @@
namespace CachetHQ\Cachet\Settings;
use CachetHQ\Cachet\Models\Setting;
+use Exception;
/**
* This is the settings repository class.
@@ -21,6 +22,15 @@
*/
class Repository
{
+ /**
+ * Array of numerical settings that are not bools.
+ *
+ * @var string[]
+ */
+ protected $notBooleans = [
+ 'app_incident_days',
+ ];
+
/**
* The eloquent model instance.
*
@@ -50,11 +60,19 @@ public function __construct(Setting $model)
/**
* Returns a setting from the database.
*
+ * @throws \CachetHQ\Cachet\Settings\ReadException
+ *
* @return array
*/
public function all()
{
- return $this->model->all(['name', 'value'])->pluck('value', 'name')->toArray();
+ try {
+ return $this->model->all(['name', 'value'])->pluck('value', 'name')->map(function ($value, $name) {
+ return $this->castSetting($name, $value);
+ })->toArray();
+ } catch (Exception $e) {
+ throw new ReadException($e);
+ }
}
/**
@@ -63,16 +81,22 @@ public function all()
* @param string $name
* @param string|null $value
*
+ * @throws \CachetHQ\Cachet\Settings\WriteException
+ *
* @return void
*/
public function set($name, $value)
{
$this->stale = true;
- if ($value === null) {
- $this->model->where('name', $name)->delete();
- } else {
- $this->model->updateOrCreate(compact('name'), compact('value'));
+ try {
+ if ($value === null) {
+ $this->model->where('name', '=', $name)->delete();
+ } else {
+ $this->model->updateOrCreate(compact('name'), compact('value'));
+ }
+ } catch (Exception $e) {
+ throw new WriteException($e);
}
}
@@ -82,15 +106,21 @@ public function set($name, $value)
* @param string $name
* @param mixed $default
*
+ * @throws \CachetHQ\Cachet\Settings\ReadException
+ *
* @return mixed
*/
public function get($name, $default = null)
{
- if ($setting = $this->model->where('name', $name)->first()) {
- return $setting->value;
+ try {
+ if ($setting = $this->model->where('name', '=', $name)->first()) {
+ return $this->castSetting($name, $setting->value);
+ }
+
+ return $default;
+ } catch (Exception $e) {
+ throw new ReadException($e);
}
-
- return $default;
}
/**
@@ -98,25 +128,37 @@ public function get($name, $default = null)
*
* @param string $name
*
+ * @throws \CachetHQ\Cachet\Settings\WriteException
+ *
* @return void
*/
public function delete($name)
{
$this->stale = true;
- $this->model->where('name', $name)->delete();
+ try {
+ $this->model->where('name', '=', $name)->delete();
+ } catch (Exception $e) {
+ throw new WriteException($e);
+ }
}
/**
* Clear all settings.
*
+ * @throws \CachetHQ\Cachet\Settings\WriteException
+ *
* @return void
*/
public function clear()
{
$this->stale = true;
- $this->model->query()->delete();
+ try {
+ $this->model->query()->delete();
+ } catch (Exception $e) {
+ throw new WriteException($e);
+ }
}
/**
@@ -128,4 +170,25 @@ public function stale()
{
return $this->stale;
}
+
+ /**
+ * Cast setting as the applicable type.
+ *
+ * @param string $key
+ * @param string $value
+ *
+ * @return mixed
+ */
+ protected function castSetting($key, $value)
+ {
+ if (is_null($value)) {
+ return $value;
+ }
+
+ if (!in_array($key, $this->notBooleans) && in_array($value, ['0', '1'])) {
+ return (bool) $value;
+ }
+
+ return $value;
+ }
}
diff --git a/app/Settings/SettingsException.php b/app/Settings/SettingsException.php
new file mode 100644
index 000000000000..1716ea366d9d
--- /dev/null
+++ b/app/Settings/SettingsException.php
@@ -0,0 +1,35 @@
+
+ */
+class SettingsException extends Exception
+{
+ /**
+ * Create a new write exception instance.
+ *
+ * @param string $m
+ * @param \Exception $e
+ *
+ * @return void
+ */
+ public function __construct(string $m, Exception $e)
+ {
+ parent::__construct($m, 0, $e);
+ }
+}
diff --git a/app/Settings/WriteException.php b/app/Settings/WriteException.php
new file mode 100644
index 000000000000..baa41ff7ac1d
--- /dev/null
+++ b/app/Settings/WriteException.php
@@ -0,0 +1,34 @@
+
+ */
+class WriteException extends SettingsException
+{
+ /**
+ * Create a new write exception instance.
+ *
+ * @param \Exception $e
+ *
+ * @return void
+ */
+ public function __construct(Exception $e)
+ {
+ parent::__construct('Unable to write Cachet settings', $e);
+ }
+}
diff --git a/app/Subscribers/CommandSubscriber.php b/app/Subscribers/CommandSubscriber.php
index 7b7acb6ff664..a879361999a7 100644
--- a/app/Subscribers/CommandSubscriber.php
+++ b/app/Subscribers/CommandSubscriber.php
@@ -15,10 +15,7 @@
use CachetHQ\Cachet\Bus\Events\System\SystemWasResetEvent;
use CachetHQ\Cachet\Bus\Events\System\SystemWasUpdatedEvent;
use CachetHQ\Cachet\Settings\Cache;
-use Carbon\Carbon;
-use Exception;
use Illuminate\Console\Command;
-use Illuminate\Contracts\Config\Repository;
use Illuminate\Contracts\Events\Dispatcher;
/**
@@ -36,25 +33,16 @@ class CommandSubscriber
*/
protected $cache;
- /**
- * The config repository instance.
- *
- * @var \Illuminate\Contracts\Config\Repository
- */
- protected $config;
-
/**
* Create a new command subscriber instance.
*
- * @param \CachetHQ\Cachet\Settings\Cache $cache
- * @param \Illuminate\Contracts\Config\Repository $config
+ * @param \CachetHQ\Cachet\Settings\Cache $cache
*
* @return void
*/
- public function __construct(Cache $cache, Repository $config)
+ public function __construct(Cache $cache)
{
$this->cache = $cache;
- $this->config = $config;
}
/**
@@ -69,6 +57,15 @@ public function subscribe(Dispatcher $events)
$events->listen('command.installing', __CLASS__.'@fireInstallingCommand', 5);
$events->listen('command.updating', __CLASS__.'@fireUpdatingCommand', 5);
$events->listen('command.resetting', __CLASS__.'@fireResettingCommand', 5);
+ $events->listen('command.generatekey', __CLASS__.'@onGenerateKey');
+ $events->listen('command.cacheconfig', __CLASS__.'@onCacheConfig');
+ $events->listen('command.cacheroutes', __CLASS__.'@onCacheRoutes');
+ $events->listen('command.publishvendors', __CLASS__.'@onPublishVendors');
+ $events->listen('command.resetmigrations', __CLASS__.'@onResetMigrations');
+ $events->listen('command.runmigrations', __CLASS__.'@onRunMigrations');
+ $events->listen('command.runseeding', __CLASS__.'@onRunSeeding');
+ $events->listen('command.linkstorage', __CLASS__.'@onLinkStorage');
+ $events->listen('command.updatecache', __CLASS__.'@onUpdateCache');
}
/**
@@ -120,7 +117,7 @@ public function fireResettingCommand(Command $command)
}
/**
- * Handle the main bulk of the command, clear the settings and backup the database.
+ * Handle the main bulk of the command, clear the settings.
*
* @param \Illuminate\Console\Command $command
*
@@ -133,29 +130,117 @@ protected function handleMainCommand(Command $command)
$this->cache->clear();
$command->line('Settings cache cleared!');
+ }
- // SQLite does not backup.
- if ($this->config->get('database.default') === 'sqlite') {
- $command->line('Backup skipped: SQLite is not supported.');
+ /**
+ * Handle a command.generatekey event.
+ *
+ * @param \Illuminate\Console\Command $command
+ *
+ * @return void
+ */
+ public function onGenerateKey(Command $command)
+ {
+ $command->call('key:generate');
+ }
- return;
- }
+ /**
+ * Handle a command.cacheconfig event.
+ *
+ * @param \Illuminate\Console\Command $command
+ *
+ * @return void
+ */
+ public function onCacheConfig(Command $command)
+ {
+ $command->call('config:cache');
+ }
+
+ /**
+ * Handle a command.cacheroutes event.
+ *
+ * @param \Illuminate\Console\Command $command
+ *
+ * @return void
+ */
+ public function onCacheRoutes(Command $command)
+ {
+ $command->call('route:cache');
+ }
+
+ /**
+ * Handle a command.publishvendors event.
+ *
+ * @param \Illuminate\Console\Command $command
+ *
+ * @return void
+ */
+ public function onPublishVendors(Command $command)
+ {
+ $command->call('vendor:publish', ['--all' => true]);
+ }
+
+ /**
+ * Handle a command.resetmigrations event.
+ *
+ * @param \Illuminate\Console\Command $command
+ *
+ * @return void
+ */
+ public function onResetMigrations(Command $command)
+ {
+ $command->call('migrate:reset', ['--force' => true]);
+ }
- $command->line('Backing up database...');
-
- try {
- $command->call('db:backup', [
- '--compression' => 'gzip',
- '--database' => $this->config->get('database.default'),
- '--destination' => 'local',
- '--destinationPath' => Carbon::now()->format('Y-m-d H.i.s'),
- '--no-interaction' => true,
- ]);
- } catch (Exception $e) {
- $command->error($e->getMessage());
- $command->line('Backup skipped!');
+ /**
+ * Handle a command.runmigrations event.
+ *
+ * @param \Illuminate\Console\Command $command
+ *
+ * @return void
+ */
+ public function onRunMigrations(Command $command)
+ {
+ $command->call('migrate', ['--force' => true]);
+ }
+
+ /**
+ * Handle a command.runseeding event.
+ *
+ * @param \Illuminate\Console\Command $command
+ *
+ * @return void
+ */
+ public function onRunSeeding(Command $command)
+ {
+ $command->call('db:seed', ['--force' => true]);
+ }
+
+ /**
+ * Handle a command.linkstorage event.
+ *
+ * @param \Illuminate\Console\Command $command
+ *
+ * @return void
+ */
+ public function onLinkStorage(Command $command)
+ {
+ if ($command->getApplication()->has('storage:link')) {
+ $command->call('storage:link');
}
+ }
- $command->line('Backup completed!');
+ /**
+ * Handle a command.updatecache event.
+ *
+ * @param \Illuminate\Console\Command $command
+ *
+ * @return void
+ */
+ public function onUpdateCache(Command $command)
+ {
+ $command->line('Clearing cache...');
+ $command->call('cache:clear');
+ $command->info('Cache cleared!');
}
}
diff --git a/app/helpers.php b/app/helpers.php
index e8ffd41ed402..d1f032545d48 100644
--- a/app/helpers.php
+++ b/app/helpers.php
@@ -9,10 +9,33 @@
* file that was distributed with this source code.
*/
+use CachetHQ\Cachet\Settings\Repository;
+use Illuminate\Contracts\Bus\Dispatcher;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Request;
use Jenssegers\Date\Date;
+if (!function_exists('setting')) {
+ /**
+ * Get a setting, or the default value.
+ *
+ * @param string $name
+ * @param mixed $default
+ *
+ * @return mixed
+ */
+ function setting($name, $default = null)
+ {
+ static $settings = [];
+
+ if (isset($settings[$name])) {
+ return $settings[$name];
+ }
+
+ return $settings[$name] = app(Repository::class)->get($name, $default);
+ }
+}
+
if (!function_exists('set_active')) {
/**
* Set active class if request is in path.
@@ -51,22 +74,6 @@ function formatted_date($date)
}
}
-if (!function_exists('subscribers_enabled')) {
- /**
- * Is the subscriber functionality enabled and configured.
- *
- * @return bool
- */
- function subscribers_enabled()
- {
- $isEnabled = Config::get('setting.enable_subscribers', false);
- $mailAddress = Config::get('mail.from.address', false);
- $mailFrom = Config::get('mail.from.name', false);
-
- return $isEnabled && $mailAddress && $mailFrom;
- }
-}
-
if (!function_exists('color_darken')) {
/**
* Darken a color.
@@ -107,35 +114,83 @@ function color_darken($hex, $percent)
*/
function color_contrast($hexcolor)
{
- $r = hexdec(substr($hexcolor, 0, 2));
- $g = hexdec(substr($hexcolor, 2, 2));
- $b = hexdec(substr($hexcolor, 4, 2));
+ $r = ctype_xdigit(substr($hexcolor, 0, 2));
+ $g = ctype_xdigit(substr($hexcolor, 2, 2));
+ $b = ctype_xdigit(substr($hexcolor, 4, 2));
$yiq = (($r * 100) + ($g * 400) + ($b * 114)) / 1000;
return ($yiq >= 128) ? 'black' : 'white';
}
}
-if (!function_exists('array_numeric_sort')) {
+if (!function_exists('cachet_route_generator')) {
/**
- * Numerically sort an array based on a specific key.
+ * Generate the route string.
*
- * @param array $array
- * @param string $key
+ * @param string $name
+ * @param string $method
+ * @param string $domain
*
- * @return array
+ * @return string
*/
- function array_numeric_sort(array $array = [], $key = 'order')
+ function cachet_route_generator($name, $method = 'get', $domain = 'core')
{
- uasort($array, function ($a, $b) use ($key) {
- $a = array_get($a, $key, PHP_INT_MAX);
- $b = array_get($b, $key, PHP_INT_MAX);
+ return "{$domain}::{$method}:{$name}";
+ }
+}
- $default = PHP_MAJOR_VERSION < 7 ? 1 : 0;
+if (!function_exists('cachet_route')) {
+ /**
+ * Generate a URL to a named route, which resides in a given domain.
+ *
+ * @param string $name
+ * @param array $parameters
+ * @param string $method
+ * @param string $domain
+ *
+ * @return string
+ */
+ function cachet_route($name, $parameters = [], $method = 'get', $domain = 'core')
+ {
+ return app('url')->route(
+ cachet_route_generator($name, $method, $domain),
+ $parameters,
+ true
+ );
+ }
+}
- return $a < $b ? -1 : ($a === $b ? $default : 1);
- });
+if (!function_exists('cachet_redirect')) {
+ /**
+ * Create a new redirect response to a named route, which resides in a given domain.
+ *
+ * @param string $name
+ * @param array $parameters
+ * @param int $status
+ * @param array $headers
+ * @param string $method
+ * @param string $domain
+ *
+ * @return \Illuminate\Http\RedirectResponse
+ */
+ function cachet_redirect($name, $parameters = [], $status = 302, $headers = [], $method = 'get', $domain = 'core')
+ {
+ $url = cachet_route($name, $parameters, $method, $domain);
+
+ return app('redirect')->to($url, $status, $headers);
+ }
+}
- return $array;
+if (!function_exists('execute')) {
+ /**
+ * Send the given command to the dispatcher for execution.
+ *
+ * @param object $command
+ *
+ * @return void
+ */
+ function execute($command)
+ {
+ return app(Dispatcher::class)->dispatchNow($command);
}
}
diff --git a/artisan b/artisan
index d00c7161e88b..d294ad8bf35c 100644
--- a/artisan
+++ b/artisan
@@ -28,11 +28,11 @@ $app = require_once __DIR__.'/bootstrap/app.php';
|
*/
-$kernel = $app->make('Illuminate\Contracts\Console\Kernel');
+$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
$status = $kernel->handle(
- $input = new Symfony\Component\Console\Input\ArgvInput(),
- new Symfony\Component\Console\Output\ConsoleOutput()
+ $input = new Symfony\Component\Console\Input\ArgvInput(),
+ new Symfony\Component\Console\Output\ConsoleOutput()
);
/*
@@ -40,7 +40,7 @@ $status = $kernel->handle(
| Shutdown The Application
|--------------------------------------------------------------------------
|
-| Once Artisan has finished running. We will fire off the shutdown events
+| Once Artisan has finished running, we will fire off the shutdown events
| so that any final work may be done by the application before we shut
| down the process. This is the last thing to happen to the request.
|
diff --git a/bootstrap/app.php b/bootstrap/app.php
index 524cdccff793..2b2ff8cb519f 100644
--- a/bootstrap/app.php
+++ b/bootstrap/app.php
@@ -22,11 +22,11 @@
|
*/
-$app->singleton('Illuminate\Contracts\Http\Kernel', 'CachetHQ\Cachet\Http\Kernel');
+$app->singleton(Illuminate\Contracts\Http\Kernel::class, CachetHQ\Cachet\Http\Kernel::class);
-$app->singleton('Illuminate\Contracts\Console\Kernel', 'CachetHQ\Cachet\Console\Kernel');
+$app->singleton(Illuminate\Contracts\Console\Kernel::class, CachetHQ\Cachet\Console\Kernel::class);
-$app->singleton('Illuminate\Contracts\Debug\ExceptionHandler', 'GrahamCampbell\Exceptions\ExceptionHandler');
+$app->singleton(Illuminate\Contracts\Debug\ExceptionHandler::class, GrahamCampbell\Exceptions\ExceptionHandler::class);
/*
|--------------------------------------------------------------------------
diff --git a/composer.json b/composer.json
index 801ce20d8e7f..ea6814120e24 100644
--- a/composer.json
+++ b/composer.json
@@ -1,7 +1,13 @@
{
"name": "cachethq/cachet",
"description": "An open source status page system, for everyone.",
- "keywords": ["laravel", "cachet", "alt-three", "status", "page"],
+ "keywords": [
+ "laravel",
+ "cachet",
+ "alt-three",
+ "status",
+ "page"
+ ],
"type": "project",
"license": "BSD-3-Clause",
"authors": [
@@ -18,42 +24,52 @@
"email": "joe@alt-three.com"
}
],
+ "replace": {
+ "paragonie/random_compat": "*",
+ "symfony/polyfill-mbstring": "*"
+ },
"require": {
- "php": ">=5.5.9",
+ "php": "^7.1.3",
+ "ext-mbstring": "*",
+ "ext-openssl": "*",
"ext-xml": "*",
- "alt-three/badger": "^3.1",
- "alt-three/bus": "^1.1",
- "alt-three/emoji": "^3.1",
- "alt-three/throttle": "^1.0",
- "alt-three/validator": "^1.5",
+ "alt-three/bus": "^4.1",
+ "cachethq/badger": "^2.0",
+ "cachethq/emoji": "^3.0",
+ "cachethq/twitter": "^3.0",
+ "alt-three/validator": "^4.1",
"aws/aws-sdk-php": "^3.7",
- "backup-manager/laravel": "^1.1",
- "barryvdh/laravel-cors": "^0.8",
- "doctrine/dbal": "^2.5",
- "fedeisas/laravel-mail-css-inliner": "^1.5",
- "fideloper/proxy": "^3.1",
- "graham-campbell/binput": "^3.4",
- "graham-campbell/core": "^5.1",
- "graham-campbell/exceptions": "^8.6",
- "graham-campbell/markdown": "^6.1",
- "guzzlehttp/guzzle": "^6.2.1",
- "jenssegers/date": "^3.2",
- "laravel/framework": "5.2.43",
- "mccool/laravel-auto-presenter": "^4.3",
- "pragmarx/google2fa": "^0.7.1",
+ "barryvdh/laravel-cors": "^0.11.0",
+ "bugsnag/bugsnag-laravel": "^2.15",
+ "chillerlan/php-qrcode": "^2.0",
+ "doctrine/dbal": "2.9.*",
+ "fideloper/proxy": "^4.0",
+ "graham-campbell/binput": "^6.0",
+ "graham-campbell/exceptions": "^11.1",
+ "graham-campbell/markdown": "^11.2",
+ "guzzlehttp/guzzle": "^6.3.3",
+ "jenssegers/date": "^3.4",
+ "laravel/framework": "5.7.*",
+ "laravel/tinker": "^1.0",
+ "mccool/laravel-auto-presenter": "^7.1",
+ "nexmo/client": "^1.5",
+ "pragmarx/google2fa": "^5.0",
"predis/predis": "^1.1",
- "rcrowe/twigbridge": "^0.9.2",
- "roumen/feed": "^2.10.4"
+ "twig/twig": "^2.13"
},
"require-dev": {
- "alt-three/testbench": "^1.8",
- "filp/whoops": "^2.1",
- "fzaninotto/faker": "^1.6",
- "graham-campbell/testbench-core": "^1.1",
- "mockery/mockery": "0.9.5",
- "phpunit/phpunit": "4.8.21",
- "symfony/css-selector": "^3.0",
- "symfony/dom-crawler": "^3.0"
+ "ext-sqlite3": "*",
+ "alt-three/testbench": "5.0.x-dev",
+ "barryvdh/laravel-debugbar": "^3.2",
+ "filp/whoops": "^2.3",
+ "fzaninotto/faker": "^1.8",
+ "graham-campbell/analyzer": "^2.1",
+ "mockery/mockery": "^1.2",
+ "phpunit/phpunit": "^7.4",
+ "tightenco/mailthief": "^0.3.14"
+ },
+ "suggest": {
+ "ext-apc": "APC Support cache driver."
},
"autoload": {
"classmap": [
@@ -73,30 +89,34 @@
},
"scripts": {
"post-root-package-install": [
- "php -r \"copy('.env.example', '.env');\"",
- "php artisan key:generate"
+ "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
- "php artisan key:generate"
+ "@php artisan key:generate"
],
- "post-install-cmd": [
- "Illuminate\\Foundation\\ComposerScripts::postInstall",
- "php artisan optimize --force",
- "php artisan config:cache",
- "php artisan route:cache"
+ "post-autoload-dump": [
+ "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
+ "@php artisan package:discover"
],
- "post-update-cmd": [
- "Illuminate\\Foundation\\ComposerScripts::postUpdate",
- "php artisan optimize --force",
- "php artisan config:cache",
- "php artisan route:cache"
+ "test": [
+ "@php artisan config:clear",
+ "vendor/bin/phpunit"
+ ],
+ "test-coverage": [
+ "@php artisan config:clear",
+ "vendor/bin/phpunit --coverage-clover=coverage.xml"
]
},
"config": {
"platform": {
- "php": "5.5.9"
+ "php": "7.1.3"
},
- "preferred-install": "dist"
+ "preferred-install": "dist",
+ "sort-packages": true,
+ "optimize-autoloader": true,
+ "allow-plugins": {
+ "kylekatarnls/update-helper": true
+ }
},
"extra": {
"branch-alias": {
diff --git a/composer.lock b/composer.lock
index c234627ab331..5694c9cc3939 100644
--- a/composer.lock
+++ b/composer.lock
@@ -1,106 +1,40 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
- "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "hash": "cfd3622f33928917617a1154e4e3a34a",
- "content-hash": "610bfbe8bb927252831d3ec61d2a78d0",
+ "content-hash": "6ca7a749bbb1681ee57e72dd9387f9ec",
"packages": [
- {
- "name": "alt-three/badger",
- "version": "v3.1.0",
- "source": {
- "type": "git",
- "url": "https://github.com/AltThree/Badger.git",
- "reference": "c5de4afcefcc0dd6576d2ae4bd5d5e83fb0cb8d9"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/AltThree/Badger/zipball/c5de4afcefcc0dd6576d2ae4bd5d5e83fb0cb8d9",
- "reference": "c5de4afcefcc0dd6576d2ae4bd5d5e83fb0cb8d9",
- "shasum": ""
- },
- "require": {
- "illuminate/contracts": "5.1.*|5.2.*|5.3.*",
- "illuminate/support": "5.1.*|5.2.*|5.3.*",
- "php": ">=5.5.9"
- },
- "require-dev": {
- "graham-campbell/testbench": "^3.1",
- "phpunit/phpunit": "^4.8|^5.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.1-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "AltThree\\Badger\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "James Brooks",
- "email": "james@alt-three.com"
- },
- {
- "name": "Graham Campbell",
- "email": "graham@alt-three.com"
- },
- {
- "name": "Joseph Cohen",
- "email": "joe@alt-three.com"
- }
- ],
- "description": "A Badge Generator For Laravel 5",
- "keywords": [
- "Alt Three",
- "badge",
- "badger",
- "shield",
- "svg"
- ],
- "time": "2016-04-22 17:23:42"
- },
{
"name": "alt-three/bus",
- "version": "v1.1.0",
+ "version": "v4.5.0",
"source": {
"type": "git",
"url": "https://github.com/AltThree/Bus.git",
- "reference": "5c8399e0ca67ba6b499aa1e8db6a278711446090"
+ "reference": "21d1623520c0ad48acb72420fd7f986cd23f349a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/AltThree/Bus/zipball/5c8399e0ca67ba6b499aa1e8db6a278711446090",
- "reference": "5c8399e0ca67ba6b499aa1e8db6a278711446090",
+ "url": "https://api.github.com/repos/AltThree/Bus/zipball/21d1623520c0ad48acb72420fd7f986cd23f349a",
+ "reference": "21d1623520c0ad48acb72420fd7f986cd23f349a",
"shasum": ""
},
"require": {
- "illuminate/container": "5.2.*|5.3.*",
- "illuminate/contracts": "5.2.*|5.3.*",
- "illuminate/pipeline": "5.2.*|5.3.*",
- "illuminate/support": "5.2.*|5.3.*",
- "php": ">=5.5.9"
+ "illuminate/bus": "^5.5 || ^6.0 || ^7.0 || ^8.0",
+ "illuminate/container": "^5.5 || ^6.0 || ^7.0 || ^8.0",
+ "illuminate/contracts": "^5.5 || ^6.0 || ^7.0 || ^8.0",
+ "illuminate/pipeline": "^5.5 || ^6.0 || ^7.0 || ^8.0",
+ "illuminate/support": "^5.5 || ^6.0 || ^7.0 || ^8.0",
+ "php": "^7.1.3 || ^8.0"
},
"require-dev": {
- "graham-campbell/testbench-core": "^1.1",
- "mockery/mockery": "^0.9.4",
- "phpunit/phpunit": "^4.8|^5.0"
+ "graham-campbell/analyzer": "^2.4 || ^3.0",
+ "graham-campbell/testbench": "^5.5",
+ "mockery/mockery": "^1.3.1",
+ "phpunit/phpunit": "^6.5 || ^7.5 || ^8.4 || ^9.0"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.1-dev"
- }
- },
"autoload": {
"psr-4": {
"AltThree\\Bus\\": "src/"
@@ -112,23 +46,11 @@
],
"authors": [
{
- "name": "Taylor Otwell",
- "email": "taylorotwell@gmail.com"
- },
- {
- "name": "James Brooks",
- "email": "james@alt-three.com"
- },
- {
- "name": "Graham Campbell",
- "email": "graham@alt-three.com"
- },
- {
- "name": "Joseph Cohen",
- "email": "joe@alt-three.com"
+ "name": "Alt Three",
+ "email": "support@alt-three.com"
}
],
- "description": "An improved command bus for Laravel 5.2+",
+ "description": "An improved command bus for Laravel",
"keywords": [
"Alt Three",
"bus",
@@ -136,43 +58,41 @@
"command bus",
"job"
],
- "time": "2016-04-22 17:24:19"
+ "support": {
+ "issues": "https://github.com/AltThree/Bus/issues",
+ "source": "https://github.com/AltThree/Bus/tree/4.5"
+ },
+ "abandoned": true,
+ "time": "2020-07-25T19:26:48+00:00"
},
{
- "name": "alt-three/emoji",
- "version": "v3.1.0",
+ "name": "alt-three/validator",
+ "version": "v4.5.0",
"source": {
"type": "git",
- "url": "https://github.com/AltThree/Emoji.git",
- "reference": "631119fb03162af8f42f7eda4c1f92c87611e36f"
+ "url": "https://github.com/AltThree/Validator.git",
+ "reference": "65ffc90cda5589052f0dac124d588946dfffd803"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/AltThree/Emoji/zipball/631119fb03162af8f42f7eda4c1f92c87611e36f",
- "reference": "631119fb03162af8f42f7eda4c1f92c87611e36f",
+ "url": "https://api.github.com/repos/AltThree/Validator/zipball/65ffc90cda5589052f0dac124d588946dfffd803",
+ "reference": "65ffc90cda5589052f0dac124d588946dfffd803",
"shasum": ""
},
"require": {
- "guzzlehttp/guzzle": "^5.3|^6.0",
- "illuminate/contracts": "5.1.*|5.2.*|5.3.*",
- "illuminate/support": "5.1.*|5.2.*|5.3.*",
- "league/commonmark": "^0.13",
- "php": ">=5.5.9"
+ "illuminate/contracts": "^5.5 || ^6.0 || ^7.0 || ^8.0",
+ "illuminate/support": "^5.5 || ^6.0 || ^7.0 || ^8.0",
+ "php": "^7.1.3 || ^8.0",
+ "psr/log": "^1.1"
},
"require-dev": {
- "graham-campbell/markdown": "^6.0",
- "graham-campbell/testbench": "^3.1",
- "phpunit/phpunit": "^4.8|^5.0"
+ "graham-campbell/analyzer": "^2.4 || ^3.0",
+ "phpunit/phpunit": "^6.5 || ^7.5 || ^8.4 || ^9.0"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.1-dev"
- }
- },
"autoload": {
"psr-4": {
- "AltThree\\Emoji\\": "src/"
+ "AltThree\\Validator\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -181,58 +101,55 @@
],
"authors": [
{
- "name": "James Brooks",
- "email": "james@alt-three.com"
- },
- {
- "name": "Graham Campbell",
- "email": "graham@alt-three.com"
- },
- {
- "name": "Joseph Cohen",
- "email": "joe@alt-three.com"
+ "name": "Alt Three",
+ "email": "support@alt-three.com"
}
],
- "description": "An Emoji Parser For Laravel 5",
+ "description": "A validation wrapper for Laravel",
"keywords": [
"Alt Three",
- "emoji",
- "parser"
+ "validation",
+ "validator"
],
- "time": "2016-04-22 17:24:35"
+ "support": {
+ "issues": "https://github.com/AltThree/Validator/issues",
+ "source": "https://github.com/AltThree/Validator/tree/4.5"
+ },
+ "abandoned": true,
+ "time": "2020-07-25T18:31:34+00:00"
},
{
- "name": "alt-three/throttle",
- "version": "v1.1.0",
+ "name": "asm89/stack-cors",
+ "version": "1.3.0",
"source": {
"type": "git",
- "url": "https://github.com/AltThree/Throttle.git",
- "reference": "3e4d57e8c61f02521b91cd911e0173710be0c1bb"
+ "url": "https://github.com/asm89/stack-cors.git",
+ "reference": "b9c31def6a83f84b4d4a40d35996d375755f0e08"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/AltThree/Throttle/zipball/3e4d57e8c61f02521b91cd911e0173710be0c1bb",
- "reference": "3e4d57e8c61f02521b91cd911e0173710be0c1bb",
+ "url": "https://api.github.com/repos/asm89/stack-cors/zipball/b9c31def6a83f84b4d4a40d35996d375755f0e08",
+ "reference": "b9c31def6a83f84b4d4a40d35996d375755f0e08",
"shasum": ""
},
"require": {
- "illuminate/cache": "5.2.*|5.3.*",
- "illuminate/http": "5.2.*|5.3.*",
- "php": ">=5.5.9"
+ "php": ">=5.5.9",
+ "symfony/http-foundation": "~2.7|~3.0|~4.0|~5.0",
+ "symfony/http-kernel": "~2.7|~3.0|~4.0|~5.0"
},
"require-dev": {
- "graham-campbell/testbench": "^3.1",
- "phpunit/phpunit": "^4.8|^5.0"
+ "phpunit/phpunit": "^5.0 || ^4.8.10",
+ "squizlabs/php_codesniffer": "^2.3"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.1-dev"
+ "dev-master": "1.2-dev"
}
},
"autoload": {
"psr-4": {
- "AltThree\\Throttle\\": "src/"
+ "Asm89\\Stack\\": "src/Asm89/Stack/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -241,129 +158,127 @@
],
"authors": [
{
- "name": "James Brooks",
- "email": "james@alt-three.com"
- },
- {
- "name": "Graham Campbell",
- "email": "graham@alt-three.com"
- },
- {
- "name": "Joseph Cohen",
- "email": "joe@alt-three.com"
+ "name": "Alexander",
+ "email": "iam.asm89@gmail.com"
}
],
- "description": "A request rate limiter for Laravel 5.2+",
+ "description": "Cross-origin resource sharing library and stack middleware",
+ "homepage": "https://github.com/asm89/stack-cors",
"keywords": [
- "Alt Three",
- "http",
- "rate limit",
- "rate limiter",
- "throttle"
+ "cors",
+ "stack"
],
- "time": "2016-08-26 21:13:17"
+ "support": {
+ "issues": "https://github.com/asm89/stack-cors/issues",
+ "source": "https://github.com/asm89/stack-cors/tree/1.3.0"
+ },
+ "time": "2019-12-24T22:41:47+00:00"
},
{
- "name": "alt-three/validator",
- "version": "v1.5.0",
+ "name": "aws/aws-crt-php",
+ "version": "v1.2.3",
"source": {
"type": "git",
- "url": "https://github.com/AltThree/Validator.git",
- "reference": "fbfe733bac9614edc2c09f8dea7ee3ce465402bb"
+ "url": "https://github.com/awslabs/aws-crt-php.git",
+ "reference": "5545a4fa310aec39f54279fdacebcce33b3ff382"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/AltThree/Validator/zipball/fbfe733bac9614edc2c09f8dea7ee3ce465402bb",
- "reference": "fbfe733bac9614edc2c09f8dea7ee3ce465402bb",
+ "url": "https://api.github.com/repos/awslabs/aws-crt-php/zipball/5545a4fa310aec39f54279fdacebcce33b3ff382",
+ "reference": "5545a4fa310aec39f54279fdacebcce33b3ff382",
"shasum": ""
},
"require": {
- "illuminate/contracts": "5.1.*|5.2.*|5.3.*",
- "illuminate/support": "5.1.*|5.2.*|5.3.*",
- "php": ">=5.5.9",
- "psr/log": "^1.0"
+ "php": ">=5.5"
},
"require-dev": {
- "phpunit/phpunit": "^4.8|^5.0"
+ "phpunit/phpunit": "^4.8.35||^5.6.3||^9.5",
+ "yoast/phpunit-polyfills": "^1.0"
},
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.5-dev"
- }
+ "suggest": {
+ "ext-awscrt": "Make sure you install awscrt native extension to use any of the functionality."
},
+ "type": "library",
"autoload": {
- "psr-4": {
- "AltThree\\Validator\\": "src/"
- }
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "Apache-2.0"
],
"authors": [
{
- "name": "James Brooks",
- "email": "james@alt-three.com"
- },
- {
- "name": "Graham Campbell",
- "email": "graham@alt-three.com"
- },
- {
- "name": "Joseph Cohen",
- "email": "joe@alt-three.com"
+ "name": "AWS SDK Common Runtime Team",
+ "email": "aws-sdk-common-runtime@amazon.com"
}
],
- "description": "A Validation Wrapper For Laravel 5",
+ "description": "AWS Common Runtime for PHP",
+ "homepage": "https://github.com/awslabs/aws-crt-php",
"keywords": [
- "Alt Three",
- "logging",
- "validator"
+ "amazon",
+ "aws",
+ "crt",
+ "sdk"
],
- "time": "2016-04-22 17:26:22"
+ "support": {
+ "issues": "https://github.com/awslabs/aws-crt-php/issues",
+ "source": "https://github.com/awslabs/aws-crt-php/tree/v1.2.3"
+ },
+ "time": "2023-10-16T20:10:06+00:00"
},
{
"name": "aws/aws-sdk-php",
- "version": "3.19.4",
+ "version": "3.278.3",
"source": {
"type": "git",
"url": "https://github.com/aws/aws-sdk-php.git",
- "reference": "f67bc37fa4b76d85423052eae2a9577aab99adc1"
+ "reference": "596534c0627d8b38597061341e99b460437d1a16"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/f67bc37fa4b76d85423052eae2a9577aab99adc1",
- "reference": "f67bc37fa4b76d85423052eae2a9577aab99adc1",
+ "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/596534c0627d8b38597061341e99b460437d1a16",
+ "reference": "596534c0627d8b38597061341e99b460437d1a16",
"shasum": ""
},
"require": {
- "guzzlehttp/guzzle": "^5.3.1|^6.2.1",
- "guzzlehttp/promises": "~1.0",
- "guzzlehttp/psr7": "~1.3.1",
- "mtdowling/jmespath.php": "~2.2",
- "php": ">=5.5"
+ "aws/aws-crt-php": "^1.0.4",
+ "ext-json": "*",
+ "ext-pcre": "*",
+ "ext-simplexml": "*",
+ "guzzlehttp/guzzle": "^6.5.8 || ^7.4.5",
+ "guzzlehttp/promises": "^1.4.0",
+ "guzzlehttp/psr7": "^1.9.1 || ^2.4.5",
+ "mtdowling/jmespath.php": "^2.6",
+ "php": ">=5.5",
+ "psr/http-message": "^1.0"
},
"require-dev": {
"andrewsville/php-token-reflection": "^1.4",
"aws/aws-php-sns-message-validator": "~1.0",
"behat/behat": "~3.0",
+ "composer/composer": "^1.10.22",
+ "dms/phpunit-arraysubset-asserts": "^0.4.0",
"doctrine/cache": "~1.4",
"ext-dom": "*",
- "ext-json": "*",
"ext-openssl": "*",
- "ext-pcre": "*",
- "ext-simplexml": "*",
- "ext-spl": "*",
+ "ext-pcntl": "*",
+ "ext-sockets": "*",
"nette/neon": "^2.3",
- "phpunit/phpunit": "~4.0|~5.0",
- "psr/cache": "^1.0"
+ "paragonie/random_compat": ">= 2",
+ "phpunit/phpunit": "^4.8.35 || ^5.6.3 || ^9.5",
+ "psr/cache": "^1.0",
+ "psr/simple-cache": "^1.0",
+ "sebastian/comparator": "^1.2.3 || ^4.0",
+ "yoast/phpunit-polyfills": "^1.0"
},
"suggest": {
"aws/aws-php-sns-message-validator": "To validate incoming SNS notifications",
"doctrine/cache": "To use the DoctrineCacheAdapter",
"ext-curl": "To send requests using cURL",
- "ext-openssl": "Allows working with CloudFront private distributions and verifying received SNS messages"
+ "ext-openssl": "Allows working with CloudFront private distributions and verifying received SNS messages",
+ "ext-sockets": "To use client-side monitoring"
},
"type": "library",
"extra": {
@@ -372,12 +287,12 @@
}
},
"autoload": {
- "psr-4": {
- "Aws\\": "src/"
- },
"files": [
"src/functions.php"
- ]
+ ],
+ "psr-4": {
+ "Aws\\": "src/"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -401,53 +316,54 @@
"s3",
"sdk"
],
- "time": "2016-09-01 21:37:32"
+ "support": {
+ "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
+ "issues": "https://github.com/aws/aws-sdk-php/issues",
+ "source": "https://github.com/aws/aws-sdk-php/tree/3.278.3"
+ },
+ "time": "2023-08-15T18:07:55+00:00"
},
{
- "name": "backup-manager/backup-manager",
- "version": "1.1.1",
+ "name": "barryvdh/laravel-cors",
+ "version": "v0.11.4",
"source": {
"type": "git",
- "url": "https://github.com/backup-manager/backup-manager.git",
- "reference": "e793277e6f6efae6a31c7abbd8028cae7e151201"
+ "url": "https://github.com/fruitcake/laravel-cors.git",
+ "reference": "03492f1a3bc74a05de23f93b94ac7cc5c173eec9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/backup-manager/backup-manager/zipball/e793277e6f6efae6a31c7abbd8028cae7e151201",
- "reference": "e793277e6f6efae6a31c7abbd8028cae7e151201",
+ "url": "https://api.github.com/repos/fruitcake/laravel-cors/zipball/03492f1a3bc74a05de23f93b94ac7cc5c173eec9",
+ "reference": "03492f1a3bc74a05de23f93b94ac7cc5c173eec9",
"shasum": ""
},
"require": {
- "league/flysystem": "~1.0",
- "php": ">=5.5.9",
- "symfony/process": "~2.1||~3.0"
+ "asm89/stack-cors": "^1.2",
+ "illuminate/support": "^5.5|^6",
+ "php": ">=7",
+ "symfony/http-foundation": "^3.1|^4",
+ "symfony/http-kernel": "^3.1|^4"
},
"require-dev": {
- "aws/aws-sdk-php": "~3.0",
- "dropbox/dropbox-sdk": "~1.1",
- "league/flysystem-aws-s3-v3": "~1.0",
- "league/flysystem-dropbox": "~1.0",
- "league/flysystem-rackspace": "~1.0",
- "league/flysystem-sftp": "~1.0",
- "mockery/mockery": "~0.9",
- "phpspec/phpspec": "~2.1",
- "satooshi/php-coveralls": "~0.6"
- },
- "suggest": {
- "league/flysystem-aws-s3-v3": "AwsS3 and GoogleCS adapter support.",
- "league/flysystem-dropbox": "Dropbox adapter support.",
- "league/flysystem-rackspace": "Rackspace adapter support.",
- "league/flysystem-sftp": "Sftp adapter support."
+ "laravel/framework": "^5.5",
+ "orchestra/testbench": "3.3.x|3.4.x|3.5.x|3.6.x|3.7.x",
+ "phpunit/phpunit": "^4.8|^5.2|^7.0",
+ "squizlabs/php_codesniffer": "^2.3"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0-dev"
+ "dev-master": "0.11-dev"
+ },
+ "laravel": {
+ "providers": [
+ "Barryvdh\\Cors\\ServiceProvider"
+ ]
}
},
"autoload": {
"psr-4": {
- "BackupManager\\": "src/"
+ "Barryvdh\\Cors\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -456,54 +372,59 @@
],
"authors": [
{
- "name": "Shawn McCool",
- "email": "shawn@heybigname.com",
- "homepage": "http://heybigname.com/"
- },
- {
- "name": "Mitchell van Wijngaarden",
- "email": "mitchell@kooding.nl",
- "homepage": "http://heybigname.com/"
+ "name": "Barry vd. Heuvel",
+ "email": "barryvdh@gmail.com"
}
],
- "description": "A framework agnostic database backup manager with user-definable procedures and support for S3, Dropbox, FTP, SFTP, and more with drivers for popular frameworks.",
- "time": "2016-02-05 10:01:19"
+ "description": "Adds CORS (Cross-Origin Resource Sharing) headers support in your Laravel application",
+ "keywords": [
+ "api",
+ "cors",
+ "crossdomain",
+ "laravel"
+ ],
+ "support": {
+ "issues": "https://github.com/fruitcake/laravel-cors/issues",
+ "source": "https://github.com/fruitcake/laravel-cors/tree/v0.11.4"
+ },
+ "abandoned": true,
+ "time": "2019-08-28T11:27:11+00:00"
},
{
- "name": "backup-manager/laravel",
- "version": "1.1.1",
+ "name": "bugsnag/bugsnag",
+ "version": "v3.29.1",
"source": {
"type": "git",
- "url": "https://github.com/backup-manager/laravel.git",
- "reference": "d7e6d12d24b8a27f58cf5eccb1ac943104c09856"
+ "url": "https://github.com/bugsnag/bugsnag-php.git",
+ "reference": "7fff8512b237a57323f600975ada6376e2b912c1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/backup-manager/laravel/zipball/d7e6d12d24b8a27f58cf5eccb1ac943104c09856",
- "reference": "d7e6d12d24b8a27f58cf5eccb1ac943104c09856",
+ "url": "https://api.github.com/repos/bugsnag/bugsnag-php/zipball/7fff8512b237a57323f600975ada6376e2b912c1",
+ "reference": "7fff8512b237a57323f600975ada6376e2b912c1",
"shasum": ""
},
"require": {
- "backup-manager/backup-manager": "^1.0",
- "illuminate/console": "^4.0||^5.0",
- "illuminate/container": "^4.0||^5.0",
- "illuminate/support": "^4.0||^5.0",
- "php": ">=5.5.0",
- "symfony/process": "^2.0||^3.0"
+ "composer/ca-bundle": "^1.0",
+ "guzzlehttp/guzzle": "^5.0|^6.0|^7.0",
+ "php": ">=5.5"
},
"require-dev": {
- "mockery/mockery": "dev-master",
- "satooshi/php-coveralls": "~0.6"
+ "guzzlehttp/psr7": "^1.3",
+ "mtdowling/burgomaster": "dev-master#72151eddf5f0cf101502b94bf5031f9c53501a04",
+ "php-mock/php-mock-phpunit": "^1.1|^2.1",
+ "phpunit/phpunit": "^4.8.36|^7.5.15|^9.3.10",
+ "sebastian/version": ">=1.0.3"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0-dev"
+ "dev-master": "3.20-dev"
}
},
"autoload": {
"psr-4": {
- "BackupManager\\Laravel\\": "src/"
+ "Bugsnag\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -512,93 +433,122 @@
],
"authors": [
{
- "name": "Shawn McCool",
- "email": "shawn@heybigname.com",
- "homepage": "http://heybigname.com/"
- },
- {
- "name": "Mitchell van Wijngaarden",
- "email": "mitchell@kooding.nl",
- "homepage": "http://heybigname.com/"
+ "name": "James Smith",
+ "email": "notifiers@bugsnag.com",
+ "homepage": "https://bugsnag.com"
}
],
- "description": "Database backup manager seamlessly integrated with Laravel 4 or 5 with user-definable procedures and support for S3, Dropbox, FTP, SFTP, and more.",
- "time": "2016-02-22 10:52:12"
+ "description": "Official Bugsnag notifier for PHP applications.",
+ "homepage": "https://github.com/bugsnag/bugsnag-php",
+ "keywords": [
+ "bugsnag",
+ "errors",
+ "exceptions",
+ "logging",
+ "tracking"
+ ],
+ "support": {
+ "issues": "https://github.com/bugsnag/bugsnag-php/issues",
+ "source": "https://github.com/bugsnag/bugsnag-php/tree/v3.29.1"
+ },
+ "time": "2023-05-10T11:07:22+00:00"
},
{
- "name": "bacon/bacon-qr-code",
- "version": "1.0.1",
+ "name": "bugsnag/bugsnag-laravel",
+ "version": "v2.26.0",
"source": {
"type": "git",
- "url": "https://github.com/Bacon/BaconQrCode.git",
- "reference": "031a2ce68c5794064b49d11775b2daf45c96e21c"
+ "url": "https://github.com/bugsnag/bugsnag-laravel.git",
+ "reference": "333a912e38ead3e02724381093778b271168c8a3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/031a2ce68c5794064b49d11775b2daf45c96e21c",
- "reference": "031a2ce68c5794064b49d11775b2daf45c96e21c",
+ "url": "https://api.github.com/repos/bugsnag/bugsnag-laravel/zipball/333a912e38ead3e02724381093778b271168c8a3",
+ "reference": "333a912e38ead3e02724381093778b271168c8a3",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
+ "bugsnag/bugsnag": "^3.29.0",
+ "bugsnag/bugsnag-psr-logger": "^1.4|^2.0",
+ "illuminate/contracts": "^5.0|^6.0|^7.0|^8.0|^9.0|^10.0",
+ "illuminate/support": "^5.0|^6.0|^7.0|^8.0|^9.0|^10.0",
+ "monolog/monolog": "^1.12|^2.0|^3.0",
+ "php": ">=5.5"
},
- "suggest": {
- "ext-gd": "to generate QR code images"
+ "require-dev": {
+ "orchestra/testbench": "^3.1|^4.0|^5.0|^6.0|^7.0|^8.0",
+ "phpunit/phpunit": "^4.8.36|^6.3.1|^7.5.15|^8.3.5|^9.3.10"
},
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.18-dev"
+ }
+ },
"autoload": {
- "psr-0": {
- "BaconQrCode": "src/"
+ "psr-4": {
+ "Bugsnag\\BugsnagLaravel\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-2-Clause"
+ "MIT"
],
"authors": [
{
- "name": "Ben Scholzen 'DASPRiD'",
- "email": "mail@dasprids.de",
- "homepage": "http://www.dasprids.de",
- "role": "Developer"
+ "name": "James Smith",
+ "email": "notifiers@bugsnag.com"
}
],
- "description": "BaconQrCode is a QR code generator for PHP.",
- "homepage": "https://github.com/Bacon/BaconQrCode",
- "time": "2016-01-09 22:55:35"
+ "description": "Official Bugsnag notifier for Laravel applications.",
+ "homepage": "https://github.com/bugsnag/bugsnag-laravel",
+ "keywords": [
+ "bugsnag",
+ "errors",
+ "exceptions",
+ "laravel",
+ "logging",
+ "tracking"
+ ],
+ "support": {
+ "issues": "https://github.com/bugsnag/bugsnag-laravel/issues",
+ "source": "https://github.com/bugsnag/bugsnag-laravel/tree/v2.26.0"
+ },
+ "time": "2023-02-16T08:48:39+00:00"
},
{
- "name": "barryvdh/laravel-cors",
- "version": "v0.8.2",
+ "name": "bugsnag/bugsnag-psr-logger",
+ "version": "v1.4.5",
"source": {
"type": "git",
- "url": "https://github.com/barryvdh/laravel-cors.git",
- "reference": "bc7f40a71221b46d24971da7f0230ed4a75a18c6"
+ "url": "https://github.com/bugsnag/bugsnag-psr-logger.git",
+ "reference": "366430a94d983488d265c1068f47d78ebfbacd74"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/barryvdh/laravel-cors/zipball/bc7f40a71221b46d24971da7f0230ed4a75a18c6",
- "reference": "bc7f40a71221b46d24971da7f0230ed4a75a18c6",
+ "url": "https://api.github.com/repos/bugsnag/bugsnag-psr-logger/zipball/366430a94d983488d265c1068f47d78ebfbacd74",
+ "reference": "366430a94d983488d265c1068f47d78ebfbacd74",
"shasum": ""
},
"require": {
- "illuminate/support": "5.1.x|5.2.x|5.3.x",
- "php": ">=5.5.9",
- "symfony/http-foundation": "~2.7|~3.0",
- "symfony/http-kernel": "~2.7|~3.0"
+ "bugsnag/bugsnag": "^3.10",
+ "php": ">=5.5",
+ "psr/log": "^1.0|^2.0"
},
"require-dev": {
- "phpunit/phpunit": "^4.8|^5.2"
+ "graham-campbell/testbench-core": "^1.1",
+ "mockery/mockery": "^0.9.4|^1.3.1",
+ "phpunit/phpunit": "^4.8.36|^7.5.15|^9.4.3"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "0.8-dev"
+ "dev-master": "1.5-dev"
}
},
"autoload": {
"psr-4": {
- "Barryvdh\\Cors\\": "src/"
+ "Bugsnag\\PsrLogger\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -607,49 +557,65 @@
],
"authors": [
{
- "name": "Barry vd. Heuvel",
- "email": "barryvdh@gmail.com"
+ "name": "James Smith",
+ "email": "notifiers@bugsnag.com",
+ "homepage": "https://bugsnag.com"
}
],
- "description": "Adds CORS (Cross-Origin Resource Sharing) headers support in your Laravel application",
+ "description": "Official Bugsnag PHP PSR Logger.",
+ "homepage": "https://github.com/bugsnag/bugsnag-psr",
"keywords": [
- "api",
- "cors",
- "crossdomain",
- "laravel"
+ "bugsnag",
+ "errors",
+ "exceptions",
+ "logging",
+ "psr",
+ "tracking"
],
- "time": "2016-08-11 08:46:01"
+ "support": {
+ "issues": "https://github.com/bugsnag/bugsnag-psr-logger/issues",
+ "source": "https://github.com/bugsnag/bugsnag-psr-logger/tree/v1.4.5"
+ },
+ "time": "2021-12-13T09:52:57+00:00"
},
{
- "name": "christian-riesen/base32",
- "version": "1.3.1",
+ "name": "cachethq/badger",
+ "version": "v2.0.0",
"source": {
"type": "git",
- "url": "https://github.com/ChristianRiesen/base32.git",
- "reference": "0a31e50c0fa9b1692d077c86ac188eecdcbaf7fa"
+ "url": "https://github.com/CachetHQ/Badger.git",
+ "reference": "9d7f9e8f8529d902f3a30ad120a403a7ba2da1e3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/ChristianRiesen/base32/zipball/0a31e50c0fa9b1692d077c86ac188eecdcbaf7fa",
- "reference": "0a31e50c0fa9b1692d077c86ac188eecdcbaf7fa",
+ "url": "https://api.github.com/repos/CachetHQ/Badger/zipball/9d7f9e8f8529d902f3a30ad120a403a7ba2da1e3",
+ "reference": "9d7f9e8f8529d902f3a30ad120a403a7ba2da1e3",
"shasum": ""
},
"require": {
- "php": ">=5.3.0"
+ "illuminate/contracts": "^5.5|^6.0",
+ "illuminate/support": "^5.5|^6.0",
+ "php": "^7.1.3"
},
"require-dev": {
- "phpunit/phpunit": "4.*",
- "satooshi/php-coveralls": "0.*"
+ "graham-campbell/analyzer": "^2.1",
+ "graham-campbell/testbench": "^5.1",
+ "phpunit/phpunit": "^6.5|^7.0|^8.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.1.x-dev"
+ "dev-master": "2.0-dev"
+ },
+ "laravel": {
+ "providers": [
+ "CachetHQ\\Badger\\BadgerServiceProvider"
+ ]
}
},
"autoload": {
"psr-4": {
- "Base32\\": "src/"
+ "CachetHQ\\Badger\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -658,52 +624,67 @@
],
"authors": [
{
- "name": "Christian Riesen",
- "email": "chris.riesen@gmail.com",
- "homepage": "http://christianriesen.com",
- "role": "Developer"
+ "name": "Cachet",
+ "email": "support@cachethq.io"
}
],
- "description": "Base32 encoder/decoder according to RFC 4648",
- "homepage": "https://github.com/ChristianRiesen/base32",
+ "description": "A Badge Generator For Laravel 5 and 6.",
"keywords": [
- "base32",
- "decode",
- "encode",
- "rfc4648"
+ "CachetHQ",
+ "badge",
+ "badger",
+ "cachet",
+ "shield",
+ "svg"
],
- "time": "2016-05-05 11:49:03"
+ "support": {
+ "issues": "https://github.com/CachetHQ/Badger/issues",
+ "source": "https://github.com/CachetHQ/Badger/tree/v2.0.0"
+ },
+ "time": "2019-11-18T20:06:20+00:00"
},
{
- "name": "classpreloader/classpreloader",
- "version": "3.0.0",
+ "name": "cachethq/emoji",
+ "version": "v3.0.0",
"source": {
"type": "git",
- "url": "https://github.com/ClassPreloader/ClassPreloader.git",
- "reference": "9b10b913c2bdf90c3d2e0d726b454fb7f77c552a"
+ "url": "https://github.com/CachetHQ/Emoji.git",
+ "reference": "45227616c9b8077deeefe5561035e219b4118233"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/ClassPreloader/ClassPreloader/zipball/9b10b913c2bdf90c3d2e0d726b454fb7f77c552a",
- "reference": "9b10b913c2bdf90c3d2e0d726b454fb7f77c552a",
+ "url": "https://api.github.com/repos/CachetHQ/Emoji/zipball/45227616c9b8077deeefe5561035e219b4118233",
+ "reference": "45227616c9b8077deeefe5561035e219b4118233",
"shasum": ""
},
"require": {
- "nikic/php-parser": "^1.0|^2.0",
- "php": ">=5.5.9"
+ "graham-campbell/guzzle-factory": "^3.0",
+ "illuminate/contracts": "^5.5|^6.0",
+ "illuminate/support": "^5.5|^6.0",
+ "league/commonmark": "^1.0",
+ "php": "^7.1.3"
},
"require-dev": {
- "phpunit/phpunit": "^4.8|^5.0"
+ "graham-campbell/analyzer": "^2.1",
+ "graham-campbell/markdown": "^11.0",
+ "graham-campbell/testbench": "^5.1",
+ "mockery/mockery": "^1.0",
+ "phpunit/phpunit": "^6.5|^7.0|^8.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.0-dev"
+ },
+ "laravel": {
+ "providers": [
+ "CachetHQ\\Emoji\\EmojiServiceProvider"
+ ]
}
},
"autoload": {
"psr-4": {
- "ClassPreloader\\": "src/"
+ "CachetHQ\\Emoji\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -712,86 +693,115 @@
],
"authors": [
{
- "name": "Michael Dowling",
- "email": "mtdowling@gmail.com"
- },
- {
- "name": "Graham Campbell",
- "email": "graham@alt-three.com"
+ "name": "Cachet",
+ "email": "support@cachethq.io"
}
],
- "description": "Helps class loading performance by generating a single PHP file containing all of the autoloaded files for a specific use case",
+ "description": "An Emoji Parser For Laravel 5 and 6",
"keywords": [
- "autoload",
- "class",
- "preload"
+ "CachetHQ",
+ "cachet",
+ "emoji",
+ "parser"
],
- "time": "2015-11-09 22:51:51"
+ "support": {
+ "issues": "https://github.com/CachetHQ/Emoji/issues",
+ "source": "https://github.com/CachetHQ/Emoji/tree/v3.0.0"
+ },
+ "time": "2019-11-19T17:04:13+00:00"
},
{
- "name": "dnoegel/php-xdg-base-dir",
- "version": "0.1",
+ "name": "cachethq/twitter",
+ "version": "v3.0.0",
"source": {
"type": "git",
- "url": "https://github.com/dnoegel/php-xdg-base-dir.git",
- "reference": "265b8593498b997dc2d31e75b89f053b5cc9621a"
+ "url": "https://github.com/CachetHQ/Twitter.git",
+ "reference": "81216cbc3c1f1a32df70bfb73837f59a35a22b1c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/265b8593498b997dc2d31e75b89f053b5cc9621a",
- "reference": "265b8593498b997dc2d31e75b89f053b5cc9621a",
+ "url": "https://api.github.com/repos/CachetHQ/Twitter/zipball/81216cbc3c1f1a32df70bfb73837f59a35a22b1c",
+ "reference": "81216cbc3c1f1a32df70bfb73837f59a35a22b1c",
"shasum": ""
},
"require": {
- "php": ">=5.3.2"
+ "illuminate/contracts": "^5.5|^6.0",
+ "illuminate/support": "^5.5|^6.0",
+ "league/commonmark": "^1.0",
+ "php": "^7.1.3"
},
"require-dev": {
- "phpunit/phpunit": "@stable"
+ "graham-campbell/analyzer": "^2.1",
+ "graham-campbell/markdown": "^11.0",
+ "graham-campbell/testbench": "^5.1",
+ "phpunit/phpunit": "^6.5|^7.0|^8.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0-dev"
+ },
+ "laravel": {
+ "providers": [
+ "CachetHQ\\Twitter\\TwitterServiceProvider"
+ ]
+ }
},
- "type": "project",
"autoload": {
"psr-4": {
- "XdgBaseDir\\": "src/"
+ "CachetHQ\\Twitter\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
- "description": "implementation of xdg base directory specification for php",
- "time": "2014-10-24 07:27:01"
- },
+ "authors": [
+ {
+ "name": "Cachet",
+ "email": "support@cachethq.io"
+ }
+ ],
+ "description": "A Twitter handle parser for Laravel 5 and 6",
+ "keywords": [
+ "CachetHQ",
+ "cachet",
+ "markdown",
+ "parser",
+ "twitter"
+ ],
+ "support": {
+ "issues": "https://github.com/CachetHQ/Twitter/issues",
+ "source": "https://github.com/CachetHQ/Twitter/tree/v3.0.0"
+ },
+ "time": "2019-11-19T17:04:54+00:00"
+ },
{
- "name": "doctrine/annotations",
- "version": "v1.2.7",
+ "name": "chillerlan/php-qrcode",
+ "version": "2.0.8",
"source": {
"type": "git",
- "url": "https://github.com/doctrine/annotations.git",
- "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535"
+ "url": "https://github.com/chillerlan/php-qrcode.git",
+ "reference": "bf0382aaf2f79fa41c2dcb0f216675f74d633fe7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/annotations/zipball/f25c8aab83e0c3e976fd7d19875f198ccf2f7535",
- "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535",
+ "url": "https://api.github.com/repos/chillerlan/php-qrcode/zipball/bf0382aaf2f79fa41c2dcb0f216675f74d633fe7",
+ "reference": "bf0382aaf2f79fa41c2dcb0f216675f74d633fe7",
"shasum": ""
},
"require": {
- "doctrine/lexer": "1.*",
- "php": ">=5.3.2"
+ "chillerlan/php-traits": "^1.1",
+ "php": ">=7.0.3"
},
"require-dev": {
- "doctrine/cache": "1.*",
- "phpunit/phpunit": "4.*"
+ "chillerlan/php-authenticator": "^2.0",
+ "phpunit/phpunit": "^6.5"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.3.x-dev"
- }
- },
"autoload": {
- "psr-0": {
- "Doctrine\\Common\\Annotations\\": "lib/"
+ "psr-4": {
+ "chillerlan\\QRCode\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -800,69 +810,56 @@
],
"authors": [
{
- "name": "Roman Borschel",
- "email": "roman@code-factory.org"
- },
- {
- "name": "Benjamin Eberlei",
- "email": "kontakt@beberlei.de"
- },
- {
- "name": "Guilherme Blanco",
- "email": "guilhermeblanco@gmail.com"
- },
- {
- "name": "Jonathan Wage",
- "email": "jonwage@gmail.com"
+ "name": "Kazuhiko Arase",
+ "homepage": "https://github.com/kazuhikoarase"
},
{
- "name": "Johannes Schmitt",
- "email": "schmittjoh@gmail.com"
+ "name": "Smiley",
+ "email": "smiley@chillerlan.net",
+ "homepage": "https://github.com/codemasher"
}
],
- "description": "Docblock Annotations Parser",
- "homepage": "http://www.doctrine-project.org",
+ "description": "A QR code generator. PHP 7+",
+ "homepage": "https://github.com/chillerlan/php-qrcode",
"keywords": [
- "annotations",
- "docblock",
- "parser"
+ "qr code"
+ ],
+ "support": {
+ "issues": "https://github.com/chillerlan/php-qrcode/issues",
+ "source": "https://github.com/chillerlan/php-qrcode/tree/v2.0.x"
+ },
+ "funding": [
+ {
+ "url": "https://ko-fi.com/codemasher",
+ "type": "ko_fi"
+ }
],
- "time": "2015-08-31 12:32:49"
+ "time": "2020-04-12T07:38:35+00:00"
},
{
- "name": "doctrine/cache",
- "version": "v1.6.0",
+ "name": "chillerlan/php-traits",
+ "version": "1.1.13",
"source": {
"type": "git",
- "url": "https://github.com/doctrine/cache.git",
- "reference": "f8af318d14bdb0eff0336795b428b547bd39ccb6"
+ "url": "https://github.com/chillerlan/php-traits.git",
+ "reference": "264759946b6aaeb427346b749fc9639b790b8e7f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/cache/zipball/f8af318d14bdb0eff0336795b428b547bd39ccb6",
- "reference": "f8af318d14bdb0eff0336795b428b547bd39ccb6",
+ "url": "https://api.github.com/repos/chillerlan/php-traits/zipball/264759946b6aaeb427346b749fc9639b790b8e7f",
+ "reference": "264759946b6aaeb427346b749fc9639b790b8e7f",
"shasum": ""
},
"require": {
- "php": "~5.5|~7.0"
- },
- "conflict": {
- "doctrine/common": ">2.2,<2.4"
+ "php": ">=7.0.3"
},
"require-dev": {
- "phpunit/phpunit": "~4.8|~5.0",
- "predis/predis": "~1.0",
- "satooshi/php-coveralls": "~0.6"
+ "phpunit/phpunit": "^6.5"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.6.x-dev"
- }
- },
"autoload": {
"psr-4": {
- "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache"
+ "chillerlan\\Traits\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -871,63 +868,61 @@
],
"authors": [
{
- "name": "Roman Borschel",
- "email": "roman@code-factory.org"
- },
- {
- "name": "Benjamin Eberlei",
- "email": "kontakt@beberlei.de"
- },
- {
- "name": "Guilherme Blanco",
- "email": "guilhermeblanco@gmail.com"
- },
- {
- "name": "Jonathan Wage",
- "email": "jonwage@gmail.com"
- },
- {
- "name": "Johannes Schmitt",
- "email": "schmittjoh@gmail.com"
+ "name": "Smiley",
+ "email": "smiley@chillerlan.net",
+ "homepage": "https://github.com/codemasher"
}
],
- "description": "Caching library offering an object-oriented API for many cache backends",
- "homepage": "http://www.doctrine-project.org",
+ "description": "Some useful traits for PHP 7+",
+ "homepage": "https://github.com/chillerlan/php-traits",
"keywords": [
- "cache",
- "caching"
+ "PHP7",
+ "container",
+ "dotenv",
+ "helper",
+ "trait"
],
- "time": "2015-12-31 16:37:02"
+ "support": {
+ "issues": "https://github.com/chillerlan/php-traits/issues",
+ "source": "https://github.com/chillerlan/php-traits"
+ },
+ "abandoned": true,
+ "time": "2018-06-22T00:30:47+00:00"
},
{
- "name": "doctrine/collections",
- "version": "v1.3.0",
+ "name": "composer/ca-bundle",
+ "version": "1.3.7",
"source": {
"type": "git",
- "url": "https://github.com/doctrine/collections.git",
- "reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a"
+ "url": "https://github.com/composer/ca-bundle.git",
+ "reference": "76e46335014860eec1aa5a724799a00a2e47cc85"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/collections/zipball/6c1e4eef75f310ea1b3e30945e9f06e652128b8a",
- "reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a",
+ "url": "https://api.github.com/repos/composer/ca-bundle/zipball/76e46335014860eec1aa5a724799a00a2e47cc85",
+ "reference": "76e46335014860eec1aa5a724799a00a2e47cc85",
"shasum": ""
},
"require": {
- "php": ">=5.3.2"
+ "ext-openssl": "*",
+ "ext-pcre": "*",
+ "php": "^5.3.2 || ^7.0 || ^8.0"
},
"require-dev": {
- "phpunit/phpunit": "~4.0"
+ "phpstan/phpstan": "^0.12.55",
+ "psr/log": "^1.0",
+ "symfony/phpunit-bridge": "^4.2 || ^5",
+ "symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0 || ^6.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.2.x-dev"
+ "dev-main": "1.x-dev"
}
},
"autoload": {
- "psr-0": {
- "Doctrine\\Common\\Collections\\": "lib/"
+ "psr-4": {
+ "Composer\\CaBundle\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -936,69 +931,115 @@
],
"authors": [
{
- "name": "Roman Borschel",
- "email": "roman@code-factory.org"
- },
- {
- "name": "Benjamin Eberlei",
- "email": "kontakt@beberlei.de"
- },
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be",
+ "homepage": "http://seld.be"
+ }
+ ],
+ "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.",
+ "keywords": [
+ "cabundle",
+ "cacert",
+ "certificate",
+ "ssl",
+ "tls"
+ ],
+ "support": {
+ "irc": "irc://irc.freenode.org/composer",
+ "issues": "https://github.com/composer/ca-bundle/issues",
+ "source": "https://github.com/composer/ca-bundle/tree/1.3.7"
+ },
+ "funding": [
{
- "name": "Guilherme Blanco",
- "email": "guilhermeblanco@gmail.com"
+ "url": "https://packagist.com",
+ "type": "custom"
},
{
- "name": "Jonathan Wage",
- "email": "jonwage@gmail.com"
+ "url": "https://github.com/composer",
+ "type": "github"
},
{
- "name": "Johannes Schmitt",
- "email": "schmittjoh@gmail.com"
+ "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+ "type": "tidelift"
}
],
- "description": "Collections Abstraction library",
- "homepage": "http://www.doctrine-project.org",
- "keywords": [
- "array",
- "collections",
- "iterator"
- ],
- "time": "2015-04-14 22:21:58"
+ "time": "2023-08-30T09:31:38+00:00"
},
{
- "name": "doctrine/common",
- "version": "v2.6.1",
+ "name": "dnoegel/php-xdg-base-dir",
+ "version": "v0.1.1",
"source": {
"type": "git",
- "url": "https://github.com/doctrine/common.git",
- "reference": "a579557bc689580c19fee4e27487a67fe60defc0"
+ "url": "https://github.com/dnoegel/php-xdg-base-dir.git",
+ "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/common/zipball/a579557bc689580c19fee4e27487a67fe60defc0",
- "reference": "a579557bc689580c19fee4e27487a67fe60defc0",
+ "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd",
+ "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd",
"shasum": ""
},
"require": {
- "doctrine/annotations": "1.*",
- "doctrine/cache": "1.*",
- "doctrine/collections": "1.*",
- "doctrine/inflector": "1.*",
- "doctrine/lexer": "1.*",
- "php": "~5.5|~7.0"
+ "php": ">=5.3.2"
},
"require-dev": {
- "phpunit/phpunit": "~4.8|~5.0"
+ "phpunit/phpunit": "~7.0|~6.0|~5.0|~4.8.35"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.7.x-dev"
+ "autoload": {
+ "psr-4": {
+ "XdgBaseDir\\": "src/"
}
},
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "implementation of xdg base directory specification for php",
+ "support": {
+ "issues": "https://github.com/dnoegel/php-xdg-base-dir/issues",
+ "source": "https://github.com/dnoegel/php-xdg-base-dir/tree/v0.1.1"
+ },
+ "time": "2019-12-04T15:06:13+00:00"
+ },
+ {
+ "name": "doctrine/cache",
+ "version": "1.13.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/cache.git",
+ "reference": "56cd022adb5514472cb144c087393c1821911d09"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/cache/zipball/56cd022adb5514472cb144c087393c1821911d09",
+ "reference": "56cd022adb5514472cb144c087393c1821911d09",
+ "shasum": ""
+ },
+ "require": {
+ "php": "~7.1 || ^8.0"
+ },
+ "conflict": {
+ "doctrine/common": ">2.2,<2.4"
+ },
+ "require-dev": {
+ "alcaeus/mongo-php-adapter": "^1.1",
+ "cache/integration-tests": "dev-master",
+ "doctrine/coding-standard": "^9",
+ "mongodb/mongodb": "^1.1",
+ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
+ "predis/predis": "~1.0",
+ "psr/cache": "^1.0 || ^2.0 || ^3.0",
+ "symfony/cache": "^4.4 || ^5.4 || ^6",
+ "symfony/var-exporter": "^4.4 || ^5.4 || ^6"
+ },
+ "suggest": {
+ "alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver"
+ },
+ "type": "library",
"autoload": {
"psr-4": {
- "Doctrine\\Common\\": "lib/Doctrine/Common"
+ "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1006,6 +1047,10 @@
"MIT"
],
"authors": [
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
@@ -1014,10 +1059,6 @@
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
- {
- "name": "Guilherme Blanco",
- "email": "guilhermeblanco@gmail.com"
- },
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
@@ -1027,38 +1068,66 @@
"email": "schmittjoh@gmail.com"
}
],
- "description": "Common Library for Doctrine projects",
- "homepage": "http://www.doctrine-project.org",
+ "description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.",
+ "homepage": "https://www.doctrine-project.org/projects/cache.html",
"keywords": [
- "annotations",
- "collections",
- "eventmanager",
- "persistence",
- "spl"
+ "abstraction",
+ "apcu",
+ "cache",
+ "caching",
+ "couchdb",
+ "memcached",
+ "php",
+ "redis",
+ "xcache"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/cache/issues",
+ "source": "https://github.com/doctrine/cache/tree/1.13.0"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcache",
+ "type": "tidelift"
+ }
],
- "time": "2015-12-25 13:18:31"
+ "time": "2022-05-20T20:06:54+00:00"
},
{
"name": "doctrine/dbal",
- "version": "v2.5.4",
+ "version": "v2.9.3",
"source": {
"type": "git",
"url": "https://github.com/doctrine/dbal.git",
- "reference": "abbdfd1cff43a7b99d027af3be709bc8fc7d4769"
+ "reference": "7345cd59edfa2036eb0fa4264b77ae2576842035"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/dbal/zipball/abbdfd1cff43a7b99d027af3be709bc8fc7d4769",
- "reference": "abbdfd1cff43a7b99d027af3be709bc8fc7d4769",
+ "url": "https://api.github.com/repos/doctrine/dbal/zipball/7345cd59edfa2036eb0fa4264b77ae2576842035",
+ "reference": "7345cd59edfa2036eb0fa4264b77ae2576842035",
"shasum": ""
},
"require": {
- "doctrine/common": ">=2.4,<2.7-dev",
- "php": ">=5.3.2"
+ "doctrine/cache": "^1.0",
+ "doctrine/event-manager": "^1.0",
+ "ext-pdo": "*",
+ "php": "^7.1"
},
"require-dev": {
- "phpunit/phpunit": "4.*",
- "symfony/console": "2.*"
+ "doctrine/coding-standard": "^5.0",
+ "jetbrains/phpstorm-stubs": "^2018.1.2",
+ "phpstan/phpstan": "^0.10.1",
+ "phpunit/phpunit": "^7.4",
+ "symfony/console": "^2.0.5|^3.0|^4.0",
+ "symfony/phpunit-bridge": "^3.4.5|^4.0.5"
},
"suggest": {
"symfony/console": "For helpful console commands such as SQL execution and import of files."
@@ -1069,12 +1138,13 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.5.x-dev"
+ "dev-master": "2.9.x-dev",
+ "dev-develop": "3.0.x-dev"
}
},
"autoload": {
- "psr-0": {
- "Doctrine\\DBAL\\": "lib/"
+ "psr-4": {
+ "Doctrine\\DBAL\\": "lib/Doctrine/DBAL"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1082,6 +1152,10 @@
"MIT"
],
"authors": [
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
@@ -1090,54 +1164,107 @@
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
- {
- "name": "Guilherme Blanco",
- "email": "guilhermeblanco@gmail.com"
- },
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
}
],
- "description": "Database Abstraction Layer",
- "homepage": "http://www.doctrine-project.org",
+ "description": "Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.",
+ "homepage": "https://www.doctrine-project.org/projects/dbal.html",
"keywords": [
+ "abstraction",
"database",
"dbal",
+ "mysql",
"persistence",
+ "pgsql",
+ "php",
"queryobject"
],
- "time": "2016-01-05 22:11:12"
+ "support": {
+ "issues": "https://github.com/doctrine/dbal/issues",
+ "source": "https://github.com/doctrine/dbal/tree/2.9"
+ },
+ "time": "2019-11-02T22:19:34+00:00"
},
{
- "name": "doctrine/inflector",
- "version": "v1.1.0",
+ "name": "doctrine/deprecations",
+ "version": "1.1.2",
"source": {
"type": "git",
- "url": "https://github.com/doctrine/inflector.git",
- "reference": "90b2128806bfde671b6952ab8bea493942c1fdae"
+ "url": "https://github.com/doctrine/deprecations.git",
+ "reference": "4f2d4f2836e7ec4e7a8625e75c6aa916004db931"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/inflector/zipball/90b2128806bfde671b6952ab8bea493942c1fdae",
- "reference": "90b2128806bfde671b6952ab8bea493942c1fdae",
+ "url": "https://api.github.com/repos/doctrine/deprecations/zipball/4f2d4f2836e7ec4e7a8625e75c6aa916004db931",
+ "reference": "4f2d4f2836e7ec4e7a8625e75c6aa916004db931",
"shasum": ""
},
"require": {
- "php": ">=5.3.2"
+ "php": "^7.1 || ^8.0"
},
"require-dev": {
- "phpunit/phpunit": "4.*"
+ "doctrine/coding-standard": "^9",
+ "phpstan/phpstan": "1.4.10 || 1.10.15",
+ "phpstan/phpstan-phpunit": "^1.0",
+ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
+ "psalm/plugin-phpunit": "0.18.4",
+ "psr/log": "^1 || ^2 || ^3",
+ "vimeo/psalm": "4.30.0 || 5.12.0"
+ },
+ "suggest": {
+ "psr/log": "Allows logging deprecations via PSR-3 logger implementation"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.1.x-dev"
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations"
}
},
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.",
+ "homepage": "https://www.doctrine-project.org/",
+ "support": {
+ "issues": "https://github.com/doctrine/deprecations/issues",
+ "source": "https://github.com/doctrine/deprecations/tree/1.1.2"
+ },
+ "time": "2023-09-27T20:04:15+00:00"
+ },
+ {
+ "name": "doctrine/event-manager",
+ "version": "1.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/event-manager.git",
+ "reference": "95aa4cb529f1e96576f3fda9f5705ada4056a520"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/event-manager/zipball/95aa4cb529f1e96576f3fda9f5705ada4056a520",
+ "reference": "95aa4cb529f1e96576f3fda9f5705ada4056a520",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/deprecations": "^0.5.3 || ^1",
+ "php": "^7.1 || ^8.0"
+ },
+ "conflict": {
+ "doctrine/common": "<2.9"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^9 || ^10",
+ "phpstan/phpstan": "~1.4.10 || ^1.8.8",
+ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
+ "vimeo/psalm": "^4.24"
+ },
+ "type": "library",
"autoload": {
- "psr-0": {
- "Doctrine\\Common\\Inflector\\": "lib/"
+ "psr-4": {
+ "Doctrine\\Common\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1145,6 +1272,10 @@
"MIT"
],
"authors": [
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
@@ -1153,10 +1284,6 @@
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
- {
- "name": "Guilherme Blanco",
- "email": "guilhermeblanco@gmail.com"
- },
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
@@ -1164,44 +1291,75 @@
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
+ },
+ {
+ "name": "Marco Pivetta",
+ "email": "ocramius@gmail.com"
}
],
- "description": "Common String Manipulations with regard to casing and singular/plural rules.",
- "homepage": "http://www.doctrine-project.org",
+ "description": "The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects.",
+ "homepage": "https://www.doctrine-project.org/projects/event-manager.html",
"keywords": [
- "inflection",
- "pluralize",
- "singularize",
- "string"
+ "event",
+ "event dispatcher",
+ "event manager",
+ "event system",
+ "events"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/event-manager/issues",
+ "source": "https://github.com/doctrine/event-manager/tree/1.2.0"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fevent-manager",
+ "type": "tidelift"
+ }
],
- "time": "2015-11-06 14:35:42"
+ "time": "2022-10-12T20:51:15+00:00"
},
{
- "name": "doctrine/lexer",
- "version": "v1.0.1",
+ "name": "doctrine/inflector",
+ "version": "1.4.4",
"source": {
"type": "git",
- "url": "https://github.com/doctrine/lexer.git",
- "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c"
+ "url": "https://github.com/doctrine/inflector.git",
+ "reference": "4bd5c1cdfcd00e9e2d8c484f79150f67e5d355d9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c",
- "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c",
+ "url": "https://api.github.com/repos/doctrine/inflector/zipball/4bd5c1cdfcd00e9e2d8c484f79150f67e5d355d9",
+ "reference": "4bd5c1cdfcd00e9e2d8c484f79150f67e5d355d9",
"shasum": ""
},
"require": {
- "php": ">=5.3.2"
+ "php": "^7.1 || ^8.0"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^8.0",
+ "phpstan/phpstan": "^0.12",
+ "phpstan/phpstan-phpunit": "^0.12",
+ "phpstan/phpstan-strict-rules": "^0.12",
+ "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0.x-dev"
+ "dev-master": "2.0.x-dev"
}
},
"autoload": {
- "psr-0": {
- "Doctrine\\Common\\Lexer\\": "lib/"
+ "psr-4": {
+ "Doctrine\\Inflector\\": "lib/Doctrine/Inflector",
+ "Doctrine\\Common\\Inflector\\": "lib/Doctrine/Common/Inflector"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1209,59 +1367,88 @@
"MIT"
],
"authors": [
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
- "name": "Guilherme Blanco",
- "email": "guilhermeblanco@gmail.com"
+ "name": "Benjamin Eberlei",
+ "email": "kontakt@beberlei.de"
+ },
+ {
+ "name": "Jonathan Wage",
+ "email": "jonwage@gmail.com"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
}
],
- "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.",
- "homepage": "http://www.doctrine-project.org",
+ "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.",
+ "homepage": "https://www.doctrine-project.org/projects/inflector.html",
"keywords": [
- "lexer",
- "parser"
- ],
- "time": "2014-09-09 13:34:57"
+ "inflection",
+ "inflector",
+ "lowercase",
+ "manipulation",
+ "php",
+ "plural",
+ "singular",
+ "strings",
+ "uppercase",
+ "words"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/inflector/issues",
+ "source": "https://github.com/doctrine/inflector/tree/1.4.4"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finflector",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-04-16T17:34:40+00:00"
},
{
- "name": "fedeisas/laravel-mail-css-inliner",
- "version": "1.5",
+ "name": "doctrine/lexer",
+ "version": "1.2.3",
"source": {
"type": "git",
- "url": "https://github.com/fedeisas/laravel-mail-css-inliner.git",
- "reference": "8c3cd958634e865a90fc398900ea59c427dd35cc"
+ "url": "https://github.com/doctrine/lexer.git",
+ "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/fedeisas/laravel-mail-css-inliner/zipball/8c3cd958634e865a90fc398900ea59c427dd35cc",
- "reference": "8c3cd958634e865a90fc398900ea59c427dd35cc",
+ "url": "https://api.github.com/repos/doctrine/lexer/zipball/c268e882d4dbdd85e36e4ad69e02dc284f89d229",
+ "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229",
"shasum": ""
},
"require": {
- "illuminate/support": "~5.0",
- "php": ">=5.4.0",
- "tijsverkoyen/css-to-inline-styles": "~1.2"
+ "php": "^7.1 || ^8.0"
},
"require-dev": {
- "jakub-onderka/php-console-highlighter": "0.3.*",
- "jakub-onderka/php-parallel-lint": "0.8.*",
- "phpmd/phpmd": "~1.5",
- "phpunit/phpunit": "~4.0",
- "satooshi/php-coveralls": "~0.7@dev",
- "squizlabs/php_codesniffer": "~1.5",
- "swiftmailer/swiftmailer": "~5.0"
+ "doctrine/coding-standard": "^9.0",
+ "phpstan/phpstan": "^1.3",
+ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
+ "vimeo/psalm": "^4.11"
},
"type": "library",
"autoload": {
"psr-4": {
- "Fedeisas\\LaravelMailCssInliner\\": "src/"
+ "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1270,44 +1457,258 @@
],
"authors": [
{
- "name": "Fede Isas",
- "email": "fedeisas@hotmail.com"
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
+ {
+ "name": "Roman Borschel",
+ "email": "roman@code-factory.org"
+ },
+ {
+ "name": "Johannes Schmitt",
+ "email": "schmittjoh@gmail.com"
}
],
- "description": "Inline the CSS of your HTML emails using Laravel",
+ "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.",
+ "homepage": "https://www.doctrine-project.org/projects/lexer.html",
"keywords": [
- "css",
- "laravel",
- "mailer"
+ "annotations",
+ "docblock",
+ "lexer",
+ "parser",
+ "php"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/lexer/issues",
+ "source": "https://github.com/doctrine/lexer/tree/1.2.3"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-02-28T11:07:21+00:00"
+ },
+ {
+ "name": "dragonmantank/cron-expression",
+ "version": "v2.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/dragonmantank/cron-expression.git",
+ "reference": "65b2d8ee1f10915efb3b55597da3404f096acba2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/65b2d8ee1f10915efb3b55597da3404f096acba2",
+ "reference": "65b2d8ee1f10915efb3b55597da3404f096acba2",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.0|^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.4|^7.0|^8.0|^9.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Cron\\": "src/Cron/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ },
+ {
+ "name": "Chris Tankersley",
+ "email": "chris@ctankersley.com",
+ "homepage": "https://github.com/dragonmantank"
+ }
+ ],
+ "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due",
+ "keywords": [
+ "cron",
+ "schedule"
+ ],
+ "support": {
+ "issues": "https://github.com/dragonmantank/cron-expression/issues",
+ "source": "https://github.com/dragonmantank/cron-expression/tree/v2.3.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/dragonmantank",
+ "type": "github"
+ }
+ ],
+ "time": "2020-10-13T00:52:37+00:00"
+ },
+ {
+ "name": "egulias/email-validator",
+ "version": "2.1.25",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/egulias/EmailValidator.git",
+ "reference": "0dbf5d78455d4d6a41d186da50adc1122ec066f4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/0dbf5d78455d4d6a41d186da50adc1122ec066f4",
+ "reference": "0dbf5d78455d4d6a41d186da50adc1122ec066f4",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/lexer": "^1.0.1",
+ "php": ">=5.5",
+ "symfony/polyfill-intl-idn": "^1.10"
+ },
+ "require-dev": {
+ "dominicsayers/isemail": "^3.0.7",
+ "phpunit/phpunit": "^4.8.36|^7.5.15",
+ "satooshi/php-coveralls": "^1.0.1"
+ },
+ "suggest": {
+ "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Egulias\\EmailValidator\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Eduardo Gulias Davis"
+ }
+ ],
+ "description": "A library for validating emails against several RFCs",
+ "homepage": "https://github.com/egulias/EmailValidator",
+ "keywords": [
+ "email",
+ "emailvalidation",
+ "emailvalidator",
+ "validation",
+ "validator"
+ ],
+ "support": {
+ "issues": "https://github.com/egulias/EmailValidator/issues",
+ "source": "https://github.com/egulias/EmailValidator/tree/2.1.25"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/egulias",
+ "type": "github"
+ }
+ ],
+ "time": "2020-12-29T14:50:06+00:00"
+ },
+ {
+ "name": "erusev/parsedown",
+ "version": "1.7.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/erusev/parsedown.git",
+ "reference": "cb17b6477dfff935958ba01325f2e8a2bfa6dab3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/erusev/parsedown/zipball/cb17b6477dfff935958ba01325f2e8a2bfa6dab3",
+ "reference": "cb17b6477dfff935958ba01325f2e8a2bfa6dab3",
+ "shasum": ""
+ },
+ "require": {
+ "ext-mbstring": "*",
+ "php": ">=5.3.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.35"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-0": {
+ "Parsedown": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Emanuil Rusev",
+ "email": "hello@erusev.com",
+ "homepage": "http://erusev.com"
+ }
+ ],
+ "description": "Parser for Markdown.",
+ "homepage": "http://parsedown.org",
+ "keywords": [
+ "markdown",
+ "parser"
],
- "time": "2016-04-19 07:02:48"
+ "support": {
+ "issues": "https://github.com/erusev/parsedown/issues",
+ "source": "https://github.com/erusev/parsedown/tree/1.7.x"
+ },
+ "time": "2019-12-30T22:54:17+00:00"
},
{
"name": "fideloper/proxy",
- "version": "3.1.0",
+ "version": "4.4.2",
"source": {
"type": "git",
"url": "https://github.com/fideloper/TrustedProxy.git",
- "reference": "ec4dd30141e2515e307aea3539ff242e85c3f120"
+ "reference": "a751f2bc86dd8e6cfef12dc0cbdada82f5a18750"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/fideloper/TrustedProxy/zipball/ec4dd30141e2515e307aea3539ff242e85c3f120",
- "reference": "ec4dd30141e2515e307aea3539ff242e85c3f120",
+ "url": "https://api.github.com/repos/fideloper/TrustedProxy/zipball/a751f2bc86dd8e6cfef12dc0cbdada82f5a18750",
+ "reference": "a751f2bc86dd8e6cfef12dc0cbdada82f5a18750",
"shasum": ""
},
"require": {
- "illuminate/contracts": "~5.0",
+ "illuminate/contracts": "^5.0|^6.0|^7.0|^8.0|^9.0",
"php": ">=5.4.0"
},
"require-dev": {
- "illuminate/http": "~5.0",
- "mockery/mockery": "~0.9.3"
+ "illuminate/http": "^5.0|^6.0|^7.0|^8.0|^9.0",
+ "mockery/mockery": "^1.0",
+ "phpunit/phpunit": "^8.5.8|^9.3.3"
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-master": "3.1-dev"
+ "laravel": {
+ "providers": [
+ "Fideloper\\Proxy\\TrustedProxyServiceProvider"
+ ]
}
},
"autoload": {
@@ -1331,38 +1732,48 @@
"proxy",
"trusted proxy"
],
- "time": "2015-12-24 15:02:55"
+ "support": {
+ "issues": "https://github.com/fideloper/TrustedProxy/issues",
+ "source": "https://github.com/fideloper/TrustedProxy/tree/4.4.2"
+ },
+ "time": "2022-02-09T13:33:34+00:00"
},
{
"name": "graham-campbell/binput",
- "version": "v3.4.0",
+ "version": "v6.2.0",
"source": {
"type": "git",
"url": "https://github.com/GrahamCampbell/Laravel-Binput.git",
- "reference": "814bcce1c012fbdf3a8275eef45e5d84ad01239d"
+ "reference": "9c0df9c3d0481a495bdc0638ee67bc199d70e3b4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/GrahamCampbell/Laravel-Binput/zipball/814bcce1c012fbdf3a8275eef45e5d84ad01239d",
- "reference": "814bcce1c012fbdf3a8275eef45e5d84ad01239d",
+ "url": "https://api.github.com/repos/GrahamCampbell/Laravel-Binput/zipball/9c0df9c3d0481a495bdc0638ee67bc199d70e3b4",
+ "reference": "9c0df9c3d0481a495bdc0638ee67bc199d70e3b4",
"shasum": ""
},
"require": {
- "graham-campbell/security": "^3.5",
- "illuminate/contracts": "5.1.*|5.2.*|5.3.*",
- "illuminate/http": "5.1.*|5.2.*|5.3.*",
- "illuminate/support": "5.1.*|5.2.*|5.3.*",
- "php": ">=5.5.9"
+ "graham-campbell/security": "^6.2",
+ "illuminate/contracts": "^5.5|^6.0",
+ "illuminate/http": "^5.5|^6.0",
+ "illuminate/support": "^5.5|^6.0",
+ "php": "^7.1.3"
},
"require-dev": {
- "graham-campbell/testbench": "^3.1",
- "mockery/mockery": "^0.9.4",
- "phpunit/phpunit": "^4.8|^5.0"
+ "graham-campbell/analyzer": "^2.1",
+ "graham-campbell/testbench": "^5.2",
+ "mockery/mockery": "^1.0",
+ "phpunit/phpunit": "^6.5|^7.0|^8.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.4-dev"
+ "dev-master": "6.2-dev"
+ },
+ "laravel": {
+ "providers": [
+ "GrahamCampbell\\Binput\\BinputServiceProvider"
+ ]
}
},
"autoload": {
@@ -1394,42 +1805,59 @@
"laravel",
"security"
],
- "time": "2016-04-26 14:18:44"
+ "support": {
+ "issues": "https://github.com/GrahamCampbell/Laravel-Binput/issues",
+ "source": "https://github.com/GrahamCampbell/Laravel-Binput/tree/master"
+ },
+ "time": "2019-08-26T16:30:03+00:00"
},
{
- "name": "graham-campbell/core",
- "version": "v5.1.0",
+ "name": "graham-campbell/exceptions",
+ "version": "v11.3.0",
"source": {
"type": "git",
- "url": "https://github.com/GrahamCampbell/Laravel-Core.git",
- "reference": "9ca45b4d0f9bde7084ffac6ca3337af153340790"
+ "url": "https://github.com/GrahamCampbell/Laravel-Exceptions.git",
+ "reference": "c33548417cf9903a049c7311ab57352a7e720b33"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/GrahamCampbell/Laravel-Core/zipball/9ca45b4d0f9bde7084ffac6ca3337af153340790",
- "reference": "9ca45b4d0f9bde7084ffac6ca3337af153340790",
+ "url": "https://api.github.com/repos/GrahamCampbell/Laravel-Exceptions/zipball/c33548417cf9903a049c7311ab57352a7e720b33",
+ "reference": "c33548417cf9903a049c7311ab57352a7e720b33",
"shasum": ""
},
"require": {
- "illuminate/console": "5.1.*|5.2.*|5.3.*",
- "illuminate/contracts": "5.1.*|5.2.*|5.3.*",
- "illuminate/support": "5.1.*|5.2.*|5.3.*",
- "php": ">=5.5.9"
+ "illuminate/contracts": "5.5.*|5.6.*|5.7.*|5.8.*",
+ "illuminate/support": "5.5.*|5.6.*|5.7.*|5.8.*",
+ "php": "^7.1.3",
+ "psr/log": "^1.0",
+ "symfony/console": "^3.3|^4.0",
+ "symfony/debug": "^3.3|^4.0",
+ "symfony/http-foundation": "^3.3|^4.0"
},
"require-dev": {
- "graham-campbell/testbench": "^3.1",
- "mockery/mockery": "^0.9.4",
- "phpunit/phpunit": "^4.8|^5.0"
+ "filp/whoops": "^2.1.4",
+ "graham-campbell/analyzer": "^2.1",
+ "graham-campbell/testbench": "^5.2",
+ "mockery/mockery": "^1.0",
+ "phpunit/phpunit": "^6.5|^7.0|^8.0"
+ },
+ "suggest": {
+ "filp/whoops": "Enables use of the debug displayer."
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "5.1-dev"
+ "dev-master": "11.3-dev"
+ },
+ "laravel": {
+ "providers": [
+ "GrahamCampbell\\Exceptions\\ExceptionsServiceProvider"
+ ]
}
},
"autoload": {
"psr-4": {
- "GrahamCampbell\\Core\\": "src/"
+ "GrahamCampbell\\Exceptions\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1442,61 +1870,57 @@
"email": "graham@alt-three.com"
}
],
- "description": "Core Provides Some Extra Functionality For Laravel 5",
+ "description": "Provides A Powerful Error Response System For Both Development And Production",
"keywords": [
"Graham Campbell",
"GrahamCampbell",
- "Laravel Core",
- "Laravel-Core",
- "base",
- "core",
+ "Laravel Exceptions",
+ "Laravel-Exceptions",
+ "error",
+ "errors",
+ "exception",
+ "exceptions",
"framework",
"laravel",
- "starter"
+ "whoops"
],
- "time": "2016-05-25 09:22:06"
+ "support": {
+ "issues": "https://github.com/GrahamCampbell/Laravel-Exceptions/issues",
+ "source": "https://github.com/GrahamCampbell/Laravel-Exceptions/tree/v11.3.0"
+ },
+ "time": "2019-06-03T06:57:27+00:00"
},
{
- "name": "graham-campbell/exceptions",
- "version": "v8.8.0",
+ "name": "graham-campbell/guzzle-factory",
+ "version": "v3.0.4",
"source": {
"type": "git",
- "url": "https://github.com/GrahamCampbell/Laravel-Exceptions.git",
- "reference": "e93f725d3637625897fe6ec30dc454cb23adb331"
+ "url": "https://github.com/GrahamCampbell/Guzzle-Factory.git",
+ "reference": "618cf7220b177c6d9939a36331df937739ffc596"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/GrahamCampbell/Laravel-Exceptions/zipball/e93f725d3637625897fe6ec30dc454cb23adb331",
- "reference": "e93f725d3637625897fe6ec30dc454cb23adb331",
+ "url": "https://api.github.com/repos/GrahamCampbell/Guzzle-Factory/zipball/618cf7220b177c6d9939a36331df937739ffc596",
+ "reference": "618cf7220b177c6d9939a36331df937739ffc596",
"shasum": ""
},
"require": {
- "illuminate/contracts": "5.1.*|5.2.*|5.3.*",
- "illuminate/support": "5.1.*|5.2.*|5.3.*",
- "paragonie/random_compat": "^1.1|^2.0",
- "php": ">=5.5.9",
- "psr/log": "^1.0",
- "symfony/debug": "^2.7|^3.0",
- "symfony/http-foundation": "^2.7|^3.0"
+ "guzzlehttp/guzzle": "^6.2",
+ "php": "^7.0|^8.0"
},
"require-dev": {
- "filp/whoops": "^1.1|^2.0",
- "graham-campbell/testbench": "^3.1",
- "mockery/mockery": "^0.9.4",
- "phpunit/phpunit": "^4.8|^5.0"
- },
- "suggest": {
- "filp/whoops": "Enables use of the debug displayer."
+ "graham-campbell/analyzer": "^2.4",
+ "phpunit/phpunit": "^6.5|^7.0|^8.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "8.7-dev"
+ "dev-master": "3.0-dev"
}
},
"autoload": {
"psr-4": {
- "GrahamCampbell\\Exceptions\\": "src/"
+ "GrahamCampbell\\GuzzleFactory\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1509,53 +1933,67 @@
"email": "graham@alt-three.com"
}
],
- "description": "Provides A Powerful Error Response System For Both Development And Production",
+ "description": "Provides A Simple Guzzle Factory With Good Defaults",
"keywords": [
"Graham Campbell",
"GrahamCampbell",
- "Laravel Exceptions",
- "Laravel-Exceptions",
- "error",
- "errors",
- "exception",
- "exceptions",
- "framework",
- "laravel",
- "whoops"
+ "Guzzle",
+ "Guzzle Factory",
+ "Guzzle-Factory",
+ "http"
+ ],
+ "support": {
+ "issues": "https://github.com/GrahamCampbell/Guzzle-Factory/issues",
+ "source": "https://github.com/GrahamCampbell/Guzzle-Factory/tree/3.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/GrahamCampbell",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/graham-campbell/guzzle-factory",
+ "type": "tidelift"
+ }
],
- "time": "2016-07-31 14:54:35"
+ "time": "2020-05-02T14:45:48+00:00"
},
{
"name": "graham-campbell/markdown",
- "version": "v6.1.0",
+ "version": "v11.2.1",
"source": {
"type": "git",
"url": "https://github.com/GrahamCampbell/Laravel-Markdown.git",
- "reference": "2208ec910d9880d6bca28d332ae7f3b7350355d1"
+ "reference": "7ead48c43098b562707a30650843d4279786b0d9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/GrahamCampbell/Laravel-Markdown/zipball/2208ec910d9880d6bca28d332ae7f3b7350355d1",
- "reference": "2208ec910d9880d6bca28d332ae7f3b7350355d1",
+ "url": "https://api.github.com/repos/GrahamCampbell/Laravel-Markdown/zipball/7ead48c43098b562707a30650843d4279786b0d9",
+ "reference": "7ead48c43098b562707a30650843d4279786b0d9",
"shasum": ""
},
"require": {
- "illuminate/contracts": "5.1.*|5.2.*|5.3.*",
- "illuminate/support": "5.1.*|5.2.*|5.3.*",
- "illuminate/view": "5.1.*|5.2.*|5.3.*",
- "league/commonmark": "^0.13",
- "php": ">=5.5.9"
+ "illuminate/contracts": "^5.5|^6.0|^7.0",
+ "illuminate/support": "^5.5|^6.0|^7.0",
+ "illuminate/view": "^5.5|^6.0|^7.0",
+ "league/commonmark": "^1.3",
+ "php": "^7.1.3"
},
"require-dev": {
- "graham-campbell/testbench": "^3.1",
- "league/commonmark-extras": "^0.1",
- "mockery/mockery": "^0.9.4",
- "phpunit/phpunit": "^4.8|^5.0"
+ "graham-campbell/analyzer": "^2.4",
+ "graham-campbell/testbench": "^5.4",
+ "mockery/mockery": "^1.3.1",
+ "phpunit/phpunit": "^6.5|^7.0|^8.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "6.1-dev"
+ "dev-master": "11.2-dev"
+ },
+ "laravel": {
+ "providers": [
+ "GrahamCampbell\\Markdown\\MarkdownServiceProvider"
+ ]
}
},
"autoload": {
@@ -1573,7 +2011,7 @@
"email": "graham@alt-three.com"
}
],
- "description": "Markdown Is A CommonMark Wrapper For Laravel 5",
+ "description": "Markdown Is A CommonMark Wrapper For Laravel",
"keywords": [
"Graham Campbell",
"GrahamCampbell",
@@ -1585,35 +2023,60 @@
"laravel",
"markdown"
],
- "time": "2016-04-26 14:28:21"
+ "support": {
+ "issues": "https://github.com/GrahamCampbell/Laravel-Markdown/issues",
+ "source": "https://github.com/GrahamCampbell/Laravel-Markdown/tree/11.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/GrahamCampbell",
+ "type": "github"
+ },
+ {
+ "url": "https://www.patreon.com/GrahamJCampbell",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/graham-campbell/markdown",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2020-04-14T14:11:12+00:00"
},
{
"name": "graham-campbell/security",
- "version": "v3.6.0",
+ "version": "v6.2.0",
"source": {
"type": "git",
"url": "https://github.com/GrahamCampbell/Laravel-Security.git",
- "reference": "07d4ec2658582032afe225928bde883474e2a543"
+ "reference": "93b3e09774987916f9a91071b2e53738180f2ba8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/GrahamCampbell/Laravel-Security/zipball/07d4ec2658582032afe225928bde883474e2a543",
- "reference": "07d4ec2658582032afe225928bde883474e2a543",
+ "url": "https://api.github.com/repos/GrahamCampbell/Laravel-Security/zipball/93b3e09774987916f9a91071b2e53738180f2ba8",
+ "reference": "93b3e09774987916f9a91071b2e53738180f2ba8",
"shasum": ""
},
"require": {
- "illuminate/contracts": "5.1.*|5.2.*|5.3.*",
- "illuminate/support": "5.1.*|5.2.*|5.3.*",
- "php": ">=5.5.9"
+ "graham-campbell/security-core": "^1.0",
+ "illuminate/contracts": "^5.5|^6.0",
+ "illuminate/support": "^5.5|^6.0",
+ "php": "^7.1.3"
},
"require-dev": {
- "graham-campbell/testbench": "^3.1",
- "phpunit/phpunit": "^4.8|^5.0"
+ "graham-campbell/analyzer": "^2.1",
+ "graham-campbell/testbench": "^5.2",
+ "phpunit/phpunit": "^6.5|^7.0|^8.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.6-dev"
+ "dev-master": "6.2-dev"
+ },
+ "laravel": {
+ "providers": [
+ "GrahamCampbell\\Security\\SecurityServiceProvider"
+ ]
}
},
"autoload": {
@@ -1642,44 +2105,42 @@
"laravel",
"security"
],
- "time": "2016-04-26 14:29:04"
+ "support": {
+ "issues": "https://github.com/GrahamCampbell/Laravel-Security/issues",
+ "source": "https://github.com/GrahamCampbell/Laravel-Security/tree/master"
+ },
+ "time": "2019-08-26T16:30:00+00:00"
},
{
- "name": "guzzlehttp/guzzle",
- "version": "6.2.1",
+ "name": "graham-campbell/security-core",
+ "version": "v1.0.3",
"source": {
"type": "git",
- "url": "https://github.com/guzzle/guzzle.git",
- "reference": "3f808fba627f2c5b69e2501217bf31af349c1427"
+ "url": "https://github.com/GrahamCampbell/Security-Core.git",
+ "reference": "3b14e58dba84b0238a3409818d6f67acc5c00bf9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/guzzle/zipball/3f808fba627f2c5b69e2501217bf31af349c1427",
- "reference": "3f808fba627f2c5b69e2501217bf31af349c1427",
+ "url": "https://api.github.com/repos/GrahamCampbell/Security-Core/zipball/3b14e58dba84b0238a3409818d6f67acc5c00bf9",
+ "reference": "3b14e58dba84b0238a3409818d6f67acc5c00bf9",
"shasum": ""
},
"require": {
- "guzzlehttp/promises": "^1.0",
- "guzzlehttp/psr7": "^1.3.1",
- "php": ">=5.5"
+ "php": "^7.0"
},
"require-dev": {
- "ext-curl": "*",
- "phpunit/phpunit": "^4.0",
- "psr/log": "^1.0"
+ "graham-campbell/analyzer": "^2.4",
+ "phpunit/phpunit": "^6.5|^7.5|^8.4|^9.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "6.2-dev"
+ "dev-master": "1.0-dev"
}
},
"autoload": {
- "files": [
- "src/functions_include.php"
- ],
"psr-4": {
- "GuzzleHttp\\": "src/"
+ "GrahamCampbell\\SecurityCore\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1688,161 +2149,368 @@
],
"authors": [
{
- "name": "Michael Dowling",
- "email": "mtdowling@gmail.com",
- "homepage": "https://github.com/mtdowling"
+ "name": "Graham Campbell",
+ "email": "graham@alt-three.com"
}
],
- "description": "Guzzle is a PHP HTTP client library",
- "homepage": "http://guzzlephp.org/",
+ "description": "Security Core Is A Port Of The Security Class From Codeigniter 3 For General Use",
"keywords": [
- "client",
- "curl",
+ "Graham Campbell",
+ "GrahamCampbell",
+ "Security Core",
+ "Security-Core",
+ "codeigniter",
"framework",
- "http",
- "http client",
- "rest",
- "web service"
+ "laravel",
+ "security"
],
- "time": "2016-07-15 17:22:37"
- },
- {
- "name": "guzzlehttp/promises",
- "version": "1.2.0",
+ "support": {
+ "issues": "https://github.com/GrahamCampbell/Security-Core/issues",
+ "source": "https://github.com/GrahamCampbell/Security-Core/tree/v1.0.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/GrahamCampbell",
+ "type": "github"
+ },
+ {
+ "url": "https://www.patreon.com/GrahamJCampbell",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/graham-campbell/security-core",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2020-04-13T13:30:49+00:00"
+ },
+ {
+ "name": "guzzlehttp/guzzle",
+ "version": "6.5.8",
"source": {
"type": "git",
- "url": "https://github.com/guzzle/promises.git",
- "reference": "c10d860e2a9595f8883527fa0021c7da9e65f579"
+ "url": "https://github.com/guzzle/guzzle.git",
+ "reference": "a52f0440530b54fa079ce76e8c5d196a42cad981"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/promises/zipball/c10d860e2a9595f8883527fa0021c7da9e65f579",
- "reference": "c10d860e2a9595f8883527fa0021c7da9e65f579",
+ "url": "https://api.github.com/repos/guzzle/guzzle/zipball/a52f0440530b54fa079ce76e8c5d196a42cad981",
+ "reference": "a52f0440530b54fa079ce76e8c5d196a42cad981",
"shasum": ""
},
"require": {
- "php": ">=5.5.0"
+ "ext-json": "*",
+ "guzzlehttp/promises": "^1.0",
+ "guzzlehttp/psr7": "^1.9",
+ "php": ">=5.5",
+ "symfony/polyfill-intl-idn": "^1.17"
},
"require-dev": {
- "phpunit/phpunit": "~4.0"
+ "ext-curl": "*",
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0",
+ "psr/log": "^1.1"
+ },
+ "suggest": {
+ "psr/log": "Required for using the Log middleware"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0-dev"
+ "dev-master": "6.5-dev"
}
},
"autoload": {
+ "files": [
+ "src/functions_include.php"
+ ],
"psr-4": {
- "GuzzleHttp\\Promise\\": "src/"
+ "GuzzleHttp\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Graham Campbell",
+ "email": "hello@gjcampbell.co.uk",
+ "homepage": "https://github.com/GrahamCampbell"
+ },
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ },
+ {
+ "name": "Jeremy Lindblom",
+ "email": "jeremeamia@gmail.com",
+ "homepage": "https://github.com/jeremeamia"
+ },
+ {
+ "name": "George Mponos",
+ "email": "gmponos@gmail.com",
+ "homepage": "https://github.com/gmponos"
+ },
+ {
+ "name": "Tobias Nyholm",
+ "email": "tobias.nyholm@gmail.com",
+ "homepage": "https://github.com/Nyholm"
+ },
+ {
+ "name": "Márk Sági-Kazár",
+ "email": "mark.sagikazar@gmail.com",
+ "homepage": "https://github.com/sagikazarmark"
+ },
+ {
+ "name": "Tobias Schultze",
+ "email": "webmaster@tubo-world.de",
+ "homepage": "https://github.com/Tobion"
+ }
+ ],
+ "description": "Guzzle is a PHP HTTP client library",
+ "homepage": "http://guzzlephp.org/",
+ "keywords": [
+ "client",
+ "curl",
+ "framework",
+ "http",
+ "http client",
+ "rest",
+ "web service"
+ ],
+ "support": {
+ "issues": "https://github.com/guzzle/guzzle/issues",
+ "source": "https://github.com/guzzle/guzzle/tree/6.5.8"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/GrahamCampbell",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/Nyholm",
+ "type": "github"
},
+ {
+ "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-06-20T22:16:07+00:00"
+ },
+ {
+ "name": "guzzlehttp/promises",
+ "version": "1.5.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/promises.git",
+ "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/promises/zipball/67ab6e18aaa14d753cc148911d273f6e6cb6721e",
+ "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "^4.4 || ^5.1"
+ },
+ "type": "library",
+ "autoload": {
"files": [
"src/functions_include.php"
- ]
+ ],
+ "psr-4": {
+ "GuzzleHttp\\Promise\\": "src/"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
+ {
+ "name": "Graham Campbell",
+ "email": "hello@gjcampbell.co.uk",
+ "homepage": "https://github.com/GrahamCampbell"
+ },
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
+ },
+ {
+ "name": "Tobias Nyholm",
+ "email": "tobias.nyholm@gmail.com",
+ "homepage": "https://github.com/Nyholm"
+ },
+ {
+ "name": "Tobias Schultze",
+ "email": "webmaster@tubo-world.de",
+ "homepage": "https://github.com/Tobion"
}
],
"description": "Guzzle promises library",
"keywords": [
"promise"
],
- "time": "2016-05-18 16:56:05"
+ "support": {
+ "issues": "https://github.com/guzzle/promises/issues",
+ "source": "https://github.com/guzzle/promises/tree/1.5.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/GrahamCampbell",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/Nyholm",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-05-21T12:31:43+00:00"
},
{
"name": "guzzlehttp/psr7",
- "version": "1.3.1",
+ "version": "1.9.1",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
- "reference": "5c6447c9df362e8f8093bda8f5d8873fe5c7f65b"
+ "reference": "e4490cabc77465aaee90b20cfc9a770f8c04be6b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/psr7/zipball/5c6447c9df362e8f8093bda8f5d8873fe5c7f65b",
- "reference": "5c6447c9df362e8f8093bda8f5d8873fe5c7f65b",
+ "url": "https://api.github.com/repos/guzzle/psr7/zipball/e4490cabc77465aaee90b20cfc9a770f8c04be6b",
+ "reference": "e4490cabc77465aaee90b20cfc9a770f8c04be6b",
"shasum": ""
},
"require": {
"php": ">=5.4.0",
- "psr/http-message": "~1.0"
+ "psr/http-message": "~1.0",
+ "ralouphie/getallheaders": "^2.0.5 || ^3.0.0"
},
"provide": {
"psr/http-message-implementation": "1.0"
},
"require-dev": {
- "phpunit/phpunit": "~4.0"
+ "ext-zlib": "*",
+ "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10"
},
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.4-dev"
- }
+ "suggest": {
+ "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
},
+ "type": "library",
"autoload": {
- "psr-4": {
- "GuzzleHttp\\Psr7\\": "src/"
- },
"files": [
"src/functions_include.php"
- ]
+ ],
+ "psr-4": {
+ "GuzzleHttp\\Psr7\\": "src/"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
+ {
+ "name": "Graham Campbell",
+ "email": "hello@gjcampbell.co.uk",
+ "homepage": "https://github.com/GrahamCampbell"
+ },
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
+ },
+ {
+ "name": "George Mponos",
+ "email": "gmponos@gmail.com",
+ "homepage": "https://github.com/gmponos"
+ },
+ {
+ "name": "Tobias Nyholm",
+ "email": "tobias.nyholm@gmail.com",
+ "homepage": "https://github.com/Nyholm"
+ },
+ {
+ "name": "Márk Sági-Kazár",
+ "email": "mark.sagikazar@gmail.com",
+ "homepage": "https://github.com/sagikazarmark"
+ },
+ {
+ "name": "Tobias Schultze",
+ "email": "webmaster@tubo-world.de",
+ "homepage": "https://github.com/Tobion"
}
],
- "description": "PSR-7 message implementation",
+ "description": "PSR-7 message implementation that also provides common utility methods",
"keywords": [
"http",
"message",
+ "psr-7",
+ "request",
+ "response",
"stream",
- "uri"
+ "uri",
+ "url"
+ ],
+ "support": {
+ "issues": "https://github.com/guzzle/psr7/issues",
+ "source": "https://github.com/guzzle/psr7/tree/1.9.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/GrahamCampbell",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/Nyholm",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7",
+ "type": "tidelift"
+ }
],
- "time": "2016-06-24 23:00:38"
+ "time": "2023-04-17T16:00:37+00:00"
},
{
"name": "jakub-onderka/php-console-color",
- "version": "0.1",
+ "version": "v0.2",
"source": {
"type": "git",
"url": "https://github.com/JakubOnderka/PHP-Console-Color.git",
- "reference": "e0b393dacf7703fc36a4efc3df1435485197e6c1"
+ "reference": "d5deaecff52a0d61ccb613bb3804088da0307191"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/JakubOnderka/PHP-Console-Color/zipball/e0b393dacf7703fc36a4efc3df1435485197e6c1",
- "reference": "e0b393dacf7703fc36a4efc3df1435485197e6c1",
+ "url": "https://api.github.com/repos/JakubOnderka/PHP-Console-Color/zipball/d5deaecff52a0d61ccb613bb3804088da0307191",
+ "reference": "d5deaecff52a0d61ccb613bb3804088da0307191",
"shasum": ""
},
"require": {
- "php": ">=5.3.2"
+ "php": ">=5.4.0"
},
"require-dev": {
"jakub-onderka/php-code-style": "1.0",
- "jakub-onderka/php-parallel-lint": "0.*",
+ "jakub-onderka/php-parallel-lint": "1.0",
"jakub-onderka/php-var-dump-check": "0.*",
- "phpunit/phpunit": "3.7.*",
+ "phpunit/phpunit": "~4.3",
"squizlabs/php_codesniffer": "1.*"
},
"type": "library",
"autoload": {
- "psr-0": {
- "JakubOnderka\\PhpConsoleColor": "src/"
+ "psr-4": {
+ "JakubOnderka\\PhpConsoleColor\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1852,41 +2520,46 @@
"authors": [
{
"name": "Jakub Onderka",
- "email": "jakub.onderka@gmail.com",
- "homepage": "http://www.acci.cz"
+ "email": "jakub.onderka@gmail.com"
}
],
- "time": "2014-04-08 15:00:19"
+ "support": {
+ "issues": "https://github.com/JakubOnderka/PHP-Console-Color/issues",
+ "source": "https://github.com/JakubOnderka/PHP-Console-Color/tree/master"
+ },
+ "abandoned": "php-parallel-lint/php-console-color",
+ "time": "2018-09-29T17:23:10+00:00"
},
{
"name": "jakub-onderka/php-console-highlighter",
- "version": "v0.3.2",
+ "version": "v0.4",
"source": {
"type": "git",
"url": "https://github.com/JakubOnderka/PHP-Console-Highlighter.git",
- "reference": "7daa75df45242c8d5b75a22c00a201e7954e4fb5"
+ "reference": "9f7a229a69d52506914b4bc61bfdb199d90c5547"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/JakubOnderka/PHP-Console-Highlighter/zipball/7daa75df45242c8d5b75a22c00a201e7954e4fb5",
- "reference": "7daa75df45242c8d5b75a22c00a201e7954e4fb5",
+ "url": "https://api.github.com/repos/JakubOnderka/PHP-Console-Highlighter/zipball/9f7a229a69d52506914b4bc61bfdb199d90c5547",
+ "reference": "9f7a229a69d52506914b4bc61bfdb199d90c5547",
"shasum": ""
},
"require": {
- "jakub-onderka/php-console-color": "~0.1",
- "php": ">=5.3.0"
+ "ext-tokenizer": "*",
+ "jakub-onderka/php-console-color": "~0.2",
+ "php": ">=5.4.0"
},
"require-dev": {
"jakub-onderka/php-code-style": "~1.0",
- "jakub-onderka/php-parallel-lint": "~0.5",
+ "jakub-onderka/php-parallel-lint": "~1.0",
"jakub-onderka/php-var-dump-check": "~0.1",
"phpunit/phpunit": "~4.0",
"squizlabs/php_codesniffer": "~1.5"
},
"type": "library",
"autoload": {
- "psr-0": {
- "JakubOnderka\\PhpConsoleHighlighter": "src/"
+ "psr-4": {
+ "JakubOnderka\\PhpConsoleHighlighter\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1900,35 +2573,49 @@
"homepage": "http://www.acci.cz/"
}
],
- "time": "2015-04-20 18:58:01"
+ "description": "Highlight PHP code in terminal",
+ "support": {
+ "issues": "https://github.com/JakubOnderka/PHP-Console-Highlighter/issues",
+ "source": "https://github.com/JakubOnderka/PHP-Console-Highlighter/tree/master"
+ },
+ "abandoned": "php-parallel-lint/php-console-highlighter",
+ "time": "2018-09-29T18:48:56+00:00"
},
{
"name": "jenssegers/date",
- "version": "v3.2.4",
+ "version": "v3.5.0",
"source": {
"type": "git",
"url": "https://github.com/jenssegers/date.git",
- "reference": "53cefb19ca0b8c314adce4c7ec79333333c9edc4"
+ "reference": "58393b0544fc2525b3fcd02aa4c989857107e05a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/jenssegers/date/zipball/53cefb19ca0b8c314adce4c7ec79333333c9edc4",
- "reference": "53cefb19ca0b8c314adce4c7ec79333333c9edc4",
+ "url": "https://api.github.com/repos/jenssegers/date/zipball/58393b0544fc2525b3fcd02aa4c989857107e05a",
+ "reference": "58393b0544fc2525b3fcd02aa4c989857107e05a",
"shasum": ""
},
"require": {
- "nesbot/carbon": "^1.0",
- "php": ">=5.4",
- "symfony/translation": "^2.7|^3.0"
+ "nesbot/carbon": "^1.0|^2.0",
+ "php": ">=5.6",
+ "symfony/translation": "^2.7|^3.0|^4.0"
},
"require-dev": {
- "phpunit/phpunit": "^4.0|^5.0",
- "satooshi/php-coveralls": "^1.0"
+ "phpunit/phpunit": "^5.0|^6.0|^7.0",
+ "satooshi/php-coveralls": "^2.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.1-dev"
+ },
+ "laravel": {
+ "providers": [
+ "Jenssegers\\Date\\DateServiceProvider"
+ ],
+ "aliases": {
+ "Date": "Jenssegers\\Date\\Date"
+ }
}
},
"autoload": {
@@ -1957,39 +2644,42 @@
"time",
"translation"
],
- "time": "2016-08-31 07:50:37"
+ "support": {
+ "issues": "https://github.com/jenssegers/date/issues",
+ "source": "https://github.com/jenssegers/date/tree/master"
+ },
+ "time": "2019-03-10T08:50:58+00:00"
},
{
- "name": "jeremeamia/SuperClosure",
- "version": "2.2.0",
+ "name": "kylekatarnls/update-helper",
+ "version": "1.2.1",
"source": {
"type": "git",
- "url": "https://github.com/jeremeamia/super_closure.git",
- "reference": "29a88be2a4846d27c1613aed0c9071dfad7b5938"
+ "url": "https://github.com/kylekatarnls/update-helper.git",
+ "reference": "429be50660ed8a196e0798e5939760f168ec8ce9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/jeremeamia/super_closure/zipball/29a88be2a4846d27c1613aed0c9071dfad7b5938",
- "reference": "29a88be2a4846d27c1613aed0c9071dfad7b5938",
+ "url": "https://api.github.com/repos/kylekatarnls/update-helper/zipball/429be50660ed8a196e0798e5939760f168ec8ce9",
+ "reference": "429be50660ed8a196e0798e5939760f168ec8ce9",
"shasum": ""
},
"require": {
- "nikic/php-parser": "^1.2|^2.0",
- "php": ">=5.4",
- "symfony/polyfill-php56": "^1.0"
+ "composer-plugin-api": "^1.1.0 || ^2.0.0",
+ "php": ">=5.3.0"
},
"require-dev": {
- "phpunit/phpunit": "^4.0|^5.0"
+ "codeclimate/php-test-reporter": "dev-master",
+ "composer/composer": "2.0.x-dev || ^2.0.0-dev",
+ "phpunit/phpunit": ">=4.8.35 <6.0"
},
- "type": "library",
+ "type": "composer-plugin",
"extra": {
- "branch-alias": {
- "dev-master": "2.2-dev"
- }
+ "class": "UpdateHelper\\ComposerPlugin"
},
"autoload": {
- "psr-4": {
- "SuperClosure\\": "src/"
+ "psr-0": {
+ "UpdateHelper\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1998,64 +2688,75 @@
],
"authors": [
{
- "name": "Jeremy Lindblom",
- "email": "jeremeamia@gmail.com",
- "homepage": "https://github.com/jeremeamia",
- "role": "Developer"
+ "name": "Kyle",
+ "email": "kylekatarnls@gmail.com"
}
],
- "description": "Serialize Closure objects, including their context and binding",
- "homepage": "https://github.com/jeremeamia/super_closure",
- "keywords": [
- "closure",
- "function",
- "lambda",
- "parser",
- "serializable",
- "serialize",
- "tokenizer"
+ "description": "Update helper",
+ "support": {
+ "issues": "https://github.com/kylekatarnls/update-helper/issues",
+ "source": "https://github.com/kylekatarnls/update-helper/tree/1.2.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/kylekatarnls",
+ "type": "github"
+ },
+ {
+ "url": "https://opencollective.com/Carbon",
+ "type": "open_collective"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/nesbot/carbon",
+ "type": "tidelift"
+ }
],
- "time": "2015-12-05 17:17:57"
+ "time": "2020-04-07T20:44:10+00:00"
},
{
"name": "laravel/framework",
- "version": "v5.2.43",
+ "version": "v5.7.29",
"source": {
"type": "git",
"url": "https://github.com/laravel/framework.git",
- "reference": "5490b8f00564bb60839002f86828e27edd1e5610"
+ "reference": "2555bf6ef6e6739e5f49f4a5d40f6264c57abd56"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/framework/zipball/5490b8f00564bb60839002f86828e27edd1e5610",
- "reference": "5490b8f00564bb60839002f86828e27edd1e5610",
+ "url": "https://api.github.com/repos/laravel/framework/zipball/2555bf6ef6e6739e5f49f4a5d40f6264c57abd56",
+ "reference": "2555bf6ef6e6739e5f49f4a5d40f6264c57abd56",
"shasum": ""
},
"require": {
- "classpreloader/classpreloader": "~3.0",
- "doctrine/inflector": "~1.0",
+ "doctrine/inflector": "^1.1",
+ "dragonmantank/cron-expression": "^2.0",
+ "erusev/parsedown": "^1.7",
"ext-mbstring": "*",
"ext-openssl": "*",
- "jeremeamia/superclosure": "~2.2",
- "league/flysystem": "~1.0",
- "monolog/monolog": "~1.11",
- "mtdowling/cron-expression": "~1.0",
- "nesbot/carbon": "~1.20",
- "paragonie/random_compat": "~1.4",
- "php": ">=5.5.9",
- "psy/psysh": "0.7.*",
- "swiftmailer/swiftmailer": "~5.1",
- "symfony/console": "2.8.*|3.0.*",
- "symfony/debug": "2.8.*|3.0.*",
- "symfony/finder": "2.8.*|3.0.*",
- "symfony/http-foundation": "2.8.*|3.0.*",
- "symfony/http-kernel": "2.8.*|3.0.*",
- "symfony/polyfill-php56": "~1.0",
- "symfony/process": "2.8.*|3.0.*",
- "symfony/routing": "2.8.*|3.0.*",
- "symfony/translation": "2.8.*|3.0.*",
- "symfony/var-dumper": "2.8.*|3.0.*",
- "vlucas/phpdotenv": "~2.2"
+ "laravel/nexmo-notification-channel": "^1.0",
+ "laravel/slack-notification-channel": "^1.0",
+ "league/flysystem": "^1.0.8",
+ "monolog/monolog": "^1.12",
+ "nesbot/carbon": "^1.26.3",
+ "opis/closure": "^3.1",
+ "php": "^7.1.3",
+ "psr/container": "^1.0",
+ "psr/simple-cache": "^1.0",
+ "ramsey/uuid": "^3.7",
+ "swiftmailer/swiftmailer": "^6.0",
+ "symfony/console": "^4.1",
+ "symfony/debug": "^4.1",
+ "symfony/finder": "^4.1",
+ "symfony/http-foundation": "^4.1",
+ "symfony/http-kernel": "^4.1",
+ "symfony/process": "^4.1",
+ "symfony/routing": "^4.1",
+ "symfony/var-dumper": "^4.1",
+ "tijsverkoyen/css-to-inline-styles": "^2.2.1",
+ "vlucas/phpdotenv": "^2.2"
+ },
+ "conflict": {
+ "tightenco/collect": "<5.5.33"
},
"replace": {
"illuminate/auth": "self.version",
@@ -2070,12 +2771,12 @@
"illuminate/database": "self.version",
"illuminate/encryption": "self.version",
"illuminate/events": "self.version",
- "illuminate/exception": "self.version",
"illuminate/filesystem": "self.version",
"illuminate/hashing": "self.version",
"illuminate/http": "self.version",
"illuminate/log": "self.version",
"illuminate/mail": "self.version",
+ "illuminate/notifications": "self.version",
"illuminate/pagination": "self.version",
"illuminate/pipeline": "self.version",
"illuminate/queue": "self.version",
@@ -2085,42 +2786,53 @@
"illuminate/support": "self.version",
"illuminate/translation": "self.version",
"illuminate/validation": "self.version",
- "illuminate/view": "self.version",
- "tightenco/collect": "self.version"
+ "illuminate/view": "self.version"
},
"require-dev": {
- "aws/aws-sdk-php": "~3.0",
- "mockery/mockery": "~0.9.4",
- "pda/pheanstalk": "~3.0",
- "phpunit/phpunit": "~4.1",
- "predis/predis": "~1.0",
- "symfony/css-selector": "2.8.*|3.0.*",
- "symfony/dom-crawler": "2.8.*|3.0.*"
+ "aws/aws-sdk-php": "^3.0",
+ "doctrine/dbal": "^2.6",
+ "filp/whoops": "^2.1.4",
+ "guzzlehttp/guzzle": "^6.3",
+ "league/flysystem-cached-adapter": "^1.0",
+ "mockery/mockery": "^1.0",
+ "moontoast/math": "^1.1",
+ "orchestra/testbench-core": "3.7.*",
+ "pda/pheanstalk": "^3.0|^4.0",
+ "phpunit/phpunit": "^7.5",
+ "predis/predis": "^1.1.1",
+ "symfony/css-selector": "^4.1",
+ "symfony/dom-crawler": "^4.1",
+ "true/punycode": "^2.1"
},
"suggest": {
- "aws/aws-sdk-php": "Required to use the SQS queue driver and SES mail driver (~3.0).",
- "doctrine/dbal": "Required to rename columns and drop SQLite columns (~2.4).",
- "fzaninotto/faker": "Required to use the eloquent factory builder (~1.4).",
- "guzzlehttp/guzzle": "Required to use the Mailgun and Mandrill mail drivers and the ping methods on schedules (~5.3|~6.0).",
- "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (~1.0).",
- "league/flysystem-rackspace": "Required to use the Flysystem Rackspace driver (~1.0).",
- "pda/pheanstalk": "Required to use the beanstalk queue driver (~3.0).",
- "predis/predis": "Required to use the redis cache and queue drivers (~1.0).",
- "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (~2.0).",
- "symfony/css-selector": "Required to use some of the crawler integration testing tools (2.8.*|3.0.*).",
- "symfony/dom-crawler": "Required to use most of the crawler integration testing tools (2.8.*|3.0.*).",
- "symfony/psr-http-message-bridge": "Required to psr7 bridging features (0.2.*)."
+ "aws/aws-sdk-php": "Required to use the SQS queue driver and SES mail driver (^3.0).",
+ "doctrine/dbal": "Required to rename columns and drop SQLite columns (^2.6).",
+ "ext-pcntl": "Required to use all features of the queue worker.",
+ "ext-posix": "Required to use all features of the queue worker.",
+ "filp/whoops": "Required for friendly error pages in development (^2.1.4).",
+ "fzaninotto/faker": "Required to use the eloquent factory builder (^1.4).",
+ "guzzlehttp/guzzle": "Required to use the Mailgun and Mandrill mail drivers and the ping methods on schedules (^6.0).",
+ "laravel/tinker": "Required to use the tinker console command (^1.0).",
+ "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^1.0).",
+ "league/flysystem-cached-adapter": "Required to use the Flysystem cache (^1.0).",
+ "league/flysystem-rackspace": "Required to use the Flysystem Rackspace driver (^1.0).",
+ "league/flysystem-sftp": "Required to use the Flysystem SFTP driver (^1.0).",
+ "moontoast/math": "Required to use ordered UUIDs (^1.1).",
+ "nexmo/client": "Required to use the Nexmo transport (^1.0).",
+ "pda/pheanstalk": "Required to use the beanstalk queue driver (^3.0|^4.0).",
+ "predis/predis": "Required to use the redis cache and queue drivers (^1.0).",
+ "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^3.0).",
+ "symfony/css-selector": "Required to use some of the crawler integration testing tools (^4.1).",
+ "symfony/dom-crawler": "Required to use most of the crawler integration testing tools (^4.1).",
+ "symfony/psr-http-message-bridge": "Required to psr7 bridging features (^1.0)."
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "5.2-dev"
+ "dev-master": "5.7-dev"
}
},
"autoload": {
- "classmap": [
- "src/Illuminate/Queue/IlluminateQueueClosure.php"
- ],
"files": [
"src/Illuminate/Foundation/helpers.php",
"src/Illuminate/Support/helpers.php"
@@ -2136,135 +2848,120 @@
"authors": [
{
"name": "Taylor Otwell",
- "email": "taylorotwell@gmail.com"
+ "email": "taylor@laravel.com"
}
],
"description": "The Laravel Framework.",
- "homepage": "http://laravel.com",
+ "homepage": "https://laravel.com",
"keywords": [
"framework",
"laravel"
],
- "time": "2016-08-10 12:23:59"
+ "support": {
+ "issues": "https://github.com/laravel/framework/issues",
+ "source": "https://github.com/laravel/framework"
+ },
+ "time": "2020-04-14T14:16:19+00:00"
},
{
- "name": "league/commonmark",
- "version": "0.13.4",
+ "name": "laravel/nexmo-notification-channel",
+ "version": "v1.0.1",
"source": {
"type": "git",
- "url": "https://github.com/thephpleague/commonmark.git",
- "reference": "83f8210427fb01f671e272bb8d44b4ed3a94d459"
+ "url": "https://github.com/laravel/vonage-notification-channel.git",
+ "reference": "03edd42a55b306ff980c9950899d5a2b03260d48"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/83f8210427fb01f671e272bb8d44b4ed3a94d459",
- "reference": "83f8210427fb01f671e272bb8d44b4ed3a94d459",
+ "url": "https://api.github.com/repos/laravel/vonage-notification-channel/zipball/03edd42a55b306ff980c9950899d5a2b03260d48",
+ "reference": "03edd42a55b306ff980c9950899d5a2b03260d48",
"shasum": ""
},
"require": {
- "ext-mbstring": "*",
- "php": ">=5.4.8"
- },
- "replace": {
- "colinodell/commonmark-php": "*"
+ "nexmo/client": "^1.0",
+ "php": "^7.1.3"
},
"require-dev": {
- "cebe/markdown": "~1.0",
- "erusev/parsedown": "~1.0",
- "jgm/commonmark": "0.25",
- "michelf/php-markdown": "~1.4",
- "mikehaertl/php-shellcommand": "~1.2.0",
- "phpunit/phpunit": "~4.3|~5.0",
- "scrutinizer/ocular": "~1.1",
- "symfony/finder": "~2.3|~3.0"
- },
- "suggest": {
- "league/commonmark-extras": "Library of useful extensions including smart punctuation"
+ "illuminate/notifications": "~5.7",
+ "mockery/mockery": "^1.0",
+ "phpunit/phpunit": "^7.0"
},
- "bin": [
- "bin/commonmark"
- ],
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "0.14-dev"
+ "dev-master": "1.0-dev"
+ },
+ "laravel": {
+ "providers": [
+ "Illuminate\\Notifications\\NexmoChannelServiceProvider"
+ ]
}
},
"autoload": {
"psr-4": {
- "League\\CommonMark\\": "src/"
+ "Illuminate\\Notifications\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-3-Clause"
+ "MIT"
],
"authors": [
{
- "name": "Colin O'Dell",
- "email": "colinodell@gmail.com",
- "homepage": "https://www.colinodell.com",
- "role": "Lead Developer"
+ "name": "Taylor Otwell",
+ "email": "taylor@laravel.com"
}
],
- "description": "Markdown parser for PHP based on the CommonMark spec",
- "homepage": "https://github.com/thephpleague/commonmark",
+ "description": "Nexmo Notification Channel for laravel.",
"keywords": [
- "commonmark",
- "markdown",
- "parser"
+ "laravel",
+ "nexmo",
+ "notifications"
],
- "time": "2016-06-14 14:49:29"
+ "support": {
+ "issues": "https://github.com/laravel/vonage-notification-channel/issues",
+ "source": "https://github.com/laravel/vonage-notification-channel/tree/v1.0.1"
+ },
+ "abandoned": "laravel/vonage-notification-channel",
+ "time": "2018-12-04T12:57:08+00:00"
},
{
- "name": "league/flysystem",
- "version": "1.0.27",
+ "name": "laravel/slack-notification-channel",
+ "version": "v1.0.3",
"source": {
"type": "git",
- "url": "https://github.com/thephpleague/flysystem.git",
- "reference": "50e2045ed70a7e75a5e30bc3662904f3b67af8a9"
+ "url": "https://github.com/laravel/slack-notification-channel.git",
+ "reference": "6e164293b754a95f246faf50ab2bbea3e4923cc9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/50e2045ed70a7e75a5e30bc3662904f3b67af8a9",
- "reference": "50e2045ed70a7e75a5e30bc3662904f3b67af8a9",
+ "url": "https://api.github.com/repos/laravel/slack-notification-channel/zipball/6e164293b754a95f246faf50ab2bbea3e4923cc9",
+ "reference": "6e164293b754a95f246faf50ab2bbea3e4923cc9",
"shasum": ""
},
"require": {
- "php": ">=5.4.0"
- },
- "conflict": {
- "league/flysystem-sftp": "<1.0.6"
+ "guzzlehttp/guzzle": "^6.0",
+ "php": "^7.1.3"
},
"require-dev": {
- "ext-fileinfo": "*",
- "mockery/mockery": "~0.9",
- "phpspec/phpspec": "^2.2",
- "phpunit/phpunit": "~4.8"
- },
- "suggest": {
- "ext-fileinfo": "Required for MimeType",
- "league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2",
- "league/flysystem-aws-s3-v3": "Allows you to use S3 storage with AWS SDK v3",
- "league/flysystem-azure": "Allows you to use Windows Azure Blob storage",
- "league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching",
- "league/flysystem-copy": "Allows you to use Copy.com storage",
- "league/flysystem-dropbox": "Allows you to use Dropbox storage",
- "league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem",
- "league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files",
- "league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib",
- "league/flysystem-webdav": "Allows you to use WebDAV storage",
- "league/flysystem-ziparchive": "Allows you to use ZipArchive adapter"
+ "illuminate/notifications": "~5.7",
+ "mockery/mockery": "^1.0",
+ "phpunit/phpunit": "^7.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.1-dev"
+ "dev-master": "1.0-dev"
+ },
+ "laravel": {
+ "providers": [
+ "Illuminate\\Notifications\\SlackChannelServiceProvider"
+ ]
}
},
"autoload": {
"psr-4": {
- "League\\Flysystem\\": "src/"
+ "Illuminate\\Notifications\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -2273,19 +2970,330 @@
],
"authors": [
{
- "name": "Frank de Jonge",
- "email": "info@frenky.net"
+ "name": "Taylor Otwell",
+ "email": "taylor@laravel.com"
}
],
- "description": "Filesystem abstraction: Many filesystems, one API.",
+ "description": "Slack Notification Channel for laravel.",
"keywords": [
- "Cloud Files",
- "WebDAV",
- "abstraction",
- "aws",
- "cloud",
- "copy.com",
- "dropbox",
+ "laravel",
+ "notifications",
+ "slack"
+ ],
+ "support": {
+ "issues": "https://github.com/laravel/slack-notification-channel/issues",
+ "source": "https://github.com/laravel/slack-notification-channel/tree/1.0"
+ },
+ "time": "2018-12-12T13:12:06+00:00"
+ },
+ {
+ "name": "laravel/tinker",
+ "version": "v1.0.10",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/laravel/tinker.git",
+ "reference": "ad571aacbac1539c30d480908f9d0c9614eaf1a7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/laravel/tinker/zipball/ad571aacbac1539c30d480908f9d0c9614eaf1a7",
+ "reference": "ad571aacbac1539c30d480908f9d0c9614eaf1a7",
+ "shasum": ""
+ },
+ "require": {
+ "illuminate/console": "~5.1|^6.0",
+ "illuminate/contracts": "~5.1|^6.0",
+ "illuminate/support": "~5.1|^6.0",
+ "php": ">=5.5.9",
+ "psy/psysh": "0.7.*|0.8.*|0.9.*",
+ "symfony/var-dumper": "~3.0|~4.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.0|~5.0"
+ },
+ "suggest": {
+ "illuminate/database": "The Illuminate Database package (~5.1)."
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ },
+ "laravel": {
+ "providers": [
+ "Laravel\\Tinker\\TinkerServiceProvider"
+ ]
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Laravel\\Tinker\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Taylor Otwell",
+ "email": "taylor@laravel.com"
+ }
+ ],
+ "description": "Powerful REPL for the Laravel framework.",
+ "keywords": [
+ "REPL",
+ "Tinker",
+ "laravel",
+ "psysh"
+ ],
+ "support": {
+ "issues": "https://github.com/laravel/tinker/issues",
+ "source": "https://github.com/laravel/tinker/tree/v1.0.10"
+ },
+ "time": "2019-08-07T15:10:45+00:00"
+ },
+ {
+ "name": "lcobucci/jwt",
+ "version": "3.4.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/lcobucci/jwt.git",
+ "reference": "3ef8657a78278dfeae7707d51747251db4176240"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/lcobucci/jwt/zipball/3ef8657a78278dfeae7707d51747251db4176240",
+ "reference": "3ef8657a78278dfeae7707d51747251db4176240",
+ "shasum": ""
+ },
+ "require": {
+ "ext-mbstring": "*",
+ "ext-openssl": "*",
+ "php": "^5.6 || ^7.0"
+ },
+ "require-dev": {
+ "mikey179/vfsstream": "~1.5",
+ "phpmd/phpmd": "~2.2",
+ "phpunit/php-invoker": "~1.1",
+ "phpunit/phpunit": "^5.7 || ^7.3",
+ "squizlabs/php_codesniffer": "~2.3"
+ },
+ "suggest": {
+ "lcobucci/clock": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.1-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "compat/class-aliases.php",
+ "compat/json-exception-polyfill.php",
+ "compat/lcobucci-clock-polyfill.php"
+ ],
+ "psr-4": {
+ "Lcobucci\\JWT\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Luís Otávio Cobucci Oblonczyk",
+ "email": "lcobucci@gmail.com",
+ "role": "Developer"
+ }
+ ],
+ "description": "A simple library to work with JSON Web Token and JSON Web Signature",
+ "keywords": [
+ "JWS",
+ "jwt"
+ ],
+ "support": {
+ "issues": "https://github.com/lcobucci/jwt/issues",
+ "source": "https://github.com/lcobucci/jwt/tree/3.4.6"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/lcobucci",
+ "type": "github"
+ },
+ {
+ "url": "https://www.patreon.com/lcobucci",
+ "type": "patreon"
+ }
+ ],
+ "time": "2021-09-28T19:18:28+00:00"
+ },
+ {
+ "name": "league/commonmark",
+ "version": "1.6.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/thephpleague/commonmark.git",
+ "reference": "2b8185c13bc9578367a5bf901881d1c1b5bbd09b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/2b8185c13bc9578367a5bf901881d1c1b5bbd09b",
+ "reference": "2b8185c13bc9578367a5bf901881d1c1b5bbd09b",
+ "shasum": ""
+ },
+ "require": {
+ "ext-mbstring": "*",
+ "php": "^7.1 || ^8.0"
+ },
+ "conflict": {
+ "scrutinizer/ocular": "1.7.*"
+ },
+ "require-dev": {
+ "cebe/markdown": "~1.0",
+ "commonmark/commonmark.js": "0.29.2",
+ "erusev/parsedown": "~1.0",
+ "ext-json": "*",
+ "github/gfm": "0.29.0",
+ "michelf/php-markdown": "~1.4",
+ "mikehaertl/php-shellcommand": "^1.4",
+ "phpstan/phpstan": "^0.12.90",
+ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.2",
+ "scrutinizer/ocular": "^1.5",
+ "symfony/finder": "^4.2"
+ },
+ "bin": [
+ "bin/commonmark"
+ ],
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "League\\CommonMark\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Colin O'Dell",
+ "email": "colinodell@gmail.com",
+ "homepage": "https://www.colinodell.com",
+ "role": "Lead Developer"
+ }
+ ],
+ "description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and Github-Flavored Markdown (GFM)",
+ "homepage": "https://commonmark.thephpleague.com",
+ "keywords": [
+ "commonmark",
+ "flavored",
+ "gfm",
+ "github",
+ "github-flavored",
+ "markdown",
+ "md",
+ "parser"
+ ],
+ "support": {
+ "docs": "https://commonmark.thephpleague.com/",
+ "issues": "https://github.com/thephpleague/commonmark/issues",
+ "rss": "https://github.com/thephpleague/commonmark/releases.atom",
+ "source": "https://github.com/thephpleague/commonmark"
+ },
+ "funding": [
+ {
+ "url": "https://www.colinodell.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.paypal.me/colinpodell/10.00",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/colinodell",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/league/commonmark",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-01-13T17:18:13+00:00"
+ },
+ {
+ "name": "league/flysystem",
+ "version": "1.0.70",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/thephpleague/flysystem.git",
+ "reference": "585824702f534f8d3cf7fab7225e8466cc4b7493"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/585824702f534f8d3cf7fab7225e8466cc4b7493",
+ "reference": "585824702f534f8d3cf7fab7225e8466cc4b7493",
+ "shasum": ""
+ },
+ "require": {
+ "ext-fileinfo": "*",
+ "php": ">=5.5.9"
+ },
+ "conflict": {
+ "league/flysystem-sftp": "<1.0.6"
+ },
+ "require-dev": {
+ "phpspec/phpspec": "^3.4 || ^4.0 || ^5.0 || ^6.0",
+ "phpunit/phpunit": "^5.7.26"
+ },
+ "suggest": {
+ "ext-fileinfo": "Required for MimeType",
+ "ext-ftp": "Allows you to use FTP server storage",
+ "ext-openssl": "Allows you to use FTPS server storage",
+ "league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2",
+ "league/flysystem-aws-s3-v3": "Allows you to use S3 storage with AWS SDK v3",
+ "league/flysystem-azure": "Allows you to use Windows Azure Blob storage",
+ "league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching",
+ "league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem",
+ "league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files",
+ "league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib",
+ "league/flysystem-webdav": "Allows you to use WebDAV storage",
+ "league/flysystem-ziparchive": "Allows you to use ZipArchive adapter",
+ "spatie/flysystem-dropbox": "Allows you to use Dropbox storage",
+ "srmklive/flysystem-dropbox-v2": "Allows you to use Dropbox storage for PHP 5 applications"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.1-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "League\\Flysystem\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Frank de Jonge",
+ "email": "info@frenky.net"
+ }
+ ],
+ "description": "Filesystem abstraction: Many filesystems, one API.",
+ "keywords": [
+ "Cloud Files",
+ "WebDAV",
+ "abstraction",
+ "aws",
+ "cloud",
+ "copy.com",
+ "dropbox",
"file systems",
"files",
"filesystem",
@@ -2297,40 +3305,56 @@
"sftp",
"storage"
],
- "time": "2016-08-10 08:55:11"
+ "support": {
+ "issues": "https://github.com/thephpleague/flysystem/issues",
+ "source": "https://github.com/thephpleague/flysystem/tree/1.0.70"
+ },
+ "funding": [
+ {
+ "url": "https://offset.earth/frankdejonge",
+ "type": "other"
+ }
+ ],
+ "time": "2020-07-26T07:20:36+00:00"
},
{
"name": "mccool/laravel-auto-presenter",
- "version": "4.3.0",
+ "version": "7.7.0",
"source": {
"type": "git",
"url": "https://github.com/laravel-auto-presenter/laravel-auto-presenter.git",
- "reference": "08ce32a41aa5d6c842b4cc19ae442e211cb3dd96"
+ "reference": "e139110a82c8a1573d4015b4f6d600d79e1d33e5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel-auto-presenter/laravel-auto-presenter/zipball/08ce32a41aa5d6c842b4cc19ae442e211cb3dd96",
- "reference": "08ce32a41aa5d6c842b4cc19ae442e211cb3dd96",
+ "url": "https://api.github.com/repos/laravel-auto-presenter/laravel-auto-presenter/zipball/e139110a82c8a1573d4015b4f6d600d79e1d33e5",
+ "reference": "e139110a82c8a1573d4015b4f6d600d79e1d33e5",
"shasum": ""
},
"require": {
- "illuminate/container": "5.1.*|5.2.*|5.3.*",
- "illuminate/contracts": "5.1.*|5.2.*|5.3.*",
- "illuminate/events": "5.1.*|5.2.*|5.3.*",
- "illuminate/pagination": "5.1.*|5.2.*|5.3.*",
- "illuminate/support": "5.1.*|5.2.*|5.3.*",
- "illuminate/view": "5.1.*|5.2.*|5.3.*",
- "php": ">=5.5.9"
+ "illuminate/container": "^5.5 || ^6.0 || ^7.0 || ^8.0 || ^9.0",
+ "illuminate/contracts": "^5.5 || ^6.0 || ^7.0 || ^8.0|| ^9.0",
+ "illuminate/events": "^5.5 || ^6.0 || ^7.0 || ^8.0|| ^9.0",
+ "illuminate/pagination": "^5.5 || ^6.0 || ^7.0 || ^8.0|| ^9.0",
+ "illuminate/support": "^5.5 || ^6.0 || ^7.0 || ^8.0|| ^9.0",
+ "illuminate/view": "^5.5 || ^6.0 || ^7.0 || ^8.0|| ^9.0",
+ "php": "^7.1.3 || ^8.0"
},
"require-dev": {
- "graham-campbell/testbench": "^3.1",
- "mockery/mockery": "^0.9.4",
- "phpunit/phpunit": "^4.8|^5.0"
+ "graham-campbell/analyzer": "^2.4 || ^3.0",
+ "graham-campbell/testbench": "^5.4",
+ "mockery/mockery": "^1.3.1",
+ "phpunit/phpunit": "^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.7"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "4.3-dev"
+ "dev-master": "7.7-dev"
+ },
+ "laravel": {
+ "providers": [
+ "McCool\\LaravelAutoPresenter\\AutoPresenterServiceProvider"
+ ]
}
},
"autoload": {
@@ -2345,11 +3369,13 @@
"authors": [
{
"name": "Shawn McCool",
- "email": "shawn@heybigname.com"
+ "email": "shawn@mccool.email",
+ "homepage": "https://github.com/ShawnMcCool"
},
{
"name": "Graham Campbell",
- "email": "graham@alt-three.com"
+ "email": "hello@gjcampbell.co.uk",
+ "homepage": "https://github.com/GrahamCampbell"
}
],
"description": "A system for auto-decorating models with presenter objects.",
@@ -2359,20 +3385,34 @@
"lpm",
"presenter"
],
- "time": "2016-05-01 15:29:13"
+ "support": {
+ "issues": "https://github.com/laravel-auto-presenter/laravel-auto-presenter/issues",
+ "source": "https://github.com/laravel-auto-presenter/laravel-auto-presenter/tree/7.7.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/GrahamCampbell",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/mccool/laravel-auto-presenter",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-02-09T09:14:24+00:00"
},
{
"name": "monolog/monolog",
- "version": "1.21.0",
+ "version": "1.27.1",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/monolog.git",
- "reference": "f42fbdfd53e306bda545845e4dbfd3e72edb4952"
+ "reference": "904713c5929655dc9b97288b69cfeedad610c9a1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Seldaek/monolog/zipball/f42fbdfd53e306bda545845e4dbfd3e72edb4952",
- "reference": "f42fbdfd53e306bda545845e4dbfd3e72edb4952",
+ "url": "https://api.github.com/repos/Seldaek/monolog/zipball/904713c5929655dc9b97288b69cfeedad610c9a1",
+ "reference": "904713c5929655dc9b97288b69cfeedad610c9a1",
"shasum": ""
},
"require": {
@@ -2383,17 +3423,16 @@
"psr/log-implementation": "1.0.0"
},
"require-dev": {
- "aws/aws-sdk-php": "^2.4.9",
+ "aws/aws-sdk-php": "^2.4.9 || ^3.0",
"doctrine/couchdb": "~1.0@dev",
"graylog2/gelf-php": "~1.0",
- "jakub-onderka/php-parallel-lint": "0.9",
"php-amqplib/php-amqplib": "~2.4",
"php-console/php-console": "^3.1.3",
+ "phpstan/phpstan": "^0.12.59",
"phpunit/phpunit": "~4.5",
- "phpunit/phpunit-mock-objects": "2.3.0",
"ruflin/elastica": ">=0.90 <3.0",
"sentry/sentry": "^0.13",
- "swiftmailer/swiftmailer": "~5.3"
+ "swiftmailer/swiftmailer": "^5.3|^6.0"
},
"suggest": {
"aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
@@ -2409,11 +3448,6 @@
"sentry/sentry": "Allow sending log messages to a Sentry server"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.0.x-dev"
- }
- },
"autoload": {
"psr-4": {
"Monolog\\": "src/Monolog"
@@ -2437,32 +3471,59 @@
"logging",
"psr-3"
],
- "time": "2016-07-29 03:23:52"
+ "support": {
+ "issues": "https://github.com/Seldaek/monolog/issues",
+ "source": "https://github.com/Seldaek/monolog/tree/1.27.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/Seldaek",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/monolog/monolog",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-06-09T08:53:42+00:00"
},
{
- "name": "mtdowling/cron-expression",
- "version": "v1.1.0",
+ "name": "mtdowling/jmespath.php",
+ "version": "2.6.1",
"source": {
"type": "git",
- "url": "https://github.com/mtdowling/cron-expression.git",
- "reference": "c9ee7886f5a12902b225a1a12f36bb45f9ab89e5"
+ "url": "https://github.com/jmespath/jmespath.php.git",
+ "reference": "9b87907a81b87bc76d19a7fb2d61e61486ee9edb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/mtdowling/cron-expression/zipball/c9ee7886f5a12902b225a1a12f36bb45f9ab89e5",
- "reference": "c9ee7886f5a12902b225a1a12f36bb45f9ab89e5",
+ "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/9b87907a81b87bc76d19a7fb2d61e61486ee9edb",
+ "reference": "9b87907a81b87bc76d19a7fb2d61e61486ee9edb",
"shasum": ""
},
"require": {
- "php": ">=5.3.2"
+ "php": "^5.4 || ^7.0 || ^8.0",
+ "symfony/polyfill-mbstring": "^1.17"
},
"require-dev": {
- "phpunit/phpunit": "~4.0|~5.0"
+ "composer/xdebug-handler": "^1.4 || ^2.0",
+ "phpunit/phpunit": "^4.8.36 || ^7.5.15"
},
+ "bin": [
+ "bin/jp.php"
+ ],
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.6-dev"
+ }
+ },
"autoload": {
- "psr-0": {
- "Cron": "src/"
+ "files": [
+ "src/JmesPath.php"
+ ],
+ "psr-4": {
+ "JmesPath\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -2471,54 +3532,1650 @@
],
"authors": [
{
- "name": "Michael Dowling",
- "email": "mtdowling@gmail.com",
- "homepage": "https://github.com/mtdowling"
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ }
+ ],
+ "description": "Declaratively specify how to extract elements from a JSON document",
+ "keywords": [
+ "json",
+ "jsonpath"
+ ],
+ "support": {
+ "issues": "https://github.com/jmespath/jmespath.php/issues",
+ "source": "https://github.com/jmespath/jmespath.php/tree/2.6.1"
+ },
+ "time": "2021-06-14T00:11:39+00:00"
+ },
+ {
+ "name": "nesbot/carbon",
+ "version": "1.39.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/briannesbitt/Carbon.git",
+ "reference": "4be0c005164249208ce1b5ca633cd57bdd42ff33"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/4be0c005164249208ce1b5ca633cd57bdd42ff33",
+ "reference": "4be0c005164249208ce1b5ca633cd57bdd42ff33",
+ "shasum": ""
+ },
+ "require": {
+ "kylekatarnls/update-helper": "^1.1",
+ "php": ">=5.3.9",
+ "symfony/translation": "~2.6 || ~3.0 || ~4.0"
+ },
+ "require-dev": {
+ "composer/composer": "^1.2",
+ "friendsofphp/php-cs-fixer": "~2",
+ "phpunit/phpunit": "^4.8.35 || ^5.7"
+ },
+ "bin": [
+ "bin/upgrade-carbon"
+ ],
+ "type": "library",
+ "extra": {
+ "update-helper": "Carbon\\Upgrade",
+ "laravel": {
+ "providers": [
+ "Carbon\\Laravel\\ServiceProvider"
+ ]
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Brian Nesbitt",
+ "email": "brian@nesbot.com",
+ "homepage": "http://nesbot.com"
+ }
+ ],
+ "description": "A simple API extension for DateTime.",
+ "homepage": "http://carbon.nesbot.com",
+ "keywords": [
+ "date",
+ "datetime",
+ "time"
+ ],
+ "support": {
+ "issues": "https://github.com/briannesbitt/Carbon/issues",
+ "source": "https://github.com/briannesbitt/Carbon"
+ },
+ "time": "2019-10-14T05:51:36+00:00"
+ },
+ {
+ "name": "nexmo/client",
+ "version": "1.9.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Nexmo/nexmo-php-complete.git",
+ "reference": "c6d11d953c8c5594590bb9ebaba9616e76948f93"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Nexmo/nexmo-php-complete/zipball/c6d11d953c8c5594590bb9ebaba9616e76948f93",
+ "reference": "c6d11d953c8c5594590bb9ebaba9616e76948f93",
+ "shasum": ""
+ },
+ "require": {
+ "nexmo/client-core": "^1.0",
+ "php": ">=5.6",
+ "php-http/guzzle6-adapter": "^1.0"
+ },
+ "type": "library",
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Tim Lytle",
+ "email": "tim@nexmo.com",
+ "homepage": "http://twitter.com/tjlytle",
+ "role": "Developer"
+ },
+ {
+ "name": "Michael Heap",
+ "email": "michael.heap@vonage.com",
+ "role": "Developer"
+ },
+ {
+ "name": "Lorna Mitchell",
+ "email": "lorna.mitchell@vonage.com",
+ "role": "Developer"
+ }
+ ],
+ "description": "PHP Client for using Nexmo's API.",
+ "support": {
+ "email": "devrel@nexmo.com",
+ "source": "https://github.com/Nexmo/nexmo-php-complete/tree/1.9.1"
+ },
+ "time": "2019-11-26T15:25:11+00:00"
+ },
+ {
+ "name": "nexmo/client-core",
+ "version": "1.8.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Nexmo/nexmo-php.git",
+ "reference": "182d41a02ebd3e4be147baea45458ccfe2f528c4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Nexmo/nexmo-php/zipball/182d41a02ebd3e4be147baea45458ccfe2f528c4",
+ "reference": "182d41a02ebd3e4be147baea45458ccfe2f528c4",
+ "shasum": ""
+ },
+ "require": {
+ "lcobucci/jwt": "^3.2",
+ "php": ">=5.6",
+ "php-http/client-implementation": "^1.0",
+ "php-http/guzzle6-adapter": "^1.0",
+ "zendframework/zend-diactoros": "^1.8.4 || ^2.0"
+ },
+ "require-dev": {
+ "estahn/phpunit-json-assertions": "^1.0.0",
+ "php-http/mock-client": "^0.3.0",
+ "phpunit/phpunit": "^5.7",
+ "squizlabs/php_codesniffer": "^3.1"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Nexmo\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Tim Lytle",
+ "email": "tim@nexmo.com",
+ "homepage": "http://twitter.com/tjlytle",
+ "role": "Developer"
+ }
+ ],
+ "description": "PHP Client for using Nexmo's API.",
+ "support": {
+ "email": "devrel@nexmo.com",
+ "source": "https://github.com/Nexmo/nexmo-php/tree/1.8.1"
+ },
+ "time": "2019-05-13T20:27:43+00:00"
+ },
+ {
+ "name": "nikic/php-parser",
+ "version": "v4.17.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/nikic/PHP-Parser.git",
+ "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d",
+ "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d",
+ "shasum": ""
+ },
+ "require": {
+ "ext-tokenizer": "*",
+ "php": ">=7.0"
+ },
+ "require-dev": {
+ "ircmaxell/php-yacc": "^0.0.7",
+ "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0"
+ },
+ "bin": [
+ "bin/php-parse"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.9-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "PhpParser\\": "lib/PhpParser"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Nikita Popov"
+ }
+ ],
+ "description": "A PHP parser written in PHP",
+ "keywords": [
+ "parser",
+ "php"
+ ],
+ "support": {
+ "issues": "https://github.com/nikic/PHP-Parser/issues",
+ "source": "https://github.com/nikic/PHP-Parser/tree/v4.17.1"
+ },
+ "time": "2023-08-13T19:53:39+00:00"
+ },
+ {
+ "name": "opis/closure",
+ "version": "3.6.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/opis/closure.git",
+ "reference": "3d81e4309d2a927abbe66df935f4bb60082805ad"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/opis/closure/zipball/3d81e4309d2a927abbe66df935f4bb60082805ad",
+ "reference": "3d81e4309d2a927abbe66df935f4bb60082805ad",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.4 || ^7.0 || ^8.0"
+ },
+ "require-dev": {
+ "jeremeamia/superclosure": "^2.0",
+ "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.6.x-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "functions.php"
+ ],
+ "psr-4": {
+ "Opis\\Closure\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Marius Sarca",
+ "email": "marius.sarca@gmail.com"
+ },
+ {
+ "name": "Sorin Sarca",
+ "email": "sarca_sorin@hotmail.com"
+ }
+ ],
+ "description": "A library that can be used to serialize closures (anonymous functions) and arbitrary objects.",
+ "homepage": "https://opis.io/closure",
+ "keywords": [
+ "anonymous functions",
+ "closure",
+ "function",
+ "serializable",
+ "serialization",
+ "serialize"
+ ],
+ "support": {
+ "issues": "https://github.com/opis/closure/issues",
+ "source": "https://github.com/opis/closure/tree/3.6.3"
+ },
+ "time": "2022-01-27T09:35:39+00:00"
+ },
+ {
+ "name": "paragonie/constant_time_encoding",
+ "version": "v2.6.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/paragonie/constant_time_encoding.git",
+ "reference": "58c3f47f650c94ec05a151692652a868995d2938"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/58c3f47f650c94ec05a151692652a868995d2938",
+ "reference": "58c3f47f650c94ec05a151692652a868995d2938",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7|^8"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6|^7|^8|^9",
+ "vimeo/psalm": "^1|^2|^3|^4"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "ParagonIE\\ConstantTime\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Paragon Initiative Enterprises",
+ "email": "security@paragonie.com",
+ "homepage": "https://paragonie.com",
+ "role": "Maintainer"
+ },
+ {
+ "name": "Steve 'Sc00bz' Thomas",
+ "email": "steve@tobtu.com",
+ "homepage": "https://www.tobtu.com",
+ "role": "Original Developer"
+ }
+ ],
+ "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)",
+ "keywords": [
+ "base16",
+ "base32",
+ "base32_decode",
+ "base32_encode",
+ "base64",
+ "base64_decode",
+ "base64_encode",
+ "bin2hex",
+ "encoding",
+ "hex",
+ "hex2bin",
+ "rfc4648"
+ ],
+ "support": {
+ "email": "info@paragonie.com",
+ "issues": "https://github.com/paragonie/constant_time_encoding/issues",
+ "source": "https://github.com/paragonie/constant_time_encoding"
+ },
+ "time": "2022-06-14T06:56:20+00:00"
+ },
+ {
+ "name": "php-http/guzzle6-adapter",
+ "version": "v1.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-http/guzzle6-adapter.git",
+ "reference": "a56941f9dc6110409cfcddc91546ee97039277ab"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-http/guzzle6-adapter/zipball/a56941f9dc6110409cfcddc91546ee97039277ab",
+ "reference": "a56941f9dc6110409cfcddc91546ee97039277ab",
+ "shasum": ""
+ },
+ "require": {
+ "guzzlehttp/guzzle": "^6.0",
+ "php": ">=5.5.0",
+ "php-http/httplug": "^1.0"
+ },
+ "provide": {
+ "php-http/async-client-implementation": "1.0",
+ "php-http/client-implementation": "1.0"
+ },
+ "require-dev": {
+ "ext-curl": "*",
+ "php-http/adapter-integration-tests": "^0.4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.2-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Http\\Adapter\\Guzzle6\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Márk Sági-Kazár",
+ "email": "mark.sagikazar@gmail.com"
+ },
+ {
+ "name": "David de Boer",
+ "email": "david@ddeboer.nl"
+ }
+ ],
+ "description": "Guzzle 6 HTTP Adapter",
+ "homepage": "http://httplug.io",
+ "keywords": [
+ "Guzzle",
+ "http"
+ ],
+ "support": {
+ "issues": "https://github.com/php-http/guzzle6-adapter/issues",
+ "source": "https://github.com/php-http/guzzle6-adapter/tree/master"
+ },
+ "time": "2016-05-10T06:13:32+00:00"
+ },
+ {
+ "name": "php-http/httplug",
+ "version": "v1.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-http/httplug.git",
+ "reference": "1c6381726c18579c4ca2ef1ec1498fdae8bdf018"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-http/httplug/zipball/1c6381726c18579c4ca2ef1ec1498fdae8bdf018",
+ "reference": "1c6381726c18579c4ca2ef1ec1498fdae8bdf018",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.4",
+ "php-http/promise": "^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": "1.1-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"
+ ],
+ "support": {
+ "issues": "https://github.com/php-http/httplug/issues",
+ "source": "https://github.com/php-http/httplug/tree/master"
+ },
+ "time": "2016-08-31T08:30:17+00:00"
+ },
+ {
+ "name": "php-http/promise",
+ "version": "1.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-http/promise.git",
+ "reference": "ef4905bfb492ff389eb7f12e26925a0f20073050"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-http/promise/zipball/ef4905bfb492ff389eb7f12e26925a0f20073050",
+ "reference": "ef4905bfb492ff389eb7f12e26925a0f20073050",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1 || ^8.0"
+ },
+ "require-dev": {
+ "friends-of-phpspec/phpspec-code-coverage": "^4.3.2 || ^6.3",
+ "phpspec/phpspec": "^5.1.2 || ^6.2 || ^7.4"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Http\\Promise\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Joel Wurtz",
+ "email": "joel.wurtz@gmail.com"
+ },
+ {
+ "name": "Márk Sági-Kazár",
+ "email": "mark.sagikazar@gmail.com"
+ }
+ ],
+ "description": "Promise used for asynchronous HTTP requests",
+ "homepage": "http://httplug.io",
+ "keywords": [
+ "promise"
+ ],
+ "support": {
+ "issues": "https://github.com/php-http/promise/issues",
+ "source": "https://github.com/php-http/promise/tree/1.2.0"
+ },
+ "time": "2023-10-24T09:20:26+00:00"
+ },
+ {
+ "name": "pragmarx/google2fa",
+ "version": "v5.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/antonioribeiro/google2fa.git",
+ "reference": "17c969c82f427dd916afe4be50bafc6299aef1b4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/antonioribeiro/google2fa/zipball/17c969c82f427dd916afe4be50bafc6299aef1b4",
+ "reference": "17c969c82f427dd916afe4be50bafc6299aef1b4",
+ "shasum": ""
+ },
+ "require": {
+ "paragonie/constant_time_encoding": "~1.0|~2.0",
+ "paragonie/random_compat": ">=1",
+ "php": ">=5.4",
+ "symfony/polyfill-php56": "~1.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4|~5|~6"
+ },
+ "type": "library",
+ "extra": {
+ "component": "package",
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "PragmaRX\\Google2FA\\": "src/",
+ "PragmaRX\\Google2FA\\Tests\\": "tests/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Antonio Carlos Ribeiro",
+ "email": "acr@antoniocarlosribeiro.com",
+ "role": "Creator & Designer"
+ }
+ ],
+ "description": "A One Time Password Authentication package, compatible with Google Authenticator.",
+ "keywords": [
+ "2fa",
+ "Authentication",
+ "Two Factor Authentication",
+ "google2fa"
+ ],
+ "support": {
+ "issues": "https://github.com/antonioribeiro/google2fa/issues",
+ "source": "https://github.com/antonioribeiro/google2fa/tree/master"
+ },
+ "time": "2019-03-19T22:44:16+00:00"
+ },
+ {
+ "name": "predis/predis",
+ "version": "v1.1.10",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/predis/predis.git",
+ "reference": "a2fb02d738bedadcffdbb07efa3a5e7bd57f8d6e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/predis/predis/zipball/a2fb02d738bedadcffdbb07efa3a5e7bd57f8d6e",
+ "reference": "a2fb02d738bedadcffdbb07efa3a5e7bd57f8d6e",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.9"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.8"
+ },
+ "suggest": {
+ "ext-curl": "Allows access to Webdis when paired with phpiredis",
+ "ext-phpiredis": "Allows faster serialization and deserialization of the Redis protocol"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Predis\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Daniele Alessandri",
+ "email": "suppakilla@gmail.com",
+ "homepage": "http://clorophilla.net",
+ "role": "Creator & Maintainer"
+ },
+ {
+ "name": "Till Krüss",
+ "homepage": "https://till.im",
+ "role": "Maintainer"
+ }
+ ],
+ "description": "Flexible and feature-complete Redis client for PHP and HHVM",
+ "homepage": "http://github.com/predis/predis",
+ "keywords": [
+ "nosql",
+ "predis",
+ "redis"
+ ],
+ "support": {
+ "issues": "https://github.com/predis/predis/issues",
+ "source": "https://github.com/predis/predis/tree/v1.1.10"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sponsors/tillkruss",
+ "type": "github"
+ }
+ ],
+ "time": "2022-01-05T17:46:08+00:00"
+ },
+ {
+ "name": "psr/container",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/container.git",
+ "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
+ "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Container\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common Container Interface (PHP FIG PSR-11)",
+ "homepage": "https://github.com/php-fig/container",
+ "keywords": [
+ "PSR-11",
+ "container",
+ "container-interface",
+ "container-interop",
+ "psr"
+ ],
+ "support": {
+ "issues": "https://github.com/php-fig/container/issues",
+ "source": "https://github.com/php-fig/container/tree/master"
+ },
+ "time": "2017-02-14T16:28:37+00:00"
+ },
+ {
+ "name": "psr/http-factory",
+ "version": "1.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/http-factory.git",
+ "reference": "e616d01114759c4c489f93b099585439f795fe35"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35",
+ "reference": "e616d01114759c4c489f93b099585439f795fe35",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.0.0",
+ "psr/http-message": "^1.0 || ^2.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Message\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interfaces for PSR-7 HTTP message factories",
+ "keywords": [
+ "factory",
+ "http",
+ "message",
+ "psr",
+ "psr-17",
+ "psr-7",
+ "request",
+ "response"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/http-factory/tree/1.0.2"
+ },
+ "time": "2023-04-10T20:10:41+00:00"
+ },
+ {
+ "name": "psr/http-message",
+ "version": "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"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/http-message/tree/master"
+ },
+ "time": "2016-08-06T14:39:51+00:00"
+ },
+ {
+ "name": "psr/log",
+ "version": "1.1.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/log.git",
+ "reference": "d49695b909c3b7628b6289db5479a1c204601f11"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11",
+ "reference": "d49695b909c3b7628b6289db5479a1c204601f11",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Log\\": "Psr/Log/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for logging libraries",
+ "homepage": "https://github.com/php-fig/log",
+ "keywords": [
+ "log",
+ "psr",
+ "psr-3"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/log/tree/1.1.4"
+ },
+ "time": "2021-05-03T11:20:27+00:00"
+ },
+ {
+ "name": "psr/simple-cache",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/simple-cache.git",
+ "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
+ "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\SimpleCache\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interfaces for simple caching",
+ "keywords": [
+ "cache",
+ "caching",
+ "psr",
+ "psr-16",
+ "simple-cache"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/simple-cache/tree/master"
+ },
+ "time": "2017-10-23T01:57:42+00:00"
+ },
+ {
+ "name": "psy/psysh",
+ "version": "v0.9.12",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/bobthecow/psysh.git",
+ "reference": "90da7f37568aee36b116a030c5f99c915267edd4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/bobthecow/psysh/zipball/90da7f37568aee36b116a030c5f99c915267edd4",
+ "reference": "90da7f37568aee36b116a030c5f99c915267edd4",
+ "shasum": ""
+ },
+ "require": {
+ "dnoegel/php-xdg-base-dir": "0.1.*",
+ "ext-json": "*",
+ "ext-tokenizer": "*",
+ "jakub-onderka/php-console-highlighter": "0.3.*|0.4.*",
+ "nikic/php-parser": "~1.3|~2.0|~3.0|~4.0",
+ "php": ">=5.4.0",
+ "symfony/console": "~2.3.10|^2.4.2|~3.0|~4.0|~5.0",
+ "symfony/var-dumper": "~2.7|~3.0|~4.0|~5.0"
+ },
+ "require-dev": {
+ "bamarni/composer-bin-plugin": "^1.2",
+ "hoa/console": "~2.15|~3.16",
+ "phpunit/phpunit": "~4.8.35|~5.0|~6.0|~7.0"
+ },
+ "suggest": {
+ "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)",
+ "ext-pdo-sqlite": "The doc command requires SQLite to work.",
+ "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well.",
+ "ext-readline": "Enables support for arrow-key history navigation, and showing and manipulating command history.",
+ "hoa/console": "A pure PHP readline implementation. You'll want this if your PHP install doesn't already support readline or libedit."
+ },
+ "bin": [
+ "bin/psysh"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-develop": "0.9.x-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/functions.php"
+ ],
+ "psr-4": {
+ "Psy\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Justin Hileman",
+ "email": "justin@justinhileman.info",
+ "homepage": "http://justinhileman.com"
+ }
+ ],
+ "description": "An interactive shell for modern PHP.",
+ "homepage": "http://psysh.org",
+ "keywords": [
+ "REPL",
+ "console",
+ "interactive",
+ "shell"
+ ],
+ "support": {
+ "issues": "https://github.com/bobthecow/psysh/issues",
+ "source": "https://github.com/bobthecow/psysh/tree/v0.9.12"
+ },
+ "time": "2019-12-06T14:19:43+00:00"
+ },
+ {
+ "name": "ralouphie/getallheaders",
+ "version": "3.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/ralouphie/getallheaders.git",
+ "reference": "120b605dfeb996808c31b6477290a714d356e822"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
+ "reference": "120b605dfeb996808c31b6477290a714d356e822",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6"
+ },
+ "require-dev": {
+ "php-coveralls/php-coveralls": "^2.1",
+ "phpunit/phpunit": "^5 || ^6.5"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "src/getallheaders.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Ralph Khattar",
+ "email": "ralph.khattar@gmail.com"
+ }
+ ],
+ "description": "A polyfill for getallheaders.",
+ "support": {
+ "issues": "https://github.com/ralouphie/getallheaders/issues",
+ "source": "https://github.com/ralouphie/getallheaders/tree/develop"
+ },
+ "time": "2019-03-08T08:55:37+00:00"
+ },
+ {
+ "name": "ramsey/uuid",
+ "version": "3.9.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/ramsey/uuid.git",
+ "reference": "dc75aa439eb4c1b77f5379fd958b3dc0e6014178"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/ramsey/uuid/zipball/dc75aa439eb4c1b77f5379fd958b3dc0e6014178",
+ "reference": "dc75aa439eb4c1b77f5379fd958b3dc0e6014178",
+ "shasum": ""
+ },
+ "require": {
+ "ext-json": "*",
+ "paragonie/random_compat": "^1 | ^2 | ^9.99.99",
+ "php": "^5.4 | ^7.0 | ^8.0",
+ "symfony/polyfill-ctype": "^1.8"
+ },
+ "replace": {
+ "rhumsaa/uuid": "self.version"
+ },
+ "require-dev": {
+ "codeception/aspect-mock": "^1 | ^2",
+ "doctrine/annotations": "^1.2",
+ "goaop/framework": "1.0.0-alpha.2 | ^1 | >=2.1.0 <=2.3.2",
+ "mockery/mockery": "^0.9.11 | ^1",
+ "moontoast/math": "^1.1",
+ "nikic/php-parser": "<=4.5.0",
+ "paragonie/random-lib": "^2",
+ "php-mock/php-mock-phpunit": "^0.3 | ^1.1 | ^2.6",
+ "php-parallel-lint/php-parallel-lint": "^1.3",
+ "phpunit/phpunit": ">=4.8.36 <9.0.0 | >=9.3.0",
+ "squizlabs/php_codesniffer": "^3.5",
+ "yoast/phpunit-polyfills": "^1.0"
+ },
+ "suggest": {
+ "ext-ctype": "Provides support for PHP Ctype functions",
+ "ext-libsodium": "Provides the PECL libsodium extension for use with the SodiumRandomGenerator",
+ "ext-openssl": "Provides the OpenSSL extension for use with the OpenSslGenerator",
+ "ext-uuid": "Provides the PECL UUID extension for use with the PeclUuidTimeGenerator and PeclUuidRandomGenerator",
+ "moontoast/math": "Provides support for converting UUID to 128-bit integer (in string form).",
+ "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter",
+ "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",
+ "autoload": {
+ "files": [
+ "src/functions.php"
+ ],
+ "psr-4": {
+ "Ramsey\\Uuid\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Ben Ramsey",
+ "email": "ben@benramsey.com",
+ "homepage": "https://benramsey.com"
+ },
+ {
+ "name": "Marijn Huizendveld",
+ "email": "marijn.huizendveld@gmail.com"
+ },
+ {
+ "name": "Thibaud Fabre",
+ "email": "thibaud@aztech.io"
+ }
+ ],
+ "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"
+ ],
+ "support": {
+ "issues": "https://github.com/ramsey/uuid/issues",
+ "rss": "https://github.com/ramsey/uuid/releases.atom",
+ "source": "https://github.com/ramsey/uuid",
+ "wiki": "https://github.com/ramsey/uuid/wiki"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/ramsey",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/ramsey/uuid",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-12-19T21:55:10+00:00"
+ },
+ {
+ "name": "swiftmailer/swiftmailer",
+ "version": "v6.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/swiftmailer/swiftmailer.git",
+ "reference": "8a5d5072dca8f48460fce2f4131fcc495eec654c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/8a5d5072dca8f48460fce2f4131fcc495eec654c",
+ "reference": "8a5d5072dca8f48460fce2f4131fcc495eec654c",
+ "shasum": ""
+ },
+ "require": {
+ "egulias/email-validator": "^2.0|^3.1",
+ "php": ">=7.0.0",
+ "symfony/polyfill-iconv": "^1.0",
+ "symfony/polyfill-intl-idn": "^1.10",
+ "symfony/polyfill-mbstring": "^1.0"
+ },
+ "require-dev": {
+ "mockery/mockery": "^1.0",
+ "symfony/phpunit-bridge": "^4.4|^5.4"
+ },
+ "suggest": {
+ "ext-intl": "Needed to support internationalized email addresses"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "6.2-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "lib/swift_required.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Chris Corbyn"
+ },
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ }
+ ],
+ "description": "Swiftmailer, free feature-rich PHP mailer",
+ "homepage": "https://swiftmailer.symfony.com",
+ "keywords": [
+ "email",
+ "mail",
+ "mailer"
+ ],
+ "support": {
+ "issues": "https://github.com/swiftmailer/swiftmailer/issues",
+ "source": "https://github.com/swiftmailer/swiftmailer/tree/v6.3.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/swiftmailer/swiftmailer",
+ "type": "tidelift"
+ }
+ ],
+ "abandoned": "symfony/mailer",
+ "time": "2021-10-18T15:26:12+00:00"
+ },
+ {
+ "name": "symfony/console",
+ "version": "v4.4.49",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/console.git",
+ "reference": "33fa45ffc81fdcc1ca368d4946da859c8cdb58d9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/console/zipball/33fa45ffc81fdcc1ca368d4946da859c8cdb58d9",
+ "reference": "33fa45ffc81fdcc1ca368d4946da859c8cdb58d9",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1.3",
+ "symfony/polyfill-mbstring": "~1.0",
+ "symfony/polyfill-php73": "^1.8",
+ "symfony/polyfill-php80": "^1.16",
+ "symfony/service-contracts": "^1.1|^2"
+ },
+ "conflict": {
+ "psr/log": ">=3",
+ "symfony/dependency-injection": "<3.4",
+ "symfony/event-dispatcher": "<4.3|>=5",
+ "symfony/lock": "<4.4",
+ "symfony/process": "<3.3"
+ },
+ "provide": {
+ "psr/log-implementation": "1.0|2.0"
+ },
+ "require-dev": {
+ "psr/log": "^1|^2",
+ "symfony/config": "^3.4|^4.0|^5.0",
+ "symfony/dependency-injection": "^3.4|^4.0|^5.0",
+ "symfony/event-dispatcher": "^4.3",
+ "symfony/lock": "^4.4|^5.0",
+ "symfony/process": "^3.4|^4.0|^5.0",
+ "symfony/var-dumper": "^4.3|^5.0"
+ },
+ "suggest": {
+ "psr/log": "For using the console logger",
+ "symfony/event-dispatcher": "",
+ "symfony/lock": "",
+ "symfony/process": ""
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Console\\": ""
+ },
+ "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": "Eases the creation of beautiful and testable command line interfaces",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/console/tree/v4.4.49"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-11-05T17:10:16+00:00"
+ },
+ {
+ "name": "symfony/css-selector",
+ "version": "v4.4.44",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/css-selector.git",
+ "reference": "bd0a6737e48de45b4b0b7b6fc98c78404ddceaed"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/css-selector/zipball/bd0a6737e48de45b4b0b7b6fc98c78404ddceaed",
+ "reference": "bd0a6737e48de45b4b0b7b6fc98c78404ddceaed",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1.3",
+ "symfony/polyfill-php80": "^1.16"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\CssSelector\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Jean-François Simon",
+ "email": "jeanfrancois.simon@sensiolabs.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Converts CSS selectors to XPath expressions",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/css-selector/tree/v4.4.44"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-06-27T13:16:42+00:00"
+ },
+ {
+ "name": "symfony/debug",
+ "version": "v4.4.44",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/debug.git",
+ "reference": "1a692492190773c5310bc7877cb590c04c2f05be"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/debug/zipball/1a692492190773c5310bc7877cb590c04c2f05be",
+ "reference": "1a692492190773c5310bc7877cb590c04c2f05be",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1.3",
+ "psr/log": "^1|^2|^3"
+ },
+ "conflict": {
+ "symfony/http-kernel": "<3.4"
+ },
+ "require-dev": {
+ "symfony/http-kernel": "^3.4|^4.0|^5.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Debug\\": ""
+ },
+ "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": "Provides tools to ease debugging PHP code",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/debug/tree/v4.4.44"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "abandoned": "symfony/error-handler",
+ "time": "2022-07-28T16:29:46+00:00"
+ },
+ {
+ "name": "symfony/error-handler",
+ "version": "v4.4.44",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/error-handler.git",
+ "reference": "be731658121ef2d8be88f3a1ec938148a9237291"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/error-handler/zipball/be731658121ef2d8be88f3a1ec938148a9237291",
+ "reference": "be731658121ef2d8be88f3a1ec938148a9237291",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1.3",
+ "psr/log": "^1|^2|^3",
+ "symfony/debug": "^4.4.5",
+ "symfony/var-dumper": "^4.4|^5.0"
+ },
+ "require-dev": {
+ "symfony/http-kernel": "^4.4|^5.0",
+ "symfony/serializer": "^4.4|^5.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\ErrorHandler\\": ""
+ },
+ "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": "Provides tools to manage errors and ease debugging PHP code",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/error-handler/tree/v4.4.44"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-07-28T16:29:46+00:00"
+ },
+ {
+ "name": "symfony/event-dispatcher",
+ "version": "v4.4.44",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/event-dispatcher.git",
+ "reference": "1e866e9e5c1b22168e0ce5f0b467f19bba61266a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/1e866e9e5c1b22168e0ce5f0b467f19bba61266a",
+ "reference": "1e866e9e5c1b22168e0ce5f0b467f19bba61266a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1.3",
+ "symfony/event-dispatcher-contracts": "^1.1",
+ "symfony/polyfill-php80": "^1.16"
+ },
+ "conflict": {
+ "symfony/dependency-injection": "<3.4"
+ },
+ "provide": {
+ "psr/event-dispatcher-implementation": "1.0",
+ "symfony/event-dispatcher-implementation": "1.1"
+ },
+ "require-dev": {
+ "psr/log": "^1|^2|^3",
+ "symfony/config": "^3.4|^4.0|^5.0",
+ "symfony/dependency-injection": "^3.4|^4.0|^5.0",
+ "symfony/error-handler": "~3.4|~4.4",
+ "symfony/expression-language": "^3.4|^4.0|^5.0",
+ "symfony/http-foundation": "^3.4|^4.0|^5.0",
+ "symfony/service-contracts": "^1.1|^2",
+ "symfony/stopwatch": "^3.4|^4.0|^5.0"
+ },
+ "suggest": {
+ "symfony/dependency-injection": "",
+ "symfony/http-kernel": ""
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\EventDispatcher\\": ""
+ },
+ "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": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due",
- "keywords": [
- "cron",
- "schedule"
+ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/event-dispatcher/tree/v4.4.44"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
],
- "time": "2016-01-26 21:23:30"
+ "time": "2022-07-20T09:59:04+00:00"
},
{
- "name": "mtdowling/jmespath.php",
- "version": "2.3.0",
+ "name": "symfony/event-dispatcher-contracts",
+ "version": "v1.1.13",
"source": {
"type": "git",
- "url": "https://github.com/jmespath/jmespath.php.git",
- "reference": "192f93e43c2c97acde7694993ab171b3de284093"
+ "url": "https://github.com/symfony/event-dispatcher-contracts.git",
+ "reference": "1d5cd762abaa6b2a4169d3e77610193a7157129e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/192f93e43c2c97acde7694993ab171b3de284093",
- "reference": "192f93e43c2c97acde7694993ab171b3de284093",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/1d5cd762abaa6b2a4169d3e77610193a7157129e",
+ "reference": "1d5cd762abaa6b2a4169d3e77610193a7157129e",
"shasum": ""
},
"require": {
- "php": ">=5.4.0"
+ "php": ">=7.1.3"
},
- "require-dev": {
- "phpunit/phpunit": "~4.0"
+ "suggest": {
+ "psr/event-dispatcher": "",
+ "symfony/event-dispatcher-implementation": ""
},
- "bin": [
- "bin/jp.php"
- ],
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.0-dev"
+ "dev-main": "1.1-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
}
},
"autoload": {
"psr-4": {
- "JmesPath\\": "src/"
- },
- "files": [
- "src/JmesPath.php"
- ]
+ "Symfony\\Contracts\\EventDispatcher\\": ""
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -2526,44 +5183,69 @@
],
"authors": [
{
- "name": "Michael Dowling",
- "email": "mtdowling@gmail.com",
- "homepage": "https://github.com/mtdowling"
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
- "description": "Declaratively specify how to extract elements from a JSON document",
+ "description": "Generic abstractions related to dispatching event",
+ "homepage": "https://symfony.com",
"keywords": [
- "json",
- "jsonpath"
+ "abstractions",
+ "contracts",
+ "decoupling",
+ "interfaces",
+ "interoperability",
+ "standards"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v1.1.13"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
],
- "time": "2016-01-05 18:25:05"
+ "time": "2022-01-02T09:41:36+00:00"
},
{
- "name": "nesbot/carbon",
- "version": "1.21.0",
+ "name": "symfony/finder",
+ "version": "v4.4.44",
"source": {
"type": "git",
- "url": "https://github.com/briannesbitt/Carbon.git",
- "reference": "7b08ec6f75791e130012f206e3f7b0e76e18e3d7"
+ "url": "https://github.com/symfony/finder.git",
+ "reference": "66bd787edb5e42ff59d3523f623895af05043e4f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/7b08ec6f75791e130012f206e3f7b0e76e18e3d7",
- "reference": "7b08ec6f75791e130012f206e3f7b0e76e18e3d7",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/66bd787edb5e42ff59d3523f623895af05043e4f",
+ "reference": "66bd787edb5e42ff59d3523f623895af05043e4f",
"shasum": ""
},
"require": {
- "php": ">=5.3.0",
- "symfony/translation": "~2.6|~3.0"
- },
- "require-dev": {
- "phpunit/phpunit": "~4.0|~5.0"
+ "php": ">=7.1.3",
+ "symfony/polyfill-php80": "^1.16"
},
"type": "library",
"autoload": {
"psr-4": {
- "Carbon\\": "src/Carbon/"
- }
+ "Symfony\\Component\\Finder\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -2571,98 +5253,144 @@
],
"authors": [
{
- "name": "Brian Nesbitt",
- "email": "brian@nesbot.com",
- "homepage": "http://nesbot.com"
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
- "description": "A simple API extension for DateTime.",
- "homepage": "http://carbon.nesbot.com",
- "keywords": [
- "date",
- "datetime",
- "time"
+ "description": "Finds files and directories via an intuitive fluent interface",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/finder/tree/v4.4.44"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
],
- "time": "2015-11-04 20:07:17"
+ "time": "2022-07-29T07:35:46+00:00"
},
{
- "name": "nikic/php-parser",
- "version": "v2.1.0",
+ "name": "symfony/http-client-contracts",
+ "version": "v1.1.13",
"source": {
"type": "git",
- "url": "https://github.com/nikic/PHP-Parser.git",
- "reference": "47b254ea51f1d6d5dc04b9b299e88346bf2369e3"
+ "url": "https://github.com/symfony/http-client-contracts.git",
+ "reference": "59f37624a82635962f04c98f31aed122e539a89e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/47b254ea51f1d6d5dc04b9b299e88346bf2369e3",
- "reference": "47b254ea51f1d6d5dc04b9b299e88346bf2369e3",
+ "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/59f37624a82635962f04c98f31aed122e539a89e",
+ "reference": "59f37624a82635962f04c98f31aed122e539a89e",
"shasum": ""
},
"require": {
- "ext-tokenizer": "*",
- "php": ">=5.4"
+ "php": ">=7.1.3"
},
- "require-dev": {
- "phpunit/phpunit": "~4.0"
+ "suggest": {
+ "symfony/http-client-implementation": ""
},
- "bin": [
- "bin/php-parse"
- ],
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.1-dev"
+ "dev-main": "1.1-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
}
},
"autoload": {
"psr-4": {
- "PhpParser\\": "lib/PhpParser"
+ "Symfony\\Contracts\\HttpClient\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-3-Clause"
+ "MIT"
],
"authors": [
{
- "name": "Nikita Popov"
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
- "description": "A PHP parser written in PHP",
+ "description": "Generic abstractions related to HTTP clients",
+ "homepage": "https://symfony.com",
"keywords": [
- "parser",
- "php"
+ "abstractions",
+ "contracts",
+ "decoupling",
+ "interfaces",
+ "interoperability",
+ "standards"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/http-client-contracts/tree/v1.1.13"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
],
- "time": "2016-04-19 13:41:41"
+ "time": "2022-04-11T14:52:04+00:00"
},
{
- "name": "paragonie/random_compat",
- "version": "v1.4.1",
+ "name": "symfony/http-foundation",
+ "version": "v4.4.49",
"source": {
"type": "git",
- "url": "https://github.com/paragonie/random_compat.git",
- "reference": "c7e26a21ba357863de030f0b9e701c7d04593774"
+ "url": "https://github.com/symfony/http-foundation.git",
+ "reference": "191413c7b832c015bb38eae963f2e57498c3c173"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/paragonie/random_compat/zipball/c7e26a21ba357863de030f0b9e701c7d04593774",
- "reference": "c7e26a21ba357863de030f0b9e701c7d04593774",
+ "url": "https://api.github.com/repos/symfony/http-foundation/zipball/191413c7b832c015bb38eae963f2e57498c3c173",
+ "reference": "191413c7b832c015bb38eae963f2e57498c3c173",
"shasum": ""
},
"require": {
- "php": ">=5.2.0"
+ "php": ">=7.1.3",
+ "symfony/mime": "^4.3|^5.0",
+ "symfony/polyfill-mbstring": "~1.1",
+ "symfony/polyfill-php80": "^1.16"
},
"require-dev": {
- "phpunit/phpunit": "4.*|5.*"
- },
- "suggest": {
- "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
+ "predis/predis": "~1.0",
+ "symfony/expression-language": "^3.4|^4.0|^5.0"
},
"type": "library",
"autoload": {
- "files": [
- "lib/random.php"
+ "psr-4": {
+ "Symfony\\Component\\HttpFoundation\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -2671,102 +5399,175 @@
],
"authors": [
{
- "name": "Paragon Initiative Enterprises",
- "email": "security@paragonie.com",
- "homepage": "https://paragonie.com"
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
- "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
- "keywords": [
- "csprng",
- "pseudorandom",
- "random"
+ "description": "Defines an object-oriented layer for the HTTP specification",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/http-foundation/tree/v4.4.49"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
],
- "time": "2016-03-18 20:34:03"
+ "time": "2022-11-04T16:17:57+00:00"
},
{
- "name": "pragmarx/google2fa",
- "version": "v0.7.1",
+ "name": "symfony/http-kernel",
+ "version": "v4.4.50",
"source": {
"type": "git",
- "url": "https://github.com/antonioribeiro/google2fa.git",
- "reference": "908678ba9b26cf8ecd7ddca6bfd86afc5b4874df"
+ "url": "https://github.com/symfony/http-kernel.git",
+ "reference": "aa6df6c045f034aa13ac752fc234bb300b9488ef"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/antonioribeiro/google2fa/zipball/908678ba9b26cf8ecd7ddca6bfd86afc5b4874df",
- "reference": "908678ba9b26cf8ecd7ddca6bfd86afc5b4874df",
+ "url": "https://api.github.com/repos/symfony/http-kernel/zipball/aa6df6c045f034aa13ac752fc234bb300b9488ef",
+ "reference": "aa6df6c045f034aa13ac752fc234bb300b9488ef",
"shasum": ""
},
"require": {
- "christian-riesen/base32": "~1.0",
- "php": ">=5.3.7",
- "simplesoftwareio/simple-qrcode": "1.3.*"
+ "php": ">=7.1.3",
+ "psr/log": "^1|^2",
+ "symfony/error-handler": "^4.4",
+ "symfony/event-dispatcher": "^4.4",
+ "symfony/http-client-contracts": "^1.1|^2",
+ "symfony/http-foundation": "^4.4.30|^5.3.7",
+ "symfony/polyfill-ctype": "^1.8",
+ "symfony/polyfill-php73": "^1.9",
+ "symfony/polyfill-php80": "^1.16"
+ },
+ "conflict": {
+ "symfony/browser-kit": "<4.3",
+ "symfony/config": "<3.4",
+ "symfony/console": ">=5",
+ "symfony/dependency-injection": "<4.3",
+ "symfony/translation": "<4.2",
+ "twig/twig": "<1.43|<2.13,>=2"
+ },
+ "provide": {
+ "psr/log-implementation": "1.0|2.0"
},
"require-dev": {
- "phpspec/phpspec": "~2.1"
+ "psr/cache": "^1.0|^2.0|^3.0",
+ "symfony/browser-kit": "^4.3|^5.0",
+ "symfony/config": "^3.4|^4.0|^5.0",
+ "symfony/console": "^3.4|^4.0",
+ "symfony/css-selector": "^3.4|^4.0|^5.0",
+ "symfony/dependency-injection": "^4.3|^5.0",
+ "symfony/dom-crawler": "^3.4|^4.0|^5.0",
+ "symfony/expression-language": "^3.4|^4.0|^5.0",
+ "symfony/finder": "^3.4|^4.0|^5.0",
+ "symfony/process": "^3.4|^4.0|^5.0",
+ "symfony/routing": "^3.4|^4.0|^5.0",
+ "symfony/stopwatch": "^3.4|^4.0|^5.0",
+ "symfony/templating": "^3.4|^4.0|^5.0",
+ "symfony/translation": "^4.2|^5.0",
+ "symfony/translation-contracts": "^1.1|^2",
+ "twig/twig": "^1.43|^2.13|^3.0.4"
},
- "type": "library",
- "extra": {
- "component": "package",
- "frameworks": [
- "Laravel"
- ]
+ "suggest": {
+ "symfony/browser-kit": "",
+ "symfony/config": "",
+ "symfony/console": "",
+ "symfony/dependency-injection": ""
},
+ "type": "library",
"autoload": {
"psr-4": {
- "PragmaRX\\Google2FA\\": "src/"
- }
+ "Symfony\\Component\\HttpKernel\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-3-Clause"
+ "MIT"
],
"authors": [
{
- "name": "Antonio Carlos Ribeiro",
- "email": "acr@antoniocarlosribeiro.com",
- "role": "Creator & Designer"
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
- "description": "A One Time Password Authentication package, compatible with Google Authenticator.",
- "keywords": [
- "Authentication",
- "Two Factor Authentication",
- "google2fa",
- "laravel"
+ "description": "Provides a structured process for converting a Request into a Response",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/http-kernel/tree/v4.4.50"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
],
- "time": "2015-11-07 13:57:42"
+ "time": "2023-02-01T08:01:31+00:00"
},
{
- "name": "predis/predis",
- "version": "v1.1.1",
+ "name": "symfony/mime",
+ "version": "v4.4.47",
"source": {
"type": "git",
- "url": "https://github.com/nrk/predis.git",
- "reference": "f0210e38881631afeafb56ab43405a92cafd9fd1"
+ "url": "https://github.com/symfony/mime.git",
+ "reference": "0eaf33cd6d1b3eaa50e7bc48b17f6e45789df35d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nrk/predis/zipball/f0210e38881631afeafb56ab43405a92cafd9fd1",
- "reference": "f0210e38881631afeafb56ab43405a92cafd9fd1",
+ "url": "https://api.github.com/repos/symfony/mime/zipball/0eaf33cd6d1b3eaa50e7bc48b17f6e45789df35d",
+ "reference": "0eaf33cd6d1b3eaa50e7bc48b17f6e45789df35d",
"shasum": ""
},
"require": {
- "php": ">=5.3.9"
+ "php": ">=7.1.3",
+ "symfony/polyfill-intl-idn": "^1.10",
+ "symfony/polyfill-mbstring": "^1.0",
+ "symfony/polyfill-php80": "^1.16"
},
- "require-dev": {
- "phpunit/phpunit": "~4.8"
+ "conflict": {
+ "egulias/email-validator": "~3.0.0",
+ "symfony/mailer": "<4.4"
},
- "suggest": {
- "ext-curl": "Allows access to Webdis when paired with phpiredis",
- "ext-phpiredis": "Allows faster serialization and deserialization of the Redis protocol"
+ "require-dev": {
+ "egulias/email-validator": "^2.1.10|^3.1",
+ "symfony/dependency-injection": "^3.4|^4.1|^5.0"
},
"type": "library",
"autoload": {
"psr-4": {
- "Predis\\": "src/"
- }
+ "Symfony\\Component\\Mime\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -2774,46 +5575,78 @@
],
"authors": [
{
- "name": "Daniele Alessandri",
- "email": "suppakilla@gmail.com",
- "homepage": "http://clorophilla.net"
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
- "description": "Flexible and feature-complete Redis client for PHP and HHVM",
- "homepage": "http://github.com/nrk/predis",
+ "description": "Allows manipulating MIME messages",
+ "homepage": "https://symfony.com",
"keywords": [
- "nosql",
- "predis",
- "redis"
+ "mime",
+ "mime-type"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/mime/tree/v4.4.47"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
],
- "time": "2016-06-16 16:22:20"
+ "time": "2022-10-03T15:15:11+00:00"
},
{
- "name": "psr/http-message",
- "version": "1.0.1",
+ "name": "symfony/polyfill-ctype",
+ "version": "v1.28.0",
"source": {
"type": "git",
- "url": "https://github.com/php-fig/http-message.git",
- "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
+ "url": "https://github.com/symfony/polyfill-ctype.git",
+ "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
- "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
+ "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
"shasum": ""
},
"require": {
- "php": ">=5.3.0"
+ "php": ">=7.1"
+ },
+ "provide": {
+ "ext-ctype": "*"
+ },
+ "suggest": {
+ "ext-ctype": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0.x-dev"
+ "dev-main": "1.28-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
"psr-4": {
- "Psr\\Http\\Message\\": "src/"
+ "Symfony\\Polyfill\\Ctype\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -2822,40 +5655,80 @@
],
"authors": [
{
- "name": "PHP-FIG",
- "homepage": "http://www.php-fig.org/"
+ "name": "Gert de Pagter",
+ "email": "BackEndTea@gmail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
- "description": "Common interface for HTTP messages",
- "homepage": "https://github.com/php-fig/http-message",
+ "description": "Symfony polyfill for ctype functions",
+ "homepage": "https://symfony.com",
"keywords": [
- "http",
- "http-message",
- "psr",
- "psr-7",
- "request",
- "response"
+ "compatibility",
+ "ctype",
+ "polyfill",
+ "portable"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
],
- "time": "2016-08-06 14:39:51"
+ "time": "2023-01-26T09:26:14+00:00"
},
{
- "name": "psr/log",
- "version": "1.0.0",
+ "name": "symfony/polyfill-iconv",
+ "version": "v1.28.0",
"source": {
"type": "git",
- "url": "https://github.com/php-fig/log.git",
- "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b"
+ "url": "https://github.com/symfony/polyfill-iconv.git",
+ "reference": "6de50471469b8c9afc38164452ab2b6170ee71c1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b",
- "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b",
+ "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/6de50471469b8c9afc38164452ab2b6170ee71c1",
+ "reference": "6de50471469b8c9afc38164452ab2b6170ee71c1",
"shasum": ""
},
+ "require": {
+ "php": ">=7.1"
+ },
+ "provide": {
+ "ext-iconv": "*"
+ },
+ "suggest": {
+ "ext-iconv": "For best performance"
+ },
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.28-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
"autoload": {
- "psr-0": {
- "Psr\\Log\\": ""
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Iconv\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -2864,67 +5737,80 @@
],
"authors": [
{
- "name": "PHP-FIG",
- "homepage": "http://www.php-fig.org/"
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
- "description": "Common interface for logging libraries",
+ "description": "Symfony polyfill for the Iconv extension",
+ "homepage": "https://symfony.com",
"keywords": [
- "log",
- "psr",
- "psr-3"
+ "compatibility",
+ "iconv",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-iconv/tree/v1.28.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
],
- "time": "2012-12-21 11:40:51"
+ "time": "2023-01-26T09:26:14+00:00"
},
{
- "name": "psy/psysh",
- "version": "v0.7.2",
+ "name": "symfony/polyfill-intl-idn",
+ "version": "v1.28.0",
"source": {
"type": "git",
- "url": "https://github.com/bobthecow/psysh.git",
- "reference": "e64e10b20f8d229cac76399e1f3edddb57a0f280"
+ "url": "https://github.com/symfony/polyfill-intl-idn.git",
+ "reference": "ecaafce9f77234a6a449d29e49267ba10499116d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/bobthecow/psysh/zipball/e64e10b20f8d229cac76399e1f3edddb57a0f280",
- "reference": "e64e10b20f8d229cac76399e1f3edddb57a0f280",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/ecaafce9f77234a6a449d29e49267ba10499116d",
+ "reference": "ecaafce9f77234a6a449d29e49267ba10499116d",
"shasum": ""
},
"require": {
- "dnoegel/php-xdg-base-dir": "0.1",
- "jakub-onderka/php-console-highlighter": "0.3.*",
- "nikic/php-parser": "^1.2.1|~2.0",
- "php": ">=5.3.9",
- "symfony/console": "~2.3.10|^2.4.2|~3.0",
- "symfony/var-dumper": "~2.7|~3.0"
- },
- "require-dev": {
- "fabpot/php-cs-fixer": "~1.5",
- "phpunit/phpunit": "~3.7|~4.0|~5.0",
- "squizlabs/php_codesniffer": "~2.0",
- "symfony/finder": "~2.1|~3.0"
+ "php": ">=7.1",
+ "symfony/polyfill-intl-normalizer": "^1.10",
+ "symfony/polyfill-php72": "^1.10"
},
"suggest": {
- "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)",
- "ext-pdo-sqlite": "The doc command requires SQLite to work.",
- "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well.",
- "ext-readline": "Enables support for arrow-key history navigation, and showing and manipulating command history."
+ "ext-intl": "For best performance"
},
- "bin": [
- "bin/psysh"
- ],
"type": "library",
"extra": {
"branch-alias": {
- "dev-develop": "0.8.x-dev"
+ "dev-main": "1.28-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"files": [
- "src/Psy/functions.php"
+ "bootstrap.php"
],
"psr-4": {
- "Psy\\": "src/Psy/"
+ "Symfony\\Polyfill\\Intl\\Idn\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -2933,63 +5819,87 @@
],
"authors": [
{
- "name": "Justin Hileman",
- "email": "justin@justinhileman.info",
- "homepage": "http://justinhileman.com"
+ "name": "Laurent Bassin",
+ "email": "laurent@bassin.info"
+ },
+ {
+ "name": "Trevor Rowbotham",
+ "email": "trevor.rowbotham@pm.me"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
- "description": "An interactive shell for modern PHP.",
- "homepage": "http://psysh.org",
+ "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions",
+ "homepage": "https://symfony.com",
"keywords": [
- "REPL",
- "console",
- "interactive",
- "shell"
+ "compatibility",
+ "idn",
+ "intl",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.28.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
],
- "time": "2016-03-09 05:03:14"
+ "time": "2023-01-26T09:30:37+00:00"
},
{
- "name": "rcrowe/twigbridge",
- "version": "v0.9.3",
+ "name": "symfony/polyfill-intl-normalizer",
+ "version": "v1.28.0",
"source": {
"type": "git",
- "url": "https://github.com/rcrowe/TwigBridge.git",
- "reference": "6226d33331bbb1cdf64593a786f7efd1670200a7"
+ "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
+ "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/rcrowe/TwigBridge/zipball/6226d33331bbb1cdf64593a786f7efd1670200a7",
- "reference": "6226d33331bbb1cdf64593a786f7efd1670200a7",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92",
+ "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92",
"shasum": ""
},
"require": {
- "illuminate/support": "5.0.*|5.1.*|5.2.*|5.3.*",
- "illuminate/view": "5.0.*|5.1.*|5.2.*|5.3.*",
- "php": ">=5.4.0",
- "twig/twig": "~1.15|~2.0"
- },
- "require-dev": {
- "laravel/framework": "5.0.*",
- "mockery/mockery": "0.9.*",
- "phpunit/phpunit": "~4.0",
- "satooshi/php-coveralls": "~0.6",
- "squizlabs/php_codesniffer": "~1.5"
+ "php": ">=7.1"
},
"suggest": {
- "laravelcollective/html": "For bringing back html/form in Laravel 5.x",
- "twig/extensions": "~1.0"
+ "ext-intl": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "0.10-dev"
+ "dev-main": "1.28-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
"psr-4": {
- "TwigBridge\\": "src",
- "TwigBridge\\Tests\\": "tests"
- }
+ "Symfony\\Polyfill\\Intl\\Normalizer\\": ""
+ },
+ "classmap": [
+ "Resources/stubs"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -2997,47 +5907,68 @@
],
"authors": [
{
- "name": "Barry vd. Heuvel",
- "email": "barryvdh@gmail.com"
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
},
{
- "name": "Rob Crowe",
- "email": "hello@vivalacrowe.com"
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
- "description": "Adds the power of Twig to Laravel",
+ "description": "Symfony polyfill for intl's Normalizer class and related functions",
+ "homepage": "https://symfony.com",
"keywords": [
- "laravel",
- "twig"
+ "compatibility",
+ "intl",
+ "normalizer",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
],
- "time": "2016-05-01 16:43:38"
+ "time": "2023-01-26T09:26:14+00:00"
},
{
- "name": "roumen/feed",
- "version": "v2.10.4",
+ "name": "symfony/polyfill-php56",
+ "version": "v1.20.0",
"source": {
"type": "git",
- "url": "https://github.com/RoumenDamianoff/laravel-feed.git",
- "reference": "900594412cab37515b2b53c8953af1201024e48d"
+ "url": "https://github.com/symfony/polyfill-php56.git",
+ "reference": "54b8cd7e6c1643d78d011f3be89f3ef1f9f4c675"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/RoumenDamianoff/laravel-feed/zipball/900594412cab37515b2b53c8953af1201024e48d",
- "reference": "900594412cab37515b2b53c8953af1201024e48d",
+ "url": "https://api.github.com/repos/symfony/polyfill-php56/zipball/54b8cd7e6c1643d78d011f3be89f3ef1f9f4c675",
+ "reference": "54b8cd7e6c1643d78d011f3be89f3ef1f9f4c675",
"shasum": ""
},
"require": {
- "illuminate/support": "^5.0",
- "php": ">=5.5.9"
- },
- "require-dev": {
- "orchestra/testbench": "^3.0",
- "phpunit/phpunit": "^4.8"
+ "php": ">=7.1"
},
- "type": "library",
- "autoload": {
- "psr-0": {
- "Roumen\\Feed": "src/"
+ "type": "metapackage",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.20-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -3046,51 +5977,74 @@
],
"authors": [
{
- "name": "Roumen Damianoff",
- "email": "roumen@dawebs.com",
- "homepage": "https://roumen.it",
- "role": "Developer"
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
- "description": "A simple feed generator for Laravel.",
- "homepage": "https://roumen.it/projects/laravel-feed",
+ "description": "Symfony polyfill backporting some PHP 5.6+ features to lower PHP versions",
+ "homepage": "https://symfony.com",
"keywords": [
- "atom",
- "feed",
- "generator",
- "laravel",
- "rss"
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php56/tree/v1.20.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
],
- "time": "2016-07-17 13:06:35"
+ "time": "2020-10-23T14:02:19+00:00"
},
{
- "name": "simplesoftwareio/simple-qrcode",
- "version": "1.3.3",
+ "name": "symfony/polyfill-php72",
+ "version": "v1.28.0",
"source": {
"type": "git",
- "url": "https://github.com/SimpleSoftwareIO/simple-qrcode.git",
- "reference": "17c5e45c79c40f717d4bc08cf5e568f29ebf9333"
+ "url": "https://github.com/symfony/polyfill-php72.git",
+ "reference": "70f4aebd92afca2f865444d30a4d2151c13c3179"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/SimpleSoftwareIO/simple-qrcode/zipball/17c5e45c79c40f717d4bc08cf5e568f29ebf9333",
- "reference": "17c5e45c79c40f717d4bc08cf5e568f29ebf9333",
+ "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/70f4aebd92afca2f865444d30a4d2151c13c3179",
+ "reference": "70f4aebd92afca2f865444d30a4d2151c13c3179",
"shasum": ""
},
"require": {
- "bacon/bacon-qr-code": "1.0.*",
- "ext-gd": "*",
- "illuminate/support": ">=4.2.0",
- "php": ">=5.4.0"
- },
- "require-dev": {
- "mockery/mockery": "0.9.*",
- "phpunit/phpunit": "4.7.*"
+ "php": ">=7.1"
},
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.28-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
"autoload": {
- "psr-0": {
- "SimpleSoftwareIO\\QrCode\\": "src"
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Php72\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -3099,50 +6053,77 @@
],
"authors": [
{
- "name": "Simple Software LLC",
- "email": "support@simplesoftware.io"
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
- "description": "Simple QrCode is a QR code generator made for Laravel.",
- "homepage": "http://www.simplesoftware.io",
+ "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions",
+ "homepage": "https://symfony.com",
"keywords": [
- "Simple",
- "generator",
- "laravel",
- "qrcode",
- "wrapper"
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php72/tree/v1.28.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
],
- "time": "2016-01-31 02:09:25"
+ "time": "2023-01-26T09:26:14+00:00"
},
{
- "name": "swiftmailer/swiftmailer",
- "version": "v5.4.3",
+ "name": "symfony/polyfill-php73",
+ "version": "v1.28.0",
"source": {
"type": "git",
- "url": "https://github.com/swiftmailer/swiftmailer.git",
- "reference": "4cc92842069c2bbc1f28daaaf1d2576ec4dfe153"
+ "url": "https://github.com/symfony/polyfill-php73.git",
+ "reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/4cc92842069c2bbc1f28daaaf1d2576ec4dfe153",
- "reference": "4cc92842069c2bbc1f28daaaf1d2576ec4dfe153",
+ "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fe2f306d1d9d346a7fee353d0d5012e401e984b5",
+ "reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
- },
- "require-dev": {
- "mockery/mockery": "~0.9.1"
+ "php": ">=7.1"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "5.4-dev"
+ "dev-main": "1.28-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"files": [
- "lib/swift_required.php"
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Php73\\": ""
+ },
+ "classmap": [
+ "Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -3151,62 +6132,77 @@
],
"authors": [
{
- "name": "Chris Corbyn"
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
},
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
- "description": "Swiftmailer, free feature-rich PHP mailer",
- "homepage": "http://swiftmailer.org",
+ "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions",
+ "homepage": "https://symfony.com",
"keywords": [
- "email",
- "mail",
- "mailer"
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php73/tree/v1.28.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
],
- "time": "2016-07-08 11:51:25"
+ "time": "2023-01-26T09:26:14+00:00"
},
{
- "name": "symfony/console",
- "version": "v3.0.9",
+ "name": "symfony/polyfill-php80",
+ "version": "v1.28.0",
"source": {
"type": "git",
- "url": "https://github.com/symfony/console.git",
- "reference": "926061e74229e935d3c5b4e9ba87237316c6693f"
+ "url": "https://github.com/symfony/polyfill-php80.git",
+ "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/926061e74229e935d3c5b4e9ba87237316c6693f",
- "reference": "926061e74229e935d3c5b4e9ba87237316c6693f",
+ "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5",
+ "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5",
"shasum": ""
},
"require": {
- "php": ">=5.5.9",
- "symfony/polyfill-mbstring": "~1.0"
- },
- "require-dev": {
- "psr/log": "~1.0",
- "symfony/event-dispatcher": "~2.8|~3.0",
- "symfony/process": "~2.8|~3.0"
- },
- "suggest": {
- "psr/log": "For using the console logger",
- "symfony/event-dispatcher": "",
- "symfony/process": ""
+ "php": ">=7.1"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.0-dev"
+ "dev-main": "1.28-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
"psr-4": {
- "Symfony\\Component\\Console\\": ""
+ "Symfony\\Polyfill\\Php80\\": ""
},
- "exclude-from-classmap": [
- "/Tests/"
+ "classmap": [
+ "Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -3215,44 +6211,67 @@
],
"authors": [
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "name": "Ion Bazan",
+ "email": "ion.bazan@gmail.com"
+ },
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony Console Component",
+ "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
"homepage": "https://symfony.com",
- "time": "2016-07-30 07:22:48"
+ "keywords": [
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-01-26T09:26:14+00:00"
},
{
- "name": "symfony/css-selector",
- "version": "v3.1.4",
+ "name": "symfony/process",
+ "version": "v4.4.44",
"source": {
"type": "git",
- "url": "https://github.com/symfony/css-selector.git",
- "reference": "2851e1932d77ce727776154d659b232d061e816a"
+ "url": "https://github.com/symfony/process.git",
+ "reference": "5cee9cdc4f7805e2699d9fd66991a0e6df8252a2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/css-selector/zipball/2851e1932d77ce727776154d659b232d061e816a",
- "reference": "2851e1932d77ce727776154d659b232d061e816a",
+ "url": "https://api.github.com/repos/symfony/process/zipball/5cee9cdc4f7805e2699d9fd66991a0e6df8252a2",
+ "reference": "5cee9cdc4f7805e2699d9fd66991a0e6df8252a2",
"shasum": ""
},
"require": {
- "php": ">=5.5.9"
+ "php": ">=7.1.3",
+ "symfony/polyfill-php80": "^1.16"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.1-dev"
- }
- },
"autoload": {
"psr-4": {
- "Symfony\\Component\\CssSelector\\": ""
+ "Symfony\\Component\\Process\\": ""
},
"exclude-from-classmap": [
"/Tests/"
@@ -3263,10 +6282,6 @@
"MIT"
],
"authors": [
- {
- "name": "Jean-François Simon",
- "email": "jeanfrancois.simon@sensiolabs.com"
- },
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
@@ -3276,44 +6291,70 @@
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony CssSelector Component",
+ "description": "Executes commands in sub-processes",
"homepage": "https://symfony.com",
- "time": "2016-06-29 05:41:56"
+ "support": {
+ "source": "https://github.com/symfony/process/tree/v4.4.44"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-06-27T13:16:42+00:00"
},
{
- "name": "symfony/debug",
- "version": "v3.0.9",
+ "name": "symfony/routing",
+ "version": "v4.4.44",
"source": {
"type": "git",
- "url": "https://github.com/symfony/debug.git",
- "reference": "697c527acd9ea1b2d3efac34d9806bf255278b0a"
+ "url": "https://github.com/symfony/routing.git",
+ "reference": "f7751fd8b60a07f3f349947a309b5bdfce22d6ae"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/debug/zipball/697c527acd9ea1b2d3efac34d9806bf255278b0a",
- "reference": "697c527acd9ea1b2d3efac34d9806bf255278b0a",
+ "url": "https://api.github.com/repos/symfony/routing/zipball/f7751fd8b60a07f3f349947a309b5bdfce22d6ae",
+ "reference": "f7751fd8b60a07f3f349947a309b5bdfce22d6ae",
"shasum": ""
},
"require": {
- "php": ">=5.5.9",
- "psr/log": "~1.0"
+ "php": ">=7.1.3",
+ "symfony/polyfill-php80": "^1.16"
},
"conflict": {
- "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2"
+ "symfony/config": "<4.2",
+ "symfony/dependency-injection": "<3.4",
+ "symfony/yaml": "<3.4"
},
"require-dev": {
- "symfony/class-loader": "~2.8|~3.0",
- "symfony/http-kernel": "~2.8|~3.0"
+ "doctrine/annotations": "^1.10.4",
+ "psr/log": "^1|^2|^3",
+ "symfony/config": "^4.2|^5.0",
+ "symfony/dependency-injection": "^3.4|^4.0|^5.0",
+ "symfony/expression-language": "^3.4|^4.0|^5.0",
+ "symfony/http-foundation": "^3.4|^4.0|^5.0",
+ "symfony/yaml": "^3.4|^4.0|^5.0"
},
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.0-dev"
- }
+ "suggest": {
+ "doctrine/annotations": "For using the annotation loader",
+ "symfony/config": "For using the all-in-one router or any loader",
+ "symfony/expression-language": "For using expression matching",
+ "symfony/http-foundation": "For using a Symfony Request object",
+ "symfony/yaml": "For using the YAML loader"
},
+ "type": "library",
"autoload": {
"psr-4": {
- "Symfony\\Component\\Debug\\": ""
+ "Symfony\\Component\\Routing\\": ""
},
"exclude-from-classmap": [
"/Tests/"
@@ -3333,51 +6374,68 @@
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony Debug Component",
+ "description": "Maps an HTTP request to a set of configuration variables",
"homepage": "https://symfony.com",
- "time": "2016-07-30 07:22:48"
+ "keywords": [
+ "router",
+ "routing",
+ "uri",
+ "url"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/routing/tree/v4.4.44"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-07-20T09:59:04+00:00"
},
{
- "name": "symfony/event-dispatcher",
- "version": "v3.1.4",
+ "name": "symfony/service-contracts",
+ "version": "v1.1.13",
"source": {
"type": "git",
- "url": "https://github.com/symfony/event-dispatcher.git",
- "reference": "c0c00c80b3a69132c4e55c3e7db32b4a387615e5"
+ "url": "https://github.com/symfony/service-contracts.git",
+ "reference": "afa00c500c2d6aea6e3b2f4862355f507bc5ebb4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/c0c00c80b3a69132c4e55c3e7db32b4a387615e5",
- "reference": "c0c00c80b3a69132c4e55c3e7db32b4a387615e5",
+ "url": "https://api.github.com/repos/symfony/service-contracts/zipball/afa00c500c2d6aea6e3b2f4862355f507bc5ebb4",
+ "reference": "afa00c500c2d6aea6e3b2f4862355f507bc5ebb4",
"shasum": ""
},
"require": {
- "php": ">=5.5.9"
- },
- "require-dev": {
- "psr/log": "~1.0",
- "symfony/config": "~2.8|~3.0",
- "symfony/dependency-injection": "~2.8|~3.0",
- "symfony/expression-language": "~2.8|~3.0",
- "symfony/stopwatch": "~2.8|~3.0"
+ "php": ">=7.1.3",
+ "psr/container": "^1.0"
},
"suggest": {
- "symfony/dependency-injection": "",
- "symfony/http-kernel": ""
+ "symfony/service-implementation": ""
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.1-dev"
+ "dev-main": "1.1-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
}
},
"autoload": {
"psr-4": {
- "Symfony\\Component\\EventDispatcher\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
+ "Symfony\\Contracts\\Service\\": ""
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -3385,44 +6443,92 @@
],
"authors": [
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony EventDispatcher Component",
+ "description": "Generic abstractions related to writing services",
"homepage": "https://symfony.com",
- "time": "2016-07-19 10:45:57"
+ "keywords": [
+ "abstractions",
+ "contracts",
+ "decoupling",
+ "interfaces",
+ "interoperability",
+ "standards"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/service-contracts/tree/v1.1.13"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-05-27T14:01:05+00:00"
},
{
- "name": "symfony/finder",
- "version": "v3.0.9",
+ "name": "symfony/translation",
+ "version": "v4.4.47",
"source": {
"type": "git",
- "url": "https://github.com/symfony/finder.git",
- "reference": "3eb4e64c6145ef8b92adefb618a74ebdde9e3fe9"
+ "url": "https://github.com/symfony/translation.git",
+ "reference": "45036b1d53accc48fe9bab71ccd86d57eba0dd94"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/finder/zipball/3eb4e64c6145ef8b92adefb618a74ebdde9e3fe9",
- "reference": "3eb4e64c6145ef8b92adefb618a74ebdde9e3fe9",
+ "url": "https://api.github.com/repos/symfony/translation/zipball/45036b1d53accc48fe9bab71ccd86d57eba0dd94",
+ "reference": "45036b1d53accc48fe9bab71ccd86d57eba0dd94",
"shasum": ""
},
"require": {
- "php": ">=5.5.9"
+ "php": ">=7.1.3",
+ "symfony/polyfill-mbstring": "~1.0",
+ "symfony/polyfill-php80": "^1.16",
+ "symfony/translation-contracts": "^1.1.6|^2"
},
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.0-dev"
- }
+ "conflict": {
+ "symfony/config": "<3.4",
+ "symfony/dependency-injection": "<3.4",
+ "symfony/http-kernel": "<4.4",
+ "symfony/yaml": "<3.4"
+ },
+ "provide": {
+ "symfony/translation-implementation": "1.0|2.0"
+ },
+ "require-dev": {
+ "psr/log": "^1|^2|^3",
+ "symfony/config": "^3.4|^4.0|^5.0",
+ "symfony/console": "^3.4|^4.0|^5.0",
+ "symfony/dependency-injection": "^3.4|^4.0|^5.0",
+ "symfony/finder": "~2.8|~3.0|~4.0|^5.0",
+ "symfony/http-kernel": "^4.4",
+ "symfony/intl": "^3.4|^4.0|^5.0",
+ "symfony/service-contracts": "^1.1.2|^2",
+ "symfony/yaml": "^3.4|^4.0|^5.0"
+ },
+ "suggest": {
+ "psr/log-implementation": "To use logging capability in translator",
+ "symfony/config": "",
+ "symfony/yaml": ""
},
+ "type": "library",
"autoload": {
"psr-4": {
- "Symfony\\Component\\Finder\\": ""
+ "Symfony\\Component\\Translation\\": ""
},
"exclude-from-classmap": [
"/Tests/"
@@ -3442,44 +6548,61 @@
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony Finder Component",
+ "description": "Provides tools to internationalize your application",
"homepage": "https://symfony.com",
- "time": "2016-06-29 05:40:00"
+ "support": {
+ "source": "https://github.com/symfony/translation/tree/v4.4.47"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-10-03T15:15:11+00:00"
},
{
- "name": "symfony/http-foundation",
- "version": "v3.0.9",
+ "name": "symfony/translation-contracts",
+ "version": "v1.1.13",
"source": {
"type": "git",
- "url": "https://github.com/symfony/http-foundation.git",
- "reference": "49ba00f8ede742169cb6b70abe33243f4d673f82"
+ "url": "https://github.com/symfony/translation-contracts.git",
+ "reference": "7462e5c4cb8b9cd152f992e8f10963b5641921f6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-foundation/zipball/49ba00f8ede742169cb6b70abe33243f4d673f82",
- "reference": "49ba00f8ede742169cb6b70abe33243f4d673f82",
+ "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/7462e5c4cb8b9cd152f992e8f10963b5641921f6",
+ "reference": "7462e5c4cb8b9cd152f992e8f10963b5641921f6",
"shasum": ""
},
"require": {
- "php": ">=5.5.9",
- "symfony/polyfill-mbstring": "~1.1"
+ "php": ">=7.1.3"
},
- "require-dev": {
- "symfony/expression-language": "~2.8|~3.0"
+ "suggest": {
+ "symfony/translation-implementation": ""
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.0-dev"
+ "dev-main": "1.1-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
}
},
"autoload": {
"psr-4": {
- "Symfony\\Component\\HttpFoundation\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
+ "Symfony\\Contracts\\Translation\\": ""
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -3487,77 +6610,88 @@
],
"authors": [
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony HttpFoundation Component",
+ "description": "Generic abstractions related to translation",
"homepage": "https://symfony.com",
- "time": "2016-07-17 13:54:30"
+ "keywords": [
+ "abstractions",
+ "contracts",
+ "decoupling",
+ "interfaces",
+ "interoperability",
+ "standards"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/translation-contracts/tree/v1.1.13"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-06-27T13:16:42+00:00"
},
{
- "name": "symfony/http-kernel",
- "version": "v3.0.9",
+ "name": "symfony/var-dumper",
+ "version": "v4.4.47",
"source": {
"type": "git",
- "url": "https://github.com/symfony/http-kernel.git",
- "reference": "d97ba4425e36e79c794e7d14ff36f00f081b37b3"
+ "url": "https://github.com/symfony/var-dumper.git",
+ "reference": "1069c7a3fca74578022fab6f81643248d02f8e63"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-kernel/zipball/d97ba4425e36e79c794e7d14ff36f00f081b37b3",
- "reference": "d97ba4425e36e79c794e7d14ff36f00f081b37b3",
+ "url": "https://api.github.com/repos/symfony/var-dumper/zipball/1069c7a3fca74578022fab6f81643248d02f8e63",
+ "reference": "1069c7a3fca74578022fab6f81643248d02f8e63",
"shasum": ""
},
"require": {
- "php": ">=5.5.9",
- "psr/log": "~1.0",
- "symfony/debug": "~2.8|~3.0",
- "symfony/event-dispatcher": "~2.8|~3.0",
- "symfony/http-foundation": "~2.8.8|~3.0.8|~3.1.2|~3.2"
+ "php": ">=7.1.3",
+ "symfony/polyfill-mbstring": "~1.0",
+ "symfony/polyfill-php72": "~1.5",
+ "symfony/polyfill-php80": "^1.16"
},
"conflict": {
- "symfony/config": "<2.8"
+ "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0",
+ "symfony/console": "<3.4"
},
"require-dev": {
- "symfony/browser-kit": "~2.8|~3.0",
- "symfony/class-loader": "~2.8|~3.0",
- "symfony/config": "~2.8|~3.0",
- "symfony/console": "~2.8|~3.0",
- "symfony/css-selector": "~2.8|~3.0",
- "symfony/dependency-injection": "~2.8|~3.0",
- "symfony/dom-crawler": "~2.8|~3.0",
- "symfony/expression-language": "~2.8|~3.0",
- "symfony/finder": "~2.8|~3.0",
- "symfony/process": "~2.8|~3.0",
- "symfony/routing": "~2.8|~3.0",
- "symfony/stopwatch": "~2.8|~3.0",
- "symfony/templating": "~2.8|~3.0",
- "symfony/translation": "~2.8|~3.0",
- "symfony/var-dumper": "~2.8|~3.0"
+ "ext-iconv": "*",
+ "symfony/console": "^3.4|^4.0|^5.0",
+ "symfony/process": "^4.4|^5.0",
+ "twig/twig": "^1.43|^2.13|^3.0.4"
},
"suggest": {
- "symfony/browser-kit": "",
- "symfony/class-loader": "",
- "symfony/config": "",
- "symfony/console": "",
- "symfony/dependency-injection": "",
- "symfony/finder": "",
- "symfony/var-dumper": ""
+ "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).",
+ "ext-intl": "To show region name in time zone dump",
+ "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script"
},
+ "bin": [
+ "Resources/bin/var-dump-server"
+ ],
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.0-dev"
- }
- },
"autoload": {
+ "files": [
+ "Resources/functions/dump.php"
+ ],
"psr-4": {
- "Symfony\\Component\\HttpKernel\\": ""
+ "Symfony\\Component\\VarDumper\\": ""
},
"exclude-from-classmap": [
"/Tests/"
@@ -3569,284 +6703,356 @@
],
"authors": [
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony HttpKernel Component",
+ "description": "Provides mechanisms for walking through any arbitrary PHP variable",
"homepage": "https://symfony.com",
- "time": "2016-07-30 09:10:37"
+ "keywords": [
+ "debug",
+ "dump"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/var-dumper/tree/v4.4.47"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-10-03T15:15:11+00:00"
},
{
- "name": "symfony/polyfill-mbstring",
- "version": "v1.2.0",
+ "name": "tijsverkoyen/css-to-inline-styles",
+ "version": "2.2.6",
"source": {
"type": "git",
- "url": "https://github.com/symfony/polyfill-mbstring.git",
- "reference": "dff51f72b0706335131b00a7f49606168c582594"
+ "url": "https://github.com/tijsverkoyen/CssToInlineStyles.git",
+ "reference": "c42125b83a4fa63b187fdf29f9c93cb7733da30c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/dff51f72b0706335131b00a7f49606168c582594",
- "reference": "dff51f72b0706335131b00a7f49606168c582594",
+ "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/c42125b83a4fa63b187fdf29f9c93cb7733da30c",
+ "reference": "c42125b83a4fa63b187fdf29f9c93cb7733da30c",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
+ "ext-dom": "*",
+ "ext-libxml": "*",
+ "php": "^5.5 || ^7.0 || ^8.0",
+ "symfony/css-selector": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0"
},
- "suggest": {
- "ext-mbstring": "For best performance"
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^7.5 || ^8.5.21 || ^9.5.10"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.2-dev"
+ "dev-master": "2.2.x-dev"
}
},
"autoload": {
"psr-4": {
- "Symfony\\Polyfill\\Mbstring\\": ""
- },
- "files": [
- "bootstrap.php"
- ]
+ "TijsVerkoyen\\CssToInlineStyles\\": "src"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
+ "name": "Tijs Verkoyen",
+ "email": "css_to_inline_styles@verkoyen.eu",
+ "role": "Developer"
}
],
- "description": "Symfony polyfill for the Mbstring extension",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "mbstring",
- "polyfill",
- "portable",
- "shim"
- ],
- "time": "2016-05-18 14:26:46"
+ "description": "CssToInlineStyles is a class that enables you to convert HTML-pages/files into HTML-pages/files with inline styles. This is very useful when you're sending emails.",
+ "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles",
+ "support": {
+ "issues": "https://github.com/tijsverkoyen/CssToInlineStyles/issues",
+ "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/2.2.6"
+ },
+ "time": "2023-01-03T09:29:04+00:00"
},
{
- "name": "symfony/polyfill-php56",
- "version": "v1.2.0",
+ "name": "twig/twig",
+ "version": "v2.15.5",
"source": {
"type": "git",
- "url": "https://github.com/symfony/polyfill-php56.git",
- "reference": "3edf57a8fbf9a927533344cef65ad7e1cf31030a"
+ "url": "https://github.com/twigphp/Twig.git",
+ "reference": "fc02a6af3eeb97c4bf5650debc76c2eda85ac22e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php56/zipball/3edf57a8fbf9a927533344cef65ad7e1cf31030a",
- "reference": "3edf57a8fbf9a927533344cef65ad7e1cf31030a",
+ "url": "https://api.github.com/repos/twigphp/Twig/zipball/fc02a6af3eeb97c4bf5650debc76c2eda85ac22e",
+ "reference": "fc02a6af3eeb97c4bf5650debc76c2eda85ac22e",
"shasum": ""
},
"require": {
- "php": ">=5.3.3",
- "symfony/polyfill-util": "~1.0"
+ "php": ">=7.1.3",
+ "symfony/polyfill-ctype": "^1.8",
+ "symfony/polyfill-mbstring": "^1.3",
+ "symfony/polyfill-php72": "^1.8"
+ },
+ "require-dev": {
+ "psr/container": "^1.0",
+ "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.2-dev"
+ "dev-master": "2.15-dev"
}
},
"autoload": {
- "psr-4": {
- "Symfony\\Polyfill\\Php56\\": ""
+ "psr-0": {
+ "Twig_": "lib/"
},
- "files": [
- "bootstrap.php"
- ]
+ "psr-4": {
+ "Twig\\": "src/"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
},
{
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
+ "name": "Twig Team",
+ "role": "Contributors"
+ },
+ {
+ "name": "Armin Ronacher",
+ "email": "armin.ronacher@active-4.com",
+ "role": "Project Founder"
}
],
- "description": "Symfony polyfill backporting some PHP 5.6+ features to lower PHP versions",
- "homepage": "https://symfony.com",
+ "description": "Twig, the flexible, fast, and secure template language for PHP",
+ "homepage": "https://twig.symfony.com",
"keywords": [
- "compatibility",
- "polyfill",
- "portable",
- "shim"
+ "templating"
+ ],
+ "support": {
+ "issues": "https://github.com/twigphp/Twig/issues",
+ "source": "https://github.com/twigphp/Twig/tree/v2.15.5"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/twig/twig",
+ "type": "tidelift"
+ }
],
- "time": "2016-05-18 14:26:46"
+ "time": "2023-05-03T17:49:41+00:00"
},
{
- "name": "symfony/polyfill-util",
- "version": "v1.2.0",
+ "name": "vlucas/phpdotenv",
+ "version": "v2.6.9",
"source": {
"type": "git",
- "url": "https://github.com/symfony/polyfill-util.git",
- "reference": "ef830ce3d218e622b221d6bfad42c751d974bf99"
+ "url": "https://github.com/vlucas/phpdotenv.git",
+ "reference": "2e93cc98e2e8e869f8d9cfa61bb3a99ba4fc4141"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-util/zipball/ef830ce3d218e622b221d6bfad42c751d974bf99",
- "reference": "ef830ce3d218e622b221d6bfad42c751d974bf99",
+ "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/2e93cc98e2e8e869f8d9cfa61bb3a99ba4fc4141",
+ "reference": "2e93cc98e2e8e869f8d9cfa61bb3a99ba4fc4141",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
+ "php": "^5.3.9 || ^7.0 || ^8.0",
+ "symfony/polyfill-ctype": "^1.17"
+ },
+ "require-dev": {
+ "ext-filter": "*",
+ "ext-pcre": "*",
+ "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.21"
+ },
+ "suggest": {
+ "ext-filter": "Required to use the boolean validator.",
+ "ext-pcre": "Required to use most of the library."
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.2-dev"
+ "dev-master": "2.6-dev"
}
},
"autoload": {
"psr-4": {
- "Symfony\\Polyfill\\Util\\": ""
+ "Dotenv\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
+ "name": "Graham Campbell",
+ "email": "hello@gjcampbell.co.uk",
+ "homepage": "https://github.com/GrahamCampbell"
},
{
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
+ "name": "Vance Lucas",
+ "email": "vance@vancelucas.com",
+ "homepage": "https://github.com/vlucas"
}
],
- "description": "Symfony utilities for portability of PHP codes",
- "homepage": "https://symfony.com",
+ "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.",
"keywords": [
- "compat",
- "compatibility",
- "polyfill",
- "shim"
+ "dotenv",
+ "env",
+ "environment"
+ ],
+ "support": {
+ "issues": "https://github.com/vlucas/phpdotenv/issues",
+ "source": "https://github.com/vlucas/phpdotenv/tree/v2.6.9"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/GrahamCampbell",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv",
+ "type": "tidelift"
+ }
],
- "time": "2016-05-18 14:26:46"
+ "time": "2021-12-12T22:59:22+00:00"
},
{
- "name": "symfony/process",
- "version": "v3.0.9",
+ "name": "zendframework/zend-diactoros",
+ "version": "2.2.1",
"source": {
"type": "git",
- "url": "https://github.com/symfony/process.git",
- "reference": "768debc5996f599c4372b322d9061dba2a4bf505"
+ "url": "https://github.com/zendframework/zend-diactoros.git",
+ "reference": "de5847b068362a88684a55b0dbb40d85986cfa52"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/process/zipball/768debc5996f599c4372b322d9061dba2a4bf505",
- "reference": "768debc5996f599c4372b322d9061dba2a4bf505",
+ "url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/de5847b068362a88684a55b0dbb40d85986cfa52",
+ "reference": "de5847b068362a88684a55b0dbb40d85986cfa52",
"shasum": ""
},
"require": {
- "php": ">=5.5.9"
+ "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-curl": "*",
+ "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": "3.0-dev"
+ "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": {
- "Symfony\\Component\\Process\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
+ "Zend\\Diactoros\\": "src/"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
+ "BSD-3-Clause"
],
- "description": "Symfony Process Component",
- "homepage": "https://symfony.com",
- "time": "2016-07-28 11:13:34"
- },
+ "description": "PSR HTTP Message implementations",
+ "keywords": [
+ "http",
+ "psr",
+ "psr-7"
+ ],
+ "support": {
+ "docs": "https://docs.zendframework.com/zend-diactoros/",
+ "forum": "https://discourse.zendframework.com/c/questions/exprssive",
+ "issues": "https://github.com/zendframework/zend-diactoros/issues",
+ "rss": "https://github.com/zendframework/zend-diactoros/releases.atom",
+ "slack": "https://zendframework-slack.herokuapp.com",
+ "source": "https://github.com/zendframework/zend-diactoros"
+ },
+ "abandoned": "laminas/laminas-diactoros",
+ "time": "2019-11-13T19:16:13+00:00"
+ }
+ ],
+ "packages-dev": [
{
- "name": "symfony/routing",
- "version": "v3.0.9",
+ "name": "alt-three/testbench",
+ "version": "5.0.x-dev",
"source": {
"type": "git",
- "url": "https://github.com/symfony/routing.git",
- "reference": "9038984bd9c05ab07280121e9e10f61a7231457b"
+ "url": "https://github.com/AltThree/TestBench.git",
+ "reference": "246d9744ec1cde265e5ea40c7cd4eebd5577b601"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/routing/zipball/9038984bd9c05ab07280121e9e10f61a7231457b",
- "reference": "9038984bd9c05ab07280121e9e10f61a7231457b",
+ "url": "https://api.github.com/repos/AltThree/TestBench/zipball/246d9744ec1cde265e5ea40c7cd4eebd5577b601",
+ "reference": "246d9744ec1cde265e5ea40c7cd4eebd5577b601",
"shasum": ""
},
"require": {
- "php": ">=5.5.9"
- },
- "conflict": {
- "symfony/config": "<2.8"
+ "graham-campbell/testbench-core": "^3.2",
+ "php": "^7.0 || ^8.0"
},
"require-dev": {
- "doctrine/annotations": "~1.0",
- "doctrine/common": "~2.2",
- "psr/log": "~1.0",
- "symfony/config": "~2.8|~3.0",
- "symfony/expression-language": "~2.8|~3.0",
- "symfony/http-foundation": "~2.8|~3.0",
- "symfony/yaml": "~2.8|~3.0"
+ "graham-campbell/analyzer": "^2.4 || ^3.0",
+ "phpunit/phpunit": "^6.5 || ^7.5 || ^8.4 || ^9.0"
},
"suggest": {
- "doctrine/annotations": "For using the annotation loader",
- "symfony/config": "For using the all-in-one router or any loader",
- "symfony/dependency-injection": "For loading routes from a service",
- "symfony/expression-language": "For using expression matching",
- "symfony/http-foundation": "For using a Symfony Request object",
- "symfony/yaml": "For using the YAML loader"
+ "laravel/framework": "Enables the use of most traits."
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.0-dev"
- }
- },
"autoload": {
"psr-4": {
- "Symfony\\Component\\Routing\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
+ "AltThree\\TestBench\\": "src/"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -3854,69 +7060,71 @@
],
"authors": [
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
+ "name": "Alt Three",
+ "email": "support@alt-three.com"
}
],
- "description": "Symfony Routing Component",
- "homepage": "https://symfony.com",
+ "description": "Provides some testing traits for apps",
"keywords": [
- "router",
- "routing",
- "uri",
- "url"
+ "Alt Three",
+ "TestBench",
+ "app"
],
- "time": "2016-06-29 05:40:00"
+ "support": {
+ "issues": "https://github.com/AltThree/TestBench/issues",
+ "source": "https://github.com/AltThree/TestBench/tree/5.0"
+ },
+ "abandoned": true,
+ "time": "2021-03-29T11:19:11+00:00"
},
{
- "name": "symfony/translation",
- "version": "v3.0.9",
+ "name": "barryvdh/laravel-debugbar",
+ "version": "v3.4.2",
"source": {
"type": "git",
- "url": "https://github.com/symfony/translation.git",
- "reference": "eee6c664853fd0576f21ae25725cfffeafe83f26"
+ "url": "https://github.com/barryvdh/laravel-debugbar.git",
+ "reference": "91ee8b3acf0d72a4937f4855bd245acbda9910ac"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/translation/zipball/eee6c664853fd0576f21ae25725cfffeafe83f26",
- "reference": "eee6c664853fd0576f21ae25725cfffeafe83f26",
+ "url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/91ee8b3acf0d72a4937f4855bd245acbda9910ac",
+ "reference": "91ee8b3acf0d72a4937f4855bd245acbda9910ac",
"shasum": ""
},
"require": {
- "php": ">=5.5.9",
- "symfony/polyfill-mbstring": "~1.0"
- },
- "conflict": {
- "symfony/config": "<2.8"
+ "illuminate/routing": "^5.5|^6|^7",
+ "illuminate/session": "^5.5|^6|^7",
+ "illuminate/support": "^5.5|^6|^7",
+ "maximebf/debugbar": "^1.16.3",
+ "php": ">=7.0",
+ "symfony/debug": "^3|^4|^5",
+ "symfony/finder": "^3|^4|^5"
},
"require-dev": {
- "psr/log": "~1.0",
- "symfony/config": "~2.8|~3.0",
- "symfony/intl": "~2.8|~3.0",
- "symfony/yaml": "~2.8|~3.0"
- },
- "suggest": {
- "psr/log": "To use logging capability in translator",
- "symfony/config": "",
- "symfony/yaml": ""
+ "orchestra/testbench": "^3.5|^4.0|^5.0",
+ "phpunit/phpunit": "^6.0|^7.0|^8.5|^9.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.0-dev"
+ "dev-master": "3.2-dev"
+ },
+ "laravel": {
+ "providers": [
+ "Barryvdh\\Debugbar\\ServiceProvider"
+ ],
+ "aliases": {
+ "Debugbar": "Barryvdh\\Debugbar\\Facade"
+ }
}
},
"autoload": {
+ "files": [
+ "src/helpers.php"
+ ],
"psr-4": {
- "Symfony\\Component\\Translation\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
+ "Barryvdh\\Debugbar\\": "src/"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -3924,58 +7132,62 @@
],
"authors": [
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
+ "name": "Barry vd. Heuvel",
+ "email": "barryvdh@gmail.com"
+ }
+ ],
+ "description": "PHP Debugbar integration for Laravel",
+ "keywords": [
+ "debug",
+ "debugbar",
+ "laravel",
+ "profiler",
+ "webprofiler"
+ ],
+ "support": {
+ "issues": "https://github.com/barryvdh/laravel-debugbar/issues",
+ "source": "https://github.com/barryvdh/laravel-debugbar/tree/3.4"
+ },
+ "funding": [
{
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
+ "url": "https://github.com/barryvdh",
+ "type": "github"
}
],
- "description": "Symfony Translation Component",
- "homepage": "https://symfony.com",
- "time": "2016-07-30 07:22:48"
+ "time": "2020-08-30T07:08:17+00:00"
},
{
- "name": "symfony/var-dumper",
- "version": "v3.0.9",
+ "name": "doctrine/instantiator",
+ "version": "1.5.0",
"source": {
"type": "git",
- "url": "https://github.com/symfony/var-dumper.git",
- "reference": "1f7e071aafc6676fcb6e3f0497f87c2397247377"
+ "url": "https://github.com/doctrine/instantiator.git",
+ "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/var-dumper/zipball/1f7e071aafc6676fcb6e3f0497f87c2397247377",
- "reference": "1f7e071aafc6676fcb6e3f0497f87c2397247377",
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b",
+ "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b",
"shasum": ""
},
"require": {
- "php": ">=5.5.9",
- "symfony/polyfill-mbstring": "~1.0"
+ "php": "^7.1 || ^8.0"
},
"require-dev": {
- "twig/twig": "~1.20|~2.0"
- },
- "suggest": {
- "ext-symfony_debug": ""
+ "doctrine/coding-standard": "^9 || ^11",
+ "ext-pdo": "*",
+ "ext-phar": "*",
+ "phpbench/phpbench": "^0.16 || ^1",
+ "phpstan/phpstan": "^1.4",
+ "phpstan/phpstan-phpunit": "^1",
+ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
+ "vimeo/psalm": "^4.30 || ^5.4"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.0-dev"
- }
- },
"autoload": {
- "files": [
- "Resources/functions/dump.php"
- ],
"psr-4": {
- "Symfony\\Component\\VarDumper\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
+ "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -3983,149 +7195,188 @@
],
"authors": [
{
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
+ "name": "Marco Pivetta",
+ "email": "ocramius@gmail.com",
+ "homepage": "https://ocramius.github.io/"
}
],
- "description": "Symfony mechanism for exploring and dumping PHP variables",
- "homepage": "https://symfony.com",
+ "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
+ "homepage": "https://www.doctrine-project.org/projects/instantiator.html",
"keywords": [
- "debug",
- "dump"
+ "constructor",
+ "instantiate"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/instantiator/issues",
+ "source": "https://github.com/doctrine/instantiator/tree/1.5.0"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator",
+ "type": "tidelift"
+ }
],
- "time": "2016-07-26 08:03:56"
+ "time": "2022-12-30T00:15:36+00:00"
},
{
- "name": "tijsverkoyen/css-to-inline-styles",
- "version": "1.5.5",
+ "name": "filp/whoops",
+ "version": "2.15.3",
"source": {
"type": "git",
- "url": "https://github.com/tijsverkoyen/CssToInlineStyles.git",
- "reference": "9753fc340726e327e4d48b7c0604f85475ae0bc3"
+ "url": "https://github.com/filp/whoops.git",
+ "reference": "c83e88a30524f9360b11f585f71e6b17313b7187"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/9753fc340726e327e4d48b7c0604f85475ae0bc3",
- "reference": "9753fc340726e327e4d48b7c0604f85475ae0bc3",
+ "url": "https://api.github.com/repos/filp/whoops/zipball/c83e88a30524f9360b11f585f71e6b17313b7187",
+ "reference": "c83e88a30524f9360b11f585f71e6b17313b7187",
"shasum": ""
},
"require": {
- "php": ">=5.3.0",
- "symfony/css-selector": "~2.1|~3.0"
+ "php": "^5.5.9 || ^7.0 || ^8.0",
+ "psr/log": "^1.0.1 || ^2.0 || ^3.0"
},
"require-dev": {
- "phpunit/phpunit": "~4.0"
+ "mockery/mockery": "^0.9 || ^1.0",
+ "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.3",
+ "symfony/var-dumper": "^2.6 || ^3.0 || ^4.0 || ^5.0"
+ },
+ "suggest": {
+ "symfony/var-dumper": "Pretty print complex values better with var-dumper available",
+ "whoops/soap": "Formats errors as SOAP responses"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.5.x-dev"
+ "dev-master": "2.7-dev"
}
},
"autoload": {
"psr-4": {
- "TijsVerkoyen\\CssToInlineStyles\\": "src"
+ "Whoops\\": "src/Whoops/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD"
+ "MIT"
],
"authors": [
{
- "name": "Tijs Verkoyen",
- "email": "css_to_inline_styles@verkoyen.eu",
+ "name": "Filipe Dobreira",
+ "homepage": "https://github.com/filp",
"role": "Developer"
}
],
- "description": "CssToInlineStyles is a class that enables you to convert HTML-pages/files into HTML-pages/files with inline styles. This is very useful when you're sending emails.",
- "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles",
- "time": "2015-12-08 16:14:14"
+ "description": "php error handling for cool kids",
+ "homepage": "https://filp.github.io/whoops/",
+ "keywords": [
+ "error",
+ "exception",
+ "handling",
+ "library",
+ "throwable",
+ "whoops"
+ ],
+ "support": {
+ "issues": "https://github.com/filp/whoops/issues",
+ "source": "https://github.com/filp/whoops/tree/2.15.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/denis-sokolov",
+ "type": "github"
+ }
+ ],
+ "time": "2023-07-13T12:00:00+00:00"
},
{
- "name": "twig/twig",
- "version": "v1.24.2",
+ "name": "fzaninotto/faker",
+ "version": "v1.9.2",
"source": {
"type": "git",
- "url": "https://github.com/twigphp/Twig.git",
- "reference": "33093f6e310e6976baeac7b14f3a6ec02f2d79b7"
+ "url": "https://github.com/fzaninotto/Faker.git",
+ "reference": "848d8125239d7dbf8ab25cb7f054f1a630e68c2e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/twigphp/Twig/zipball/33093f6e310e6976baeac7b14f3a6ec02f2d79b7",
- "reference": "33093f6e310e6976baeac7b14f3a6ec02f2d79b7",
+ "url": "https://api.github.com/repos/fzaninotto/Faker/zipball/848d8125239d7dbf8ab25cb7f054f1a630e68c2e",
+ "reference": "848d8125239d7dbf8ab25cb7f054f1a630e68c2e",
"shasum": ""
},
"require": {
- "php": ">=5.2.7"
+ "php": "^5.3.3 || ^7.0"
},
"require-dev": {
- "symfony/debug": "~2.7",
- "symfony/phpunit-bridge": "~2.7"
+ "ext-intl": "*",
+ "phpunit/phpunit": "^4.8.35 || ^5.7",
+ "squizlabs/php_codesniffer": "^2.9.2"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.24-dev"
+ "dev-master": "1.9-dev"
}
},
"autoload": {
- "psr-0": {
- "Twig_": "lib/"
+ "psr-4": {
+ "Faker\\": "src/Faker/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-3-Clause"
+ "MIT"
],
"authors": [
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com",
- "homepage": "http://fabien.potencier.org",
- "role": "Lead Developer"
- },
- {
- "name": "Armin Ronacher",
- "email": "armin.ronacher@active-4.com",
- "role": "Project Founder"
- },
- {
- "name": "Twig Team",
- "homepage": "http://twig.sensiolabs.org/contributors",
- "role": "Contributors"
+ "name": "François Zaninotto"
}
],
- "description": "Twig, the flexible, fast, and secure template language for PHP",
- "homepage": "http://twig.sensiolabs.org",
+ "description": "Faker is a PHP library that generates fake data for you.",
"keywords": [
- "templating"
+ "data",
+ "faker",
+ "fixtures"
],
- "time": "2016-09-01 17:50:53"
+ "support": {
+ "issues": "https://github.com/fzaninotto/Faker/issues",
+ "source": "https://github.com/fzaninotto/Faker/tree/v1.9.2"
+ },
+ "abandoned": true,
+ "time": "2020-12-11T09:56:16+00:00"
},
{
- "name": "vlucas/phpdotenv",
- "version": "v2.4.0",
+ "name": "graham-campbell/analyzer",
+ "version": "v2.4.3",
"source": {
"type": "git",
- "url": "https://github.com/vlucas/phpdotenv.git",
- "reference": "3cc116adbe4b11be5ec557bf1d24dc5e3a21d18c"
+ "url": "https://github.com/GrahamCampbell/Analyzer.git",
+ "reference": "baecd15b7e1185075a8db63ca1806c555cd60bc8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/3cc116adbe4b11be5ec557bf1d24dc5e3a21d18c",
- "reference": "3cc116adbe4b11be5ec557bf1d24dc5e3a21d18c",
+ "url": "https://api.github.com/repos/GrahamCampbell/Analyzer/zipball/baecd15b7e1185075a8db63ca1806c555cd60bc8",
+ "reference": "baecd15b7e1185075a8db63ca1806c555cd60bc8",
"shasum": ""
},
"require": {
- "php": ">=5.3.9"
+ "nikic/php-parser": "^3.0|^4.0",
+ "php": "^7.0|^8.0",
+ "phpdocumentor/reflection-docblock": "^4.2",
+ "phpdocumentor/type-resolver": "~0.4|^1.0"
},
"require-dev": {
- "phpunit/phpunit": "^4.8 || ^5.0"
+ "phpunit/phpunit": "^6.5|^7.5|^8.4|^9.0"
+ },
+ "suggest": {
+ "phpunit/phpunit": "Required to use the analysis trait."
},
"type": "library",
"extra": {
@@ -4135,65 +7386,74 @@
},
"autoload": {
"psr-4": {
- "Dotenv\\": "src/"
+ "GrahamCampbell\\Analyzer\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-3-Clause-Attribution"
+ "MIT"
],
"authors": [
{
- "name": "Vance Lucas",
- "email": "vance@vancelucas.com",
- "homepage": "http://www.vancelucas.com"
+ "name": "Graham Campbell",
+ "email": "graham@alt-three.com"
}
],
- "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.",
+ "description": "Checks if referenced classes really exist.",
"keywords": [
- "dotenv",
- "env",
- "environment"
+ "Graham Campbell",
+ "GrahamCampbell",
+ "analysis",
+ "analyzer",
+ "classes",
+ "testing"
],
- "time": "2016-09-01 10:05:43"
- }
- ],
- "packages-dev": [
+ "support": {
+ "issues": "https://github.com/GrahamCampbell/Analyzer/issues",
+ "source": "https://github.com/GrahamCampbell/Analyzer/tree/v2.4.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/GrahamCampbell",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/graham-campbell/analyzer",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2020-05-02T14:42:06+00:00"
+ },
{
- "name": "alt-three/testbench",
- "version": "v1.9.0",
+ "name": "graham-campbell/testbench-core",
+ "version": "v3.4.1",
"source": {
"type": "git",
- "url": "https://github.com/AltThree/TestBench.git",
- "reference": "51b9d3aa9b2cd6d00ee72e018089df4c60913825"
+ "url": "https://github.com/GrahamCampbell/Laravel-TestBench-Core.git",
+ "reference": "f62a3d0200cbea9f8156ac2cd7d16684ad324c8d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/AltThree/TestBench/zipball/51b9d3aa9b2cd6d00ee72e018089df4c60913825",
- "reference": "51b9d3aa9b2cd6d00ee72e018089df4c60913825",
+ "url": "https://api.github.com/repos/GrahamCampbell/Laravel-TestBench-Core/zipball/f62a3d0200cbea9f8156ac2cd7d16684ad324c8d",
+ "reference": "f62a3d0200cbea9f8156ac2cd7d16684ad324c8d",
"shasum": ""
},
"require": {
- "graham-campbell/testbench-core": "^1.1",
- "php": ">=5.5.9"
+ "php": "^7.0 || ^8.0"
},
"require-dev": {
- "nikic/php-parser": "^2.0",
- "phpunit/phpunit": "^4.8|^5.0"
+ "graham-campbell/analyzer": "^2.4 || ^3.0",
+ "phpunit/phpunit": "^6.5 || ^7.5 || ^8.0 || ^9.0 || ^10.0"
},
"suggest": {
- "laravel/framework": "Enables the use of every trait.",
- "nikic/php-parser": "Enables the use of the static analyzer."
+ "illuminate/support": "Required to use the laravel trait.",
+ "mockery/mockery": "Required to use the mockery trait.",
+ "phpunit/phpunit": "Required to use the most of the features."
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.9-dev"
- }
- },
"autoload": {
"psr-4": {
- "AltThree\\TestBench\\": "src/"
+ "GrahamCampbell\\TestBenchCore\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -4201,116 +7461,128 @@
"MIT"
],
"authors": [
- {
- "name": "James Brooks",
- "email": "james@alt-three.com"
- },
{
"name": "Graham Campbell",
- "email": "graham@alt-three.com"
- },
- {
- "name": "Joseph Cohen",
- "email": "joe@alt-three.com"
+ "email": "hello@gjcampbell.co.uk",
+ "homepage": "https://github.com/GrahamCampbell"
}
],
- "description": "Provides Some Testing Traits For Apps",
+ "description": "TestBench Core Provides Some Testing Functionality For Laravel",
"keywords": [
- "Alt Three",
+ "Graham Campbell",
+ "GrahamCampbell",
+ "Laravel TestBench Core",
+ "Laravel-TestBench-Core",
"TestBench",
- "app"
+ "framework",
+ "laravel",
+ "testbench-core",
+ "testing"
+ ],
+ "support": {
+ "issues": "https://github.com/GrahamCampbell/Laravel-TestBench-Core/issues",
+ "source": "https://github.com/GrahamCampbell/Laravel-TestBench-Core/tree/v3.4.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/GrahamCampbell",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/graham-campbell/testbench-core",
+ "type": "tidelift"
+ }
],
- "time": "2016-08-25 14:09:25"
+ "time": "2023-02-25T15:19:33+00:00"
},
{
- "name": "doctrine/instantiator",
- "version": "1.0.5",
+ "name": "hamcrest/hamcrest-php",
+ "version": "v2.0.1",
"source": {
"type": "git",
- "url": "https://github.com/doctrine/instantiator.git",
- "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d"
+ "url": "https://github.com/hamcrest/hamcrest-php.git",
+ "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d",
- "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d",
+ "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/8c3d0a3f6af734494ad8f6fbbee0ba92422859f3",
+ "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3",
"shasum": ""
},
"require": {
- "php": ">=5.3,<8.0-DEV"
+ "php": "^5.3|^7.0|^8.0"
+ },
+ "replace": {
+ "cordoval/hamcrest-php": "*",
+ "davedevelopment/hamcrest-php": "*",
+ "kodova/hamcrest-php": "*"
},
"require-dev": {
- "athletic/athletic": "~0.1.8",
- "ext-pdo": "*",
- "ext-phar": "*",
- "phpunit/phpunit": "~4.0",
- "squizlabs/php_codesniffer": "~2.0"
+ "phpunit/php-file-iterator": "^1.4 || ^2.0",
+ "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0.x-dev"
+ "dev-master": "2.1-dev"
}
},
"autoload": {
- "psr-4": {
- "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
- }
+ "classmap": [
+ "hamcrest"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Marco Pivetta",
- "email": "ocramius@gmail.com",
- "homepage": "http://ocramius.github.com/"
- }
+ "BSD-3-Clause"
],
- "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
- "homepage": "https://github.com/doctrine/instantiator",
+ "description": "This is the PHP port of Hamcrest Matchers",
"keywords": [
- "constructor",
- "instantiate"
+ "test"
],
- "time": "2015-06-14 21:17:01"
+ "support": {
+ "issues": "https://github.com/hamcrest/hamcrest-php/issues",
+ "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.0.1"
+ },
+ "time": "2020-07-09T08:09:16+00:00"
},
{
- "name": "filp/whoops",
- "version": "2.1.3",
+ "name": "maximebf/debugbar",
+ "version": "v1.19.1",
"source": {
"type": "git",
- "url": "https://github.com/filp/whoops.git",
- "reference": "8828aaa2178e0a19325522e2a45282ff0a14649b"
+ "url": "https://github.com/maximebf/php-debugbar.git",
+ "reference": "03dd40a1826f4d585ef93ef83afa2a9874a00523"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/filp/whoops/zipball/8828aaa2178e0a19325522e2a45282ff0a14649b",
- "reference": "8828aaa2178e0a19325522e2a45282ff0a14649b",
+ "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/03dd40a1826f4d585ef93ef83afa2a9874a00523",
+ "reference": "03dd40a1826f4d585ef93ef83afa2a9874a00523",
"shasum": ""
},
"require": {
- "php": ">=5.5.9"
+ "php": "^7.1|^8",
+ "psr/log": "^1|^2|^3",
+ "symfony/var-dumper": "^4|^5|^6"
},
"require-dev": {
- "mockery/mockery": "0.9.*",
- "phpunit/phpunit": "^4.8 || ^5.0",
- "symfony/var-dumper": "~3.0"
+ "phpunit/phpunit": ">=7.5.20 <10.0",
+ "twig/twig": "^1.38|^2.7|^3.0"
},
"suggest": {
- "symfony/var-dumper": "Pretty print complex values better with var-dumper available",
- "whoops/soap": "Formats errors as SOAP responses"
+ "kriswallsmith/assetic": "The best way to manage assets",
+ "monolog/monolog": "Log using Monolog",
+ "predis/predis": "Redis storage"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.0-dev"
+ "dev-master": "1.18-dev"
}
},
"autoload": {
"psr-4": {
- "Whoops\\": "src/Whoops/"
+ "DebugBar\\": "src/DebugBar/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -4319,208 +7591,236 @@
],
"authors": [
{
- "name": "Filipe Dobreira",
- "homepage": "https://github.com/filp",
- "role": "Developer"
+ "name": "Maxime Bouroumeau-Fuseau",
+ "email": "maxime.bouroumeau@gmail.com",
+ "homepage": "http://maximebf.com"
+ },
+ {
+ "name": "Barry vd. Heuvel",
+ "email": "barryvdh@gmail.com"
}
],
- "description": "php error handling for cool kids",
- "homepage": "https://github.com/filp/whoops",
+ "description": "Debug bar in the browser for php application",
+ "homepage": "https://github.com/maximebf/php-debugbar",
"keywords": [
- "error",
- "exception",
- "handling",
- "library",
- "whoops",
- "zf2"
+ "debug",
+ "debugbar"
],
- "time": "2016-05-06 18:25:35"
+ "support": {
+ "issues": "https://github.com/maximebf/php-debugbar/issues",
+ "source": "https://github.com/maximebf/php-debugbar/tree/v1.19.1"
+ },
+ "time": "2023-10-12T08:10:52+00:00"
},
{
- "name": "fzaninotto/faker",
- "version": "v1.6.0",
+ "name": "mockery/mockery",
+ "version": "1.3.6",
"source": {
"type": "git",
- "url": "https://github.com/fzaninotto/Faker.git",
- "reference": "44f9a286a04b80c76a4e5fb7aad8bb539b920123"
+ "url": "https://github.com/mockery/mockery.git",
+ "reference": "dc206df4fa314a50bbb81cf72239a305c5bbd5c0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/fzaninotto/Faker/zipball/44f9a286a04b80c76a4e5fb7aad8bb539b920123",
- "reference": "44f9a286a04b80c76a4e5fb7aad8bb539b920123",
+ "url": "https://api.github.com/repos/mockery/mockery/zipball/dc206df4fa314a50bbb81cf72239a305c5bbd5c0",
+ "reference": "dc206df4fa314a50bbb81cf72239a305c5bbd5c0",
"shasum": ""
},
"require": {
- "php": "^5.3.3|^7.0"
+ "hamcrest/hamcrest-php": "^2.0.1",
+ "lib-pcre": ">=7.0",
+ "php": ">=5.6.0"
},
"require-dev": {
- "ext-intl": "*",
- "phpunit/phpunit": "~4.0",
- "squizlabs/php_codesniffer": "~1.5"
+ "phpunit/phpunit": "^5.7.10|^6.5|^7.5|^8.5|^9.3"
},
"type": "library",
"extra": {
- "branch-alias": []
+ "branch-alias": {
+ "dev-master": "1.3.x-dev"
+ }
},
"autoload": {
- "psr-4": {
- "Faker\\": "src/Faker/"
+ "psr-0": {
+ "Mockery": "library/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "François Zaninotto"
+ "name": "Pádraic Brady",
+ "email": "padraic.brady@gmail.com",
+ "homepage": "http://blog.astrumfutura.com"
+ },
+ {
+ "name": "Dave Marshall",
+ "email": "dave.marshall@atstsolutions.co.uk",
+ "homepage": "http://davedevelopment.co.uk"
}
],
- "description": "Faker is a PHP library that generates fake data for you.",
+ "description": "Mockery is a simple yet flexible PHP mock object framework",
+ "homepage": "https://github.com/mockery/mockery",
"keywords": [
- "data",
- "faker",
- "fixtures"
+ "BDD",
+ "TDD",
+ "library",
+ "mock",
+ "mock objects",
+ "mockery",
+ "stub",
+ "test",
+ "test double",
+ "testing"
],
- "time": "2016-04-29 12:21:54"
+ "support": {
+ "issues": "https://github.com/mockery/mockery/issues",
+ "source": "https://github.com/mockery/mockery/tree/1.3.6"
+ },
+ "time": "2022-09-07T15:05:49+00:00"
},
{
- "name": "graham-campbell/testbench-core",
- "version": "v1.1.1",
+ "name": "myclabs/deep-copy",
+ "version": "1.11.1",
"source": {
"type": "git",
- "url": "https://github.com/GrahamCampbell/Laravel-TestBench-Core.git",
- "reference": "407e8cff5568ab95c4788ed5f7633e54be712de1"
+ "url": "https://github.com/myclabs/DeepCopy.git",
+ "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/GrahamCampbell/Laravel-TestBench-Core/zipball/407e8cff5568ab95c4788ed5f7633e54be712de1",
- "reference": "407e8cff5568ab95c4788ed5f7633e54be712de1",
+ "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c",
+ "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c",
"shasum": ""
},
"require": {
- "php": ">=5.5.9"
+ "php": "^7.1 || ^8.0"
},
- "require-dev": {
- "phpunit/phpunit": "^4.8|^5.0"
+ "conflict": {
+ "doctrine/collections": "<1.6.8",
+ "doctrine/common": "<2.13.3 || >=3,<3.2.2"
},
- "suggest": {
- "illuminate/support": "Required to use the laravel trait.",
- "mockery/mockery": "Required to use the mockery trait.",
- "phpunit/phpunit": "Required to use the most of the features."
+ "require-dev": {
+ "doctrine/collections": "^1.6.8",
+ "doctrine/common": "^2.13.3 || ^3.2.2",
+ "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.1-dev"
- }
- },
"autoload": {
+ "files": [
+ "src/DeepCopy/deep_copy.php"
+ ],
"psr-4": {
- "GrahamCampbell\\TestBenchCore\\": "src/"
+ "DeepCopy\\": "src/DeepCopy/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
- "authors": [
+ "description": "Create deep copies (clones) of your objects",
+ "keywords": [
+ "clone",
+ "copy",
+ "duplicate",
+ "object",
+ "object graph"
+ ],
+ "support": {
+ "issues": "https://github.com/myclabs/DeepCopy/issues",
+ "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1"
+ },
+ "funding": [
{
- "name": "Graham Campbell",
- "email": "graham@alt-three.com"
+ "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
+ "type": "tidelift"
}
],
- "description": "TestBench Core Provides Some Testing Functionality For Laravel 5",
- "keywords": [
- "Graham Campbell",
- "GrahamCampbell",
- "Laravel TestBench Core",
- "Laravel-TestBench-Core",
- "TestBench",
- "framework",
- "laravel",
- "testbench-core",
- "testing"
- ],
- "time": "2016-01-30 13:57:27"
+ "time": "2023-03-08T13:26:56+00:00"
},
{
- "name": "hamcrest/hamcrest-php",
- "version": "v1.2.2",
+ "name": "phar-io/manifest",
+ "version": "1.0.3",
"source": {
"type": "git",
- "url": "https://github.com/hamcrest/hamcrest-php.git",
- "reference": "b37020aa976fa52d3de9aa904aa2522dc518f79c"
+ "url": "https://github.com/phar-io/manifest.git",
+ "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/b37020aa976fa52d3de9aa904aa2522dc518f79c",
- "reference": "b37020aa976fa52d3de9aa904aa2522dc518f79c",
+ "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4",
+ "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4",
"shasum": ""
},
"require": {
- "php": ">=5.3.2"
- },
- "replace": {
- "cordoval/hamcrest-php": "*",
- "davedevelopment/hamcrest-php": "*",
- "kodova/hamcrest-php": "*"
- },
- "require-dev": {
- "phpunit/php-file-iterator": "1.3.3",
- "satooshi/php-coveralls": "dev-master"
+ "ext-dom": "*",
+ "ext-phar": "*",
+ "phar-io/version": "^2.0",
+ "php": "^5.6 || ^7.0"
},
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
"autoload": {
"classmap": [
- "hamcrest"
- ],
- "files": [
- "hamcrest/Hamcrest.php"
+ "src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD"
+ "BSD-3-Clause"
],
- "description": "This is the PHP port of Hamcrest Matchers",
- "keywords": [
- "test"
+ "authors": [
+ {
+ "name": "Arne Blankerts",
+ "email": "arne@blankerts.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Heuer",
+ "email": "sebastian@phpeople.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "Developer"
+ }
],
- "time": "2015-05-11 14:41:42"
+ "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
+ "support": {
+ "issues": "https://github.com/phar-io/manifest/issues",
+ "source": "https://github.com/phar-io/manifest/tree/master"
+ },
+ "time": "2018-07-08T19:23:20+00:00"
},
{
- "name": "mockery/mockery",
- "version": "0.9.5",
+ "name": "phar-io/version",
+ "version": "2.0.1",
"source": {
"type": "git",
- "url": "https://github.com/padraic/mockery.git",
- "reference": "4db079511a283e5aba1b3c2fb19037c645e70fc2"
+ "url": "https://github.com/phar-io/version.git",
+ "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/padraic/mockery/zipball/4db079511a283e5aba1b3c2fb19037c645e70fc2",
- "reference": "4db079511a283e5aba1b3c2fb19037c645e70fc2",
+ "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6",
+ "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6",
"shasum": ""
},
"require": {
- "hamcrest/hamcrest-php": "~1.1",
- "lib-pcre": ">=7.0",
- "php": ">=5.3.2"
- },
- "require-dev": {
- "phpunit/phpunit": "~4.0"
+ "php": "^5.6 || ^7.0"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "0.9.x-dev"
- }
- },
"autoload": {
- "psr-0": {
- "Mockery": "library/"
- }
+ "classmap": [
+ "src/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -4528,63 +7828,54 @@
],
"authors": [
{
- "name": "Pádraic Brady",
- "email": "padraic.brady@gmail.com",
- "homepage": "http://blog.astrumfutura.com"
+ "name": "Arne Blankerts",
+ "email": "arne@blankerts.de",
+ "role": "Developer"
},
{
- "name": "Dave Marshall",
- "email": "dave.marshall@atstsolutions.co.uk",
- "homepage": "http://davedevelopment.co.uk"
+ "name": "Sebastian Heuer",
+ "email": "sebastian@phpeople.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "Developer"
}
],
- "description": "Mockery is a simple yet flexible PHP mock object framework for use in unit testing with PHPUnit, PHPSpec or any other testing framework. Its core goal is to offer a test double framework with a succinct API capable of clearly defining all possible object operations and interactions using a human readable Domain Specific Language (DSL). Designed as a drop in alternative to PHPUnit's phpunit-mock-objects library, Mockery is easy to integrate with PHPUnit and can operate alongside phpunit-mock-objects without the World ending.",
- "homepage": "http://github.com/padraic/mockery",
- "keywords": [
- "BDD",
- "TDD",
- "library",
- "mock",
- "mock objects",
- "mockery",
- "stub",
- "test",
- "test double",
- "testing"
- ],
- "time": "2016-05-22 21:52:33"
+ "description": "Library for handling version information and constraints",
+ "support": {
+ "issues": "https://github.com/phar-io/version/issues",
+ "source": "https://github.com/phar-io/version/tree/master"
+ },
+ "time": "2018-07-08T19:19:57+00:00"
},
{
"name": "phpdocumentor/reflection-common",
- "version": "1.0",
+ "version": "2.1.0",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/ReflectionCommon.git",
- "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c"
+ "reference": "6568f4687e5b41b054365f9ae03fcb1ed5f2069b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
- "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/6568f4687e5b41b054365f9ae03fcb1ed5f2069b",
+ "reference": "6568f4687e5b41b054365f9ae03fcb1ed5f2069b",
"shasum": ""
},
"require": {
- "php": ">=5.5"
- },
- "require-dev": {
- "phpunit/phpunit": "^4.6"
+ "php": ">=7.1"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0.x-dev"
+ "dev-master": "2.x-dev"
}
},
"autoload": {
"psr-4": {
- "phpDocumentor\\Reflection\\": [
- "src"
- ]
+ "phpDocumentor\\Reflection\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -4606,33 +7897,44 @@
"reflection",
"static analysis"
],
- "time": "2015-12-27 11:43:31"
+ "support": {
+ "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues",
+ "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/master"
+ },
+ "time": "2020-04-27T09:25:28+00:00"
},
{
"name": "phpdocumentor/reflection-docblock",
- "version": "3.1.0",
+ "version": "4.3.4",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
- "reference": "9270140b940ff02e58ec577c237274e92cd40cdd"
+ "reference": "da3fd972d6bafd628114f7e7e036f45944b62e9c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/9270140b940ff02e58ec577c237274e92cd40cdd",
- "reference": "9270140b940ff02e58ec577c237274e92cd40cdd",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/da3fd972d6bafd628114f7e7e036f45944b62e9c",
+ "reference": "da3fd972d6bafd628114f7e7e036f45944b62e9c",
"shasum": ""
},
"require": {
- "php": ">=5.5",
- "phpdocumentor/reflection-common": "^1.0@dev",
- "phpdocumentor/type-resolver": "^0.2.0",
+ "php": "^7.0",
+ "phpdocumentor/reflection-common": "^1.0.0 || ^2.0.0",
+ "phpdocumentor/type-resolver": "~0.4 || ^1.0.0",
"webmozart/assert": "^1.0"
},
"require-dev": {
- "mockery/mockery": "^0.9.4",
- "phpunit/phpunit": "^4.4"
+ "doctrine/instantiator": "^1.0.5",
+ "mockery/mockery": "^1.0",
+ "phpdocumentor/type-resolver": "0.4.*",
+ "phpunit/phpunit": "^6.4"
},
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.x-dev"
+ }
+ },
"autoload": {
"psr-4": {
"phpDocumentor\\Reflection\\": [
@@ -4651,41 +7953,44 @@
}
],
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
- "time": "2016-06-10 09:48:41"
+ "support": {
+ "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
+ "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/release/4.x"
+ },
+ "time": "2019-12-28T18:55:12+00:00"
},
{
"name": "phpdocumentor/type-resolver",
- "version": "0.2",
+ "version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/TypeResolver.git",
- "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443"
+ "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/b39c7a5b194f9ed7bd0dd345c751007a41862443",
- "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443",
+ "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/2e32a6d48972b2c1976ed5d8967145b6cec4a4a9",
+ "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9",
"shasum": ""
},
"require": {
- "php": ">=5.5",
- "phpdocumentor/reflection-common": "^1.0"
+ "php": "^7.1",
+ "phpdocumentor/reflection-common": "^2.0"
},
"require-dev": {
- "mockery/mockery": "^0.9.4",
- "phpunit/phpunit": "^5.2||^4.8.24"
+ "ext-tokenizer": "^7.1",
+ "mockery/mockery": "~1",
+ "phpunit/phpunit": "^7.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0.x-dev"
+ "dev-master": "1.x-dev"
}
},
"autoload": {
"psr-4": {
- "phpDocumentor\\Reflection\\": [
- "src/"
- ]
+ "phpDocumentor\\Reflection\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -4698,41 +8003,47 @@
"email": "me@mikevanriel.com"
}
],
- "time": "2016-06-10 07:14:17"
+ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
+ "support": {
+ "issues": "https://github.com/phpDocumentor/TypeResolver/issues",
+ "source": "https://github.com/phpDocumentor/TypeResolver/tree/0.7.2"
+ },
+ "time": "2019-08-22T18:11:29+00:00"
},
{
"name": "phpspec/prophecy",
- "version": "v1.6.1",
+ "version": "v1.10.3",
"source": {
"type": "git",
"url": "https://github.com/phpspec/prophecy.git",
- "reference": "58a8137754bc24b25740d4281399a4a3596058e0"
+ "reference": "451c3cd1418cf640de218914901e51b064abb093"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpspec/prophecy/zipball/58a8137754bc24b25740d4281399a4a3596058e0",
- "reference": "58a8137754bc24b25740d4281399a4a3596058e0",
+ "url": "https://api.github.com/repos/phpspec/prophecy/zipball/451c3cd1418cf640de218914901e51b064abb093",
+ "reference": "451c3cd1418cf640de218914901e51b064abb093",
"shasum": ""
},
"require": {
"doctrine/instantiator": "^1.0.2",
"php": "^5.3|^7.0",
- "phpdocumentor/reflection-docblock": "^2.0|^3.0.2",
- "sebastian/comparator": "^1.1",
- "sebastian/recursion-context": "^1.0"
+ "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0",
+ "sebastian/comparator": "^1.2.3|^2.0|^3.0|^4.0",
+ "sebastian/recursion-context": "^1.0|^2.0|^3.0|^4.0"
},
"require-dev": {
- "phpspec/phpspec": "^2.0"
+ "phpspec/phpspec": "^2.5 || ^3.2",
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.6.x-dev"
+ "dev-master": "1.10.x-dev"
}
},
"autoload": {
- "psr-0": {
- "Prophecy\\": "src/"
+ "psr-4": {
+ "Prophecy\\": "src/Prophecy"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -4760,43 +8071,48 @@
"spy",
"stub"
],
- "time": "2016-06-07 08:13:47"
+ "support": {
+ "issues": "https://github.com/phpspec/prophecy/issues",
+ "source": "https://github.com/phpspec/prophecy/tree/v1.10.3"
+ },
+ "time": "2020-03-05T15:02:03+00:00"
},
{
"name": "phpunit/php-code-coverage",
- "version": "2.2.4",
+ "version": "6.1.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
- "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979"
+ "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979",
- "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/807e6013b00af69b6c5d9ceb4282d0393dbb9d8d",
+ "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d",
"shasum": ""
},
"require": {
- "php": ">=5.3.3",
- "phpunit/php-file-iterator": "~1.3",
- "phpunit/php-text-template": "~1.2",
- "phpunit/php-token-stream": "~1.3",
- "sebastian/environment": "^1.3.2",
- "sebastian/version": "~1.0"
+ "ext-dom": "*",
+ "ext-xmlwriter": "*",
+ "php": "^7.1",
+ "phpunit/php-file-iterator": "^2.0",
+ "phpunit/php-text-template": "^1.2.1",
+ "phpunit/php-token-stream": "^3.0",
+ "sebastian/code-unit-reverse-lookup": "^1.0.1",
+ "sebastian/environment": "^3.1 || ^4.0",
+ "sebastian/version": "^2.0.1",
+ "theseer/tokenizer": "^1.1"
},
"require-dev": {
- "ext-xdebug": ">=2.1.4",
- "phpunit/phpunit": "~4"
+ "phpunit/phpunit": "^7.0"
},
"suggest": {
- "ext-dom": "*",
- "ext-xdebug": ">=2.2.1",
- "ext-xmlwriter": "*"
+ "ext-xdebug": "^2.6.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.2.x-dev"
+ "dev-master": "6.1-dev"
}
},
"autoload": {
@@ -4811,7 +8127,7 @@
"authors": [
{
"name": "Sebastian Bergmann",
- "email": "sb@sebastian-bergmann.de",
+ "email": "sebastian@phpunit.de",
"role": "lead"
}
],
@@ -4822,29 +8138,36 @@
"testing",
"xunit"
],
- "time": "2015-10-06 15:47:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
+ "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/master"
+ },
+ "time": "2018-10-31T16:06:48+00:00"
},
{
"name": "phpunit/php-file-iterator",
- "version": "1.4.1",
+ "version": "2.0.5",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-file-iterator.git",
- "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0"
+ "reference": "42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0",
- "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5",
+ "reference": "42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
+ "php": ">=7.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^8.5"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.4.x-dev"
+ "dev-master": "2.0.x-dev"
}
},
"autoload": {
@@ -4859,7 +8182,7 @@
"authors": [
{
"name": "Sebastian Bergmann",
- "email": "sb@sebastian-bergmann.de",
+ "email": "sebastian@phpunit.de",
"role": "lead"
}
],
@@ -4869,7 +8192,17 @@
"filesystem",
"iterator"
],
- "time": "2015-06-21 13:08:43"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
+ "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/2.0.5"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2021-12-02T12:42:26+00:00"
},
{
"name": "phpunit/php-text-template",
@@ -4910,29 +8243,38 @@
"keywords": [
"template"
],
- "time": "2015-06-21 13:50:34"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-text-template/issues",
+ "source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1"
+ },
+ "time": "2015-06-21T13:50:34+00:00"
},
{
"name": "phpunit/php-timer",
- "version": "1.0.8",
+ "version": "2.1.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-timer.git",
- "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260"
+ "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260",
- "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/2454ae1765516d20c4ffe103d85a58a9a3bd5662",
+ "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
+ "php": ">=7.1"
},
"require-dev": {
- "phpunit/phpunit": "~4|~5"
+ "phpunit/phpunit": "^8.5"
},
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.1-dev"
+ }
+ },
"autoload": {
"classmap": [
"src/"
@@ -4945,7 +8287,7 @@
"authors": [
{
"name": "Sebastian Bergmann",
- "email": "sb@sebastian-bergmann.de",
+ "email": "sebastian@phpunit.de",
"role": "lead"
}
],
@@ -4954,33 +8296,43 @@
"keywords": [
"timer"
],
- "time": "2016-05-12 18:03:57"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-timer/issues",
+ "source": "https://github.com/sebastianbergmann/php-timer/tree/2.1.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-11-30T08:20:02+00:00"
},
{
"name": "phpunit/php-token-stream",
- "version": "1.4.8",
+ "version": "3.1.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
- "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da"
+ "reference": "9c1da83261628cb24b6a6df371b6e312b3954768"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da",
- "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/9c1da83261628cb24b6a6df371b6e312b3954768",
+ "reference": "9c1da83261628cb24b6a6df371b6e312b3954768",
"shasum": ""
},
"require": {
"ext-tokenizer": "*",
- "php": ">=5.3.3"
+ "php": ">=7.1"
},
"require-dev": {
- "phpunit/phpunit": "~4.2"
+ "phpunit/phpunit": "^7.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.4-dev"
+ "dev-master": "3.1-dev"
}
},
"autoload": {
@@ -5003,53 +8355,261 @@
"keywords": [
"tokenizer"
],
- "time": "2015-09-15 10:49:45"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-token-stream/issues",
+ "source": "https://github.com/sebastianbergmann/php-token-stream/tree/3.1.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "abandoned": true,
+ "time": "2021-07-26T12:15:06+00:00"
+ },
+ {
+ "name": "phpunit/phpunit",
+ "version": "7.5.20",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpunit.git",
+ "reference": "9467db479d1b0487c99733bb1e7944d32deded2c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9467db479d1b0487c99733bb1e7944d32deded2c",
+ "reference": "9467db479d1b0487c99733bb1e7944d32deded2c",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/instantiator": "^1.1",
+ "ext-dom": "*",
+ "ext-json": "*",
+ "ext-libxml": "*",
+ "ext-mbstring": "*",
+ "ext-xml": "*",
+ "myclabs/deep-copy": "^1.7",
+ "phar-io/manifest": "^1.0.2",
+ "phar-io/version": "^2.0",
+ "php": "^7.1",
+ "phpspec/prophecy": "^1.7",
+ "phpunit/php-code-coverage": "^6.0.7",
+ "phpunit/php-file-iterator": "^2.0.1",
+ "phpunit/php-text-template": "^1.2.1",
+ "phpunit/php-timer": "^2.1",
+ "sebastian/comparator": "^3.0",
+ "sebastian/diff": "^3.0",
+ "sebastian/environment": "^4.0",
+ "sebastian/exporter": "^3.1",
+ "sebastian/global-state": "^2.0",
+ "sebastian/object-enumerator": "^3.0.3",
+ "sebastian/resource-operations": "^2.0",
+ "sebastian/version": "^2.0.1"
+ },
+ "conflict": {
+ "phpunit/phpunit-mock-objects": "*"
+ },
+ "require-dev": {
+ "ext-pdo": "*"
+ },
+ "suggest": {
+ "ext-soap": "*",
+ "ext-xdebug": "*",
+ "phpunit/php-invoker": "^2.0"
+ },
+ "bin": [
+ "phpunit"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "7.5-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "The PHP Unit Testing framework.",
+ "homepage": "https://phpunit.de/",
+ "keywords": [
+ "phpunit",
+ "testing",
+ "xunit"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/phpunit/issues",
+ "source": "https://github.com/sebastianbergmann/phpunit/tree/7.5.20"
+ },
+ "time": "2020-01-08T08:45:45+00:00"
+ },
+ {
+ "name": "sebastian/code-unit-reverse-lookup",
+ "version": "1.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
+ "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619",
+ "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^8.5"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Looks up which function or method a line of code belongs to",
+ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues",
+ "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-11-30T08:15:22+00:00"
+ },
+ {
+ "name": "sebastian/comparator",
+ "version": "3.0.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/comparator.git",
+ "reference": "1dc7ceb4a24aede938c7af2a9ed1de09609ca770"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1dc7ceb4a24aede938c7af2a9ed1de09609ca770",
+ "reference": "1dc7ceb4a24aede938c7af2a9ed1de09609ca770",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1",
+ "sebastian/diff": "^3.0",
+ "sebastian/exporter": "^3.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^8.5"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Volker Dusch",
+ "email": "github@wallbash.com"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@2bepublished.at"
+ }
+ ],
+ "description": "Provides the functionality to compare PHP values for equality",
+ "homepage": "https://github.com/sebastianbergmann/comparator",
+ "keywords": [
+ "comparator",
+ "compare",
+ "equality"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/comparator/issues",
+ "source": "https://github.com/sebastianbergmann/comparator/tree/3.0.5"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2022-09-14T12:31:48+00:00"
},
{
- "name": "phpunit/phpunit",
- "version": "4.8.21",
+ "name": "sebastian/diff",
+ "version": "3.0.4",
"source": {
"type": "git",
- "url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "ea76b17bced0500a28098626b84eda12dbcf119c"
+ "url": "https://github.com/sebastianbergmann/diff.git",
+ "reference": "6296a0c086dd0117c1b78b059374d7fcbe7545ae"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ea76b17bced0500a28098626b84eda12dbcf119c",
- "reference": "ea76b17bced0500a28098626b84eda12dbcf119c",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/6296a0c086dd0117c1b78b059374d7fcbe7545ae",
+ "reference": "6296a0c086dd0117c1b78b059374d7fcbe7545ae",
"shasum": ""
},
"require": {
- "ext-dom": "*",
- "ext-json": "*",
- "ext-pcre": "*",
- "ext-reflection": "*",
- "ext-spl": "*",
- "php": ">=5.3.3",
- "phpspec/prophecy": "^1.3.1",
- "phpunit/php-code-coverage": "~2.1",
- "phpunit/php-file-iterator": "~1.4",
- "phpunit/php-text-template": "~1.2",
- "phpunit/php-timer": ">=1.0.6",
- "phpunit/phpunit-mock-objects": "~2.3",
- "sebastian/comparator": "~1.1",
- "sebastian/diff": "~1.2",
- "sebastian/environment": "~1.3",
- "sebastian/exporter": "~1.2",
- "sebastian/global-state": "~1.0",
- "sebastian/version": "~1.0",
- "symfony/yaml": "~2.1|~3.0"
+ "php": ">=7.1"
},
- "suggest": {
- "phpunit/php-invoker": "~1.1"
+ "require-dev": {
+ "phpunit/phpunit": "^7.5 || ^8.0",
+ "symfony/process": "^2 || ^3.3 || ^4"
},
- "bin": [
- "phpunit"
- ],
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "4.8.x-dev"
+ "dev-master": "3.0-dev"
}
},
"autoload": {
@@ -5064,49 +8624,60 @@
"authors": [
{
"name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "lead"
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Kore Nordmann",
+ "email": "mail@kore-nordmann.de"
}
],
- "description": "The PHP Unit Testing framework.",
- "homepage": "https://phpunit.de/",
+ "description": "Diff implementation",
+ "homepage": "https://github.com/sebastianbergmann/diff",
"keywords": [
- "phpunit",
- "testing",
- "xunit"
+ "diff",
+ "udiff",
+ "unidiff",
+ "unified diff"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/diff/issues",
+ "source": "https://github.com/sebastianbergmann/diff/tree/3.0.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
],
- "time": "2015-12-12 07:45:58"
+ "time": "2023-05-07T05:30:20+00:00"
},
{
- "name": "phpunit/phpunit-mock-objects",
- "version": "2.3.8",
+ "name": "sebastian/environment",
+ "version": "4.2.4",
"source": {
"type": "git",
- "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
- "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983"
+ "url": "https://github.com/sebastianbergmann/environment.git",
+ "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983",
- "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983",
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/d47bbbad83711771f167c72d4e3f25f7fcc1f8b0",
+ "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0",
"shasum": ""
},
"require": {
- "doctrine/instantiator": "^1.0.2",
- "php": ">=5.3.3",
- "phpunit/php-text-template": "~1.2",
- "sebastian/exporter": "~1.2"
+ "php": ">=7.1"
},
"require-dev": {
- "phpunit/phpunit": "~4.4"
+ "phpunit/phpunit": "^7.5"
},
"suggest": {
- "ext-soap": "*"
+ "ext-posix": "*"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.3.x-dev"
+ "dev-master": "4.2-dev"
}
},
"autoload": {
@@ -5121,44 +8692,54 @@
"authors": [
{
"name": "Sebastian Bergmann",
- "email": "sb@sebastian-bergmann.de",
- "role": "lead"
+ "email": "sebastian@phpunit.de"
}
],
- "description": "Mock Object library for PHPUnit",
- "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
+ "description": "Provides functionality to handle HHVM/PHP environments",
+ "homepage": "http://www.github.com/sebastianbergmann/environment",
"keywords": [
- "mock",
- "xunit"
+ "Xdebug",
+ "environment",
+ "hhvm"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/environment/issues",
+ "source": "https://github.com/sebastianbergmann/environment/tree/4.2.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
],
- "time": "2015-10-02 06:51:40"
+ "time": "2020-11-30T07:53:42+00:00"
},
{
- "name": "sebastian/comparator",
- "version": "1.2.0",
+ "name": "sebastian/exporter",
+ "version": "3.1.5",
"source": {
"type": "git",
- "url": "https://github.com/sebastianbergmann/comparator.git",
- "reference": "937efb279bd37a375bcadf584dec0726f84dbf22"
+ "url": "https://github.com/sebastianbergmann/exporter.git",
+ "reference": "73a9676f2833b9a7c36968f9d882589cd75511e6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22",
- "reference": "937efb279bd37a375bcadf584dec0726f84dbf22",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/73a9676f2833b9a7c36968f9d882589cd75511e6",
+ "reference": "73a9676f2833b9a7c36968f9d882589cd75511e6",
"shasum": ""
},
"require": {
- "php": ">=5.3.3",
- "sebastian/diff": "~1.2",
- "sebastian/exporter": "~1.2"
+ "php": ">=7.0",
+ "sebastian/recursion-context": "^3.0"
},
"require-dev": {
- "phpunit/phpunit": "~4.4"
+ "ext-mbstring": "*",
+ "phpunit/phpunit": "^8.5"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.2.x-dev"
+ "dev-master": "3.1.x-dev"
}
},
"autoload": {
@@ -5171,6 +8752,10 @@
"BSD-3-Clause"
],
"authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
{
"name": "Jeff Welch",
"email": "whatthejeff@gmail.com"
@@ -5180,47 +8765,59 @@
"email": "github@wallbash.com"
},
{
- "name": "Bernhard Schussek",
- "email": "bschussek@2bepublished.at"
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
},
{
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
+ "name": "Bernhard Schussek",
+ "email": "bschussek@gmail.com"
}
],
- "description": "Provides the functionality to compare PHP values for equality",
- "homepage": "http://www.github.com/sebastianbergmann/comparator",
+ "description": "Provides the functionality to export PHP variables for visualization",
+ "homepage": "http://www.github.com/sebastianbergmann/exporter",
"keywords": [
- "comparator",
- "compare",
- "equality"
+ "export",
+ "exporter"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/exporter/issues",
+ "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.5"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
],
- "time": "2015-07-26 15:48:44"
+ "time": "2022-09-14T06:00:17+00:00"
},
{
- "name": "sebastian/diff",
- "version": "1.4.1",
+ "name": "sebastian/global-state",
+ "version": "2.0.0",
"source": {
"type": "git",
- "url": "https://github.com/sebastianbergmann/diff.git",
- "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e"
+ "url": "https://github.com/sebastianbergmann/global-state.git",
+ "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e",
- "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e",
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4",
+ "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
+ "php": "^7.0"
},
"require-dev": {
- "phpunit/phpunit": "~4.8"
+ "phpunit/phpunit": "^6.0"
+ },
+ "suggest": {
+ "ext-uopz": "*"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.4-dev"
+ "dev-master": "2.0-dev"
}
},
"autoload": {
@@ -5233,46 +8830,48 @@
"BSD-3-Clause"
],
"authors": [
- {
- "name": "Kore Nordmann",
- "email": "mail@kore-nordmann.de"
- },
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
}
],
- "description": "Diff implementation",
- "homepage": "https://github.com/sebastianbergmann/diff",
+ "description": "Snapshotting of global state",
+ "homepage": "http://www.github.com/sebastianbergmann/global-state",
"keywords": [
- "diff"
+ "global state"
],
- "time": "2015-12-08 07:14:41"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/global-state/issues",
+ "source": "https://github.com/sebastianbergmann/global-state/tree/2.0.0"
+ },
+ "time": "2017-04-27T15:39:26+00:00"
},
{
- "name": "sebastian/environment",
- "version": "1.3.8",
+ "name": "sebastian/object-enumerator",
+ "version": "3.0.4",
"source": {
"type": "git",
- "url": "https://github.com/sebastianbergmann/environment.git",
- "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea"
+ "url": "https://github.com/sebastianbergmann/object-enumerator.git",
+ "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea",
- "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2",
+ "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2",
"shasum": ""
},
"require": {
- "php": "^5.3.3 || ^7.0"
+ "php": ">=7.0",
+ "sebastian/object-reflector": "^1.1.1",
+ "sebastian/recursion-context": "^3.0"
},
"require-dev": {
- "phpunit/phpunit": "^4.8 || ^5.0"
+ "phpunit/phpunit": "^6.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.3.x-dev"
+ "dev-master": "3.0.x-dev"
}
},
"autoload": {
@@ -5290,41 +8889,44 @@
"email": "sebastian@phpunit.de"
}
],
- "description": "Provides functionality to handle HHVM/PHP environments",
- "homepage": "http://www.github.com/sebastianbergmann/environment",
- "keywords": [
- "Xdebug",
- "environment",
- "hhvm"
+ "description": "Traverses array structures and object graphs to enumerate all referenced objects",
+ "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/object-enumerator/issues",
+ "source": "https://github.com/sebastianbergmann/object-enumerator/tree/3.0.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
],
- "time": "2016-08-18 05:49:44"
+ "time": "2020-11-30T07:40:27+00:00"
},
{
- "name": "sebastian/exporter",
- "version": "1.2.2",
+ "name": "sebastian/object-reflector",
+ "version": "1.1.2",
"source": {
"type": "git",
- "url": "https://github.com/sebastianbergmann/exporter.git",
- "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4"
+ "url": "https://github.com/sebastianbergmann/object-reflector.git",
+ "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4",
- "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/9b8772b9cbd456ab45d4a598d2dd1a1bced6363d",
+ "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d",
"shasum": ""
},
"require": {
- "php": ">=5.3.3",
- "sebastian/recursion-context": "~1.0"
+ "php": ">=7.0"
},
"require-dev": {
- "ext-mbstring": "*",
- "phpunit/phpunit": "~4.4"
+ "phpunit/phpunit": "^6.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.3.x-dev"
+ "dev-master": "1.1-dev"
}
},
"autoload": {
@@ -5337,62 +8939,49 @@
"BSD-3-Clause"
],
"authors": [
- {
- "name": "Jeff Welch",
- "email": "whatthejeff@gmail.com"
- },
- {
- "name": "Volker Dusch",
- "email": "github@wallbash.com"
- },
- {
- "name": "Bernhard Schussek",
- "email": "bschussek@2bepublished.at"
- },
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
- },
- {
- "name": "Adam Harvey",
- "email": "aharvey@php.net"
}
],
- "description": "Provides the functionality to export PHP variables for visualization",
- "homepage": "http://www.github.com/sebastianbergmann/exporter",
- "keywords": [
- "export",
- "exporter"
+ "description": "Allows reflection of object attributes, including inherited and non-public ones",
+ "homepage": "https://github.com/sebastianbergmann/object-reflector/",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/object-reflector/issues",
+ "source": "https://github.com/sebastianbergmann/object-reflector/tree/1.1.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
],
- "time": "2016-06-17 09:04:28"
+ "time": "2020-11-30T07:37:18+00:00"
},
{
- "name": "sebastian/global-state",
- "version": "1.1.1",
+ "name": "sebastian/recursion-context",
+ "version": "3.0.1",
"source": {
"type": "git",
- "url": "https://github.com/sebastianbergmann/global-state.git",
- "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4"
+ "url": "https://github.com/sebastianbergmann/recursion-context.git",
+ "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4",
- "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4",
+ "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/367dcba38d6e1977be014dc4b22f47a484dac7fb",
+ "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
+ "php": ">=7.0"
},
"require-dev": {
- "phpunit/phpunit": "~4.2"
- },
- "suggest": {
- "ext-uopz": "*"
+ "phpunit/phpunit": "^6.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0-dev"
+ "dev-master": "3.0.x-dev"
}
},
"autoload": {
@@ -5408,39 +8997,51 @@
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
}
],
- "description": "Snapshotting of global state",
- "homepage": "http://www.github.com/sebastianbergmann/global-state",
- "keywords": [
- "global state"
+ "description": "Provides functionality to recursively process PHP variables",
+ "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/recursion-context/issues",
+ "source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
],
- "time": "2015-10-12 03:26:01"
+ "time": "2020-11-30T07:34:24+00:00"
},
{
- "name": "sebastian/recursion-context",
- "version": "1.0.2",
+ "name": "sebastian/resource-operations",
+ "version": "2.0.2",
"source": {
"type": "git",
- "url": "https://github.com/sebastianbergmann/recursion-context.git",
- "reference": "913401df809e99e4f47b27cdd781f4a258d58791"
+ "url": "https://github.com/sebastianbergmann/resource-operations.git",
+ "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791",
- "reference": "913401df809e99e4f47b27cdd781f4a258d58791",
+ "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/31d35ca87926450c44eae7e2611d45a7a65ea8b3",
+ "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
- },
- "require-dev": {
- "phpunit/phpunit": "~4.4"
+ "php": ">=7.1"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0.x-dev"
+ "dev-master": "2.0-dev"
}
},
"autoload": {
@@ -5453,38 +9054,48 @@
"BSD-3-Clause"
],
"authors": [
- {
- "name": "Jeff Welch",
- "email": "whatthejeff@gmail.com"
- },
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
- },
+ }
+ ],
+ "description": "Provides a list of PHP built-in functions that operate on resources",
+ "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/resource-operations/issues",
+ "source": "https://github.com/sebastianbergmann/resource-operations/tree/2.0.2"
+ },
+ "funding": [
{
- "name": "Adam Harvey",
- "email": "aharvey@php.net"
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
}
],
- "description": "Provides functionality to recursively process PHP variables",
- "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
- "time": "2015-11-11 19:50:13"
+ "time": "2020-11-30T07:30:19+00:00"
},
{
"name": "sebastian/version",
- "version": "1.0.6",
+ "version": "2.0.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/version.git",
- "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6"
+ "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
- "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
+ "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019",
+ "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019",
"shasum": ""
},
+ "require": {
+ "php": ">=5.6"
+ },
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
"autoload": {
"classmap": [
"src/"
@@ -5503,94 +9114,84 @@
],
"description": "Library that helps with managing the version number of Git-hosted PHP projects",
"homepage": "https://github.com/sebastianbergmann/version",
- "time": "2015-06-21 13:59:46"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/version/issues",
+ "source": "https://github.com/sebastianbergmann/version/tree/master"
+ },
+ "time": "2016-10-03T07:35:21+00:00"
},
{
- "name": "symfony/dom-crawler",
- "version": "v3.1.4",
+ "name": "theseer/tokenizer",
+ "version": "1.1.3",
"source": {
"type": "git",
- "url": "https://github.com/symfony/dom-crawler.git",
- "reference": "bb7395e8b1db3654de82b9f35d019958276de4d7"
+ "url": "https://github.com/theseer/tokenizer.git",
+ "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/bb7395e8b1db3654de82b9f35d019958276de4d7",
- "reference": "bb7395e8b1db3654de82b9f35d019958276de4d7",
+ "url": "https://api.github.com/repos/theseer/tokenizer/zipball/11336f6f84e16a720dae9d8e6ed5019efa85a0f9",
+ "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9",
"shasum": ""
},
"require": {
- "php": ">=5.5.9",
- "symfony/polyfill-mbstring": "~1.0"
- },
- "require-dev": {
- "symfony/css-selector": "~2.8|~3.0"
- },
- "suggest": {
- "symfony/css-selector": ""
+ "ext-dom": "*",
+ "ext-tokenizer": "*",
+ "ext-xmlwriter": "*",
+ "php": "^7.0"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.1-dev"
- }
- },
"autoload": {
- "psr-4": {
- "Symfony\\Component\\DomCrawler\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
+ "classmap": [
+ "src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
+ "name": "Arne Blankerts",
+ "email": "arne@blankerts.de",
+ "role": "Developer"
}
],
- "description": "Symfony DomCrawler Component",
- "homepage": "https://symfony.com",
- "time": "2016-08-05 08:37:39"
+ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
+ "support": {
+ "issues": "https://github.com/theseer/tokenizer/issues",
+ "source": "https://github.com/theseer/tokenizer/tree/master"
+ },
+ "time": "2019-06-13T22:48:21+00:00"
},
{
- "name": "symfony/yaml",
- "version": "v3.1.4",
+ "name": "tightenco/mailthief",
+ "version": "v0.3.14",
"source": {
"type": "git",
- "url": "https://github.com/symfony/yaml.git",
- "reference": "f291ed25eb1435bddbe8a96caaef16469c2a092d"
+ "url": "https://github.com/tighten/mailthief.git",
+ "reference": "9a8c2443be2b3d77753596f70ae6cd879b5b26a6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/yaml/zipball/f291ed25eb1435bddbe8a96caaef16469c2a092d",
- "reference": "f291ed25eb1435bddbe8a96caaef16469c2a092d",
+ "url": "https://api.github.com/repos/tighten/mailthief/zipball/9a8c2443be2b3d77753596f70ae6cd879b5b26a6",
+ "reference": "9a8c2443be2b3d77753596f70ae6cd879b5b26a6",
"shasum": ""
},
"require": {
- "php": ">=5.5.9"
+ "illuminate/mail": "5.*",
+ "illuminate/view": "5.*"
},
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.1-dev"
- }
+ "require-dev": {
+ "laravel/framework": ">=5.0 <5.5",
+ "mockery/mockery": "^0.9.5",
+ "phpunit/phpunit": "^5.5"
},
+ "type": "library",
"autoload": {
"psr-4": {
- "Symfony\\Component\\Yaml\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
+ "MailThief\\": "src/"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -5598,45 +9199,43 @@
],
"authors": [
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
+ "name": "Adam Wathan",
+ "email": "adam.wathan@gmail.com"
}
],
- "description": "Symfony Yaml Component",
- "homepage": "https://symfony.com",
- "time": "2016-09-02 02:12:52"
+ "description": "A fake Mailer for Laravel applications that takes the pain out of testing mail.",
+ "support": {
+ "issues": "https://github.com/tighten/mailthief/issues",
+ "source": "https://github.com/tighten/mailthief/tree/v0.3.14"
+ },
+ "time": "2018-02-10T04:17:52+00:00"
},
{
"name": "webmozart/assert",
- "version": "1.1.0",
+ "version": "1.9.1",
"source": {
"type": "git",
- "url": "https://github.com/webmozart/assert.git",
- "reference": "bb2d123231c095735130cc8f6d31385a44c7b308"
+ "url": "https://github.com/webmozarts/assert.git",
+ "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/webmozart/assert/zipball/bb2d123231c095735130cc8f6d31385a44c7b308",
- "reference": "bb2d123231c095735130cc8f6d31385a44c7b308",
+ "url": "https://api.github.com/repos/webmozarts/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389",
+ "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389",
"shasum": ""
},
"require": {
- "php": "^5.3.3|^7.0"
+ "php": "^5.3.3 || ^7.0 || ^8.0",
+ "symfony/polyfill-ctype": "^1.8"
+ },
+ "conflict": {
+ "phpstan/phpstan": "<0.12.20",
+ "vimeo/psalm": "<3.9.1"
},
"require-dev": {
- "phpunit/phpunit": "^4.6",
- "sebastian/version": "^1.0.1"
+ "phpunit/phpunit": "^4.8.36 || ^7.5.13"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.2-dev"
- }
- },
"autoload": {
"psr-4": {
"Webmozart\\Assert\\": "src/"
@@ -5658,20 +9257,31 @@
"check",
"validate"
],
- "time": "2016-08-09 15:02:57"
+ "support": {
+ "issues": "https://github.com/webmozarts/assert/issues",
+ "source": "https://github.com/webmozarts/assert/tree/1.9.1"
+ },
+ "time": "2020-07-08T17:02:28+00:00"
}
],
"aliases": [],
"minimum-stability": "dev",
- "stability-flags": [],
+ "stability-flags": {
+ "alt-three/testbench": 20
+ },
"prefer-stable": true,
"prefer-lowest": false,
"platform": {
- "php": ">=5.5.9",
+ "php": "^7.1.3",
+ "ext-mbstring": "*",
+ "ext-openssl": "*",
"ext-xml": "*"
},
- "platform-dev": [],
+ "platform-dev": {
+ "ext-sqlite3": "*"
+ },
"platform-overrides": {
- "php": "5.5.9"
- }
+ "php": "7.1.3"
+ },
+ "plugin-api-version": "2.3.0"
}
diff --git a/config/app.php b/config/app.php
index a1f3fb811c98..b9599092fed0 100644
--- a/config/app.php
+++ b/config/app.php
@@ -11,6 +11,18 @@
return [
+ /*
+ |--------------------------------------------------------------------------
+ | Application Name
+ |--------------------------------------------------------------------------
+ |
+ | This value is the name of your application. This value is used when the
+ | framework needs to place the application's name in a notification or
+ | any other location as required by the application or its packages.
+ */
+
+ 'name' => 'Cachet',
+
/*
|--------------------------------------------------------------------------
| Application Environment
@@ -35,7 +47,7 @@
|
*/
- 'debug' => env('APP_DEBUG', false),
+ 'debug' => (bool) env('APP_DEBUG', false),
/*
|--------------------------------------------------------------------------
@@ -61,7 +73,7 @@
|
*/
- 'timezone' => 'UTC',
+ 'timezone' => env('APP_TIMEZONE', 'UTC'),
/*
|--------------------------------------------------------------------------
@@ -135,60 +147,57 @@
/*
* Laravel Framework Service Providers...
*/
- 'Illuminate\Auth\AuthServiceProvider',
- 'Illuminate\Broadcasting\BroadcastServiceProvider',
- 'AltThree\Bus\BusServiceProvider',
- 'Illuminate\Cache\CacheServiceProvider',
- 'Illuminate\Foundation\Providers\ConsoleSupportServiceProvider',
- 'Illuminate\Cookie\CookieServiceProvider',
- 'Illuminate\Database\DatabaseServiceProvider',
- 'Illuminate\Encryption\EncryptionServiceProvider',
- 'Illuminate\Filesystem\FilesystemServiceProvider',
- 'Illuminate\Foundation\Providers\FoundationServiceProvider',
- 'Illuminate\Hashing\HashServiceProvider',
- 'Illuminate\Mail\MailServiceProvider',
- 'Illuminate\Pagination\PaginationServiceProvider',
- 'Illuminate\Pipeline\PipelineServiceProvider',
- 'Illuminate\Queue\QueueServiceProvider',
- 'Illuminate\Redis\RedisServiceProvider',
- 'Illuminate\Auth\Passwords\PasswordResetServiceProvider',
- 'Illuminate\Session\SessionServiceProvider',
- 'Illuminate\Translation\TranslationServiceProvider',
- 'Illuminate\Validation\ValidationServiceProvider',
- 'Illuminate\View\ViewServiceProvider',
+ Illuminate\Auth\AuthServiceProvider::class,
+ Illuminate\Broadcasting\BroadcastServiceProvider::class,
+ AltThree\Bus\BusServiceProvider::class,
+ Illuminate\Cache\CacheServiceProvider::class,
+ Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
+ Illuminate\Cookie\CookieServiceProvider::class,
+ Illuminate\Database\DatabaseServiceProvider::class,
+ Illuminate\Encryption\EncryptionServiceProvider::class,
+ Illuminate\Filesystem\FilesystemServiceProvider::class,
+ Illuminate\Foundation\Providers\FoundationServiceProvider::class,
+ Illuminate\Hashing\HashServiceProvider::class,
+ Illuminate\Mail\MailServiceProvider::class,
+ Illuminate\Notifications\NotificationServiceProvider::class,
+ Illuminate\Pagination\PaginationServiceProvider::class,
+ Illuminate\Pipeline\PipelineServiceProvider::class,
+ Illuminate\Queue\QueueServiceProvider::class,
+ Illuminate\Redis\RedisServiceProvider::class,
+ Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
+ Illuminate\Session\SessionServiceProvider::class,
+ Illuminate\Translation\TranslationServiceProvider::class,
+ Illuminate\Validation\ValidationServiceProvider::class,
+ Illuminate\View\ViewServiceProvider::class,
/*
* Packages Service Providers...
*/
- 'AltThree\Badger\BadgerServiceProvider',
- 'AltThree\Emoji\EmojiServiceProvider',
- 'BackupManager\Laravel\Laravel5ServiceProvider',
- 'Barryvdh\Cors\ServiceProvider',
- 'Fedeisas\LaravelMailCssInliner\LaravelMailCssInlinerServiceProvider',
- 'Fideloper\Proxy\TrustedProxyServiceProvider',
- 'GrahamCampbell\Binput\BinputServiceProvider',
- 'GrahamCampbell\Exceptions\ExceptionsServiceProvider',
- 'GrahamCampbell\Core\CoreServiceProvider',
- 'GrahamCampbell\Markdown\MarkdownServiceProvider',
- 'GrahamCampbell\Security\SecurityServiceProvider',
- 'Jenssegers\Date\DateServiceProvider',
- 'McCool\LaravelAutoPresenter\AutoPresenterServiceProvider',
- 'PragmaRX\Google2FA\Vendor\Laravel\ServiceProvider',
- 'Roumen\Feed\FeedServiceProvider',
- 'TwigBridge\ServiceProvider',
+ env('APP_DEBUG') ? Bugsnag\BugsnagLaravel\BugsnagServiceProvider::class : null,
+ Barryvdh\Cors\ServiceProvider::class,
+ env('APP_DEBUG') ? Barryvdh\Debugbar\ServiceProvider::class : null,
+ CachetHQ\Badger\BadgerServiceProvider::class,
+ CachetHQ\Emoji\EmojiServiceProvider::class,
+ CachetHQ\Twitter\TwitterServiceProvider::class,
+ GrahamCampbell\Binput\BinputServiceProvider::class,
+ GrahamCampbell\Exceptions\ExceptionsServiceProvider::class,
+ GrahamCampbell\Markdown\MarkdownServiceProvider::class,
+ GrahamCampbell\Security\SecurityServiceProvider::class,
+ Jenssegers\Date\DateServiceProvider::class,
+ Laravel\Tinker\TinkerServiceProvider::class,
+ McCool\LaravelAutoPresenter\AutoPresenterServiceProvider::class,
/*
* Application Service Providers...
*/
- 'CachetHQ\Cachet\Foundation\Providers\AppServiceProvider',
- 'CachetHQ\Cachet\Foundation\Providers\ComposerServiceProvider',
- 'CachetHQ\Cachet\Foundation\Providers\ConsoleServiceProvider',
- 'CachetHQ\Cachet\Foundation\Providers\ConfigServiceProvider',
- 'CachetHQ\Cachet\Foundation\Providers\EventServiceProvider',
- 'CachetHQ\Cachet\Foundation\Providers\IntegrationServiceProvider',
- 'CachetHQ\Cachet\Foundation\Providers\ModuleServiceProvider',
- 'CachetHQ\Cachet\Foundation\Providers\RepositoryServiceProvider',
- 'CachetHQ\Cachet\Foundation\Providers\RouteServiceProvider',
+ CachetHQ\Cachet\Providers\AppServiceProvider::class,
+ CachetHQ\Cachet\Providers\ComposerServiceProvider::class,
+ CachetHQ\Cachet\Providers\ConsoleServiceProvider::class,
+ CachetHQ\Cachet\Providers\ConfigServiceProvider::class,
+ CachetHQ\Cachet\Providers\EventServiceProvider::class,
+ CachetHQ\Cachet\Providers\IntegrationServiceProvider::class,
+ CachetHQ\Cachet\Providers\RepositoryServiceProvider::class,
+ CachetHQ\Cachet\Providers\RouteServiceProvider::class,
]),
@@ -205,38 +214,41 @@
'aliases' => [
- 'App' => 'Illuminate\Support\Facades\App',
- 'Artisan' => 'Illuminate\Support\Facades\Artisan',
- 'Auth' => 'Illuminate\Support\Facades\Auth',
- 'Blade' => 'Illuminate\Support\Facades\Blade',
- 'Cache' => 'Illuminate\Support\Facades\Cache',
- 'Config' => 'Illuminate\Support\Facades\Config',
- 'Cookie' => 'Illuminate\Support\Facades\Cookie',
- 'Crypt' => 'Illuminate\Support\Facades\Crypt',
- 'DB' => 'Illuminate\Support\Facades\DB',
- 'Event' => 'Illuminate\Support\Facades\Event',
- 'File' => 'Illuminate\Support\Facades\File',
- 'Gate' => 'Illuminate\Support\Facades\Gate',
- 'Hash' => 'Illuminate\Support\Facades\Hash',
- 'Lang' => 'Illuminate\Support\Facades\Lang',
- 'Log' => 'Illuminate\Support\Facades\Log',
- 'Mail' => 'Illuminate\Support\Facades\Mail',
- 'Password' => 'Illuminate\Support\Facades\Password',
- 'Queue' => 'Illuminate\Support\Facades\Queue',
- 'Redirect' => 'Illuminate\Support\Facades\Redirect',
- 'Redis' => 'Illuminate\Support\Facades\Redis',
- 'Request' => 'Illuminate\Support\Facades\Request',
- 'Response' => 'Illuminate\Support\Facades\Response',
- 'Route' => 'Illuminate\Support\Facades\Route',
- 'Schema' => 'Illuminate\Support\Facades\Schema',
- 'Session' => 'Illuminate\Support\Facades\Session',
- 'Storage' => 'Illuminate\Support\Facades\Storage',
- 'URL' => 'Illuminate\Support\Facades\URL',
- 'Validator' => 'Illuminate\Support\Facades\Validator',
- 'View' => 'Illuminate\Support\Facades\View',
-
- 'Binput' => 'GrahamCampbell\Binput\Facades\Binput',
- 'Str' => 'Illuminate\Support\Str',
+ 'App' => Illuminate\Support\Facades\App::class,
+ 'Artisan' => Illuminate\Support\Facades\Artisan::class,
+ 'Auth' => Illuminate\Support\Facades\Auth::class,
+ 'Blade' => Illuminate\Support\Facades\Blade::class,
+ 'Broadcast' => Illuminate\Support\Facades\Broadcast::class,
+ 'Bus' => Illuminate\Support\Facades\Bus::class,
+ 'Cache' => Illuminate\Support\Facades\Cache::class,
+ 'Config' => Illuminate\Support\Facades\Config::class,
+ 'Cookie' => Illuminate\Support\Facades\Cookie::class,
+ 'Crypt' => Illuminate\Support\Facades\Crypt::class,
+ 'DB' => Illuminate\Support\Facades\DB::class,
+ 'Eloquent' => Illuminate\Database\Eloquent\Model::class,
+ 'Event' => Illuminate\Support\Facades\Event::class,
+ 'File' => Illuminate\Support\Facades\File::class,
+ 'Gate' => Illuminate\Support\Facades\Gate::class,
+ 'Hash' => Illuminate\Support\Facades\Hash::class,
+ 'Lang' => Illuminate\Support\Facades\Lang::class,
+ 'Log' => Illuminate\Support\Facades\Log::class,
+ 'Mail' => Illuminate\Support\Facades\Mail::class,
+ 'Notification' => Illuminate\Support\Facades\Notification::class,
+ 'Password' => Illuminate\Support\Facades\Password::class,
+ 'Queue' => Illuminate\Support\Facades\Queue::class,
+ 'Redirect' => Illuminate\Support\Facades\Redirect::class,
+ 'Redis' => Illuminate\Support\Facades\Redis::class,
+ 'Request' => Illuminate\Support\Facades\Request::class,
+ 'Response' => Illuminate\Support\Facades\Response::class,
+ 'Route' => Illuminate\Support\Facades\Route::class,
+ 'Schema' => Illuminate\Support\Facades\Schema::class,
+ 'Session' => Illuminate\Support\Facades\Session::class,
+ 'Storage' => Illuminate\Support\Facades\Storage::class,
+ 'URL' => Illuminate\Support\Facades\URL::class,
+ 'Validator' => Illuminate\Support\Facades\Validator::class,
+ 'View' => Illuminate\Support\Facades\View::class,
+ 'Binput' => GrahamCampbell\Binput\Facades\Binput::class,
+ 'Str' => Illuminate\Support\Str::class,
],
diff --git a/config/auth.php b/config/auth.php
index 97aef242b077..a0697fac50ff 100644
--- a/config/auth.php
+++ b/config/auth.php
@@ -76,8 +76,13 @@
'providers' => [
'users' => [
'driver' => 'eloquent',
- 'model' => 'CachetHQ\Cachet\Models\User',
+ 'model' => \CachetHQ\Cachet\Models\User::class,
],
+
+ // 'users' => [
+ // 'driver' => 'database',
+ // 'table' => 'users',
+ // ],
],
/*
@@ -85,10 +90,6 @@
| Resetting Passwords
|--------------------------------------------------------------------------
|
- | Here you may set the options for resetting passwords including the view
- | that is your password reset e-mail. You may also set the name of the
- | table that maintains all of the reset tokens for your application.
- |
| You may specify multiple password reset configurations if you have more
| than one user table or model in the application and you want to have
| separate password reset settings based on the specific user types.
@@ -102,7 +103,6 @@
'passwords' => [
'users' => [
'provider' => 'users',
- 'email' => 'auth.emails.password',
'table' => 'password_resets',
'expire' => 60,
],
diff --git a/config/avatar.php b/config/avatar.php
new file mode 100644
index 000000000000..68590dd603b9
--- /dev/null
+++ b/config/avatar.php
@@ -0,0 +1,88 @@
+ 'gd',
+
+ // Whether all characters supplied must be replaced with their closest ASCII counterparts
+ 'ascii' => false,
+
+ // Image shape: circle or square
+ 'shape' => 'circle',
+
+ // Image width, in pixel
+ 'width' => 100,
+
+ // Image height, in pixel
+ 'height' => 100,
+
+ // Number of characters used as initials. If name consists of single word, the first N character will be used
+ 'chars' => 2,
+
+ // font size
+ 'fontSize' => 48,
+
+ // convert initial letter in uppercase
+ 'uppercase' => false,
+
+ // Fonts used to render text.
+ // If contains more than one fonts, randomly selected based on name supplied
+ // You can provide absolute path, path relative to folder resources/laravolt/avatar/fonts/, or mixed.
+ 'fonts' => ['OpenSans-Bold.ttf', 'rockwell.ttf'],
+
+ // List of foreground colors to be used, randomly selected based on name supplied
+ 'foregrounds' => [
+ '#FFFFFF',
+ ],
+
+ // List of background colors to be used, randomly selected based on name supplied
+ 'backgrounds' => [
+ '#f44336',
+ '#E91E63',
+ '#9C27B0',
+ '#673AB7',
+ '#3F51B5',
+ '#2196F3',
+ '#03A9F4',
+ '#00BCD4',
+ '#009688',
+ '#4CAF50',
+ '#8BC34A',
+ '#CDDC39',
+ '#FFC107',
+ '#FF9800',
+ '#FF5722',
+ ],
+
+ 'border' => [
+ 'size' => 1,
+
+ // border color, available value are:
+ // 'foreground' (same as foreground color)
+ // 'background' (same as background color)
+ // or any valid hex ('#aabbcc')
+ 'color' => 'foreground',
+ ],
+
+];
diff --git a/config/backup-manager.php b/config/backup-manager.php
deleted file mode 100644
index 40c8539bc14a..000000000000
--- a/config/backup-manager.php
+++ /dev/null
@@ -1,70 +0,0 @@
- [
- 'type' => 'Local',
- 'root' => database_path('backups'),
- ],
- 's3' => [
- 'type' => 'AwsS3',
- 'key' => '',
- 'secret' => '',
- 'region' => 'us-east-1',
- 'bucket' => '',
- 'root' => '',
- ],
- 'gcs' => [
- 'type' => 'Gcs',
- 'key' => '',
- 'secret' => '',
- 'bucket' => '',
- 'root' => '',
- ],
- 'rackspace' => [
- 'type' => 'Rackspace',
- 'username' => '',
- 'key' => '',
- 'container' => '',
- 'zone' => '',
- 'endpoint' => 'https://identity.api.rackspacecloud.com/v2.0/',
- 'root' => '',
- ],
- 'dropbox' => [
- 'type' => 'Dropbox',
- 'token' => '',
- 'key' => '',
- 'secret' => '',
- 'app' => '',
- 'root' => '',
- ],
- 'ftp' => [
- 'type' => 'Ftp',
- 'host' => '',
- 'username' => '',
- 'password' => '',
- 'port' => 21,
- 'passive' => true,
- 'ssl' => true,
- 'timeout' => 30,
- 'root' => '',
- ],
- 'sftp' => [
- 'type' => 'Sftp',
- 'host' => '',
- 'username' => '',
- 'password' => '',
- 'port' => 21,
- 'timeout' => 10,
- 'privateKey' => '',
- 'root' => '',
- ],
-];
diff --git a/config/broadcasting.php b/config/broadcasting.php
index 9305cdeb5c32..01c1213a4c7d 100644
--- a/config/broadcasting.php
+++ b/config/broadcasting.php
@@ -20,9 +20,11 @@
| framework when an event needs to be broadcast. You may set this to
| any of the connections defined in the "connections" array below.
|
+ | Supported: "pusher", "redis", "log", "null"
+ |
*/
- 'default' => env('BROADCAST_DRIVER', 'pusher'),
+ 'default' => env('BROADCAST_DRIVER', 'null'),
/*
|--------------------------------------------------------------------------
@@ -39,9 +41,9 @@
'pusher' => [
'driver' => 'pusher',
- 'key' => null,
- 'secret' => null,
- 'app_id' => null,
+ 'key' => env('PUSHER_APP_KEY'),
+ 'secret' => env('PUSHER_APP_SECRET'),
+ 'app_id' => env('PUSHER_APP_ID'),
'options' => [
//
],
@@ -56,6 +58,10 @@
'driver' => 'log',
],
+ 'null' => [
+ 'driver' => 'null',
+ ],
+
],
];
diff --git a/config/cache.php b/config/cache.php
index ce53b14c79c9..06ec44c36eaf 100644
--- a/config/cache.php
+++ b/config/cache.php
@@ -20,6 +20,8 @@
| using this caching library. This connection is used when another is
| not explicitly specified when executing a given caching function.
|
+ | Supported: "apc", "array", "database", "file", "memcached", "redis"
+ |
*/
'default' => env('CACHE_DRIVER', 'file'),
@@ -53,15 +55,23 @@
'file' => [
'driver' => 'file',
- 'path' => storage_path('framework/cache'),
+ 'path' => storage_path('framework/cache/data'),
],
'memcached' => [
- 'driver' => 'memcached',
+ 'driver' => 'memcached',
+ 'persistent_id' => env('MEMCACHED_PERSISTENT_ID'),
+ 'sasl' => [
+ env('MEMCACHED_USERNAME'),
+ env('MEMCACHED_PASSWORD'),
+ ],
+ 'options' => [
+ // Memcached::OPT_CONNECT_TIMEOUT => 2000,
+ ],
'servers' => [
[
- 'host' => '127.0.0.1',
- 'port' => 11211,
+ 'host' => env('MEMCACHED_HOST', '127.0.0.1'),
+ 'port' => env('MEMCACHED_PORT', 11211),
'weight' => 100,
],
],
@@ -70,6 +80,9 @@
'redis' => [
'driver' => 'redis',
'connection' => 'default',
+ 'password' => env('REDIS_PASSWORD', null),
+ 'port' => env('REDIS_PORT', 6379),
+ 'database' => env('REDIS_DB', 0),
],
],
diff --git a/config/cachet.php b/config/cachet.php
index 2f193d21e84c..6e0c9f8debdc 100644
--- a/config/cachet.php
+++ b/config/cachet.php
@@ -31,7 +31,7 @@
|
*/
- 'is_docker' => env('DOCKER', false),
+ 'is_docker' => env('DOCKER', false),
/*
|--------------------------------------------------------------------------
@@ -44,6 +44,23 @@
|
*/
- 'beacon' => env('CACHET_BEACON', true),
+ 'beacon' => env('CACHET_BEACON', true),
+ /*
+ |--------------------------------------------------------------------------
+ | Templates configurations
+ |--------------------------------------------------------------------------
+ |
+ | Security fix: now user can provide information which will be included to the Twig sandbox settings
+ |
+ | Default: Described below
+ |
+ */
+ 'twig' => [
+ 'methods' => [],
+ 'functions' => [],
+ 'filters' => ['escape'],
+ 'tags' => ['if'],
+ 'props' => [],
+ ],
];
diff --git a/config/cors.php b/config/cors.php
index fb12f8c9df49..6e843598bebd 100644
--- a/config/cors.php
+++ b/config/cors.php
@@ -10,6 +10,7 @@
*/
return [
+
/*
|--------------------------------------------------------------------------
| Laravel CORS
@@ -19,11 +20,13 @@
| to accept any value.
|
*/
- 'supportsCredentials' => false,
- 'allowedOrigins' => ['*'],
- 'allowedHeaders' => ['X-Cachet-Token'],
- 'allowedMethods' => ['*'],
- 'exposedHeaders' => [],
- 'maxAge' => 3600,
- 'hosts' => [],
+
+ 'supportsCredentials' => false,
+ 'allowedOrigins' => ['*'],
+ 'allowedOriginsPatterns' => [],
+ 'allowedHeaders' => ['X-Cachet-Token'],
+ 'allowedMethods' => ['*'],
+ 'exposedHeaders' => [],
+ 'maxAge' => 3600,
+
];
diff --git a/config/css-inliner.php b/config/css-inliner.php
deleted file mode 100644
index f1e9c78bf342..000000000000
--- a/config/css-inliner.php
+++ /dev/null
@@ -1,41 +0,0 @@
- true,
-
- /*
- |--------------------------------------------------------------------------
- | Remove classes
- |--------------------------------------------------------------------------
- |
- | Settings this to false disables the removal of class attributes from
- | your html elements (do not enable this if you use media queries)
- |
- */
-
- 'strip-classes' => true,
-
-];
diff --git a/config/database.php b/config/database.php
index b6d967af0e50..bb5f8221b91b 100644
--- a/config/database.php
+++ b/config/database.php
@@ -11,19 +11,6 @@
return [
- /*
- |--------------------------------------------------------------------------
- | PDO Fetch Style
- |--------------------------------------------------------------------------
- |
- | By default, database results will be returned as instances of the PHP
- | stdClass object; however, you may desire to retrieve records in an
- | array format for simplicity. Here you can tweak the fetch style.
- |
- */
-
- 'fetch' => PDO::FETCH_CLASS,
-
/*
|--------------------------------------------------------------------------
| Default Database Connection Name
@@ -58,33 +45,35 @@
'sqlite' => [
'driver' => 'sqlite',
'database' => env('DB_DATABASE', database_path('database.sqlite')),
- 'prefix' => env('DB_PREFIX', null),
+ 'prefix' => '',
],
'mysql' => [
- 'driver' => 'mysql',
- 'host' => env('DB_HOST', null),
- 'database' => env('DB_DATABASE', null),
- 'username' => env('DB_USERNAME', null),
- 'password' => env('DB_PASSWORD', null),
- 'port' => env('DB_PORT', '3306'),
- 'charset' => 'utf8',
- 'collation' => 'utf8_unicode_ci',
- 'prefix' => env('DB_PREFIX', null),
- 'strict' => false,
- 'engine' => null,
+ 'driver' => 'mysql',
+ 'host' => env('DB_HOST', '127.0.0.1'),
+ 'unix_socket' => env('DB_UNIX_SOCKET', null),
+ 'port' => env('DB_PORT', '3306'),
+ 'database' => env('DB_DATABASE', 'forge'),
+ 'username' => env('DB_USERNAME', 'forge'),
+ 'password' => env('DB_PASSWORD', ''),
+ 'charset' => 'utf8mb4',
+ 'collation' => 'utf8mb4_unicode_ci',
+ 'prefix' => env('DB_PREFIX', null),
+ 'strict' => false,
+ 'engine' => null,
],
'pgsql' => [
'driver' => 'pgsql',
- 'host' => env('DB_HOST', null),
- 'database' => env('DB_DATABASE', null),
- 'username' => env('DB_USERNAME', null),
- 'password' => env('DB_PASSWORD', null),
+ 'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '5432'),
+ 'database' => env('DB_DATABASE', 'forge'),
+ 'username' => env('DB_USERNAME', 'forge'),
+ 'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => env('DB_PREFIX', null),
'schema' => env('DB_SCHEMA', 'public'),
+ 'sslmode' => 'prefer',
],
],
@@ -115,13 +104,13 @@
'redis' => [
- 'cluster' => false,
+ 'client' => 'predis',
'default' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
+ 'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_DATABASE', 0),
- 'password' => env('REDIS_PASSWORD', null),
],
],
diff --git a/config/debugbar.php b/config/debugbar.php
new file mode 100644
index 000000000000..f2591b99f80f
--- /dev/null
+++ b/config/debugbar.php
@@ -0,0 +1,201 @@
+ env('DEBUGBAR_ENABLED', null),
+
+ /*
+ |--------------------------------------------------------------------------
+ | Storage settings
+ |--------------------------------------------------------------------------
+ |
+ | DebugBar stores data for session/ajax requests.
+ | You can disable this, so the debugbar stores data in headers/session,
+ | but this can cause problems with large data collectors.
+ | By default, file storage (in the storage folder) is used. Redis and PDO
+ | can also be used. For PDO, run the package migrations first.
+ |
+ */
+ 'storage' => [
+ 'enabled' => true,
+ 'driver' => 'file', // redis, file, pdo, custom
+ 'path' => storage_path('debugbar'), // For file driver
+ 'connection' => null, // Leave null for default connection (Redis/PDO)
+ 'provider' => '', // Instance of StorageInterface for custom driver
+ ],
+
+ /*
+ |--------------------------------------------------------------------------
+ | Vendors
+ |--------------------------------------------------------------------------
+ |
+ | Vendor files are included by default, but can be set to false.
+ | This can also be set to 'js' or 'css', to only include javascript or css vendor files.
+ | Vendor files are for css: font-awesome (including fonts) and highlight.js (css files)
+ | and for js: jquery and and highlight.js
+ | So if you want syntax highlighting, set it to true.
+ | jQuery is set to not conflict with existing jQuery scripts.
+ |
+ */
+
+ 'include_vendors' => true,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Capture Ajax Requests
+ |--------------------------------------------------------------------------
+ |
+ | The Debugbar can capture Ajax requests and display them. If you don't want this (ie. because of errors),
+ | you can use this option to disable sending the data through the headers.
+ |
+ | Optionally, you can also send ServerTiming headers on ajax requests for the Chrome DevTools.
+ */
+
+ 'capture_ajax' => true,
+ 'add_ajax_timing' => false,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Custom Error Handler for Deprecated warnings
+ |--------------------------------------------------------------------------
+ |
+ | When enabled, the Debugbar shows deprecated warnings for Symfony components
+ | in the Messages tab.
+ |
+ */
+ 'error_handler' => false,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Clockwork integration
+ |--------------------------------------------------------------------------
+ |
+ | The Debugbar can emulate the Clockwork headers, so you can use the Chrome
+ | Extension, without the server-side code. It uses Debugbar collectors instead.
+ |
+ */
+ 'clockwork' => false,
+
+ /*
+ |--------------------------------------------------------------------------
+ | DataCollectors
+ |--------------------------------------------------------------------------
+ |
+ | Enable/disable DataCollectors
+ |
+ */
+
+ 'collectors' => [
+ 'phpinfo' => true, // Php version
+ 'messages' => true, // Messages
+ 'time' => true, // Time Datalogger
+ 'memory' => true, // Memory usage
+ 'exceptions' => true, // Exception displayer
+ 'log' => true, // Logs from Monolog (merged in messages if enabled)
+ 'db' => true, // Show database (PDO) queries and bindings
+ 'views' => true, // Views with their data
+ 'route' => true, // Current route information
+ 'auth' => true, // Display Laravel authentication status
+ 'gate' => true, // Display Laravel Gate checks
+ 'session' => true, // Display session data
+ 'symfony_request' => true, // Only one can be enabled..
+ 'mail' => true, // Catch mail messages
+ 'laravel' => false, // Laravel version and environment
+ 'events' => false, // All events fired
+ 'default_request' => false, // Regular or special Symfony request logger
+ 'logs' => false, // Add the latest log messages
+ 'files' => false, // Show the included files
+ 'config' => false, // Display config settings
+ ],
+
+ /*
+ |--------------------------------------------------------------------------
+ | Extra options
+ |--------------------------------------------------------------------------
+ |
+ | Configure some DataCollectors
+ |
+ */
+
+ 'options' => [
+ 'auth' => [
+ 'show_name' => true, // Also show the users name/email in the debugbar
+ ],
+ 'db' => [
+ 'with_params' => true, // Render SQL with the parameters substituted
+ 'backtrace' => true, // Use a backtrace to find the origin of the query in your files.
+ 'timeline' => false, // Add the queries to the timeline
+ 'explain' => [ // Show EXPLAIN output on queries
+ 'enabled' => false,
+ 'types' => ['SELECT'], // ['SELECT', 'INSERT', 'UPDATE', 'DELETE']; for MySQL 5.6.3+
+ ],
+ 'hints' => true, // Show hints for common mistakes
+ ],
+ 'mail' => [
+ 'full_log' => false,
+ ],
+ 'views' => [
+ 'data' => false, //Note: Can slow down the application, because the data can be quite large..
+ ],
+ 'route' => [
+ 'label' => true, // show complete route on bar
+ ],
+ 'logs' => [
+ 'file' => null,
+ ],
+ ],
+
+ /*
+ |--------------------------------------------------------------------------
+ | Inject Debugbar in Response
+ |--------------------------------------------------------------------------
+ |
+ | Usually, the debugbar is added just before