├── .gitignore
├── src
├── ServiceProvider.php
└── routes.php
├── composer.json
├── LICENSE
├── resources
└── views
│ ├── ios-manifest.blade.php
│ └── ios-download.blade.php
├── README.md
└── composer.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | .idea/
3 | vendor/
4 |
--------------------------------------------------------------------------------
/src/ServiceProvider.php:
--------------------------------------------------------------------------------
1 | loadRoutesFrom(__DIR__.'/routes.php');
15 | $this->loadViewsFrom(__DIR__ . '/../resources/views', 'ota-distribution-ios');
16 |
17 | $this->publishes([
18 | __DIR__.'/../resources/views' => resource_path('views/vendor/ota-distribution-ios'),
19 | ]);
20 | }
21 |
22 | /**
23 | * Register the application services.
24 | *
25 | * @return void
26 | */
27 | public function register()
28 | {
29 | //
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "pavankataria/laravel-ota-distribution-ios",
3 | "repositories": [
4 | {
5 | "type": "vcs",
6 | "url": "https://github.com/pavankataria/laravel-ota-distribution-ios"
7 | }
8 | ],
9 | "description": "This package creates the html download views and routes required for both uploading ios builds and the creation of manifest files ready for downloading the ios builds.",
10 | "keywords": ["laravel", "ota", "ios", "distribution", "over the air", "ipa"],
11 | "type": "library",
12 | "license": "MIT",
13 | "authors": [
14 | {
15 | "name": "Pavan Kataria",
16 | "email": "info@pavankataria.com"
17 | }
18 | ],
19 | "minimum-stability": "dev",
20 | "require": {
21 | "php": ">=5.5.9",
22 | "illuminate/support": "8.*",
23 | "nesbot/carbon": "^2.53.1"
24 | },
25 | "autoload": {
26 | "psr-4" : {
27 | "PavanKataria\\OtaDistributionIos\\" : "src/"
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 pavankataria
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/resources/views/ios-manifest.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | items
6 |
7 |
8 | assets
9 |
10 |
11 | kind
12 | software-package
13 | url
14 | {{ $buildUrlRoute }}
15 |
16 |
17 | kind
18 | display-image
19 | url
20 | {{ $publicUrl }}/image.57x57.jpg
21 | {{--{{ $publicUrl }}/image57--}}
22 |
23 |
24 | kind
25 | full-size-image
26 | url
27 | {{ $publicUrl }}/image.512x512.jpg
28 | {{--{{ $publicUrl }}/image512--}}
29 |
30 |
31 | metadata
32 |
33 | bundle-identifier
34 | <\com.domain.projectname identical to the app's bundle identifier>
35 | bundle-version
36 | {{ $bundleVersionNumber }}
37 | kind
38 | software
39 | title
40 | <\Insert Application Name>
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/resources/views/ios-download.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | [BETA_NAME] [BETA_VERSION]
7 |
17 |
18 |
19 |
20 |
21 |
22 | [BETA_ICON]
23 |
24 |
Install Link
25 |
26 |
27 |
28 |
Link didn't work?
29 | Make sure you're visiting this page on your device, not your computer.
30 |
31 |
Last Updated: {{ $appLastUpdated }}
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Laravel OTA (Over-The-Air) Distribution for iOS
2 |
3 | [![Latest Version on Packagist][ico-version]][link-packagist]
4 | [![Software License][ico-license]](LICENSE.md)
5 |
7 |
8 | The package creates the necessary files and routes on your server to cater for the upload of iOS .ipa files and provision the installation of those builds on iOS devices.
9 |
10 | ### Great, how does it work?
11 |
12 | The package allows an integration tool to submit an iOS build to your server - where you can act as the host - the package’s service provider creates the routes that 1) handle the submission of the build which in turn create the necessary manifest files, views, and the download page required for over the air distribution for ios devices, and routes to download the build using those generated files.
13 |
14 | Note, since iOS 9, over-the-air distribution requires the https protocol or installation will fail.
15 |
16 | ## Installation
17 |
18 | Require this package with composer:
19 |
20 | ```shell
21 | composer require "pavankataria/laravel-ota-distribution-ios":"dev-master"
22 | ```
23 |
24 | After updating composer, add the ServiceProvider to the providers array in config/app.php
25 |
26 | ### Laravel 5.x:
27 |
28 | ```php
29 | PavanKataria\OtaDistributionIos\ServiceProvider::class,
30 | ```
31 |
32 | Run the publish command to finish with the installation, copy the views to the views vendor directory. The routes that serve the build use these views.
33 |
34 | ```shell
35 | php artisan vendor:publish --provider="PavanKataria\OtaDistributionIos\ServiceProvider"
36 | ```
37 |
38 | ### Lumen:
39 |
40 | For Lumen, register a different Provider in `bootstrap/app.php`:
41 |
42 | ### License
43 |
44 | The Laravel OTA Distribution for iOS package is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT)
45 |
46 | [ico-version]: https://img.shields.io/packagist/v/pavankataria/laravel-ota-distribution-ios.svg?style=flat-square
47 | [ico-license]: https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square
48 | [ico-travis]: https://img.shields.io/travis/pavankataria/laravel-ota-distribution-ios/master.svg?style=flat-square
49 | [ico-scrutinizer]: https://img.shields.io/scrutinizer/coverage/g/pavankataria/laravel-ota-distribution-ios.svg?style=flat-square
50 | [ico-code-quality]: https://img.shields.io/scrutinizer/g/pavankataria/laravel-ota-distribution-ios.svg?style=flat-square
51 | [ico-downloads]: https://img.shields.io/packagist/dt/pavankataria/laravel-ota-distribution-ios.svg?style=flat-square
52 |
53 | [link-packagist]: https://packagist.org/packages/pavankataria/laravel-ota-distribution-ios
54 | [link-travis]: https://travis-ci.org/pavankataria/laravel-ota-distribution-ios
55 | [link-scrutinizer]: https://scrutinizer-ci.com/g/pavankataria/laravel-ota-distribution-ios
56 | [link-code-quality]: https://scrutinizer-ci.com/g/pavankataria/laravel-ota-distribution-ios
57 | [link-downloads]: https://packagist.org/packages/pavankataria/laravel-ota-distribution-ios
58 | [link-author]: https://github.com/pavankataria
59 | [link-contributors]: ../../contributors
60 |
--------------------------------------------------------------------------------
/src/routes.php:
--------------------------------------------------------------------------------
1 | input('build_version_number');
11 | echo "branch: {$branch}";
12 | echo "\nfile: {$file}";
13 | echo "\nsize of file: {$file->getSize()}";
14 | echo "\nbundle version number: " . $bundleVersionNumber;
15 |
16 | $appLastUpdated = Carbon::now();
17 | $pathToBuildDirectory = "builds";
18 |
19 | $iosManifestFileContents = view('ota-distribution-ios::ios-manifest')
20 | ->with('buildUrlRoute', $buildUrlRoute)
21 | ->with('publicUrl', $publicUrl)
22 | ->with('bundleVersionNumber', $bundleVersionNumber)
23 | ->render();
24 |
25 | //Render the iOS view
26 | $iosDownloadFileContents = view('ota-distribution-ios::ios-download')
27 | ->with('appLastUpdated', $appLastUpdated)
28 | ->with('appVersion', $bundleVersionNumber)
29 | ->with('urlToManifestFile', route('builds.manifest'))
30 | ->render();
31 |
32 | //Creates files and places them in a latest folder.
33 | $latestBuildPath = "{$pathToBuildDirectory}/latest";
34 | Storage::put("{$latestBuildPath}/manifest.plist", $iosManifestFileContents);
35 | Storage::put("{$latestBuildPath}/download.html", $iosDownloadFileContents);
36 | $file->storeAs("{$latestBuildPath}", "build.ipa");
37 |
38 | //Makes duplicate files in a separate bundle version folder for versioning.
39 | $bundleVersionPath = "{$pathToBuildDirectory}/{$bundleVersionNumber}";
40 | Storage::put("{$bundleVersionPath}/manifest.plist", $iosManifestFileContents);
41 | Storage::put("{$bundleVersionPath}/download.html", $iosDownloadFileContents);
42 | $file->storeAs($bundleVersionPath, "build.ipa");
43 | });
44 |
45 | /**
46 | * A call to this request will search the directory for existing installable builds
47 | * and displays a message if none are found. If a build is found then a download
48 | * link is shown allowing the user to install the app from their iOS devices.
49 | *
50 | * @return string
51 | */
52 | Route::get('/download', function(){
53 | $directory = "builds/latest";
54 | $buildFile = Storage::exists("{$directory}/download.html");
55 | if ($buildFile == false) {
56 | //TODO: Return a view instead
57 | return "There are no builds available";
58 | }
59 | return Storage::get("{$directory}/download.html");
60 | });
61 |
62 | //TODO: Give this route a name of builds/latest
63 | Route::get('api/build', function() {
64 | $directory = "builds/latest";
65 | $buildFile = Storage::exists("{$directory}/build.ipa");
66 | if ($buildFile == false) {
67 | return "There currently are no builds available";
68 | }
69 | return Storage::get("{$directory}/build.ipa");
70 | });
71 |
72 |
73 |
74 | //Route::get('/api/builds/latest/download')
75 |
76 | /**
77 | * This exposed route is for the iOS installation process which requires the manifest file
78 | * to be exposed. This manifest file contains the details for the download of image
79 | * urls, and ipa build files.
80 | *
81 | * @return mixed
82 | */
83 | Route::get('/api/manifest', function() {
84 | return Storage::get("builds/latest/manifest.plist");
85 | })->name("builds.manifest");
--------------------------------------------------------------------------------
/composer.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_readme": [
3 | "This file locks the dependencies of your project to a known state",
4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
5 | "This file is @generated automatically"
6 | ],
7 | "content-hash": "afce8df0afe832c0426a83d1c3ba55b7",
8 | "packages": [
9 | {
10 | "name": "doctrine/inflector",
11 | "version": "dev-master",
12 | "source": {
13 | "type": "git",
14 | "url": "https://github.com/doctrine/inflector.git",
15 | "reference": "803a2ed9fea02f9ca47cd45395089fe78769a392"
16 | },
17 | "dist": {
18 | "type": "zip",
19 | "url": "https://api.github.com/repos/doctrine/inflector/zipball/803a2ed9fea02f9ca47cd45395089fe78769a392",
20 | "reference": "803a2ed9fea02f9ca47cd45395089fe78769a392",
21 | "shasum": ""
22 | },
23 | "require": {
24 | "php": ">=5.3.2"
25 | },
26 | "require-dev": {
27 | "phpunit/phpunit": "4.*"
28 | },
29 | "type": "library",
30 | "extra": {
31 | "branch-alias": {
32 | "dev-master": "1.1.x-dev"
33 | }
34 | },
35 | "autoload": {
36 | "psr-0": {
37 | "Doctrine\\Common\\Inflector\\": "lib/"
38 | }
39 | },
40 | "notification-url": "https://packagist.org/downloads/",
41 | "license": [
42 | "MIT"
43 | ],
44 | "authors": [
45 | {
46 | "name": "Roman Borschel",
47 | "email": "roman@code-factory.org"
48 | },
49 | {
50 | "name": "Benjamin Eberlei",
51 | "email": "kontakt@beberlei.de"
52 | },
53 | {
54 | "name": "Guilherme Blanco",
55 | "email": "guilhermeblanco@gmail.com"
56 | },
57 | {
58 | "name": "Jonathan Wage",
59 | "email": "jonwage@gmail.com"
60 | },
61 | {
62 | "name": "Johannes Schmitt",
63 | "email": "schmittjoh@gmail.com"
64 | }
65 | ],
66 | "description": "Common String Manipulations with regard to casing and singular/plural rules.",
67 | "homepage": "http://www.doctrine-project.org",
68 | "keywords": [
69 | "inflection",
70 | "pluralize",
71 | "singularize",
72 | "string"
73 | ],
74 | "time": "2016-05-12 17:23:41"
75 | },
76 | {
77 | "name": "illuminate/contracts",
78 | "version": "5.4.x-dev",
79 | "source": {
80 | "type": "git",
81 | "url": "https://github.com/illuminate/contracts.git",
82 | "reference": "dd256891c80fd94a58ab83d7989d6da2f50e30ea"
83 | },
84 | "dist": {
85 | "type": "zip",
86 | "url": "https://api.github.com/repos/illuminate/contracts/zipball/dd256891c80fd94a58ab83d7989d6da2f50e30ea",
87 | "reference": "dd256891c80fd94a58ab83d7989d6da2f50e30ea",
88 | "shasum": ""
89 | },
90 | "require": {
91 | "php": ">=5.6.4"
92 | },
93 | "type": "library",
94 | "extra": {
95 | "branch-alias": {
96 | "dev-master": "5.4-dev"
97 | }
98 | },
99 | "autoload": {
100 | "psr-4": {
101 | "Illuminate\\Contracts\\": ""
102 | }
103 | },
104 | "notification-url": "https://packagist.org/downloads/",
105 | "license": [
106 | "MIT"
107 | ],
108 | "authors": [
109 | {
110 | "name": "Taylor Otwell",
111 | "email": "taylor@laravel.com"
112 | }
113 | ],
114 | "description": "The Illuminate Contracts package.",
115 | "homepage": "https://laravel.com",
116 | "time": "2017-02-21 14:21:59"
117 | },
118 | {
119 | "name": "illuminate/support",
120 | "version": "5.4.x-dev",
121 | "source": {
122 | "type": "git",
123 | "url": "https://github.com/illuminate/support.git",
124 | "reference": "20c703419244557c10d9b035b205078fcb99f739"
125 | },
126 | "dist": {
127 | "type": "zip",
128 | "url": "https://api.github.com/repos/illuminate/support/zipball/20c703419244557c10d9b035b205078fcb99f739",
129 | "reference": "20c703419244557c10d9b035b205078fcb99f739",
130 | "shasum": ""
131 | },
132 | "require": {
133 | "doctrine/inflector": "~1.0",
134 | "ext-mbstring": "*",
135 | "illuminate/contracts": "5.4.*",
136 | "paragonie/random_compat": "~1.4|~2.0",
137 | "php": ">=5.6.4"
138 | },
139 | "replace": {
140 | "tightenco/collect": "self.version"
141 | },
142 | "suggest": {
143 | "illuminate/filesystem": "Required to use the composer class (5.2.*).",
144 | "symfony/process": "Required to use the composer class (~3.2).",
145 | "symfony/var-dumper": "Required to use the dd function (~3.2)."
146 | },
147 | "type": "library",
148 | "extra": {
149 | "branch-alias": {
150 | "dev-master": "5.4-dev"
151 | }
152 | },
153 | "autoload": {
154 | "psr-4": {
155 | "Illuminate\\Support\\": ""
156 | },
157 | "files": [
158 | "helpers.php"
159 | ]
160 | },
161 | "notification-url": "https://packagist.org/downloads/",
162 | "license": [
163 | "MIT"
164 | ],
165 | "authors": [
166 | {
167 | "name": "Taylor Otwell",
168 | "email": "taylor@laravel.com"
169 | }
170 | ],
171 | "description": "The Illuminate Support package.",
172 | "homepage": "https://laravel.com",
173 | "time": "2017-03-05 16:32:05"
174 | },
175 | {
176 | "name": "nesbot/carbon",
177 | "version": "dev-master",
178 | "source": {
179 | "type": "git",
180 | "url": "https://github.com/briannesbitt/Carbon.git",
181 | "reference": "926aee5ab38c2868816aa760f862a85ad01cb61a"
182 | },
183 | "dist": {
184 | "type": "zip",
185 | "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/926aee5ab38c2868816aa760f862a85ad01cb61a",
186 | "reference": "926aee5ab38c2868816aa760f862a85ad01cb61a",
187 | "shasum": ""
188 | },
189 | "require": {
190 | "php": ">=5.3.0",
191 | "symfony/translation": "~2.6 || ~3.0"
192 | },
193 | "require-dev": {
194 | "friendsofphp/php-cs-fixer": "~2",
195 | "phpunit/phpunit": "~4.0 || ~5.0"
196 | },
197 | "type": "library",
198 | "extra": {
199 | "branch-alias": {
200 | "dev-master": "1.23-dev"
201 | }
202 | },
203 | "autoload": {
204 | "psr-4": {
205 | "Carbon\\": "src/Carbon/"
206 | }
207 | },
208 | "notification-url": "https://packagist.org/downloads/",
209 | "license": [
210 | "MIT"
211 | ],
212 | "authors": [
213 | {
214 | "name": "Brian Nesbitt",
215 | "email": "brian@nesbot.com",
216 | "homepage": "http://nesbot.com"
217 | }
218 | ],
219 | "description": "A simple API extension for DateTime.",
220 | "homepage": "http://carbon.nesbot.com",
221 | "keywords": [
222 | "date",
223 | "datetime",
224 | "time"
225 | ],
226 | "time": "2017-02-06 22:02:47"
227 | },
228 | {
229 | "name": "paragonie/random_compat",
230 | "version": "v2.0.9",
231 | "source": {
232 | "type": "git",
233 | "url": "https://github.com/paragonie/random_compat.git",
234 | "reference": "6968531206671f94377b01dc7888d5d1b858a01b"
235 | },
236 | "dist": {
237 | "type": "zip",
238 | "url": "https://api.github.com/repos/paragonie/random_compat/zipball/6968531206671f94377b01dc7888d5d1b858a01b",
239 | "reference": "6968531206671f94377b01dc7888d5d1b858a01b",
240 | "shasum": ""
241 | },
242 | "require": {
243 | "php": ">=5.2.0"
244 | },
245 | "require-dev": {
246 | "phpunit/phpunit": "4.*|5.*"
247 | },
248 | "suggest": {
249 | "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
250 | },
251 | "type": "library",
252 | "autoload": {
253 | "files": [
254 | "lib/random.php"
255 | ]
256 | },
257 | "notification-url": "https://packagist.org/downloads/",
258 | "license": [
259 | "MIT"
260 | ],
261 | "authors": [
262 | {
263 | "name": "Paragon Initiative Enterprises",
264 | "email": "security@paragonie.com",
265 | "homepage": "https://paragonie.com"
266 | }
267 | ],
268 | "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
269 | "keywords": [
270 | "csprng",
271 | "pseudorandom",
272 | "random"
273 | ],
274 | "time": "2017-03-03T20:43:42+00:00"
275 | },
276 | {
277 | "name": "symfony/polyfill-mbstring",
278 | "version": "dev-master",
279 | "source": {
280 | "type": "git",
281 | "url": "https://github.com/symfony/polyfill-mbstring.git",
282 | "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4"
283 | },
284 | "dist": {
285 | "type": "zip",
286 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/e79d363049d1c2128f133a2667e4f4190904f7f4",
287 | "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4",
288 | "shasum": ""
289 | },
290 | "require": {
291 | "php": ">=5.3.3"
292 | },
293 | "suggest": {
294 | "ext-mbstring": "For best performance"
295 | },
296 | "type": "library",
297 | "extra": {
298 | "branch-alias": {
299 | "dev-master": "1.3-dev"
300 | }
301 | },
302 | "autoload": {
303 | "psr-4": {
304 | "Symfony\\Polyfill\\Mbstring\\": ""
305 | },
306 | "files": [
307 | "bootstrap.php"
308 | ]
309 | },
310 | "notification-url": "https://packagist.org/downloads/",
311 | "license": [
312 | "MIT"
313 | ],
314 | "authors": [
315 | {
316 | "name": "Nicolas Grekas",
317 | "email": "p@tchwork.com"
318 | },
319 | {
320 | "name": "Symfony Community",
321 | "homepage": "https://symfony.com/contributors"
322 | }
323 | ],
324 | "description": "Symfony polyfill for the Mbstring extension",
325 | "homepage": "https://symfony.com",
326 | "keywords": [
327 | "compatibility",
328 | "mbstring",
329 | "polyfill",
330 | "portable",
331 | "shim"
332 | ],
333 | "time": "2016-11-14 01:06:16"
334 | },
335 | {
336 | "name": "symfony/translation",
337 | "version": "dev-master",
338 | "source": {
339 | "type": "git",
340 | "url": "https://github.com/symfony/translation.git",
341 | "reference": "987e8740b947320ce8431b4d48da97ec5c05c66c"
342 | },
343 | "dist": {
344 | "type": "zip",
345 | "url": "https://api.github.com/repos/symfony/translation/zipball/987e8740b947320ce8431b4d48da97ec5c05c66c",
346 | "reference": "987e8740b947320ce8431b4d48da97ec5c05c66c",
347 | "shasum": ""
348 | },
349 | "require": {
350 | "php": ">=5.5.9",
351 | "symfony/polyfill-mbstring": "~1.0"
352 | },
353 | "conflict": {
354 | "symfony/config": "<2.8",
355 | "symfony/yaml": "<3.3"
356 | },
357 | "require-dev": {
358 | "psr/log": "~1.0",
359 | "symfony/config": "~2.8|~3.0",
360 | "symfony/intl": "^2.8.18|^3.2.5",
361 | "symfony/yaml": "~3.3"
362 | },
363 | "suggest": {
364 | "psr/log": "To use logging capability in translator",
365 | "symfony/config": "",
366 | "symfony/yaml": ""
367 | },
368 | "type": "library",
369 | "extra": {
370 | "branch-alias": {
371 | "dev-master": "3.3-dev"
372 | }
373 | },
374 | "autoload": {
375 | "psr-4": {
376 | "Symfony\\Component\\Translation\\": ""
377 | },
378 | "exclude-from-classmap": [
379 | "/Tests/"
380 | ]
381 | },
382 | "notification-url": "https://packagist.org/downloads/",
383 | "license": [
384 | "MIT"
385 | ],
386 | "authors": [
387 | {
388 | "name": "Fabien Potencier",
389 | "email": "fabien@symfony.com"
390 | },
391 | {
392 | "name": "Symfony Community",
393 | "homepage": "https://symfony.com/contributors"
394 | }
395 | ],
396 | "description": "Symfony Translation Component",
397 | "homepage": "https://symfony.com",
398 | "time": "2017-03-06 19:18:14"
399 | }
400 | ],
401 | "packages-dev": [],
402 | "aliases": [],
403 | "minimum-stability": "dev",
404 | "stability-flags": [],
405 | "prefer-stable": false,
406 | "prefer-lowest": false,
407 | "platform": {
408 | "php": ">=5.5.9"
409 | },
410 | "platform-dev": []
411 | }
412 |
--------------------------------------------------------------------------------