├── .gitignore ├── tests ├── bootstrap.php ├── PhpFcmTestCase.php ├── ClientTest.php ├── NotificationTest.php └── MessageTest.php ├── src ├── Recipient │ ├── Recipient.php │ ├── Topic.php │ └── Device.php ├── ClientInterface.php ├── Client.php ├── Notification.php └── Message.php ├── .travis.yml ├── phpunit.xml.dist ├── composer.json ├── LICENSE ├── README.md └── composer.lock /.gitignore: -------------------------------------------------------------------------------- 1 | vendor 2 | .project 3 | .buildpath 4 | .settings -------------------------------------------------------------------------------- /tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | name = $name; 11 | } 12 | 13 | public function getIdentifier() 14 | { 15 | return $this->name; 16 | } 17 | } -------------------------------------------------------------------------------- /src/Recipient/Device.php: -------------------------------------------------------------------------------- 1 | token = $token; 11 | } 12 | 13 | public function getIdentifier() 14 | { 15 | return $this->token; 16 | } 17 | } -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | tests 6 | 7 | 8 | 9 | 10 | src 11 | 12 | src/ 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/ClientInterface.php: -------------------------------------------------------------------------------- 1 | =5.5" 20 | }, 21 | "require-dev": { 22 | "phpunit/phpunit": "4.8.*", 23 | "mockery/mockery" : "0.9.5", 24 | "satooshi/php-coveralls": "dev-master" 25 | }, 26 | "autoload": { 27 | "psr-4": { 28 | "paragraph1\\phpFCM\\": "src/" 29 | } 30 | }, 31 | "autoload-dev": { 32 | "psr-4": { 33 | "paragraph1\\phpFCM\\Tests\\": "tests/" 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Paragraph1 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /tests/ClientTest.php: -------------------------------------------------------------------------------- 1 | fixture = new Client(); 19 | } 20 | 21 | public function testSendConstruesValidJsonForNotificationWithTopic() 22 | { 23 | $apiKey = 'key'; 24 | $headers = array( 25 | 'Authorization' => sprintf('key=%s', $apiKey), 26 | 'Content-Type' => 'application/json' 27 | ); 28 | 29 | $guzzle = \Mockery::mock(\GuzzleHttp\Client::class); 30 | $guzzle->shouldReceive('post') 31 | ->once() 32 | ->with(Client::DEFAULT_API_URL, array('headers' => $headers, 'body' => '{"to":"\\/topics\\/test","priority":"high"}')) 33 | ->andReturn(\Mockery::mock(Response::class)); 34 | 35 | $this->fixture->injectHttpClient($guzzle); 36 | $this->fixture->setApiKey($apiKey); 37 | 38 | $message = new Message(); 39 | $message->addRecipient(new Topic('test')); 40 | 41 | $this->fixture->send($message); 42 | } 43 | 44 | public function testProxyUriOverridesDefaultUrl() 45 | { 46 | $proxy = 'my_nice_proxy_around_that_server'; 47 | $this->fixture->setProxyApiUrl($proxy); 48 | $guzzle = \Mockery::mock(\GuzzleHttp\Client::class); 49 | $guzzle->shouldReceive('post') 50 | ->once() 51 | ->with($proxy, \Mockery::any()) 52 | ->andReturn(\Mockery::mock(Response::class)); 53 | $this->fixture->injectHttpClient($guzzle); 54 | 55 | $message = new Message(); 56 | $message->addRecipient(new Topic('test')); 57 | 58 | $this->fixture->send($message); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /tests/NotificationTest.php: -------------------------------------------------------------------------------- 1 | fixture = new Notification('foo', 'bar'); 14 | } 15 | 16 | public function testJsonSerializeWithMinimalConfigurations() 17 | { 18 | $this->assertEquals(array('title' => 'foo', 'body' =>'bar'), $this->fixture->jsonSerialize()); 19 | } 20 | 21 | public function testJsonSerializeWithBadge() 22 | { 23 | $this->fixture->setBadge(1); 24 | $this->assertEquals(array('title' => 'foo', 'body' =>'bar', 'badge' => 1), $this->fixture->jsonSerialize()); 25 | } 26 | 27 | public function testJsonSerializeWithIcon() 28 | { 29 | $this->fixture->setIcon('name'); 30 | $this->assertEquals(array('title' => 'foo', 'body' =>'bar', 'icon' => 'name'), $this->fixture->jsonSerialize()); 31 | } 32 | 33 | public function testJsonSerializeWithClickAction() 34 | { 35 | $this->fixture->setClickAction('INTENT_NAME'); 36 | $this->assertEquals(array('title' => 'foo', 'body' =>'bar', 'click_action' => 'INTENT_NAME'), $this->fixture->jsonSerialize()); 37 | } 38 | 39 | public function testJsonSerializeWithSound() 40 | { 41 | $this->fixture->setSound('mySound.mp3'); 42 | $this->assertEquals(array('title' => 'foo', 'body' =>'bar', 'sound' => 'mySound.mp3'), $this->fixture->jsonSerialize()); 43 | } 44 | 45 | public function testJsonSerializeWithColor() 46 | { 47 | $this->fixture->setColor('#ffffff'); 48 | $this->assertEquals(array('title' => 'foo', 'body' =>'bar', 'color' => '#ffffff'), $this->fixture->jsonSerialize()); 49 | } 50 | 51 | public function testJsonSerializeWithTag() 52 | { 53 | $this->fixture->setTag('foo'); 54 | $this->assertEquals(array('title' => 'foo', 'body' =>'bar', 'tag' => 'foo'), $this->fixture->jsonSerialize()); 55 | } 56 | } -------------------------------------------------------------------------------- /src/Client.php: -------------------------------------------------------------------------------- 1 | guzzleClient = $client; 25 | } 26 | 27 | /** 28 | * add your server api key here 29 | * read how to obtain an api key here: https://firebase.google.com/docs/server/setup#prerequisites 30 | * 31 | * @param string $apiKey 32 | * 33 | * @return \paragraph1\phpFCM\Client 34 | */ 35 | public function setApiKey($apiKey) 36 | { 37 | $this->apiKey = $apiKey; 38 | return $this; 39 | } 40 | 41 | /** 42 | * people can overwrite the api url with a proxy server url of their own 43 | * 44 | * @param string $url 45 | * 46 | * @return \paragraph1\phpFCM\Client 47 | */ 48 | public function setProxyApiUrl($url) 49 | { 50 | $this->proxyApiUrl = $url; 51 | return $this; 52 | } 53 | 54 | /** 55 | * sends your notification to the google servers and returns a guzzle repsonse object 56 | * containing their answer. 57 | * 58 | * @param Message $message 59 | * 60 | * @return \Psr\Http\Message\ResponseInterface 61 | * @throws \GuzzleHttp\Exception\RequestException 62 | */ 63 | public function send(Message $message) 64 | { 65 | return $this->guzzleClient->post( 66 | $this->getApiUrl(), 67 | [ 68 | 'headers' => [ 69 | 'Authorization' => sprintf('key=%s', $this->apiKey), 70 | 'Content-Type' => 'application/json' 71 | ], 72 | 'body' => json_encode($message) 73 | ] 74 | ); 75 | } 76 | 77 | private function getApiUrl() 78 | { 79 | return isset($this->proxyApiUrl) ? $this->proxyApiUrl : self::DEFAULT_API_URL; 80 | } 81 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # phpFCM 2 | [![Build Status](https://travis-ci.org/Paragraph1/php-fcm.svg?branch=master)](https://travis-ci.org/Paragraph1/php-fcm) 3 | [![Coverage Status](https://coveralls.io/repos/github/Paragraph1/php-fcm/badge.svg?branch=master)](https://coveralls.io/github/Paragraph1/php-fcm?branch=master) 4 | [![Latest Stable Version](https://poser.pugx.org/paragraph1/php-fcm/v/stable)](https://packagist.org/packages/paragraph1/php-fcm) 5 | [![Total Downloads](https://poser.pugx.org/paragraph1/php-fcm/downloads)](https://packagist.org/packages/paragraph1/php-fcm) 6 | [![License](https://poser.pugx.org/paragraph1/php-fcm/license)](https://packagist.org/packages/paragraph1/php-fcm) 7 | 8 | PHP application server implementation for Firebase Cloud Messaging. 9 | - supports device and topic messages 10 | - currently this app server library only supports sending Messages/Notifications via HTTP. 11 | - thanks to guzzle our library answers in PSR7 compatible response objects 12 | - see the full docs on firebase cloud messaging here : https://firebase.google.com/docs/cloud-messaging/ 13 | - Firebase Cloud Messaging HTTP Protocol: https://firebase.google.com/docs/cloud-messaging/http-server-ref#send-downstream for in-depth description 14 | 15 | 16 | #Setup 17 | The recommended way of installing is using Composer. 18 | 19 | command line 20 | ``` 21 | composer require paragraph1/php-fcm 22 | ``` 23 | 24 | composer.json 25 | ``` 26 | "require": { 27 | "paragraph1/php-fcm": "*" 28 | } 29 | ``` 30 | 31 | #Send to Device 32 | also see https://firebase.google.com/docs/cloud-messaging/downstream 33 | ```php 34 | use paragraph1\phpFCM\Client; 35 | use paragraph1\phpFCM\Message; 36 | use paragraph1\phpFCM\Recipient\Device; 37 | use paragraph1\phpFCM\Notification; 38 | 39 | require_once 'vendor/autoload.php'; 40 | 41 | $apiKey = 'YOUR SERVER KEY'; 42 | $client = new Client(); 43 | $client->setApiKey($apiKey); 44 | $client->injectHttpClient(new \GuzzleHttp\Client()); 45 | 46 | $note = new Notification('test title', 'testing body'); 47 | $note->setIcon('notification_icon_resource_name') 48 | ->setColor('#ffffff') 49 | ->setBadge(1); 50 | 51 | $message = new Message(); 52 | $message->addRecipient(new Device('your-device-token')); 53 | $message->setNotification($note) 54 | ->setData(array('someId' => 111)); 55 | 56 | $response = $client->send($message); 57 | var_dump($response->getStatusCode()); 58 | ``` 59 | 60 | #Send to topic 61 | also see https://firebase.google.com/docs/cloud-messaging/topic-messaging 62 | ```php 63 | use paragraph1\phpFCM\Client; 64 | use paragraph1\phpFCM\Message; 65 | use paragraph1\phpFCM\Recipient\Topic; 66 | use paragraph1\phpFCM\Notification; 67 | 68 | require_once 'vendor/autoload.php'; 69 | 70 | 71 | $apiKey = 'YOUR SERVER KEY'; 72 | $client = new Client(); 73 | $client->setApiKey($apiKey); 74 | $client->injectHttpClient(new \GuzzleHttp\Client()); 75 | 76 | $message = new Message(); 77 | $message->addRecipient(new Topic('your-topic')); 78 | //select devices where has 'your-topic1' && 'your-topic2' topics 79 | $message->addRecipient(new Topic(['your-topic1', 'your-topic2'])); 80 | $message->setNotification(new Notification('test title', 'testing body')) 81 | ->setData(array('someId' => 111)); 82 | 83 | $response = $client->send($message); 84 | var_dump($response->getStatusCode()); 85 | ``` -------------------------------------------------------------------------------- /src/Notification.php: -------------------------------------------------------------------------------- 1 | title = $title; 22 | $this->body = $body; 23 | $this->image = $image; 24 | } 25 | 26 | /** 27 | * android only: notification title (also works for ios watches) 28 | * 29 | * @param string $title 30 | * 31 | * @return \paragraph1\phpFCM\Notification 32 | */ 33 | public function setTitle($title) 34 | { 35 | $this->title = $title; 36 | return $this; 37 | } 38 | 39 | /** 40 | * android/ios: the body text is the main content of the notification 41 | * 42 | * @param string $body 43 | * 44 | * @return \paragraph1\phpFCM\Notification 45 | */ 46 | public function setBody($body) 47 | { 48 | $this->body = $body; 49 | return $this; 50 | } 51 | 52 | /** 53 | * iOS only: will add smal red bubbles indicating the number of notifications to your apps icon 54 | * 55 | * @param integer $badge 56 | * 57 | * @return \paragraph1\phpFCM\Notification 58 | */ 59 | public function setBadge($badge) 60 | { 61 | $this->badge = $badge; 62 | return $this; 63 | } 64 | 65 | /** 66 | * android only: set the name of your drawable resource as string 67 | * 68 | * @param string $icon the drawable name without .xml 69 | * 70 | * @return \paragraph1\phpFCM\Notification 71 | */ 72 | public function setIcon($icon) 73 | { 74 | $this->icon = $icon; 75 | return $this; 76 | } 77 | 78 | /** 79 | * android only: background color of the notification icon when showing details on notifications 80 | * 81 | * @param string $color in #rrggbb format 82 | * 83 | * @return \paragraph1\phpFCM\Notification 84 | */ 85 | public function setColor($color) 86 | { 87 | $this->color = $color; 88 | return $this; 89 | } 90 | 91 | /** 92 | * android/ios: what should happen upon notification click. when empty on android the default activity 93 | * will be launched passing any payload to an intent. 94 | * 95 | * @param string $actionName on android: intent name, on ios: category in apns payload 96 | * 97 | * @return \paragraph1\phpFCM\Notification 98 | */ 99 | public function setClickAction($actionName) 100 | { 101 | $this->clickAction = $actionName; 102 | return $this; 103 | } 104 | 105 | /** 106 | * android only: when set notification will replace prior notifications from the same app with the same 107 | * tag. 108 | * 109 | * @param string $tag 110 | * 111 | * @return \paragraph1\phpFCM\Notification 112 | */ 113 | public function setTag($tag) 114 | { 115 | $this->tag = $tag; 116 | return $this; 117 | } 118 | 119 | /** 120 | * android/ios: can be default or a filename of a sound resource bundled in the app. 121 | * @see https://firebase.google.com/docs/cloud-messaging/http-server-ref#notification-payload-support 122 | * 123 | * @param string $sound a sounds filename 124 | * 125 | * @return \paragraph1\phpFCM\Notification 126 | */ 127 | public function setSound($sound) 128 | { 129 | $this->sound = $sound; 130 | return $this; 131 | } 132 | 133 | public function jsonSerialize() 134 | { 135 | $jsonData = array(); 136 | 137 | if ($this->title) { 138 | $jsonData['title'] = $this->title; 139 | } 140 | 141 | $jsonData['body'] = $this->body; 142 | 143 | if ($this->badge) { 144 | $jsonData['badge'] = $this->badge; 145 | } 146 | if ($this->icon) { 147 | $jsonData['icon'] = $this->icon; 148 | } 149 | if ($this->clickAction) { 150 | $jsonData['click_action'] = $this->clickAction; 151 | } 152 | if ($this->sound) { 153 | $jsonData['sound'] = $this->sound; 154 | } 155 | if ($this->color) { 156 | $jsonData['color'] = $this->color; 157 | } 158 | if ($this->tag) { 159 | $jsonData['tag'] = $this->tag; 160 | } 161 | if ($this->image) { 162 | $jsonData['image'] = $this->image; 163 | } 164 | 165 | return $jsonData; 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /tests/MessageTest.php: -------------------------------------------------------------------------------- 1 | fixture = new Message(); 18 | } 19 | 20 | public function testThrowsExceptionWhenDifferentRecepientTypesAreRegistered() 21 | { 22 | $this->setExpectedException(\InvalidArgumentException::class, 'mixed recepient types are not supported by FCM'); 23 | $this->fixture->addRecipient(new Topic('breaking-news')) 24 | ->addRecipient(new Device('token')); 25 | } 26 | 27 | public function testThrowsExceptionWhenNoRecepientWasAdded() 28 | { 29 | $this->setExpectedException(\UnexpectedValueException::class, 'message must have at least one recipient'); 30 | $this->fixture->jsonSerialize(); 31 | } 32 | 33 | public function testWorksCorrectlyWithMultipleTopics() 34 | { 35 | $body = '{"condition":"\'topic1\' in topics || \'topic2\' in topics","data":{"foo":"bar"},"priority":"high"}'; 36 | 37 | $this->fixture->addRecipient(new Topic('topic1')) 38 | ->addRecipient(new Topic('topic2')) 39 | ->setData(['foo' => 'bar']); 40 | 41 | $this->assertSame( 42 | $body, 43 | json_encode($this->fixture) 44 | ); 45 | } 46 | 47 | public function testWorksCorrectlyWithMultipleTopicsAnd() 48 | { 49 | $body = '{"condition":"(\'topic1\' in topics && \'topic2\' in topics)","data":{"foo":"bar"},"priority":"high"}'; 50 | 51 | $this->fixture->addRecipient(new Topic(['topic1','topic2'])) 52 | ->setData(['foo' => 'bar']); 53 | 54 | $this->assertSame( 55 | $body, 56 | json_encode($this->fixture) 57 | ); 58 | } 59 | 60 | public function testJsonEncodeWorksOnTopicRecipients() 61 | { 62 | $body = '{"to":"\/topics\/breaking-news","priority":"high","notification":{"title":"test","body":"a nice testing notification"}}'; 63 | 64 | $notification = new Notification('test', 'a nice testing notification'); 65 | $this->fixture->setNotification($notification); 66 | 67 | $this->fixture->addRecipient(new Topic('breaking-news')); 68 | $this->assertSame( 69 | $body, 70 | json_encode($this->fixture) 71 | ); 72 | } 73 | 74 | public function testJsonEncodeWorksOnDeviceRecipients() 75 | { 76 | $body = '{"to":"deviceId","priority":"high","notification":{"title":"test","body":"a nice testing notification"}}'; 77 | 78 | $notification = new Notification('test', 'a nice testing notification'); 79 | $this->fixture->setNotification($notification); 80 | 81 | $this->fixture->addRecipient(new Device('deviceId')); 82 | $this->assertSame( 83 | $body, 84 | json_encode($this->fixture) 85 | ); 86 | } 87 | 88 | public function testAddingMultipleDeviceRecipientsAddsRegistrationIds() 89 | { 90 | $body = '{"registration_ids":["deviceId","anotherDeviceId"],"priority":"high","notification":{"title":"test","body":"a nice testing notification"}}'; 91 | 92 | $notification = new Notification('test', 'a nice testing notification'); 93 | $this->fixture->setNotification($notification); 94 | 95 | $this->fixture->addRecipient(new Device('deviceId')) 96 | ->addRecipient(new Device('anotherDeviceId')); 97 | 98 | $this->assertSame( 99 | $body, 100 | json_encode($this->fixture) 101 | ); 102 | } 103 | 104 | public function testJsonEncodeCorrectlyHandlesCollapseKeyAndData() 105 | { 106 | $body = '{"to":"\/topics\/testing","collapse_key":"collapseMe","data":{"foo":"bar"},"priority":"normal"}'; 107 | 108 | $this->fixture->setData(['foo' => 'bar']) 109 | ->setCollapseKey('collapseMe') 110 | ->setPriority(Message::PRIORITY_NORMAL); 111 | 112 | $this->fixture->addRecipient(new Topic('testing')); 113 | $this->assertSame( 114 | $body, 115 | json_encode($this->fixture) 116 | ); 117 | } 118 | 119 | public function testJsonEncodeHandlesTTL() 120 | { 121 | $body = '{"to":"\/topics\/testing","data":{"foo":"bar"},"priority":"high","time_to_live":3}'; 122 | 123 | $this->fixture->setData(['foo' => 'bar']) 124 | ->setTimeToLive(3); 125 | 126 | $this->fixture->addRecipient(new Topic('testing')); 127 | 128 | $this->assertSame( 129 | $body, 130 | json_encode($this->fixture) 131 | ); 132 | } 133 | 134 | public function testJsonEncodeHandlesDelayIdle() 135 | { 136 | $body = '{"to":"\/topics\/testing","data":{"foo":"bar"},"priority":"high","delay_while_idle":true}'; 137 | 138 | $this->fixture->setData(['foo' => 'bar']) 139 | ->setDelayWhileIdle(true); 140 | 141 | $this->fixture->addRecipient(new Topic('testing')); 142 | 143 | $this->assertSame( 144 | $body, 145 | json_encode($this->fixture) 146 | ); 147 | } 148 | 149 | public function testAddingNewAndUnknownRecipientTypesYieldsException() 150 | { 151 | $this->setExpectedException(\UnexpectedValueException::class); 152 | $this->fixture->addRecipient(\Mockery::mock(Recipient::class)); 153 | } 154 | 155 | public function testJsonEncodeWorksWithContentAvailableFlag() 156 | { 157 | $body = '{"to":"deviceId","priority":"high","content_available":true}'; 158 | 159 | $this->fixture->setContentAvailable(); 160 | $this->fixture->addRecipient(new Device('deviceId')); 161 | $this->assertSame( 162 | $body, 163 | json_encode($this->fixture) 164 | ); 165 | } 166 | 167 | public function testJsonEncodeWorksWithoutContentAvailableFlag() 168 | { 169 | $body = '{"to":"deviceId","priority":"high"}'; 170 | 171 | $this->fixture->addRecipient(new Device('deviceId')); 172 | $this->assertSame( 173 | $body, 174 | json_encode($this->fixture) 175 | ); 176 | } 177 | 178 | } 179 | -------------------------------------------------------------------------------- /src/Message.php: -------------------------------------------------------------------------------- 1 | recipientType)) { 55 | $this->recipientType = get_class($recipient); 56 | } 57 | 58 | if ($this->recipientType !== get_class($recipient)) { 59 | throw new \InvalidArgumentException('mixed recepient types are not supported by FCM'); 60 | } 61 | 62 | $this->recipients[] = $recipient; 63 | return $this; 64 | } 65 | 66 | public function setNotification(Notification $notification) 67 | { 68 | $this->notification = $notification; 69 | return $this; 70 | } 71 | 72 | /** 73 | * @see https://firebase.google.com/docs/cloud-messaging/concept-options#collapsible_and_non-collapsible_messages 74 | * 75 | * @param string $collapseKey 76 | * 77 | * @return \paragraph1\phpFCM\Message 78 | */ 79 | public function setCollapseKey($collapseKey) 80 | { 81 | $this->collapseKey = $collapseKey; 82 | return $this; 83 | } 84 | 85 | /** 86 | * normal or high, use class constants as value 87 | * @see https://firebase.google.com/docs/cloud-messaging/concept-options#setting-the-priority-of-a-message 88 | * 89 | * @param string $priority use the class constants 90 | * 91 | * @return \paragraph1\phpFCM\Message 92 | */ 93 | public function setPriority($priority) 94 | { 95 | $this->priority = $priority; 96 | return $this; 97 | } 98 | 99 | /** 100 | * @see https://firebase.google.com/docs/cloud-messaging/concept-options#ttl 101 | * 102 | * @param integer $ttl 103 | * 104 | * @return \paragraph1\phpFCM\Message 105 | */ 106 | public function setTimeToLive($ttl) 107 | { 108 | $this->timeToLive = $ttl; 109 | 110 | return $this; 111 | } 112 | 113 | /** 114 | * @see https://firebase.google.com/docs/cloud-messaging/concept-options#lifetime 115 | * 116 | * @param bool $delayWhileIdle 117 | * 118 | * @return \paragraph1\phpFCM\Message 119 | */ 120 | public function setDelayWhileIdle($delayWhileIdle) 121 | { 122 | $this->delayWhileIdle = $delayWhileIdle; 123 | return $this; 124 | } 125 | 126 | /** 127 | * @see https://firebase.google.com/docs/cloud-messaging/concept-options#collapsible_and_non-collapsible_messages 128 | * 129 | * @return \paragraph1\phpFCM\Message 130 | */ 131 | public function setContentAvailable() { 132 | $this->contentAvailableFlag = TRUE; 133 | return $this; 134 | } 135 | 136 | public function setData(array $data) 137 | { 138 | $this->data = $data; 139 | return $this; 140 | } 141 | 142 | public function jsonSerialize() 143 | { 144 | $jsonData = array(); 145 | 146 | if (empty($this->recipients)) { 147 | throw new \UnexpectedValueException('message must have at least one recipient'); 148 | } 149 | 150 | $this->createTo($jsonData); 151 | if ($this->collapseKey) { 152 | $jsonData['collapse_key'] = $this->collapseKey; 153 | } 154 | if ($this->data) { 155 | $jsonData['data'] = $this->data; 156 | } 157 | if ($this->priority) { 158 | $jsonData['priority'] = $this->priority; 159 | } 160 | if ($this->notification) { 161 | $jsonData['notification'] = $this->notification; 162 | } 163 | if ($this->timeToLive) { 164 | $jsonData['time_to_live'] = (int)$this->timeToLive; 165 | } 166 | if ($this->delayWhileIdle) { 167 | $jsonData['delay_while_idle'] = (bool)$this->delayWhileIdle; 168 | } 169 | if ($this->contentAvailableFlag === TRUE) { 170 | $jsonData['content_available'] = TRUE; 171 | } 172 | 173 | return $jsonData; 174 | } 175 | 176 | private function createTo(array &$jsonData) 177 | { 178 | switch ($this->recipientType) { 179 | case Topic::class: 180 | if (count($this->recipients) > 1 || is_array(current($this->recipients)->getIdentifier())) { 181 | $topics = array_map( 182 | function (Topic $topic) { 183 | $identity = $topic->getIdentifier(); 184 | 185 | if (is_array($identity)) { 186 | $conditions = array_map(function ($condition) { 187 | return sprintf("'%s' in topics", $condition); 188 | }, $identity); 189 | 190 | return '(' . implode(' && ', $conditions) . ')'; 191 | } else { 192 | return sprintf("'%s' in topics", $topic->getIdentifier()); 193 | } 194 | }, 195 | $this->recipients 196 | ); 197 | $jsonData['condition'] = implode(' || ', $topics); 198 | return; 199 | } 200 | $jsonData['to'] = sprintf('/topics/%s', current($this->recipients)->getIdentifier()); 201 | break; 202 | default: 203 | if (count($this->recipients) === 1) { 204 | $jsonData['to'] = current($this->recipients)->getIdentifier(); 205 | } elseif(count($this->recipients) > 1) { 206 | $jsonData['registration_ids'] = array(); 207 | 208 | foreach($this->recipients as $recipient) { 209 | $jsonData['registration_ids'][] = $recipient->getIdentifier(); 210 | } 211 | } 212 | } 213 | } 214 | } -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", 5 | "This file is @generated automatically" 6 | ], 7 | "hash": "c0e5d553fe0ca7eb104838c469da2b8a", 8 | "content-hash": "e5c0a92189ae8d5af3a6ff26ee377cf6", 9 | "packages": [ 10 | { 11 | "name": "guzzlehttp/guzzle", 12 | "version": "6.2.0", 13 | "source": { 14 | "type": "git", 15 | "url": "https://github.com/guzzle/guzzle.git", 16 | "reference": "d094e337976dff9d8e2424e8485872194e768662" 17 | }, 18 | "dist": { 19 | "type": "zip", 20 | "url": "https://api.github.com/repos/guzzle/guzzle/zipball/d094e337976dff9d8e2424e8485872194e768662", 21 | "reference": "d094e337976dff9d8e2424e8485872194e768662", 22 | "shasum": "" 23 | }, 24 | "require": { 25 | "guzzlehttp/promises": "~1.0", 26 | "guzzlehttp/psr7": "~1.1", 27 | "php": ">=5.5.0" 28 | }, 29 | "require-dev": { 30 | "ext-curl": "*", 31 | "phpunit/phpunit": "~4.0", 32 | "psr/log": "~1.0" 33 | }, 34 | "type": "library", 35 | "extra": { 36 | "branch-alias": { 37 | "dev-master": "6.2-dev" 38 | } 39 | }, 40 | "autoload": { 41 | "files": [ 42 | "src/functions_include.php" 43 | ], 44 | "psr-4": { 45 | "GuzzleHttp\\": "src/" 46 | } 47 | }, 48 | "notification-url": "https://packagist.org/downloads/", 49 | "license": [ 50 | "MIT" 51 | ], 52 | "authors": [ 53 | { 54 | "name": "Michael Dowling", 55 | "email": "mtdowling@gmail.com", 56 | "homepage": "https://github.com/mtdowling" 57 | } 58 | ], 59 | "description": "Guzzle is a PHP HTTP client library", 60 | "homepage": "http://guzzlephp.org/", 61 | "keywords": [ 62 | "client", 63 | "curl", 64 | "framework", 65 | "http", 66 | "http client", 67 | "rest", 68 | "web service" 69 | ], 70 | "time": "2016-03-21 20:02:09" 71 | }, 72 | { 73 | "name": "guzzlehttp/promises", 74 | "version": "1.2.0", 75 | "source": { 76 | "type": "git", 77 | "url": "https://github.com/guzzle/promises.git", 78 | "reference": "c10d860e2a9595f8883527fa0021c7da9e65f579" 79 | }, 80 | "dist": { 81 | "type": "zip", 82 | "url": "https://api.github.com/repos/guzzle/promises/zipball/c10d860e2a9595f8883527fa0021c7da9e65f579", 83 | "reference": "c10d860e2a9595f8883527fa0021c7da9e65f579", 84 | "shasum": "" 85 | }, 86 | "require": { 87 | "php": ">=5.5.0" 88 | }, 89 | "require-dev": { 90 | "phpunit/phpunit": "~4.0" 91 | }, 92 | "type": "library", 93 | "extra": { 94 | "branch-alias": { 95 | "dev-master": "1.0-dev" 96 | } 97 | }, 98 | "autoload": { 99 | "psr-4": { 100 | "GuzzleHttp\\Promise\\": "src/" 101 | }, 102 | "files": [ 103 | "src/functions_include.php" 104 | ] 105 | }, 106 | "notification-url": "https://packagist.org/downloads/", 107 | "license": [ 108 | "MIT" 109 | ], 110 | "authors": [ 111 | { 112 | "name": "Michael Dowling", 113 | "email": "mtdowling@gmail.com", 114 | "homepage": "https://github.com/mtdowling" 115 | } 116 | ], 117 | "description": "Guzzle promises library", 118 | "keywords": [ 119 | "promise" 120 | ], 121 | "time": "2016-05-18 16:56:05" 122 | }, 123 | { 124 | "name": "guzzlehttp/psr7", 125 | "version": "1.3.0", 126 | "source": { 127 | "type": "git", 128 | "url": "https://github.com/guzzle/psr7.git", 129 | "reference": "31382fef2889136415751badebbd1cb022a4ed72" 130 | }, 131 | "dist": { 132 | "type": "zip", 133 | "url": "https://api.github.com/repos/guzzle/psr7/zipball/31382fef2889136415751badebbd1cb022a4ed72", 134 | "reference": "31382fef2889136415751badebbd1cb022a4ed72", 135 | "shasum": "" 136 | }, 137 | "require": { 138 | "php": ">=5.4.0", 139 | "psr/http-message": "~1.0" 140 | }, 141 | "provide": { 142 | "psr/http-message-implementation": "1.0" 143 | }, 144 | "require-dev": { 145 | "phpunit/phpunit": "~4.0" 146 | }, 147 | "type": "library", 148 | "extra": { 149 | "branch-alias": { 150 | "dev-master": "1.0-dev" 151 | } 152 | }, 153 | "autoload": { 154 | "psr-4": { 155 | "GuzzleHttp\\Psr7\\": "src/" 156 | }, 157 | "files": [ 158 | "src/functions_include.php" 159 | ] 160 | }, 161 | "notification-url": "https://packagist.org/downloads/", 162 | "license": [ 163 | "MIT" 164 | ], 165 | "authors": [ 166 | { 167 | "name": "Michael Dowling", 168 | "email": "mtdowling@gmail.com", 169 | "homepage": "https://github.com/mtdowling" 170 | } 171 | ], 172 | "description": "PSR-7 message implementation", 173 | "keywords": [ 174 | "http", 175 | "message", 176 | "stream", 177 | "uri" 178 | ], 179 | "time": "2016-04-13 19:56:01" 180 | }, 181 | { 182 | "name": "psr/http-message", 183 | "version": "1.0", 184 | "source": { 185 | "type": "git", 186 | "url": "https://github.com/php-fig/http-message.git", 187 | "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298" 188 | }, 189 | "dist": { 190 | "type": "zip", 191 | "url": "https://api.github.com/repos/php-fig/http-message/zipball/85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", 192 | "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", 193 | "shasum": "" 194 | }, 195 | "require": { 196 | "php": ">=5.3.0" 197 | }, 198 | "type": "library", 199 | "extra": { 200 | "branch-alias": { 201 | "dev-master": "1.0.x-dev" 202 | } 203 | }, 204 | "autoload": { 205 | "psr-4": { 206 | "Psr\\Http\\Message\\": "src/" 207 | } 208 | }, 209 | "notification-url": "https://packagist.org/downloads/", 210 | "license": [ 211 | "MIT" 212 | ], 213 | "authors": [ 214 | { 215 | "name": "PHP-FIG", 216 | "homepage": "http://www.php-fig.org/" 217 | } 218 | ], 219 | "description": "Common interface for HTTP messages", 220 | "keywords": [ 221 | "http", 222 | "http-message", 223 | "psr", 224 | "psr-7", 225 | "request", 226 | "response" 227 | ], 228 | "time": "2015-05-04 20:22:00" 229 | } 230 | ], 231 | "packages-dev": [ 232 | { 233 | "name": "doctrine/instantiator", 234 | "version": "1.0.5", 235 | "source": { 236 | "type": "git", 237 | "url": "https://github.com/doctrine/instantiator.git", 238 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" 239 | }, 240 | "dist": { 241 | "type": "zip", 242 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", 243 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", 244 | "shasum": "" 245 | }, 246 | "require": { 247 | "php": ">=5.3,<8.0-DEV" 248 | }, 249 | "require-dev": { 250 | "athletic/athletic": "~0.1.8", 251 | "ext-pdo": "*", 252 | "ext-phar": "*", 253 | "phpunit/phpunit": "~4.0", 254 | "squizlabs/php_codesniffer": "~2.0" 255 | }, 256 | "type": "library", 257 | "extra": { 258 | "branch-alias": { 259 | "dev-master": "1.0.x-dev" 260 | } 261 | }, 262 | "autoload": { 263 | "psr-4": { 264 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" 265 | } 266 | }, 267 | "notification-url": "https://packagist.org/downloads/", 268 | "license": [ 269 | "MIT" 270 | ], 271 | "authors": [ 272 | { 273 | "name": "Marco Pivetta", 274 | "email": "ocramius@gmail.com", 275 | "homepage": "http://ocramius.github.com/" 276 | } 277 | ], 278 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", 279 | "homepage": "https://github.com/doctrine/instantiator", 280 | "keywords": [ 281 | "constructor", 282 | "instantiate" 283 | ], 284 | "time": "2015-06-14 21:17:01" 285 | }, 286 | { 287 | "name": "hamcrest/hamcrest-php", 288 | "version": "v1.2.2", 289 | "source": { 290 | "type": "git", 291 | "url": "https://github.com/hamcrest/hamcrest-php.git", 292 | "reference": "b37020aa976fa52d3de9aa904aa2522dc518f79c" 293 | }, 294 | "dist": { 295 | "type": "zip", 296 | "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/b37020aa976fa52d3de9aa904aa2522dc518f79c", 297 | "reference": "b37020aa976fa52d3de9aa904aa2522dc518f79c", 298 | "shasum": "" 299 | }, 300 | "require": { 301 | "php": ">=5.3.2" 302 | }, 303 | "replace": { 304 | "cordoval/hamcrest-php": "*", 305 | "davedevelopment/hamcrest-php": "*", 306 | "kodova/hamcrest-php": "*" 307 | }, 308 | "require-dev": { 309 | "phpunit/php-file-iterator": "1.3.3", 310 | "satooshi/php-coveralls": "dev-master" 311 | }, 312 | "type": "library", 313 | "autoload": { 314 | "classmap": [ 315 | "hamcrest" 316 | ], 317 | "files": [ 318 | "hamcrest/Hamcrest.php" 319 | ] 320 | }, 321 | "notification-url": "https://packagist.org/downloads/", 322 | "license": [ 323 | "BSD" 324 | ], 325 | "description": "This is the PHP port of Hamcrest Matchers", 326 | "keywords": [ 327 | "test" 328 | ], 329 | "time": "2015-05-11 14:41:42" 330 | }, 331 | { 332 | "name": "mockery/mockery", 333 | "version": "0.9.5", 334 | "source": { 335 | "type": "git", 336 | "url": "https://github.com/padraic/mockery.git", 337 | "reference": "4db079511a283e5aba1b3c2fb19037c645e70fc2" 338 | }, 339 | "dist": { 340 | "type": "zip", 341 | "url": "https://api.github.com/repos/padraic/mockery/zipball/4db079511a283e5aba1b3c2fb19037c645e70fc2", 342 | "reference": "4db079511a283e5aba1b3c2fb19037c645e70fc2", 343 | "shasum": "" 344 | }, 345 | "require": { 346 | "hamcrest/hamcrest-php": "~1.1", 347 | "lib-pcre": ">=7.0", 348 | "php": ">=5.3.2" 349 | }, 350 | "require-dev": { 351 | "phpunit/phpunit": "~4.0" 352 | }, 353 | "type": "library", 354 | "extra": { 355 | "branch-alias": { 356 | "dev-master": "0.9.x-dev" 357 | } 358 | }, 359 | "autoload": { 360 | "psr-0": { 361 | "Mockery": "library/" 362 | } 363 | }, 364 | "notification-url": "https://packagist.org/downloads/", 365 | "license": [ 366 | "BSD-3-Clause" 367 | ], 368 | "authors": [ 369 | { 370 | "name": "Pádraic Brady", 371 | "email": "padraic.brady@gmail.com", 372 | "homepage": "http://blog.astrumfutura.com" 373 | }, 374 | { 375 | "name": "Dave Marshall", 376 | "email": "dave.marshall@atstsolutions.co.uk", 377 | "homepage": "http://davedevelopment.co.uk" 378 | } 379 | ], 380 | "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.", 381 | "homepage": "http://github.com/padraic/mockery", 382 | "keywords": [ 383 | "BDD", 384 | "TDD", 385 | "library", 386 | "mock", 387 | "mock objects", 388 | "mockery", 389 | "stub", 390 | "test", 391 | "test double", 392 | "testing" 393 | ], 394 | "time": "2016-05-22 21:52:33" 395 | }, 396 | { 397 | "name": "phpdocumentor/reflection-docblock", 398 | "version": "2.0.4", 399 | "source": { 400 | "type": "git", 401 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", 402 | "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" 403 | }, 404 | "dist": { 405 | "type": "zip", 406 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", 407 | "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", 408 | "shasum": "" 409 | }, 410 | "require": { 411 | "php": ">=5.3.3" 412 | }, 413 | "require-dev": { 414 | "phpunit/phpunit": "~4.0" 415 | }, 416 | "suggest": { 417 | "dflydev/markdown": "~1.0", 418 | "erusev/parsedown": "~1.0" 419 | }, 420 | "type": "library", 421 | "extra": { 422 | "branch-alias": { 423 | "dev-master": "2.0.x-dev" 424 | } 425 | }, 426 | "autoload": { 427 | "psr-0": { 428 | "phpDocumentor": [ 429 | "src/" 430 | ] 431 | } 432 | }, 433 | "notification-url": "https://packagist.org/downloads/", 434 | "license": [ 435 | "MIT" 436 | ], 437 | "authors": [ 438 | { 439 | "name": "Mike van Riel", 440 | "email": "mike.vanriel@naenius.com" 441 | } 442 | ], 443 | "time": "2015-02-03 12:10:50" 444 | }, 445 | { 446 | "name": "phpspec/prophecy", 447 | "version": "v1.6.0", 448 | "source": { 449 | "type": "git", 450 | "url": "https://github.com/phpspec/prophecy.git", 451 | "reference": "3c91bdf81797d725b14cb62906f9a4ce44235972" 452 | }, 453 | "dist": { 454 | "type": "zip", 455 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/3c91bdf81797d725b14cb62906f9a4ce44235972", 456 | "reference": "3c91bdf81797d725b14cb62906f9a4ce44235972", 457 | "shasum": "" 458 | }, 459 | "require": { 460 | "doctrine/instantiator": "^1.0.2", 461 | "php": "^5.3|^7.0", 462 | "phpdocumentor/reflection-docblock": "~2.0", 463 | "sebastian/comparator": "~1.1", 464 | "sebastian/recursion-context": "~1.0" 465 | }, 466 | "require-dev": { 467 | "phpspec/phpspec": "~2.0" 468 | }, 469 | "type": "library", 470 | "extra": { 471 | "branch-alias": { 472 | "dev-master": "1.5.x-dev" 473 | } 474 | }, 475 | "autoload": { 476 | "psr-0": { 477 | "Prophecy\\": "src/" 478 | } 479 | }, 480 | "notification-url": "https://packagist.org/downloads/", 481 | "license": [ 482 | "MIT" 483 | ], 484 | "authors": [ 485 | { 486 | "name": "Konstantin Kudryashov", 487 | "email": "ever.zet@gmail.com", 488 | "homepage": "http://everzet.com" 489 | }, 490 | { 491 | "name": "Marcello Duarte", 492 | "email": "marcello.duarte@gmail.com" 493 | } 494 | ], 495 | "description": "Highly opinionated mocking framework for PHP 5.3+", 496 | "homepage": "https://github.com/phpspec/prophecy", 497 | "keywords": [ 498 | "Double", 499 | "Dummy", 500 | "fake", 501 | "mock", 502 | "spy", 503 | "stub" 504 | ], 505 | "time": "2016-02-15 07:46:21" 506 | }, 507 | { 508 | "name": "phpunit/php-code-coverage", 509 | "version": "2.2.4", 510 | "source": { 511 | "type": "git", 512 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git", 513 | "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" 514 | }, 515 | "dist": { 516 | "type": "zip", 517 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", 518 | "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", 519 | "shasum": "" 520 | }, 521 | "require": { 522 | "php": ">=5.3.3", 523 | "phpunit/php-file-iterator": "~1.3", 524 | "phpunit/php-text-template": "~1.2", 525 | "phpunit/php-token-stream": "~1.3", 526 | "sebastian/environment": "^1.3.2", 527 | "sebastian/version": "~1.0" 528 | }, 529 | "require-dev": { 530 | "ext-xdebug": ">=2.1.4", 531 | "phpunit/phpunit": "~4" 532 | }, 533 | "suggest": { 534 | "ext-dom": "*", 535 | "ext-xdebug": ">=2.2.1", 536 | "ext-xmlwriter": "*" 537 | }, 538 | "type": "library", 539 | "extra": { 540 | "branch-alias": { 541 | "dev-master": "2.2.x-dev" 542 | } 543 | }, 544 | "autoload": { 545 | "classmap": [ 546 | "src/" 547 | ] 548 | }, 549 | "notification-url": "https://packagist.org/downloads/", 550 | "license": [ 551 | "BSD-3-Clause" 552 | ], 553 | "authors": [ 554 | { 555 | "name": "Sebastian Bergmann", 556 | "email": "sb@sebastian-bergmann.de", 557 | "role": "lead" 558 | } 559 | ], 560 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", 561 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage", 562 | "keywords": [ 563 | "coverage", 564 | "testing", 565 | "xunit" 566 | ], 567 | "time": "2015-10-06 15:47:00" 568 | }, 569 | { 570 | "name": "phpunit/php-file-iterator", 571 | "version": "1.4.1", 572 | "source": { 573 | "type": "git", 574 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git", 575 | "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0" 576 | }, 577 | "dist": { 578 | "type": "zip", 579 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0", 580 | "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0", 581 | "shasum": "" 582 | }, 583 | "require": { 584 | "php": ">=5.3.3" 585 | }, 586 | "type": "library", 587 | "extra": { 588 | "branch-alias": { 589 | "dev-master": "1.4.x-dev" 590 | } 591 | }, 592 | "autoload": { 593 | "classmap": [ 594 | "src/" 595 | ] 596 | }, 597 | "notification-url": "https://packagist.org/downloads/", 598 | "license": [ 599 | "BSD-3-Clause" 600 | ], 601 | "authors": [ 602 | { 603 | "name": "Sebastian Bergmann", 604 | "email": "sb@sebastian-bergmann.de", 605 | "role": "lead" 606 | } 607 | ], 608 | "description": "FilterIterator implementation that filters files based on a list of suffixes.", 609 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", 610 | "keywords": [ 611 | "filesystem", 612 | "iterator" 613 | ], 614 | "time": "2015-06-21 13:08:43" 615 | }, 616 | { 617 | "name": "phpunit/php-text-template", 618 | "version": "1.2.1", 619 | "source": { 620 | "type": "git", 621 | "url": "https://github.com/sebastianbergmann/php-text-template.git", 622 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" 623 | }, 624 | "dist": { 625 | "type": "zip", 626 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 627 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 628 | "shasum": "" 629 | }, 630 | "require": { 631 | "php": ">=5.3.3" 632 | }, 633 | "type": "library", 634 | "autoload": { 635 | "classmap": [ 636 | "src/" 637 | ] 638 | }, 639 | "notification-url": "https://packagist.org/downloads/", 640 | "license": [ 641 | "BSD-3-Clause" 642 | ], 643 | "authors": [ 644 | { 645 | "name": "Sebastian Bergmann", 646 | "email": "sebastian@phpunit.de", 647 | "role": "lead" 648 | } 649 | ], 650 | "description": "Simple template engine.", 651 | "homepage": "https://github.com/sebastianbergmann/php-text-template/", 652 | "keywords": [ 653 | "template" 654 | ], 655 | "time": "2015-06-21 13:50:34" 656 | }, 657 | { 658 | "name": "phpunit/php-timer", 659 | "version": "1.0.8", 660 | "source": { 661 | "type": "git", 662 | "url": "https://github.com/sebastianbergmann/php-timer.git", 663 | "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260" 664 | }, 665 | "dist": { 666 | "type": "zip", 667 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260", 668 | "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260", 669 | "shasum": "" 670 | }, 671 | "require": { 672 | "php": ">=5.3.3" 673 | }, 674 | "require-dev": { 675 | "phpunit/phpunit": "~4|~5" 676 | }, 677 | "type": "library", 678 | "autoload": { 679 | "classmap": [ 680 | "src/" 681 | ] 682 | }, 683 | "notification-url": "https://packagist.org/downloads/", 684 | "license": [ 685 | "BSD-3-Clause" 686 | ], 687 | "authors": [ 688 | { 689 | "name": "Sebastian Bergmann", 690 | "email": "sb@sebastian-bergmann.de", 691 | "role": "lead" 692 | } 693 | ], 694 | "description": "Utility class for timing", 695 | "homepage": "https://github.com/sebastianbergmann/php-timer/", 696 | "keywords": [ 697 | "timer" 698 | ], 699 | "time": "2016-05-12 18:03:57" 700 | }, 701 | { 702 | "name": "phpunit/php-token-stream", 703 | "version": "1.4.8", 704 | "source": { 705 | "type": "git", 706 | "url": "https://github.com/sebastianbergmann/php-token-stream.git", 707 | "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da" 708 | }, 709 | "dist": { 710 | "type": "zip", 711 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", 712 | "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", 713 | "shasum": "" 714 | }, 715 | "require": { 716 | "ext-tokenizer": "*", 717 | "php": ">=5.3.3" 718 | }, 719 | "require-dev": { 720 | "phpunit/phpunit": "~4.2" 721 | }, 722 | "type": "library", 723 | "extra": { 724 | "branch-alias": { 725 | "dev-master": "1.4-dev" 726 | } 727 | }, 728 | "autoload": { 729 | "classmap": [ 730 | "src/" 731 | ] 732 | }, 733 | "notification-url": "https://packagist.org/downloads/", 734 | "license": [ 735 | "BSD-3-Clause" 736 | ], 737 | "authors": [ 738 | { 739 | "name": "Sebastian Bergmann", 740 | "email": "sebastian@phpunit.de" 741 | } 742 | ], 743 | "description": "Wrapper around PHP's tokenizer extension.", 744 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/", 745 | "keywords": [ 746 | "tokenizer" 747 | ], 748 | "time": "2015-09-15 10:49:45" 749 | }, 750 | { 751 | "name": "phpunit/phpunit", 752 | "version": "4.8.26", 753 | "source": { 754 | "type": "git", 755 | "url": "https://github.com/sebastianbergmann/phpunit.git", 756 | "reference": "fc1d8cd5b5de11625979125c5639347896ac2c74" 757 | }, 758 | "dist": { 759 | "type": "zip", 760 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fc1d8cd5b5de11625979125c5639347896ac2c74", 761 | "reference": "fc1d8cd5b5de11625979125c5639347896ac2c74", 762 | "shasum": "" 763 | }, 764 | "require": { 765 | "ext-dom": "*", 766 | "ext-json": "*", 767 | "ext-pcre": "*", 768 | "ext-reflection": "*", 769 | "ext-spl": "*", 770 | "php": ">=5.3.3", 771 | "phpspec/prophecy": "^1.3.1", 772 | "phpunit/php-code-coverage": "~2.1", 773 | "phpunit/php-file-iterator": "~1.4", 774 | "phpunit/php-text-template": "~1.2", 775 | "phpunit/php-timer": "^1.0.6", 776 | "phpunit/phpunit-mock-objects": "~2.3", 777 | "sebastian/comparator": "~1.1", 778 | "sebastian/diff": "~1.2", 779 | "sebastian/environment": "~1.3", 780 | "sebastian/exporter": "~1.2", 781 | "sebastian/global-state": "~1.0", 782 | "sebastian/version": "~1.0", 783 | "symfony/yaml": "~2.1|~3.0" 784 | }, 785 | "suggest": { 786 | "phpunit/php-invoker": "~1.1" 787 | }, 788 | "bin": [ 789 | "phpunit" 790 | ], 791 | "type": "library", 792 | "extra": { 793 | "branch-alias": { 794 | "dev-master": "4.8.x-dev" 795 | } 796 | }, 797 | "autoload": { 798 | "classmap": [ 799 | "src/" 800 | ] 801 | }, 802 | "notification-url": "https://packagist.org/downloads/", 803 | "license": [ 804 | "BSD-3-Clause" 805 | ], 806 | "authors": [ 807 | { 808 | "name": "Sebastian Bergmann", 809 | "email": "sebastian@phpunit.de", 810 | "role": "lead" 811 | } 812 | ], 813 | "description": "The PHP Unit Testing framework.", 814 | "homepage": "https://phpunit.de/", 815 | "keywords": [ 816 | "phpunit", 817 | "testing", 818 | "xunit" 819 | ], 820 | "time": "2016-05-17 03:09:28" 821 | }, 822 | { 823 | "name": "phpunit/phpunit-mock-objects", 824 | "version": "2.3.8", 825 | "source": { 826 | "type": "git", 827 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", 828 | "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983" 829 | }, 830 | "dist": { 831 | "type": "zip", 832 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", 833 | "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983", 834 | "shasum": "" 835 | }, 836 | "require": { 837 | "doctrine/instantiator": "^1.0.2", 838 | "php": ">=5.3.3", 839 | "phpunit/php-text-template": "~1.2", 840 | "sebastian/exporter": "~1.2" 841 | }, 842 | "require-dev": { 843 | "phpunit/phpunit": "~4.4" 844 | }, 845 | "suggest": { 846 | "ext-soap": "*" 847 | }, 848 | "type": "library", 849 | "extra": { 850 | "branch-alias": { 851 | "dev-master": "2.3.x-dev" 852 | } 853 | }, 854 | "autoload": { 855 | "classmap": [ 856 | "src/" 857 | ] 858 | }, 859 | "notification-url": "https://packagist.org/downloads/", 860 | "license": [ 861 | "BSD-3-Clause" 862 | ], 863 | "authors": [ 864 | { 865 | "name": "Sebastian Bergmann", 866 | "email": "sb@sebastian-bergmann.de", 867 | "role": "lead" 868 | } 869 | ], 870 | "description": "Mock Object library for PHPUnit", 871 | "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", 872 | "keywords": [ 873 | "mock", 874 | "xunit" 875 | ], 876 | "time": "2015-10-02 06:51:40" 877 | }, 878 | { 879 | "name": "psr/log", 880 | "version": "1.0.0", 881 | "source": { 882 | "type": "git", 883 | "url": "https://github.com/php-fig/log.git", 884 | "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b" 885 | }, 886 | "dist": { 887 | "type": "zip", 888 | "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b", 889 | "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b", 890 | "shasum": "" 891 | }, 892 | "type": "library", 893 | "autoload": { 894 | "psr-0": { 895 | "Psr\\Log\\": "" 896 | } 897 | }, 898 | "notification-url": "https://packagist.org/downloads/", 899 | "license": [ 900 | "MIT" 901 | ], 902 | "authors": [ 903 | { 904 | "name": "PHP-FIG", 905 | "homepage": "http://www.php-fig.org/" 906 | } 907 | ], 908 | "description": "Common interface for logging libraries", 909 | "keywords": [ 910 | "log", 911 | "psr", 912 | "psr-3" 913 | ], 914 | "time": "2012-12-21 11:40:51" 915 | }, 916 | { 917 | "name": "satooshi/php-coveralls", 918 | "version": "dev-master", 919 | "source": { 920 | "type": "git", 921 | "url": "https://github.com/satooshi/php-coveralls.git", 922 | "reference": "50c60bb64054974f8ed7540ae6e75fd7981a5fd3" 923 | }, 924 | "dist": { 925 | "type": "zip", 926 | "url": "https://api.github.com/repos/satooshi/php-coveralls/zipball/50c60bb64054974f8ed7540ae6e75fd7981a5fd3", 927 | "reference": "50c60bb64054974f8ed7540ae6e75fd7981a5fd3", 928 | "shasum": "" 929 | }, 930 | "require": { 931 | "ext-json": "*", 932 | "ext-simplexml": "*", 933 | "guzzlehttp/guzzle": "^6.0", 934 | "php": ">=5.5", 935 | "psr/log": "^1.0", 936 | "symfony/config": "^2.1|^3.0", 937 | "symfony/console": "^2.1|^3.0", 938 | "symfony/stopwatch": "^2.0|^3.0", 939 | "symfony/yaml": "^2.0|^3.0" 940 | }, 941 | "suggest": { 942 | "symfony/http-kernel": "Allows Symfony integration" 943 | }, 944 | "bin": [ 945 | "bin/coveralls" 946 | ], 947 | "type": "library", 948 | "extra": { 949 | "branch-alias": { 950 | "dev-master": "2.0-dev" 951 | } 952 | }, 953 | "autoload": { 954 | "psr-4": { 955 | "Satooshi\\": "src/Satooshi/" 956 | } 957 | }, 958 | "notification-url": "https://packagist.org/downloads/", 959 | "license": [ 960 | "MIT" 961 | ], 962 | "authors": [ 963 | { 964 | "name": "Kitamura Satoshi", 965 | "email": "with.no.parachute@gmail.com", 966 | "homepage": "https://www.facebook.com/satooshi.jp" 967 | } 968 | ], 969 | "description": "PHP client library for Coveralls API", 970 | "homepage": "https://github.com/satooshi/php-coveralls", 971 | "keywords": [ 972 | "ci", 973 | "coverage", 974 | "github", 975 | "test" 976 | ], 977 | "time": "2016-01-20 17:44:41" 978 | }, 979 | { 980 | "name": "sebastian/comparator", 981 | "version": "1.2.0", 982 | "source": { 983 | "type": "git", 984 | "url": "https://github.com/sebastianbergmann/comparator.git", 985 | "reference": "937efb279bd37a375bcadf584dec0726f84dbf22" 986 | }, 987 | "dist": { 988 | "type": "zip", 989 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22", 990 | "reference": "937efb279bd37a375bcadf584dec0726f84dbf22", 991 | "shasum": "" 992 | }, 993 | "require": { 994 | "php": ">=5.3.3", 995 | "sebastian/diff": "~1.2", 996 | "sebastian/exporter": "~1.2" 997 | }, 998 | "require-dev": { 999 | "phpunit/phpunit": "~4.4" 1000 | }, 1001 | "type": "library", 1002 | "extra": { 1003 | "branch-alias": { 1004 | "dev-master": "1.2.x-dev" 1005 | } 1006 | }, 1007 | "autoload": { 1008 | "classmap": [ 1009 | "src/" 1010 | ] 1011 | }, 1012 | "notification-url": "https://packagist.org/downloads/", 1013 | "license": [ 1014 | "BSD-3-Clause" 1015 | ], 1016 | "authors": [ 1017 | { 1018 | "name": "Jeff Welch", 1019 | "email": "whatthejeff@gmail.com" 1020 | }, 1021 | { 1022 | "name": "Volker Dusch", 1023 | "email": "github@wallbash.com" 1024 | }, 1025 | { 1026 | "name": "Bernhard Schussek", 1027 | "email": "bschussek@2bepublished.at" 1028 | }, 1029 | { 1030 | "name": "Sebastian Bergmann", 1031 | "email": "sebastian@phpunit.de" 1032 | } 1033 | ], 1034 | "description": "Provides the functionality to compare PHP values for equality", 1035 | "homepage": "http://www.github.com/sebastianbergmann/comparator", 1036 | "keywords": [ 1037 | "comparator", 1038 | "compare", 1039 | "equality" 1040 | ], 1041 | "time": "2015-07-26 15:48:44" 1042 | }, 1043 | { 1044 | "name": "sebastian/diff", 1045 | "version": "1.4.1", 1046 | "source": { 1047 | "type": "git", 1048 | "url": "https://github.com/sebastianbergmann/diff.git", 1049 | "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e" 1050 | }, 1051 | "dist": { 1052 | "type": "zip", 1053 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", 1054 | "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e", 1055 | "shasum": "" 1056 | }, 1057 | "require": { 1058 | "php": ">=5.3.3" 1059 | }, 1060 | "require-dev": { 1061 | "phpunit/phpunit": "~4.8" 1062 | }, 1063 | "type": "library", 1064 | "extra": { 1065 | "branch-alias": { 1066 | "dev-master": "1.4-dev" 1067 | } 1068 | }, 1069 | "autoload": { 1070 | "classmap": [ 1071 | "src/" 1072 | ] 1073 | }, 1074 | "notification-url": "https://packagist.org/downloads/", 1075 | "license": [ 1076 | "BSD-3-Clause" 1077 | ], 1078 | "authors": [ 1079 | { 1080 | "name": "Kore Nordmann", 1081 | "email": "mail@kore-nordmann.de" 1082 | }, 1083 | { 1084 | "name": "Sebastian Bergmann", 1085 | "email": "sebastian@phpunit.de" 1086 | } 1087 | ], 1088 | "description": "Diff implementation", 1089 | "homepage": "https://github.com/sebastianbergmann/diff", 1090 | "keywords": [ 1091 | "diff" 1092 | ], 1093 | "time": "2015-12-08 07:14:41" 1094 | }, 1095 | { 1096 | "name": "sebastian/environment", 1097 | "version": "1.3.7", 1098 | "source": { 1099 | "type": "git", 1100 | "url": "https://github.com/sebastianbergmann/environment.git", 1101 | "reference": "4e8f0da10ac5802913afc151413bc8c53b6c2716" 1102 | }, 1103 | "dist": { 1104 | "type": "zip", 1105 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/4e8f0da10ac5802913afc151413bc8c53b6c2716", 1106 | "reference": "4e8f0da10ac5802913afc151413bc8c53b6c2716", 1107 | "shasum": "" 1108 | }, 1109 | "require": { 1110 | "php": ">=5.3.3" 1111 | }, 1112 | "require-dev": { 1113 | "phpunit/phpunit": "~4.4" 1114 | }, 1115 | "type": "library", 1116 | "extra": { 1117 | "branch-alias": { 1118 | "dev-master": "1.3.x-dev" 1119 | } 1120 | }, 1121 | "autoload": { 1122 | "classmap": [ 1123 | "src/" 1124 | ] 1125 | }, 1126 | "notification-url": "https://packagist.org/downloads/", 1127 | "license": [ 1128 | "BSD-3-Clause" 1129 | ], 1130 | "authors": [ 1131 | { 1132 | "name": "Sebastian Bergmann", 1133 | "email": "sebastian@phpunit.de" 1134 | } 1135 | ], 1136 | "description": "Provides functionality to handle HHVM/PHP environments", 1137 | "homepage": "http://www.github.com/sebastianbergmann/environment", 1138 | "keywords": [ 1139 | "Xdebug", 1140 | "environment", 1141 | "hhvm" 1142 | ], 1143 | "time": "2016-05-17 03:18:57" 1144 | }, 1145 | { 1146 | "name": "sebastian/exporter", 1147 | "version": "1.2.1", 1148 | "source": { 1149 | "type": "git", 1150 | "url": "https://github.com/sebastianbergmann/exporter.git", 1151 | "reference": "7ae5513327cb536431847bcc0c10edba2701064e" 1152 | }, 1153 | "dist": { 1154 | "type": "zip", 1155 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7ae5513327cb536431847bcc0c10edba2701064e", 1156 | "reference": "7ae5513327cb536431847bcc0c10edba2701064e", 1157 | "shasum": "" 1158 | }, 1159 | "require": { 1160 | "php": ">=5.3.3", 1161 | "sebastian/recursion-context": "~1.0" 1162 | }, 1163 | "require-dev": { 1164 | "phpunit/phpunit": "~4.4" 1165 | }, 1166 | "type": "library", 1167 | "extra": { 1168 | "branch-alias": { 1169 | "dev-master": "1.2.x-dev" 1170 | } 1171 | }, 1172 | "autoload": { 1173 | "classmap": [ 1174 | "src/" 1175 | ] 1176 | }, 1177 | "notification-url": "https://packagist.org/downloads/", 1178 | "license": [ 1179 | "BSD-3-Clause" 1180 | ], 1181 | "authors": [ 1182 | { 1183 | "name": "Jeff Welch", 1184 | "email": "whatthejeff@gmail.com" 1185 | }, 1186 | { 1187 | "name": "Volker Dusch", 1188 | "email": "github@wallbash.com" 1189 | }, 1190 | { 1191 | "name": "Bernhard Schussek", 1192 | "email": "bschussek@2bepublished.at" 1193 | }, 1194 | { 1195 | "name": "Sebastian Bergmann", 1196 | "email": "sebastian@phpunit.de" 1197 | }, 1198 | { 1199 | "name": "Adam Harvey", 1200 | "email": "aharvey@php.net" 1201 | } 1202 | ], 1203 | "description": "Provides the functionality to export PHP variables for visualization", 1204 | "homepage": "http://www.github.com/sebastianbergmann/exporter", 1205 | "keywords": [ 1206 | "export", 1207 | "exporter" 1208 | ], 1209 | "time": "2015-06-21 07:55:53" 1210 | }, 1211 | { 1212 | "name": "sebastian/global-state", 1213 | "version": "1.1.1", 1214 | "source": { 1215 | "type": "git", 1216 | "url": "https://github.com/sebastianbergmann/global-state.git", 1217 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" 1218 | }, 1219 | "dist": { 1220 | "type": "zip", 1221 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", 1222 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", 1223 | "shasum": "" 1224 | }, 1225 | "require": { 1226 | "php": ">=5.3.3" 1227 | }, 1228 | "require-dev": { 1229 | "phpunit/phpunit": "~4.2" 1230 | }, 1231 | "suggest": { 1232 | "ext-uopz": "*" 1233 | }, 1234 | "type": "library", 1235 | "extra": { 1236 | "branch-alias": { 1237 | "dev-master": "1.0-dev" 1238 | } 1239 | }, 1240 | "autoload": { 1241 | "classmap": [ 1242 | "src/" 1243 | ] 1244 | }, 1245 | "notification-url": "https://packagist.org/downloads/", 1246 | "license": [ 1247 | "BSD-3-Clause" 1248 | ], 1249 | "authors": [ 1250 | { 1251 | "name": "Sebastian Bergmann", 1252 | "email": "sebastian@phpunit.de" 1253 | } 1254 | ], 1255 | "description": "Snapshotting of global state", 1256 | "homepage": "http://www.github.com/sebastianbergmann/global-state", 1257 | "keywords": [ 1258 | "global state" 1259 | ], 1260 | "time": "2015-10-12 03:26:01" 1261 | }, 1262 | { 1263 | "name": "sebastian/recursion-context", 1264 | "version": "1.0.2", 1265 | "source": { 1266 | "type": "git", 1267 | "url": "https://github.com/sebastianbergmann/recursion-context.git", 1268 | "reference": "913401df809e99e4f47b27cdd781f4a258d58791" 1269 | }, 1270 | "dist": { 1271 | "type": "zip", 1272 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791", 1273 | "reference": "913401df809e99e4f47b27cdd781f4a258d58791", 1274 | "shasum": "" 1275 | }, 1276 | "require": { 1277 | "php": ">=5.3.3" 1278 | }, 1279 | "require-dev": { 1280 | "phpunit/phpunit": "~4.4" 1281 | }, 1282 | "type": "library", 1283 | "extra": { 1284 | "branch-alias": { 1285 | "dev-master": "1.0.x-dev" 1286 | } 1287 | }, 1288 | "autoload": { 1289 | "classmap": [ 1290 | "src/" 1291 | ] 1292 | }, 1293 | "notification-url": "https://packagist.org/downloads/", 1294 | "license": [ 1295 | "BSD-3-Clause" 1296 | ], 1297 | "authors": [ 1298 | { 1299 | "name": "Jeff Welch", 1300 | "email": "whatthejeff@gmail.com" 1301 | }, 1302 | { 1303 | "name": "Sebastian Bergmann", 1304 | "email": "sebastian@phpunit.de" 1305 | }, 1306 | { 1307 | "name": "Adam Harvey", 1308 | "email": "aharvey@php.net" 1309 | } 1310 | ], 1311 | "description": "Provides functionality to recursively process PHP variables", 1312 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context", 1313 | "time": "2015-11-11 19:50:13" 1314 | }, 1315 | { 1316 | "name": "sebastian/version", 1317 | "version": "1.0.6", 1318 | "source": { 1319 | "type": "git", 1320 | "url": "https://github.com/sebastianbergmann/version.git", 1321 | "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" 1322 | }, 1323 | "dist": { 1324 | "type": "zip", 1325 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", 1326 | "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", 1327 | "shasum": "" 1328 | }, 1329 | "type": "library", 1330 | "autoload": { 1331 | "classmap": [ 1332 | "src/" 1333 | ] 1334 | }, 1335 | "notification-url": "https://packagist.org/downloads/", 1336 | "license": [ 1337 | "BSD-3-Clause" 1338 | ], 1339 | "authors": [ 1340 | { 1341 | "name": "Sebastian Bergmann", 1342 | "email": "sebastian@phpunit.de", 1343 | "role": "lead" 1344 | } 1345 | ], 1346 | "description": "Library that helps with managing the version number of Git-hosted PHP projects", 1347 | "homepage": "https://github.com/sebastianbergmann/version", 1348 | "time": "2015-06-21 13:59:46" 1349 | }, 1350 | { 1351 | "name": "symfony/config", 1352 | "version": "v3.1.0", 1353 | "source": { 1354 | "type": "git", 1355 | "url": "https://github.com/symfony/config.git", 1356 | "reference": "048dc47e07f92333203c3b7045868bbc864fc40e" 1357 | }, 1358 | "dist": { 1359 | "type": "zip", 1360 | "url": "https://api.github.com/repos/symfony/config/zipball/048dc47e07f92333203c3b7045868bbc864fc40e", 1361 | "reference": "048dc47e07f92333203c3b7045868bbc864fc40e", 1362 | "shasum": "" 1363 | }, 1364 | "require": { 1365 | "php": ">=5.5.9", 1366 | "symfony/filesystem": "~2.8|~3.0" 1367 | }, 1368 | "suggest": { 1369 | "symfony/yaml": "To use the yaml reference dumper" 1370 | }, 1371 | "type": "library", 1372 | "extra": { 1373 | "branch-alias": { 1374 | "dev-master": "3.1-dev" 1375 | } 1376 | }, 1377 | "autoload": { 1378 | "psr-4": { 1379 | "Symfony\\Component\\Config\\": "" 1380 | }, 1381 | "exclude-from-classmap": [ 1382 | "/Tests/" 1383 | ] 1384 | }, 1385 | "notification-url": "https://packagist.org/downloads/", 1386 | "license": [ 1387 | "MIT" 1388 | ], 1389 | "authors": [ 1390 | { 1391 | "name": "Fabien Potencier", 1392 | "email": "fabien@symfony.com" 1393 | }, 1394 | { 1395 | "name": "Symfony Community", 1396 | "homepage": "https://symfony.com/contributors" 1397 | } 1398 | ], 1399 | "description": "Symfony Config Component", 1400 | "homepage": "https://symfony.com", 1401 | "time": "2016-05-20 11:48:17" 1402 | }, 1403 | { 1404 | "name": "symfony/console", 1405 | "version": "v3.1.0", 1406 | "source": { 1407 | "type": "git", 1408 | "url": "https://github.com/symfony/console.git", 1409 | "reference": "f62db5b8afec27073a4609b8c84b1f9936652259" 1410 | }, 1411 | "dist": { 1412 | "type": "zip", 1413 | "url": "https://api.github.com/repos/symfony/console/zipball/f62db5b8afec27073a4609b8c84b1f9936652259", 1414 | "reference": "f62db5b8afec27073a4609b8c84b1f9936652259", 1415 | "shasum": "" 1416 | }, 1417 | "require": { 1418 | "php": ">=5.5.9", 1419 | "symfony/polyfill-mbstring": "~1.0" 1420 | }, 1421 | "require-dev": { 1422 | "psr/log": "~1.0", 1423 | "symfony/event-dispatcher": "~2.8|~3.0", 1424 | "symfony/process": "~2.8|~3.0" 1425 | }, 1426 | "suggest": { 1427 | "psr/log": "For using the console logger", 1428 | "symfony/event-dispatcher": "", 1429 | "symfony/process": "" 1430 | }, 1431 | "type": "library", 1432 | "extra": { 1433 | "branch-alias": { 1434 | "dev-master": "3.1-dev" 1435 | } 1436 | }, 1437 | "autoload": { 1438 | "psr-4": { 1439 | "Symfony\\Component\\Console\\": "" 1440 | }, 1441 | "exclude-from-classmap": [ 1442 | "/Tests/" 1443 | ] 1444 | }, 1445 | "notification-url": "https://packagist.org/downloads/", 1446 | "license": [ 1447 | "MIT" 1448 | ], 1449 | "authors": [ 1450 | { 1451 | "name": "Fabien Potencier", 1452 | "email": "fabien@symfony.com" 1453 | }, 1454 | { 1455 | "name": "Symfony Community", 1456 | "homepage": "https://symfony.com/contributors" 1457 | } 1458 | ], 1459 | "description": "Symfony Console Component", 1460 | "homepage": "https://symfony.com", 1461 | "time": "2016-05-30 06:58:39" 1462 | }, 1463 | { 1464 | "name": "symfony/filesystem", 1465 | "version": "v3.1.0", 1466 | "source": { 1467 | "type": "git", 1468 | "url": "https://github.com/symfony/filesystem.git", 1469 | "reference": "5751e80d6f94b7c018f338a4a7be0b700d6f3058" 1470 | }, 1471 | "dist": { 1472 | "type": "zip", 1473 | "url": "https://api.github.com/repos/symfony/filesystem/zipball/5751e80d6f94b7c018f338a4a7be0b700d6f3058", 1474 | "reference": "5751e80d6f94b7c018f338a4a7be0b700d6f3058", 1475 | "shasum": "" 1476 | }, 1477 | "require": { 1478 | "php": ">=5.5.9" 1479 | }, 1480 | "type": "library", 1481 | "extra": { 1482 | "branch-alias": { 1483 | "dev-master": "3.1-dev" 1484 | } 1485 | }, 1486 | "autoload": { 1487 | "psr-4": { 1488 | "Symfony\\Component\\Filesystem\\": "" 1489 | }, 1490 | "exclude-from-classmap": [ 1491 | "/Tests/" 1492 | ] 1493 | }, 1494 | "notification-url": "https://packagist.org/downloads/", 1495 | "license": [ 1496 | "MIT" 1497 | ], 1498 | "authors": [ 1499 | { 1500 | "name": "Fabien Potencier", 1501 | "email": "fabien@symfony.com" 1502 | }, 1503 | { 1504 | "name": "Symfony Community", 1505 | "homepage": "https://symfony.com/contributors" 1506 | } 1507 | ], 1508 | "description": "Symfony Filesystem Component", 1509 | "homepage": "https://symfony.com", 1510 | "time": "2016-04-12 18:27:47" 1511 | }, 1512 | { 1513 | "name": "symfony/polyfill-mbstring", 1514 | "version": "v1.2.0", 1515 | "source": { 1516 | "type": "git", 1517 | "url": "https://github.com/symfony/polyfill-mbstring.git", 1518 | "reference": "dff51f72b0706335131b00a7f49606168c582594" 1519 | }, 1520 | "dist": { 1521 | "type": "zip", 1522 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/dff51f72b0706335131b00a7f49606168c582594", 1523 | "reference": "dff51f72b0706335131b00a7f49606168c582594", 1524 | "shasum": "" 1525 | }, 1526 | "require": { 1527 | "php": ">=5.3.3" 1528 | }, 1529 | "suggest": { 1530 | "ext-mbstring": "For best performance" 1531 | }, 1532 | "type": "library", 1533 | "extra": { 1534 | "branch-alias": { 1535 | "dev-master": "1.2-dev" 1536 | } 1537 | }, 1538 | "autoload": { 1539 | "psr-4": { 1540 | "Symfony\\Polyfill\\Mbstring\\": "" 1541 | }, 1542 | "files": [ 1543 | "bootstrap.php" 1544 | ] 1545 | }, 1546 | "notification-url": "https://packagist.org/downloads/", 1547 | "license": [ 1548 | "MIT" 1549 | ], 1550 | "authors": [ 1551 | { 1552 | "name": "Nicolas Grekas", 1553 | "email": "p@tchwork.com" 1554 | }, 1555 | { 1556 | "name": "Symfony Community", 1557 | "homepage": "https://symfony.com/contributors" 1558 | } 1559 | ], 1560 | "description": "Symfony polyfill for the Mbstring extension", 1561 | "homepage": "https://symfony.com", 1562 | "keywords": [ 1563 | "compatibility", 1564 | "mbstring", 1565 | "polyfill", 1566 | "portable", 1567 | "shim" 1568 | ], 1569 | "time": "2016-05-18 14:26:46" 1570 | }, 1571 | { 1572 | "name": "symfony/stopwatch", 1573 | "version": "v3.1.0", 1574 | "source": { 1575 | "type": "git", 1576 | "url": "https://github.com/symfony/stopwatch.git", 1577 | "reference": "4670f122fa32a4900003a6802f6b8575f3f0b17e" 1578 | }, 1579 | "dist": { 1580 | "type": "zip", 1581 | "url": "https://api.github.com/repos/symfony/stopwatch/zipball/4670f122fa32a4900003a6802f6b8575f3f0b17e", 1582 | "reference": "4670f122fa32a4900003a6802f6b8575f3f0b17e", 1583 | "shasum": "" 1584 | }, 1585 | "require": { 1586 | "php": ">=5.5.9" 1587 | }, 1588 | "type": "library", 1589 | "extra": { 1590 | "branch-alias": { 1591 | "dev-master": "3.1-dev" 1592 | } 1593 | }, 1594 | "autoload": { 1595 | "psr-4": { 1596 | "Symfony\\Component\\Stopwatch\\": "" 1597 | }, 1598 | "exclude-from-classmap": [ 1599 | "/Tests/" 1600 | ] 1601 | }, 1602 | "notification-url": "https://packagist.org/downloads/", 1603 | "license": [ 1604 | "MIT" 1605 | ], 1606 | "authors": [ 1607 | { 1608 | "name": "Fabien Potencier", 1609 | "email": "fabien@symfony.com" 1610 | }, 1611 | { 1612 | "name": "Symfony Community", 1613 | "homepage": "https://symfony.com/contributors" 1614 | } 1615 | ], 1616 | "description": "Symfony Stopwatch Component", 1617 | "homepage": "https://symfony.com", 1618 | "time": "2016-03-04 07:56:56" 1619 | }, 1620 | { 1621 | "name": "symfony/yaml", 1622 | "version": "v3.1.0", 1623 | "source": { 1624 | "type": "git", 1625 | "url": "https://github.com/symfony/yaml.git", 1626 | "reference": "eca51b7b65eb9be6af88ad7cc91685f1556f5c9a" 1627 | }, 1628 | "dist": { 1629 | "type": "zip", 1630 | "url": "https://api.github.com/repos/symfony/yaml/zipball/eca51b7b65eb9be6af88ad7cc91685f1556f5c9a", 1631 | "reference": "eca51b7b65eb9be6af88ad7cc91685f1556f5c9a", 1632 | "shasum": "" 1633 | }, 1634 | "require": { 1635 | "php": ">=5.5.9" 1636 | }, 1637 | "type": "library", 1638 | "extra": { 1639 | "branch-alias": { 1640 | "dev-master": "3.1-dev" 1641 | } 1642 | }, 1643 | "autoload": { 1644 | "psr-4": { 1645 | "Symfony\\Component\\Yaml\\": "" 1646 | }, 1647 | "exclude-from-classmap": [ 1648 | "/Tests/" 1649 | ] 1650 | }, 1651 | "notification-url": "https://packagist.org/downloads/", 1652 | "license": [ 1653 | "MIT" 1654 | ], 1655 | "authors": [ 1656 | { 1657 | "name": "Fabien Potencier", 1658 | "email": "fabien@symfony.com" 1659 | }, 1660 | { 1661 | "name": "Symfony Community", 1662 | "homepage": "https://symfony.com/contributors" 1663 | } 1664 | ], 1665 | "description": "Symfony Yaml Component", 1666 | "homepage": "https://symfony.com", 1667 | "time": "2016-05-26 21:46:24" 1668 | } 1669 | ], 1670 | "aliases": [], 1671 | "minimum-stability": "stable", 1672 | "stability-flags": { 1673 | "satooshi/php-coveralls": 20 1674 | }, 1675 | "prefer-stable": false, 1676 | "prefer-lowest": false, 1677 | "platform": { 1678 | "php": ">=5.5" 1679 | }, 1680 | "platform-dev": [] 1681 | } 1682 | --------------------------------------------------------------------------------