Browse Source

Improved lang handling

Sergio Brighenti 5 năm trước cách đây
mục cha
commit
5af7567b1a

+ 4 - 1
CHANGELOG.md

@@ -1,6 +1,9 @@
 ## v2.6
 ## v2.6
 + Added support to use AWS S3, Google Cloud Storage, Dropbox and FTP(s) accounts as storage location.
 + Added support to use AWS S3, Google Cloud Storage, Dropbox and FTP(s) accounts as storage location.
-+ Fixed missing icon. 
++ Fixed missing icon.
++ Added german and norwegian translations from [Weblate](https://hosted.weblate.org/projects/xbackbone/xbackbone/).
++ Improved lang detection.
++ Added ability to force system language.
 
 
 ## v2.5.3
 ## v2.5.3
 + Fixed bad css loading on Firefox (#35).
 + Fixed bad css loading on Firefox (#35).

+ 23 - 0
app/Controllers/AdminController.php

@@ -38,6 +38,7 @@ class AdminController extends Controller
 			'totalSize' => humanFileSize($totalSize),
 			'totalSize' => humanFileSize($totalSize),
 			'post_max_size' => ini_get('post_max_size'),
 			'post_max_size' => ini_get('post_max_size'),
 			'upload_max_filesize' => ini_get('upload_max_filesize'),
 			'upload_max_filesize' => ini_get('upload_max_filesize'),
+			'installed_lang' => $this->lang->getList(),
 		]);
 		]);
 	}
 	}
 
 
@@ -65,4 +66,26 @@ class AdminController extends Controller
 
 
 		return redirect($response, 'system');
 		return redirect($response, 'system');
 	}
 	}
+
+	/**
+	 * @param Request $request
+	 * @param Response $response
+	 * @return Response
+	 */
+	public function applyLang(Request $request, Response $response): Response
+	{
+		$config = require BASE_DIR . 'config.php';
+
+		if ($request->getParam('lang') !== 'auto') {
+			$config['lang'] = $request->getParam('lang');
+		} else {
+			unset($config['lang']);
+		}
+
+		file_put_contents(BASE_DIR . 'config.php', '<?php' . PHP_EOL . 'return ' . var_export($config, true) . ';');
+
+		$this->session->alert(lang('lang_set', [$request->getParam('lang')]));
+
+		return redirect($response, 'system');
+	}
 }
 }

+ 2 - 0
app/Controllers/Controller.php

@@ -3,6 +3,7 @@
 namespace App\Controllers;
 namespace App\Controllers;
 
 
 use App\Database\DB;
 use App\Database\DB;
+use App\Web\Lang;
 use App\Web\Session;
 use App\Web\Session;
 use League\Flysystem\FileNotFoundException;
 use League\Flysystem\FileNotFoundException;
 use League\Flysystem\Filesystem;
 use League\Flysystem\Filesystem;
@@ -15,6 +16,7 @@ use Slim\Container;
  * @property DB|null database
  * @property DB|null database
  * @property Logger|null logger
  * @property Logger|null logger
  * @property Filesystem|null storage
  * @property Filesystem|null storage
