diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e5d3c3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.idea +/vendor diff --git a/Controller/ApiController.php b/Controller/ApiController.php new file mode 100644 index 0000000..d59d752 --- /dev/null +++ b/Controller/ApiController.php @@ -0,0 +1,27 @@ +getUser()->getUsername(); + $apiKey = $this->get('playtini.auth.security.api_key_user_provider')->getHash($username); + + return JsonResponse::create([ + 'api_key' => $username . '~' . $apiKey, + ]); + } +} diff --git a/Controller/GoogleController.php b/Controller/GoogleController.php new file mode 100644 index 0000000..7bd4f7f --- /dev/null +++ b/Controller/GoogleController.php @@ -0,0 +1,64 @@ +get('oauth2.registry')->getClient('google')->getOAuth2Provider()->getAuthorizationUrl(); + + if (!$request->cookies->get('logout')) { + return RedirectResponse::create($link); + } + + $response = new Response(); + $response->headers->clearCookie('logout'); + + return $this->render('AuthBundle::login.html.twig', [ + 'link' => $link + ], $response); + } + + /** + * After going to Facebook, you're redirect back here + * because this is the "redirect_route" you configured + * in services.yml + * + * @param Request $request + * @return Response + */ + public function loginCheckAction(Request $request) + { + // ** if you want to *authenticate* the user, then + // leave this method blank and create a Guard authenticator + } + + public function logoutAction() + { + // will never be executed + } + + /** + * @return RedirectResponse + */ + public function forceLogoutAction() + { + $response = new RedirectResponse($this->get('router')->generate('mailer_auth_security_logout')); + $response->headers->setCookie(new Cookie('logout', 1, '+1 hour')); + + return $response; + } +} diff --git a/DependencyInjection/AuthExtension.php b/DependencyInjection/AuthExtension.php new file mode 100644 index 0000000..6bc759b --- /dev/null +++ b/DependencyInjection/AuthExtension.php @@ -0,0 +1,49 @@ + [ + 'google' => [ + // must be "google" - it activates that type! + 'type' => 'google', + // add and configure client_id and client_secret in parameters.yml + 'client_id' => $container->getParameter('google_app_id'), + 'client_secret' => $container->getParameter('google_app_secret'), + // a route name you'll create + 'redirect_route' => 'playtini_auth_connect_google_check', + 'redirect_params' => [], + // Optional value for sending access_type parameter. More detail: https://developers.google.com/identity/protocols/OAuth2WebServer#offline + 'access_type' => 'online', + // Optional value for sending hd parameter. More detail: https://developers.google.com/accounts/docs/OAuth2Login#hd-param + //'hosted_domain' => 'yourdomain.com', + // whether to check OAuth2 "state": defaults to true + 'use_state' => false + ] + ] + ]; + $container->prependExtensionConfig('knpu_oauth2_client', $config); + } + + /** + * {@inheritdoc} + */ + public function load(array $configs, ContainerBuilder $container) + { + $loader = new YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); + $loader->load('services.yml'); + } +} diff --git a/Entity/User.php b/Entity/User.php new file mode 100644 index 0000000..d61956e --- /dev/null +++ b/Entity/User.php @@ -0,0 +1,268 @@ +createdAt = new \DateTime(); + $this->lastActiveAt = new \DateTime(); + $this->roles = [self::ROLE_USER]; + } + + /** + * @return integer + */ + public function getId() + { + return $this->id; + } + + /** + * @param \DateTime $createdAt + * + * @return User + */ + public function setCreatedAt(\DateTime $createdAt) + { + $this->createdAt = $createdAt; + + return $this; + } + + /** + * @return \DateTime + */ + public function getCreatedAt(): \DateTime + { + return $this->createdAt; + } + + /** + * @param \DateTime $lastActiveAt + * + * @return User + */ + public function setLastActiveAt(\DateTime $lastActiveAt) + { + $this->lastActiveAt = $lastActiveAt; + + return $this; + } + + /** + * @return \DateTime + */ + public function getLastActiveAt(): \DateTime + { + return $this->lastActiveAt; + } + + /** + * @param string $googleId + * @return User + */ + public function setGoogleId(string $googleId) + { + $this->googleId = $googleId; + + return $this; + } + + /** + * @return string + */ + public function getGoogleId() + { + return $this->googleId; + } + + /** + * @param string $googleAccessToken + * @return User + */ + public function setGoogleAccessToken(string $googleAccessToken) + { + $this->googleAccessToken = $googleAccessToken; + + return $this; + } + + /** + * @return string + */ + public function getGoogleAccessToken() + { + return $this->googleAccessToken; + } + + /** + * Returns the roles granted to the user. + * + * + * public function getRoles() + * { + * return array('ROLE_USER'); + * } + * + * + * Alternatively, the roles might be stored on a ``roles`` property, + * and populated in any number of different ways when the user object + * is created. + * + * @return Role[]|string[] The user roles + */ + public function getRoles() + { + return $this->roles; + } + + /** + * @param array $roles + * @return User + */ + public function setRoles(array $roles) + { + $this->roles = $roles; + + return $this; + } + + /** + * Returns the password used to authenticate the user. + * + * This should be the encoded password. On authentication, a plain-text + * password will be salted, encoded, and then compared to this value. + * + * @return string The password + */ + public function getPassword() + { + return null; + } + + /** + * Returns the salt that was originally used to encode the password. + * + * This can return null if the password was not encoded using a salt. + * + * @return string|null The salt + */ + public function getSalt() + { + return null; + } + + /** + * Returns the username used to authenticate the user. + * + * @return string The username + */ + public function getUsername() + { + return $this->username; + } + + /** + * Removes sensitive data from the user. + * + * This is important if, at any given point, sensitive information like + * the plain-text password is stored on this object. + */ + public function eraseCredentials() + { + return; + } + + /** + * @param bool $enabled + * + * @return User + */ + public function setEnabled(bool $enabled) + { + $this->enabled = $enabled; + + return $this; + } + + /** + * @return boolean + */ + public function getEnabled() + { + return $this->enabled; + } + + /** + * @param string $username + * + * @return User + */ + public function setUsername(string $username) + { + $this->username = $username; + + return $this; + } + + /** + * @param string $email + * + * @return User + */ + public function setEmail(string $email) + { + $this->email = $email; + + return $this; + } + + /** + * @return string + */ + public function getEmail() + { + return $this->email; + } +} diff --git a/Model/UserManager.php b/Model/UserManager.php new file mode 100644 index 0000000..27cfeb0 --- /dev/null +++ b/Model/UserManager.php @@ -0,0 +1,65 @@ +objectManager = $objectManager; + $this->repository = $objectManager->getRepository($class); + + $metadata = $objectManager->getClassMetadata($class); + $this->class = $metadata->getName(); + } + + public function getClass(): string + { + return $this->class; + } + + public function saveUser(User $user) + { + $this->objectManager->persist($user); + $this->objectManager->flush(); + } + + public function createUser(): User + { + $class = $this->getClass(); + $user = new $class; + + return $user; + } + + /** + * @param string $googleId + * @return User|null + */ + public function findOneByGoogleId(string $googleId) + { + return $this->repository->findOneBy(['googleId' => $googleId]); + } + + /** + * @param string $email + * @return User|null + */ + public function findOneByEmail(string $email) + { + return $this->repository->findOneBy(['email' => $email]); + } +} diff --git a/PlaytiniAuthBundle.php b/PlaytiniAuthBundle.php new file mode 100644 index 0000000..4a74f64 --- /dev/null +++ b/PlaytiniAuthBundle.php @@ -0,0 +1,9 @@ + + + + + + + + Reports + + + +
+ + Sign in with Google + +
+ + diff --git a/Security/ApiKeyAuthenticator.php b/Security/ApiKeyAuthenticator.php new file mode 100644 index 0000000..da00eb1 --- /dev/null +++ b/Security/ApiKeyAuthenticator.php @@ -0,0 +1,94 @@ +headers->get('X-Api-Key'); + if (!$apiKey) { + $apiKey = $request->request->get('apikey'); + } + if (!$apiKey) { + $apiKey = $request->query->get('apikey'); + } + + if (!$apiKey) { + throw new BadCredentialsException('No API key found'); + } + + return new PreAuthenticatedToken( + 'anon.', + $apiKey, + $providerKey + ); + } + + public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey) + { + if (!$userProvider instanceof ApiKeyUserProvider) { + throw new \InvalidArgumentException( + sprintf( + 'The user provider must be an instance of ApiKeyUserProvider (%s was given).', + get_class($userProvider) + ) + ); + } + + $apiKey = $token->getCredentials(); + $username = $userProvider->getUsernameForApiKey($apiKey); + + // User is the Entity which represents your user + $user = $token->getUser(); + if ($user instanceof User) { + return new PreAuthenticatedToken( + $user, + $apiKey, + $providerKey, + $user->getRoles() + ); + } + + if (!$username) { + // CAUTION: this message will be returned to the client + // (so don't put any un-trusted messages / error strings here) + throw new CustomUserMessageAuthenticationException( + sprintf('API Key "%s" does not exist.', $apiKey) + ); + } + + $user = $userProvider->loadUserByUsername($username); + + return new PreAuthenticatedToken( + $user, + $apiKey, + $providerKey, + $user->getRoles() + ); + } + + public function supportsToken(TokenInterface $token, $providerKey) + { + return $token instanceof PreAuthenticatedToken && $token->getProviderKey() === $providerKey; + } + + public function onAuthenticationFailure(Request $request, AuthenticationException $exception) + { + return JsonResponse::create([ + 'key' => $exception->getMessageKey(), + 'data' => $exception->getMessageData() + ], 403); + } +} diff --git a/Security/ApiKeyUserProvider.php b/Security/ApiKeyUserProvider.php new file mode 100644 index 0000000..ff8ca71 --- /dev/null +++ b/Security/ApiKeyUserProvider.php @@ -0,0 +1,64 @@ +em = $em; + $this->salt = md5($salt); + } + + public function getHash($username) + { + return md5(md5(md5($username) . $this->salt)); + } + + public function getUsernameForApiKey($apiKey) + { + if (strpos($apiKey, '~') === false) { + return null; + } + list($username, $hash) = explode('~', $apiKey, 2); + + return ($hash == $this->getHash($username)) ? $username : null; + } + + public function loadUserByUsername($username) + { + $repository = $this->em->getRepository('AuthBundle:User'); + + return $repository->findOneBy(['username' => $username]); + } + + public function refreshUser(UserInterface $user) + { + // $user is the User that you set in the token inside authenticateToken() + // after it has been deserialized from the session + + // you might use $user to query the database for a fresh user + // $id = $user->getId(); + // use $id to make a query + + // if you are *not* reading from a database and are just creating + // a User object (like in this example), you can just return it + return $user; + } + + public function supportsClass($class) + { + return User::class === $class; + } +} diff --git a/Security/GoogleAuthenticator.php b/Security/GoogleAuthenticator.php new file mode 100644 index 0000000..1e877e1 --- /dev/null +++ b/Security/GoogleAuthenticator.php @@ -0,0 +1,185 @@ +clientRegistry = $clientRegistry; + $this->router = $router; + $this->googleDomain = $googleDomain; + $this->allowedUsers = array_values(array_filter(array_map('trim', explode(',', $allowedUsers)))); + $this->userManager = $userManager; + if ($adminUsersString) { + $this->adminUsers = array_values(array_filter(array_map('trim', explode(',', $adminUsersString)))); + } + } + + public function getCredentials(Request $request) + { + if ($request->getPathInfo() != $this->router->generate('playtini_auth_connect_google_check')) { + // skip authentication unless we're on this URL! + return null; + } + try { + $client = $this->clientRegistry->getClient('google'); + $token = $client->getAccessToken(); + + return $token; + } catch (IdentityProviderException $e) { + // you could parse the response to see the problem + throw $e; + } + } + + /** + * @param AccessToken $credentials + * @param UserProviderInterface $userProvider + * @return User|null + */ + public function getUser($credentials, UserProviderInterface $userProvider) + { + /** @var GoogleClient $googleClient */ + $googleClient = $this->clientRegistry->getClient('google'); + $googleUser = $googleClient->fetchUserFromToken($credentials); + + // 1) have they logged in with Google before? Easy! + $existingUser = $this->userManager->findOneByGoogleId($googleUser->getId()); + if ($existingUser) { + $this->setUserRoles($existingUser); + + return $existingUser; + } + + // 2) do we have a matching user by email? + $email = $googleUser->getEmail(); + $user = $this->userManager->findOneByEmail($email); + + // 3) no user? Redirect to finish registration + if (!$user) { + $username = preg_replace('#@.*#', '', $email); + if ( + substr($email, -strlen($this->googleDomain) - 1) !== '@' . $this->googleDomain || + !in_array($username, $this->allowedUsers) + ) { + throw new AuthenticationException(); + } + + $user = $this->userManager->createUser(); + $user + ->setEnabled(true) + ->setEmail($email) + ->setUsername($username); + } + + // make sure the Google user is set + $user->setGoogleId($googleUser->getId()); + $this->userManager->saveUser($user); + + $this->setUserRoles($user); + + return $user; + } + + public function checkCredentials($credentials, UserInterface $user) + { + return true; + // do nothing - the fact that the access token worked means that + // our app has been authorized with Google + } + + public function onAuthenticationFailure(Request $request, AuthenticationException $exception) + { + $this->saveAuthenticationErrorToSession($request, $exception); + $loginUrl = $this->router->generate('playtini_auth_security_logout'); + + return new RedirectResponse($loginUrl); + } + + public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey) + { + $url = $this->getPreviousUrl($request, $providerKey); + if (!$url) { + $url = $this->router->generate('homepage'); + } + + return new RedirectResponse($url); + } + + /** + * Called when an anonymous user tries to access an protected page. + * + * In our app, this is never actually called, because there is only *one* "entry_point" per firewall and in security.yml, + * we're using app.form_login_authenticator as the entry point (so it's start() method is the one that's called). + * @param Request $request + * @param AuthenticationException $authException + * @return Response + */ + public function start(Request $request, AuthenticationException $authException = null) + { + // not called in our app, but if it were, redirecting to the login page makes sense + $url = $this->router->generate('playtini_auth_security_login'); + + return new RedirectResponse($url); + } + + /** + * Set user's roles on fly + * + * @param User $user + */ + private function setUserRoles(User $user) + { + if ($this->adminUsers && in_array($user->getUsername(), $this->adminUsers)) { + $user->setRoles([User::ROLE_ADMIN]); + } + } +} diff --git a/Tests/DependencyInjection/AuthExtensionTest.php b/Tests/DependencyInjection/AuthExtensionTest.php new file mode 100644 index 0000000..bd58a5d --- /dev/null +++ b/Tests/DependencyInjection/AuthExtensionTest.php @@ -0,0 +1,53 @@ +setParameter('google_app_id', '123asd321'); + $container->setParameter('google_app_secret', 'asd123dsa'); + $loader = new AuthExtension(); + $loader->prepend($container); + $expected = [ + 'clients' => [ + 'google' => [ + 'type' => 'google', + 'client_id' => '123asd321', + 'client_secret' => 'asd123dsa', + 'redirect_route' => 'playtini_auth_connect_google_check', + 'redirect_params' => [], + 'access_type' => 'online', + //'hosted_domain' => 'yourdomain.com', + 'use_state' => false + ] + ] + ]; + $this->assertEquals([0 => $expected], $container->getExtensionConfig('knpu_oauth2_client')); + } + + public function testLoad() + { + $container = new ContainerBuilder(); + $loader = new AuthExtension(); + $config = []; + $loader->load([$config], $container); + + $expectedServices = [ + 'playtini.auth.model.user_manager', + 'playtini.auth.security.google_authenticator', + 'playtini.auth.security.api_key_user_provider', + 'playtini.auth.security.api_key_authenticator', + 'twig.security_extension', + ]; + $this->assertEquals($expectedServices, array_keys($container->getDefinitions())); + } +} diff --git a/Tests/Entity/UserTest.php b/Tests/Entity/UserTest.php new file mode 100644 index 0000000..7ee305d --- /dev/null +++ b/Tests/Entity/UserTest.php @@ -0,0 +1,106 @@ +user = new class extends User {}; + } + + public function tearDown() + { + unset($this->user); + } + + public function testId() + { + $this->assertEquals(time(), $this->user->getCreatedAt()->getTimestamp(), 2); + $this->assertEquals(time(), $this->user->getLastActiveAt()->getTimestamp(), 2); + $this->assertNull($this->user->getId()); + } + + public function testCreatedAt() + { + $this->assertEquals(time(), $this->user->getCreatedAt()->getTimestamp(), 2); + $createdAt = new \DateTime('-4 hours'); + $this->user->setCreatedAt($createdAt); + $this->assertSame($createdAt, $this->user->getCreatedAt()); + } + + public function testLastActiveAt() + { + $this->assertEquals(time(), $this->user->getLastActiveAt()->getTimestamp(), 2); + $lastActiveAt = new \DateTime('-4 hours'); + $this->user->setLastActiveAt($lastActiveAt); + $this->assertSame($lastActiveAt, $this->user->getLastActiveAt()); + } + + public function testGoogleId() + { + $this->assertNull($this->user->getGoogleId()); + $googleId = '123asd321'; + $this->user->setGoogleId($googleId); + $this->assertSame($googleId, $this->user->getGoogleId()); + } + + public function testGoogleAccessToken() + { + $this->assertNull($this->user->getGoogleAccessToken()); + $googleAccessToken = '123asd321'; + $this->user->setGoogleAccessToken($googleAccessToken); + $this->assertSame($googleAccessToken, $this->user->getGoogleAccessToken()); + } + + public function testUsername() + { + $this->assertNull($this->user->getUsername()); + $username = '123asd321'; + $this->user->setUsername($username); + $this->assertSame($username, $this->user->getUsername()); + } + + public function testEnabled() + { + $this->assertNull($this->user->getEnabled()); + $this->user->setEnabled(true); + $this->assertTrue($this->user->getEnabled()); + } + + public function testEmail() + { + $this->assertNull($this->user->getEmail()); + $email = '123asd321'; + $this->user->setEmail($email); + $this->assertSame($email, $this->user->getEmail()); + } + + public function testGetRoles() + { + $this->assertEquals(['ROLE_USER'], $this->user->getRoles()); + } + + public function testGetPassword() + { + $this->assertNull($this->user->getPassword()); + } + + public function testGetSalt() + { + $this->assertNull($this->user->getSalt()); + } + + public function testEraseCredentials() + { + $this->assertNull($this->user->eraseCredentials()); + } +} diff --git a/Tests/Model/UserManagerTest.php b/Tests/Model/UserManagerTest.php new file mode 100644 index 0000000..4c1e489 --- /dev/null +++ b/Tests/Model/UserManagerTest.php @@ -0,0 +1,84 @@ +om = $this->prophesize(ObjectManager::class); + $this->repository = $this->prophesize(ObjectRepository::class); + $class = $this->prophesize(ClassMetadata::class); + + $this->om->getRepository(self::USER_CLASS)->shouldBeCalledTimes(1)->willReturn($this->repository); + $this->om->getClassMetadata(self::USER_CLASS)->shouldBeCalledTimes(1)->willReturn($class); + $class->getName()->willReturn(self::USER_CLASS); + + $this->userManager = new UserManager($this->om->reveal(), self::USER_CLASS); + } + + public function testGetClass() + { + $this->assertEquals(self::USER_CLASS, $this->userManager->getClass()); + } + + public function testCreateUser() + { + $user = $this->userManager->createUser(); + $this->assertEquals(time(), $user->getCreatedAt()->getTimestamp(), 2); + $this->assertEquals(time(), $user->getLastActiveAt()->getTimestamp(), 2); + } + + public function testSaveUser() + { + $user = new TestUser(); + + $this->om->persist($user)->shouldBeCalledTimes(1); + $this->om->flush()->shouldBeCalledTimes(1); + + $this->userManager->saveUser($user); + } + + public function testFinOneByGoogleId() + { + $user = new TestUser(); + $googleId = '123asd321'; + + $this->repository->findOneBy(['googleId' => $googleId])->shouldBeCalledTimes(1)->willReturn($user); + + $this->assertSame($user, $this->userManager->findOneByGoogleId($googleId)); + } + + public function testFindOneByEmail() + { + $user = new TestUser(); + $email = 'email@test.com'; + + $this->repository->findOneBy(['email' => $email])->shouldBeCalledTimes(1)->willReturn($user); + + $this->assertSame($user, $this->userManager->findOneByEmail($email)); + } +} diff --git a/Tests/Security/ApiKeyAuthenticatorTest.php b/Tests/Security/ApiKeyAuthenticatorTest.php new file mode 100644 index 0000000..3b10873 --- /dev/null +++ b/Tests/Security/ApiKeyAuthenticatorTest.php @@ -0,0 +1,93 @@ +prophesize(Request::class); + $headers = $this->prophesize(ParameterBag::class); + $request->headers = $headers; + + $headers->get('X-Api-Key')->shouldBeCalledTimes(1)->willReturn('123'); + + $authenticator = new ApiKeyAuthenticator(); + $token = $authenticator->createToken($request->reveal(), 'testkey'); + + $this->assertInstanceOf(PreAuthenticatedToken::class, $token); + $this->assertEquals('testkey', $token->getProviderKey()); + $this->assertEquals('123', $token->getCredentials()); + } + + public function testCreateTokenRequest() + { + $request = $this->prophesize(Request::class); + $headers = $this->prophesize(ParameterBag::class); + $request->headers = $headers; + $requestRequest = $this->prophesize(ParameterBag::class); + $request->request = $requestRequest; + + $headers->get('X-Api-Key')->shouldBeCalledTimes(1)->willReturn(null); + $requestRequest->get('apikey')->shouldBeCalledTimes(1)->willReturn('123'); + + $authenticator = new ApiKeyAuthenticator(); + $token = $authenticator->createToken($request->reveal(), 'testkey'); + + $this->assertInstanceOf(PreAuthenticatedToken::class, $token); + $this->assertEquals('testkey', $token->getProviderKey()); + $this->assertEquals('123', $token->getCredentials()); + } + + public function testCreateTokenQuery() + { + $request = $this->prophesize(Request::class); + $headers = $this->prophesize(ParameterBag::class); + $request->headers = $headers; + $requestRequest = $this->prophesize(ParameterBag::class); + $request->request = $requestRequest; + $requestQuery = $this->prophesize(ParameterBag::class); + $request->query = $requestQuery; + + $headers->get('X-Api-Key')->shouldBeCalledTimes(1)->willReturn(null); + $requestRequest->get('apikey')->shouldBeCalledTimes(1)->willReturn(null); + $requestQuery->get('apikey')->shouldBeCalledTimes(1)->willReturn('123'); + + $authenticator = new ApiKeyAuthenticator(); + $token = $authenticator->createToken($request->reveal(), 'testkey'); + + $this->assertInstanceOf(PreAuthenticatedToken::class, $token); + $this->assertEquals('testkey', $token->getProviderKey()); + $this->assertEquals('123', $token->getCredentials()); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException + * @expectedExceptionMessage No API key found + */ + public function testCreateTokenNoApiKey() + { + $request = $this->prophesize(Request::class); + $headers = $this->prophesize(ParameterBag::class); + $request->headers = $headers; + $requestRequest = $this->prophesize(ParameterBag::class); + $request->request = $requestRequest; + $requestQuery = $this->prophesize(ParameterBag::class); + $request->query = $requestQuery; + + $headers->get('X-Api-Key')->shouldBeCalledTimes(1)->willReturn(null); + $requestRequest->get('apikey')->shouldBeCalledTimes(1)->willReturn(null); + $requestQuery->get('apikey')->shouldBeCalledTimes(1)->willReturn(null); + + $authenticator = new ApiKeyAuthenticator(); + $authenticator->createToken($request->reveal(), 'testkey'); + } +} diff --git a/Tests/Security/GoogleAuthenticatorTest.php b/Tests/Security/GoogleAuthenticatorTest.php new file mode 100644 index 0000000..371af4d --- /dev/null +++ b/Tests/Security/GoogleAuthenticatorTest.php @@ -0,0 +1,320 @@ +clientRegistry = $this->prophesize(ClientRegistry::class); + $this->router = $this->prophesize(RouterInterface::class); + $this->userManager = $this->prophesize(UserManager::class); + + $this->authenticator = new GoogleAuthenticator( + $this->clientRegistry->reveal(), + $this->router->reveal(), + $this->googleDomain, + $this->allowedUsers, + $this->userManager->reveal(), + $this->adminUsers + ); + } + + public function testGetCredentialsSkip() + { + $request = Request::create('/some/path'); + + $this->router->generate('playtini_auth_connect_google_check')->shouldBeCalledTimes(1)->willReturn('/another/path'); + + $this->assertNull($this->authenticator->getCredentials($request)); + } + + public function testGetCredentials() + { + $request = Request::create('/some/path'); + $this->router->generate('playtini_auth_connect_google_check')->shouldBeCalledTimes(1)->willReturn('/some/path'); + $client = $this->prophesize(OAuth2Client::class); + $this->clientRegistry->getClient('google')->shouldBeCalledTimes(1)->willReturn($client); + $token = 'some_token'; + $client->getAccessToken()->shouldBeCalledTimes(1)->willReturn($token); + + $result = $this->authenticator->getCredentials($request); + + $this->assertSame($token, $result); + } + + /** + * @expectedException \League\OAuth2\Client\Provider\Exception\IdentityProviderException + */ + public function testGetCredentialsException() + { + $request = Request::create('/some/path'); + $this->router->generate('playtini_auth_connect_google_check')->shouldBeCalledTimes(1)->willReturn('/some/path'); + $client = $this->prophesize(OAuth2Client::class); + $this->clientRegistry->getClient('google')->shouldBeCalledTimes(1)->willReturn($client); + $client->getAccessToken()->shouldBeCalledTimes(1)->willThrow(new IdentityProviderException(1, 2, 3)); + + $this->authenticator->getCredentials($request); + } + + public function testGetUser_UserRegisteredViaGoogle() + { + $credentials = new AccessToken(['access_token' => 'token']); + $googleClient = $this->prophesize(OAuth2Client::class); + $this->clientRegistry->getClient('google')->shouldBeCalledTimes(1)->willReturn($googleClient); + $googleUser = new GoogleUser(['id' => '123dsa213']); + $googleClient->fetchUserFromToken($credentials)->shouldBeCalledTimes(1)->willReturn($googleUser); + $user = (new User())->setUsername('user1'); + $this->userManager->findOneByGoogleId('123dsa213')->shouldBeCalledTimes(1)->willReturn($user); + + $result = $this->authenticator->getUser($credentials, $this->prophesize(UserProviderInterface::class)->reveal()); + + $this->assertEquals($user, $result); + } + + public function testGetUser_UserRegisteredViaGoogleNotAdminUser() + { + $credentials = new AccessToken(['access_token' => 'token']); + $googleClient = $this->prophesize(OAuth2Client::class); + $this->clientRegistry->getClient('google')->shouldBeCalledTimes(1)->willReturn($googleClient); + $googleUser = new GoogleUser(['id' => '123dsa213']); + $googleClient->fetchUserFromToken($credentials)->shouldBeCalledTimes(1)->willReturn($googleUser); + $user = (new User())->setGoogleAccessToken('token')->setUsername('user1'); + $this->userManager->findOneByGoogleId('123dsa213')->shouldBeCalledTimes(1)->willReturn($user); + + $result = $this->authenticator->getUser($credentials, $this->prophesize(UserProviderInterface::class)->reveal()); + + $this->assertEquals($user, $result); + $this->assertEquals([User::ROLE_USER], $result->getRoles()); + } + + public function testGetUser_UserRegisteredViaGoogleAdmin() + { + $credentials = new AccessToken(['access_token' => 'token']); + $googleClient = $this->prophesize(OAuth2Client::class); + $this->clientRegistry->getClient('google')->shouldBeCalledTimes(1)->willReturn($googleClient); + $googleUser = new GoogleUser(['id' => '123dsa213']); + $googleClient->fetchUserFromToken($credentials)->shouldBeCalledTimes(1)->willReturn($googleUser); + $user = (new User())->setGoogleAccessToken('token')->setUsername('user3'); + $this->userManager->findOneByGoogleId('123dsa213')->shouldBeCalledTimes(1)->willReturn($user); + + $result = $this->authenticator->getUser($credentials, $this->prophesize(UserProviderInterface::class)->reveal()); + + $this->assertEquals($user, $result); + $this->assertEquals([User::ROLE_ADMIN], $result->getRoles()); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationException + */ + public function testGetUser_CreateNewUserInvalidEmilException() + { + $credentials = new AccessToken(['access_token' => 'token']); + $googleClient = $this->prophesize(OAuth2Client::class); + $this->clientRegistry->getClient('google')->shouldBeCalledTimes(1)->willReturn($googleClient); + $googleUser = new GoogleUser([ + 'id' => '123dsa213', + 'emails' => [0 => ['value' => 'email@test.com']] + ]); + $googleClient->fetchUserFromToken($credentials)->shouldBeCalledTimes(1)->willReturn($googleUser); + $this->userManager->findOneByGoogleId('123dsa213')->shouldBeCalledTimes(1)->willReturn(null); + $this->userManager->findOneByEmail('email@test.com')->shouldBeCalledTimes(1)->willReturn(null); + + $result = $this->authenticator->getUser($credentials, $this->prophesize(UserProviderInterface::class)->reveal()); + + $this->assertEquals('user', $result); + } + + public function testGetUser_CreateNewUser() + { + $credentials = new AccessToken(['access_token' => 'token']); + $googleClient = $this->prophesize(OAuth2Client::class); + $this->clientRegistry->getClient('google')->shouldBeCalledTimes(1)->willReturn($googleClient); + $googleUser = new GoogleUser([ + 'id' => '123asd321', + 'emails' => [0 => ['value' => 'user1@example.com']] + ]); + $googleClient->fetchUserFromToken($credentials)->shouldBeCalledTimes(1)->willReturn($googleUser); + $this->userManager->findOneByGoogleId('123asd321')->shouldBeCalledTimes(1)->willReturn(null); + $this->userManager->findOneByEmail('user1@example.com')->shouldBeCalledTimes(1)->willReturn(null); + $user = new User(); + $this->userManager->createUser()->shouldBeCalledTimes(1)->willReturn($user); + $user->setEnabled(true)->setEmail('user1@example.com')->setUsername('user1')->setGoogleId('123asd321'); + /** @noinspection PhpParamsInspection */ + $this->userManager->saveUser(Argument::that(function(User $user) { + $this->assertTrue($user->getEnabled()); + $this->assertEquals('user1@example.com', $user->getEmail()); + $this->assertEquals('user1', $user->getUsername()); + $this->assertEquals('123asd321', $user->getGoogleId()); + $this->assertEquals(time(), $user->getCreatedAt()->getTimestamp(), 2); + $this->assertEquals(time(), $user->getLastActiveAt()->getTimestamp(), 2); + return true; + }))->shouldBeCalledTimes(1); + + $result = $this->authenticator->getUser($credentials, $this->prophesize(UserProviderInterface::class)->reveal()); + + $this->assertEquals($user, $result); + } + + public function testGetUser_RegisteredNotByGoogle_NotAdmin() + { + $credentials = new AccessToken(['access_token' => 'token']); + $googleClient = $this->prophesize(OAuth2Client::class); + $this->clientRegistry->getClient('google')->shouldBeCalledTimes(1)->willReturn($googleClient); + $googleUser = new GoogleUser([ + 'id' => '123dsa213', + 'emails' => [0 => ['value' => 'email@test.com']] + ]); + $googleClient->fetchUserFromToken($credentials)->shouldBeCalledTimes(1)->willReturn($googleUser); + $this->userManager->findOneByGoogleId('123dsa213')->shouldBeCalledTimes(1)->willReturn(null); + $user = (new User())->setUsername('user2')->setCreatedAt(new \DateTime('2016-01-01'))->setLastActiveAt(new \DateTime('2016-10-10')); + $this->userManager->findOneByEmail('email@test.com')->shouldBeCalledTimes(1)->willReturn($user); + $this->userManager->saveUser(Argument::that(function(User $arg) use ($user) { + $this->assertEquals($arg, $user); + return true; + }))->shouldBeCalledTimes(1); + + $result = $this->authenticator->getUser($credentials, $this->prophesize(UserProviderInterface::class)->reveal()); + + $this->assertEquals($user, $result); + $this->assertEquals([User::ROLE_USER], $result->getRoles()); + } + + public function testGetUser_RegisteredNotByGoogle_Admin() + { + $credentials = new AccessToken(['access_token' => 'token']); + $googleClient = $this->prophesize(OAuth2Client::class); + $this->clientRegistry->getClient('google')->shouldBeCalledTimes(1)->willReturn($googleClient); + $googleUser = new GoogleUser([ + 'id' => '123dsa213', + 'emails' => [0 => ['value' => 'email@test.com']] + ]); + $googleClient->fetchUserFromToken($credentials)->shouldBeCalledTimes(1)->willReturn($googleUser); + $this->userManager->findOneByGoogleId('123dsa213')->shouldBeCalledTimes(1)->willReturn(null); + $user = (new User())->setUsername('user3')->setCreatedAt(new \DateTime('2016-01-01'))->setLastActiveAt(new \DateTime('2016-10-10')); + $this->userManager->findOneByEmail('email@test.com')->shouldBeCalledTimes(1)->willReturn($user); + $this->userManager->saveUser(Argument::that(function(User $arg) use ($user) { + $this->assertEquals($arg, $user); + return true; + }))->shouldBeCalledTimes(1); + + $result = $this->authenticator->getUser($credentials, $this->prophesize(UserProviderInterface::class)->reveal()); + + $this->assertEquals($user, $result); + $this->assertEquals([User::ROLE_ADMIN], $result->getRoles()); + } + + public function testCheckCredential() + { + $result =$this->authenticator->checkCredentials('credentials', $this->prophesize(UserInterface::class)->reveal()); + + $this->assertTrue($result); + } + + public function testOnAuthenticationFailure() + { + $request = new Request(); + $session = $this->prophesize(Session::class); + $request->setSession($session->reveal()); + $session->set(Security::AUTHENTICATION_ERROR, new AuthenticationException())->shouldBeCalledTimes(1); + $this->router->generate('playtini_auth_security_logout')->shouldBeCalledTimes(1)->willReturn('/login/url'); + + $result = $this->authenticator->onAuthenticationFailure($request, new AuthenticationException()); + + $this->assertInstanceOf(RedirectResponse::class, $result); + $this->assertEquals('/login/url', $result->getTargetUrl()); + } + + public function testOnAuthenticationSuccess_NoPreviousUrl() + { + $providerKey = 'provider_key'; + $request = new Request(); + $session = $this->prophesize(Session::class); + $request->setSession($session->reveal()); + $session->get('_security.'.$providerKey.'.target_path')->shouldBeCalledTimes(1)->willReturn(null); + $this->router->generate('homepage')->shouldBeCalledTimes(1)->willReturn('/homepage'); + + $result = $this->authenticator->onAuthenticationSuccess( + $request, + $this->prophesize(TokenInterface::class)->reveal(), + $providerKey + ); + + $this->assertInstanceOf(RedirectResponse::class, $result); + $this->assertEquals('/homepage', $result->getTargetUrl()); + } + + public function testOnAuthenticationSuccess_WithPreviousUrl() + { + $providerKey = 'provider_key'; + $request = new Request(); + $session = $this->prophesize(Session::class); + $request->setSession($session->reveal()); + $session->get('_security.'.$providerKey.'.target_path')->shouldBeCalledTimes(1)->willReturn('/prev/page'); + + $result = $this->authenticator->onAuthenticationSuccess( + $request, + $this->prophesize(TokenInterface::class)->reveal(), + $providerKey + ); + + $this->assertInstanceOf(RedirectResponse::class, $result); + $this->assertEquals('/prev/page', $result->getTargetUrl()); + } + + public function testStart() + { + $request = new Request(); + $this->router->generate('playtini_auth_security_login')->shouldBeCalledTimes(1)->willReturn('/homepage'); + + $result = $this->authenticator->start($request); + + $this->assertInstanceOf(RedirectResponse::class, $result); + $this->assertEquals('/homepage', $result->getTargetUrl()); + } +} diff --git a/Tests/Twig/SecurityExtensionTest.php b/Tests/Twig/SecurityExtensionTest.php new file mode 100644 index 0000000..5c798ef --- /dev/null +++ b/Tests/Twig/SecurityExtensionTest.php @@ -0,0 +1,68 @@ +apiKeyUserProvider = $this->prophesize(ApiKeyUserProvider::class); + $this->tokenStorage = $this->prophesize(TokenStorage::class); + + $this->extension = new SecurityExtension( + $this->apiKeyUserProvider->reveal(), + $this->tokenStorage->reveal() + ); + } + + public function testApiKey_NoUsername() + { + $token = $this->prophesize(TokenInterface::class); + $token->getUsername()->willReturn(''); + $this->tokenStorage->getToken()->shouldBeCalledTimes(1)->willReturn($token); + + $result = $this->extension->apiKey(); + + $this->assertSame('', $result); + } + + public function testApiKey() + { + $token = $this->prophesize(TokenInterface::class); + $token->getUsername()->shouldBeCalledTimes(1)->willReturn('username'); + $this->tokenStorage->getToken()->shouldBeCalledTimes(1)->willReturn($token); + $this->apiKeyUserProvider->getHash('username')->shouldBeCalledTimes(1)->willReturn('hash'); + + $result = $this->extension->apiKey(); + + $this->assertSame('username~hash', $result); + } + + public function testGetName() + { + $this->assertEquals('security_extension', $this->extension->getName()); + } + + public function testGetFunctions() + { + $functions = $this->extension->getFunctions(); + + $this->assertCount(1, $functions); + $this->assertEquals('api_key', $functions[0]->getName()); + } +} diff --git a/Twig/SecurityExtension.php b/Twig/SecurityExtension.php new file mode 100644 index 0000000..4ee6eba --- /dev/null +++ b/Twig/SecurityExtension.php @@ -0,0 +1,46 @@ +apiKeyUserProvider = $apiKeyUserProvider; + $this->tokenStorage = $tokenStorage; + } + + public function getFunctions() + { + return array( + new \Twig_SimpleFunction('api_key', [$this, 'apiKey']), + ); + } + + public function apiKey() + { + $username = $this->tokenStorage->getToken()->getUsername(); + if (!$username) { + return ''; + } + + $hash = $this->apiKeyUserProvider->getHash($username); + $apiKey = sprintf('%s~%s', $username, $hash); + + return $apiKey; + } + + public function getName() + { + return 'security_extension'; + } +} diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..24d1968 --- /dev/null +++ b/composer.json @@ -0,0 +1,41 @@ +{ + "name": "playtini/auth-bundle", + "description": "Simple Google Account Authentication Symfony Bundle", + "type": "symfony-bundle", + "license": "proprietary", + "authors": [ + { + "name": "Andrew Shukailo", + "email": "ash@playtini.ua" + } + ], + "minimum-stability": "dev", + "prefer-stable": true, + "autoload": { + "psr-4": { + "Playtini\\Bundle\\AuthBundle\\": "" + } + }, + "autoload-dev": { + "psr-4": { + "Tests\\": "Tests/" + } + }, + "require": { + "php": ">=7.0", + "knpuniversity/oauth2-client-bundle": "^1.1", + "league/oauth2-google": "^1.0", + "twig/twig": "^1.24", + "symfony/security-guard": "^3.0", + "doctrine/doctrine-bundle": "^1.6" + }, + "require-dev": { + "symfony/phpunit-bridge": "^3.0", + "phpunit/phpunit": "^5.6" + }, + "config": { + "platform": { + "php": "7.0" + } + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..46ca949 --- /dev/null +++ b/composer.lock @@ -0,0 +1,4259 @@ +{ + "_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", + "This file is @generated automatically" + ], + "hash": "2aebbcca84d95746c928b9ff0cb4378c", + "content-hash": "0e307d7bfe52669b191169630c7b359c", + "packages": [ + { + "name": "doctrine/annotations", + "version": "v1.3.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "bd4461328621bde0ae6b1b2675fbc6aca4ceb558" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/bd4461328621bde0ae6b1b2675fbc6aca4ceb558", + "reference": "bd4461328621bde0ae6b1b2675fbc6aca4ceb558", + "shasum": "" + }, + "require": { + "doctrine/lexer": "1.*", + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "doctrine/cache": "1.*", + "phpunit/phpunit": "^5.6.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "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" + } + ], + "description": "Docblock Annotations Parser", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "annotations", + "docblock", + "parser" + ], + "time": "2016-12-30 15:59:45" + }, + { + "name": "doctrine/cache", + "version": "v1.6.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/cache.git", + "reference": "b6f544a20f4807e81f7044d31e679ccbb1866dc3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/cache/zipball/b6f544a20f4807e81f7044d31e679ccbb1866dc3", + "reference": "b6f544a20f4807e81f7044d31e679ccbb1866dc3", + "shasum": "" + }, + "require": { + "php": "~5.5|~7.0" + }, + "conflict": { + "doctrine/common": ">2.2,<2.4" + }, + "require-dev": { + "phpunit/phpunit": "~4.8|~5.0", + "predis/predis": "~1.0", + "satooshi/php-coveralls": "~0.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "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" + } + ], + "description": "Caching library offering an object-oriented API for many cache backends", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "cache", + "caching" + ], + "time": "2016-10-29 11:16:17" + }, + { + "name": "doctrine/collections", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/collections.git", + "reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/collections/zipball/6c1e4eef75f310ea1b3e30945e9f06e652128b8a", + "reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Collections\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "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" + } + ], + "description": "Collections Abstraction library", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "array", + "collections", + "iterator" + ], + "time": "2015-04-14 22:21:58" + }, + { + "name": "doctrine/common", + "version": "v2.7.2", + "source": { + "type": "git", + "url": "https://github.com/doctrine/common.git", + "reference": "930297026c8009a567ac051fd545bf6124150347" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/common/zipball/930297026c8009a567ac051fd545bf6124150347", + "reference": "930297026c8009a567ac051fd545bf6124150347", + "shasum": "" + }, + "require": { + "doctrine/annotations": "1.*", + "doctrine/cache": "1.*", + "doctrine/collections": "1.*", + "doctrine/inflector": "1.*", + "doctrine/lexer": "1.*", + "php": "~5.6|~7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.4.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "lib/Doctrine/Common" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "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" + } + ], + "description": "Common Library for Doctrine projects", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "annotations", + "collections", + "eventmanager", + "persistence", + "spl" + ], + "time": "2017-01-13 14:02:13" + }, + { + "name": "doctrine/dbal", + "version": "v2.5.7", + "source": { + "type": "git", + "url": "https://github.com/doctrine/dbal.git", + "reference": "3a351369582dade60c750e2cef540eb7b568e6b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/3a351369582dade60c750e2cef540eb7b568e6b3", + "reference": "3a351369582dade60c750e2cef540eb7b568e6b3", + "shasum": "" + }, + "require": { + "doctrine/common": ">=2.4,<2.8-dev", + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "4.*", + "symfony/console": "2.*||^3.0" + }, + "suggest": { + "symfony/console": "For helpful console commands such as SQL execution and import of files." + }, + "bin": [ + "bin/doctrine-dbal" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\DBAL\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "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" + } + ], + "description": "Database Abstraction Layer", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "database", + "dbal", + "persistence", + "queryobject" + ], + "time": "2017-01-14 21:05:28" + }, + { + "name": "doctrine/doctrine-bundle", + "version": "1.6.6", + "source": { + "type": "git", + "url": "https://github.com/doctrine/DoctrineBundle.git", + "reference": "0f0c4df366bd1d36d38a27e2f5ff128e118ac969" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/0f0c4df366bd1d36d38a27e2f5ff128e118ac969", + "reference": "0f0c4df366bd1d36d38a27e2f5ff128e118ac969", + "shasum": "" + }, + "require": { + "doctrine/dbal": "~2.3", + "doctrine/doctrine-cache-bundle": "~1.0", + "jdorn/sql-formatter": "~1.1", + "php": ">=5.5.9", + "symfony/console": "~2.7|~3.0", + "symfony/dependency-injection": "~2.7|~3.0", + "symfony/doctrine-bridge": "~2.7|~3.0", + "symfony/framework-bundle": "~2.7|~3.0" + }, + "require-dev": { + "doctrine/orm": "~2.3", + "phpunit/phpunit": "~4", + "satooshi/php-coveralls": "^1.0", + "symfony/phpunit-bridge": "~2.7|~3.0", + "symfony/property-info": "~2.8|~3.0", + "symfony/validator": "~2.7|~3.0", + "symfony/yaml": "~2.7|~3.0", + "twig/twig": "~1.10|~2.0" + }, + "suggest": { + "doctrine/orm": "The Doctrine ORM integration is optional in the bundle.", + "symfony/web-profiler-bundle": "To use the data collector." + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Bundle\\DoctrineBundle\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Doctrine Project", + "homepage": "http://www.doctrine-project.org/" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony DoctrineBundle", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "database", + "dbal", + "orm", + "persistence" + ], + "time": "2017-01-07 21:47:22" + }, + { + "name": "doctrine/doctrine-cache-bundle", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/DoctrineCacheBundle.git", + "reference": "18c600a9b82f6454d2e81ca4957cdd56a1cf3504" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/DoctrineCacheBundle/zipball/18c600a9b82f6454d2e81ca4957cdd56a1cf3504", + "reference": "18c600a9b82f6454d2e81ca4957cdd56a1cf3504", + "shasum": "" + }, + "require": { + "doctrine/cache": "^1.4.2", + "doctrine/inflector": "~1.0", + "php": ">=5.3.2", + "symfony/doctrine-bridge": "~2.2|~3.0" + }, + "require-dev": { + "instaclick/coding-standard": "~1.1", + "instaclick/object-calisthenics-sniffs": "dev-master", + "instaclick/symfony2-coding-standard": "dev-remaster", + "phpunit/phpunit": "~4", + "predis/predis": "~0.8", + "satooshi/php-coveralls": "~0.6.1", + "squizlabs/php_codesniffer": "~1.5", + "symfony/console": "~2.2|~3.0", + "symfony/finder": "~2.2|~3.0", + "symfony/framework-bundle": "~2.2|~3.0", + "symfony/phpunit-bridge": "~2.7|~3.0", + "symfony/security-acl": "~2.3|~3.0", + "symfony/validator": "~2.2|~3.0", + "symfony/yaml": "~2.2|~3.0" + }, + "suggest": { + "symfony/security-acl": "For using this bundle to cache ACLs" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Bundle\\DoctrineCacheBundle\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Fabio B. Silva", + "email": "fabio.bat.silva@gmail.com" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@hotmail.com" + }, + { + "name": "Doctrine Project", + "homepage": "http://www.doctrine-project.org/" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony Bundle for Doctrine Cache", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "cache", + "caching" + ], + "time": "2016-01-26 17:28:51" + }, + { + "name": "doctrine/inflector", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/inflector.git", + "reference": "90b2128806bfde671b6952ab8bea493942c1fdae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/90b2128806bfde671b6952ab8bea493942c1fdae", + "reference": "90b2128806bfde671b6952ab8bea493942c1fdae", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "4.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Inflector\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "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" + } + ], + "description": "Common String Manipulations with regard to casing and singular/plural rules.", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "inflection", + "pluralize", + "singularize", + "string" + ], + "time": "2015-11-06 14:35:42" + }, + { + "name": "doctrine/lexer", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Lexer\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@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", + "keywords": [ + "lexer", + "parser" + ], + "time": "2014-09-09 13:34:57" + }, + { + "name": "guzzlehttp/guzzle", + "version": "6.2.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "ebf29dee597f02f09f4d5bbecc68230ea9b08f60" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/ebf29dee597f02f09f4d5bbecc68230ea9b08f60", + "reference": "ebf29dee597f02f09f4d5bbecc68230ea9b08f60", + "shasum": "" + }, + "require": { + "guzzlehttp/promises": "^1.0", + "guzzlehttp/psr7": "^1.3.1", + "php": ">=5.5" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "^4.0", + "psr/log": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.2-dev" + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "time": "2016-10-08 15:01:37" + }, + { + "name": "guzzlehttp/promises", + "version": "v1.3.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "shasum": "" + }, + "require": { + "php": ">=5.5.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "time": "2016-12-20 10:07:11" + }, + { + "name": "guzzlehttp/psr7", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "5c6447c9df362e8f8093bda8f5d8873fe5c7f65b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/5c6447c9df362e8f8093bda8f5d8873fe5c7f65b", + "reference": "5c6447c9df362e8f8093bda8f5d8873fe5c7f65b", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "PSR-7 message implementation", + "keywords": [ + "http", + "message", + "stream", + "uri" + ], + "time": "2016-06-24 23:00:38" + }, + { + "name": "ircmaxell/random-lib", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/ircmaxell/RandomLib.git", + "reference": "e9e0204f40e49fa4419946c677eccd3fa25b8cf4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ircmaxell/RandomLib/zipball/e9e0204f40e49fa4419946c677eccd3fa25b8cf4", + "reference": "e9e0204f40e49fa4419946c677eccd3fa25b8cf4", + "shasum": "" + }, + "require": { + "ircmaxell/security-lib": "^1.1", + "php": ">=5.3.2" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^1.11", + "mikey179/vfsstream": "^1.6", + "phpunit/phpunit": "^4.8|^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-0": { + "RandomLib": "lib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Anthony Ferrara", + "email": "ircmaxell@ircmaxell.com", + "homepage": "http://blog.ircmaxell.com" + } + ], + "description": "A Library For Generating Secure Random Numbers", + "homepage": "https://github.com/ircmaxell/RandomLib", + "keywords": [ + "cryptography", + "random", + "random-numbers", + "random-strings" + ], + "time": "2016-09-07 15:52:06" + }, + { + "name": "ircmaxell/security-lib", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/ircmaxell/SecurityLib.git", + "reference": "f3db6de12c20c9bcd1aa3db4353a1bbe0e44e1b5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ircmaxell/SecurityLib/zipball/f3db6de12c20c9bcd1aa3db4353a1bbe0e44e1b5", + "reference": "f3db6de12c20c9bcd1aa3db4353a1bbe0e44e1b5", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "mikey179/vfsstream": "1.1.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "SecurityLib": "lib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Anthony Ferrara", + "email": "ircmaxell@ircmaxell.com", + "homepage": "http://blog.ircmaxell.com" + } + ], + "description": "A Base Security Library", + "homepage": "https://github.com/ircmaxell/SecurityLib", + "time": "2015-03-20 14:31:23" + }, + { + "name": "jdorn/sql-formatter", + "version": "v1.2.17", + "source": { + "type": "git", + "url": "https://github.com/jdorn/sql-formatter.git", + "reference": "64990d96e0959dff8e059dfcdc1af130728d92bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jdorn/sql-formatter/zipball/64990d96e0959dff8e059dfcdc1af130728d92bc", + "reference": "64990d96e0959dff8e059dfcdc1af130728d92bc", + "shasum": "" + }, + "require": { + "php": ">=5.2.4" + }, + "require-dev": { + "phpunit/phpunit": "3.7.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "lib" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jeremy Dorn", + "email": "jeremy@jeremydorn.com", + "homepage": "http://jeremydorn.com/" + } + ], + "description": "a PHP SQL highlighting library", + "homepage": "https://github.com/jdorn/sql-formatter/", + "keywords": [ + "highlight", + "sql" + ], + "time": "2014-01-12 16:20:24" + }, + { + "name": "knpuniversity/oauth2-client-bundle", + "version": "1.8.0", + "source": { + "type": "git", + "url": "https://github.com/knpuniversity/oauth2-client-bundle.git", + "reference": "10dc3b43c364eb74f497c7ea621f55bda5b71ac7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/knpuniversity/oauth2-client-bundle/zipball/10dc3b43c364eb74f497c7ea621f55bda5b71ac7", + "reference": "10dc3b43c364eb74f497c7ea621f55bda5b71ac7", + "shasum": "" + }, + "require": { + "league/oauth2-client": "^1.0", + "php": " >=5.5.9", + "symfony/dependency-injection": "^2.8|^3.0", + "symfony/framework-bundle": "^2.7|^3.0", + "symfony/http-foundation": "^2.7|^3.0", + "symfony/routing": "^2.7|^3.0" + }, + "require-dev": { + "league/oauth2-facebook": "^1.1", + "phpunit/phpunit": "^4.8", + "symfony/security-guard": "^2.8|^3.0" + }, + "suggest": { + "symfony/security-guard": "For integration with Symfony's Guard Security layer" + }, + "type": "symfony-bundle", + "autoload": { + "psr-4": { + "KnpU\\OAuth2ClientBundle\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ryan Weaver", + "email": "ryan@knpuniversity.com" + } + ], + "description": "Integration with league/oauth2-client to provide services", + "homepage": "http://knpuniversity.com", + "keywords": [ + "oauth", + "oauth2" + ], + "time": "2017-01-10 22:20:54" + }, + { + "name": "league/oauth2-client", + "version": "1.4.2", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/oauth2-client.git", + "reference": "01f955b85040b41cf48885b078f7fd39a8be5411" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/oauth2-client/zipball/01f955b85040b41cf48885b078f7fd39a8be5411", + "reference": "01f955b85040b41cf48885b078f7fd39a8be5411", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "guzzlehttp/guzzle": "~6.0", + "ircmaxell/random-lib": "~1.1", + "php": ">=5.5.0" + }, + "require-dev": { + "jakub-onderka/php-parallel-lint": "0.8.*", + "mockery/mockery": "~0.9", + "phpunit/phpunit": "~4.0", + "satooshi/php-coveralls": "0.6.*", + "squizlabs/php_codesniffer": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\OAuth2\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alex Bilbie", + "email": "hello@alexbilbie.com", + "homepage": "http://www.alexbilbie.com", + "role": "Developer" + } + ], + "description": "OAuth 2.0 Client Library", + "keywords": [ + "Authentication", + "SSO", + "authorization", + "identity", + "idp", + "oauth", + "oauth2", + "single sign on" + ], + "time": "2016-07-28 13:20:43" + }, + { + "name": "league/oauth2-google", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/oauth2-google.git", + "reference": "4788fcef5cf0fdb65e0322c3f4d4632d8f1f3e82" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/oauth2-google/zipball/4788fcef5cf0fdb65e0322c3f4d4632d8f1f3e82", + "reference": "4788fcef5cf0fdb65e0322c3f4d4632d8f1f3e82", + "shasum": "" + }, + "require": { + "league/oauth2-client": "~1.0" + }, + "require-dev": { + "mockery/mockery": "~0.9", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\OAuth2\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Woody Gilk", + "email": "woody.gilk@gmail.com", + "homepage": "http://shadowhand.me" + } + ], + "description": "Google OAuth 2.0 Client Provider for The PHP League OAuth2-Client", + "keywords": [ + "Authentication", + "authorization", + "client", + "google", + "oauth", + "oauth2" + ], + "time": "2015-08-28 18:33:30" + }, + { + "name": "paragonie/random_compat", + "version": "v2.0.4", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "a9b97968bcde1c4de2a5ec6cbd06a0f6c919b46e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/a9b97968bcde1c4de2a5ec6cbd06a0f6c919b46e", + "reference": "a9b97968bcde1c4de2a5ec6cbd06a0f6c919b46e", + "shasum": "" + }, + "require": { + "php": ">=5.2.0" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "autoload": { + "files": [ + "lib/random.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "pseudorandom", + "random" + ], + "time": "2016-11-07 23:38:38" + }, + { + "name": "psr/cache", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "time": "2016-08-06 20:24:11" + }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2016-08-06 14:39:51" + }, + { + "name": "psr/log", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2016-10-10 12:19:37" + }, + { + "name": "symfony/cache", + "version": "v3.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache.git", + "reference": "c96ac9056b38702683c1b719be2d7f0c00107240" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/cache/zipball/c96ac9056b38702683c1b719be2d7f0c00107240", + "reference": "c96ac9056b38702683c1b719be2d7f0c00107240", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "psr/cache": "~1.0", + "psr/log": "~1.0" + }, + "provide": { + "psr/cache-implementation": "1.0" + }, + "require-dev": { + "cache/integration-tests": "dev-master", + "doctrine/cache": "~1.6", + "doctrine/dbal": "~2.4", + "predis/predis": "~1.0" + }, + "suggest": { + "symfony/polyfill-apcu": "For using ApcuAdapter on HHVM" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Cache\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony implementation of PSR-6", + "homepage": "https://symfony.com", + "keywords": [ + "caching", + "psr6" + ], + "time": "2017-01-12 11:00:26" + }, + { + "name": "symfony/class-loader", + "version": "v3.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/class-loader.git", + "reference": "0152f7a47acd564ca62c652975c2b32ac6d613a6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/class-loader/zipball/0152f7a47acd564ca62c652975c2b32ac6d613a6", + "reference": "0152f7a47acd564ca62c652975c2b32ac6d613a6", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "require-dev": { + "symfony/finder": "~2.8|~3.0", + "symfony/polyfill-apcu": "~1.1" + }, + "suggest": { + "symfony/polyfill-apcu": "For using ApcClassLoader on HHVM" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\ClassLoader\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony ClassLoader Component", + "homepage": "https://symfony.com", + "time": "2017-01-10 14:14:38" + }, + { + "name": "symfony/config", + "version": "v3.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "c5ea878b5a7f6a01b9a2f182f905831711b9ff3f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/c5ea878b5a7f6a01b9a2f182f905831711b9ff3f", + "reference": "c5ea878b5a7f6a01b9a2f182f905831711b9ff3f", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "symfony/filesystem": "~2.8|~3.0" + }, + "require-dev": { + "symfony/yaml": "~3.0" + }, + "suggest": { + "symfony/yaml": "To use the yaml reference dumper" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Config\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Config Component", + "homepage": "https://symfony.com", + "time": "2017-01-02 20:32:22" + }, + { + "name": "symfony/console", + "version": "v3.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "4f9e449e76996adf310498a8ca955c6deebe29dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/4f9e449e76996adf310498a8ca955c6deebe29dd", + "reference": "4f9e449e76996adf310498a8ca955c6deebe29dd", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "symfony/debug": "~2.8|~3.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/event-dispatcher": "~2.8|~3.0", + "symfony/filesystem": "~2.8|~3.0", + "symfony/process": "~2.8|~3.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/filesystem": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "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": "Symfony Console Component", + "homepage": "https://symfony.com", + "time": "2017-01-08 20:47:33" + }, + { + "name": "symfony/debug", + "version": "v3.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/debug.git", + "reference": "810ba5c1c5352a4ddb15d4719e8936751dff0b05" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/debug/zipball/810ba5c1c5352a4ddb15d4719e8936751dff0b05", + "reference": "810ba5c1c5352a4ddb15d4719e8936751dff0b05", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "psr/log": "~1.0" + }, + "conflict": { + "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" + }, + "require-dev": { + "symfony/class-loader": "~2.8|~3.0", + "symfony/http-kernel": "~2.8|~3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "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": "Symfony Debug Component", + "homepage": "https://symfony.com", + "time": "2017-01-02 20:32:22" + }, + { + "name": "symfony/dependency-injection", + "version": "v3.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/dependency-injection.git", + "reference": "22b2c97cffc6a612db82084f9e7823b095958751" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/22b2c97cffc6a612db82084f9e7823b095958751", + "reference": "22b2c97cffc6a612db82084f9e7823b095958751", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "conflict": { + "symfony/yaml": "<3.2" + }, + "require-dev": { + "symfony/config": "~2.8|~3.0", + "symfony/expression-language": "~2.8|~3.0", + "symfony/yaml": "~3.2" + }, + "suggest": { + "symfony/config": "", + "symfony/expression-language": "For using expressions in service container configuration", + "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", + "symfony/yaml": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\DependencyInjection\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony DependencyInjection Component", + "homepage": "https://symfony.com", + "time": "2017-01-10 14:21:25" + }, + { + "name": "symfony/doctrine-bridge", + "version": "v3.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/doctrine-bridge.git", + "reference": "4be61f186195fb2a6d46d956dfeb2f8d58111626" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/4be61f186195fb2a6d46d956dfeb2f8d58111626", + "reference": "4be61f186195fb2a6d46d956dfeb2f8d58111626", + "shasum": "" + }, + "require": { + "doctrine/common": "~2.4", + "php": ">=5.5.9", + "symfony/polyfill-mbstring": "~1.0" + }, + "require-dev": { + "doctrine/data-fixtures": "1.0.*", + "doctrine/dbal": "~2.4", + "doctrine/orm": "~2.4,>=2.4.5", + "symfony/dependency-injection": "~2.8|~3.0", + "symfony/expression-language": "~2.8|~3.0", + "symfony/form": "~3.0,>=3.0.5", + "symfony/http-kernel": "~2.8|~3.0", + "symfony/property-access": "~2.8|~3.0", + "symfony/property-info": "~2.8|3.0", + "symfony/proxy-manager-bridge": "~2.8|~3.0", + "symfony/security": "~2.8|~3.0", + "symfony/stopwatch": "~2.8|~3.0", + "symfony/translation": "~2.8|~3.0", + "symfony/validator": "~2.8|~3.0" + }, + "suggest": { + "doctrine/data-fixtures": "", + "doctrine/dbal": "", + "doctrine/orm": "", + "symfony/form": "", + "symfony/property-info": "", + "symfony/validator": "" + }, + "type": "symfony-bridge", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Bridge\\Doctrine\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Doctrine Bridge", + "homepage": "https://symfony.com", + "time": "2017-01-02 20:32:22" + }, + { + "name": "symfony/event-dispatcher", + "version": "v3.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "9137eb3a3328e413212826d63eeeb0217836e2b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/9137eb3a3328e413212826d63eeeb0217836e2b6", + "reference": "9137eb3a3328e413212826d63eeeb0217836e2b6", + "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" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "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": "Symfony EventDispatcher Component", + "homepage": "https://symfony.com", + "time": "2017-01-02 20:32:22" + }, + { + "name": "symfony/filesystem", + "version": "v3.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "a0c6ef2dc78d33b58d91d3a49f49797a184d06f4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/a0c6ef2dc78d33b58d91d3a49f49797a184d06f4", + "reference": "a0c6ef2dc78d33b58d91d3a49f49797a184d06f4", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Filesystem Component", + "homepage": "https://symfony.com", + "time": "2017-01-08 20:47:33" + }, + { + "name": "symfony/finder", + "version": "v3.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "8c71141cae8e2957946b403cc71a67213c0380d6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/8c71141cae8e2957946b403cc71a67213c0380d6", + "reference": "8c71141cae8e2957946b403cc71a67213c0380d6", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Finder Component", + "homepage": "https://symfony.com", + "time": "2017-01-02 20:32:22" + }, + { + "name": "symfony/framework-bundle", + "version": "v3.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/framework-bundle.git", + "reference": "56ee53e901867cbb63f168a06efc6716b47e0cb7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/56ee53e901867cbb63f168a06efc6716b47e0cb7", + "reference": "56ee53e901867cbb63f168a06efc6716b47e0cb7", + "shasum": "" + }, + "require": { + "doctrine/cache": "~1.0", + "php": ">=5.5.9", + "symfony/cache": "~3.2.2|~3.3", + "symfony/class-loader": "~3.2", + "symfony/config": "~2.8|~3.0", + "symfony/dependency-injection": "~3.2.1|~3.3", + "symfony/event-dispatcher": "~2.8|~3.0", + "symfony/filesystem": "~2.8|~3.0", + "symfony/finder": "~2.8|~3.0", + "symfony/http-foundation": "~3.1", + "symfony/http-kernel": "~3.2.2|~3.3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/routing": "~3.0", + "symfony/stopwatch": "~2.8|~3.0" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "<3.0", + "phpdocumentor/type-resolver": "<0.2.0" + }, + "require-dev": { + "doctrine/annotations": "~1.0", + "phpdocumentor/reflection-docblock": "^3.0", + "symfony/asset": "~2.8|~3.0", + "symfony/browser-kit": "~2.8|~3.0", + "symfony/console": "~2.8.8|~3.0.8|~3.1.2|~3.2", + "symfony/css-selector": "~2.8|~3.0", + "symfony/dom-crawler": "~2.8|~3.0", + "symfony/expression-language": "~2.8|~3.0", + "symfony/form": "~2.8.16|~3.1.9|^3.2.2", + "symfony/polyfill-intl-icu": "~1.0", + "symfony/process": "~2.8|~3.0", + "symfony/property-info": "~2.8|~3.0", + "symfony/security": "~2.8|~3.0", + "symfony/security-core": "~3.2", + "symfony/security-csrf": "~2.8|~3.0", + "symfony/serializer": "~2.8|~3.0", + "symfony/templating": "~2.8|~3.0", + "symfony/translation": "~2.8|~3.0", + "symfony/validator": "~3.2", + "symfony/yaml": "~3.2", + "twig/twig": "~1.26|~2.0" + }, + "suggest": { + "ext-apcu": "For best performance of the system caches", + "symfony/console": "For using the console commands", + "symfony/form": "For using forms", + "symfony/process": "For using the server:run, server:start, server:stop, and server:status commands", + "symfony/property-info": "For using the property_info service", + "symfony/serializer": "For using the serializer service", + "symfony/validator": "For using validation", + "symfony/yaml": "For using the debug:config and lint:yaml commands" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Bundle\\FrameworkBundle\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony FrameworkBundle", + "homepage": "https://symfony.com", + "time": "2017-01-12 20:17:20" + }, + { + "name": "symfony/http-foundation", + "version": "v3.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "33eb76bf1d833c705433e5361a646c164696394b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/33eb76bf1d833c705433e5361a646c164696394b", + "reference": "33eb76bf1d833c705433e5361a646c164696394b", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "symfony/polyfill-mbstring": "~1.1" + }, + "require-dev": { + "symfony/expression-language": "~2.8|~3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpFoundation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony HttpFoundation Component", + "homepage": "https://symfony.com", + "time": "2017-01-08 20:47:33" + }, + { + "name": "symfony/http-kernel", + "version": "v3.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-kernel.git", + "reference": "8a898e340a89022246645b1288d295f49c9381e4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/8a898e340a89022246645b1288d295f49c9381e4", + "reference": "8a898e340a89022246645b1288d295f49c9381e4", + "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.13|~3.1.6|~3.2" + }, + "conflict": { + "symfony/config": "<2.8" + }, + "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": "~3.2" + }, + "suggest": { + "symfony/browser-kit": "", + "symfony/class-loader": "", + "symfony/config": "", + "symfony/console": "", + "symfony/dependency-injection": "", + "symfony/finder": "", + "symfony/var-dumper": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpKernel\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony HttpKernel Component", + "homepage": "https://symfony.com", + "time": "2017-01-12 21:36:33" + }, + { + "name": "symfony/inflector", + "version": "v3.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/inflector.git", + "reference": "20a37c39c1f29badc188e4c50a061b79c8bf3ff6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/inflector/zipball/20a37c39c1f29badc188e4c50a061b79c8bf3ff6", + "reference": "20a37c39c1f29badc188e4c50a061b79c8bf3ff6", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Inflector\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Inflector Component", + "homepage": "https://symfony.com", + "keywords": [ + "inflection", + "pluralize", + "singularize", + "string", + "symfony", + "words" + ], + "time": "2017-01-02 20:32:22" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/e79d363049d1c2128f133a2667e4f4190904f7f4", + "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "time": "2016-11-14 01:06:16" + }, + { + "name": "symfony/polyfill-php56", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php56.git", + "reference": "1dd42b9b89556f18092f3d1ada22cb05ac85383c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php56/zipball/1dd42b9b89556f18092f3d1ada22cb05ac85383c", + "reference": "1dd42b9b89556f18092f3d1ada22cb05ac85383c", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "symfony/polyfill-util": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php56\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 5.6+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2016-11-14 01:06:16" + }, + { + "name": "symfony/polyfill-php70", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php70.git", + "reference": "13ce343935f0f91ca89605a2f6ca6f5c2f3faac2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/13ce343935f0f91ca89605a2f6ca6f5c2f3faac2", + "reference": "13ce343935f0f91ca89605a2f6ca6f5c2f3faac2", + "shasum": "" + }, + "require": { + "paragonie/random_compat": "~1.0|~2.0", + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php70\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2016-11-14 01:06:16" + }, + { + "name": "symfony/polyfill-util", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-util.git", + "reference": "746bce0fca664ac0a575e465f65c6643faddf7fb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-util/zipball/746bce0fca664ac0a575e465f65c6643faddf7fb", + "reference": "746bce0fca664ac0a575e465f65c6643faddf7fb", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Util\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony utilities for portability of PHP codes", + "homepage": "https://symfony.com", + "keywords": [ + "compat", + "compatibility", + "polyfill", + "shim" + ], + "time": "2016-11-14 01:06:16" + }, + { + "name": "symfony/property-access", + "version": "v3.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/property-access.git", + "reference": "370a5276e00885648f6dde3cabc7c61eaab57bd8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/property-access/zipball/370a5276e00885648f6dde3cabc7c61eaab57bd8", + "reference": "370a5276e00885648f6dde3cabc7c61eaab57bd8", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "symfony/inflector": "~3.1", + "symfony/polyfill-php70": "~1.0" + }, + "require-dev": { + "symfony/cache": "~3.1" + }, + "suggest": { + "psr/cache-implementation": "To cache access methods." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\PropertyAccess\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony PropertyAccess Component", + "homepage": "https://symfony.com", + "keywords": [ + "access", + "array", + "extraction", + "index", + "injection", + "object", + "property", + "property path", + "reflection" + ], + "time": "2017-01-02 20:32:22" + }, + { + "name": "symfony/routing", + "version": "v3.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/routing.git", + "reference": "fda2c67d47ec801726ca888c95d701d31b27b444" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/routing/zipball/fda2c67d47ec801726ca888c95d701d31b27b444", + "reference": "fda2c67d47ec801726ca888c95d701d31b27b444", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "conflict": { + "symfony/config": "<2.8" + }, + "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" + }, + "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" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Routing\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Routing Component", + "homepage": "https://symfony.com", + "keywords": [ + "router", + "routing", + "uri", + "url" + ], + "time": "2017-01-02 20:32:22" + }, + { + "name": "symfony/security-core", + "version": "v3.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/security-core.git", + "reference": "72b310c5d510ca48d7a8c4cd5e4af95c8896dd25" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/security-core/zipball/72b310c5d510ca48d7a8c4cd5e4af95c8896dd25", + "reference": "72b310c5d510ca48d7a8c4cd5e4af95c8896dd25", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "symfony/polyfill-php56": "~1.0", + "symfony/polyfill-util": "~1.0" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/event-dispatcher": "~2.8|~3.0", + "symfony/expression-language": "~2.8|~3.0", + "symfony/http-foundation": "~2.8|~3.0", + "symfony/ldap": "~3.1", + "symfony/validator": "~2.8|~3.0" + }, + "suggest": { + "symfony/event-dispatcher": "", + "symfony/expression-language": "For using the expression voter", + "symfony/http-foundation": "", + "symfony/ldap": "For using LDAP integration", + "symfony/validator": "For using the user password constraint" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Security\\Core\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Security Component - Core Library", + "homepage": "https://symfony.com", + "time": "2017-01-02 20:32:22" + }, + { + "name": "symfony/security-guard", + "version": "v3.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/security-guard.git", + "reference": "9c627b9465f16a72aed038e3dd7e26b4b095988c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/security-guard/zipball/9c627b9465f16a72aed038e3dd7e26b4b095988c", + "reference": "9c627b9465f16a72aed038e3dd7e26b4b095988c", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "symfony/security-core": "~2.8|~3.0", + "symfony/security-http": "~3.1" + }, + "require-dev": { + "psr/log": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Security\\Guard\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Security Component - Guard", + "homepage": "https://symfony.com", + "time": "2017-01-02 20:32:22" + }, + { + "name": "symfony/security-http", + "version": "v3.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/security-http.git", + "reference": "bd2250a97046d995c183ae4dc51e3c97d23d605f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/security-http/zipball/bd2250a97046d995c183ae4dc51e3c97d23d605f", + "reference": "bd2250a97046d995c183ae4dc51e3c97d23d605f", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "symfony/event-dispatcher": "~2.8|~3.0", + "symfony/http-foundation": "~2.8|~3.0", + "symfony/http-kernel": "~2.8|~3.0", + "symfony/polyfill-php56": "~1.0", + "symfony/polyfill-php70": "~1.0", + "symfony/property-access": "~2.8|~3.0", + "symfony/security-core": "~3.2" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/routing": "~2.8|~3.0", + "symfony/security-csrf": "~2.8|~3.0" + }, + "suggest": { + "symfony/routing": "For using the HttpUtils class to create sub-requests, redirect the user, and match URLs", + "symfony/security-csrf": "For using tokens to protect authentication/logout attempts" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Security\\Http\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Security Component - HTTP Integration", + "homepage": "https://symfony.com", + "time": "2017-01-02 20:32:22" + }, + { + "name": "symfony/stopwatch", + "version": "v3.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "9aa0b51889c01bca474853ef76e9394b02264464" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/9aa0b51889c01bca474853ef76e9394b02264464", + "reference": "9aa0b51889c01bca474853ef76e9394b02264464", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Stopwatch Component", + "homepage": "https://symfony.com", + "time": "2017-01-02 20:32:22" + }, + { + "name": "twig/twig", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/twigphp/Twig.git", + "reference": "ddc9e3e20ee9c0b6908f401ac8353635b750eca7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/ddc9e3e20ee9c0b6908f401ac8353635b750eca7", + "reference": "ddc9e3e20ee9c0b6908f401ac8353635b750eca7", + "shasum": "" + }, + "require": { + "php": ">=5.2.7" + }, + "require-dev": { + "symfony/debug": "~2.7", + "symfony/phpunit-bridge": "~3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.31-dev" + } + }, + "autoload": { + "psr-0": { + "Twig_": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "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" + } + ], + "description": "Twig, the flexible, fast, and secure template language for PHP", + "homepage": "http://twig.sensiolabs.org", + "keywords": [ + "templating" + ], + "time": "2017-01-11 19:36:15" + } + ], + "packages-dev": [ + { + "name": "doctrine/instantiator", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", + "shasum": "" + }, + "require": { + "php": ">=5.3,<8.0-DEV" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2015-06-14 21:17:01" + }, + { + "name": "myclabs/deep-copy", + "version": "1.5.5", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "399c1f9781e222f6eb6cc238796f5200d1b7f108" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/399c1f9781e222f6eb6cc238796f5200d1b7f108", + "reference": "399c1f9781e222f6eb6cc238796f5200d1b7f108", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "doctrine/collections": "1.*", + "phpunit/phpunit": "~4.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "homepage": "https://github.com/myclabs/DeepCopy", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "time": "2016-10-31 17:19:45" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "1.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c", + "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "time": "2015-12-27 11:43:31" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/8331b5efe816ae05461b7ca1e721c01b46bafb3e", + "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e", + "shasum": "" + }, + "require": { + "php": ">=5.5", + "phpdocumentor/reflection-common": "^1.0@dev", + "phpdocumentor/type-resolver": "^0.2.0", + "webmozart/assert": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^4.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "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-09-30 07:12:33" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "0.2.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb", + "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb", + "shasum": "" + }, + "require": { + "php": ">=5.5", + "phpdocumentor/reflection-common": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^5.2||^4.8.24" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "time": "2016-11-25 06:54:22" + }, + { + "name": "phpspec/prophecy", + "version": "v1.6.2", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "6c52c2722f8460122f96f86346600e1077ce22cb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/6c52c2722f8460122f96f86346600e1077ce22cb", + "reference": "6c52c2722f8460122f96f86346600e1077ce22cb", + "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|^2.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.0", + "phpunit/phpunit": "^4.8 || ^5.6.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2016-11-21 14:58:47" + }, + { + "name": "phpunit/php-code-coverage", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "c14196e64a78570034afd0b7a9f3757ba71c2a0a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c14196e64a78570034afd0b7a9f3757ba71c2a0a", + "reference": "c14196e64a78570034afd0b7a9f3757ba71c2a0a", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0", + "phpunit/php-file-iterator": "~1.3", + "phpunit/php-text-template": "~1.2", + "phpunit/php-token-stream": "^1.4.2", + "sebastian/code-unit-reverse-lookup": "~1.0", + "sebastian/environment": "^1.3.2 || ^2.0", + "sebastian/version": "~1.0|~2.0" + }, + "require-dev": { + "ext-xdebug": ">=2.1.4", + "phpunit/phpunit": "^5.4" + }, + "suggest": { + "ext-dom": "*", + "ext-xdebug": ">=2.4.0", + "ext-xmlwriter": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2016-12-20 15:22:42" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.4.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5", + "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2016-10-03 07:40:28" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2015-06-21 13:50:34" + }, + { + "name": "phpunit/php-timer", + "version": "1.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260", + "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4|~5" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2016-05-12 18:03:57" + }, + { + "name": "phpunit/php-token-stream", + "version": "1.4.9", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3b402f65a4cc90abf6e1104e388b896ce209631b", + "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "time": "2016-11-15 14:06:22" + }, + { + "name": "phpunit/phpunit", + "version": "5.7.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "50fd2be8f3e23e91da825f36f08e5f9633076ffe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/50fd2be8f3e23e91da825f36f08e5f9633076ffe", + "reference": "50fd2be8f3e23e91da825f36f08e5f9633076ffe", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "myclabs/deep-copy": "~1.3", + "php": "^5.6 || ^7.0", + "phpspec/prophecy": "^1.6.2", + "phpunit/php-code-coverage": "^4.0.3", + "phpunit/php-file-iterator": "~1.4", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": "^1.0.6", + "phpunit/phpunit-mock-objects": "^3.2", + "sebastian/comparator": "~1.2.2", + "sebastian/diff": "~1.2", + "sebastian/environment": "^1.3.4 || ^2.0", + "sebastian/exporter": "~2.0", + "sebastian/global-state": "^1.0 || ^2.0", + "sebastian/object-enumerator": "~2.0", + "sebastian/resource-operations": "~1.0", + "sebastian/version": "~1.0|~2.0", + "symfony/yaml": "~2.1|~3.0" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "3.0.2" + }, + "require-dev": { + "ext-pdo": "*" + }, + "suggest": { + "ext-xdebug": "*", + "phpunit/php-invoker": "~1.1" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.7.x-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" + ], + "time": "2016-12-28 07:18:51" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "3.4.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "3ab72b65b39b491e0c011e2e09bb2206c2aa8e24" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/3ab72b65b39b491e0c011e2e09bb2206c2aa8e24", + "reference": "3ab72b65b39b491e0c011e2e09bb2206c2aa8e24", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.6 || ^7.0", + "phpunit/php-text-template": "^1.2", + "sebastian/exporter": "^1.2 || ^2.0" + }, + "conflict": { + "phpunit/phpunit": "<5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.4" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "time": "2016-12-08 20:27:08" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/c36f5e7cfce482fde5bf8d10d41a53591e0198fe", + "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "phpunit/phpunit": "~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/", + "time": "2016-02-13 06:45:14" + }, + { + "name": "sebastian/comparator", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "6a1ed12e8b2409076ab22e3897126211ff8b1f7f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/6a1ed12e8b2409076ab22e3897126211ff8b1f7f", + "reference": "6a1ed12e8b2409076ab22e3897126211ff8b1f7f", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/diff": "~1.2", + "sebastian/exporter": "~1.2 || ~2.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "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" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2016-11-19 09:18:40" + }, + { + "name": "sebastian/diff", + "version": "1.4.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", + "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "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", + "keywords": [ + "diff" + ], + "time": "2015-12-08 07:14:41" + }, + { + "name": "sebastian/environment", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5795ffe5dc5b02460c3e34222fee8cbe245d8fac", + "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.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": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2016-11-26 07:53:53" + }, + { + "name": "sebastian/exporter", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", + "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/recursion-context": "~2.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "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" + ], + "time": "2016-11-19 08:54:04" + }, + { + "name": "sebastian/global-state", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2015-10-12 03:26:01" + }, + { + "name": "sebastian/object-enumerator", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "96f8a3f257b69e8128ad74d3a7fd464bcbaa3b35" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/96f8a3f257b69e8128ad74d3a7fd464bcbaa3b35", + "reference": "96f8a3f257b69e8128ad74d3a7fd464bcbaa3b35", + "shasum": "" + }, + "require": { + "php": ">=5.6", + "sebastian/recursion-context": "~2.0" + }, + "require-dev": { + "phpunit/phpunit": "~5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.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": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "time": "2016-11-19 07:35:10" + }, + { + "name": "sebastian/recursion-context", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/2c3ba150cbec723aa057506e73a8d33bdb286c9a", + "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2016-11-19 07:33:16" + }, + { + "name": "sebastian/resource-operations", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "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": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "time": "2015-07-28 20:34:47" + }, + { + "name": "sebastian/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + }, + "dist": { + "type": "zip", + "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/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2016-10-03 07:35:21" + }, + { + "name": "symfony/phpunit-bridge", + "version": "v3.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/phpunit-bridge.git", + "reference": "d32e4062c3a3dfb95709d2ca6dd89a327ae51c3b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/d32e4062c3a3dfb95709d2ca6dd89a327ae51c3b", + "reference": "d32e4062c3a3dfb95709d2ca6dd89a327ae51c3b", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "symfony/debug": "For tracking deprecated interfaces usages at runtime with DebugClassLoader" + }, + "bin": [ + "bin/simple-phpunit" + ], + "type": "symfony-bridge", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Bridge\\PhpUnit\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony PHPUnit Bridge", + "homepage": "https://symfony.com", + "time": "2017-01-06 17:19:17" + }, + { + "name": "symfony/yaml", + "version": "v3.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "50eadbd7926e31842893c957eca362b21592a97d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/50eadbd7926e31842893c957eca362b21592a97d", + "reference": "50eadbd7926e31842893c957eca362b21592a97d", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "require-dev": { + "symfony/console": "~2.8|~3.0" + }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Yaml Component", + "homepage": "https://symfony.com", + "time": "2017-01-03 13:51:32" + }, + { + "name": "webmozart/assert", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f", + "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "time": "2016-11-23 20:04:58" + } + ], + "aliases": [], + "minimum-stability": "dev", + "stability-flags": [], + "prefer-stable": true, + "prefer-lowest": false, + "platform": { + "php": ">=7.0" + }, + "platform-dev": [], + "platform-overrides": { + "php": "7.0" + } +} diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..d738053 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,30 @@ + + + + + + + + + + + ./Tests + + + + + + ./ + + ./Resources + ./Tests + ./vendor + + + +