From e74bb796c3efbe9b6bedfa0e5f257189e6d830d7 Mon Sep 17 00:00:00 2001 From: Jeremy Guiselin <jeremy.guiselin@student.ecp.fr> Date: Sat, 10 Dec 2016 11:09:16 +0100 Subject: [PATCH] and teams + notification + API --- app/AppKernel.php | 3 +- app/config/config.yml | 17 + app/config/routing.yml | 3 +- composer.json | 5 +- composer.lock | 713 +++++++++++++++--- google-service-account.json | 12 + .../Controller/DefaultController.php | 183 ++++- .../Controller/EntityBrowserController.php | 8 +- .../Controller/NotificationController.php | 114 ++- src/BackendBundle/Entity/Device.php | 189 +++++ src/BackendBundle/Entity/Notification.php | 148 ++++ .../Entity/NotificationOnDevice.php | 119 +++ src/BackendBundle/Entity/Prediction.php | 18 +- src/BackendBundle/Entity/Team.php | 68 ++ src/BackendBundle/Form/NotificationType.php | 36 + src/BackendBundle/Form/PredictionType.php | 31 +- src/BackendBundle/Form/TeamType.php | 32 + .../Repository/DeviceRepository.php | 49 ++ .../NotificationOnDeviceRepository.php | 53 ++ .../Repository/NotificationRepository.php | 35 + .../Repository/TeamRepository.php | 38 + .../views/layout/dashboard.html.twig | 5 +- .../views/notification/create.html.twig | 23 + .../views/notification/index.html.twig | 0 .../views/notification/list.html.twig | 47 ++ .../Resources/views/prediction/form.html.twig | 60 +- .../Resources/views/prediction/list.html.twig | 10 +- .../Resources/views/team/form.html.twig | 32 + .../Resources/views/team/list.html.twig | 43 ++ web/config.php | 217 +++++- web/css/style.css | 27 + 31 files changed, 2150 insertions(+), 188 deletions(-) create mode 100644 google-service-account.json create mode 100644 src/BackendBundle/Entity/Device.php create mode 100644 src/BackendBundle/Entity/Notification.php create mode 100644 src/BackendBundle/Entity/NotificationOnDevice.php create mode 100644 src/BackendBundle/Entity/Team.php create mode 100644 src/BackendBundle/Form/NotificationType.php create mode 100644 src/BackendBundle/Form/TeamType.php create mode 100644 src/BackendBundle/Repository/DeviceRepository.php create mode 100644 src/BackendBundle/Repository/NotificationOnDeviceRepository.php create mode 100644 src/BackendBundle/Repository/NotificationRepository.php create mode 100644 src/BackendBundle/Repository/TeamRepository.php create mode 100644 src/BackendBundle/Resources/views/notification/create.html.twig delete mode 100644 src/BackendBundle/Resources/views/notification/index.html.twig create mode 100644 src/BackendBundle/Resources/views/notification/list.html.twig create mode 100644 src/BackendBundle/Resources/views/team/form.html.twig create mode 100644 src/BackendBundle/Resources/views/team/list.html.twig diff --git a/app/AppKernel.php b/app/AppKernel.php index 9f0252f..a6888df 100644 --- a/app/AppKernel.php +++ b/app/AppKernel.php @@ -17,9 +17,8 @@ class AppKernel extends Kernel new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(), new BackendBundle\BackendBundle(), new JMS\SerializerBundle\JMSSerializerBundle(), - new RMS\PushNotificationsBundle\RMSPushNotificationsBundle(), new ApiBundle\ApiBundle(), - new FOS\RestBundle\FOSRestBundle(), + new FOS\RestBundle\FOSRestBundle() ]; if (in_array($this->getEnvironment(), ['dev', 'test'], true)) { diff --git a/app/config/config.yml b/app/config/config.yml index 841bcb8..c451008 100644 --- a/app/config/config.yml +++ b/app/config/config.yml @@ -70,3 +70,20 @@ swiftmailer: username: "%mailer_user%" password: "%mailer_password%" spool: { type: memory } + +fos_rest: + view: + formats: + json: true + xml: false + html: false + rss: false + templating_formats: + json: false + xml: false + html: false + rss: false + view_response_listener: 'force' + routing_loader: + include_format: false + default_format: json diff --git a/app/config/routing.yml b/app/config/routing.yml index 4fb543f..e9a1189 100644 --- a/app/config/routing.yml +++ b/app/config/routing.yml @@ -1,6 +1,7 @@ api: resource: "@ApiBundle/Controller/" - type: annotation + type: rest + defaults: {_format: json} prefix: /api backend: diff --git a/composer.json b/composer.json index 17ab514..2872d53 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ } }, "require": { - "php": ">=5.5.9", + "php": "^7.0", "symfony/symfony": "3.1.*", "doctrine/orm": "^2.5", "doctrine/doctrine-bundle": "^1.6", @@ -29,7 +29,6 @@ "sensio/framework-extra-bundle": "^3.0.2", "incenteev/composer-parameter-handler": "^2.0", "jms/serializer-bundle": "^1.1", - "richsage/rms-push-notifications-bundle": "dev-master", "friendsofsymfony/rest-bundle": "^2.1" }, "require-dev": { @@ -54,7 +53,7 @@ }, "config": { "platform": { - "php": "5.5.9" + "php": "7.0" } }, "extra": { diff --git a/composer.lock b/composer.lock index a37fd7e..ed8297d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "949f86b0d629d6d6f28aaeed8c203c54", - "content-hash": "6476d980fd3be1501a0134c9b160fa0d", + "hash": "e2ad80fd5d559db7f34d32407738a93b", + "content-hash": "6dd49f9599d38261eba217230b75a721", "packages": [ { "name": "doctrine/annotations", @@ -775,6 +775,220 @@ ], "time": "2016-09-10 18:51:13" }, + { + "name": "eightpoints/guzzle-bundle", + "version": "v5.0.3", + "target-dir": "EightPoints/Bundle/GuzzleBundle", + "source": { + "type": "git", + "url": "https://github.com/8p/GuzzleBundle.git", + "reference": "9afc670d5b730ab1d90d92f50b86fa5282279d28" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/8p/GuzzleBundle/zipball/9afc670d5b730ab1d90d92f50b86fa5282279d28", + "reference": "9afc670d5b730ab1d90d92f50b86fa5282279d28", + "shasum": "" + }, + "require": { + "eightpoints/guzzle-wsse-middleware": "~4.0", + "guzzlehttp/guzzle": "~6.0", + "php": ">=5.6", + "psr/log": "~1.0", + "symfony/dependency-injection": "~2.3|~3.0", + "symfony/event-dispatcher": "~2.3|~3.0", + "symfony/expression-language": "~2.3|~3.0", + "symfony/http-kernel": "~2.3|~3.0" + }, + "require-dev": { + "phpunit/phpunit": "~5.4", + "symfony/config": "2.3|~3.0" + }, + "type": "symfony-bundle", + "autoload": { + "psr-0": { + "EightPoints\\Bundle\\GuzzleBundle": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Community", + "homepage": "https://github.com/8p/GuzzleBundle/contributors" + }, + { + "name": "Florian Preusner", + "email": "florian.preusner@8points.de", + "homepage": "https://github.com/florianpreusner" + } + ], + "description": "Integrates Guzzle into Symfony2, comes with WSSE Plugin for RESTful Interfaces", + "homepage": "https://github.com/8p/GuzzleBundle", + "keywords": [ + "Guzzle", + "bundle", + "client", + "curl", + "http client", + "rest", + "symfony", + "web service" + ], + "time": "2016-09-30 17:12:30" + }, + { + "name": "eightpoints/guzzle-wsse-middleware", + "version": "v4.2.0", + "source": { + "type": "git", + "url": "https://github.com/8p/guzzle-wsse-middleware.git", + "reference": "3998dae6fed29f2d3384024764046b63a764ddda" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/8p/guzzle-wsse-middleware/zipball/3998dae6fed29f2d3384024764046b63a764ddda", + "reference": "3998dae6fed29f2d3384024764046b63a764ddda", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": ">=6.0", + "php": ">=5.5" + }, + "type": "library", + "autoload": { + "psr-0": { + "EightPoints\\Guzzle": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Florian Preusner", + "email": "florian.preusner@8points.de", + "homepage": "https://github.com/florianpreusner" + }, + { + "name": "Community", + "homepage": "https://github.com/eightpoints/guzzle-wsse-middleware/contributors" + } + ], + "description": "WSSE Middleware for Guzzle, a PHP HTTP client library and framework for building RESTful web service clients", + "homepage": "https://github.com/8p/guzzle-wsse-middleware", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "middleware", + "plugin", + "rest", + "web service", + "wsse" + ], + "time": "2016-06-03 14:03:33" + }, + { + "name": "firebase/php-jwt", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/firebase/php-jwt.git", + "reference": "fa8a06e96526eb7c0eeaa47e4f39be59d21f16e1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/fa8a06e96526eb7c0eeaa47e4f39be59d21f16e1", + "reference": "fa8a06e96526eb7c0eeaa47e4f39be59d21f16e1", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Firebase\\JWT\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Neuman Vong", + "email": "neuman+pear@twilio.com", + "role": "Developer" + }, + { + "name": "Anant Narayanan", + "email": "anant@php.net", + "role": "Developer" + } + ], + "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", + "homepage": "https://github.com/firebase/php-jwt", + "time": "2015-07-22 18:31:08" + }, + { + "name": "firebase/token-generator", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/firebase/firebase-token-generator-php.git", + "reference": "60f74f02ae9e0ab498def706bdf43582379086f6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/firebase/firebase-token-generator-php/zipball/60f74f02ae9e0ab498def706bdf43582379086f6", + "reference": "60f74f02ae9e0ab498def706bdf43582379086f6", + "shasum": "" + }, + "require": { + "firebase/php-jwt": "^3.0", + "php": ">=5.4" + }, + "require-dev": { + "phpunit/phpunit": "^4.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Firebase\\Token\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Anant Narayanan", + "email": "anant@php.net", + "role": "Developer" + }, + { + "name": "Chris Raynor", + "email": "chris@firebase.com", + "role": "Developer" + } + ], + "description": "A simple library to generate JWT tokens for authenticating to a Firebase.", + "homepage": "https://github.com/firebase/firebase-token-generator-php", + "time": "2015-11-19 06:18:40" + }, { "name": "friendsofsymfony/rest-bundle", "version": "2.1.0", @@ -863,6 +1077,225 @@ ], "time": "2016-09-07 15:10:55" }, + { + "name": "google/auth", + "version": "v0.9", + "source": { + "type": "git", + "url": "https://github.com/google/google-auth-library-php.git", + "reference": "47c3c6bece495e58381a21fed13a735bd23a51cc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/google/google-auth-library-php/zipball/47c3c6bece495e58381a21fed13a735bd23a51cc", + "reference": "47c3c6bece495e58381a21fed13a735bd23a51cc", + "shasum": "" + }, + "require": { + "firebase/php-jwt": "~2.0|~3.0", + "guzzlehttp/guzzle": "~5.3|~6.0", + "guzzlehttp/psr7": "~1.2", + "php": ">=5.4", + "psr/cache": "^1.0", + "psr/http-message": "^1.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^1.11", + "phpunit/phpunit": "3.7.*" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ], + "psr-4": { + "Google\\Auth\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "description": "Google Auth Library for PHP", + "homepage": "http://github.com/google/google-auth-library-php", + "keywords": [ + "Authentication", + "google", + "oauth2" + ], + "time": "2016-06-01 22:07:52" + }, + { + "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": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "c10d860e2a9595f8883527fa0021c7da9e65f579" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/c10d860e2a9595f8883527fa0021c7da9e65f579", + "reference": "c10d860e2a9595f8883527fa0021c7da9e65f579", + "shasum": "" + }, + "require": { + "php": ">=5.5.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-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-05-18 16:56:05" + }, + { + "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": "incenteev/composer-parameter-handler", "version": "v2.1.2", @@ -1196,52 +1629,66 @@ "time": "2015-11-10 12:26:42" }, { - "name": "kriswallsmith/buzz", - "version": "v0.15", + "name": "kreait/firebase-php", + "version": "2.0.0-beta2", "source": { "type": "git", - "url": "https://github.com/kriswallsmith/Buzz.git", - "reference": "d4041666c3ffb379af02a92dabe81c904b35fab8" + "url": "https://github.com/kreait/firebase-php.git", + "reference": "ebee678764737f4163a9d4bd033b4565143cce4d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/kriswallsmith/Buzz/zipball/d4041666c3ffb379af02a92dabe81c904b35fab8", - "reference": "d4041666c3ffb379af02a92dabe81c904b35fab8", + "url": "https://api.github.com/repos/kreait/firebase-php/zipball/ebee678764737f4163a9d4bd033b4565143cce4d", + "reference": "ebee678764737f4163a9d4bd033b4565143cce4d", "shasum": "" }, "require": { - "php": ">=5.3.0" + "ext-mbstring": "*", + "firebase/token-generator": "^3.0", + "google/auth": "^0.9.0", + "guzzlehttp/guzzle": "^6.2.1", + "mtdowling/jmespath.php": "^2.3", + "php": "^7.0" }, "require-dev": { - "phpunit/phpunit": "3.7.*" - }, - "suggest": { - "ext-curl": "*" + "fabpot/php-cs-fixer": "^1.11", + "phpunit/phpunit": "^5.5" }, "type": "library", - "autoload": { - "psr-0": { - "Buzz": "lib/" + "extra": { + "branch-alias": { + "dev-1.0": "1.x-dev", + "dev-master": "2.x-dev" } }, + "autoload": { + "psr-4": { + "Firebase\\": "src/Firebase" + }, + "files": [ + "src/Firebase.php" + ] + }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { - "name": "Kris Wallsmith", - "email": "kris.wallsmith@gmail.com", - "homepage": "http://kriswallsmith.net/" + "name": "Jérôme Gamez", + "homepage": "https://github.com/jeromegamez" } ], - "description": "Lightweight HTTP client", - "homepage": "https://github.com/kriswallsmith/Buzz", + "description": "PHP SDK for Google Firebase", + "homepage": "https://github.com/kreait/firebase-php", "keywords": [ - "curl", - "http client" + "api", + "database", + "firebase", + "google", + "sdk" ], - "time": "2015-06-25 17:26:56" + "time": "2016-10-11 13:13:47" }, { "name": "monolog/monolog", @@ -1321,6 +1768,61 @@ ], "time": "2016-07-29 03:23:52" }, + { + "name": "mtdowling/jmespath.php", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/jmespath/jmespath.php.git", + "reference": "192f93e43c2c97acde7694993ab171b3de284093" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/192f93e43c2c97acde7694993ab171b3de284093", + "reference": "192f93e43c2c97acde7694993ab171b3de284093", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "bin": [ + "bin/jp.php" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "JmesPath\\": "src/" + }, + "files": [ + "src/JmesPath.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Declaratively specify how to extract elements from a JSON document", + "keywords": [ + "json", + "jsonpath" + ], + "time": "2016-01-05 18:25:05" + }, { "name": "paragonie/random_compat", "version": "v2.0.2", @@ -1514,17 +2016,17 @@ "time": "2016-08-06 20:24:11" }, { - "name": "psr/log", + "name": "psr/http-message", "version": "1.0.1", "source": { "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "5277094ed527a1c4477177d102fe4c53551953e0" + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/5277094ed527a1c4477177d102fe4c53551953e0", - "reference": "5277094ed527a1c4477177d102fe4c53551953e0", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", "shasum": "" }, "require": { @@ -1538,7 +2040,7 @@ }, "autoload": { "psr-4": { - "Psr\\Log\\": "Psr/Log/" + "Psr\\Http\\Message\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1551,50 +2053,44 @@ "homepage": "http://www.php-fig.org/" } ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", "keywords": [ - "log", + "http", + "http-message", "psr", - "psr-3" + "psr-7", + "request", + "response" ], - "time": "2016-09-19 16:02:08" + "time": "2016-08-06 14:39:51" }, { - "name": "richsage/rms-push-notifications-bundle", - "version": "dev-master", - "target-dir": "RMS/PushNotificationsBundle", + "name": "psr/log", + "version": "1.0.2", "source": { "type": "git", - "url": "https://github.com/richsage/RMSPushNotificationsBundle.git", - "reference": "324b29431ad58a006f53891cb103fad65c23d948" + "url": "https://github.com/php-fig/log.git", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/richsage/RMSPushNotificationsBundle/zipball/324b29431ad58a006f53891cb103fad65c23d948", - "reference": "324b29431ad58a006f53891cb103fad65c23d948", + "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", "shasum": "" }, "require": { - "kriswallsmith/buzz": "*", - "php": ">=5.3.0", - "psr/log": "^1.0" - }, - "require-dev": { - "symfony/symfony": "2.*" - }, - "suggest": { - "symfony/symfony": "To use as a bundle" + "php": ">=5.3.0" }, - "type": "symfony-bundle", + "type": "library", "extra": { "branch-alias": { - "dev-master": "0.2.x-dev" + "dev-master": "1.0.x-dev" } }, "autoload": { - "psr-0": { - "RMS\\PushNotificationsBundle": "" + "psr-4": { + "Psr\\Log\\": "Psr/Log/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1603,44 +2099,36 @@ ], "authors": [ { - "name": "Rich Sage", - "email": "rich.sage@gmail.com", - "homepage": "http://www.richsage.co.uk/" + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" } ], - "description": "Push notifications/messages for mobile devices", - "homepage": "https://github.com/richsage/RMSPushNotificationsBundle", + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", "keywords": [ - "apns", - "blackberry", - "bundle", - "c2dm", - "gcm", - "ios", - "mpns", - "notification", - "push", - "windowsphone" - ], - "time": "2016-04-01 10:10:29" + "log", + "psr", + "psr-3" + ], + "time": "2016-10-10 12:19:37" }, { "name": "sensio/distribution-bundle", - "version": "v5.0.12", + "version": "v5.0.13", "source": { "type": "git", "url": "https://github.com/sensiolabs/SensioDistributionBundle.git", - "reference": "b6dcd04595e4db95ead22ddea58c397864e00c32" + "reference": "7bc47dcfdbde6d567e1a834577d1c04ddb970281" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sensiolabs/SensioDistributionBundle/zipball/b6dcd04595e4db95ead22ddea58c397864e00c32", - "reference": "b6dcd04595e4db95ead22ddea58c397864e00c32", + "url": "https://api.github.com/repos/sensiolabs/SensioDistributionBundle/zipball/7bc47dcfdbde6d567e1a834577d1c04ddb970281", + "reference": "7bc47dcfdbde6d567e1a834577d1c04ddb970281", "shasum": "" }, "require": { "php": ">=5.3.9", - "sensiolabs/security-checker": "~3.0", + "sensiolabs/security-checker": "~3.0|~4.0", "symfony/class-loader": "~2.3|~3.0", "symfony/config": "~2.3|~3.0", "symfony/dependency-injection": "~2.3|~3.0", @@ -1674,7 +2162,7 @@ "configuration", "distribution" ], - "time": "2016-09-14 20:25:12" + "time": "2016-10-08 18:50:33" }, { "name": "sensio/framework-extra-bundle", @@ -1740,20 +2228,20 @@ }, { "name": "sensiolabs/security-checker", - "version": "v3.0.2", + "version": "v4.0.0", "source": { "type": "git", "url": "https://github.com/sensiolabs/security-checker.git", - "reference": "21696b0daa731064c23cfb694c60a2584a7b6e93" + "reference": "116027b57b568ed61b7b1c80eeb4f6ee9e8c599c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sensiolabs/security-checker/zipball/21696b0daa731064c23cfb694c60a2584a7b6e93", - "reference": "21696b0daa731064c23cfb694c60a2584a7b6e93", + "url": "https://api.github.com/repos/sensiolabs/security-checker/zipball/116027b57b568ed61b7b1c80eeb4f6ee9e8c599c", + "reference": "116027b57b568ed61b7b1c80eeb4f6ee9e8c599c", "shasum": "" }, "require": { - "symfony/console": "~2.0|~3.0" + "symfony/console": "~2.7|~3.0" }, "bin": [ "security-checker" @@ -1761,7 +2249,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1780,7 +2268,7 @@ } ], "description": "A security checker for your composer.lock", - "time": "2015-11-07 08:07:40" + "time": "2016-09-23 18:09:57" }, { "name": "swiftmailer/swiftmailer", @@ -2291,16 +2779,16 @@ }, { "name": "symfony/symfony", - "version": "v3.1.4", + "version": "v3.1.5", "source": { "type": "git", "url": "https://github.com/symfony/symfony.git", - "reference": "65ca9e4fbdb34f6d463ef77898ca583b101a4162" + "reference": "e7e1d01fe103de78bca6fbf7f6f4acf64482d63c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/symfony/zipball/65ca9e4fbdb34f6d463ef77898ca583b101a4162", - "reference": "65ca9e4fbdb34f6d463ef77898ca583b101a4162", + "url": "https://api.github.com/repos/symfony/symfony/zipball/e7e1d01fe103de78bca6fbf7f6f4acf64482d63c", + "reference": "e7e1d01fe103de78bca6fbf7f6f4acf64482d63c", "shasum": "" }, "require": { @@ -2313,7 +2801,7 @@ "symfony/polyfill-php56": "~1.0", "symfony/polyfill-php70": "~1.0", "symfony/polyfill-util": "~1.0", - "twig/twig": "~1.23|~2.0" + "twig/twig": "~1.26|~2.0" }, "conflict": { "phpdocumentor/reflection-docblock": "<3.0", @@ -2382,6 +2870,7 @@ "ocramius/proxy-manager": "~0.4|~1.0|~2.0", "phpdocumentor/reflection-docblock": "^3.0", "predis/predis": "~1.0", + "symfony/phpunit-bridge": "~3.2", "symfony/polyfill-apcu": "~1.1", "symfony/security-acl": "~2.8|~3.0" }, @@ -2427,20 +2916,20 @@ "keywords": [ "framework" ], - "time": "2016-09-03 15:28:43" + "time": "2016-10-03 19:01:14" }, { "name": "twig/twig", - "version": "v1.25.0", + "version": "v1.26.1", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "f16a634ab08d87e520da5671ec52153d627f10f6" + "reference": "a09d8ee17ac1cfea29ed60c83960ad685c6a898d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/f16a634ab08d87e520da5671ec52153d627f10f6", - "reference": "f16a634ab08d87e520da5671ec52153d627f10f6", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/a09d8ee17ac1cfea29ed60c83960ad685c6a898d", + "reference": "a09d8ee17ac1cfea29ed60c83960ad685c6a898d", "shasum": "" }, "require": { @@ -2453,7 +2942,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.25-dev" + "dev-master": "1.26-dev" } }, "autoload": { @@ -2488,7 +2977,7 @@ "keywords": [ "templating" ], - "time": "2016-09-21 23:05:12" + "time": "2016-10-05 18:57:41" }, { "name": "willdurand/jsonp-callback-validator", @@ -2532,16 +3021,16 @@ }, { "name": "willdurand/negotiation", - "version": "v2.1.0", + "version": "v2.2.1", "source": { "type": "git", "url": "https://github.com/willdurand/Negotiation.git", - "reference": "bc814293b153f543c99c89d94c8cc07b3259eef9" + "reference": "1f210db45723b21edd69f39794662b8d64656b93" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/willdurand/Negotiation/zipball/bc814293b153f543c99c89d94c8cc07b3259eef9", - "reference": "bc814293b153f543c99c89d94c8cc07b3259eef9", + "url": "https://api.github.com/repos/willdurand/Negotiation/zipball/1f210db45723b21edd69f39794662b8d64656b93", + "reference": "1f210db45723b21edd69f39794662b8d64656b93", "shasum": "" }, "require": { @@ -2553,7 +3042,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } }, "autoload": { @@ -2580,22 +3069,22 @@ "header", "negotiation" ], - "time": "2016-09-21 11:26:55" + "time": "2016-10-14 09:17:47" } ], "packages-dev": [ { "name": "sensio/generator-bundle", - "version": "v3.0.8", + "version": "v3.0.11", "source": { "type": "git", "url": "https://github.com/sensiolabs/SensioGeneratorBundle.git", - "reference": "3c20d16512f37d2be159eca0411b99a141b90fa4" + "reference": "b9be7f1b3b2e8bcfc1debefc901b71da923a5e5c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sensiolabs/SensioGeneratorBundle/zipball/3c20d16512f37d2be159eca0411b99a141b90fa4", - "reference": "3c20d16512f37d2be159eca0411b99a141b90fa4", + "url": "https://api.github.com/repos/sensiolabs/SensioGeneratorBundle/zipball/b9be7f1b3b2e8bcfc1debefc901b71da923a5e5c", + "reference": "b9be7f1b3b2e8bcfc1debefc901b71da923a5e5c", "shasum": "" }, "require": { @@ -2634,11 +3123,11 @@ } ], "description": "This bundle generates code for you", - "time": "2016-09-06 01:30:19" + "time": "2016-10-10 14:17:42" }, { "name": "symfony/phpunit-bridge", - "version": "v3.1.4", + "version": "v3.1.5", "source": { "type": "git", "url": "https://github.com/symfony/phpunit-bridge.git", @@ -2695,15 +3184,15 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { - "richsage/rms-push-notifications-bundle": 20 + "kreait/firebase-php": 10 }, "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=5.5.9" + "php": "^7.0" }, "platform-dev": [], "platform-overrides": { - "php": "5.5.9" + "php": "7.0" } } diff --git a/google-service-account.json b/google-service-account.json new file mode 100644 index 0000000..a5e781e --- /dev/null +++ b/google-service-account.json @@ -0,0 +1,12 @@ +{ + "type": "service_account", + "project_id": "betskills-145919", + "private_key_id": "d6194a42716587ceda21dca5422cdc56f1b964c2", + "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC7hvx8lBvZvcF+\nPd+y9WZuvIK6a97PaRoXz4lgxGLccLsXvxfGYNrKczMkSzJP7K3jjrGw4FdDlmVN\nKN+3ZUW4hLvjhGxdsX3czRhCeMk+ZWTpf98NkgdRMvy7RZa8SB4CkcdUjxF/oCJD\nKR09S+ua7ESIMh6ObtInhO0NAdNZZXSOXo/6QvH06PW2sR6SILc2yCmGWz5M0/3n\nzstpxxqfh6ZmbTsJi/ncwR+0nce0nh39O27AWPkmV1OYxlzNNZpE4/8N/2lIOGwB\nmQdi1daxz7ASm3VOxNbF4BhUlgUS7IJVVLt/oRW2eBfJkMJF/D4VLwZd5ZJfBuB9\nosQtEYnRAgMBAAECggEAXIXyZ0jwINN192Jxz6syeep6mZ4FVdJmdF8KSfs7R8Y7\nGTFIerFo4cBK+Fo9nZ+KAB90Xm+hvpAitRo4nxTRfIPI7C13Bhc/oURz9r//ktCW\nJHrZw6lMAO0mMwPXplfyrpPchET+fji1DuvnKEogGdT+zy/jUaUt/R+hkexXqeAC\nLjdKVdKs8lc+hrGIkysm4VYGZ7BpdBphh67vZifb3yJZwQ1PbJA7Sf9RmNTNh561\nKzgOqQAZOrtXMEVbzOsO3lUAHywPvczBdIMcK3ADQMu7ZCQ1+1KUXDV7CK6RFwsm\nGAk7E/qjgV/3NAN7LlxlKrJ0Lwx5rBsBZux+D9HkAQKBgQD1mrvmlgZ125DtX14O\ncyVKLx1+bfmuWPx2NrDNLFBh30bw/6t7R6OzWBcu20w59XKGWcnmsE+zghGUWGsB\nyVxUM4jVAzCk9pDrFBJBp9g0v4K1L8wIT9E/JF/I0DjyYtlIfds8ZYzqRu6ghmYM\nB+FQ4ThFnpq8ZEy93NxSEZ3QEQKBgQDDdvPxPxTGOhJc7ZdEThtjDO6rptXS9Xto\nzHui2iIwvi09xUNRG9s+u998zHEyEC0lUNu1e5GEEcsYgQ8jCfAn5oaJ3JoYUBEj\nw9aeeRha9o9rQzZU3D0Ku0nc2B813+J6qmRXTwvqjADR261BdVyyo6tkDLVnCECI\nQLGhuendwQKBgFrg6IpIFRfjKNtMoIcEQFYU3Pr9QpgqwTAUyJMCxLOSZLOkRxWU\nypQAEoP6DVic48Wmz7iWoMcxZ8PWe7Hrikh10TnQtl00ByeVA7RboPrTqk/U4dBp\niGmu0eqCca/ut6vFNixA/0Vo/b9UO8pT2CGPVL0eFO+ExYizgqqzbguhAoGAG9g+\nOAe8deCf7Q0Ll3do/1tARMOngj3mLq+yjSh15muxFjObu1o0iWNKGwUkuvUC+WXj\nZp8Lw7ylKgB4n40y4Pw9/jWm3f/J8UZctIabqZmmJKmWe9BEAdtcUlGXYJ1cLg1H\n7ggcsnTvSPX6YHDPm8MlD0OgM+VBDCfrJhbN8gECgYAO0v/lFKFdzf2wmD/OSS7I\no0FPpAFZAmVvZ8LU4qM2Oc/yRXnaEKB3WDjnHZu6wu8J7eZSvWBvGKei6DCVmrFx\nlv98EhtFnZrLUDmg8raS+yc9vTgqWPP5TxjwnE1rtlKBiUIlR78rXzyTKKfz5Xak\n2CJofRDcBx96QQw80e2mcA==\n-----END PRIVATE KEY-----\n", + "client_email": "betskills-firebase@betskills-145919.iam.gserviceaccount.com", + "client_id": "109430858857397166788", + "auth_uri": "https://accounts.google.com/o/oauth2/auth", + "token_uri": "https://accounts.google.com/o/oauth2/token", + "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", + "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/betskills-firebase%40betskills-145919.iam.gserviceaccount.com" +} diff --git a/src/ApiBundle/Controller/DefaultController.php b/src/ApiBundle/Controller/DefaultController.php index d40d2e6..74a0044 100644 --- a/src/ApiBundle/Controller/DefaultController.php +++ b/src/ApiBundle/Controller/DefaultController.php @@ -2,11 +2,190 @@ namespace ApiBundle\Controller; -use Symfony\Bundle\FrameworkBundle\Controller\Controller; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; +use BackendBundle\Entity\Device; +use FOS\RestBundle\View\View; +use FOS\RestBundle\Controller\Annotations\Get; +use FOS\RestBundle\Controller\Annotations\Post; use FOS\RestBundle\Controller\FOSRestController; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; class DefaultController extends FOSRestController { + /** + * @return Response + */ + public function getPredictionsAction() + { + $view = View::create() + ->setStatusCode(200) + ->setData($this->getPredictionRepository()->findAll()); + return $this->handleView($view); + + } + + /** + * @return Response + */ + public function getLeaguesAction() + { + $view = View::create() + ->setStatusCode(200) + ->setData($this->getLeagueRepository()->findAll()); + + return $this->handleView($view); + + } + + /** + * @return Response + */ + public function getPacksAction() + { + $view = View::create() + ->setStatusCode(200) + ->setData($this->getPackRepository()->findAll()); + + return $this->handleView($view); + + } + + /** + * @param int $id + * @return Response + * + * GET Route annotation. + * @Get("/predictions/league/{id}") + */ + public function getPredictionsByLeagueAction(int $id) + { + $league = $this->getLeagueRepository()->find($id); + + $view = View::create(); + + if ($league) { + $view->setStatusCode(200); + $view->setData($this->getPredictionRepository()->findBy([ + 'league' => $league + ])); + return $view; + } + + $view->setStatusCode(400); + return $view; + } + + /** + * @param $id + * @return Response + */ + public function getPredictionAction($id) + { + $prediction = $this->getPredictionRepository()->find($id); + + $view = View::create(); + + if ($prediction) { + $view->setStatusCode(200); + $view->setData($prediction); + return $view; + } + + $view->setStatusCode(400); + return $this->handleView($view); + } + + /** + * @param Request $request + * @return Response + * + * @Post("/devices/register") + */ + public function registerDeviceAction(Request $request) + { + + $view = View::create(); + + if ($request->getMethod() === 'POST') { + $content = (array)\GuzzleHttp\json_decode($request->getContent()); + $deviceRepository = $this->getDeviceRepository(); + if ($device = $deviceRepository->findOneBy(['uuid' => $content['uuid']])) { + $deviceRepository->updateInfo($content,$device); + } else { + $deviceRepository->hydrate($content); + } + + return $this->handleView($view); + + } + + $view->setStatusCode(500); + return $this->handleView($view); + } + + /** + * @param string $uuid + * @return Response + * + * GET Route annotation. + * @Get("/notifications/{uuid}") + */ + public function getNotificationsAction(string $uuid) + { + $notifications = $this->getNotificationRepository()->get(10); + $device = $this->getDeviceRepository()->findOneBy(['uuid' => $uuid]); + if ($device) { + $status = $this->getNotificationOnDeviceRepository()->findNotificationsByDevice($notifications, $device); + $view = View::create() + ->setStatusCode(200) + ->setData([ + 'notifications' => $notifications, + 'status' => $status + ]); + } else { + $view = View::create() + ->setStatusCode(400); + } + + return $this->handleView($view); + } + + public function readAllNotificationsAction(string $uuid) + { + $device = $this->getDeviceRepository()->findOneBy(['uuid' => $uuid]); + if ($device) { + $this->getNotificationOnDeviceRepository()->readAllNotifications($device); + } + } + + private function getNotificationOnDeviceRepository() + { + return $this->getDoctrine()->getRepository('BackendBundle:NotificationOnDevice'); + } + + private function getDeviceRepository() + { + return $this->getDoctrine()->getRepository('BackendBundle:Device'); + } + + private function getNotificationRepository() + { + return $this->getDoctrine()->getRepository('BackendBundle:Notification'); + } + + private function getPredictionRepository() + { + return $this->getDoctrine()->getRepository('BackendBundle:Prediction'); + } + + private function getLeagueRepository() + { + return $this->getDoctrine()->getRepository('BackendBundle:League'); + } + + private function getPackRepository() + { + return $this->getDoctrine()->getRepository('BackendBundle:Pack'); + } } diff --git a/src/BackendBundle/Controller/EntityBrowserController.php b/src/BackendBundle/Controller/EntityBrowserController.php index b40cd7f..f0d98e1 100644 --- a/src/BackendBundle/Controller/EntityBrowserController.php +++ b/src/BackendBundle/Controller/EntityBrowserController.php @@ -20,7 +20,7 @@ class EntityBrowserController extends Controller * @param int $page * @return Response * - * @Route("/admin/{name}/list/{page}", requirements={"name" = "league|prediction|pack"}) + * @Route("/admin/{name}/list/{page}", requirements={"name" = "league|prediction|pack|team"}) */ public function listAction(string $name, Request $request, int $page) { @@ -63,7 +63,7 @@ class EntityBrowserController extends Controller * @param Request $request * @return Response * - * @Route("/admin/{name}/new", requirements={"name" = "league|prediction|pack"}) + * @Route("/admin/{name}/new", requirements={"name" = "league|prediction|pack|team"}) */ public function newAction(string $name, Request $request) { @@ -103,7 +103,7 @@ class EntityBrowserController extends Controller * @param Request $request * @return Response * - * @Route("/admin/{name}/edit/{id}", requirements={"name" = "league|prediction|pack", "id"}) + * @Route("/admin/{name}/edit/{id}", requirements={"name" = "league|prediction|pack|team", "id"}) */ public function editAction(string $name, int $id, Request $request) { @@ -140,7 +140,7 @@ class EntityBrowserController extends Controller * @param Request $request * @return JsonResponse * - * @Route("/admin/{name}/delete", requirements={"name" = "league|prediction|pack"}) + * @Route("/admin/{name}/delete", requirements={"name" = "league|prediction|pack|team"}) */ public function deleteAction(string $name, Request $request) { diff --git a/src/BackendBundle/Controller/NotificationController.php b/src/BackendBundle/Controller/NotificationController.php index 8f96ab6..f629dc4 100644 --- a/src/BackendBundle/Controller/NotificationController.php +++ b/src/BackendBundle/Controller/NotificationController.php @@ -8,13 +8,123 @@ namespace BackendBundle\Controller; +use BackendBundle\Entity\Notification; +use Doctrine\ORM\Tools\Pagination\Paginator; +use GuzzleHttp\Client; +use GuzzleHttp\Exception\BadResponseException; +use GuzzleHttp\Exception\ClientException; use Symfony\Bundle\FrameworkBundle\Controller\Controller; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; class NotificationController extends Controller { - public function indexAction() + const NOTIFICATION_API_URL = 'https://fcm.googleapis.com/fcm/send'; + const SERVER_KEY = "AIzaSyCFdGq-rjzznFOEzDifZGsRoeWT8LFAc9s"; + const SENDER_ID = "1006878207346"; + const DEFAULT_PAGE_RESULT = 20; + + + + /** + * @param Request $request + * @return Response + * + * @Route("/admin/notification/create") + */ + public function createAction(Request $request) { - return $this->render('@Backend/notification/index.html.twig'); + + $notification = new Notification(); + + $form = $this->createForm('BackendBundle\\Form\\NotificationType', $notification); + + if ($request->getMethod() === Request::METHOD_POST) { + $form->handleRequest($request); + + if ($form->isValid()) { + $message = [ + 'notification' => [ + 'title' => $notification->getTitle(), + 'body' => $notification->getContent() + ], + 'to' => 'cNgyx3ZgOX4:APA91bF5eigDuJLjj8wI8SC4l5KIHATuxi-2G5whpWI1n1jWpWWwRAwbEXec4fQ2S7HW8EdUPaREXJ5fVd_TZV8rZq_eIJIEhEadeH9wpsbYmUUM7E8H8Y0Qst9KmBuHWodCFFJPJ0vh' + ]; + + $client = new Client(); + $response = $client->request('POST', self::NOTIFICATION_API_URL, [ + 'body' => json_encode($message), + 'headers'=> [ + 'Authorization' => 'key='.self::SERVER_KEY, + 'Content-Type' => 'application/json', + ] + ]); + + $response = (array) \GuzzleHttp\json_decode($response->getBody()->getContents()); + + if (!$response['failure']) { + $notification->setDate(new \DateTime()); + $devices = $this->getDoctrine()->getRepository('BackendBundle:Device')->findAll(); + $em = $this->getDoctrine()->getEntityManager(); + $em->persist($notification); + $this->getDoctrine()->getRepository('BackendBundle:NotificationOnDevice')->updateStatusOnAllDevices($devices, $notification); + $this->addFlash('success', 'La notification a bien été envoyée'); + return $this->redirectToRoute('backend_notification_list', ['page' => 1]); + } + + $this->addFlash('danger', $response['results'][0]->error); + + } + + } + + return $this->render('@Backend/notification/create.html.twig',[ + 'form' => $form->createView() + ]); } + + /** + * @param Request $request + * @param int $page + * @return Response + * + * @Route("/admin/notification/list/{page}") + */ + public function listAction(Request $request, int $page) + { + $em = $this->getDoctrine()->getManager(); + + if (!isset($page)) { + $page = 1; + } + + $repository = $em->getRepository('BackendBundle:Notification'); + + $query = $repository->getAll(); + + $firstResult = $page === 1 ? 0 : self::DEFAULT_PAGE_RESULT * ($page-1) - 1; + + $pagination = new Paginator($query); + + $totalItems = count($pagination); + + $pagesCount = ceil($totalItems / self::DEFAULT_PAGE_RESULT) >= 1 ? ceil($totalItems / self::DEFAULT_PAGE_RESULT) : 1; + + $pagination->getQuery() + ->setMaxResults(self::DEFAULT_PAGE_RESULT) + ->setFirstResult($firstResult) + ; + + return $this->render( + 'BackendBundle:notification:list.html.twig', + [ + 'elements' => $pagination, + 'countPages' => $pagesCount, + 'page' => $page + ] + ); + } + } \ No newline at end of file diff --git a/src/BackendBundle/Entity/Device.php b/src/BackendBundle/Entity/Device.php new file mode 100644 index 0000000..d741a97 --- /dev/null +++ b/src/BackendBundle/Entity/Device.php @@ -0,0 +1,189 @@ +<?php + +namespace BackendBundle\Entity; + +use Doctrine\ORM\Mapping as ORM; + +/** + * Device + * + * @ORM\Table(name="device") + * @ORM\Entity(repositoryClass="BackendBundle\Repository\DeviceRepository") + */ +class Device +{ + /** + * @var int + * + * @ORM\Column(name="id", type="integer") + * @ORM\Id + * @ORM\GeneratedValue(strategy="AUTO") + */ + private $id; + + /** + * @var string + * + * @ORM\Column(name="uuid", type="string", length=255) + */ + private $uuid; + + /** + * @var string + * + * @ORM\Column(name="model", type="string", length=255) + */ + private $model; + + /** + * @var string + * + * @ORM\Column(name="version", type="string", length=255) + */ + private $version; + + /** + * @var string + * + * @ORM\Column(name="platform", type="string", length=255) + */ + private $platform; + + /** + * @var string + * + * @ORM\Column(name="token", type="string", length=255) + */ + private $token; + + + /** + * Get id + * + * @return int + */ + public function getId() + { + return $this->id; + } + + /** + * Set uuid + * + * @param string $uuid + * + * @return Device + */ + public function setUuid($uuid) + { + $this->uuid = $uuid; + + return $this; + } + + /** + * Get uuid + * + * @return string + */ + public function getUuid() + { + return $this->uuid; + } + + /** + * Set model + * + * @param string $model + * + * @return Device + */ + public function setModel($model) + { + $this->model = $model; + + return $this; + } + + /** + * Get model + * + * @return string + */ + public function getModel() + { + return $this->model; + } + + /** + * Set version + * + * @param string $version + * + * @return Device + */ + public function setVersion($version) + { + $this->version = $version; + + return $this; + } + + /** + * Get version + * + * @return string + */ + public function getVersion() + { + return $this->version; + } + + /** + * Set platform + * + * @param string $platform + * + * @return Device + */ + public function setPlatform($platform) + { + $this->platform = $platform; + + return $this; + } + + /** + * Get platform + * + * @return string + */ + public function getPlatform() + { + return $this->platform; + } + + /** + * Set token + * + * @param string $token + * + * @return Device + */ + public function setToken($token) + { + $this->token = $token; + + return $this; + } + + /** + * Get token + * + * @return string + */ + public function getToken() + { + return $this->token; + } +} diff --git a/src/BackendBundle/Entity/Notification.php b/src/BackendBundle/Entity/Notification.php new file mode 100644 index 0000000..ca52bf4 --- /dev/null +++ b/src/BackendBundle/Entity/Notification.php @@ -0,0 +1,148 @@ +<?php + +namespace BackendBundle\Entity; + +use Doctrine\ORM\Mapping as ORM; + +/** + * Notification + * + * @ORM\Table(name="notification") + * @ORM\Entity(repositoryClass="BackendBundle\Repository\NotificationRepository") + */ +class Notification +{ + /** + * @var int + * + * @ORM\Column(name="id", type="integer") + * @ORM\Id + * @ORM\GeneratedValue(strategy="AUTO") + */ + private $id; + + /** + * @var string + * + * @ORM\Column(name="title", type="string", length=255) + */ + private $title; + + /** + * @var string + * + * @ORM\Column(name="content", type="text") + */ + private $content; + + /** + * @var \DateTime + * + * @ORM\Column(name="date", type="datetime") + */ + private $date; + + /** + * @var string + */ + private $deviceStatus; + + + /** + * Get id + * + * @return int + */ + public function getId() + { + return $this->id; + } + + /** + * Set title + * + * @param string $title + * + * @return Notification + */ + public function setTitle($title) + { + $this->title = $title; + + return $this; + } + + /** + * Get title + * + * @return string + */ + public function getTitle() + { + return $this->title; + } + + /** + * Set content + * + * @param string $content + * + * @return Notification + */ + public function setContent($content) + { + $this->content = $content; + + return $this; + } + + /** + * Get content + * + * @return string + */ + public function getContent() + { + return $this->content; + } + + /** + * Set date + * + * @param \DateTime $date + * + * @return Notification + */ + public function setDate($date) + { + $this->date = $date; + + return $this; + } + + /** + * Get date + * + * @return \DateTime + */ + public function getDate() + { + return $this->date; + } + + /** + * @return string + */ + public function getDeviceStatus() + { + return $this->deviceStatus; + } + + /** + * @param string $deviceStatus + */ + public function setDeviceStatus($deviceStatus) + { + $this->deviceStatus = $deviceStatus; + } +} diff --git a/src/BackendBundle/Entity/NotificationOnDevice.php b/src/BackendBundle/Entity/NotificationOnDevice.php new file mode 100644 index 0000000..6331eb4 --- /dev/null +++ b/src/BackendBundle/Entity/NotificationOnDevice.php @@ -0,0 +1,119 @@ +<?php +/** + * Created by PhpStorm. + * User: jeremyguiselin + * Date: 01/11/2016 + * Time: 17:16 + */ + +namespace BackendBundle\Entity; + +use Doctrine\ORM\Mapping as ORM; + +/** + * NotificationOnDevice + * + * @ORM\Entity(repositoryClass="BackendBundle\Repository\NotificationOnDeviceRepository") + */ +class NotificationOnDevice +{ + + const STATUS_NEW = 'new'; + const STATUS_READ = 'read'; + + /** + * @var int + * + * @ORM\Column(name="id", type="integer") + * @ORM\Id + * @ORM\GeneratedValue(strategy="AUTO") + */ + private $id; + + /** + * @var Device + * + * @ORM\ManyToOne(targetEntity="BackendBundle\Entity\Device") + * @ORM\JoinColumn(nullable=false, onDelete="CASCADE", name="device", referencedColumnName="id") + */ + private $device; + + /** + * @var Notification + * + * @ORM\ManyToOne(targetEntity="BackendBundle\Entity\Notification") + * @ORM\JoinColumn(nullable=false, onDelete="CASCADE", name="notification", referencedColumnName="id") + */ + private $notification; + + /** + * @var string + * @ORM\Column(type="string") + */ + private $status = self::STATUS_NEW; + + /** + * @return int + */ + public function getId() + { + return $this->id; + } + + /** + * @param int $id + */ + public function setId($id) + { + $this->id = $id; + } + + /** + * @return Device + */ + public function getDevice() + { + return $this->device; + } + + /** + * @param Device $device + */ + public function setDevice($device) + { + $this->device = $device; + } + + /** + * @return Notification + */ + public function getNotification() + { + return $this->notification; + } + + /** + * @param Notification $notification + */ + public function setNotification($notification) + { + $this->notification = $notification; + } + + /** + * @return string + */ + public function getStatus() + { + return $this->status; + } + + /** + * @param string $status + */ + public function setStatus($status) + { + $this->status = $status; + } + +} \ No newline at end of file diff --git a/src/BackendBundle/Entity/Prediction.php b/src/BackendBundle/Entity/Prediction.php index 5104138..95e4922 100644 --- a/src/BackendBundle/Entity/Prediction.php +++ b/src/BackendBundle/Entity/Prediction.php @@ -22,16 +22,18 @@ class Prediction private $id; /** - * @var string + * @var Team * - * @ORM\Column(name="firstTeam", type="string", length=255) + * @ORM\ManyToOne(targetEntity="BackendBundle\Entity\Team") + * @ORM\JoinColumn(nullable=false, onDelete="CASCADE") */ private $firstTeam; /** - * @var string + * @var Team * - * @ORM\Column(name="secondTeam", type="string", length=255) + * @ORM\ManyToOne(targetEntity="BackendBundle\Entity\Team") + * @ORM\JoinColumn(nullable=false, onDelete="CASCADE") */ private $secondTeam; @@ -91,7 +93,7 @@ class Prediction /** * Set firstTeam * - * @param string $firstTeam + * @param Team $firstTeam * * @return Prediction */ @@ -105,7 +107,7 @@ class Prediction /** * Get firstTeam * - * @return string + * @return Team */ public function getFirstTeam() { @@ -115,7 +117,7 @@ class Prediction /** * Set secondTeam * - * @param string $secondTeam + * @param Team $secondTeam * * @return Prediction */ @@ -129,7 +131,7 @@ class Prediction /** * Get secondTeam * - * @return string + * @return Team */ public function getSecondTeam() { diff --git a/src/BackendBundle/Entity/Team.php b/src/BackendBundle/Entity/Team.php new file mode 100644 index 0000000..20fc4fa --- /dev/null +++ b/src/BackendBundle/Entity/Team.php @@ -0,0 +1,68 @@ +<?php +/** + * Created by PhpStorm. + * User: jeremyguiselin + * Date: 05/12/2016 + * Time: 12:41 + */ + +namespace BackendBundle\Entity; + +use Doctrine\ORM\Mapping as ORM; + +/** + * Team + * + * @ORM\Table(name="team") + * @ORM\Entity(repositoryClass="BackendBundle\Repository\TeamRepository") + */ +class Team +{ + /** + * @var int + * + * @ORM\Column(name="id", type="integer") + * @ORM\Id + * @ORM\GeneratedValue(strategy="AUTO") + */ + private $id; + + /** + * @var string + * + * @ORM\Column(name="name", type="string", length=255) + */ + private $name; + + /** + * @return int + */ + public function getId() + { + return $this->id; + } + + /** + * @param int $id + */ + public function setId($id) + { + $this->id = $id; + } + + /** + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * @param string $name + */ + public function setName($name) + { + $this->name = $name; + } +} \ No newline at end of file diff --git a/src/BackendBundle/Form/NotificationType.php b/src/BackendBundle/Form/NotificationType.php new file mode 100644 index 0000000..b75cf0e --- /dev/null +++ b/src/BackendBundle/Form/NotificationType.php @@ -0,0 +1,36 @@ +<?php + +namespace BackendBundle\Form; + +use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\TextareaType; +use Symfony\Component\Form\Extension\Core\Type\TextType; +use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\OptionsResolver\OptionsResolver; + +class NotificationType extends AbstractType +{ + public function buildForm(FormBuilderInterface $builder, array $options) + { + $builder + ->add('title', TextType::class, [ + 'label' => 'Titre', + ]) + ->add('content', TextareaType::class, [ + 'label' => 'Contenu', + ]); + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults([ + 'data_class' => 'BackendBundle\Entity\Notification', + 'csrf_protection' => false, + ]); + } + + public function getName() + { + return 'backend_bundle_notification_type'; + } +} diff --git a/src/BackendBundle/Form/PredictionType.php b/src/BackendBundle/Form/PredictionType.php index b3c7626..3f89aff 100644 --- a/src/BackendBundle/Form/PredictionType.php +++ b/src/BackendBundle/Form/PredictionType.php @@ -2,11 +2,10 @@ namespace BackendBundle\Form; -use BackendBundle\Form\Type\FloatType; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\DateTimeType; -use Symfony\Component\Form\Extension\Core\Type\TextType; +use Symfony\Component\Form\Extension\Core\Type\IntegerType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; @@ -15,11 +14,15 @@ class PredictionType extends AbstractType public function buildForm(FormBuilderInterface $builder, array $options) { $builder - ->add('firstTeam', TextType::class, [ - 'label' => 'Équipe 1', + ->add('firstTeam', EntityType::class, [ + 'label' => 'Équipe 1', + 'class' => 'BackendBundle\Entity\Team', + 'choice_label' => 'name' ]) - ->add('secondTeam', TextType::class, [ + ->add('secondTeam', EntityType::class, [ 'label' => 'Équipe 2', + 'class' => 'BackendBundle\Entity\Team', + 'choice_label' => 'name' ]) ->add('league', EntityType::class, [ 'label' => 'Ligue', @@ -32,29 +35,29 @@ class PredictionType extends AbstractType 'html5' => false, 'widget' => 'single_text', ]) - ->add('predictionWinFirst', FloatType::class, [ + ->add('predictionWinFirst', IntegerType::class, [ 'label' => 'Côte victoire de l\'équipe 1', 'attr' => [ - 'step' => '0.01', + 'step' => '1', 'min' => '0', - 'scale' => "3" + 'max' => "100" ] ]) - ->add('predictionWinSecond', FloatType::class, [ + ->add('predictionWinSecond', IntegerType::class, [ 'label' => 'Côte victoire de l\'équipe 2', 'attr' => [ - 'step' => '0.01', + 'step' => '1', 'min' => '0', - 'scale' => "3" + 'max' => "100" ] ]) - ->add('predictionDraw', FloatType::class, [ + ->add('predictionDraw', IntegerType::class, [ 'label' => 'Côte match nul', 'required' => false, 'attr' => [ - 'step' => '0.01', + 'step' => '1', 'min' => '0', - 'scale' => "3" + 'max' => "100" ] ]); } diff --git a/src/BackendBundle/Form/TeamType.php b/src/BackendBundle/Form/TeamType.php new file mode 100644 index 0000000..7310067 --- /dev/null +++ b/src/BackendBundle/Form/TeamType.php @@ -0,0 +1,32 @@ +<?php + +namespace BackendBundle\Form; + +use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\TextType; +use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\OptionsResolver\OptionsResolver; + +class TeamType extends AbstractType +{ + public function buildForm(FormBuilderInterface $builder, array $options) + { + $builder + ->add('name', TextType::class, [ + 'label' => 'Nom', + ]); + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults([ + 'data_class' => 'BackendBundle\Entity\Team', + 'csrf_protection' => false, + ]); + } + + public function getName() + { + return 'backend_bundle_team_type'; + } +} diff --git a/src/BackendBundle/Repository/DeviceRepository.php b/src/BackendBundle/Repository/DeviceRepository.php new file mode 100644 index 0000000..3a907de --- /dev/null +++ b/src/BackendBundle/Repository/DeviceRepository.php @@ -0,0 +1,49 @@ +<?php + +namespace BackendBundle\Repository; +use BackendBundle\Entity\Device; +use Doctrine\ORM\EntityRepository; + +/** + * DeviceRepository + * + * This class was generated by the Doctrine ORM. Add your own custom + * repository methods below. + */ +class DeviceRepository extends EntityRepository +{ + /** + * @param array $data + */ + public function hydrate(array $data) + { + $device = new Device(); + $device->setUuid($data['uuid']); + $this->updateChangingInfo($data, $device); + $this->_em->persist($device); + $this->_em->flush(); + } + + /** + * @param array $data + * @param Device $device + */ + public function updateInfo(array $data, Device $device) + { + $this->updateChangingInfo($data, $device); + $this->_em->flush(); + } + + /** + * @param array $data + * @param Device $device + */ + private function updateChangingInfo(array $data, Device $device) + { + $device + ->setModel($data['model']) + ->setPlatform($data['platform']) + ->setToken($data['token']) + ->setVersion($data['version']); + } +} diff --git a/src/BackendBundle/Repository/NotificationOnDeviceRepository.php b/src/BackendBundle/Repository/NotificationOnDeviceRepository.php new file mode 100644 index 0000000..742d09d --- /dev/null +++ b/src/BackendBundle/Repository/NotificationOnDeviceRepository.php @@ -0,0 +1,53 @@ +<?php +/** + * Created by PhpStorm. + * User: jeremyguiselin + * Date: 01/11/2016 + * Time: 17:31 + */ + +namespace BackendBundle\Repository; + + +use BackendBundle\Entity\Device; +use BackendBundle\Entity\Notification; +use BackendBundle\Entity\NotificationOnDevice; +use Doctrine\ORM\EntityRepository; + +class NotificationOnDeviceRepository extends EntityRepository +{ + public function findNotificationsByDevice(array $notifications, Device $device) + { + return $this->createQueryBuilder('s') + ->where('s.notification IN (:notifications)') + ->andWhere('s.device = :device') + ->setParameters([ + 'device' => $device, + 'notifications' => $notifications + ]) + ->getQuery() + ->getResult(); + } + + public function updateStatusOnAllDevices(array $devices, Notification $notification) + { + foreach ($devices as $device) { + $notifOnDevice = new NotificationOnDevice(); + $notifOnDevice->setDevice($device); + $notifOnDevice->setNotification($notification); + $this->getEntityManager()->persist($notifOnDevice); + } + + $this->getEntityManager()->flush(); + } + + public function readAllNotifications(Device $device) + { + $qb = $this->createQueryBuilder('n'); + $qb + ->update('n') + ->set('n.status', NotificationOnDevice::STATUS_READ) + ->where('n.device = :device') + ->setParameter('device', $device); + } +} \ No newline at end of file diff --git a/src/BackendBundle/Repository/NotificationRepository.php b/src/BackendBundle/Repository/NotificationRepository.php new file mode 100644 index 0000000..1aca913 --- /dev/null +++ b/src/BackendBundle/Repository/NotificationRepository.php @@ -0,0 +1,35 @@ +<?php + +namespace BackendBundle\Repository; +use Doctrine\ORM\EntityRepository; + +/** + * NotificationRepository + * + * This class was generated by the Doctrine ORM. Add your own custom + * repository methods below. + */ +class NotificationRepository extends EntityRepository +{ + /** + * @param int $limit + * @return array + */ + public function get(int $limit) + { + return $this->createQueryBuilder('n') + ->setMaxResults($limit) + ->getQuery() + ->getResult(); + } + + /** + * Prevent lazy loading + * @return array + */ + public function getAll() + { + return $this->createQueryBuilder('n') + ->select('n'); + } +} diff --git a/src/BackendBundle/Repository/TeamRepository.php b/src/BackendBundle/Repository/TeamRepository.php new file mode 100644 index 0000000..574c0ff --- /dev/null +++ b/src/BackendBundle/Repository/TeamRepository.php @@ -0,0 +1,38 @@ +<?php +/** + * Created by PhpStorm. + * User: jeremyguiselin + * Date: 05/12/2016 + * Time: 13:01 + */ + +namespace BackendBundle\Repository; + +use BackendBundle\Entity\Team; +use Doctrine\ORM\EntityRepository; + +/** + * TeamRepository + * + * This class was generated by the Doctrine ORM. Add your own custom + * repository methods below. + */ + +class TeamRepository extends EntityRepository +{ + public function getAll() + { + $qb = $this->createQueryBuilder('t'); + $qb->select('t'); + + return $qb; + + } + + public function alreadyExists(Team $pack) : bool + { + return $this->findOneBy([ + 'name' => $pack->getName() + ]) !== null; + } +} \ No newline at end of file diff --git a/src/BackendBundle/Resources/views/layout/dashboard.html.twig b/src/BackendBundle/Resources/views/layout/dashboard.html.twig index 0946f04..394abc9 100644 --- a/src/BackendBundle/Resources/views/layout/dashboard.html.twig +++ b/src/BackendBundle/Resources/views/layout/dashboard.html.twig @@ -10,14 +10,15 @@ <span class="icon-bar"></span> <span class="icon-bar"></span> </button> - <a class="navbar-brand" href="">Betskills</a> + <a class="navbar-brand" href="#">Betskills</a> </div> <div class="navbar-collapse collapse navbar-inverse-collapse"> <ul class="nav navbar-nav"> <li><a href="{{ path('backend_entitybrowser_list', {'name': 'league', 'page': 1}) }}">Gestion des ligues</a></li> <li><a href="{{ path('backend_entitybrowser_list', {'name': 'prediction', 'page': 1}) }}">Gestion des prédictions</a></li> <li><a href="{{ path('backend_entitybrowser_list', {'name': 'pack', 'page': 1}) }}">Gestion des packs</a></li> - <li><a href="">Notifications</a></li> + <li><a href="{{ path('backend_entitybrowser_list', {'name': 'team', 'page': 1}) }}">Gestion des équipes</a></li> + <li><a href="{{ path('backend_notification_list', {'page': 1}) }}">Notifications</a></li> </ul> </div> </div> diff --git a/src/BackendBundle/Resources/views/notification/create.html.twig b/src/BackendBundle/Resources/views/notification/create.html.twig new file mode 100644 index 0000000..2fa1b16 --- /dev/null +++ b/src/BackendBundle/Resources/views/notification/create.html.twig @@ -0,0 +1,23 @@ +{% extends '@Backend/layout/dashboard.html.twig' %} + +{% block title %}Envoyer une notification{% endblock %} + +{% block subcontent %} + <div class="row"> + <div class="col-sm-8 col-sm-offset-2"> + <h3 class="text-center text-primary">Créer une nouvelle notification</h3> + {{ form_start(form, {'attr': {'class': 'form-horizontal'}}) }} + {% for child in form.children %} + <div class="form-group is-empty has-primary"> + {{ form_label(child, null, {'label_attr': {'class': "col-sm-2 control-label"}}) }} + <div class="col-sm-10"> + {{ form_widget(child, {'attr' : {'class': "form-control"}}) }} + </div> + {{ form_errors(child) }} + </div> + {% endfor %} + <button type="submit" class="modal-action modal-close waves-effect waves-green waves-light btn">Envoyer</button> + {{ form_end(form, {'render_rest': false}) }} + </div> + </div> +{% endblock %} \ No newline at end of file diff --git a/src/BackendBundle/Resources/views/notification/index.html.twig b/src/BackendBundle/Resources/views/notification/index.html.twig deleted file mode 100644 index e69de29..0000000 diff --git a/src/BackendBundle/Resources/views/notification/list.html.twig b/src/BackendBundle/Resources/views/notification/list.html.twig new file mode 100644 index 0000000..8f7520c --- /dev/null +++ b/src/BackendBundle/Resources/views/notification/list.html.twig @@ -0,0 +1,47 @@ +{% extends '@Backend/layout/dashboard.html.twig' %} + +{% block title %}Liste des notifications{% endblock %} + +{% block subcontent %} + <div class="row"> + <div class="col-sm-8 col-sm-offset-2"> + <div> + <div class="left"></div> + <div class="right"> + <a class="btn btn-lg btn-raised btn-success" href="{{ path('backend_notification_create') }}">Ajouter une notification</a> + </div> + </div> + <table class="table table-striped" cellspacing="0" width="50%"> + <thead> + <tr> + <th>#</th> + <th>Titre</th> + <th>Contenu</th> + <th>Date</th> + </tr> + </thead> + <tbody> + {% for element in elements %} + <tr id="{{ element.id }}"> + <td>{{ element.id }}</td> + <td>{{ element.title }}</td> + <td>{{ element.content }}</td> + <td>{{ element.date | date('d-m-Y H:i') }}</td> + </tr> + {% endfor %} + </tbody> + </table> + + <nav class="flex-display-right"> + <ul class="pagination"> + <li class="page-item waves-effect {% if page == 1 %}disabled{% endif %}"><a class="page-link page-link waves-effect waves-effect" href="{% if page > 1 %}{{ path('backend_notification_list', {'page': page - 1}) }}{% else %}#{% endif %}"><i class="material-icons">chevron_left</i></a></li> + {% for i in range(1, countPages) %} + <li class="page-item {% if i == page %}active{% endif %}"><a class="page-link page-link waves-effect waves-effect" href="{{ path('backend_notification_list', {'page': i}) }}">{{ i }}</a></li> + {% endfor %} + <li class="page-item waves-effect {% if page == countPages %}disabled{% endif %}"><a class="page-link page-link waves-effect waves-effect" href="{% if page < countPages %}{{ path('backend_notification_list', {'page': page + 1}) }}{% else %}#{% endif %}"><i class="material-icons">chevron_right</i></a></li> + </ul> + </nav> + + </div> + </div> +{% endblock %} \ No newline at end of file diff --git a/src/BackendBundle/Resources/views/prediction/form.html.twig b/src/BackendBundle/Resources/views/prediction/form.html.twig index 6adf4fc..7190784 100644 --- a/src/BackendBundle/Resources/views/prediction/form.html.twig +++ b/src/BackendBundle/Resources/views/prediction/form.html.twig @@ -4,69 +4,71 @@ <link rel="stylesheet" href="{{ asset('css/boostrap-material-datetimepicker.css') }}"> <script src="{{ asset('js/moment.js') }}"></script> <script src="{{ asset('js/bootstrap-material-datetimepicker.js') }}"></script> + <link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css" rel="stylesheet" /> + <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js"></script> {% endblock %} {% block title %}Gestion de {{ name }}{% endblock %} {% block subcontent %} <div class="row"> - <div class="col-sm-8 col-sm-offset-2"> + <div class="col-sm-8 col-sm-offset-2 col-xs-12"> <h3 class="text-center text-primary">Ajouter une nouvelle ou éditer une {{ name | trans }}</h3> {{ form_start(form, {'attr': {'class': 'form-horizontal'}}) }} <div class="row"> - <div class="col-sm-6"> + <div class="col-xs-12"> <div class="form-group is-empty has-primary"> - {{ form_label(form.firstTeam, null, {'label_attr': {'class': "col-sm-3 control-label"}}) }} - <div class="col-sm-9"> - {{ form_widget(form.firstTeam, {'attr' : {'class': "form-control"}}) }} + {{ form_label(form.firstTeam, null, {'label_attr': {'class': "col-md-3 col-xs-12 control-label"}}) }} + <div class="col-md-9 col-xs-12"> + {{ form_widget(form.firstTeam, {'attr' : {'class': "form-control js-example-basic-single"}}) }} {{ form_errors(form.firstTeam) }} </div> </div> </div> - <div class="col-sm-6"> + <div class="col-xs-12"> <div class="form-group is-empty has-primary"> - {{ form_label(form.secondTeam, null, {'label_attr': {'class': "col-sm-3 control-label"}}) }} - <div class="col-sm-9"> - {{ form_widget(form.secondTeam, {'attr' : {'class': "form-control"}}) }} + {{ form_label(form.secondTeam, null, {'label_attr': {'class': "col-md-3 col-xs-12 control-label"}}) }} + <div class="col-md-9 col-xs-12"> + {{ form_widget(form.secondTeam, {'attr' : {'class': "form-control js-example-basic-single"}}) }} {{ form_errors(form.secondTeam) }} </div> </div> </div> </div> <div class="row"> - <div class="col-sm-6"> + <div class="col-xs-12"> <div class="form-group is-empty"> - {{ form_label(form.date, null, {'label_attr': {'class': "col-sm-3 control-label"}}) }} - <div class="col-sm-9"> + {{ form_label(form.date, null, {'label_attr': {'class': "col-md-3 col-xs-12 control-label"}}) }} + <div class="col-md-9 col-xs-12"> {{ form_widget(form.date, {'attr' : {'class': "form-control"}}) }} {{ form_errors(form.date) }} </div> </div> </div> - <div class="col-sm-6"> + <div class="col-xs-12"> <div class="form-group is-empty"> - {{ form_label(form.league, null, {'label_attr': {'class': "col-sm-3 control-label"}}) }} - <div class="col-sm-9"> - {{ form_widget(form.league, {'attr' : {'class': "form-control"}}) }} + {{ form_label(form.league, null, {'label_attr': {'class': "col-md-3 col-xs-12 control-label"}}) }} + <div class="col-md-9 col-xs-12"> + {{ form_widget(form.league, {'attr' : {'class': "form-control js-example-basic-single"}}) }} {{ form_errors(form.league) }} </div> </div> </div> </div> <div class="row"> - <div class="col-sm-6"> + <div class="col-xs-12"> <div class="form-group is-empty"> - {{ form_label(form.predictionWinFirst, null, {'label_attr': {'class': "col-sm-3 control-label"}}) }} - <div class="col-sm-9"> + {{ form_label(form.predictionWinFirst, null, {'label_attr': {'class': "col-md-3 col-xs-12 control-label"}}) }} + <div class="col-md-9 col-xs-12"> {{ form_widget(form.predictionWinFirst, {'attr' : {'class': "form-control"}}) }} {{ form_errors(form.predictionWinFirst) }} </div> </div> </div> - <div class="col-sm-6"> + <div class="col-xs-12"> <div class="form-group is-empty"> - {{ form_label(form.predictionWinSecond, null, {'label_attr': {'class': "col-sm-3 control-label"}}) }} - <div class="col-sm-9"> + {{ form_label(form.predictionWinSecond, null, {'label_attr': {'class': "col-md-3 col-xs-12 control-label"}}) }} + <div class="col-md-9 col-xs-12"> {{ form_widget(form.predictionWinSecond, {'attr' : {'class': "form-control"}}) }} {{ form_errors(form.predictionWinSecond) }} </div> @@ -75,10 +77,10 @@ </div> <div class="row"> - <div class="col-sm-6"> + <div class="col-xs-12"> <div class="form-group is-empty"> - {{ form_label(form.predictionDraw, null, {'label_attr': {'class': "col-sm-3 control-label"}}) }} - <div class="col-sm-9"> + {{ form_label(form.predictionDraw, null, {'label_attr': {'class': "col-md-3 col-xs-12 control-label"}}) }} + <div class="col-md-9 col-xs-12"> {{ form_widget(form.predictionDraw, {'attr' : {'class': "form-control"}}) }} {{ form_errors(form.predictionDraw) }} </div> @@ -86,7 +88,9 @@ </div> </div> - <button type="submit" class="modal-action modal-close waves-effect waves-green waves-light btn">Ajouter</button> + <div class="col-xs-12 text-center"> + <button type="submit" class="btn btn-lg btn-raised btn-success">Valider</button> + </div> {{ form_end(form, {'render_rest': false}) }} </div> </div> @@ -96,8 +100,8 @@ <script> $('#prediction_date').bootstrapMaterialDatePicker({ clearButton: true, - format: 'YYYY-MM-DD HH:mm', - currentDate: moment('now') + format: 'YYYY-MM-DD HH:mm' }); + $('select').select2(); </script> {% endblock %} \ No newline at end of file diff --git a/src/BackendBundle/Resources/views/prediction/list.html.twig b/src/BackendBundle/Resources/views/prediction/list.html.twig index 7a13483..2c78ead 100644 --- a/src/BackendBundle/Resources/views/prediction/list.html.twig +++ b/src/BackendBundle/Resources/views/prediction/list.html.twig @@ -26,13 +26,13 @@ {% for element in elements %} <tr> <td>{{ element.id }}</td> - <td>{{ element.firstTeam }}</td> - <td>{{ element.secondTeam }}</td> + <td>{{ element.firstTeam.name }}</td> + <td>{{ element.secondTeam.name }}</td> <td>{{ element.date | date('d-m-Y H:i') }}</td> <td>{{ element.league.name }}</td> - <td>{{ element.predictionWinFirst }}</td> - <td>{{ element.predictionWinSecond }}</td> - <td>{{ element.predictionDraw }}</td> + <td>{{ element.predictionWinFirst }} %</td> + <td>{{ element.predictionWinSecond }} %</td> + <td>{{ element.predictionDraw }} %</td> <td>{{ element.score }}</td> <td><a href="{{ path('backend_entitybrowser_edit', {'name': name, 'id': element.id}) }}" class="btn btn-info">Modifier<div class="ripple-container"></div></a></td> <td> diff --git a/src/BackendBundle/Resources/views/team/form.html.twig b/src/BackendBundle/Resources/views/team/form.html.twig new file mode 100644 index 0000000..5bee3ac --- /dev/null +++ b/src/BackendBundle/Resources/views/team/form.html.twig @@ -0,0 +1,32 @@ +{% extends '@Backend/layout/dashboard.html.twig' %} + +{% block stylesheets %} + <link rel="stylesheet" href="{{ asset('css/boostrap-material-datetimepicker.css') }}"> + <script src="{{ asset('js/moment.js') }}"></script> + <script src="{{ asset('js/bootstrap-material-datetimepicker.js') }}"></script> +{% endblock %} + +{% block title %}Gestion de {{ name }}{% endblock %} + +{% block subcontent %} + <div class="row"> + <div class="col-sm-8 col-sm-offset-2"> + <h3 class="text-center text-primary">Ajouter une nouvelle ou éditer une {{ name | trans }}</h3> + {{ form_start(form, {'attr': {'class': 'form-horizontal'}}) }} + <div class="row"> + <div class="col-sm-6"> + <div class="form-group is-empty has-primary"> + {{ form_label(form.name, null, {'label_attr': {'class': "col-sm-3 control-label"}}) }} + <div class="col-sm-9"> + {{ form_widget(form.name, {'attr' : {'class': "form-control"}}) }} + {{ form_errors(form.name) }} + </div> + </div> + </div> + </div> + + <button type="submit" class="modal-action modal-close waves-effect waves-green waves-light btn">Ajouter</button> + {{ form_end(form, {'render_rest': false}) }} + </div> + </div> +{% endblock %} \ No newline at end of file diff --git a/src/BackendBundle/Resources/views/team/list.html.twig b/src/BackendBundle/Resources/views/team/list.html.twig new file mode 100644 index 0000000..986afdf --- /dev/null +++ b/src/BackendBundle/Resources/views/team/list.html.twig @@ -0,0 +1,43 @@ +{% extends '@Backend/layout/dashboard.html.twig' %} + +{% block title %}Liste de {{ name | trans }}{% endblock %} + +{% block subcontent %} + <div class="row"> + <div class="col-sm-12"> + {% include '@Backend/entity-browser/buttons.html.twig' %} + <table class="table table-striped" cellspacing="0" width="50%"> + <thead> + <tr> + <th>#</th> + <th>Nom</th> + <th>Selectionnerr</th> + </tr> + </thead> + <tbody> + {% for element in elements %} + <tr> + <td>{{ element.id }}</td> + <td>{{ element.name }}</td> + <td><a href="{{ path('backend_entitybrowser_edit', {'name': name, 'id': element.id}) }}" class="btn btn-info">Modifier<div class="ripple-container"></div></a></td> + <td> + <div class="checkbox"> + <label> + <input type="checkbox" data-id="{{ element.id }}"> + </label> + </div> + </td> + </tr> + {% endfor %} + </tbody> + </table> + + {% include '@Backend/entity-browser/paginator.html.twig' %} + + </div> + </div> +{% endblock %} + +{% block javascripts %} + <script src="{{ asset('js/ajax-select-and-delete.js') }}"></script> +{% endblock %} \ No newline at end of file diff --git a/web/config.php b/web/config.php index 1368c8a..a031a3a 100644 --- a/web/config.php +++ b/web/config.php @@ -38,9 +38,216 @@ $hasMinorProblems = (bool) count($minorProblems); <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta name="robots" content="noindex,nofollow" /> <title>Symfony Configuration Checker</title> - <link rel="stylesheet" href="bundles/framework/css/structure.css" media="all" /> - <link rel="stylesheet" href="bundles/framework/css/body.css" media="all" /> - <style type="text/css"> + <style> + /* styles copied from symfony framework bundle */ + html { + background: #eee; + } + body { + font: 11px Verdana, Arial, sans-serif; + color: #333; + } + .sf-reset, .sf-reset .block, .sf-reset #message { + margin: auto; + } + img { + border: 0; + } + .clear { + clear: both; + height: 0; + font-size: 0; + line-height: 0; + } + .clear-fix:after { + content: "\0020"; + display: block; + height: 0; + clear: both; + visibility: hidden; + } + .clear-fix { + display: inline-block; + } + * html .clear-fix { + height: 1%; + } + .clear-fix { + display: block; + } + .header { + padding: 30px 30px 20px 30px; + } + .header-logo { + float: left; + } + .search { + float: right; + padding-top: 20px; + } + .search label { + line-height: 28px; + vertical-align: middle; + } + .search input { + width: 195px; + font-size: 12px; + border: 1px solid #dadada; + background: #fff url(data:image/gif;base64,R0lGODlhAQAFAKIAAPX19e/v7/39/fr6+urq6gAAAAAAAAAAACH5BAAAAAAALAAAAAABAAUAAAMESAEjCQA7) repeat-x left top; + padding: 5px 6px; + color: #565656; + } + .search input[type="search"] { + -webkit-appearance: textfield; + } + #content { + width: 970px; + margin: 0 auto; + } + #content pre { + white-space: normal; + font-family: Arial, Helvetica, sans-serif; + } + + /* + Copyright (c) 2010, Yahoo! Inc. All rights reserved. + Code licensed under the BSD License: + http://developer.yahoo.com/yui/license.html + version: 3.1.2 + build: 56 + */ + .sf-reset div,.sf-reset dl,.sf-reset dt,.sf-reset dd,.sf-reset ul,.sf-reset ol,.sf-reset li,.sf-reset h1,.sf-reset h2,.sf-reset h3,.sf-reset h4,.sf-reset h5,.sf-reset h6,.sf-reset pre,.sf-reset code,.sf-reset form,.sf-reset fieldset,.sf-reset legend,.sf-reset input,.sf-reset textarea,.sf-reset p,.sf-reset blockquote,.sf-reset th,.sf-reset td{margin:0;padding:0;}.sf-reset table{border-collapse:collapse;border-spacing:0;}.sf-reset fieldset,.sf-reset img{border:0;}.sf-reset address,.sf-reset caption,.sf-reset cite,.sf-reset code,.sf-reset dfn,.sf-reset em,.sf-reset strong,.sf-reset th,.sf-reset var{font-style:normal;font-weight:normal;}.sf-reset li{list-style:none;}.sf-reset caption,.sf-reset th{text-align:left;}.sf-reset h1,.sf-reset h2,.sf-reset h3,.sf-reset h4,.sf-reset h5,.sf-reset h6{font-size:100%;font-weight:normal;}.sf-reset q:before,.sf-reset q:after{content:'';}.sf-reset abbr,.sf-reset acronym{border:0;font-variant:normal;}.sf-reset sup{vertical-align:text-top;}.sf-reset sub{vertical-align:text-bottom;}.sf-reset input,.sf-reset textarea,.sf-reset select{font-family:inherit;font-size:inherit;font-weight:inherit;}.sf-reset input,.sf-reset textarea,.sf-reset select{font-size:100%;}.sf-reset legend{color:#000;} + .sf-reset abbr { + border-bottom: 1px dotted #000; + cursor: help; + } + .sf-reset p { + font-size: 14px; + line-height: 20px; + padding-bottom: 20px; + } + .sf-reset strong { + color: #313131; + font-weight: bold; + } + .sf-reset a { + color: #6c6159; + } + .sf-reset a img { + border: none; + } + .sf-reset a:hover { + text-decoration: underline; + } + .sf-reset em { + font-style: italic; + } + .sf-reset h2, + .sf-reset h3 { + font-weight: bold; + } + .sf-reset h1 { + font-family: Georgia, "Times New Roman", Times, serif; + font-size: 20px; + color: #313131; + word-wrap: break-word; + } + .sf-reset li { + padding-bottom: 10px; + } + .sf-reset .block { + -moz-border-radius: 16px; + -webkit-border-radius: 16px; + border-radius: 16px; + margin-bottom: 20px; + background-color: #FFFFFF; + border: 1px solid #dfdfdf; + padding: 40px 50px; + word-break: break-all; + } + .sf-reset h2 { + font-size: 16px; + font-family: Arial, Helvetica, sans-serif; + } + .sf-reset li a { + background: none; + color: #868686; + text-decoration: none; + } + .sf-reset li a:hover { + background: none; + color: #313131; + text-decoration: underline; + } + .sf-reset ol { + padding: 10px 0; + } + .sf-reset ol li { + list-style: decimal; + margin-left: 20px; + padding: 2px; + padding-bottom: 20px; + } + .sf-reset ol ol li { + list-style-position: inside; + margin-left: 0; + white-space: nowrap; + font-size: 12px; + padding-bottom: 0; + } + .sf-reset li .selected { + background-color: #ffd; + } + .sf-button { + display: -moz-inline-box; + display: inline-block; + text-align: center; + vertical-align: middle; + border: 0; + background: transparent none; + text-transform: uppercase; + cursor: pointer; + font: bold 11px Arial, Helvetica, sans-serif; + } + .sf-button span { + text-decoration: none; + display: block; + height: 28px; + float: left; + } + .sf-button .border-l { + text-decoration: none; + display: block; + height: 28px; + float: left; + padding: 0 0 0 7px; + background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAcCAYAAACtQ6WLAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQtJREFUeNpiPHnyJAMakARiByDWYEGT8ADiYGVlZStubm5xlv///4MEQYoKZGRkQkRERLRYWVl5wYJQyXBZWdkwCQkJUxAHKgaWlAHSLqKiosb//v1DsYMFKGCvoqJiDmQzwXTAJYECulxcXNLoumCSoszMzDzoumDGghQwYZUECWIzkrAkSIIGOmlkLI10AiX//P379x8jIyMTNmPf/v79+ysLCwsvuiQoNi5//fr1Kch4dAyS3P/gwYMTQBP+wxwHw0xA4gkQ73v9+vUZdJ2w1Lf82bNn4iCHCQoKasHsZw4ODgbRIL8c+/Lly5M3b978Y2dn5wC6npkFLXnsAOKLjx49AmUHLYAAAwBoQubG016R5wAAAABJRU5ErkJggg==) no-repeat top left; + } + .sf-button .border-r { + padding: 0 7px 0 0; + background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAcCAYAAACtQ6WLAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAR1JREFUeNpiPHnyZCMDA8MNID5gZmb2nAEJMH7//v3N169fX969e/cYkL8WqGAHXPLv37//QYzfv39/fvPmzbUnT56sAXInmJub/2H5/x8sx8DCwsIrISFhDmQyPX78+CmQXs70798/BmQsKipqBNTgdvz4cWkmkE5kDATMioqKZkCFdiwg1eiAi4tLGqhQF24nMmBmZuYEigth1QkEbEBxTlySYPvJkwSJ00AnjYylgU6gxB8g/oFVEphkvgLF32KNMmCCewYUv4qhEyj47+HDhyeBzIMYOoEp8CxQw56wsLAncJ1//vz5/P79+2svX74EJc2V4BT58+fPd8CE/QKYHMGJOiIiAp6oWW7evDkNSF8DZYfIyEiU7AAQYACJ2vxVdJW4eQAAAABJRU5ErkJggg==) right top no-repeat; + } + .sf-button .btn-bg { + padding: 0 14px; + color: #636363; + line-height: 28px; + background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAcCAYAAACgXdXMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAClJREFUeNpiPnny5EKGf//+/Wf6//8/A4QAcrGzKCZwGc9sa2urBBBgAIbDUoYVp9lmAAAAAElFTkSuQmCC) repeat-x top left; + } + .sf-button:hover .border-l, + .sf-button-selected .border-l { + background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAcCAYAAACtQ6WLAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAR9JREFUeNpi/P//PwMyOHfunDqQSgNiexZkibNnzxYBqZa3HOs5v7PcYQBLnjlzhg1IbfzIdsTjA/t+ht9Mr8GKwZL//v3r+sB+0OMN+zqIEf8gFMvJkyd1gXTOa9YNDP//otrPAtSV/Jp9HfPff78Z0AEL0LUeXxivMfxD0wXTqfjj/2ugkf+wSrL9/YtpJEyS4S8WI5Ek/+GR/POPFjr//cenE6/kP9q4Fo/kr39/mdj+M/zFkGQCSj5i+ccPjLJ/GBgkuYOHQR1sNDpmAkb2LBmWwL///zKCIxwZM0VHR18G6p4uxeLLAA4tJMwEshiou1iMxXaHLGswA+t/YbhORuQUv2DBAnCifvxzI+enP3dQJUFg/vz5sOzgBBBgAPxX9j0YnH4JAAAAAElFTkSuQmCC) no-repeat top left; + } + .sf-button:hover .border-r, + .sf-button-selected .border-r { + background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAcCAYAAACtQ6WLAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAT5JREFUeNpiPHv27BkGBoaDQDzLyMjoJgMSYHrM3WX8hn1d0f///88DFRYhSzIuv2X5H8Rg/SfKIPDTkYH/l80OINffxMTkF9O/f/8ZQPgnwyuGl+wrGd6x7vf49+9fO9jYf3+Bkkj4NesmBqAV+SdPntQC6vzHgIz//gOawbqOGchOxtAJwp8Zr4F0e7D8/fuPAR38/P8eZIo0yz8skv8YvoIk+YE6/zNgAyD7sRqLkPzzjxY6/+HS+R+fTkZ8djLh08lCUCcuSWawJGbwMTGwg7zyBatX2Bj5QZKPsBrLzaICktzN8g/NWEYGZgYZjoC/wMiei5FMpFh8QPSU6Ojoy3Cd7EwiDBJsDgxiLNY7gLrKQGIsHAxSDHxAO2TZ/b8D+TVxcXF9MCtYtLiKLgDpfUDVsxITE1GyA0CAAQA2E/N8VuHyAAAAAABJRU5ErkJggg==) right top no-repeat; + } + .sf-button:hover .btn-bg, + .sf-button-selected .btn-bg { + color: #FFFFFF; + text-shadow:0 1px 1px #6b9311; + background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAcCAIAAAAvP0KbAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAEFJREFUeNpiPnv2LNMdvlymf///M/37B8R/QfQ/MP33L4j+B6Qh7L9//sHpf2h8MA1V+w/KRjYLaDaLCU8vQIABAFO3TxZriO4yAAAAAElFTkSuQmCC) repeat-x top left; + } + /* styles copied from bundles/sensiodistribution/webconfigurator/css/install.css */ body { font-size: 14px; @@ -126,7 +333,7 @@ $hasMinorProblems = (bool) count($minorProblems); <div id="content"> <div class="header clear-fix"> <div class="header-logo"> - <img src="bundles/framework/images/logo_symfony.png" alt="Symfony" /> + <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALYAAAA+CAMAAACxzRGDAAAAUVBMVEX////Ly8yko6WLioxkYmVXVVkwLjLl5eWxsLJKSEzy8vJxcHLY2Ni+vb89Oz9XVVh+fH+Yl5n///+xsbLY2Nlxb3KkpKWXlph+fX+LiYy+vr/IZP61AAAAAXRSTlMAQObYZgAABRBJREFUeNrVmtuWoyAQRS1FEEQSzQU7//+hYxUiXsKQZLJWM+chsUloN+WhCuguYoKyYqzmvGasKqH4HyRKxndipcgcumH8qViTM7TkUclcwaHmf5XM0eWq4km1KjdqXfMXJHVe1J3hL8lk5fCGv6wmT+o0d87U+XNrk0Y9nfv+7LM6ZJH5ZBL6LAbSxQ3Q5FDr22Skr8PQSy4n7isnsQxSX4r6pobhjCHHeDNOKrO3yGmCvZOjV9jmt8ulTdXFKdbKLNh+kOMvBzuVRa4Y7MUsdEUSWQe7xxCfZmcwjHU83LqzFvSbJQOXQvptbPnEFoyZtUUGwTeKuLuTHyT1kaP0P6cR01OKvv448gtl61dqZfmJezQmU/t+1R2fJLtBwXV6uWGwB9SZPrn0fKO2WAvQN1PUhHjTom3xgXYTkvlSKHs19OhslETq6X3HrXbjt8XbGj9b4Gi+lUAnL6XxQj8Pyk9N4Bt1xUrsLVN/3isYMug8rODMdbgOvoHs8uAb2fcANIAzkKCLYy+AXRpSU8sr1r4P67xhLgPp7vM32zlqt7Bhq2fI1Hwp+VgANxok59SsGV3oqdUL0YVDMRY7Yg8QLbVUU4NZNoOq5hJHuxEM28Sh/IyUZ8D3reR+yc58EGvOy2U0HQL6G9V+kWyEWHmzaMx6t4o9RhOm/riUiYrzqij4Ptqkn7AaCXqc+F47m04ahfde7YIz8RHEBN6BdVwdIGRVdNbKqYu1Hc0x0wBY4wqC8+XUgBGnj81SZsQB+0yAS1x/BlI/6ebHHk0lauQLuPDpu6EwAVJ7T0rl2uXa23jcqNyOZekhqYHRz3JOANrF4wCCmEs1f9D1lUe0n4NAATed80Y5e0Q7CO2TezM/BR6wKdgQzKbCF4uOQC3Bk0fKAzbFlyRWg3gksA/gmm7eOjrpaKX7fHlEW2xLbE6GZsPiCiShVzN7RG2xTz2G+OJtEqzdJ7APxy3MrSsV0VukXbKMp9lhs5BN6dr3CN+sySUaoxGwfRUM3I/gdPYONgVU+PLX4vUWm32AvUySarbONvcpV2RQEPKKjEBHFk01kQDGRblnn8ZuE9g+JUl8OWAPbkFK2K6JxhJVvF47FzYYnAN22ttwxKYCoH36rheEB7KG/HF/YUaa2G5JF+55tpyrl7B1WHM39HuP2N2EXPl1UBu8vbj4OjvD+NoTE4ssF+ScARgaJY1N7+u8bY/Y9BSM5PKwJbvMVab32YP5FB5TtcYVrGoASolVLTzI7kVsYVxRtAb5n2JXq1vCdtd47XtYItynrN0835PasLg0y13aOPbmPI+on2Lr9e5tjSHvgkAvclUjL3Fsdaw03IzgTR62yYClk7QMah4IQ0qSsoYYbOix6zJR1ZGDNMOY3Bb6W5S6jiyovep3t7bUPyoq7OkjYumrfESp8zSBc/OLosVf+nTnnKjsqR16++WDwpI8FxJWRFTlI6NKnqYJaL96TqjAbo9Toi5QiWBDcmfdFV+T8dkvFe5bItgstbM2X6QG2mVun+cazfRwOS0eiaeRRJKgLfc3BQAqfnhJyz8lfR6580SF/FXVu83Nz1xrrnFqqXL6Qxl47DNSm4RFflvN5sABDD8peouqLLKQXVdGbnqf+qIpOxON4ZyYdJEJ6sy4zS2c5eRPTT4Jyp46qDE5/ptAWqJOQ9e6yE82FXBbZCk1/tXVoshVoopE3CB0zmraI3nbqCJ/gW3ZMgtbC5nh/QHlOoOZBxQCRgAAAABJRU5ErkJggg==" alt="Symfony" /> </div> <div class="search"> @@ -134,7 +341,7 @@ $hasMinorProblems = (bool) count($minorProblems); <div class="form-row"> <label for="search-id"> - <img src="bundles/framework/images/grey_magnifier.png" alt="Search on Symfony website" /> + <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAABUElEQVQoz2NgAIJ29iBdD0d7X2cPb+tY2f9MDMjgP2O2hKu7vS8CBlisZUNSMJ3fxRMkXO61wm2ue6I3iB1q8Z8ZriDZFCS03fm/wX+1/xp/TBo8QPxeqf+MUAW+QIFKj/+q/wX/c/3n/i/6Qd/bx943z/Q/K1SBI1D9fKv/AhCn/Wf5L5EHdFGKw39OqAIXoPpOMziX4T9/DFBBnuN/HqhAEtCKCNf/XDA/rZRyAmrpsvrPDVUw3wrkqCiLaewg6TohX1d7X0ffs5r/OaAKfinmgt3t4ulr4+Xg4ANip3j+l/zPArNT4LNOD0pAgWCSOUIBy3+h/+pXbBa5tni0eMx23+/mB1YSYnENroT5Pw/QSOX/mkCo+l/jgo0v2KJA643s8PgAmsMBDCbu/5xALHPB2husxN9uCzsDOgAq5kAoaZVnYMCh5Ky1r88Eh/+iABM8jUk7ClYIAAAAAElFTkSuQmCC" alt="Search on Symfony website" /> </label> <input name="q" id="search-id" type="search" placeholder="Search on Symfony website" /> diff --git a/web/css/style.css b/web/css/style.css index ef84e40..be100a0 100644 --- a/web/css/style.css +++ b/web/css/style.css @@ -1,3 +1,7 @@ +body { + background-color: white; +} + .flex-display-right { display: flex; align-content: center; @@ -83,4 +87,27 @@ .pagination li.disabled a { cursor: default; color: #999; +} + +.select2-container--default .select2-selection--single .select2-selection__arrow { + margin-top: 8px; +} + +.select2-container--default .select2-selection--single { + margin-top: 8px !important; + background-color: transparent !important; + border-top: 0 !important; + border-left: 0 !important; + border-right: 0 !important; + border-radius: 0 !important; + font-size: 16px !important; + border-color: #D2D2D2 !important; +} + +.select2-container .select2-selection--single .select2-selection__rendered { + padding-left: 0 !important; +} + +.select2-container--default .select2-selection--single .select2-selection__arrow b { + border-color: #D2D2D2 transparent transparent transparent !important; } \ No newline at end of file -- GitLab