From 460aca5b013d5c50aeed4f208ef8ea967d69fe9e Mon Sep 17 00:00:00 2001 From: Ben Thomson Date: Fri, 10 Apr 2020 01:50:00 +0800 Subject: [PATCH 01/13] Reset outline to default - roll back #4895 (#5035) Replaces #4965. Rolls back #4895. Fixes #4964. Partially fixes #4819. The previous attempts to add a stylised "focus" ring, while with the best intentions, did not take into account how "outline" normally works for people using visual aids. Most high contrast software will effect the outline if its available (ie. make it bolder or more prevalant), thus the "outline" property is paramount to maintaining accessibility. The previous changes also present issues with elements using box-shadows already, and again, on high contrast, box-shadows are no longer rendered. This change will bring back the outline property for focus, but with an addition to allow a blue highlight for Firefox, would should keep it in "parity" with WebKit. Refs: - https://a11yproject.com/posts/never-remove-css-outlines/ - http://www.outlinenone.com - https://stackoverflow.com/questions/52589391/css-box-shadow-vs-outline --- modules/backend/assets/css/october.css | 4 ++-- modules/backend/assets/less/layout/mainmenu.less | 1 - modules/system/assets/css/styles.css | 2 +- .../system/assets/ui/less/global.mixins.utility.css | 0 .../system/assets/ui/less/global.mixins.utility.less | 9 ++++++--- modules/system/assets/ui/less/site.normalize.less | 10 ---------- modules/system/assets/ui/storm.css | 7 +++---- 7 files changed, 12 insertions(+), 21 deletions(-) create mode 100644 modules/system/assets/ui/less/global.mixins.utility.css diff --git a/modules/backend/assets/css/october.css b/modules/backend/assets/css/october.css index cfe543c40..53e7ed673 100644 --- a/modules/backend/assets/css/october.css +++ b/modules/backend/assets/css/october.css @@ -664,7 +664,7 @@ nav#layout-mainmenu a {text-decoration:none} nav#layout-mainmenu a:focus {background:transparent} nav#layout-mainmenu ul {margin:0;padding:0;list-style:none;float:left;white-space:nowrap;overflow:hidden} nav#layout-mainmenu ul li {color:rgba(255,255,255,0.6);display:inline-block;vertical-align:top;position:relative;margin-right:30px} -nav#layout-mainmenu ul li a {display:inline-block;font-size:14px;color:inherit;outline:none;padding:14px 0 10px} +nav#layout-mainmenu ul li a {display:inline-block;font-size:14px;color:inherit;padding:14px 0 10px} nav#layout-mainmenu ul li a:hover {background-color:transparent} nav#layout-mainmenu ul li a:active, nav#layout-mainmenu ul li a:focus {text-decoration:none;color:rgba(255,255,255,0.6)} @@ -771,7 +771,7 @@ nav#layout-mainmenu.navbar-mode-collapse .menu-toggle {display:inline-block;colo .mainmenu-collapsed >div ul.mainmenu-nav li:first-child {margin-left:0} .mainmenu-collapsed >div ul {margin:0;padding:5px 0 15px 15px;overflow:hidden} .mainmenu-collapsed >div ul li {color:rgba(255,255,255,0.6);display:inline-block;vertical-align:top;position:relative;margin-right:30px} -.mainmenu-collapsed >div ul li a {display:inline-block;font-size:14px;color:inherit;outline:none} +.mainmenu-collapsed >div ul li a {display:inline-block;font-size:14px;color:inherit} .mainmenu-collapsed >div ul li a:hover {background-color:transparent} .mainmenu-collapsed >div ul li a:active, .mainmenu-collapsed >div ul li a:focus {text-decoration:none;color:rgba(255,255,255,0.6)} diff --git a/modules/backend/assets/less/layout/mainmenu.less b/modules/backend/assets/less/layout/mainmenu.less index 4e399cf44..5d3492c26 100644 --- a/modules/backend/assets/less/layout/mainmenu.less +++ b/modules/backend/assets/less/layout/mainmenu.less @@ -20,7 +20,6 @@ body.mainmenu-open { display: inline-block; font-size: @font-size-base; color: inherit; - outline: none; &:hover { background-color: transparent; diff --git a/modules/system/assets/css/styles.css b/modules/system/assets/css/styles.css index f65f3bc8f..11318749e 100644 --- a/modules/system/assets/css/styles.css +++ b/modules/system/assets/css/styles.css @@ -89,7 +89,7 @@ textarea {background-image:none} a {color:#0181b9;text-decoration:none} a:hover, a:focus {color:#001721;text-decoration:underline} -a:focus {outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px} +a:focus {outline:thin dotted;outline-offset:0;outline:4px auto Highlight;outline:4px auto -webkit-focus-ring-color} img {vertical-align:middle} .img-responsive {display:block;max-width:100%;height:auto} .img-rounded {-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px} diff --git a/modules/system/assets/ui/less/global.mixins.utility.css b/modules/system/assets/ui/less/global.mixins.utility.css new file mode 100644 index 000000000..e69de29bb diff --git a/modules/system/assets/ui/less/global.mixins.utility.less b/modules/system/assets/ui/less/global.mixins.utility.less index e767d5113..4da6c82f1 100644 --- a/modules/system/assets/ui/less/global.mixins.utility.less +++ b/modules/system/assets/ui/less/global.mixins.utility.less @@ -26,9 +26,12 @@ .tab-focus() { // Default outline: thin dotted; + outline-offset: 0px; + + // Firefox + outline: 4px auto Highlight; // WebKit - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; + outline: 4px auto -webkit-focus-ring-color; } // Center-align a block level element @@ -128,4 +131,4 @@ .responsive-invisibility() { display: none !important; -} \ No newline at end of file +} diff --git a/modules/system/assets/ui/less/site.normalize.less b/modules/system/assets/ui/less/site.normalize.less index 5cda25032..d40b1a822 100644 --- a/modules/system/assets/ui/less/site.normalize.less +++ b/modules/system/assets/ui/less/site.normalize.less @@ -1,13 +1,3 @@ -/*! Make focus ring standard on every browser */ - -// See github issue https://github.com/octobercms/october/issues/4892 - -&:focus { - outline: none; - -webkit-box-shadow: inset 0 1px 2px rgba(27,31,35,.075), 0 0 0 0.2em rgba(3,102,214,.3); - box-shadow: inset 0 1px 2px rgba(27,31,35,.075), 0 0 0 0.2em rgba(3,102,214,.3); -} - /*! normalize.css v3.0.0 | MIT License | git.io/normalize */ // diff --git a/modules/system/assets/ui/storm.css b/modules/system/assets/ui/storm.css index c52bc7218..50a4f7c2e 100644 --- a/modules/system/assets/ui/storm.css +++ b/modules/system/assets/ui/storm.css @@ -1,4 +1,3 @@ -:focus {outline:none;-webkit-box-shadow:inset 0 1px 2px rgba(27,31,35,.075),0 0 0 .2em rgba(3,102,214,.3);box-shadow:inset 0 1px 2px rgba(27,31,35,.075),0 0 0 .2em rgba(3,102,214,.3)} html {font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%} body {margin:0} article, @@ -90,7 +89,7 @@ textarea {background-image:none} a {color:#0181b9;text-decoration:none} a:hover, a:focus {color:#001721;text-decoration:underline} -a:focus {outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px} +a:focus {outline:thin dotted;outline-offset:0;outline:4px auto Highlight;outline:4px auto -webkit-focus-ring-color} img {vertical-align:middle} .img-responsive {display:block;max-width:100%;height:auto} .img-rounded {-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px} @@ -467,7 +466,7 @@ address {margin-bottom:20px;font-style:normal;line-height:1.42857143} .btn {display:inline-block;margin-bottom:0;font-weight:normal;text-align:center;vertical-align:middle;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:8px 19.5px;font-size:14px;line-height:1.42857143;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none} .btn:focus, .btn:active:focus, -.btn.active:focus {outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px} +.btn.active:focus {outline:thin dotted;outline-offset:0;outline:4px auto Highlight;outline:4px auto -webkit-focus-ring-color} .btn:hover, .btn:focus {color:#fff;text-decoration:none} .btn:active, @@ -3690,7 +3689,7 @@ select[multiple], select[size] {height:auto} input[type="file"]:focus, input[type="radio"]:focus, -input[type="checkbox"]:focus {outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px} +input[type="checkbox"]:focus {outline:thin dotted;outline-offset:0;outline:4px auto Highlight;outline:4px auto -webkit-focus-ring-color} output {display:block;padding-top:9px;font-size:14px;line-height:1.42857143;color:#385487} .form-control {display:block;width:100%;height:38px;padding:8px 13px 9px;font-size:14px;line-height:1.42857143;color:#385487;background-color:#fff;background-image:none;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-transition:border-color ease-in-out 0.15s,box-shadow ease-in-out 0.15s;transition:border-color ease-in-out 0.15s,box-shadow ease-in-out 0.15s} .form-control:focus {border-color:#d1d6d9;outline:0} From d69ade86d183873ec1f2b5bfb2b9d4ac9203fdda Mon Sep 17 00:00:00 2001 From: Mike Robinson Date: Thu, 9 Apr 2020 14:24:51 -0600 Subject: [PATCH 02/13] Validate backend forms client-side (#4804) Fixes #4799. --- modules/backend/classes/FormField.php | 9 +++++++++ modules/system/assets/js/framework.js | 13 ++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/modules/backend/classes/FormField.php b/modules/backend/classes/FormField.php index 5f52b5c23..f2b6efc68 100644 --- a/modules/backend/classes/FormField.php +++ b/modules/backend/classes/FormField.php @@ -425,6 +425,15 @@ class FormField $result = array_get($this->attributes, $position, []); $result = $this->filterAttributes($result, $position); + // Field is required, so add the "required" attribute + if ($position === 'field' && $this->required && (!isset($result['required']) || $result['required'])) { + $result['required'] = ''; + } + // The "required" attribute is set and falsy, so unset it + elseif ($position === 'field' && isset($result['required']) && !$result['required']) { + unset($result['required']); + } + return $htmlBuild ? Html::attributes($result) : $result; } diff --git a/modules/system/assets/js/framework.js b/modules/system/assets/js/framework.js index 39bc3e89c..160a4321a 100644 --- a/modules/system/assets/js/framework.js +++ b/modules/system/assets/js/framework.js @@ -30,12 +30,23 @@ if (window.jQuery.request !== undefined) { } /* - * Prepare the options and execute the request + * Prepare the options */ var $form = options.form ? $(options.form) : $el.closest('form'), $triggerEl = !!$form.length ? $form : $el, context = { handler: handler, options: options } + /* + * Validate the form client-side + */ + if (typeof document.createElement('input').reportValidity == 'function' && $form && $form[0] && !$form[0].checkValidity()) { + $form[0].reportValidity(); + return false; + } + + /* + * Execute the request + */ $el.trigger('ajaxSetup', [context]) var _event = jQuery.Event('oc.beforeRequest') $triggerEl.trigger(_event, context) From b4c65e9febb881232bb8d1418e0f7998b3575ebf Mon Sep 17 00:00:00 2001 From: Kallef Alexandre Date: Sat, 11 Apr 2020 12:46:22 -0300 Subject: [PATCH 03/13] Added plugin:rollback command (#4389) --- modules/system/ServiceProvider.php | 1 + modules/system/classes/UpdateManager.php | 101 +++++++------- modules/system/classes/VersionManager.php | 155 ++++++++++++++++------ modules/system/console/PluginRollback.php | 88 ++++++++++++ modules/system/lang/en/lang.php | 1 + modules/system/lang/pt-br/lang.php | 2 +- 6 files changed, 259 insertions(+), 89 deletions(-) create mode 100644 modules/system/console/PluginRollback.php diff --git a/modules/system/ServiceProvider.php b/modules/system/ServiceProvider.php index 43aa516e1..9fc858f39 100644 --- a/modules/system/ServiceProvider.php +++ b/modules/system/ServiceProvider.php @@ -253,6 +253,7 @@ class ServiceProvider extends ModuleServiceProvider $this->registerConsoleCommand('plugin.disable', 'System\Console\PluginDisable'); $this->registerConsoleCommand('plugin.enable', 'System\Console\PluginEnable'); $this->registerConsoleCommand('plugin.refresh', 'System\Console\PluginRefresh'); + $this->registerConsoleCommand('plugin.rollback', 'System\Console\PluginRollback'); $this->registerConsoleCommand('plugin.list', 'System\Console\PluginList'); $this->registerConsoleCommand('theme.install', 'System\Console\ThemeInstall'); diff --git a/modules/system/classes/UpdateManager.php b/modules/system/classes/UpdateManager.php index 0aed46961..7e4779de1 100644 --- a/modules/system/classes/UpdateManager.php +++ b/modules/system/classes/UpdateManager.php @@ -50,17 +50,17 @@ class UpdateManager protected $tempDirectory; /** - * @var System\Classes\PluginManager + * @var \System\Classes\PluginManager */ protected $pluginManager; /** - * @var Cms\Classes\ThemeManager + * @var \Cms\Classes\ThemeManager */ protected $themeManager; /** - * @var System\Classes\VersionManager + * @var \System\Classes\VersionManager */ protected $versionManager; @@ -85,12 +85,12 @@ class UpdateManager protected $productCache; /** - * @var Illuminate\Database\Migrations\Migrator + * @var \Illuminate\Database\Migrations\Migrator */ protected $migrator; /** - * @var Illuminate\Database\Migrations\DatabaseMigrationRepository + * @var \Illuminate\Database\Migrations\DatabaseMigrationRepository */ protected $repository; @@ -173,7 +173,7 @@ class UpdateManager /** * Checks for new updates and returns the amount of unapplied updates. * Only requests from the server at a set interval (retry timer). - * @param boolean $force Ignore the retry timer. + * @param boolean $force Ignore the retry timer. * @return int Number of unapplied updates. */ public function check($force = false) @@ -199,8 +199,7 @@ class UpdateManager try { $result = $this->requestUpdateList(); $newCount = array_get($result, 'update', 0); - } - catch (Exception $ex) { + } catch (Exception $ex) { $newCount = 0; } @@ -215,7 +214,7 @@ class UpdateManager /** * Requests an update list used for checking for new updates. - * @param boolean $force Request application and plugins hash list regardless of version. + * @param boolean $force Request application and plugins hash list regardless of version. * @return array */ public function requestUpdateList($force = false) @@ -234,11 +233,11 @@ class UpdateManager } $params = [ - 'core' => $this->getHash(), + 'core' => $this->getHash(), 'plugins' => serialize($versions), - 'themes' => serialize($themes), - 'build' => $build, - 'force' => $force + 'themes' => serialize($themes), + 'build' => $build, + 'force' => $force ]; $result = $this->requestServerData('core/update', $params); @@ -270,8 +269,7 @@ class UpdateManager (isset($updatable[$code]) && !$updatable[$code]) ) { $updateCount = max(0, --$updateCount); - } - else { + } else { $plugins[$code] = $info; } } @@ -312,7 +310,7 @@ class UpdateManager /** * Requests details about a project based on its identifier. - * @param string $projectId + * @param string $projectId * @return array */ public function requestProjectDetails($projectId) @@ -341,7 +339,7 @@ class UpdateManager $modules = Config::get('cms.loadModules', []); foreach ($modules as $module) { - $paths[] = $path = base_path() . '/modules/'.strtolower($module).'/database/migrations'; + $paths[] = $path = base_path() . '/modules/' . strtolower($module) . '/database/migrations'; } /* @@ -405,12 +403,12 @@ class UpdateManager */ public function migrateModule($module) { - $this->migrator->run(base_path() . '/modules/'.strtolower($module).'/database/migrations'); + $this->migrator->run(base_path() . '/modules/' . strtolower($module) . '/database/migrations'); $this->note($module); foreach ($this->migrator->getNotes() as $note) { - $this->note(' - '.$note); + $this->note(' - ' . $note); } return $this; @@ -423,7 +421,7 @@ class UpdateManager */ public function seedModule($module) { - $className = '\\'.$module.'\Database\Seeds\DatabaseSeeder'; + $className = '\\' . $module . '\Database\Seeds\DatabaseSeeder'; if (!class_exists($className)) { return; } @@ -532,11 +530,13 @@ class UpdateManager } /** - * Removes an existing plugin + * Rollback an existing plugin + * * @param string $name Plugin name. + * @param string $stopOnVersion If this parameter is specified, the process stops once the provided version number is reached * @return self */ - public function rollbackPlugin($name) + public function rollbackPlugin(string $name, string $stopOnVersion = null) { /* * Remove the plugin database and version @@ -548,8 +548,17 @@ class UpdateManager return $this; } - if ($this->versionManager->removePlugin($plugin)) { + if ($stopOnVersion && !$this->versionManager->hasDatabaseVersion($plugin, $stopOnVersion)) { + throw new ApplicationException(Lang::get('system::lang.updates.plugin_version_not_found')); + } + + if ($this->versionManager->removePlugin($plugin, $stopOnVersion, true)) { $this->note('Rolled back: ' . $name); + + if ($currentVersion = $this->versionManager->getCurrentVersion($plugin)) { + $this->note('Current Version: ' . $currentVersion . ' (' . $this->versionManager->getCurrentVersionNote($plugin) . ')'); + } + return $this; } @@ -569,7 +578,7 @@ class UpdateManager { $fileCode = $name . $hash; $this->requestServerFile('plugin/get', $fileCode, $hash, [ - 'name' => $name, + 'name' => $name, 'installation' => $installation ? 1 : 0 ]); } @@ -654,7 +663,7 @@ class UpdateManager $newCodes = array_diff($codes, array_keys($this->productCache[$type])); if (count($newCodes)) { $dataCodes = []; - $data = $this->requestServerData($type.'/details', ['names' => $newCodes]); + $data = $this->requestServerData($type . '/details', ['names' => $newCodes]); foreach ($data as $product) { $code = array_get($product, 'code', -1); $this->cacheProductDetail($type, $code, $product); @@ -697,13 +706,13 @@ class UpdateManager $type = 'plugin'; } - $cacheKey = 'system-updates-popular-'.$type; + $cacheKey = 'system-updates-popular-' . $type; if (Cache::has($cacheKey)) { return @unserialize(@base64_decode(Cache::get($cacheKey))) ?: []; } - $data = $this->requestServerData($type.'/popular'); + $data = $this->requestServerData($type . '/popular'); Cache::put($cacheKey, base64_encode(serialize($data)), 60); foreach ($data as $product) { @@ -723,8 +732,7 @@ class UpdateManager if (Cache::has($cacheKey)) { $this->productCache = @unserialize(@base64_decode(Cache::get($cacheKey))) ?: $defaultCache; - } - else { + } else { $this->productCache = $defaultCache; } } @@ -774,8 +782,7 @@ class UpdateManager try { $resultData = json_decode($result->body, true); - } - catch (Exception $ex) { + } catch (Exception $ex) { throw new ApplicationException(Lang::get('system::lang.server.response_invalid')); } @@ -788,15 +795,14 @@ class UpdateManager /** * Raise a note event for the migrator. - * @param string $message + * @param string $message * @return self */ protected function note($message) { if ($this->notesOutput !== null) { $this->notesOutput->writeln($message); - } - else { + } else { $this->notes[] = $message; } @@ -827,7 +833,7 @@ class UpdateManager /** * Sets an output stream for writing notes. - * @param Illuminate\Console\Command $output + * @param Illuminate\Console\Command $output * @return self */ public function setNotesOutput($output) @@ -843,8 +849,8 @@ class UpdateManager /** * Contacts the update server for a response. - * @param string $uri Gateway API URI - * @param array $postData Extra post data + * @param string $uri Gateway API URI + * @param array $postData Extra post data * @return array */ public function requestServerData($uri, $postData = []) @@ -869,8 +875,7 @@ class UpdateManager try { $resultData = @json_decode($result->body, true); - } - catch (Exception $ex) { + } catch (Exception $ex) { throw new ApplicationException(Lang::get('system::lang.server.response_invalid')); } @@ -883,10 +888,10 @@ class UpdateManager /** * Downloads a file from the update server. - * @param string $uri Gateway API URI - * @param string $fileCode A unique code for saving the file. - * @param string $expectedHash The expected file hash of the file. - * @param array $postData Extra post data + * @param string $uri Gateway API URI + * @param string $fileCode A unique code for saving the file. + * @param string $expectedHash The expected file hash of the file. + * @param array $postData Extra post data * @return void */ public function requestServerFile($uri, $fileCode, $expectedHash, $postData = []) @@ -910,7 +915,7 @@ class UpdateManager /** * Calculates a file path for a file code - * @param string $fileCode A unique file code + * @param string $fileCode A unique file code * @return string Full path on the disk */ protected function getFilePath($fileCode) @@ -921,7 +926,7 @@ class UpdateManager /** * Set the API security for all transmissions. - * @param string $key API Key + * @param string $key API Key * @param string $secret API Secret */ public function setSecurity($key, $secret) @@ -932,7 +937,7 @@ class UpdateManager /** * Create a complete gateway server URL from supplied URI - * @param string $uri URI + * @param string $uri URI * @return string URL */ protected function createServerUrl($uri) @@ -947,8 +952,8 @@ class UpdateManager /** * Modifies the Network HTTP object with common attributes. - * @param Http $http Network object - * @param array $postData Post data + * @param Http $http Network object + * @param array $postData Post data * @return void */ protected function applyHttpAttributes($http, $postData) diff --git a/modules/system/classes/VersionManager.php b/modules/system/classes/VersionManager.php index 55e8636fe..77127cf12 100644 --- a/modules/system/classes/VersionManager.php +++ b/modules/system/classes/VersionManager.php @@ -157,8 +157,13 @@ class VersionManager * Removes and packs down a plugin from the system. Files are left intact. * If the $stopOnVersion parameter is specified, the process stops after * the specified version is rolled back. + * + * @param mixed $plugin Either the identifier of a plugin as a string, or a Plugin class. + * @param string $stopOnVersion + * @param bool $stopCurrentVersion + * @return bool */ - public function removePlugin($plugin, $stopOnVersion = null) + public function removePlugin($plugin, $stopOnVersion = null, $stopCurrentVersion = false) { $code = is_string($plugin) ? $plugin : $this->pluginManager->getIdentifier($plugin); @@ -172,25 +177,37 @@ class VersionManager $stopOnNextVersion = false; $newPluginVersion = null; - foreach ($pluginHistory as $history) { - if ($stopOnNextVersion && $history->version !== $stopOnVersion) { - // Stop if the $stopOnVersion value was found and - // this is a new version. The history could contain - // multiple items for a single version (comments and scripts). - $newPluginVersion = $history->version; - break; - } + try { + foreach ($pluginHistory as $history) { + if ($stopCurrentVersion && $stopOnVersion === $history->version) { + $newPluginVersion = $history->version; + break; + } - if ($history->type == self::HISTORY_TYPE_COMMENT) { - $this->removeDatabaseComment($code, $history->version); - } - elseif ($history->type == self::HISTORY_TYPE_SCRIPT) { - $this->removeDatabaseScript($code, $history->version, $history->detail); - } + if ($stopOnNextVersion && $history->version !== $stopOnVersion) { + // Stop if the $stopOnVersion value was found and + // this is a new version. The history could contain + // multiple items for a single version (comments and scripts). + $newPluginVersion = $history->version; + break; + } - if ($stopOnVersion === $history->version) { - $stopOnNextVersion = true; + if ($history->type == self::HISTORY_TYPE_COMMENT) { + $this->removeDatabaseComment($code, $history->version); + } elseif ($history->type == self::HISTORY_TYPE_SCRIPT) { + $this->removeDatabaseScript($code, $history->version, $history->detail); + } + + if ($stopOnVersion === $history->version) { + $stopOnNextVersion = true; + } } + } catch (\Exception $exception) { + $lastHistory = $this->getLastHistory($code); + if ($lastHistory) { + $this->setDatabaseVersion($code, $lastHistory->version); + } + throw $exception; } $this->setDatabaseVersion($code, $newPluginVersion); @@ -209,7 +226,7 @@ class VersionManager /** * Deletes all records from the version and history tables for a plugin. - * @param string $pluginCode Plugin code + * @param string $pluginCode Plugin code * @return void */ public function purgePlugin($pluginCode) @@ -317,8 +334,7 @@ class VersionManager if (!isset($this->databaseVersions[$code])) { $this->databaseVersions[$code] = Db::table('system_plugin_versions') ->where('code', $code) - ->value('version') - ; + ->value('version'); } return $this->databaseVersions[$code] ?? self::NO_VERSION_VALUE; @@ -333,18 +349,16 @@ class VersionManager if ($version && !$currentVersion) { Db::table('system_plugin_versions')->insert([ - 'code' => $code, - 'version' => $version, + 'code' => $code, + 'version' => $version, 'created_at' => new Carbon ]); - } - elseif ($version && $currentVersion) { + } elseif ($version && $currentVersion) { Db::table('system_plugin_versions')->where('code', $code)->update([ - 'version' => $version, + 'version' => $version, 'created_at' => new Carbon ]); - } - elseif ($currentVersion) { + } elseif ($currentVersion) { Db::table('system_plugin_versions')->where('code', $code)->delete(); } @@ -357,10 +371,10 @@ class VersionManager protected function applyDatabaseComment($code, $version, $comment) { Db::table('system_plugin_history')->insert([ - 'code' => $code, - 'type' => self::HISTORY_TYPE_COMMENT, - 'version' => $version, - 'detail' => $comment, + 'code' => $code, + 'type' => self::HISTORY_TYPE_COMMENT, + 'version' => $version, + 'detail' => $comment, 'created_at' => new Carbon ]); } @@ -395,10 +409,10 @@ class VersionManager $this->updater->setUp($updateFile); Db::table('system_plugin_history')->insert([ - 'code' => $code, - 'type' => self::HISTORY_TYPE_SCRIPT, - 'version' => $version, - 'detail' => $script, + 'code' => $code, + 'type' => self::HISTORY_TYPE_SCRIPT, + 'version' => $version, + 'detail' => $script, 'created_at' => new Carbon ]); } @@ -440,6 +454,20 @@ class VersionManager return $this->databaseHistory[$code] = $historyInfo; } + /** + * Returns the last update history for a plugin. + * + * @param string $code The plugin identifier + * @return stdClass|null + */ + protected function getLastHistory($code) + { + return Db::table('system_plugin_history') + ->where('code', $code) + ->orderBy('id', 'DESC') + ->first(); + } + /** * Checks if a plugin has an applied update version. */ @@ -473,15 +501,14 @@ class VersionManager /** * Raise a note event for the migrator. - * @param string $message + * @param string $message * @return void */ protected function note($message) { if ($this->notesOutput !== null) { $this->notesOutput->writeln($message); - } - else { + } else { $this->notes[] = $message; } @@ -512,7 +539,7 @@ class VersionManager /** * Sets an output stream for writing notes. - * @param Illuminate\Console\Command $output + * @param Illuminate\Console\Command $output * @return self */ public function setNotesOutput($output) @@ -527,7 +554,7 @@ class VersionManager * * @return array */ - protected function extractScriptsAndComments($details) + protected function extractScriptsAndComments($details): array { if (is_array($details)) { $fileNamePattern = "/^[a-z0-9\_\-\.\/\\\]+\.php$/i"; @@ -546,4 +573,52 @@ class VersionManager return [$comments, $scripts]; } + + /** + * Get the currently installed version of the plugin. + * + * @param string|PluginBase $plugin Either the identifier of a plugin as a string, or a Plugin class. + * @return string + */ + public function getCurrentVersion($plugin): string + { + $code = $this->pluginManager->getIdentifier($plugin); + return $this->getDatabaseVersion($code); + } + + /** + * Check if a certain version of the plugin exists in the plugin history database. + * + * @param string|PluginBase $plugin Either the identifier of a plugin as a string, or a Plugin class. + * @param string $version + * @return bool + */ + public function hasDatabaseVersion($plugin, string $version): bool + { + $code = $this->pluginManager->getIdentifier($plugin); + $histories = $this->getDatabaseHistory($code); + foreach ($histories as $history) { + if ($history->version === $version) { + return true; + } + } + + return false; + } + + /** + * Get last version note + * + * @param string|PluginBase $plugin + * @return string + */ + public function getCurrentVersionNote($plugin): string + { + $code = $this->pluginManager->getIdentifier($plugin); + $histories = $this->getDatabaseHistory($code); + $lastHistory = array_last(array_where($histories, function ($history) { + return $history->type === self::HISTORY_TYPE_COMMENT; + })); + return $lastHistory ? $lastHistory->detail : ''; + } } diff --git a/modules/system/console/PluginRollback.php b/modules/system/console/PluginRollback.php new file mode 100644 index 000000000..af4d2065c --- /dev/null +++ b/modules/system/console/PluginRollback.php @@ -0,0 +1,88 @@ +argument('name'); + $pluginName = PluginManager::instance()->normalizeIdentifier($pluginName); + if (!PluginManager::instance()->exists($pluginName)) { + throw new \InvalidArgumentException('Plugin not found'); + } + + $stopOnVersion = ltrim(($this->argument('version') ?: null), 'v'); + + if ($stopOnVersion) { + if (!VersionManager::instance()->hasDatabaseVersion($pluginName, $stopOnVersion)) { + throw new \InvalidArgumentException('Plugin version not found'); + } + $confirmQuestion = 'Please confirm that you wish to revert the plugin to version ' . $stopOnVersion . '. This may result in changes to your database and potential data loss.'; + } else { + $confirmQuestion = 'Please confirm that you wish to completely rollback this plugin. This may result in potential data loss.'; + } + + if ($this->option('force') || $this->confirm($confirmQuestion)) { + $manager = UpdateManager::instance()->setNotesOutput($this->output); + $stopOnVersion = ltrim(($this->argument('version') ?: null), 'v'); + + try { + $manager->rollbackPlugin($pluginName, $stopOnVersion); + } catch (\Exception $exception) { + $lastVersion = VersionManager::instance()->getCurrentVersion($pluginName); + $this->output->writeln(sprintf("An exception occurred during the rollback and the process has been stopped. The plugin was rolled back to version v%s.", $lastVersion)); + throw $exception; + } + } + } + + /** + * Get the console command arguments. + * @return array + */ + protected function getArguments() + { + return [ + ['name', InputArgument::REQUIRED, 'The name of the plugin to be rolled back. Eg: AuthorName.PluginName'], + ['version', InputArgument::OPTIONAL, 'If this parameter is specified, the process will stop on the specified version, if not, it will completely rollback the plugin. Example: 1.3.9'], + ]; + } + + protected function getOptions() + { + return [ + ['force', 'f', InputOption::VALUE_NONE, 'Force rollback', null], + ]; + } +} diff --git a/modules/system/lang/en/lang.php b/modules/system/lang/en/lang.php index 760bfde5d..3adf7f6c9 100644 --- a/modules/system/lang/en/lang.php +++ b/modules/system/lang/en/lang.php @@ -322,6 +322,7 @@ return [ 'plugin_version' => 'Version', 'plugin_author' => 'Author', 'plugin_not_found' => 'Plugin not found', + 'plugin_version_not_found' => 'Plugin version not found', 'core_current_build' => 'Current build', 'core_view_changelog' => 'View Changelog', 'core_build' => 'Build :build', diff --git a/modules/system/lang/pt-br/lang.php b/modules/system/lang/pt-br/lang.php index 6f080515c..adbaa043c 100644 --- a/modules/system/lang/pt-br/lang.php +++ b/modules/system/lang/pt-br/lang.php @@ -276,7 +276,7 @@ return [ 'plugin_description' => 'Descrição', 'plugin_version' => 'Versão', 'plugin_author' => 'Autor', - 'plugin_not_found' => 'Plugin encotrado', + 'plugin_not_found' => 'Plugin não encontrado', 'plugin_version_not_found' => 'Versão do plugin não encontrada', 'core_current_build' => 'Compilação atual', 'core_view_changelog' => 'Visualizar Changelog', From baca3c8adf7f5ba1832a254979b373e3ae7016b5 Mon Sep 17 00:00:00 2001 From: 4NIK3T Date: Sun, 12 Apr 2020 22:47:45 +0530 Subject: [PATCH 04/13] Allow translations of default column values (#5038) Currently the default column values cannot be translated. This change will allow us to translate them. --- modules/backend/widgets/Lists.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/backend/widgets/Lists.php b/modules/backend/widgets/Lists.php index 70eeff323..bc83c11f6 100644 --- a/modules/backend/widgets/Lists.php +++ b/modules/backend/widgets/Lists.php @@ -1076,8 +1076,8 @@ class Lists extends WidgetBase /* * Apply default value. */ - if ($value === '' || $value === null) { - $value = $column->defaults; + if (($value === '' || is_null($value)) && !empty($column->defaults)) { + $value = Lang::get($column->defaults); } /** From 965732bd4563d26497eb8f9c1ee9484684ab938b Mon Sep 17 00:00:00 2001 From: Ben Thomson Date: Wed, 15 Apr 2020 00:16:29 +0800 Subject: [PATCH 05/13] Allow sidePanel to be used independent of sideNav Also, updated compiled assets --- modules/backend/assets/js/october-min.js | 5 +++-- .../backend/assets/js/october.sidepaneltab.js | 8 +++++++- modules/system/assets/js/framework-min.js | 1 + .../assets/js/framework.combined-min.js | 1 + modules/system/assets/ui/storm-min.js | 19 ++++++++++++++----- 5 files changed, 26 insertions(+), 8 deletions(-) diff --git a/modules/backend/assets/js/october-min.js b/modules/backend/assets/js/october-min.js index 34770c73c..41cba9726 100644 --- a/modules/backend/assets/js/october-min.js +++ b/modules/backend/assets/js/october-min.js @@ -1041,7 +1041,7 @@ self.$el.on('close.oc.sidePanel',function(){self.hideSidePanel()})} this.updateActiveTab()} SidePanelTab.prototype.displayTab=function(menuItem){var menuItemId=$(menuItem).data('menu-item') this.visibleItemId=menuItemId -$.oc.sideNav.setActiveItem(menuItemId) +if($.oc.sideNav!==undefined){$.oc.sideNav.setActiveItem(menuItemId)} this.$sidePanelItems.each(function(){var $el=$(this) $el.toggleClass('hide',$el.data('content-id')!=menuItemId)}) $(window).trigger('resize')} @@ -1058,7 +1058,8 @@ this.updateActiveTab()} SidePanelTab.prototype.updatePanelPosition=function(){if(!this.panelFixed()||Modernizr.touchevents){this.$el.height($(document).height()-this.mainNavHeight)} else{this.$el.css('height','')} if(this.panelVisible&&$(window).width()>this.options.breakpoint&&this.panelFixed()){this.hideSidePanel()}} -SidePanelTab.prototype.updateActiveTab=function(){if(!this.panelVisible&&($(window).width() \ + data-search /> \
\
    \ {{#available}} \ @@ -3115,7 +3112,8 @@ $(event.relatedTarget).on('ajaxDone','#controlFilterPopover input.filter-search- $(event.relatedTarget).on('click','#controlFilterPopover [data-filter-action="apply"]',function(e){e.preventDefault() self.filterScope()}) $(event.relatedTarget).on('click','#controlFilterPopover [data-filter-action="clear"]',function(e){e.preventDefault() -self.filterScope(true)})}) +self.filterScope(true)}) +$(event.relatedTarget).on('input','#controlFilterPopover input[data-search]',function(e){self.searchQuery($(this))});}) this.$el.on('hide.oc.popover','a.filter-scope',function(){var $scope=$(this) self.pushOptions(self.activeScopeName) self.activeScopeName=null @@ -3230,6 +3228,17 @@ this.updateScopeSetting(this.$activeScope,0)} this.pushOptions(scopeName);this.isActiveScopeDirty=true;this.$activeScope.data('oc.popover').hide()} FilterWidget.prototype.getLang=function(name,defaultValue){if($.oc===undefined||$.oc.lang===undefined){return defaultValue} return $.oc.lang.get(name,defaultValue)} +FilterWidget.prototype.searchQuery=function($el){if(this.dataTrackInputTimer!==undefined){window.clearTimeout(this.dataTrackInputTimer)} +var self=this +this.dataTrackInputTimer=window.setTimeout(function(){var +lastValue=$el.data('oc.lastvalue'),thisValue=$el.val() +if(lastValue!==undefined&&lastValue==thisValue){return} +$el.data('oc.lastvalue',thisValue) +if(self.lastDataTrackInputRequest){self.lastDataTrackInputRequest.abort()} +var data={scopeName:self.activeScopeName,search:thisValue} +$.oc.stripeLoadIndicator.show() +self.lastDataTrackInputRequest=self.$el.request(self.options.optionsHandler,{data:data}).success(function(data){self.filterAvailable(self.activeScopeName,data.options.available) +self.toggleFilterButtons()}).always(function(){$.oc.stripeLoadIndicator.hide()})},300)} var old=$.fn.filterWidget $.fn.filterWidget=function(option){var args=arguments,result this.each(function(){var $this=$(this) From d029d6ea24743a4187078679ad678879de1b87c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=90or=C4=91e=20Joci=C4=87?= Date: Tue, 14 Apr 2020 23:58:47 -0400 Subject: [PATCH 06/13] Added Serbian translation (#5040) --- modules/backend/lang/rs/lang.php | 639 ++++++++++++++++++++++++++ modules/backend/models/Preference.php | 1 + modules/cms/lang/rs/lang.php | 303 ++++++++++++ modules/system/lang/ar/lang.php | 1 + modules/system/lang/en/lang.php | 1 + modules/system/lang/et/lang.php | 1 + modules/system/lang/fa/lang.php | 1 + modules/system/lang/fi/lang.php | 1 + modules/system/lang/lt/lang.php | 1 + modules/system/lang/nl/lang.php | 1 + modules/system/lang/pt-pt/lang.php | 1 + modules/system/lang/rs/client.php | 102 ++++ modules/system/lang/rs/lang.php | 480 +++++++++++++++++++ modules/system/lang/rs/validation.php | 125 +++++ modules/system/lang/sk/lang.php | 1 + modules/system/lang/sl/lang.php | 1 + modules/system/lang/tr/lang.php | 1 + modules/system/lang/vn/lang.php | 1 + 18 files changed, 1662 insertions(+) create mode 100644 modules/backend/lang/rs/lang.php create mode 100644 modules/cms/lang/rs/lang.php create mode 100644 modules/system/lang/rs/client.php create mode 100644 modules/system/lang/rs/lang.php create mode 100644 modules/system/lang/rs/validation.php diff --git a/modules/backend/lang/rs/lang.php b/modules/backend/lang/rs/lang.php new file mode 100644 index 000000000..17a6d6356 --- /dev/null +++ b/modules/backend/lang/rs/lang.php @@ -0,0 +1,639 @@ + [ + 'title' => 'Administratorska sekcija', + 'invalid_login' => 'Unešeni detalji se ne podudaraju sa onima u bazi, pokušajte ponovo.', + ], + 'field' => [ + 'invalid_type' => 'Iskorišćen tip polja nije validan :type.', + 'options_method_invalid_model' => "Atribut ':field' ne vraća validni model. Pokušaj da eksplicitno specificiraš metod opcija za model klase :model.", + 'options_method_not_exists' => "Model klase :model mora definisati metod :method() koji vraća opcije za polje obrasca ':field'.", + 'colors_method_not_exists' => "Model klase :model mora da definiše metod :method() koji vraća heksadecimalne kodove boje za polje obrasca ':field'.", + ], + 'widget' => [ + 'not_registered' => "Klasa posredničkog elementa ':name' nije registrovana", + 'not_bound' => "Kalasa posredničkog elementa ':name' nije vezana za kontroler", + ], + 'page' => [ + 'untitled' => 'Bez naziva', + '404' => [ + 'label' => 'Stranica nije pronađena', + 'help' => "Traženi URL nije pronađen. Možda tražiš nešto drugo?", + 'back_link' => 'Nazad na prošlu stranicu', + ], + 'access_denied' => [ + 'label' => 'Pristup odbijen', + 'help' => "Nemaš odgovarajuće dozvole za pristup ovoj stranici.", + 'cms_link' => 'Nazad na pozadinski sistem', + ], + 'no_database' => [ + 'label' => 'Baza podataka nedostaje', + 'help' => "Baza podataka je neophodna za pristup pozadinskom sistemu. Proveri da li je baza podataka konfigurisana kako treba i pokušaj ponovo.", + 'cms_link' => 'Nazad na početnu stranicu', + ], + ], + 'partial' => [ + 'not_found_name' => "Parcijal ':name' nije pronađen.", + 'invalid_name' => 'Naziv parcijala nije validan: :name.', + ], + 'ajax_handler' => [ + 'invalid_name' => 'Naziv AJAX rukovatelja nije validan: :name.', + 'not_found' => "AJAX rukovatelj ':name' nije pronađen.", + ], + 'account' => [ + 'impersonate' => 'Oponašaj korisnika', + 'impersonate_confirm' => 'Da li zaista želiš da oponašaš ovog korisnika? Možeš se vratiti na originalno stanje kada se izloguješ.', + 'impersonate_success' => 'Sada oponašaš ovog korisnika', + 'impersonate_working' => 'Oponašanje...', + 'impersonating' => 'Oponašanje :full_name', + 'stop_impersonating' => 'Prestani sa oponašanjem', + 'unsuspend' => 'Obustavljena suspenzija', + 'unsuspend_confirm' => 'Da li zaista želiš da obustaviš suspenziju za ovog korisnika?', + 'unsuspend_success' => 'Korisnik više nije supsendovan.', + 'unsuspend_working' => 'Obustavljanje suspenzije...', + 'signed_in_as' => 'Ulogovan kao :full_name', + 'sign_out' => 'Izloguj se', + 'login' => 'Logovanje', + 'reset' => 'Resetuj', + 'restore' => 'Povrati', + 'login_placeholder' => 'login', + 'password_placeholder' => 'lozinka', + 'remember_me' => 'Ostani ulogovan', + 'forgot_password' => 'Zaboravljena lozinka?', + 'enter_email' => 'Unesi svoj email', + 'enter_login' => 'Unesi svoj login', + 'email_placeholder' => 'email', + 'enter_new_password' => 'Unesi novu lozinku', + 'password_reset' => 'Resetovanje lozinke', + 'restore_success' => 'Poruka sa instrukcijama je poslata na vašu adresu.', + 'restore_error' => "Korisnik nije pronađen sa navedenom vrednošću: ':login'", + 'reset_success' => 'Lozinka je resetovana, možeš se ulogovati.', + 'reset_error' => 'Priloženi podaci za resetovanje lozinke nisu validni. Pokušaj ponovo!', + 'reset_fail' => 'Resetovanje lozinke nije moguće!', + 'apply' => 'Primeni', + 'cancel' => 'Otkaži', + 'delete' => 'Izbriši', + 'ok' => 'OK', + ], + 'dashboard' => [ + 'menu_label' => 'Kontrolna tabla', + 'widget_label' => 'Posrednički element', + 'widget_width' => 'Širina', + 'full_width' => 'puna širina', + 'manage_widgets' => 'Upravljanje posredničkim elementima', + 'add_widget' => 'Dodaj posrednički element', + 'widget_inspector_title' => 'Konfiguracija posredničkog elementa', + 'widget_inspector_description' => 'Konfiguriši izveštaj za posrednički element', + 'widget_columns_label' => 'Širina :columns', + 'widget_columns_description' => 'Širina posredničkog elementa, broj između 1 i 12.', + 'widget_columns_error' => 'Unesi širinu posredničkog elementa kao broj između 1 i 12.', + 'columns' => '{1} kolona|[2,Inf] kolone', + 'widget_new_row_label' => 'Novi red na silu', + 'widget_new_row_description' => 'Postavi posrednički element u novi red.', + 'widget_title_label' => 'Naslov posredničkog elementa', + 'widget_title_error' => 'Naslov za posrednički element je neophodan.', + 'reset_layout' => 'Resetuj plan', + 'reset_layout_confirm' => 'Resetuj plan na podrazumevani?', + 'reset_layout_success' => 'Plan je resetovan', + 'make_default' => 'Učini podrazumevanim', + 'make_default_confirm' => 'Postavi trenutni plan kao podrazumevani?', + 'make_default_success' => 'Trenutni plan je sada podrazumevani', + 'collapse_all' => 'Sklopi sve', + 'expand_all' => 'Rasklopi sve', + 'status' => [ + 'widget_title_default' => 'Status sistema', + 'update_available' => '{0} ispravki dostupno!|{1} ispravka dostupna!|[2,Inf] ispravke dostupne!', + 'updates_pending' => 'Čekaju se ispravke softvera', + 'updates_nil' => 'Softver je ažuriran', + 'updates_link' => 'Ažuriraj', + 'warnings_pending' => 'Neki problemi zahtevaju vašu pažnju', + 'warnings_nil' => 'Nema upozorenja za prikaz', + 'warnings_link' => 'Pogled', + 'core_build' => 'Verzija sistema', + 'event_log' => 'Log događaja', + 'request_log' => 'Log zahteva', + 'app_birthday' => 'Na mreži od', + ], + 'welcome' => [ + 'widget_title_default' => 'Dobrodošli', + 'welcome_back_name' => 'Dobrodošli nazad na :app, :name.', + 'welcome_to_name' => 'Dobrodošli na :app, :name.', + 'first_sign_in' => 'Prvi put ste se ulogovali.', + 'last_sign_in' => 'Vaše poslednje logovanje je bilo na', + 'view_access_logs' => 'Prikaži logove pristupa', + 'nice_message' => 'Lep dan želim!', + ], + ], + 'user' => [ + 'name' => 'Administrator', + 'menu_label' => 'Administratori', + 'menu_description' => 'Upravljaj administratorima pozadinskog sistema, grupama i dozvolama.', + 'list_title' => 'Upravljanje administratorima', + 'new' => 'Novi administrator', + 'login' => 'Logovanje', + 'first_name' => 'Ime', + 'last_name' => 'Prezime', + 'full_name' => 'Ime i prezime', + 'email' => 'Email', + 'role_field' => 'Rola', + 'role_comment' => 'Role definišu dozvole korisnika, koje mogu biti pregažene na korisničkom nivou ili preko taba za dozvole.', + 'groups' => 'Grupe', + 'groups_comment' => 'Speicificiraj grupe kojima nalog treba pripadati.', + 'avatar' => 'Avatar', + 'password' => 'Lozinka', + 'password_confirmation' => 'Potvrdi lozinku', + 'permissions' => 'Dozvole', + 'account' => 'Nalog', + 'superuser' => 'Super korisnik', + 'superuser_comment' => 'Dozvoli ovom nalogu pristup svim delovima sistema bez ograničenja. Super korisnici mogu dodavati i upravljati drugim korisnicima.', + 'send_invite' => 'Pošalji pozivnicu preko mejla', + 'send_invite_comment' => 'Pošalji poruku dobrodošlice koja sadrži informacije za logovanje.', + 'delete_confirm' => 'Obriši administratora?', + 'return' => 'Nazad na listu administratora', + 'allow' => 'Dozvoli', + 'inherit' => 'Nasledi', + 'deny' => 'Odbij', + 'activated' => 'Aktiviran', + 'last_login' => 'Poslednje logovanje:', + 'created_at' => 'Napravljen:', + 'updated_at' => 'Ažuriran:', + 'deleted_at' => 'Obrisan:', + 'show_deleted' => 'Prikaži izbrisane', + 'group' => [ + 'name' => 'Grupe', + 'name_field' => 'Naziv', + 'name_comment' => 'Naziv je prikazan u listi grupa u administratorskom obrascu.', + 'description_field' => 'Opis', + 'is_new_user_default_field_label' => 'Osnovna grupa', + 'is_new_user_default_field_comment' => 'Podrazumevano dodaj nove administratore ovoj grupi.', + 'code_field' => 'Kod', + 'code_comment' => 'Unesi jedinstveni kod ako želiš da pristupaš objektu grupe preko API-ja.', + 'menu_label' => 'Upravljaj grupama', + 'list_title' => 'Upravljaj grupama', + 'new' => 'Nova grupa', + 'delete_confirm' => 'Izbriši ovu administratorsku grupu?', + 'return' => 'Nazad na listu grupa', + 'users_count' => 'Korisnici', + ], + 'role' => [ + 'name' => 'Rola', + 'name_field' => 'Naziv', + 'name_comment' => 'Naziv je prikazan u listi rola u administratorskom obrascu.', + 'description_field' => 'Opis', + 'code_field' => 'Kod', + 'code_comment' => 'Unesi jedinstveni kod ako želiš da pristupaš objektu role preko API-ja.', + 'menu_label' => 'Upravljaj rolama', + 'list_title' => 'Upravljaj rolama', + 'new' => 'Nova rola', + 'delete_confirm' => 'Izbriši ovu administratorsku rolu?', + 'return' => 'Nazad na listu rola', + 'users_count' => 'Korisnici', + ], + 'preferences' => [ + 'not_authenticated' => 'Nema autentifikovanog korisnika za učitavanje ili čuvanje podeski.', + ], + 'trashed_hint_title' => 'Ovaj nalog je izbrisan', + 'trashed_hint_desc' => 'Ovaj nalog je izbrisan i neće više moći da se koristi za logovanje. Da ga povratiš, klikni na ikonicu u donjem desnom uglu', + ], + 'list' => [ + 'default_title' => 'Lista', + 'search_prompt' => 'Traži...', + 'no_records' => 'Nema zapisa u ovom pogledu.', + 'missing_model' => 'Lista ponašanja korišćena u klasi :class nema definisan model.', + 'missing_column' => 'Nema definicija za sledeće kolone: :columns.', + 'missing_columns' => 'Lista korišćena u klasi :class nema definisane kolone.', + 'missing_definition' => "Lista ponašanja ne sadrži definiciju za ':field'.", + 'missing_parent_definition' => "Lista ponašanja ne sadrži definiciju za ':definition'.", + 'behavior_not_ready' => 'Lista ponašanja nije inicijalizovana, proveri da li je metoda makeLists() pozvana u kontroleru.', + 'invalid_column_datetime' => "Vrednost kolone ':column' nije DateTime objekat, da li ti nedostaje \$dates referenca u modelu?", + 'pagination' => 'Prikazani zapisi: :from-:to od ukupno :total', + 'first_page' => 'Prva strana', + 'last_page' => 'Poslednja strana', + 'prev_page' => 'Prošla strana', + 'next_page' => 'Sledeća strana', + 'refresh' => 'Osveži', + 'updating' => 'Ažuriranje...', + 'loading' => 'Učitavanje...', + 'setup_title' => 'Podešavanje liste', + 'setup_help' => 'Koristi polja za potvrdu za biranje kolona koje želiš da vidiš u listi. Možeš menjati položaj kolona prevlačenjem na gore ili dole.', + 'records_per_page' => 'Zapisa po strani', + 'records_per_page_help' => 'Izaberi broj zapisa za prikazivanje po strani. Imaj samo na umu da veliki broj zapisa po strani može smanjiti performanse.', + 'check' => 'Proveri', + 'delete_selected' => 'Izbriši izabrane', + 'delete_selected_empty' => 'Nema izabranih zapisa za brisanje.', + 'delete_selected_confirm' => 'Izbriši izabrane zapise?', + 'delete_selected_success' => 'Izabrani zapisi su obrisani.', + 'column_switch_true' => 'Da', + 'column_switch_false' => 'Ne', + ], + 'fileupload' => [ + 'attachment' => 'Prilog', + 'help' => 'Dodaj naslov i opis za ovaj prilog.', + 'title_label' => 'Naslov', + 'description_label' => 'Opis', + 'default_prompt' => 'Klikni na %s ili prevuci fajl ovde za otpremanje', + 'attachment_url' => 'URL priloga', + 'upload_file' => 'Otpremi fajl', + 'upload_error' => 'Greška pri otpremanju', + 'remove_confirm' => 'Da li si siguran?', + 'remove_file' => 'Izbriši fajl', + ], + 'repeater' => [ + 'add_new_item' => 'Dodaj novi element', + 'min_items_failed' => 'Ponavljač :name zahteva minimum :min elementa, samo :items je obezbeđeno', + 'max_items_failed' => 'Ponavljač :name može imati maksimum :max elemenata, :items je obezbeđeno', + ], + 'form' => [ + 'create_title' => 'Nova :name', + 'update_title' => 'Izmeni :name', + 'preview_title' => 'Pregledaj :name', + 'create_success' => ':name napravljen', + 'update_success' => ':name ažuriran', + 'delete_success' => ':name obrisan', + 'restore_success' => ':name povraćen', + 'reset_success' => 'Resetovanje završeno', + 'missing_id' => 'ID obrasca nije specificiran.', + 'missing_model' => 'Ponašanje obrasca koje se koristi u klasi :class nema definisan model.', + 'missing_definition' => "Ponašanje obrasca ne sadrži sledeće polje: ':field'.", + 'not_found' => 'Zapis obrasca sa identifikatorom :id nije pronađen.', + 'action_confirm' => 'Da li ste sigurni?', + 'create' => 'Napravi', + 'create_and_close' => 'Napravi i zatvori', + 'creating' => 'Pravljenje...', + 'creating_name' => 'Pravljenje :name...', + 'save' => 'Sačuvaj', + 'save_and_close' => 'Sačuvaj i zatvori', + 'saving' => 'Čuvanje...', + 'saving_name' => 'Čuvanje :name...', + 'delete' => 'Izbriši', + 'deleting' => 'Brisanje...', + 'confirm_delete' => 'Izbriši zapis?', + 'confirm_delete_multiple' => 'Izbriši odabrane zapise?', + 'deleting_name' => 'Brisanje :name...', + 'restore' => 'Povrati', + 'restoring' => 'Vraćanje...', + 'confirm_restore' => 'Da li zaista želite da povratite ovaj zapis?', + 'reset_default' => 'Resetuj na osnovno', + 'resetting' => 'Resetovanje', + 'resetting_name' => 'Resetovanje :name', + 'undefined_tab' => 'Razno', + 'field_off' => 'Isključi', + 'field_on' => 'Uključi', + 'add' => 'Dodaj', + 'apply' => 'Primeni', + 'cancel' => 'Poništi', + 'close' => 'Zatvori', + 'confirm' => 'Potvrdi', + 'reload' => 'Ponovo učitaj', + 'complete' => 'Kompletno', + 'ok' => 'OK', + 'or' => 'ili', + 'confirm_tab_close' => 'Zatvori tab? Nesačuvane promene će biti izgubljene.', + 'behavior_not_ready' => 'Ponašanje obrasca se nije inicijalizovalo, proveri da li je metoda initForm() pozvana.', + 'preview_no_files_message' => 'Nema otpremljenih fajlova.', + 'preview_no_media_message' => 'Nema izabranih medija.', + 'preview_no_record_message' => 'Nema izabranih zapisa.', + 'select' => 'Izaberi', + 'select_all' => 'Izaberi sve', + 'select_none' => 'Ukloni odabire', + 'select_placeholder' => 'izaberi', + 'insert_row' => 'Ubaci red', + 'insert_row_below' => 'Ubaci red ispod', + 'delete_row' => 'Izbriši red', + 'concurrency_file_changed_title' => 'Fajl je izmenjen', + 'concurrency_file_changed_description' => "Fajl nad kojim je rađeno je u međuvremenu promenjen od strane drugog korisnika. Možeš ponovo da ga učitaš i izgubiš svoje promene, ili ga jednostavno pregaziš.", + 'return_to_list' => 'Nazad na listu', + ], + 'recordfinder' => [ + 'find_record' => 'Pronađi zapis', + 'invalid_model_class' => 'Klasa modela ":modelClass" za pretragu nije validna', + 'cancel' => 'Otkaži', + ], + 'pagelist' => [ + 'page_link' => 'Link strane', + 'select_page' => 'Izaberi stranu...', + ], + 'relation' => [ + 'missing_config' => "Relacioni odnos nema konfiguraciju za ':config'.", + 'missing_definition' => "Relacioni odnos ne sadrži definiciju za polje ':field'.", + 'missing_model' => 'Relacioni odnos korišćen u klasi :class nema definisan model.', + 'invalid_action_single' => 'Ova radnja se ne može izvršiti na jednoj vezi.', + 'invalid_action_multi' => 'Ova radnja se ne može izvršiti na više veza.', + 'help' => 'Klikni na element za dodavanje', + 'related_data' => 'Srodni podatak: :name', + 'add' => 'Dodaj', + 'add_selected' => 'Dodaj izabrane', + 'add_a_new' => 'Dodaj novu :name', + 'link_selected' => 'Zakači izabrane', + 'link_a_new' => 'Zakači novu :name', + 'cancel' => 'Otkaži', + 'close' => 'Zatvori', + 'add_name' => 'Dodaj :name', + 'create' => 'Napravi', + 'create_name' => 'Napravi :name', + 'update' => 'Ažuriraj', + 'update_name' => 'Ažuriraj :name', + 'preview' => 'Pregledaj', + 'preview_name' => 'Pregledaj :name', + 'remove' => 'Ukloni', + 'remove_name' => 'Ukloni :name', + 'delete' => 'Izbriši', + 'delete_name' => 'Izbriši :name', + 'delete_confirm' => 'Da li ste sigurni?', + 'link' => 'Zakači', + 'link_name' => 'Zakači :name', + 'unlink' => 'Otkači', + 'unlink_name' => 'Otkači :name', + 'unlink_confirm' => 'Da li ste sigurni?', + ], + 'reorder' => [ + 'default_title' => 'Promeni redosled', + 'no_records' => 'Ne postoje elementi za razmeštanje.', + ], + 'model' => [ + 'name' => 'Model', + 'not_found' => "Model ':class' sa odabranim identifikatorom :id nije pronađen", + 'missing_id' => 'ID za pretragu modela nije specificiran.', + 'missing_relation' => "Model ':class' ne sadrži definiciju za relaciju: ':relation'.", + 'missing_method' => "Model ':class' ne sadrži metod: ':method'.", + 'invalid_class' => "Model :model korišćen u klasi :class nije validan, mora da nasledi klasu \Model.", + 'mass_assignment_failed' => "Greška pri masovnom dodeljivanju za atribut modela: ':attribute'.", + ], + 'warnings' => [ + 'tips' => 'Saveti za konfigurisanje sistema', + 'tips_description' => 'Postoje problemi na koje bi trebalo da obratiš pažnju da bi konfigurisao sistem kako treba.', + 'permissions' => 'PHP ne može pristupiti direktorijumu :name ili njegovim poddirektorijuma zarad upisivanja. Promeni RWX dozvole na serveru za ovaj direktorijum.', + 'extension' => 'Produžetak za PHP :name nije instaliran. Instaliraj ovu biblioteku i produžetak.', + 'plugin_missing' => 'Produžetak :name je obavezan ali nije instaliran. Instaliraj ovaj produžetak.', + 'debug' => 'Uključen je mod za ispravljanje grešaka što nije preporučljivo.', + 'decompileBackendAssets' => 'Sredstva u pozadinskom sistemu trenutno nisu kompajlovana što nije preporučljivo.', + ], + 'editor' => [ + 'menu_label' => 'Podešavanje editora', + 'menu_description' => 'Izmeni postavke globalnog editora, kao što su veličina fonta, boje, itd.', + 'font_size' => 'Veličina fonta', + 'tab_size' => 'Veličina taba', + 'use_hard_tabs' => 'Uvođenje pomoću tabova', + 'code_folding' => 'Presavijanje koda', + 'code_folding_begin' => 'Označi početak', + 'code_folding_begin_end' => 'Označi početak i kraj', + 'autocompletion' => 'Automatsko dovršavanje', + 'word_wrap' => 'Prelomi redove', + 'highlight_active_line' => 'Istakni aktivne linije', + 'auto_closing' => 'Automatski zatvori tagove', + 'show_invisibles' => 'Prikaži nevidljive karaktere', + 'show_gutter' => 'Prikaži margine za povezivanje', + 'basic_autocompletion' => 'Osnovno automatsko dovršavanje (Ctrl + Space)', + 'live_autocompletion' => 'Instant automatsko dovršavanje', + 'enable_snippets' => 'Uključi isečke za kod (Tab)', + 'display_indent_guides' => 'Prikaži pomoćne margine za uvođenje', + 'show_print_margin' => 'Prikaži margine za štampu', + 'mode_off' => 'Isključen mod', + 'mode_fluid' => 'Fluidan mod', + '40_characters' => '40 karaktera', + '80_characters' => '80 karaktera', + 'theme' => 'Boje', + 'markup_styles' => 'Stilovi označavanja', + 'custom_styles' => 'Proizvoljni stilovi', + 'custom styles_comment' => 'Proizvoljni stilovi za uključivanje u HTML editor.', + 'markup_classes' => 'Klase označavanja', + 'paragraph' => 'Paragraf', + 'link' => 'Link', + 'table' => 'Tabela', + 'table_cell' => 'Ćelija tabele', + 'image' => 'Slika', + 'label' => 'Oznaka', + 'class_name' => 'Naziv klase', + 'markup_tags' => 'Tagovi označavanja', + 'allowed_empty_tags' => 'Dozvoljeni prazni tagovi', + 'allowed_empty_tags_comment' => 'Lista tagova koji se ne brišu kada nemaju sadržaj.', + 'allowed_tags' => 'Dozvoljeni tagovi', + 'allowed_tags_comment' => 'Lista dozvoljenih tagova.', + 'no_wrap' => 'Ne umeći tagove', + 'no_wrap_comment' => 'Lista tagova koji se ne trebaju umetati u blokovske tagove.', + 'remove_tags' => 'Ukloni tagove', + 'remove_tags_comment' => 'Lista tagova koji se brišu zajedno sa njihovim sadržajem.', + 'line_breaker_tags' => 'Tagovi za liniju prekida', + 'line_breaker_tags_comment' => 'Lista tagova koji se koriste za postavljanje linije prekida za elemente.', + 'toolbar_buttons' => 'Traka sa alatkama', + 'toolbar_buttons_comment' => 'Traka sa alatkama će obično biti prikazana u editoru.', + 'toolbar_buttons_preset' => 'Ubaci već podešenu konfiguraciju za traku sa alatkama:', + 'toolbar_buttons_presets' => [ + 'default' => 'Osnovna', + 'minimal' => 'Minimalna', + 'full' => 'Kompletna', + ], + ], + 'tooltips' => [ + 'preview_website' => 'Pregledaj sajt', + ], + 'mysettings' => [ + 'menu_label' => 'Moja podešavanja', + 'menu_description' => 'Podešavanja vezana za administratorski nalog', + ], + 'myaccount' => [ + 'menu_label' => 'Moj nalog', + 'menu_description' => 'Ažuriraj detalje svog naloga kao što su ime, prezime, email adresa i lozinka.', + 'menu_keywords' => 'bezbednosno logovanje', + ], + 'branding' => [ + 'menu_label' => 'Izmene pozadinskog sistema', + 'menu_description' => 'Izmene za administratorsku sekciju poput naziva, boja, logoa, itd.', + 'brand' => 'Brend', + 'logo' => 'Logo', + 'logo_description' => 'Otpremi željeni logo za pozadinski sistem.', + 'favicon' => 'Ikonica', + 'favicon_description' => 'Otpremi željenu ikonicu za pozadinski sistem.', + 'app_name' => 'Naziv aplikacije', + 'app_name_description' => 'Ovo ime će se prikazati kao naslov pozadinskog sistema.', + 'app_tagline' => 'Slogan aplikacije', + 'app_tagline_description' => 'Ovaj slogan će se prikazati na strani za logovanje na pozadinski sistem.', + 'colors' => 'Boje', + 'primary_color' => 'Primarne boje', + 'secondary_color' => 'Sekundarne boje', + 'accent_color' => 'Akcentovane boje', + 'styles' => 'Stilovi', + 'custom_stylesheet' => 'Proizvoljni stil', + 'navigation' => 'Navigacija', + 'menu_mode' => 'Stil menija', + 'menu_mode_inline' => 'Uveden', + 'menu_mode_inline_no_icons' => 'Uveden (bez ikonica)', + 'menu_mode_tile' => 'Poređan', + 'menu_mode_collapsed' => 'Sklopljen', + ], + 'backend_preferences' => [ + 'menu_label' => 'Postavke pozadinskog sistema', + 'menu_description' => 'Upravljaj postavkama tvog naloga.', + 'region' => 'Region', + 'code_editor' => 'Editor koda', + 'timezone' => 'Vremenska zona', + 'timezone_comment' => 'Podesi prikazane datume na osnovu ove vremenske zone.', + 'locale' => 'Prevod', + 'locale_comment' => 'Izaberi željeni jezik prevoda.', + ], + 'access_log' => [ + 'hint' => 'Ovaj log prikazuje listu uspešnih logova od strane administratora. Logovi se čuvaju ukupno :days dana.', + 'menu_label' => 'Logovi pristupa', + 'menu_description' => 'Prikaži listu uspešnih logovanja na pozadinski sistem.', + 'id' => 'ID', + 'created_at' => 'Datum & vreme', + 'type' => 'Tip', + 'login' => 'Logovanje', + 'ip_address' => 'IP adresa', + 'first_name' => 'Ime', + 'last_name' => 'Prezime', + 'email' => 'Email', + ], + 'filter' => [ + 'all' => 'svi', + 'options_method_not_exists' => "Model klase :model mora definisati povratne opcije metoda :method() za ':filter' filter.", + 'date_all' => 'svi periodi', + 'number_all' => 'svi brojevi', + ], + 'import_export' => [ + 'upload_csv_file' => '1. Otpremi CSV fajl', + 'import_file' => 'Uvezi fajl', + 'row' => 'Red :row', + 'first_row_contains_titles' => 'Prvi red sadrži naslove kolona', + 'first_row_contains_titles_desc' => 'Ostavite ovo polje označeno ako se prvi red u CSV fajlu koristi za naslove kolona.', + 'match_columns' => '2. Upari kolone fajla sa kolonama baze podataka', + 'file_columns' => 'Kolone fajla', + 'database_fields' => 'Polja u bazi podataka', + 'set_import_options' => '3. Postavi uvozne opcije', + 'export_output_format' => '1. Izvezi izlazni format', + 'file_format' => 'Format fajla', + 'standard_format' => 'Standardni format', + 'custom_format' => 'Proizvoljni format', + 'delimiter_char' => 'Granični znak', + 'enclosure_char' => 'Ogradni znak', + 'escape_char' => 'Komandni znak', + 'select_columns' => '2. Izaberi kolone za izvoz', + 'column' => 'Kolona', + 'columns' => 'Kolone', + 'set_export_options' => '3. Postavi izvozne opcije', + 'show_ignored_columns' => 'Prikaži ignorisane kolone', + 'auto_match_columns' => 'Automatski upari kolone', + 'created' => 'Napravljeni', + 'updated' => 'Ažurirani', + 'skipped' => 'Preskočeni', + 'warnings' => 'Upozorenja', + 'errors' => 'Greške', + 'skipped_rows' => 'Preskočeni redovi', + 'import_progress' => 'Progres uvoza', + 'processing' => 'Procesovanje', + 'import_error' => 'Greška pri uvozu', + 'upload_valid_csv' => 'Otpremi validan CSV fajl.', + 'drop_column_here' => 'Spusti kolonu ovde...', + 'ignore_this_column' => 'Ignoriši ovu kolonu', + 'processing_successful_line1' => 'Proces izvoza fajla je završen!', + 'processing_successful_line2' => 'Pretraživač će sada biti preusmeren na fajl za preuzimanje.', + 'export_progress' => 'Progres izvoza', + 'export_error' => 'Greška pri izvozu', + 'column_preview' => 'Pregled kolone', + 'file_not_found_error' => 'Fajl nije pronađen', + 'empty_error' => 'Nije bilo podataka za izvoz', + 'empty_import_columns_error' => 'Specificiraj neke kolone za uvoz.', + 'match_some_column_error' => 'Upari prvo neke kolone.', + 'required_match_column_error' => 'Specificiraj par za obavezno polje: :label.', + 'empty_export_columns_error' => 'Specificiraj kolone za izvoz.', + 'behavior_missing_uselist_error' => 'Moraš implementirati ponašanje za "ListController" sa omogućenom opcijom izvoza - "useList."', + 'missing_model_class_error' => 'Izaberi svojstvo modela kalse za svojstvo: :type', + 'missing_column_id_error' => 'Identifikator kolone ne postoji', + 'unknown_column_error' => 'Nepoznata kolona', + 'encoding_not_supported_error' => 'Kodiranje izvorne datoteke nije prepoznato. Izaberite opciju prilagođenog formata datoteke sa odgovarajućim kodiranjem da biste uvezli datoteku.', + 'encoding_format' => 'Format enkodovanja', + 'encodings' => [ + 'utf_8' => 'UTF-8', + 'us_ascii' => 'US-ASCII', + 'iso_8859_1' => 'ISO-8859-1 (Latin-1, Zapadnoevropski)', + 'iso_8859_2' => 'ISO-8859-2 (Latin-2, Srednjoevropski)', + 'iso_8859_3' => 'ISO-8859-3 (Latin-3, Južnoevropski)', + 'iso_8859_4' => 'ISO-8859-4 (Latin-4, Severnoevropski)', + 'iso_8859_5' => 'ISO-8859-5 (Latin, Ćirilični)', + 'iso_8859_6' => 'ISO-8859-6 (Latin, Arapski)', + 'iso_8859_7' => 'ISO-8859-7 (Latin, Grčki)', + 'iso_8859_8' => 'ISO-8859-8 (Latin, Hebrejski)', + 'iso_8859_0' => 'ISO-8859-9 (Latin-5, Turski)', + 'iso_8859_10' => 'ISO-8859-10 (Latin-6, Nordijski)', + 'iso_8859_11' => 'ISO-8859-11 (Latin, Tajlandski)', + 'iso_8859_13' => 'ISO-8859-13 (Latin-7, Baltički region)', + 'iso_8859_14' => 'ISO-8859-14 (Latin-8, Keltski)', + 'iso_8859_15' => 'ISO-8859-15 (Latin-9, Zapadnoevropska revizija sa euro znakom)', + 'windows_1250' => 'Windows-1250 (CP1250, Severnoevropski i istočnoevropski)', + 'windows_1251' => 'Windows-1251 (CP1251)', + 'windows_1252' => 'Windows-1252 (CP1252)', + ], + ], + 'permissions' => [ + 'manage_media' => 'Otpremi i upravljaj medijima - slikama, video i audio zapisima, dokumentima', + ], + 'mediafinder' => [ + 'label' => 'Pretražuj medije', + 'default_prompt' => 'Klikni na %s dugme za traženje elementa', + 'no_image' => 'Slika nije pronađena', + ], + 'media' => [ + 'menu_label' => 'Mediji', + 'upload' => 'Otpremanje', + 'move' => 'Pomeri', + 'delete' => 'Izbriši', + 'add_folder' => 'Dodaj direktorijum', + 'search' => 'Traži', + 'display' => 'Prikaži', + 'filter_everything' => 'Sve', + 'filter_images' => 'Slike', + 'filter_video' => 'Video zapisi', + 'filter_audio' => 'Audio zapisi', + 'filter_documents' => 'Dokumenta', + 'library' => 'Biblioteka', + 'size' => 'Veličina', + 'title' => 'Naslov', + 'last_modified' => 'Poslednja modifikacija', + 'public_url' => 'URL', + 'click_here' => 'Klikni ovde', + 'thumbnail_error' => 'Greška pri generisanju pregledne slike.', + 'return_to_parent' => 'Nazad na nadređeni direktorijum', + 'return_to_parent_label' => 'Idi nazad ..', + 'nothing_selected' => 'Ništa nije izabrano.', + 'multiple_selected' => 'Više elemenata je izabrano.', + 'uploading_file_num' => 'Otpremi :number fajl(ova)...', + 'uploading_complete' => 'Otpremanje završeno', + 'uploading_error' => 'Otpremanje neuspešno', + 'type_blocked' => 'Fajl je blokiran iz bezbednosnih razloga.', + 'order_by' => 'Sortiraj po', + 'direction' => 'Pravac', + 'direction_asc' => 'Uzlazni', + 'direction_desc' => 'Silazni', + 'folder' => 'Direktorijum', + 'no_files_found' => 'Nijedan fajl nije pronađen.', + 'delete_empty' => 'Izaberi elemente za brisanje.', + 'delete_confirm' => 'Izbriši odabran element(e)?', + 'error_renaming_file' => 'Greška pri promeni naziva elementa.', + 'new_folder_title' => 'Novi direktorijum', + 'folder_name' => 'Naziv direktorijuma', + 'error_creating_folder' => 'Greška pri pravljenju direktorijuma', + 'folder_or_file_exist' => 'Direktorijum ili fajl sa navedenim nazivom već postoji.', + 'move_empty' => 'Izaberi elemente za pomeranje.', + 'move_popup_title' => 'Pomeri fajlove ili direktorijume', + 'move_destination' => 'Odredišni direktorijum', + 'please_select_move_dest' => 'Izaberi odredišni direktorijum.', + 'move_dest_src_match' => 'Izaberi drugi odredišni direktorijum.', + 'empty_library' => 'Otpremi fajlove ili napravi direktorijume.', + 'insert' => 'Ubaci', + 'crop_and_insert' => 'Iseci & ubaci', + 'select_single_image' => 'Izaberi jednu sliku.', + 'selection_not_image' => 'Izabrani element nije slika.', + 'restore' => 'Poništi sve promene', + 'resize' => 'Promeni veličinu...', + 'selection_mode_normal' => 'Normalna', + 'selection_mode_fixed_ratio' => 'Fiksirani odnos', + 'selection_mode_fixed_size' => 'Fiksirana veličina', + 'height' => 'Visina', + 'width' => 'Širina', + 'selection_mode' => 'Mod selekcije', + 'resize_image' => 'Promeni veličinu slike', + 'image_size' => 'Veličina slike:', + 'selected_size' => 'Izabrana veličina:', + ], +]; diff --git a/modules/backend/models/Preference.php b/modules/backend/models/Preference.php index 12d7f0ae4..9eb5d6b1d 100644 --- a/modules/backend/models/Preference.php +++ b/modules/backend/models/Preference.php @@ -210,6 +210,7 @@ class Preference extends Model 'pt-br' => [Lang::get('system::lang.locale.pt-br'), 'flag-br'], 'pt-pt' => [Lang::get('system::lang.locale.pt-pt'), 'flag-pt'], 'ro' => [Lang::get('system::lang.locale.ro'), 'flag-ro'], + 'rs' => [Lang::get('system::lang.locale.rs'), 'flag-rs'], 'ru' => [Lang::get('system::lang.locale.ru'), 'flag-ru'], 'sk' => [Lang::get('system::lang.locale.sk'), 'flag-sk'], 'sl' => [Lang::get('system::lang.locale.sl'), 'flag-si'], diff --git a/modules/cms/lang/rs/lang.php b/modules/cms/lang/rs/lang.php new file mode 100644 index 000000000..046600bc2 --- /dev/null +++ b/modules/cms/lang/rs/lang.php @@ -0,0 +1,303 @@ + [ + 'invalid_file' => 'Naziv fajla nije validan: :name. Nazivi fajlova mogu sadržati samo alfanumeričke simbole, donje crte, povlake i tačke. Validni primeri su: strana.htm, strana, direktorijum/strana', + 'invalid_property' => "Svojstvo ':name' se ne može postaviti", + 'file_already_exists' => "Fajl ':name' već postoji.", + 'error_saving' => "Greška pri čuvanju fajla ':name'. Proveri dozvole na sistemu.", + 'error_creating_directory' => 'Greška pri pravljenju direktorijuma :name. Proveri dozvole na sistemu.', + 'invalid_file_extension' => 'Ekstenzija fajla nije validna: :invalid. Dozvoljene ekstenzije su: :allowed.', + 'error_deleting' => "Greška pri brisanju šablonskog fajla ':name'. Proveri dozvole na sistemu.", + 'delete_success' => 'Izbrisani šabloni: :count.', + 'file_name_required' => 'Polje za naziv fajla je obavezno.', + 'safe_mode_enabled' => 'Signurni režim je trenutno omogućen. Izmena PHP koda u CMS šablonima je trenutno onemogućena. Da isključiš siguran režim rada, izmeni vrednost konfiguracione promenljive `cms.enableSafeMode` u `false`.', + ], + 'dashboard' => [ + 'active_theme' => [ + 'widget_title_default' => 'Sajt', + 'online' => 'Na mreži', + 'maintenance' => 'U fazi održavanju', + 'manage_themes' => 'Upravljaj temama', + 'customize_theme' => 'Izmeni temu', + ], + ], + 'theme' => [ + 'not_found_name' => "Tema ':name' nije pronađena.", + 'by_author' => 'Autor: :name', + 'active' => [ + 'not_set' => 'Aktivna tema nije postavljena.', + 'not_found' => 'Aktivna tema nije pronađena.', + ], + 'edit' => [ + 'not_set' => 'Tema za izmenu nije postavljena.', + 'not_found' => 'Tema za izmenu nije pronađena.', + 'not_match' => "Objekat kojem pokušavaš da pristupiš ne pripada temi koju menjaš. Osveži stranicu.", + ], + 'settings_menu' => 'Teme', + 'settings_menu_description' => 'Upravljaj temama i opcijama prilagođavanja.', + 'default_tab' => 'Svojstva', + 'name_label' => 'Naziv', + 'name_create_placeholder' => 'Naziv nove teme', + 'author_label' => 'Autor', + 'author_placeholder' => 'Pravno ili privatno lice', + 'description_label' => 'Opis', + 'description_placeholder' => 'Opis teme', + 'homepage_label' => 'Početna stranica', + 'homepage_placeholder' => 'URL sajta', + 'code_label' => 'Kod', + 'code_placeholder' => 'Jedinstveni kod ove teme za distribuciju', + 'preview_image_label' => 'Slika pregleda', + 'preview_image_placeholder' => 'Putanja za sliku pregleda teme.', + 'dir_name_label' => 'Naziv direktorijuma', + 'dir_name_create_label' => 'Odredišni direktorijum za temu', + 'theme_label' => 'Tema', + 'theme_title' => 'Teme', + 'activate_button' => 'Aktiviraj', + 'active_button' => 'Aktiviraj', + 'customize_theme' => 'Izmeni temu', + 'customize_button' => 'Izmeni', + 'duplicate_button' => 'Duplikat', + 'duplicate_title' => 'Dupliraj temu', + 'duplicate_theme_success' => 'Tema duplirana!', + 'manage_button' => 'Upravljaj', + 'manage_title' => 'Upravljaj temom', + 'edit_properties_title' => 'Tema', + 'edit_properties_button' => 'Izmeni svojstva', + 'save_properties' => 'Snimi svojstva', + 'import_button' => 'Uvezi', + 'import_title' => 'Uvezi temu', + 'import_theme_success' => 'Tema uvežena!', + 'import_uploaded_file' => 'Arhivni fajl teme', + 'import_overwrite_label' => 'Pregazi postojeće fajlove', + 'import_overwrite_comment' => 'Nemoj čekirati ovo polje ako želiš samo da uvezeš nove fajlove', + 'import_folders_label' => 'Direktorijumi', + 'import_folders_comment' => 'Odaberi direktorijume teme koje želiš da uvezeš', + 'export_button' => 'Eksportuj', + 'export_title' => 'Eksportuj temu', + 'export_folders_label' => 'Direktorijumi', + 'export_folders_comment' => 'Odaberi direktorijume teme koje želiš da izvezeš', + 'delete_button' => 'Izbriši', + 'delete_confirm' => 'Izbriši ovu temu? Ova radnja se ne može poništiti.', + 'delete_active_theme_failed' => 'Aktivna tema se ne može izbrisati, pokušaj prvo da napraviš i aktiviraš drugu.', + 'delete_theme_success' => 'Tema izbrisana!', + 'create_title' => 'Napravi temu', + 'create_button' => 'Napravi', + 'create_new_blank_theme' => 'Napravi novu praznu temu', + 'create_theme_success' => 'Tema napravljena!', + 'create_theme_required_name' => 'Odaberi naziv za temu.', + 'new_directory_name_label' => 'Direktorijum teme', + 'new_directory_name_comment' => 'Odaberi drugi naziv za direktorijum teme koja je duplikat.', + 'dir_name_invalid' => 'Naziv može sadržati samo brojeve, latinska slova, kao i sledeće simbole: _-', + 'dir_name_taken' => 'Direktorijum za željenu temu postoji.', + 'find_more_themes' => 'Pronađi još tema', + 'saving' => 'Čuvanje tema...', + 'return' => 'Nazad na listu tema', + ], + 'maintenance' => [ + 'settings_menu' => 'Mod održavanja', + 'settings_menu_description' => 'Konfiguriši mod održavanja stranice i uključi/isključi isti.', + 'is_enabled' => 'Uključi mod održavanja', + 'is_enabled_comment' => 'Izaberi stranicu za prikazivanje kada je mod održavanja uključen.', + 'hint' => 'Mod održavanja će prikazati odabranu stranicu korisnicima koji nisu ulogovani preko pozadinskog sistema.', + ], + 'page' => [ + 'not_found_name' => "Strana ':name' nije pronađena", + 'not_found' => [ + 'label' => 'Strana nije pronađena', + 'help' => 'Tražena strana nije pronađena.', + ], + 'custom_error' => [ + 'label' => 'Greška sa stranom', + 'help' => "Žao nam je, nešto je pošlo po zlu pa strana ne može biti prikazana.", + ], + 'menu_label' => 'Strane', + 'unsaved_label' => 'Nesačuvana strana(e)', + 'no_list_records' => 'Nema pronađenih strana', + 'new' => 'Nova strana', + 'invalid_url' => 'Format URL-a nije validan. URL treba početi sa kosom crtom i može sadržati brojeve, latinska slova, kao i sledeće simbole: ._-[]:?|/+*^$', + 'delete_confirm_multiple' => 'Izbriši odabrane strane?', + 'delete_confirm_single' => 'Izbriši ovu stranu?', + 'no_layout' => '-- nema plana --', + 'cms_page' => 'CMS strana', + 'title' => 'Naslov strane', + 'url' => 'URL strane', + 'file_name' => 'Naziv fajla strane', + ], + 'layout' => [ + 'not_found_name' => "Plan ':name' nije pronađen", + 'menu_label' => 'Planovi', + 'unsaved_label' => 'Nesačuvani plan(ovi)', + 'no_list_records' => 'Nema pronađenih planova', + 'new' => 'Novi plan', + 'delete_confirm_multiple' => 'Izbriši izabrane planove?', + 'delete_confirm_single' => 'Izbriši ovaj plan?', + ], + 'partial' => [ + 'not_found_name' => "Parcijal ':name' nije pronađen", + 'invalid_name' => 'Naziv parcijala nije validan: :name.', + 'menu_label' => 'Parcijal', + 'unsaved_label' => 'Nesačuvan parcijal(i)', + 'no_list_records' => 'Nema pronađenih parcijala', + 'delete_confirm_multiple' => 'Izbriši izabrane parcijale?', + 'delete_confirm_single' => 'Izbriši ovaj parcijal?', + 'new' => 'Novi parcijal', + ], + 'content' => [ + 'not_found_name' => "Fajl sadržaja ':name' nije pronađen", + 'menu_label' => 'Sadržaj', + 'unsaved_label' => 'Nesačuvani sadržaj', + 'no_list_records' => 'Fajlovi za sardžaj nisu pronađeni', + 'delete_confirm_multiple' => 'Izbriši odabrane fajlove ili direktorijume za sadržaj?', + 'delete_confirm_single' => 'Izbriši ovaj fajl za sadržaj?', + 'new' => 'Novi fajl za sadržaj', + ], + 'ajax_handler' => [ + 'invalid_name' => 'Naziv za AJAX rukovatelja nije validan: :name.', + 'not_found' => "AJAX rukovatelj ':name' nije pronađen.", + ], + 'cms' => [ + 'menu_label' => 'CMS', + ], + 'sidebar' => [ + 'add' => 'Dodaj', + 'search' => 'Traži...', + ], + 'editor' => [ + 'settings' => 'Podešavanja', + 'title' => 'Naslov', + 'new_title' => 'Naslov nove strane', + 'url' => 'URL', + 'filename' => 'Naziv fajla', + 'layout' => 'Plan', + 'description' => 'Opis', + 'preview' => 'Pregled', + 'meta' => 'Meta', + 'meta_title' => 'Meta Naslov', + 'meta_description' => 'Meta Opis', + 'markup' => 'Označavanje', + 'code' => 'Kod', + 'content' => 'Sadržaj', + 'hidden' => 'Skrivena', + 'hidden_comment' => 'Skrivena stranica je dostupna samo korisnicima koji su ulogovani na pozadinski sistem.', + 'enter_fullscreen' => 'Uđite u režim punog ekrana', + 'exit_fullscreen' => 'Izađite iz režima punog ekrana', + 'open_searchbox' => 'Otvori polje za pretragu', + 'close_searchbox' => 'Zatvori polje za pretragu', + 'open_replacebox' => 'Otvori polje za zamenu', + 'close_replacebox' => 'Zatvori polje za zamenu', + 'commit' => 'Izvrši', + 'reset' => 'Resetuj', + 'commit_confirm' => 'Da li zaista želite da izvršite promene nad ovim fajlom? Ovo će pregaziti postojeći', + 'reset_confirm' => 'Da li zaista želite da resetujete ovaj fajl? Ovo će u potpunosti zameniti trenutni sa onim koji je na sistemu', + 'committing' => 'Izvršavanje', + 'resetting' => 'Resetovanje', + 'commit_success' => 'Izvršenje :type je uspešno.', + 'reset_success' => 'Resetovanje :type je uspešno.', + ], + 'asset' => [ + 'menu_label' => 'Sredstva', + 'unsaved_label' => 'Nesačuvano sredstvo(a)', + 'drop_down_add_title' => 'Dodaj...', + 'drop_down_operation_title' => 'Radnja...', + 'upload_files' => 'Otpremi fajl(ove)', + 'create_file' => 'Napravi fajl', + 'create_directory' => 'Napravi direktorijum', + 'directory_popup_title' => 'Novi direktorijum', + 'directory_name' => 'Naziv direktorijuma', + 'rename' => 'Promeni naziv', + 'delete' => 'Izbriši', + 'move' => 'Pomeri', + 'select' => 'Izaberi', + 'new' => 'Novi fajl', + 'rename_popup_title' => 'Promeni naziv', + 'rename_new_name' => 'Novi naziv', + 'invalid_path' => 'Putanja može sadržati samo brojeve, latinska slova, razmake, kao i sledeće simbole: ._-/', + 'error_deleting_file' => 'Greška pri brisanju fajla :name.', + 'error_deleting_dir_not_empty' => 'Greška pri brisanju direktorijuma :name. Direktorijum nije prazan.', + 'error_deleting_dir' => 'Greška pri brisanju direktorijuma :name.', + 'invalid_name' => 'Naziv može sadržati samo brojeve, latinska slova, razmake, kao i sledeće simbole: ._-', + 'original_not_found' => 'Originalni fajl ili direktorijum nije pronađen', + 'already_exists' => 'Fajl ili direktorijum sa ovim nazivom već postoji', + 'error_renaming' => 'Greška pri promeni naziva fajla ili direktorijuma', + 'name_cant_be_empty' => 'Naziv ne može biti prazan', + 'too_large' => 'Otpremljeni fajl je previše velik. Maksimalna dozvoljena veličina je :max_size', + 'type_not_allowed' => 'Samo sledeći tipovi fajla su dozvoljeni: :allowed_types', + 'file_not_valid' => 'Fajl nije validan', + 'error_uploading_file' => "Greška pri otpremanju fajla ':name': :error", + 'move_please_select' => 'Izaberi', + 'move_destination' => 'Odredište direktorijuma', + 'move_popup_title' => 'Pomeri sredstva', + 'move_button' => 'Pomeri', + 'selected_files_not_found' => 'Izabrani fajlovi nisu pronađeni', + 'select_destination_dir' => 'Izaberi odredišni direktorijum', + 'destination_not_found' => 'Odredišni direktorijum nije pronađen', + 'error_moving_file' => 'Greška pri pomeranju fajla :file', + 'error_moving_directory' => 'Greška pri pomeranju direktorijuma :dir', + 'error_deleting_directory' => 'Greška pri brisanju originalnog direktorijuma :dir', + 'no_list_records' => 'Nema pronađenih fajlova', + 'delete_confirm' => 'Izbriši izabrane fajlove ili direktorijume?', + 'path' => 'Putanja', + ], + 'component' => [ + 'menu_label' => 'Komponente', + 'unnamed' => 'Bez naziva', + 'no_description' => 'Opis nije dat', + 'alias' => 'Pseudonim', + 'alias_description' => 'Jedinstven naziv koji je dat komponenti kada se koristi u stranici ili kodu plana.', + 'validation_message' => 'Pseudonimi komponente su neophodni i mogu sadržati samo latinske simbole, brojeve i donje crte. Pseudonimi bi trebalo da počinju latinskim simbolom.', + 'invalid_request' => 'Šablon ne može biti sačuvan zbog podataka koji nisu validni.', + 'no_records' => 'Nema pronađenih komponenti', + 'not_found' => "Komponenta ':name' nije pronađena.", + 'method_not_found' => "Komponenta ':name' ne sadrži ':method'.", + 'soft_component' => 'Opciona komponenta', + 'soft_component_description' => 'Ova komponenta nedostaje ali je opciona.', + ], + 'template' => [ + 'invalid_type' => 'Nepoznati tip šablona.', + 'not_found' => 'Šablon nije pronađen.', + 'saved' => 'Šablon sačuvan.', + 'no_list_records' => 'Zapisi nisu pronađeni', + 'delete_confirm' => 'Izbriši izabrane šablone?', + 'order_by' => 'Sortiraj po', + ], + 'permissions' => [ + 'name' => 'CMS', + 'manage_content' => 'Upravljaj sadržajem sajta', + 'manage_assets' => 'Upravljaj slikama, JS i CSS fajlovima sajta', + 'manage_pages' => 'Napravi, modifikuj i izbriši stranice sajta', + 'manage_layouts' => 'Napravi, modifikuj i izbriši planove CMS-a', + 'manage_partials' => 'Napravi, modifikuj i izbriši parcijale CMS-a', + 'manage_themes' => 'Aktiviraj, deaktiviraj i konfiguriši teme CMS-a', + 'manage_theme_options' => 'Konfiguriši opcije izmena za aktivnu temu', + ], + 'theme_log' => [ + 'hint' => 'Ovaj log prikazuje promene načinjene nad temom od strane administratora u pozadinskom delu sistema.', + 'menu_label' => 'Log teme', + 'menu_description' => 'Prikaži promene načinjene nad aktivnom temom.', + 'empty_link' => 'Isprazni log teme', + 'empty_loading' => 'Pražnjenje loga teme...', + 'empty_success' => 'Log teme je ispražnjen', + 'return_link' => 'Vrati se na logove teme', + 'id' => 'ID', + 'id_label' => 'ID loga', + 'created_at' => 'Datum & vreme', + 'user' => 'Korisnik', + 'type' => 'Tip', + 'type_create' => 'Napravi', + 'type_update' => 'Ažuriraj', + 'type_delete' => 'Izbriši', + 'theme_name' => 'Tema', + 'theme_code' => 'Kod teme', + 'old_template' => 'Šablon (Stari)', + 'new_template' => 'Šablon (Novi)', + 'template' => 'Šablon', + 'diff' => 'Izmene', + 'old_value' => 'Stara vrednost', + 'new_value' => 'Nova vrednost', + 'preview_title' => 'Izmene šablona', + 'template_updated' => 'Šablon je ažuriran', + 'template_created' => 'Šablon je napravljen', + 'template_deleted' => 'Šablon je izbrisan', + ], +]; diff --git a/modules/system/lang/ar/lang.php b/modules/system/lang/ar/lang.php index 91ca67bd6..c1ed3df95 100644 --- a/modules/system/lang/ar/lang.php +++ b/modules/system/lang/ar/lang.php @@ -36,6 +36,7 @@ return [ 'pt-br' => 'Português (Brasil)', 'pt-pt' => 'Português (Portugal)', 'ro' => 'Română', + 'rs' => 'Srpski', 'ru' => 'Русский', 'fi' => 'Suomi', 'sv' => 'Svenska', diff --git a/modules/system/lang/en/lang.php b/modules/system/lang/en/lang.php index 3adf7f6c9..6c57d9e68 100644 --- a/modules/system/lang/en/lang.php +++ b/modules/system/lang/en/lang.php @@ -37,6 +37,7 @@ return [ 'pt-br' => 'Português (Brasil)', 'pt-pt' => 'Português (Portugal)', 'ro' => 'Română', + 'rs' => 'Srpski', 'ru' => 'Русский', 'fi' => 'Suomi', 'sv' => 'Svenska', diff --git a/modules/system/lang/et/lang.php b/modules/system/lang/et/lang.php index 85ff20188..b47c46758 100644 --- a/modules/system/lang/et/lang.php +++ b/modules/system/lang/et/lang.php @@ -33,6 +33,7 @@ return [ 'pl' => 'Polski', 'pt-br' => 'Português (Brasil)', 'ro' => 'Română', + 'rs' => 'Srpski', 'ru' => 'Русский', 'sv' => 'Svenska', 'sk' => 'Slovenský', diff --git a/modules/system/lang/fa/lang.php b/modules/system/lang/fa/lang.php index fc65f4d8a..fdbdd7ad9 100644 --- a/modules/system/lang/fa/lang.php +++ b/modules/system/lang/fa/lang.php @@ -35,6 +35,7 @@ return [ 'pt-br' => 'Português (Brasil)', 'pt-pt' => 'Português (Portugal)', 'ro' => 'Română', + 'rs' => 'Srpski', 'ru' => 'Русский', 'fi' => 'Suomi', 'sv' => 'Svenska', diff --git a/modules/system/lang/fi/lang.php b/modules/system/lang/fi/lang.php index 0bb43eed5..e577f3b42 100644 --- a/modules/system/lang/fi/lang.php +++ b/modules/system/lang/fi/lang.php @@ -36,6 +36,7 @@ return [ 'pt-br' => 'Português (Brasil)', 'pt-pt' => 'Português (Portugal)', 'ro' => 'Română', + 'rs' => 'Srpski', 'ru' => 'Русский', 'sv' => 'Svenska', 'sk' => 'Slovenský', diff --git a/modules/system/lang/lt/lang.php b/modules/system/lang/lt/lang.php index 45ad1bd02..a0b3f527d 100644 --- a/modules/system/lang/lt/lang.php +++ b/modules/system/lang/lt/lang.php @@ -32,6 +32,7 @@ return [ 'pl' => 'Polski', 'pt-br' => 'Português (Brasil)', 'ro' => 'Română', + 'rs' => 'Srpski', 'ru' => 'Русский', 'sv' => 'Svenska', 'sk' => 'Slovenský', diff --git a/modules/system/lang/nl/lang.php b/modules/system/lang/nl/lang.php index a04790aab..5bd0d76cd 100644 --- a/modules/system/lang/nl/lang.php +++ b/modules/system/lang/nl/lang.php @@ -37,6 +37,7 @@ return [ 'pt-br' => 'Português (Brasil)', 'pt-pt' => 'Português (Portugal)', 'ro' => 'Română', + 'rs' => 'Srpski', 'ru' => 'Русский', 'fi' => 'Suomi', 'sv' => 'Svenska', diff --git a/modules/system/lang/pt-pt/lang.php b/modules/system/lang/pt-pt/lang.php index fe8836c12..7229a69d9 100644 --- a/modules/system/lang/pt-pt/lang.php +++ b/modules/system/lang/pt-pt/lang.php @@ -32,6 +32,7 @@ return [ 'pt-pt' => 'Português (Portugal)', 'pt-br' => 'Português (Brasil)', 'ro' => 'Romeno', + 'rs' => 'Srpski', 'ru' => 'Russo', 'sv' => 'Suéco', 'sk' => 'Esloveno', diff --git a/modules/system/lang/rs/client.php b/modules/system/lang/rs/client.php new file mode 100644 index 000000000..44e2e3fac --- /dev/null +++ b/modules/system/lang/rs/client.php @@ -0,0 +1,102 @@ + [ + 'formatting' => 'Formatiranje', + 'quote' => 'Citat', + 'code' => 'Kod', + 'header1' => 'Zaglavlje 1', + 'header2' => 'Zaglavlje 2', + 'header3' => 'Zaglavlje 3', + 'header4' => 'Zaglavlje 4', + 'header5' => 'Zaglavlje 5', + 'header6' => 'Zaglavlje 6', + 'bold' => 'Podebljaj', + 'italic' => 'Ukosi', + 'unorderedlist' => 'Neuređena lista', + 'orderedlist' => 'Uređena lista', + 'video' => 'Video', + 'image' => 'Slika', + 'link' => 'Link', + 'horizontalrule' => 'Ubaci horizontalnu liniju', + 'fullscreen' => 'Ceo ekran', + 'preview' => 'Pregled', + ], + 'mediamanager' => [ + 'insert_link' => 'Ubaci link', + 'insert_image' => 'Ubaci sliku', + 'insert_video' => 'Ubaci video zapis', + 'insert_audio' => 'Ubaci zvučni zapis', + 'invalid_file_empty_insert' => 'Odaberi fajl za ubacivanje linkova.', + 'invalid_file_single_insert' => 'Odaberi jedan fajl za ubacivanje.', + 'invalid_image_empty_insert' => 'Odaberi sliku/slike za ubacivanje.', + 'invalid_video_empty_insert' => 'Odaberi video zapis za ubacivanje.', + 'invalid_audio_empty_insert' => 'Odaberi audio zapis za ubacivanje.', + ], + 'alert' => [ + 'confirm_button_text' => 'OK', + 'cancel_button_text' => 'Otkaži', + 'widget_remove_confirm' => 'Otkloni ovaj posrednički element?', + ], + 'datepicker' => [ + 'previousMonth' => 'Prethodni mesec', + 'nextMonth' => 'Sledeći mesec', + 'months' => ['Januar', 'Februar', 'Mart', 'April', 'Maj', 'Juni', 'Juli', 'Avgust', 'Septembar', 'Oktobar', 'Novembar', 'Decembar'], + 'weekdays' => ['Nedelja', 'Ponedeljak', 'Utorak', 'Sreda', 'Četvrtak', 'Petak', 'Subota'], + 'weekdaysShort' => ['Ned', 'Pon', 'Uto', 'Sre', 'Čet', 'Pet', 'Sub'] + ], + 'colorpicker' => [ + 'choose' => 'Ok', + ], + 'filter' => [ + 'group' => [ + 'all' => 'sve', + ], + 'scopes' => [ + 'apply_button_text' => 'Primeni', + 'clear_button_text' => 'Očisti', + ], + 'dates' => [ + 'all' => 'svi', + 'filter_button_text' => 'Filtriraj', + 'reset_button_text' => 'Resetuj', + 'date_placeholder' => 'Datum', + 'after_placeholder' => 'Pre', + 'before_placeholder' => 'Posle', + ], + 'numbers' => [ + 'all' => 'svi', + 'filter_button_text' => 'Filtriraj', + 'reset_button_text' => 'Resetuj', + 'min_placeholder' => 'Minimum', + 'max_placeholder' => 'Maksimum', + ], + ], + 'eventlog' => [ + 'show_stacktrace' => 'Prikaži trag', + 'hide_stacktrace' => 'Sakrij trag', + 'tabs' => [ + 'formatted' => 'Formatiraj', + 'raw' => 'Izvorno', + ], + 'editor' => [ + 'title' => 'Izvorni kod editora', + 'description' => 'Vaš operativni sistem treba da bude konfigurisan za osluškivanje ovih URL šema.', + 'openWith' => 'Otvori sa', + 'remember_choice' => 'Zapamti izabranu opciju za ovu sesiju', + 'open' => 'Otvori', + 'cancel' => 'Otkaži', + ], + ], +]; diff --git a/modules/system/lang/rs/lang.php b/modules/system/lang/rs/lang.php new file mode 100644 index 000000000..86e9dc659 --- /dev/null +++ b/modules/system/lang/rs/lang.php @@ -0,0 +1,480 @@ + [ + 'name' => 'OctoberCMS', + 'tagline' => 'Povratak osnovama', + ], + 'locale' => [ + 'ar' => 'العربية', + 'be' => 'Беларуская', + 'bg' => 'Български', + 'ca' => 'Català', + 'cs' => 'Čeština', + 'da' => 'Dansk', + 'en' => 'English (United States)', + 'en-au' => 'English (Australia)', + 'en-ca' => 'English (Canada)', + 'en-gb' => 'English (United Kingdom)', + 'et' => 'Eesti', + 'de' => 'Deutsch', + 'el' => 'Ελληνικά', + 'es' => 'Español', + 'es-ar' => 'Español (Argentina)', + 'fa' => 'فارسی', + 'fr' => 'Français', + 'fr-ca' => 'Français (Canada)', + 'hu' => 'Magyar', + 'id' => 'Bahasa Indonesia', + 'it' => 'Italiano', + 'ja' => '日本語', + 'kr' => '한국어', + 'lt' => 'Lietuvių', + 'lv' => 'Latviešu', + 'nb-no' => 'Norsk (Bokmål)', + 'nl' => 'Nederlands', + 'pl' => 'Polski', + 'pt-br' => 'Português (Brasil)', + 'pt-pt' => 'Português (Portugal)', + 'ro' => 'Română', + 'ru' => 'Русский', + 'fi' => 'Suomi', + 'sv' => 'Svenska', + 'sk' => 'Slovenský', + 'sl' => 'Slovenščina', + 'rs' => 'Srpski', + 'th' => 'ไทย', + 'tr' => 'Türkçe', + 'uk' => 'Українська мова', + 'zh-cn' => '简体中文', + 'zh-tw' => '繁體中文', + 'vn' => 'Tiếng việt', + ], + 'directory' => [ + 'create_fail' => 'Nije moguće napraviti direktorijum: :name', + ], + 'file' => [ + 'create_fail' => 'Nije moguće napraviti fajl: :name', + ], + 'combiner' => [ + 'not_found' => "Kombinovani fajl ':name' nije pronađen.", + ], + 'system' => [ + 'name' => 'Sistem', + 'menu_label' => 'Sistem', + 'categories' => [ + 'cms' => 'CMS', + 'misc' => 'Ostalo', + 'logs' => 'Logovi', + 'mail' => 'Pošta', + 'shop' => 'Prodavnica', + 'team' => 'Tim', + 'users' => 'Korisnici', + 'system' => 'Sistem', + 'social' => 'Društvene mreže', + 'backend' => 'Pozadinski sistem', + 'events' => 'Događaji', + 'customers' => 'Mušterije', + 'my_settings' => 'Moja podešavanja', + 'notifications' => 'Obaveštenja', + ], + ], + 'theme' => [ + 'label' => 'Tema', + 'unnamed' => 'Tema bez naziva', + 'name' => [ + 'label' => 'Naziv teme', + 'help' => 'Imenuj temu po njenom jedinstvenom kodu. Na primer, RainLab.Vanilla', + ], + ], + 'themes' => [ + 'install' => 'Instaliraj teme', + 'search' => 'traži teme za instaliranje...', + 'installed' => 'Instalirane teme', + 'no_themes' => 'Nijedna tema nije instalirana sa tržišta.', + 'recommended' => 'Preporučene', + 'remove_confirm' => 'Da li zaista želite da uklonite temu?', + ], + 'plugin' => [ + 'label' => 'Priključak', + 'unnamed' => 'Neimenovani priključak', + 'name' => [ + 'label' => 'Naziv priključka', + 'help' => 'Imenuj priključak po njegovom jedinstvenom kodu. Na primer, RainLab.Blog', + ], + 'by_author' => 'Od :name', + ], + 'plugins' => [ + 'manage' => 'Upravljaj priključcima', + 'install' => 'Instaliraj priključke', + 'install_products' => 'Instaliraj proizvode', + 'search' => 'traži priključke za instaliranje...', + 'installed' => 'Instalirani priključci', + 'no_plugins' => 'Nijedan priključak nije instaliran sa tržišta.', + 'recommended' => 'Preporučeni', + 'plugin_label' => 'Priključak', + 'unknown_plugin' => 'Priključak je uklonjen sa sistema.', + 'select_label' => 'Izaberi radnju...', + 'bulk_actions_label' => 'Više radnji', + 'check_yes' => 'Da', + 'check_no' => 'Ne', + 'unfrozen' => 'Uključeno aužuriranje', + 'enabled' => 'Priključak uključen', + 'freeze' => 'isključi ažuriranje za', + 'unfreeze' => 'uključi ažuriranje za', + 'enable' => 'uključi', + 'disable' => 'isključi', + 'refresh' => 'resetuj', + 'remove' => 'Ukloni', + 'freeze_label' => 'Isključi ažuriranje', + 'unfreeze_label' => 'Uključi ažuriranje', + 'enable_label' => 'Uključi priključke', + 'disable_label' => 'Isključi priključke', + 'refresh_label' => 'Resetuj podatke priključka', + 'action_confirm' => 'Da li zaista želite da :action ove priključke?', + 'freeze_success' => 'Uspešno isključeno ažuriranje za izabrane priključke.', + 'unfreeze_success' => 'Uspešno uključeno ažuriranje za izabrane priključke.', + 'enable_success' => 'Izabrani priključci su uspešno uključeni.', + 'disable_success' => 'Izabrani priključci su uspešno isključeni.', + 'refresh_confirm' => 'Da li zaista želite da resetujete sledeće priključke? Ovo će resetovati podatke svakog priključka vraćajući ih na inicijalno stanje.', + 'refresh_success' => 'Izabrani priključci su uspešno resetovani.', + 'remove_confirm' => 'Da li zaista želite da uklonite sledeće priključke? Ovo će takođe ukloniti asocirane podatke.', + 'remove_success' => 'Izabrani priključci su uspešno uklonjeni.', + ], + 'project' => [ + 'name' => 'Projekat', + 'owner_label' => 'Vlasnik', + 'attach' => 'Dodaj projekat', + 'detach' => 'Odvoji projekat', + 'none' => 'Nijedan', + 'id' => [ + 'label' => 'ID projekta', + 'help' => 'Kako pronaći svoj ID projekta', + 'missing' => 'Specifikuj ID projekta za korišćenje.', + ], + 'detach_confirm' => 'Da li zaista želite da odvojite ovaj projekat?', + 'unbind_success' => 'Projekat je uspešno odvojen.', + ], + 'settings' => [ + 'menu_label' => 'Podešavanja', + 'not_found' => 'Nije moguće pronaći navedena podešavanja.', + 'missing_model' => 'Na stranici sa podešavanjima nedostaje definicija modela.', + 'update_success' => 'Podešavanje :name je uspešno ažurirano.', + 'return' => 'Nazad na sistemska podešavanja', + 'search' => 'Traži', + ], + 'mail' => [ + 'log_file' => 'Fajl sa logovima', + 'menu_label' => 'Konfiguracija pošte', + 'menu_description' => 'Upravljaj konfiguracijom pošte.', + 'general' => 'Generalno', + 'method' => 'Metod pošte', + 'sender_name' => 'Ime pošiljaoca', + 'sender_email' => 'Email pošiljaoca', + 'php_mail' => 'PHP mejl', + 'smtp' => 'SMTP', + 'smtp_address' => 'SMTP adresa', + 'smtp_authorization' => 'Potrebna SMTP autorizacija', + 'smtp_authorization_comment' => 'Čekiraj ovo polje ako tvoj server zahteva SMTP autorizaciju.', + 'smtp_username' => 'Korisničko ime', + 'smtp_password' => 'Lozinka', + 'smtp_port' => 'SMTP port', + 'smtp_ssl' => 'Potrebna SSL konekcija', + 'smtp_encryption' => 'SMTP šifarski protokol', + 'smtp_encryption_none' => 'Bez šifrovanja', + 'smtp_encryption_tls' => 'TLS', + 'smtp_encryption_ssl' => 'SSL', + 'sendmail' => 'Sendmail', + 'sendmail_path' => 'Sendmail putanja', + 'sendmail_path_comment' => 'Specificiraj putanju Sendmail programa.', + 'mailgun' => 'Mailgun', + 'mailgun_domain' => 'Mailgun domen', + 'mailgun_domain_comment' => 'Specificiraj Mailgun domen.', + 'mailgun_secret' => 'Mailgun tajna', + 'mailgun_secret_comment' => 'Unesi svoj Mailgun API ključ.', + 'mandrill' => 'Mandrill', + 'mandrill_secret' => 'Mandrill tajna', + 'mandrill_secret_comment' => 'Unesi svoj Mandrill API ključ.', + 'ses' => 'SES', + 'ses_key' => 'SES ključ', + 'ses_key_comment' => 'Unesi svoj SES API ključ.', + 'ses_secret' => 'SES tajna', + 'ses_secret_comment' => 'Unesi svoju SES API tajnu.', + 'sparkpost' => 'SparkPost', + 'sparkpost_secret' => 'SparkPost tajna', + 'sparkpost_secret_comment' => 'Unesi svoju SparkPost API tajnu.', + 'ses_region' => 'SES region', + 'ses_region_comment' => 'Unesi svoj SES region. (e.g. us-east-1)', + 'drivers_hint_header' => 'Drajveri nisu instalirani.', + 'drivers_hint_content' => 'Ovaj metod pošte zahteva instaliranje ":plugin" priključka.', + ], + 'mail_templates' => [ + 'menu_label' => 'Šabloni pošte', + 'menu_description' => 'Izmeni šablone pošte koji se šalju korisnicima i administratorima.', + 'new_template' => 'Novi šablon', + 'new_layout' => 'Novi plan', + 'new_partial' => 'Novi parcijal', + 'template' => 'Šablon', + 'templates' => 'Šabloni', + 'partial' => 'Parcijal', + 'partials' => 'Parcijali', + 'menu_layouts_label' => 'Planovi pošte', + 'menu_partials_label' => 'Parcijali pošte', + 'layout' => 'Plan', + 'layouts' => 'Planovi', + 'no_layout' => '-- Bez plana --', + 'name' => 'Naziv', + 'name_comment' => 'Unikatni naziv za referenciranje ovog šablona.', + 'code' => 'Kod', + 'code_comment' => 'Unikatan kod za referenciranje ovog šablona.', + 'subject' => 'Naslov', + 'subject_comment' => 'Naslov e-pošte.', + 'description' => 'Opis', + 'content_html' => 'HTML', + 'content_css' => 'CSS', + 'content_text' => 'Običan tekst', + 'test_send' => 'Pošalji testnu poruku', + 'test_success' => 'Test poruka poslata.', + 'test_confirm' => 'Pošalji test poruku na :email. Nastavi?', + 'creating' => 'Pravljenje šablona...', + 'creating_layout' => 'Pravljenje plana...', + 'saving' => 'Čuvanje šablona...', + 'saving_layout' => 'Čuvanje plana...', + 'delete_confirm' => 'Izbriši ovaj šablon?', + 'delete_layout_confirm' => 'Izbriši ovaj plan?', + 'deleting' => 'Brisanje šablona...', + 'deleting_layout' => 'Brisanje plana...', + 'sending' => 'Slanje testne poruke...', + 'return' => 'Povratak na listu šablona', + 'options' => 'Opcije', + 'disable_auto_inline_css' => 'Isključi automatsko uvođenje CSS-a.', + ], + 'mail_brand' => [ + 'menu_label' => 'Brendovanje pošte', + 'menu_description' => 'Modifikuj boje i izgled šablona pošte.', + 'page_title' => 'Izmeni izgled pošte', + 'sample_template' => [ + 'heading' => 'Zaglavlje', + 'paragraph' => 'Ovo je paragraf ispunjen prozvoljnim tekstom koji ne znači ništa.', + 'table' => [ + 'item' => 'Element', + 'description' => 'Opis', + 'price' => 'Cena', + 'centered' => 'Centrirana', + 'right_aligned' => 'Poravnjana na desno', + ], + 'buttons' => [ + 'primary' => 'Primarno dugme', + 'positive' => 'Pozitivno dugme', + 'negative' => 'Negativno dugme', + ], + 'panel' => 'Koliko je fenomenalan ovaj panel?', + 'more' => 'Još malo teksta', + 'promotion' => 'Kupon: OKTOBAR', + 'subcopy' => 'Ovo je podkopija ovog mejla.', + 'thanks' => 'Hvala', + ], + 'fields' => [ + '_section_background' => 'Pozadina', + 'body_bg' => 'Pozadina tela', + 'content_bg' => 'Pozadina sadržaja', + 'content_inner_bg' => 'Pozadina unutrašnjeg sadržaja', + '_section_buttons' => 'Dugmići', + 'button_text_color' => 'Boja teksta dugmeta', + 'button_primary_bg' => 'Primarna pozadina dugmeta', + 'button_positive_bg' => 'Pozitivna pozadina dugmeta', + 'button_negative_bg' => 'Negativna pozadina dugmeta', + '_section_type' => 'Tipografija', + 'header_color' => 'Boja zaglavlja mejla', + 'heading_color' => 'Boja zaglavlja', + 'text_color' => 'Boja teksta', + 'link_color' => 'Boja linka', + 'footer_color' => 'Boja podnožja', + '_section_borders' => 'Ivice', + 'body_border_color' => 'Boja ivica tela', + 'subcopy_border_color' => 'Boja ivica podkopije', + 'table_border_color' => 'Boja ivica tabele', + '_section_components' => 'Komponente', + 'panel_bg' => 'Pozadina panela', + 'promotion_bg' => 'Pozadina promocije', + 'promotion_border_color' => 'Boja ivica promocije', + ], + ], + 'install' => [ + 'project_label' => 'Dodaj projektu', + 'plugin_label' => 'Instaliraj priključak', + 'theme_label' => 'Instaliraj temu', + 'missing_plugin_name' => 'Specificiraj naziv priključka za instaliranje.', + 'missing_theme_name' => 'Specificiraj naziv teme za instaliranje.', + 'install_completing' => 'Završavanje instalacionog procesa', + 'install_success' => 'Priključak je instaliran uspešno', + ], + 'updates' => [ + 'title' => 'Upravljaj ispravkama', + 'name' => 'Ažuriraj softver', + 'menu_label' => 'Ispravke & priključci', + 'menu_description' => 'Ažuriraj sistem, upravljaj i instaliraj priključke i teme.', + 'return_link' => 'Povratak na ažuriranje sistema', + 'check_label' => 'Proveri ispravke', + 'retry_label' => 'Pokušaj ponovo', + 'plugin_name' => 'Naziv', + 'plugin_code' => 'Kod', + 'plugin_description' => 'Opis', + 'plugin_version' => 'Verzija', + 'plugin_author' => 'Autor', + 'plugin_not_found' => 'Priključak nije pronađen', + 'core_current_build' => 'Trenutna verzija', + 'core_view_changelog' => 'Prikaži listu promena', + 'core_build' => 'Verzija :build', + 'core_build_help' => 'Novija verzija je dostupna.', + 'core_downloading' => 'Dopremanje fajlova aplikacije', + 'core_extracting' => 'Ekstrakcija fajlova aplikacije', + 'core_set_build' => 'Postavljanje broja verzije', + 'changelog' => 'Lista izmena', + 'changelog_view_details' => 'Prikaži detalje', + 'plugins' => 'Priključci', + 'themes' => 'Teme', + 'disabled' => 'Isključeni', + 'plugin_downloading' => 'Dopremanje priključka: :name', + 'plugin_extracting' => 'Ektrakcija priključka: :name', + 'plugin_version_none' => 'Novi priključak', + 'plugin_current_version' => 'Trenutna verzija', + 'theme_new_install' => 'Instalacija nove teme.', + 'theme_downloading' => 'Dopremanje teme: :name', + 'theme_extracting' => 'Ekstrakcija teme: :name', + 'update_label' => 'Ažuriranje softvera', + 'update_completing' => 'Završavanje procesa ažuriranja', + 'update_loading' => 'Učitavanje mogućih ispravki...', + 'update_success' => 'Proces ažuriranja je završen', + 'update_failed_label' => 'Ažuriranje je neuspešno', + 'force_label' => 'Ažuriraj na silu', + 'found' => [ + 'label' => 'Nove ispravke su pronađene!', + 'help' => 'Klikni na ažuriraj softver da bi započeo proces.', + ], + 'none' => [ + 'label' => 'Nema ispravki', + 'help' => 'Nove ispravke nisu pronađene.', + ], + 'important_action' => [ + 'empty' => 'Izaberi radnju', + 'confirm' => 'Potvrdi ispravke', + 'skip' => 'Preskoči ovu ispravku (samo jednom)', + 'ignore' => 'Preskoči ovu ispravku (uvek)', + ], + 'important_action_required' => 'Akcija neophodna', + 'important_view_guide' => 'Prikaži vodič za nadogradnju', + 'important_view_release_notes' => 'Prikaži beleške o izdanju', + 'important_alert_text' => 'Neke ispravke zahtevaju vašu pažnju.', + 'details_title' => 'Detalji priključka', + 'details_view_homepage' => 'Prikaži početnu stranicu', + 'details_readme' => 'Dokumentacija', + 'details_readme_missing' => 'Nema dokumentacije.', + 'details_changelog' => 'Lista izmena', + 'details_changelog_missing' => 'Nema liste izmena.', + 'details_upgrades' => 'Vodič za nadogradnju', + 'details_upgrades_missing' => 'Nema vodiča za nadogradnju.', + 'details_licence' => 'Licenca', + 'details_licence_missing' => 'Nema licence.', + 'details_current_version' => 'Trenutna verzija', + 'details_author' => 'Autor', + ], + 'server' => [ + 'connect_error' => 'Greška pri povezivanju na server.', + 'response_not_found' => 'Server za ispravke nije pronađen.', + 'response_invalid' => 'Odgovor servera nije validan.', + 'response_empty' => 'Odgovor servera je prazan.', + 'file_error' => 'Server nije uspeo da dopremi paket.', + 'file_corrupt' => 'Fajl sa servera je korumpiran.', + ], + 'behavior' => [ + 'missing_property' => 'Klasa :class mora definisati svojstvo $:property korišćeno od strane :behavior ponašanja.', + ], + 'config' => [ + 'not_found' => 'Konfiguracioni fajl :file za definisanu :location lokaciju nije mogao biti pronađen.', + 'required' => "Konfiguracija korišćena u :location lokaciji mora obezbediti vrednost za ':property' svojstvo.", + ], + 'zip' => [ + 'extract_failed' => "Ekstrakcija glavnog fajla ':file' nije moguća.", + ], + 'event_log' => [ + 'hint' => 'Ovaj log prikazuje spisak potencijalnih grešaka koje se mogu dogoditi tokom rada aplikacije.', + 'menu_label' => 'Log događaja', + 'menu_description' => 'Prikaži sistemske poruke sa vremenom i detaljima.', + 'empty_link' => 'Isprazni log događaja', + 'empty_loading' => 'Pražnjenje loga događaja...', + 'empty_success' => 'Log događaja je ispražnjen', + 'return_link' => 'Nazad na log događaja', + 'id' => 'ID', + 'id_label' => 'ID događaja', + 'created_at' => 'Datum & vreme', + 'message' => 'Poruka', + 'level' => 'Nivo', + 'preview_title' => 'Događaj', + ], + 'request_log' => [ + 'hint' => 'Ovaj log prikazuje listu zahteva koji mogu zahtevati vašu pažnju. Na primer, kada posetilac otvori neku stranicu a ona ne postoji.', + 'menu_label' => 'Log zahteva', + 'menu_description' => 'Prikaži loše ili preusmerene zahteve.', + 'empty_link' => 'Isprazni log zahteva', + 'empty_loading' => 'Pražnjenje loga zahteva...', + 'empty_success' => 'Log zahteva je ispražnjen', + 'return_link' => 'Nazad na log zahteva', + 'id' => 'ID', + 'id_label' => 'ID zahteva', + 'count' => 'Broj', + 'referer' => 'Reference', + 'url' => 'URL', + 'status_code' => 'Status', + 'preview_title' => 'Zahtev', + ], + 'permissions' => [ + 'name' => 'Sistem', + 'manage_system_settings' => 'Upravljaj sistemskim podešavanjima', + 'manage_software_updates' => 'Upravljaj softverskim ispravkama', + 'access_logs' => 'Prikaži sistemske logove', + 'manage_mail_templates' => 'Upravljaj šablonima pošte', + 'manage_mail_settings' => 'Upravljaj podešavanjima pošte', + 'manage_other_administrators' => 'Upravljaj drugim administratorima', + 'impersonate_users' => 'Oponašaj korisnike', + 'manage_preferences' => 'Upravljaj preferencama pozadinskog sistema', + 'manage_editor' => 'Upravljaj preferencama editora za kod', + 'view_the_dashboard' => 'Prikaži kontrolnu tablu', + 'manage_default_dashboard' => 'Upravljaj osnovama kontrolne table', + 'manage_branding' => 'Izmeni pozadinski sistem', + ], + 'log' => [ + 'menu_label' => 'Log podešavanja', + 'menu_description' => 'Specificiraj oblasti koje se trebaju logovati.', + 'default_tab' => 'Logovanje', + 'log_events' => 'Log sistemskih događaja', + 'log_events_comment' => 'Čuvanje sistemskih događaja u bazi podataka pored čuvanja na fajlu.', + 'log_requests' => 'Log loših zahteva', + 'log_requests_comment' => 'Zahtevi na koje treba obratiti pažnju.', + 'log_theme' => 'Log izmena kod tema', + 'log_theme_comment' => 'Kada je tema promenjena preko pozadinskog sistema.', + ], + 'media' => [ + 'invalid_path' => "Specificirana putanja fajla nije validna: ':path'.", + 'folder_size_items' => 'element(i)', + ], + 'page' => [ + 'custom_error' => [ + 'label' => 'Greška kod stranice', + 'help' => 'Žao nam je, nešto je pošlo po zlu i željena stranica se ne može prikazati.', + ], + 'invalid_token' => [ + 'label' => 'Bezbednosni žeton nije validan.', + ], + 'maintenance' => [ + 'label' => "Odmah se vraćamo!", + 'help' => "Sajt je u fazi održavanja, dođite kasnije!", + 'message' => 'Poruka:', + 'available_at' => 'Pokušajte ponovo za:', + ], + ], + 'pagination' => [ + 'previous' => 'Prošla', + 'next' => 'Sledeća', + ], +]; diff --git a/modules/system/lang/rs/validation.php b/modules/system/lang/rs/validation.php new file mode 100644 index 000000000..c2ea5d07d --- /dev/null +++ b/modules/system/lang/rs/validation.php @@ -0,0 +1,125 @@ + 'Polje :attribute mora biti prihvaćeno.', + 'active_url' => 'Polje :attribute mora sadržati validan URL.', + 'after' => 'Polje :attribute mora sadržati datum koji je posle sledećeg: :date.', + 'after_or_equal' => 'Polje :attribute mora sadržati datum koji je posle sledećeg ili: :date.', + 'alpha' => 'Polje :attribute mora sadržati samo slova.', + 'alpha_dash' => 'Polje :attribute može sadržati samo slova, brojeve, i povlake', + 'alpha_num' => 'Polje :attribute može sadržati samo slova ili brojeve.', + 'array' => 'Polje :attribute mora sadržati niz.', + 'before' => 'Polje :attribute mora sadržati datum koji je pre sledećeg: :date.', + 'before_or_equal' => 'Polje :attribute mora sadržati datum koji je pre sledećeg ili: :date.', + 'between' => [ + 'numeric' => 'Polje :attribute mora sadržati broj između :min i :max.', + 'file' => 'Polje :attribute mora sadržati fajl veličine između :min i :max kilobajta.', + 'string' => 'Polje :attribute mora sadržati tekst dužine između :min i :max karaktera.', + 'array' => 'Polje :attribute mora imati između :min i :max elemenata.', + ], + 'boolean' => 'Polje :attribute mora imati vrednost tačno ili netačno.', + 'confirmed' => 'Potvrda :attribute nije u odgovarajućem formatu.', + 'date' => 'Polje :attribute ne sadrži validan datum.', + 'date_format' => 'Polje :attribute ne sadrži datum u odgovarajućem formatu :format.', + 'different' => 'Polja :attribute i :other moraju imati različite vrednosti.', + 'digits' => 'Polje :attribute mora sadržati :digits cifre.', + 'digits_between' => 'Polje :attribute mora sadržati između :min i :max cifre.', + 'dimensions' => 'Polje :attribute ne sadrži validne dimenzije.', + 'distinct' => 'Polje :attribute sadrži vrednost koja je duplikat.', + 'email' => 'Polje :attribute mora sadržati validnu email adresu.', + 'exists' => 'Polje :attribute nema validnu vrednost.', + 'file' => 'Polje :attribute mora sadržati fajl.', + 'filled' => 'Polje :attribute mora imati vrednost.', + 'image' => 'Polje :attribute mora sadržati sliku.', + 'in' => 'Polje :attribute nema validnu vrednost.', + 'in_array' => 'Polje :attribute ne sadrži vrednost koja postoji u polju :other.', + 'integer' => 'Polje :attribute mora sadržati ceo broj.', + 'ip' => 'Polje :attribute mora sadržati validnu IP adresu.', + 'ipv4' => 'Polje :attribute mora sadržati validnu IPv4 adresu.', + 'ipv6' => 'Polje :attribute mora sadržati validnu IPv6 adresu.', + 'json' => 'Polje :attribute mora sadržati validan JSON objekat.', + 'max' => [ + 'numeric' => 'Polje :attribute ne sme sadržati broj veći od :max.', + 'file' => 'Polje :attribute ne sme sadržati fajl veći od :max kilobajta.', + 'string' => 'Polje :attribute ne sme sadržati tekst duži od :max karaktera.', + 'array' => 'Polje :attribute ne sme imati više od :max elemenata.', + ], + 'mimes' => 'Polje :attribute mora sadržati fajl tipa: :values.', + 'mimetypes' => 'Polje :attribute mora sadržati fajl jednog od sledećih tipova: :values.', + 'min' => [ + 'numeric' => 'Polje :attribute ne sme sadržati broj manji od :min.', + 'file' => 'Polje :attribute ne sme sadržati fajl manji od :min kilobajta.', + 'string' => 'Polje :attribute ne sme sadržati tekst manji od :min karaktera.', + 'array' => 'Polje :attribute ne sme imati manje od :min elemenata.', + ], + 'not_in' => 'Polje :attribute nema validnu vrednost.', + 'numeric' => 'Polje :attribute mora sadržati broj.', + 'present' => 'Polje :attribute mora biti prisutno.', + 'regex' => 'Format polja :attribute nije validan.', + 'required' => 'Polje :attribute je obavezno.', + 'required_if' => 'Polje :attribute je obavezno kada :other ima vrednost :value.', + 'required_unless' => 'Polje :attribute je obavezno kada vrednost polja :other nije deo :values.', + 'required_with' => 'Polje :attribute je obavezno kada su vrednosti :values prisutne.', + 'required_with_all' => 'Polje :attribute je obavezno kada su vrednosti :values prisutne.', + 'required_without' => 'Polje :attribute je obavezno kada vrednosti :values nisu prisutne.', + 'required_without_all' => 'Polje :attribute je obavezno kada nijedna od vrednosti :values nije prisutna.', + 'same' => 'Polja :attribute i :other moraju imati iste vrednosti.', + 'size' => [ + 'numeric' => 'Polje :attribute mora sadržati broj :size.', + 'file' => 'Polje :attribute mora sadržati fajl od :size kilobajta.', + 'string' => 'Polje :attribute mora sadržati tekst od :size karaktera.', + 'array' => 'Polje :attribute mora imati :size elemenata.', + ], + 'string' => 'Polje :attribute mora sadržati tekst.', + 'timezone' => 'Polje :attribute mora sadržati validnu vremensku zonu.', + 'unique' => 'Polje :attribute mora biti jedinstveno.', + 'uploaded' => 'Otpremanje fajla iz polja :attribute je neuspešno.', + 'url' => 'Format polja :attribute nije validan.', + + /* + |-------------------------------------------------------------------------- + | Custom Validation Language Lines + |-------------------------------------------------------------------------- + | + | Here you may specify custom validation messages for attributes using the + | convention "attribute.rule" to name the lines. This makes it quick to + | specify a specific custom language line for a given attribute rule. + | + */ + + 'custom' => [ + 'attribute-name' => [ + 'rule-name' => 'uobičajena-poruka', + ], + ], + + /* + |-------------------------------------------------------------------------- + | Custom Validation Attributes + |-------------------------------------------------------------------------- + | + | The following language lines are used to swap attribute place-holders + | with something more reader friendly such as E-Mail Address instead + | of "email". This simply helps us make messages a little cleaner. + | + */ + + 'attributes' => [ + 'name' => 'ime', + 'password' => 'lozinka', + 'user' => 'korisnik', + ], + +]; diff --git a/modules/system/lang/sk/lang.php b/modules/system/lang/sk/lang.php index d453311a6..26a75252c 100644 --- a/modules/system/lang/sk/lang.php +++ b/modules/system/lang/sk/lang.php @@ -35,6 +35,7 @@ return [ 'pt-br' => 'Português (Brasil)', 'pt-pt' => 'Português (Portugal)', 'ro' => 'Română', + 'rs' => 'Srpski', 'ru' => 'Русский', 'fi' => 'Suomi', 'sv' => 'Svenska', diff --git a/modules/system/lang/sl/lang.php b/modules/system/lang/sl/lang.php index 31717704c..12f62a43b 100644 --- a/modules/system/lang/sl/lang.php +++ b/modules/system/lang/sl/lang.php @@ -37,6 +37,7 @@ return [ 'pt-br' => 'Português (Brasil)', 'pt-pt' => 'Português (Portugal)', 'ro' => 'Română', + 'rs' => 'Srpski', 'ru' => 'Русский', 'fi' => 'Suomi', 'sv' => 'Svenska', diff --git a/modules/system/lang/tr/lang.php b/modules/system/lang/tr/lang.php index b057f50a0..ee57995ad 100644 --- a/modules/system/lang/tr/lang.php +++ b/modules/system/lang/tr/lang.php @@ -37,6 +37,7 @@ return [ 'pt-br' => 'Português (Brasil)', 'pt-pt' => 'Português (Portugal)', 'ro' => 'Română', + 'rs' => 'Srpski', 'ru' => 'Русский', 'fi' => 'Suomi', 'sv' => 'Svenska', diff --git a/modules/system/lang/vn/lang.php b/modules/system/lang/vn/lang.php index 83a83c4bd..f0e056792 100644 --- a/modules/system/lang/vn/lang.php +++ b/modules/system/lang/vn/lang.php @@ -35,6 +35,7 @@ return [ 'pt-br' => 'Português (Brasil)', 'pt-pt' => 'Português (Portugal)', 'ro' => 'Română', + 'rs' => 'Srpski', 'ru' => 'Русский', 'fi' => 'Suomi', 'sv' => 'Svenska', From 6097566c526819f2dc71dafa6476184fcf8872a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Roy?= Date: Sun, 19 Apr 2020 04:43:47 +0200 Subject: [PATCH 07/13] Allow blob files naming in AJAX request (#5042) --- modules/system/assets/js/framework-min.js | 2 +- modules/system/assets/js/framework.combined-min.js | 2 +- modules/system/assets/js/framework.js | 6 +++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/modules/system/assets/js/framework-min.js b/modules/system/assets/js/framework-min.js index c24329248..e0a487918 100644 --- a/modules/system/assets/js/framework-min.js +++ b/modules/system/assets/js/framework-min.js @@ -25,7 +25,7 @@ if(options.data!==undefined&&!$.isEmptyObject(options.data)){$.extend(data,optio if(useFiles){requestData=new FormData($form.length?$form.get(0):undefined) if($el.is(':file')&&inputName){$.each($el.prop('files'),function(){requestData.append(inputName,this)}) delete data[inputName]} -$.each(data,function(key){requestData.append(key,this)})} +$.each(data,function(key){if(typeof Blob!=="undefined"&&this instanceof Blob&&this.filename){requestData.append(key,this,this.filename)}else{requestData.append(key,this)}})} else{requestData=[$form.serialize(),$.param(data)].filter(Boolean).join('&')} var requestOptions={url:url,crossDomain:false,global:options.ajaxGlobal,context:context,headers:requestHeaders,success:function(data,textStatus,jqXHR){if(this.options.beforeUpdate.apply(this,[data,textStatus,jqXHR])===false)return if(options.evalBeforeUpdate&&eval('(function($el, context, data, textStatus, jqXHR) {'+options.evalBeforeUpdate+'}.call($el.get(0), $el, context, data, textStatus, jqXHR))')===false)return diff --git a/modules/system/assets/js/framework.combined-min.js b/modules/system/assets/js/framework.combined-min.js index 65d73d186..dc8316b3e 100644 --- a/modules/system/assets/js/framework.combined-min.js +++ b/modules/system/assets/js/framework.combined-min.js @@ -25,7 +25,7 @@ if(options.data!==undefined&&!$.isEmptyObject(options.data)){$.extend(data,optio if(useFiles){requestData=new FormData($form.length?$form.get(0):undefined) if($el.is(':file')&&inputName){$.each($el.prop('files'),function(){requestData.append(inputName,this)}) delete data[inputName]} -$.each(data,function(key){requestData.append(key,this)})} +$.each(data,function(key){if(typeof Blob!=="undefined"&&this instanceof Blob&&this.filename){requestData.append(key,this,this.filename)}else{requestData.append(key,this)}})} else{requestData=[$form.serialize(),$.param(data)].filter(Boolean).join('&')} var requestOptions={url:url,crossDomain:false,global:options.ajaxGlobal,context:context,headers:requestHeaders,success:function(data,textStatus,jqXHR){if(this.options.beforeUpdate.apply(this,[data,textStatus,jqXHR])===false)return if(options.evalBeforeUpdate&&eval('(function($el, context, data, textStatus, jqXHR) {'+options.evalBeforeUpdate+'}.call($el.get(0), $el, context, data, textStatus, jqXHR))')===false)return diff --git a/modules/system/assets/js/framework.js b/modules/system/assets/js/framework.js index 160a4321a..bf1038929 100644 --- a/modules/system/assets/js/framework.js +++ b/modules/system/assets/js/framework.js @@ -118,7 +118,11 @@ if (window.jQuery.request !== undefined) { } $.each(data, function(key) { - requestData.append(key, this) + if (typeof Blob !== "undefined" && this instanceof Blob && this.filename) { + requestData.append(key, this, this.filename) + } else { + requestData.append(key, this) + } }) } else { From 1c621ae4c951081c5cc044bb84e5d8143b76ee9d Mon Sep 17 00:00:00 2001 From: Calum <2722330+caloggs@users.noreply.github.com> Date: Mon, 20 Apr 2020 02:56:19 +0100 Subject: [PATCH 08/13] Support git submodules in october:util git pull (#5047) --- modules/system/console/OctoberUtil.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/system/console/OctoberUtil.php b/modules/system/console/OctoberUtil.php index 398893d0d..dba334058 100644 --- a/modules/system/console/OctoberUtil.php +++ b/modules/system/console/OctoberUtil.php @@ -313,7 +313,7 @@ class OctoberUtil extends Command { foreach (File::directories(plugins_path()) as $authorDir) { foreach (File::directories($authorDir) as $pluginDir) { - if (!File::isDirectory($pluginDir.'/.git')) { + if (!File::exists($pluginDir.'/.git')) { continue; } @@ -325,7 +325,7 @@ class OctoberUtil extends Command } foreach (File::directories(themes_path()) as $themeDir) { - if (!File::isDirectory($themeDir.'/.git')) { + if (!File::exists($themeDir.'/.git')) { continue; } From a2b835864ecd5307f63ac53133ce818b18a9963b Mon Sep 17 00:00:00 2001 From: Web-VPF <61043464+Web-VPF@users.noreply.github.com> Date: Tue, 21 Apr 2020 23:50:50 +0300 Subject: [PATCH 09/13] Updated Russian translation (#5048) --- modules/system/lang/ru/lang.php | 85 ++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 33 deletions(-) diff --git a/modules/system/lang/ru/lang.php b/modules/system/lang/ru/lang.php index 50477359b..042aefbcd 100644 --- a/modules/system/lang/ru/lang.php +++ b/modules/system/lang/ru/lang.php @@ -11,11 +11,6 @@ return [ 'file' => [ 'create_fail' => 'Невозможно создать файл: :name', ], - 'page' => [ - 'invalid_token' => [ - 'label' => 'Неверный токен безопасности', - ], - ], 'combiner' => [ 'not_found' => "Сборщик ресурсов не может найти файл ':name'.", ], @@ -66,46 +61,40 @@ return [ ], 'plugins' => [ 'manage' => 'Управление плагинами', - 'enable_or_disable' => 'Включить или выключить', - 'enable_or_disable_title' => 'Включение или отключение плагинов', 'install' => 'Установить плагины', 'install_products' => 'Установка расширений', 'search' => 'поиск плагинов для установки...', 'installed' => 'Установленные плагины', 'no_plugins' => 'Нет плагинов, установленных из магазина.', 'recommended' => 'Рекомендуется', - 'remove' => 'Удалить', - 'refresh' => 'Обновить', - 'disabled_label' => 'Отключить', - 'disabled_help' => 'Отключенные плагины будут игнорироваться.', - 'frozen_label' => 'Замораживание обновления', - 'frozen_help' => 'Плагины, которые были заморожены игнорируются в процессе обновления.', - 'selected_amount' => 'Выбрано плагинов: :amount', - 'remove_confirm' => 'Вы уверены, что хотите удалить выбранные плагины? Это также удалит все связанные данные.', - 'remove_success' => 'Выбранные плагины успешно удалены.', - 'refresh_confirm' => 'Вы уверены, что хотите сбросить данные у выбранных плагинов? Данное действие восстановит их в исходное состояние', - 'refresh_success' => 'Выбранные плагины успешно обновлены.', - 'disable_confirm' => 'Вы уверены?', - 'disable_success' => 'Плагин успешно отключен.', - 'enable_success' => 'Плагин успешно включен.', + 'plugin_label' => 'Плагин', 'unknown_plugin' => 'Плагин был удален из файловой системы.', - 'unfrozen' => 'Обновления включены', - 'enabled' => 'Плагин включен', + 'select_label' => 'Выберите действие...', + 'bulk_actions_label' => 'Массовые действия', 'check_yes' => 'Да', 'check_no' => 'Нет', - 'select_label' => 'Выберите действие...', - 'freeze_label' => 'Отключить обновления', + 'unfrozen' => 'Обновления включены', + 'enabled' => 'Плагин включен', + 'freeze' => 'отключить обновления для', + 'unfreeze' => 'включить обновления для', + 'enable' => 'включить', + 'disable' => 'выключить', + 'refresh' => 'сбросить', + 'remove' => 'Удалить', + 'freeze_label' => 'Выключить обновления', 'unfreeze_label' => 'Включить обновления', 'enable_label' => 'Включить плагины', 'disable_label' => 'Отключить плагины', 'refresh_label' => 'Сбросить данные плагина', - 'freeze' => 'отключить обновления', - 'unfreeze' => 'включить обновления', - 'enable' => 'включить', - 'disable' => 'отключить', - 'action_confirm' => 'Вы действительно хотите :action?', - 'freeze_success' => 'Обновления успешно отключены', - 'unfreeze_success' => 'Обновления успешно включены', + 'action_confirm' => 'Вы уверены что хотите :action эти плагины?', + 'freeze_success' => 'Обновления успешно выключены для выбранных плагинов.', + 'unfreeze_success' => 'Обновления успешно включены для выбранных плагинов.', + 'enable_success' => 'Выбранные плагины успешно включены.', + 'disable_success' => 'Выбранные плагины успешно выключены.', + 'refresh_confirm' => 'Вы уверены, что хотите сбросить данные выбранных плагинов? Это приведет к сбросу данных каждого плагина, восстановив его в исходное состояние.', + 'refresh_success' => 'Выбранные плагины успешно обновлены.', + 'remove_confirm' => 'Вы уверены, что хотите удалить выбранные Плагины? Это также приведет к удалению всех связанных данных.', + 'remove_success' => 'Выбранные плагины успешно удалены.', ], 'project' => [ 'name' => 'Проект', @@ -166,6 +155,9 @@ return [ 'ses_key_comment' => 'Введите ваш SES API-ключ', 'ses_secret' => 'SES секретный API-ключ', 'ses_secret_comment' => 'Введите ваш секретный SES API-ключ', + 'sparkpost' => 'SparkPost', + 'sparkpost_secret' => 'SparkPost secret', + 'sparkpost_secret_comment' => 'Введите ваш SparkPost API secret key', 'ses_region' => 'SES регион', 'ses_region_comment' => 'Введите ваш SES регион (например, us-east-1)', 'drivers_hint_header' => 'Драйвера не установлены', @@ -209,6 +201,8 @@ return [ 'deleting_layout' => 'Удаление макета...', 'sending' => 'Отправка тестового сообщения...', 'return' => 'Вернуться к списку шаблонов', + 'options' => 'Опции', + 'disable_auto_inline_css' => 'Выключить автоматический встроенный CSS', ], 'mail_brand' => [ 'menu_label' => 'Почтовый брендинг', @@ -273,7 +267,7 @@ return [ 'updates' => [ 'title' => 'Менеджер обновлений', 'name' => 'Обновление ПО', - 'menu_label' => 'Обновления', + 'menu_label' => 'Обновления и плагины', 'menu_description' => 'Обновление системы, управление и установка плагинов и тем.', 'return_link' => 'Вернуться к системе обновлений', 'check_label' => 'Проверить обновления ', @@ -284,12 +278,16 @@ return [ 'plugin_version' => 'Версия', 'plugin_author' => 'Автор', 'plugin_not_found' => 'Плагин не найден', + 'plugin_version_not_found' => 'Версия плагина не найдена', 'core_current_build' => 'Текущая сборка', + 'core_view_changelog' => 'Просмотр списка изменений', 'core_build' => 'Сборка :build', 'core_build_help' => 'Последняя доступная сборка.', 'core_downloading' => 'Загрузка файлов приложения', 'core_extracting' => 'Распаковка файлов приложения', 'core_set_build' => 'Установка номера сборки', + 'changelog' => 'Список изменений', + 'changelog_view_details' => 'Просмотр подробностей', 'plugins' => 'Плагины', 'themes' => 'Темы', 'disabled' => 'Отключено', @@ -394,9 +392,11 @@ return [ 'manage_mail_templates' => 'Управление почтовыми шаблонами', 'manage_mail_settings' => 'Управление настройками почты', 'manage_other_administrators' => 'Управление другими администраторами', + 'impersonate_users' => 'Выдавать себя за пользователей', 'manage_preferences' => 'Управление настройками бэкенда', 'manage_editor' => 'Управление настройками редактора кода', 'view_the_dashboard' => 'Просмотр панели управления', + 'manage_default_dashboard' => 'Управление панелью управления по умолчанию', 'manage_branding' => 'Персонализация панели управления', ], 'log' => [ @@ -414,4 +414,23 @@ return [ 'invalid_path' => "Указан недопустимый путь к файлу: ':path'.", 'folder_size_items' => 'объектов', ], + 'page' => [ + 'custom_error' => [ + 'label' => 'Ошибка страницы', + 'help' => 'Приносим извинения, что-то пошло не так и страница не может быть отображена.', + ], + 'invalid_token' => [ + 'label' => 'Неверный токен безопасности', + ], + 'maintenance' => [ + 'label' => "Мы скоро вернемся!", + 'help' => "В настоящее время мы находимся на обслуживании, зайдите позже!", + 'message' => 'Сообщение:', + 'available_at' => 'Попробуйте еще раз после:', + ], + ], + 'pagination' => [ + 'previous' => 'Предыдущий', + 'next' => 'Следующий', + ], ]; From dc72cafcd11485941a1e3f9586863937cd403db2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20K=C3=BCndig?= Date: Mon, 27 Apr 2020 09:55:40 +0200 Subject: [PATCH 10/13] Don't persist failed search terms (#5039) If a column is defined as searchable, that is not actually searchable (like a partial) and a user filters a list using the searchbox, an Exception is thrown. Unfortunately, this errorenous search term has already been persisted to the session so on subsequent page loads, the user is presented with an Exception with no way to resolve it themselves. This PR catches any exception that happens during the search and resets any persisted search terms so that the user can continue working after a page load. The exception itself will still be thrown. To reproduce the issue this PR solves: Set a partial column in any list as searchable: true Submit a search query Hit F5 --- modules/backend/widgets/Search.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/modules/backend/widgets/Search.php b/modules/backend/widgets/Search.php index 2f5749abf..8e554fb21 100644 --- a/modules/backend/widgets/Search.php +++ b/modules/backend/widgets/Search.php @@ -128,7 +128,14 @@ class Search extends WidgetBase * Trigger class event, merge results as viewable array */ $params = func_get_args(); - $result = $this->fireEvent('search.submit', [$params]); + try { + $result = $this->fireEvent('search.submit', [$params]); + } catch (\Throwable $e) { + // Remove the search term from the session if the search has failed. + $this->setActiveTerm(''); + throw $e; + } + if ($result && is_array($result)) { return call_user_func_array('array_merge', $result); } From 35ecf7019db6dfaeb6822b0d0a2426b89f9edef2 Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Tue, 28 Apr 2020 09:56:02 -0600 Subject: [PATCH 11/13] Fix visual bug with remember checkbox on mobile. Fixes #5054 --- modules/backend/assets/css/october.css | 1 + modules/backend/assets/less/layout/outerlayout.less | 3 +++ 2 files changed, 4 insertions(+) diff --git a/modules/backend/assets/css/october.css b/modules/backend/assets/css/october.css index 53e7ed673..668127f9e 100644 --- a/modules/backend/assets/css/october.css +++ b/modules/backend/assets/css/october.css @@ -857,6 +857,7 @@ body.outer .layout >.layout-row >.layout-cell .outer-form-container .horizontal- body.outer .layout >.layout-row >.layout-cell .outer-form-container .horizontal-form input {vertical-align:top;margin-right:9px;display:inline-block;border:none;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px} body.outer .layout >.layout-row >.layout-cell .outer-form-container .horizontal-form button {background:#0181b9;text-align:center;font-size:13px;font-weight:600;height:40px;vertical-align:top;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box} body.outer .layout >.layout-row >.layout-cell .outer-form-container .remember label {color:rgba(255,255,255,0.44)} +body.outer .layout >.layout-row >.layout-cell .outer-form-container .remember input {display:none} body.outer .layout >.layout-row >.layout-cell .outer-form-container .forgot-password {margin-top:30px;font-size:13px;top:8px} body.outer .layout >.layout-row >.layout-cell .outer-form-container .forgot-password a {color:rgba(255,255,255,0.44)} body.outer .layout >.layout-row >.layout-cell .outer-form-container .forgot-password:before {color:rgba(255,255,255,0.44);font-size:14px;position:relative;margin-right:5px} diff --git a/modules/backend/assets/less/layout/outerlayout.less b/modules/backend/assets/less/layout/outerlayout.less index 2de805597..2175a7883 100644 --- a/modules/backend/assets/less/layout/outerlayout.less +++ b/modules/backend/assets/less/layout/outerlayout.less @@ -78,6 +78,9 @@ body.outer { label { color: @color-outer-muted-text; } + input { + display: none; + } } .forgot-password { From 29740ea1e80f0567420f9c8f9bbe5e442da51aa3 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 29 Apr 2020 17:50:12 -0400 Subject: [PATCH 12/13] add input tag id to css selector so it does not get overriden by a more generic css rule (#5057) Improves on fix to #5054 --- modules/backend/assets/css/october.css | 2 +- modules/backend/assets/less/layout/outerlayout.less | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/backend/assets/css/october.css b/modules/backend/assets/css/october.css index 668127f9e..e11e70041 100644 --- a/modules/backend/assets/css/october.css +++ b/modules/backend/assets/css/october.css @@ -857,7 +857,7 @@ body.outer .layout >.layout-row >.layout-cell .outer-form-container .horizontal- body.outer .layout >.layout-row >.layout-cell .outer-form-container .horizontal-form input {vertical-align:top;margin-right:9px;display:inline-block;border:none;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px} body.outer .layout >.layout-row >.layout-cell .outer-form-container .horizontal-form button {background:#0181b9;text-align:center;font-size:13px;font-weight:600;height:40px;vertical-align:top;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box} body.outer .layout >.layout-row >.layout-cell .outer-form-container .remember label {color:rgba(255,255,255,0.44)} -body.outer .layout >.layout-row >.layout-cell .outer-form-container .remember input {display:none} +body.outer .layout >.layout-row >.layout-cell .outer-form-container .remember input#remember {display:none} body.outer .layout >.layout-row >.layout-cell .outer-form-container .forgot-password {margin-top:30px;font-size:13px;top:8px} body.outer .layout >.layout-row >.layout-cell .outer-form-container .forgot-password a {color:rgba(255,255,255,0.44)} body.outer .layout >.layout-row >.layout-cell .outer-form-container .forgot-password:before {color:rgba(255,255,255,0.44);font-size:14px;position:relative;margin-right:5px} diff --git a/modules/backend/assets/less/layout/outerlayout.less b/modules/backend/assets/less/layout/outerlayout.less index 2175a7883..1fd47da2f 100644 --- a/modules/backend/assets/less/layout/outerlayout.less +++ b/modules/backend/assets/less/layout/outerlayout.less @@ -78,7 +78,7 @@ body.outer { label { color: @color-outer-muted-text; } - input { + input#remember { display: none; } } From fc8e258c6d8f11fad6f7aa415a2c8d782a6c9f9e Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Wed, 29 Apr 2020 16:48:46 -0600 Subject: [PATCH 13/13] set attributes and save instead of creating via mass assignment to play nicer with various features and avoid requiring fillable properties to be set --- modules/backend/formwidgets/TagList.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/backend/formwidgets/TagList.php b/modules/backend/formwidgets/TagList.php index 1163f18c1..2e2b5c0b7 100644 --- a/modules/backend/formwidgets/TagList.php +++ b/modules/backend/formwidgets/TagList.php @@ -137,7 +137,9 @@ class TagList extends FormWidgetBase $newTags = $this->customTags ? array_diff($names, $existingTags) : []; foreach ($newTags as $newTag) { - $newModel = $relationModel::create([$this->nameFrom => $newTag]); + $newModel = new $relationModel; + $newModel->{$this->nameFrom} = $newTag; + $newModel->save(); $existingTags[$newModel->getKey()] = $newTag; }