+ * @property Lang lang
  */
  */
 abstract class Controller
 abstract class Controller
 {
 {

+ 27 - 7
app/Web/Lang.php

@@ -41,12 +41,7 @@ class Lang
 	 */
 	 */
 	public static function build($lang = self::DEFAULT_LANG, $langPath = null): Lang
 	public static function build($lang = self::DEFAULT_LANG, $langPath = null): Lang
 	{
 	{
-
-		if (strlen($lang) !== 2) {
-			self::$lang = strtolower(substr($lang, 0, 2));
-		} else {
-			self::$lang = $lang;
-		}
+		self::$lang = $lang;
 
 
 		if ($langPath !== null) {
 		if ($langPath !== null) {
 			self::$langPath = $langPath;
 			self::$langPath = $langPath;
@@ -63,7 +58,7 @@ class Lang
 	 */
 	 */
 	public static function recognize()
 	public static function recognize()
 	{
 	{
-		return substr(@$_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
+		return locale_accept_from_http($_SERVER['HTTP_ACCEPT_LANGUAGE']);
 	}
 	}
 
 
 	/**
 	/**
@@ -74,6 +69,27 @@ class Lang
 		return self::$lang;
 		return self::$lang;
 	}
 	}
 
 
+	/**
+	 * @return array
+	 */
+	public static function getList()
+	{
+		$languages = [];
+
+		$default = count(include self::$langPath . self::DEFAULT_LANG . '.lang.php') - 1;
+
+		foreach (glob(self::$langPath . '*.lang.php') as $file) {
+			$dict = include $file;
+
+			$count = count($dict) - 1;
+			$prepend = "[{$count}/{$default}] ";
+
+			$languages[str_replace('.lang.php', '', basename($file))] = $prepend . $dict['lang'];
+		}
+
+		return $languages;
+	}
+
 
 
 	/**
 	/**
 	 * @param $key
 	 * @param $key
@@ -93,12 +109,16 @@ class Lang
 	 */
 	 */
 	private function getString($key, $lang, $args): string
 	private function getString($key, $lang, $args): string
 	{
 	{
+		$redLang = strtolower(substr($lang, 0, 2));
 
 
 		if (array_key_exists($lang, $this->cache)) {
 		if (array_key_exists($lang, $this->cache)) {
 			$transDict = $this->cache[$lang];
 			$transDict = $this->cache[$lang];
 		} elseif (file_exists(self::$langPath . $lang . '.lang.php')) {
 		} elseif (file_exists(self::$langPath . $lang . '.lang.php')) {
 			$transDict = include self::$langPath . $lang . '.lang.php';
 			$transDict = include self::$langPath . $lang . '.lang.php';
 			$this->cache[$lang] = $transDict;
 			$this->cache[$lang] = $transDict;
+		} elseif (file_exists(self::$langPath . $redLang . '.lang.php')) {
+			$transDict = include self::$langPath . $redLang . '.lang.php';
+			$this->cache[$lang] = $transDict;
 		} else {
 		} else {
 			$transDict = [];
 			$transDict = [];
 		}
 		}

+ 2 - 0
app/routes.php

@@ -11,6 +11,8 @@ $app->group('', function () {
 		$this->get('/system/themes', \App\Controllers\ThemeController::class . ':getThemes')->setName('theme');
 		$this->get('/system/themes', \App\Controllers\ThemeController::class . ':getThemes')->setName('theme');
 		$this->post('/system/theme/apply', \App\Controllers\ThemeController::class . ':applyTheme')->setName('theme.apply');
 		$this->post('/system/theme/apply', \App\Controllers\ThemeController::class . ':applyTheme')->setName('theme.apply');
 
 
+		$this->post('/system/lang/apply', \App\Controllers\AdminController::class . ':applyLang')->setName('lang.apply');
+
 		$this->post('/system/upgrade', \App\Controllers\UpgradeController::class . ':upgrade')->setName('system.upgrade');
 		$this->post('/system/upgrade', \App\Controllers\UpgradeController::class . ':upgrade')->setName('system.upgrade');
 		$this->get('/system/checkForUpdates', \App\Controllers\UpgradeController::class . ':checkForUpdates')->setName('system.checkForUpdates');
 		$this->get('/system/checkForUpdates', \App\Controllers\UpgradeController::class . ':checkForUpdates')->setName('system.checkForUpdates');
 
 

+ 11 - 8
bootstrap/app.php

@@ -105,13 +105,13 @@ $container['storage'] = function ($container) use (&$config) {
 			return new Filesystem(new DropboxAdapter($client), ['case_sensitive' => false]);
 			return new Filesystem(new DropboxAdapter($client), ['case_sensitive' => false]);
 		case 'ftp':
 		case 'ftp':
 			return new Filesystem(new FtpAdapter([
 			return new Filesystem(new FtpAdapter([
-				'host' =>  $config['storage']['host'],
-				'username' =>  $config['storage']['username'],
-				'password' =>  $config['storage']['password'],
-				'port' =>  $config['storage']['port'],
-				'root' =>  $config['storage']['path'],
-				'passive' =>  $config['storage']['passive'],
-				'ssl' =>  $config['storage']['ssl'],
+				'host' => $config['storage']['host'],
+				'username' => $config['storage']['username'],
+				'password' => $config['storage']['password'],
+				'port' => $config['storage']['port'],
+				'root' => $config['storage']['path'],
+				'passive' => $config['storage']['passive'],
+				'ssl' => $config['storage']['ssl'],
 				'timeout' => 30,
 				'timeout' => 30,
 			]));
 			]));
 		case 'google-cloud':
 		case 'google-cloud':
@@ -125,7 +125,10 @@ $container['storage'] = function ($container) use (&$config) {
 	}
 	}
 };
 };
 
 
-$container['lang'] = function ($container) {
+$container['lang'] = function ($container) use (&$config) {
+	if (isset($config['lang'])) {
+		return Lang::build($config['lang'], BASE_DIR . 'resources/lang/');
+	}
 	return Lang::build(Lang::recognize(), BASE_DIR . 'resources/lang/');
 	return Lang::build(Lang::recognize(), BASE_DIR . 'resources/lang/');
 };
 };
 
 

+ 5 - 4
composer.json

@@ -10,13 +10,14 @@
     "league/flysystem": "^1.0.45",
     "league/flysystem": "^1.0.45",
     "monolog/monolog": "^1.23",
     "monolog/monolog": "^1.23",
     "intervention/image": "^2.4",
     "intervention/image": "^2.4",
+    "league/flysystem-aws-s3-v3": "^1.0",
+    "spatie/flysystem-dropbox": "^1.0",
+    "superbalist/flysystem-google-storage": "^7.2",
+    "ext-intl": "*",
     "ext-json": "*",
     "ext-json": "*",
     "ext-gd": "*",
     "ext-gd": "*",
     "ext-pdo": "*",
     "ext-pdo": "*",
-    "ext-zip": "*",
-    "league/flysystem-aws-s3-v3": "^1.0",
-    "spatie/flysystem-dropbox": "^1.0",
-    "superbalist/flysystem-google-storage": "^7.2"
+    "ext-zip": "*"
   },
   },
   "autoload": {
   "autoload": {
     "files": [
     "files": [

+ 176 - 72
composer.lock

@@ -4,20 +4,20 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
         "This file is @generated automatically"
     ],
     ],
-    "content-hash": "d2c8e7bde7729d78cef484491535c639",
+    "content-hash": "b00b4789eb0530c6eb3a5280dae29c86",
     "packages": [
     "packages": [
         {
         {
             "name": "aws/aws-sdk-php",
             "name": "aws/aws-sdk-php",
-            "version": "3.99.2",
+            "version": "3.109.7",
             "source": {
             "source": {
                 "type": "git",
                 "type": "git",
                 "url": "https://github.com/aws/aws-sdk-php.git",
                 "url": "https://github.com/aws/aws-sdk-php.git",
-                "reference": "c3c2877ac7d17125631106c1ee3532e9bf33df53"
+                "reference": "e8d3416f9b1e21029fc0eb63df075e325c690187"
             },
             },
             "dist": {
             "dist": {
                 "type": "zip",
                 "type": "zip",
-                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/c3c2877ac7d17125631106c1ee3532e9bf33df53",
-                "reference": "c3c2877ac7d17125631106c1ee3532e9bf33df53",
+                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/e8d3416f9b1e21029fc0eb63df075e325c690187",
+                "reference": "e8d3416f9b1e21029fc0eb63df075e325c690187",
                 "shasum": ""
                 "shasum": ""
             },
             },
             "require": {
             "require": {
@@ -87,7 +87,7 @@
                 "s3",
                 "s3",
                 "sdk"
                 "sdk"
             ],
             ],
-            "time": "2019-06-05T18:07:37+00:00"
+            "time": "2019-08-19T18:08:45+00:00"
         },
         },
         {
         {
             "name": "container-interop/container-interop",
             "name": "container-interop/container-interop",
@@ -168,16 +168,16 @@
         },
         },
         {
         {
             "name": "google/auth",
             "name": "google/auth",
-            "version": "v1.5.1",
+            "version": "v1.5.2",
             "source": {
             "source": {
                 "type": "git",
                 "type": "git",
                 "url": "https://github.com/googleapis/google-auth-library-php.git",
                 "url": "https://github.com/googleapis/google-auth-library-php.git",
-                "reference": "0f75e20e7392e863f5550ed2c2d3d50af21710fb"
+                "reference": "2ee962e5df3e9427fda859f1b0515d6d62c4afa5"
             },
             },
             "dist": {
             "dist": {
                 "type": "zip",
                 "type": "zip",
-                "url": "https://api.github.com/repos/googleapis/google-auth-library-php/zipball/0f75e20e7392e863f5550ed2c2d3d50af21710fb",
-                "reference": "0f75e20e7392e863f5550ed2c2d3d50af21710fb",
+                "url": "https://api.github.com/repos/googleapis/google-auth-library-php/zipball/2ee962e5df3e9427fda859f1b0515d6d62c4afa5",
+                "reference": "2ee962e5df3e9427fda859f1b0515d6d62c4afa5",
                 "shasum": ""
                 "shasum": ""
             },
             },
             "require": {
             "require": {
@@ -215,20 +215,20 @@
                 "google",
                 "google",
                 "oauth2"
                 "oauth2"
             ],
             ],
-            "time": "2019-04-16T18:48:28+00:00"
+            "time": "2019-07-22T21:01:31+00:00"
         },
         },
         {
         {
             "name": "google/cloud-core",
             "name": "google/cloud-core",
-            "version": "v1.28.0",
+            "version": "v1.31.0",
             "source": {
             "source": {
                 "type": "git",
                 "type": "git",
                 "url": "https://github.com/googleapis/google-cloud-php-core.git",
                 "url": "https://github.com/googleapis/google-cloud-php-core.git",
-                "reference": "d32db261499d28268f9ed97834e7aca829df5b53"
+                "reference": "c7b8890cdab3761e341ecf8f5d7c141aa616978f"
             },
             },
             "dist": {
             "dist": {
                 "type": "zip",
                 "type": "zip",
-                "url": "https://api.github.com/repos/googleapis/google-cloud-php-core/zipball/d32db261499d28268f9ed97834e7aca829df5b53",
-                "reference": "d32db261499d28268f9ed97834e7aca829df5b53",
+                "url": "https://api.github.com/repos/googleapis/google-cloud-php-core/zipball/c7b8890cdab3761e341ecf8f5d7c141aa616978f",
+                "reference": "c7b8890cdab3761e341ecf8f5d7c141aa616978f",
                 "shasum": ""
                 "shasum": ""
             },
             },
             "require": {
             "require": {
@@ -243,7 +243,8 @@
             },
             },
             "require-dev": {
             "require-dev": {
                 "erusev/parsedown": "^1.6",
                 "erusev/parsedown": "^1.6",
-                "google/gax": "^1.0",
+                "google/common-protos": "^1.0",
+                "google/gax": "^1.1",
                 "opis/closure": "^3",
                 "opis/closure": "^3",
                 "phpdocumentor/reflection": "^3.0",
                 "phpdocumentor/reflection": "^3.0",
                 "phpunit/phpunit": "^4.8|^5.0",
                 "phpunit/phpunit": "^4.8|^5.0",
@@ -275,24 +276,25 @@
                 "Apache-2.0"
                 "Apache-2.0"
             ],
             ],
             "description": "Google Cloud PHP shared dependency, providing functionality useful to all components.",
             "description": "Google Cloud PHP shared dependency, providing functionality useful to all components.",
-            "time": "2019-04-16T20:44:33+00:00"
+            "time": "2019-08-07T20:57:43+00:00"
         },
         },
         {
         {
             "name": "google/cloud-storage",
             "name": "google/cloud-storage",
-            "version": "v1.12.1",
+            "version": "v1.14.0",
             "source": {
             "source": {
                 "type": "git",
                 "type": "git",
                 "url": "https://github.com/googleapis/google-cloud-php-storage.git",
                 "url": "https://github.com/googleapis/google-cloud-php-storage.git",
-                "reference": "a252e2012ea875e873b6d146159e54edb8fa4544"
+                "reference": "7315239270318e618f025791b20ac8cc2586ccf0"
             },
             },
             "dist": {
             "dist": {
                 "type": "zip",
                 "type": "zip",
-                "url": "https://api.github.com/repos/googleapis/google-cloud-php-storage/zipball/a252e2012ea875e873b6d146159e54edb8fa4544",
-                "reference": "a252e2012ea875e873b6d146159e54edb8fa4544",
+                "url": "https://api.github.com/repos/googleapis/google-cloud-php-storage/zipball/7315239270318e618f025791b20ac8cc2586ccf0",
+                "reference": "7315239270318e618f025791b20ac8cc2586ccf0",
                 "shasum": ""
                 "shasum": ""
             },
             },
             "require": {
             "require": {
-                "google/cloud-core": "^1.28"
+                "google/cloud-core": "^1.31",
+                "google/crc32": "^0.1.0"
             },
             },
             "require-dev": {
             "require-dev": {
                 "erusev/parsedown": "^1.6",
                 "erusev/parsedown": "^1.6",
@@ -325,7 +327,103 @@
                 "Apache-2.0"
                 "Apache-2.0"
             ],
             ],
             "description": "Cloud Storage Client for PHP",
             "description": "Cloud Storage Client for PHP",
-            "time": "2019-05-02T16:40:15+00:00"
+            "time": "2019-08-07T20:57:43+00:00"
+        },
+        {
+            "name": "google/crc32",
+            "version": "v0.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/google/php-crc32.git",
+                "reference": "a8525f0dea6fca1893e1bae2f6e804c5f7d007fb"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/google/php-crc32/zipball/a8525f0dea6fca1893e1bae2f6e804c5f7d007fb",
+                "reference": "a8525f0dea6fca1893e1bae2f6e804c5f7d007fb",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.4"
+            },
+            "require-dev": {
+                "friendsofphp/php-cs-fixer": "^1.13 || v2.14.2",
+                "paragonie/random_compat": ">=2",
+                "phpunit/phpunit": "^4"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Google\\CRC32\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "Apache-2.0"
+            ],
+            "authors": [
+                {
+                    "name": "Andrew Brampton",
+                    "email": "bramp@google.com"
+                }
+            ],
+            "description": "Various CRC32 implementations",
+            "homepage": "https://github.com/google/php-crc32",
+            "time": "2019-05-09T06:24:58+00:00"
+        },
+        {
+            "name": "graham-campbell/guzzle-factory",
+            "version": "v3.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/GrahamCampbell/Guzzle-Factory.git",
+                "reference": "5953039c541533647110f8c8f48cbc428d51beb1"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/GrahamCampbell/Guzzle-Factory/zipball/5953039c541533647110f8c8f48cbc428d51beb1",
+                "reference": "5953039c541533647110f8c8f48cbc428d51beb1",
+                "shasum": ""
+            },
+            "require": {
+                "guzzlehttp/guzzle": "^6.2",
+                "php": "^7.0"
+            },
+            "require-dev": {
+                "graham-campbell/analyzer": "^2.1",
+                "phpunit/phpunit": "^6.5|^7.0|^8.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.0-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "GrahamCampbell\\GuzzleFactory\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Graham Campbell",
+                    "email": "graham@alt-three.com"
+                }
+            ],
+            "description": "Provides A Simple Guzzle Factory With Good Defaults",
+            "keywords": [
+                "Graham Campbell",
+                "GrahamCampbell",
+                "Guzzle",
+                "Guzzle Factory",
+                "Guzzle-Factory",
+                "http"
+            ],
+            "time": "2019-06-30T12:48:08+00:00"
         },
         },
         {
         {
             "name": "guzzlehttp/guzzle",
             "name": "guzzlehttp/guzzle",
@@ -445,33 +543,37 @@
         },
         },
         {
         {
             "name": "guzzlehttp/psr7",
             "name": "guzzlehttp/psr7",
-            "version": "1.5.2",
+            "version": "1.6.1",
             "source": {
             "source": {
                 "type": "git",
                 "type": "git",
                 "url": "https://github.com/guzzle/psr7.git",
                 "url": "https://github.com/guzzle/psr7.git",
-                "reference": "9f83dded91781a01c63574e387eaa769be769115"
+                "reference": "239400de7a173fe9901b9ac7c06497751f00727a"
             },
             },
             "dist": {
             "dist": {
                 "type": "zip",
                 "type": "zip",
-                "url": "https://api.github.com/repos/guzzle/psr7/zipball/9f83dded91781a01c63574e387eaa769be769115",
-                "reference": "9f83dded91781a01c63574e387eaa769be769115",
+                "url": "https://api.github.com/repos/guzzle/psr7/zipball/239400de7a173fe9901b9ac7c06497751f00727a",
+                "reference": "239400de7a173fe9901b9ac7c06497751f00727a",
                 "shasum": ""
                 "shasum": ""
             },
             },
             "require": {
             "require": {
                 "php": ">=5.4.0",
                 "php": ">=5.4.0",
                 "psr/http-message": "~1.0",
                 "psr/http-message": "~1.0",
-                "ralouphie/getallheaders": "^2.0.5"
+                "ralouphie/getallheaders": "^2.0.5 || ^3.0.0"
             },
             },
             "provide": {
             "provide": {
                 "psr/http-message-implementation": "1.0"
                 "psr/http-message-implementation": "1.0"
             },
             },
             "require-dev": {
             "require-dev": {
+                "ext-zlib": "*",
                 "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8"
                 "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8"
             },
             },
+            "suggest": {
+                "zendframework/zend-httphandlerrunner": "Emit PSR-7 responses"
+            },
             "type": "library",
             "type": "library",
             "extra": {
             "extra": {
                 "branch-alias": {
                 "branch-alias": {
-                    "dev-master": "1.5-dev"
+                    "dev-master": "1.6-dev"
                 }
                 }
             },
             },
             "autoload": {
             "autoload": {
@@ -508,7 +610,7 @@
                 "uri",
                 "uri",
                 "url"
                 "url"
             ],
             ],
-            "time": "2018-12-04T20:46:45+00:00"
+            "time": "2019-07-01T23:21:34+00:00"
         },
         },
         {
         {
             "name": "intervention/image",
             "name": "intervention/image",
@@ -1134,24 +1236,24 @@
         },
         },
         {
         {
             "name": "ralouphie/getallheaders",
             "name": "ralouphie/getallheaders",
-            "version": "2.0.5",
+            "version": "3.0.3",
             "source": {
             "source": {
                 "type": "git",
                 "type": "git",
                 "url": "https://github.com/ralouphie/getallheaders.git",
                 "url": "https://github.com/ralouphie/getallheaders.git",
-                "reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa"
+                "reference": "120b605dfeb996808c31b6477290a714d356e822"
             },
             },
             "dist": {
             "dist": {
                 "type": "zip",
                 "type": "zip",
-                "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/5601c8a83fbba7ef674a7369456d12f1e0d0eafa",
-                "reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa",
+                "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
+                "reference": "120b605dfeb996808c31b6477290a714d356e822",
                 "shasum": ""
                 "shasum": ""
             },
             },
             "require": {
             "require": {
-                "php": ">=5.3"
+                "php": ">=5.6"
             },
             },
             "require-dev": {
             "require-dev": {
-                "phpunit/phpunit": "~3.7.0",
-                "satooshi/php-coveralls": ">=1.0"
+                "php-coveralls/php-coveralls": "^2.1",
+                "phpunit/phpunit": "^5 || ^6.5"
             },
             },
             "type": "library",
             "type": "library",
             "autoload": {
             "autoload": {
@@ -1170,7 +1272,7 @@
                 }
                 }
             ],
             ],
             "description": "A polyfill for getallheaders.",
             "description": "A polyfill for getallheaders.",
-            "time": "2016-02-11T07:05:27+00:00"
+            "time": "2019-03-08T08:55:37+00:00"
         },
         },
         {
         {
             "name": "rize/uri-template",
             "name": "rize/uri-template",
@@ -1340,19 +1442,20 @@
         },
         },
         {
         {
             "name": "spatie/dropbox-api",
             "name": "spatie/dropbox-api",
-            "version": "1.9.0",
+            "version": "1.11.0",
             "source": {
             "source": {
                 "type": "git",
                 "type": "git",
                 "url": "https://github.com/spatie/dropbox-api.git",
                 "url": "https://github.com/spatie/dropbox-api.git",
-                "reference": "72a7c833ada88b8eb0af7cc1c561e02b0c9a5987"
+                "reference": "47c6a14bcdc639ba90f86f98b2ada38ac9cc8e30"
             },
             },
             "dist": {
             "dist": {
                 "type": "zip",
                 "type": "zip",
-                "url": "https://api.github.com/repos/spatie/dropbox-api/zipball/72a7c833ada88b8eb0af7cc1c561e02b0c9a5987",
-                "reference": "72a7c833ada88b8eb0af7cc1c561e02b0c9a5987",
+                "url": "https://api.github.com/repos/spatie/dropbox-api/zipball/47c6a14bcdc639ba90f86f98b2ada38ac9cc8e30",
+                "reference": "47c6a14bcdc639ba90f86f98b2ada38ac9cc8e30",
                 "shasum": ""
                 "shasum": ""
             },
             },
             "require": {
             "require": {
+                "graham-campbell/guzzle-factory": "^3.0",
                 "guzzlehttp/guzzle": "^6.2",
                 "guzzlehttp/guzzle": "^6.2",
                 "php": "^7.1"
                 "php": "^7.1"
             },
             },
@@ -1372,15 +1475,15 @@
             "authors": [
             "authors": [
                 {
                 {
                     "name": "Freek Van der Herten",
                     "name": "Freek Van der Herten",
+                    "role": "Developer",
                     "email": "freek@spatie.be",
                     "email": "freek@spatie.be",
-                    "homepage": "https://spatie.be",
-                    "role": "Developer"
+                    "homepage": "https://spatie.be"
                 },
                 },
                 {
                 {
                     "name": "Alex Vanderbist",
                     "name": "Alex Vanderbist",
+                    "role": "Developer",
                     "email": "alex.vanderbist@gmail.com",
                     "email": "alex.vanderbist@gmail.com",
-                    "homepage": "https://spatie.be",
-                    "role": "Developer"
+                    "homepage": "https://spatie.be"
                 }
                 }
             ],
             ],
             "description": "A minimal implementation of Dropbox API v2",
             "description": "A minimal implementation of Dropbox API v2",
@@ -1392,7 +1495,7 @@
                 "spatie",
                 "spatie",
                 "v2"
                 "v2"
             ],
             ],
-            "time": "2019-05-21T12:13:37+00:00"
+            "time": "2019-07-04T19:04:14+00:00"
         },
         },
         {
         {
             "name": "spatie/flysystem-dropbox",
             "name": "spatie/flysystem-dropbox",
@@ -1429,9 +1532,9 @@
             "authors": [
             "authors": [
                 {
                 {
                     "name": "Alex Vanderbist",
                     "name": "Alex Vanderbist",
+                    "role": "Developer",
                     "email": "alex.vanderbist@gmail.com",
                     "email": "alex.vanderbist@gmail.com",
-                    "homepage": "https://spatie.be",
-                    "role": "Developer"
+                    "homepage": "https://spatie.be"
                 }
                 }
             ],
             ],
             "description": "Flysystem Adapter for the Dropbox v2 API",
             "description": "Flysystem Adapter for the Dropbox v2 API",
@@ -1495,16 +1598,16 @@
         },
         },
         {
         {
             "name": "symfony/polyfill-ctype",
             "name": "symfony/polyfill-ctype",
-            "version": "v1.11.0",
+            "version": "v1.12.0",
             "source": {
             "source": {
                 "type": "git",
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-ctype.git",
                 "url": "https://github.com/symfony/polyfill-ctype.git",
-                "reference": "82ebae02209c21113908c229e9883c419720738a"
+                "reference": "550ebaac289296ce228a706d0867afc34687e3f4"
             },
             },
             "dist": {
             "dist": {
                 "type": "zip",
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/82ebae02209c21113908c229e9883c419720738a",
-                "reference": "82ebae02209c21113908c229e9883c419720738a",
+                "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/550ebaac289296ce228a706d0867afc34687e3f4",
+                "reference": "550ebaac289296ce228a706d0867afc34687e3f4",
                 "shasum": ""
                 "shasum": ""
             },
             },
             "require": {
             "require": {
@@ -1516,7 +1619,7 @@
             "type": "library",
             "type": "library",
             "extra": {
             "extra": {
                 "branch-alias": {
                 "branch-alias": {
-                    "dev-master": "1.11-dev"
+                    "dev-master": "1.12-dev"
                 }
                 }
             },
             },
             "autoload": {
             "autoload": {
@@ -1533,12 +1636,12 @@
             ],
             ],
             "authors": [
             "authors": [
                 {
                 {
-                    "name": "Symfony Community",
-                    "homepage": "https://symfony.com/contributors"
+                    "name": "Gert de Pagter",
+                    "email": "BackEndTea@gmail.com"
                 },
                 },
                 {
                 {
-                    "name": "Gert de Pagter",
-                    "email": "backendtea@gmail.com"
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
                 }
                 }
             ],
             ],
             "description": "Symfony polyfill for ctype functions",
             "description": "Symfony polyfill for ctype functions",
@@ -1549,7 +1652,7 @@
                 "polyfill",
                 "polyfill",
                 "portable"
                 "portable"
             ],
             ],
-            "time": "2019-02-06T07:57:58+00:00"
+            "time": "2019-08-06T08:03:45+00:00"
         },
         },
         {
         {
             "name": "symfony/polyfill-mbstring",
             "name": "symfony/polyfill-mbstring",
@@ -1612,16 +1715,16 @@
         },
         },
         {
         {
             "name": "twig/twig",
             "name": "twig/twig",
-            "version": "v2.10.0",
+            "version": "v2.11.3",
             "source": {
             "source": {
                 "type": "git",
                 "type": "git",
                 "url": "https://github.com/twigphp/Twig.git",
                 "url": "https://github.com/twigphp/Twig.git",
-                "reference": "5240e21982885b76629552d83b4ebb6d41ccde6b"
+                "reference": "699ed2342557c88789a15402de5eb834dedd6792"
             },
             },
             "dist": {
             "dist": {
                 "type": "zip",
                 "type": "zip",
-                "url": "https://api.github.com/repos/twigphp/Twig/zipball/5240e21982885b76629552d83b4ebb6d41ccde6b",
-                "reference": "5240e21982885b76629552d83b4ebb6d41ccde6b",
+                "url": "https://api.github.com/repos/twigphp/Twig/zipball/699ed2342557c88789a15402de5eb834dedd6792",
+                "reference": "699ed2342557c88789a15402de5eb834dedd6792",
                 "shasum": ""
                 "shasum": ""
             },
             },
             "require": {
             "require": {
@@ -1632,12 +1735,12 @@
             "require-dev": {
             "require-dev": {
                 "psr/container": "^1.0",
                 "psr/container": "^1.0",
                 "symfony/debug": "^2.7",
                 "symfony/debug": "^2.7",
-                "symfony/phpunit-bridge": "^3.4.19|^4.1.8"
+                "symfony/phpunit-bridge": "^3.4.19|^4.1.8|^5.0"
             },
             },
             "type": "library",
             "type": "library",
             "extra": {
             "extra": {
                 "branch-alias": {
                 "branch-alias": {
-                    "dev-master": "2.10-dev"
+                    "dev-master": "2.11-dev"
                 }
                 }
             },
             },
             "autoload": {
             "autoload": {
@@ -1655,19 +1758,19 @@
             "authors": [
             "authors": [
                 {
                 {
                     "name": "Fabien Potencier",
                     "name": "Fabien Potencier",
+                    "role": "Lead Developer",
                     "email": "fabien@symfony.com",
                     "email": "fabien@symfony.com",
-                    "homepage": "http://fabien.potencier.org",
-                    "role": "Lead Developer"
+                    "homepage": "http://fabien.potencier.org"
                 },
                 },
                 {
                 {
                     "name": "Armin Ronacher",
                     "name": "Armin Ronacher",
-                    "email": "armin.ronacher@active-4.com",
-                    "role": "Project Founder"
+                    "role": "Project Founder",
+                    "email": "armin.ronacher@active-4.com"
                 },
                 },
                 {
                 {
                     "name": "Twig Team",
                     "name": "Twig Team",
-                    "homepage": "https://twig.symfony.com/contributors",
-                    "role": "Contributors"
+                    "role": "Contributors",
+                    "homepage": "https://twig.symfony.com/contributors"
                 }
                 }
             ],
             ],
             "description": "Twig, the flexible, fast, and secure template language for PHP",
             "description": "Twig, the flexible, fast, and secure template language for PHP",
@@ -1675,7 +1778,7 @@
             "keywords": [
             "keywords": [
                 "templating"
                 "templating"
             ],
             ],
-            "time": "2019-05-14T12:03:52+00:00"
+            "time": "2019-06-18T15:37:11+00:00"
         }
         }
     ],
     ],
     "packages-dev": [
     "packages-dev": [
@@ -2768,6 +2871,7 @@
     "prefer-lowest": false,
     "prefer-lowest": false,
     "platform": {
     "platform": {
         "php": ">=7.1",
         "php": ">=7.1",
+        "ext-intl": "*",
         "ext-json": "*",
         "ext-json": "*",
         "ext-gd": "*",
         "ext-gd": "*",
         "ext-pdo": "*",
         "ext-pdo": "*",

+ 9 - 1
install/index.php

@@ -260,6 +260,14 @@ $app->post('/', function (Request $request, Response $response) use (&$config) {
 		}
 		}
 	}
 	}
 
 
+	// if from older installations with no support of other than local driver
+	// update the config
+	if ($installed && isset($config['storage_dir'])) {
+		$config['storage']['driver'] = 'local';
+		$config['storage']['path'] = $config['storage_dir'];
+		unset($config['storage_dir']);
+	}
+
 
 
 	// Build the dns string and run the migrations
 	// Build the dns string and run the migrations
 	try {
 	try {
@@ -282,7 +290,7 @@ $app->post('/', function (Request $request, Response $response) use (&$config) {
 	cleanDirectory(__DIR__ . '/../resources/cache');
 	cleanDirectory(__DIR__ . '/../resources/cache');
 	cleanDirectory(__DIR__ . '/../resources/sessions');
 	cleanDirectory(__DIR__ . '/../resources/sessions');
 
 
-	//removeDirectory(__DIR__ . '/../install');
+	removeDirectory(__DIR__ . '/../install');
 
 
 	// if is upgrading and existing installation, put it out maintenance
 	// if is upgrading and existing installation, put it out maintenance
 	if ($installed) {
 	if ($installed) {

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 455 - 68
package-lock.json


+ 7 - 0
resources/lang/en.lang.php

@@ -2,6 +2,7 @@
 
 
 return [
 return [
 	'lang' => 'English',
 	'lang' => 'English',
+	'enforce_language' => 'Enforce language',
 	'yes' => 'Yes',
 	'yes' => 'Yes',
 	'no' => 'No',
 	'no' => 'No',
 	'send' => 'Send',
 	'send' => 'Send',
@@ -95,4 +96,10 @@ return [
 	'updates' => 'Updates',
 	'updates' => 'Updates',
 	'maintenance_in_progress' => 'Platform under maintenance, try again later...',
 	'maintenance_in_progress' => 'Platform under maintenance, try again later...',
 	'cancel' => 'Cancel',
 	'cancel' => 'Cancel',
+	'auto_set' => 'Set automatically',
+	'translated_strings' => 'translated strings',
+	'total_strings' => 'total strings',
+	'lang_name' => 'language name',
+	'default_lang_behavior' => 'By default, it XBackbone will try to match the browser language (fallback is english).',
+	'lang_set' => 'System language enforced to "%s"',
 ];
 ];

+ 26 - 1
resources/templates/dashboard/system.twig

@@ -75,8 +75,33 @@
                         </form>
                         </form>
                     </div>
                     </div>
                 </div>
                 </div>
+                <div class="card shadow-sm mb-3">
+                    <div class="card-header"><i class="fas fa-language fa-fw"></i> {{ lang('enforce_language') }}</div>
+                    <div class="card-body">
+                        <form method="post" action="{{ route('lang.apply') }}">
+                            <div class="form-group row">
+                                <div class="col-sm-12">
+                                    <select class="form-control" id="lang" name="lang">
+                                        <option value="auto" selected>({{ lang('auto_set') }})</option>
+                                        {% for lang, name in installed_lang %}
+                                            <option value="{{ lang }}">{{ name }}</option>
+                                        {% endfor %}
+                                    </select>
+                                    <small>[{{ lang('translated_strings') }} / {{ lang('total_strings') }}] {{ lang('lang_name') }}. {{ lang('default_lang_behavior') }}</small>
+                                </div>
+                            </div>
+                            <div class="form-group row">
+                                <div class="col-sm-12">
+                                    <button type="submit" class="btn btn-outline-success" id="lang-apply">
+                                        <i class="fas fa-save fa-fw"></i> {{ lang('apply') }}
+                                    </button>
+                                </div>
+                            </div>
+                        </form>
+                    </div>
+                </div>
                 <div class="card shadow-sm">
                 <div class="card shadow-sm">
-                    <div class="card-header"><i class="fas fa-cloud-download-alt fa-fw"></i> {{ lang('updates') }} <b>[BETA]</b></div>
+                    <div class="card-header"><i class="fas fa-cloud-download-alt fa-fw"></i> {{ lang('updates') }} <b>[BETA]</b> <span class="float-right">v{{ PLATFORM_VERSION }}</span></div>
                     <div class="card-body">
                     <div class="card-body">
                         <div class="row">
                         <div class="row">
                             <div class="col">
                             <div class="col">

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác