Merge branch 'develop' into 1.1

This commit is contained in:
Samuel Georges 2021-03-06 08:59:55 +11:00
commit 1b704e0e23
69 changed files with 1321 additions and 547 deletions

View File

@ -1,10 +1,10 @@
# Contributing to OctoberCMS
# Contributing to October CMS
Thank you for your interest in contributing to the OctoberCMS project. We appreciate any assistance that community members and users of OctoberCMS are willing to provide. You can contribute to the project in several different ways:
Thank you for your interest in contributing to the October CMS project. We appreciate any assistance that community members and users of October CMS are willing to provide. You can contribute to the project in several different ways:
- [Reporting a Security Vulnerability](#reporting-a-security-vulnerability)
- [Reporting an issue with OctoberCMS](#reporting-an-issue-with-octobercms)
- [Reporting an issue with an OctoberCMS plugin](#reporting-an-issue-with-an-octobercms-plugin)
- [Reporting an issue with October CMS](#reporting-an-issue-with-octobercms)
- [Reporting an issue with an October CMS plugin](#reporting-an-issue-with-an-octobercms-plugin)
- [Making a Feature Request](#making-a-feature-request)
- [Making a Pull Request](#making-a-pull-request)
- [Testing Pull Requests](#testing-a-pull-request)
@ -13,9 +13,9 @@ Thank you for your interest in contributing to the OctoberCMS project. We apprec
Please review [our security policy](https://github.com/octobercms/october/security/policy) on how to report security vulnerabilities. Please do not report security vulnerabilities on GitHub.
## Reporting an issue with OctoberCMS
## Reporting an issue with October CMS
>**NOTE:** If your issue is related to an OctoberCMS plugin, please see the [Reporting an issue with an OctoberCMS plugin](#reporting-an-issue-with-an-octobercms-plugin) section below.
>**NOTE:** If your issue is related to an October CMS plugin, please see the [Reporting an issue with an October CMS plugin](#reporting-an-issue-with-an-octobercms-plugin) section below.
We work hard to process bugs that are reported, to assist with this please ensure the following details are always included:
@ -25,7 +25,7 @@ We work hard to process bugs that are reported, to assist with this please ensur
- **Reproduce steps**: Clearly mention the steps to reproduce the bug.
- **Expected behavior**: Describe how OctoberCMS should behave on above mentioned steps.
- **Expected behavior**: Describe how October CMS should behave on above mentioned steps.
- **Actual behavior**: What is the actual result on running above steps i.e. the bug behavior - **include any error messages**.
@ -47,7 +47,7 @@ If possible, please provide any screenshots or GIFs of the issue occurring to pr
If you find out your bug is actually a duplicate of another bug and only notice that after you created it, please also close your bug with a short reference to the other issue that was there before.
#### Reporting an issue with an OctoberCMS plugin
#### Reporting an issue with an October CMS plugin
>Please don't use the main GitHub for reporting issues with plugins.
@ -57,11 +57,11 @@ If you are unable to contact the plugin author and the issue prevents the plugin
#### Escalation process
We do our best to attend to all reported issues. If you have an important issue that requires attention, consider submitting a bounty using the [OctoberCMS Bounty Program](https://www.bountysource.com/teams/october).
We do our best to attend to all reported issues. If you have an important issue that requires attention, consider submitting a bounty using the [October CMS Bounty Program](https://www.bountysource.com/teams/october).
## Making a Feature Request
>**NOTE:** Please don't use GitHub issues for suggesting a new feature. If you have a feature idea, the best place to suggest it is the [OctoberCMS website forum](https://octobercms.com/forum/chan/feature-requests).
>**NOTE:** Please don't use GitHub issues for suggesting a new feature. If you have a feature idea, the best place to suggest it is the [October CMS website forum](https://octobercms.com/forum/chan/feature-requests).
Only use GitHub if you are planning on contributing a new feature and developing it. If you want to discuss your idea first, before "officially" posting it anywhere, you can always join us on [Discord](https://discord.gg/gEKgwSZ).
@ -79,16 +79,16 @@ To help us merge your Pull Request, please make sure you follow these points:
- Describe the problem clearly in the Pull Request description
- Please make your fix on the `develop` branch. This makes merging much easier.
- Do not edit compiled asset files such as `october.css`, `framework.css`, etc. directly. Instead, edit the LESS files inside the `less/` directory and then run `php artisan october:util compile assets` from the project root and commit the changed LESS files as well as the recompiled asset files.
- Do not edit compiled core asset files such as `october.css`, `storm.js`, `framework.css`, `framework.combined.js`, `framework-min.js`, etc. directly. Instead, edit the relevant source / non-minified / non-combined LESS / JS files. For third-party vendor files, you should update both the **.min** and **non-min** versions. Afterwards, run `php artisan october:util compile assets` from the project root to compile all the source asset files; and then commit the changes. For a list of options available for the `compile assets` command, see https://octobercms.com/docs/console/commands#october-util-command
- For any change that you make, **please also add a test case(s)** in the `tests/unit` directory. This helps us understand the issue and make sure that it will stay fixed forever.
Thank you for your contributions!
#### Best practices
It is ideal to keep your development branch or fork synchronised with the core OctoberCMS `develop` branch when submitting Pull Requests, as this minimises the possibility of merge conflicts.
It is ideal to keep your development branch or fork synchronised with the core October CMS `develop` branch when submitting Pull Requests, as this minimises the possibility of merge conflicts.
To keep in sync with OctoberCMS, add the core OctoberCMS repository as a Git remote (ie. `upstream`) and pull changes from the OctoberCMS repository into your local `develop` branch as often as possible:
To keep in sync with October CMS, add the core OctoberCMS repository as a Git remote (ie. `upstream`) and pull changes from the OctoberCMS repository into your local `develop` branch as often as possible:
```
git remote add upstream git@github.com:octobercms/october.git
@ -97,7 +97,7 @@ git checkout develop
git pull upstream develop
```
This ensures that your local `develop` branch matches OctoberCMS. When developing a pull request, it is best to use your own development branch. For example, creating a fix to improve spelling on a language file could be made into a branch called `lang-en-spelling-fixes`, which can be branched off from the `develop` branch.
This ensures that your local `develop` branch matches October CMS. When developing a pull request, it is best to use your own development branch. For example, creating a fix to improve spelling on a language file could be made into a branch called `lang-en-spelling-fixes`, which can be branched off from the `develop` branch.
```
git checkout -b lang-en-spelling-fixes develop
@ -109,15 +109,15 @@ When you wish to update your development branch with the latest changes from the
git merge develop
```
This will merge all the latest changes from the OctoberCMS `develop` branch into your development branch.
This will merge all the latest changes from the October CMS `develop` branch into your development branch.
#### Resolving merge conflicts
Occassionally, you may encounter a merge conflict with your Pull Request. This most commonly occurs if another change made to the OctoberCMS repository was made to a file that your Pull Request has also changed.
Occassionally, you may encounter a merge conflict with your Pull Request. This most commonly occurs if another change made to the October CMS repository was made to a file that your Pull Request has also changed.
It is the responsibility of the author of the Pull Request to resolve any merge conflicts before their Pull Request is accepted.
You should ensure that your local copy of OctoberCMS is synchronised with with the `develop` branch in the OctoberCMS repository. Please follow the [steps above](#best-practices) to synchronise the repositories.
You should ensure that your local copy of October CMS is synchronised with the `develop` branch in the October CMS repository. Please follow the [steps above](#best-practices) to synchronise the repositories.
If Git reports that your changes have conflicts, you will need to resolve the changes in a way that includes the changes from the OctoberCMS repository as well as implementing your Pull Request's changes. See GitHub's guide to [resolving a merge conflict](https://help.github.com/en/articles/resolving-a-merge-conflict-using-the-command-line) for tips on resolving conflicts.
@ -133,24 +133,26 @@ To validate your changes against our coding standards, you may run `./vendor/bin
#### Team rules
The OctoberCMS team follows the [developer guidelines](https://octobercms.com/docs/help/developer-guide) as much as possible.
The October CMS team follows the [developer guidelines](https://octobercms.com/docs/help/developer-guide) as much as possible.
## Testing a Pull Request
Although we aim to test all pull requests made to the OctoberCMS repository, the maintainers of OctoberCMS are volunteers and may not be able to promptly attend to all pull requests.
Although we aim to test all pull requests made to the October CMS repository, the maintainers of October CMS are volunteers and may not be able to promptly attend to all pull requests.
To help speed things up, any assistance with testing Pull Requests and fixes will be very appreciated. The best Pull Requests to test are those that are tagged as [**Testing Needed**](https://github.com/octobercms/october/pulls?q=is%3Apr+is%3Aopen+label%3A%22Testing+Needed%22) in the repository.
To test a Pull Request, you can use the steps below in a terminal or command-line interface to create a fresh installation of OctoberCMS with the changes made in the Pull Request, ready to test. In this example, we have a user called `qwerty123` that has created a pull request with an ID of `#4509`.
To test a Pull Request, you can use the steps below in a terminal or command-line interface to create a fresh installation of October CMS with the changes made in the Pull Request, ready to test. In this example, we have a user called `qwerty123` that has created a pull request with an ID of `#4509`.
1. Check out a copy of the OctoberCMS repository to a folder that you can view in your web browser: `git clone git@github.com:octobercms/october.git`. This will add the files into a subfolder called `october`.
1. Check out a copy of the October CMS repository to a folder that you can view in your web browser: `git clone git@github.com:octobercms/october.git`. This will add the files into a subfolder called `october`.
2. Then, go to the `october` subfolder and check out **@qwerty123**'s changes in a branch in your local repository: `git fetch origin pull/4509/head:pr-4509`. This will pull their changes into a branch called `pr-4509`. You will then need to check out the branch: `git checkout pr-4509`.
3. Next, get the Composer dependencies: `composer update`.
4. Next, run `php artisan october:env` to create a `.env` file in your folder. This will contain the configuration values for the database and site.
4. Next run `git checkout pr-4509` again in case composer overwrote the changes.
5. Finally, once you've populated that file with your database and site details, run `php artisan october:up` to install the necessary database tables.
5. Next, run `php artisan october:env` to create a `.env` file in your folder. This will contain the configuration values for the database and site.
6. Finally, once you've populated that file with your database and site details, run `php artisan october:up` to install the necessary database tables.
At this point, you should have a working copy of the Pull Request ready to test.

2
.github/FUNDING.yml vendored
View File

@ -1,4 +1,2 @@
# These are supported funding model platforms
custom: ['https://octobercms.com/premium-support']
open_collective: octobercms
github: LukeTowers

View File

@ -10,6 +10,4 @@ This repository is only for reporting reproducible bugs or problems. If you need
- Forum: https://octobercms.com/forum
- Stack Overflow: https://stackoverflow.com/questions/tagged/octobercms
If you rely on OctoberCMS for your business consider purchasing a paid support plan! Send an email to octobercms@luketowers.ca to get started.
Thanks!
If you rely on OctoberCMS for your business consider purchasing a paid support plan, visit https://octobercms.com/premium-support

View File

@ -30,10 +30,10 @@ jobs:
run: npm run test
phpUnitTests:
strategy:
max-parallel: 6
max-parallel: 8
matrix:
operatingSystem: [ubuntu-latest, windows-latest]
phpVersion: ['7.2', '7.3', '7.4']
phpVersion: ['7.2', '7.3', '7.4', '8.0']
fail-fast: false
runs-on: ${{ matrix.operatingSystem }}
name: ${{ matrix.operatingSystem }} / PHP ${{ matrix.phpVersion }}
@ -66,6 +66,10 @@ jobs:
tools: composer:v1
extensions: ${{ env.extensions }}
- name: Switch library dependency
if: github.ref == 'refs/heads/develop' || github.base_ref == 'develop'
run: php ./.github/workflows/utilities/library-switcher "dev-develop as 1.1"
- name: Setup dependency cache
id: composercache
run: echo "::set-output name=dir::$(composer config cache-files-dir)"

12
.github/workflows/utilities/library-switcher vendored Executable file
View File

@ -0,0 +1,12 @@
#!/usr/bin/env php
<?php
if (empty($argv[1])) {
echo 'You must provide a version to switch the library dependency to.';
echo "\n";
exit(1);
}
$composer = json_decode(file_get_contents(getcwd() . '/composer.json'), true);
$composer['require']['october/rain'] = $argv[1];
file_put_contents(getcwd() . '/composer.json', json_encode($composer, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) OctoberCMS
Copyright (c) 2013-2021 Alexey Bobkov, Samuel Georges, October CMS
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -13,19 +13,15 @@ October's mission is to show the world that web development is not rocket scienc
Instructions on how to install October can be found at the [installation guide](https://octobercms.com/docs/setup/installation).
### Quick start installation
### Quick Start Installation
For advanced users, run this in your terminal to install October from command line:
If you have composer installed, run this in your terminal to install October CMS from command line. This will place the files in a directory named **myoctober**.
```shell
php -r "eval('?>'.file_get_contents('https://octobercms.com/api/installer'));"
```
composer create-project october/october myoctober
If you plan on using a database, run this command:
If you plan on using a database, run this command inside the application directory.
```shell
php artisan october:install
```
php artisan october:install
## Learning October
@ -37,17 +33,6 @@ You may also watch these introductory videos for [beginners](https://vimeo.com/7
October was created by [Alexey Bobkov](https://www.linkedin.com/in/alexey-bobkov-232ba02b/) and [Samuel Georges](https://www.linkedin.com/in/samuel-georges-0a964131/), who both continue to develop the platform.
The maintenance of October is lead by [Luke Towers](https://luketowers.ca/), along with many wonderful people that dedicate their time to help support and grow the community.
<table>
<tr>
<td align="center"><a href="https://luketowers.ca/"><img src="https://avatars.githubusercontent.com/u/7253840?v=3" width="100px;" alt="Luke Towers"/><br /><sub><b>Luke Towers</b></sub></a></td>
<td align="center"><a href="https://github.com/bennothommo"><img src="https://avatars.githubusercontent.com/u/15900351?v=3" width="100px;" alt="Ben Thomson"/><br /><sub><b>Ben Thomson</b></sub></a></td>
<td align="center"><a href="https://github.com/w20k"><img src="https://avatars.githubusercontent.com/u/1053320?v=3" width="100px;" alt="Denis Denisov"/><br /><sub><b>Denis Denisov</b></sub></a></td>
<td align="center"><a href="https://github.com/mjauvin"><img src="https://avatars.githubusercontent.com/u/2013630?v=3" width="100px;" alt="Marc Jauvin"/><br /><sub><b>Marc Jauvin</b></sub></a></td>
</tr>
</table>
## Foundation library
The CMS uses [Laravel](https://laravel.com) as a foundation PHP framework.
@ -67,7 +52,7 @@ October CMS can provide premium support for a monthly fee. Find out more via the
## Contributing
Before sending or reviewing Pull Requests, be sure to review the [Contributing Guidelines](.github/CONTRIBUTING.md) first.
Before sending a Pull Request, be sure to review the [Contributing Guidelines](.github/CONTRIBUTING.md) first. We are currently operating on a smaller staff and it may take some time to reach your issue. For priority issues, consider purchasing a [premium support plan](https://octobercms.com/premium-support).
### Coding standards

View File

@ -1,11 +1,13 @@
# Security Policy
**PLEASE DON'T DISCLOSE SECURITY-RELATED ISSUES PUBLICLY, [SEE BELOW](#reporting-a-vulnerability).**
**Please do NOT disclose security-related issues in public, [see instructions below](#reporting-a-vulnerability).**
## Supported Versions
October is evergreen, no one version is singled out for security fixes because there is no way to update just one version. Builds are continually released and security fixes will always be available in the latest build.
October CMS is an evergreen product, no one version is singled out for security fixes because there is no way to update just one version. Builds are continually released and security fixes will always be available in the latest build. We encourage all users to upgrade their websites to the latest version.
In cases where there are platform versioning constraints, such as old version of Laravel or PHP, we will make a best effort to backport security fixes to these compatible versions.
## Reporting a Vulnerability
If you discover a security vulnerability within OctoberCMS, please send an email to Samuel Georges at hello@octobercms.com and Luke Towers at octobercms@luketowers.ca. All security vulnerabilities will be promptly addressed.
If you discover a security vulnerability within October CMS, please send an email the security team at hello@octobercms.com. All security vulnerabilities will be promptly addressed.

View File

@ -15,12 +15,6 @@
"name": "Samuel Georges",
"email": "daftspunky@gmail.com",
"role": "Co-founder"
},
{
"name": "Luke Towers",
"email": "octobercms@luketowers.ca",
"homepage": "https://luketowers.ca",
"role": "Maintainer"
}
],
"support": {
@ -30,20 +24,14 @@
"docs": "https://octobercms.com/docs/",
"source": "https://github.com/octobercms/october"
},
"repositories": [
{
"type":"vcs",
"url":"https://github.com/octoberrain/composer-merge-plugin"
}
],
"require": {
"php": ">=7.2",
"php": ">=7.2.9",
"october/rain": "1.1.*",
"october/system": "1.1.*",
"october/backend": "1.1.*",
"october/cms": "1.1.*",
"laravel/framework": "~6.0",
"wikimedia/composer-merge-plugin": "dev-feature/composer-v2 as 1.5.0"
"wikimedia/composer-merge-plugin": "~2.0.1"
},
"require-dev": {
"phpunit/phpunit": "^8.4|^9.3.3",
@ -51,8 +39,7 @@
"fzaninotto/faker": "~1.9",
"squizlabs/php_codesniffer": "3.*",
"php-parallel-lint/php-parallel-lint": "^1.0",
"meyfa/phpunit-assert-gd": "^2.0.0",
"dms/phpunit-arraysubset-asserts": "^0.1.0"
"dms/phpunit-arraysubset-asserts": "^0.1.0|^0.2.1"
},
"autoload-dev": {
"classmap": [
@ -82,10 +69,7 @@
]
},
"config": {
"preferred-install": "dist",
"platform": {
"php": "7.2"
}
"preferred-install": "dist"
},
"minimum-stability": "dev",
"prefer-stable": true,

View File

@ -43,6 +43,36 @@ return [
'url' => 'http://localhost',
/*
|--------------------------------------------------------------------------
| Trusted hosts
|--------------------------------------------------------------------------
|
| You may specify valid hosts for your application as an array or boolean
| below. This helps prevent host header poisoning attacks.
|
| Possible values:
| - `true`: Trust the host specified in app.url, as well as the "www"
| subdomain, if applicable.
| - `false`: Disable the trusted hosts feature.
| - array: Defines the domains to be trusted hosts. Each item should be
| a string defining a domain, IP address, or a regex pattern.
|
| Example of array values:
|
| 'trustedHosts' => [
| 'example.com', // Matches just example.com
| 'www.example.com', // Matches just www.example.com
| '^(.+\.)?example\.com$', // Matches example.com and all subdomains
| 'https://example.com', // Matches just example.com
| ],
|
| NOTE: Even when set to `false`, this functionality is explicitly enabled
| on the Backend password reset flow for security reasons.
*/
'trustedHosts' => false,
/*
|--------------------------------------------------------------------------
| Application Timezone
@ -148,7 +178,7 @@ return [
*/
'loadDiscoveredPackages' => false,
/*
|--------------------------------------------------------------------------
| Class Aliases

View File

@ -646,7 +646,7 @@ class FormController extends ControllerBehavior
* View helper to render the form fields belonging to the
* secondary tabs section.
*
* <?= $this->formRenderPrimaryTabs() ?>
* <?= $this->formRenderSecondaryTabs() ?>
*
* @return string HTML markup
* @throws \October\Rain\Exception\ApplicationException if the Form Widget isn't set

View File

@ -145,6 +145,7 @@ class ListController extends ControllerBehavior
'recordUrl',
'recordOnClick',
'recordsPerPage',
'perPageOptions',
'showPageNumbers',
'noRecordsMessage',
'defaultSort',

View File

@ -111,6 +111,14 @@ class BackendController extends ControllerBase
self::extendableExtendCallback($callback);
}
/**
* @inheritDoc
*/
public function callAction($method, $parameters)
{
return parent::callAction($method, array_values($parameters));
}
/**
* Pass unhandled URLs to the CMS Controller, if it exists
*
@ -210,7 +218,7 @@ class BackendController extends ControllerBase
* Look for a Plugin controller
*/
if (count($params) >= 2) {
list($author, $plugin) = $params;
[$author, $plugin] = $params;
$pluginCode = ucfirst($author) . '.' . ucfirst($plugin);
if (PluginManager::instance()->isDisabled($pluginCode)) {

View File

@ -617,7 +617,7 @@ class Controller extends ControllerBase
$pageHandler = $this->action . '_' . $handler;
if ($this->methodExists($pageHandler)) {
$result = call_user_func_array([$this, $pageHandler], $this->params);
$result = call_user_func_array([$this, $pageHandler], array_values($this->params));
return $result ?: true;
}
@ -625,7 +625,7 @@ class Controller extends ControllerBase
* Process page global handler (onSomething)
*/
if ($this->methodExists($handler)) {
$result = call_user_func_array([$this, $handler], $this->params);
$result = call_user_func_array([$this, $handler], array_values($this->params));
return $result ?: true;
}
@ -662,7 +662,7 @@ class Controller extends ControllerBase
{
$this->addViewPath($widget->getViewPaths());
$result = call_user_func_array([$widget, $handler], $this->params);
$result = call_user_func_array([$widget, $handler], array_values($this->params));
$this->vars = $widget->vars + $this->vars;

View File

@ -13,6 +13,7 @@ use ApplicationException;
use ValidationException;
use Exception;
use Config;
use October\Rain\Foundation\Http\Middleware\CheckForTrustedHost;
/**
* Authentication controller
@ -147,6 +148,20 @@ class Auth extends Controller
*/
public function restore_onSubmit()
{
// Force Trusted Host verification on password reset link generation
// regardless of config to protect against host header poisoning
$trustedHosts = Config::get('app.trustedHosts', false);
if ($trustedHosts === false) {
$hosts = CheckForTrustedHost::processTrustedHosts(true);
if (count($hosts)) {
Request::setTrustedHosts($hosts);
// Trigger the host validation logic
Request::getHost();
}
}
$rules = [
'login' => 'required|between:2,255'
];

View File

@ -3,6 +3,7 @@
use Str;
use Seeder;
use Eloquent;
use Backend\Database\Seeds\SeedSetupAdmin;
class DatabaseSeeder extends Seeder
{
@ -13,7 +14,8 @@ class DatabaseSeeder extends Seeder
*/
public function run()
{
$adminPassword = Str::random(22);
$shouldRandomizePassword = SeedSetupAdmin::$password === 'admin';
$adminPassword = $shouldRandomizePassword ? Str::random(22) : SeedSetupAdmin::$password;
Eloquent::unguarded(function () use ($adminPassword) {
// Generate a random password for the seeded admin account
@ -24,7 +26,7 @@ class DatabaseSeeder extends Seeder
$this->call($adminSeeder);
});
return 'The following password has been automatically generated for the "admin" account: '
. "<fg=yellow;options=bold>${adminPassword}</>";
return $shouldRandomizePassword ? 'The following password has been automatically generated for the "admin" account: '
. "<fg=yellow;options=bold>${adminPassword}</>" : '';
}
}

View File

@ -55,7 +55,7 @@ $.FE.LANGUAGE['sk'] = {
"Remove": "Odstr\u00e1ni\u0165",
"More": "Viac",
"Update": "Aktualizova\u0165",
"Style": "\u0165t\u00fdl",
"Style": "\u0160t\u00fdl",
// Font
"Font Family": "Typ p\u00edsma",
@ -77,7 +77,7 @@ $.FE.LANGUAGE['sk'] = {
"Heading 4": "Nadpis 4",
// Style
"Paragraph Style": "\u0165t\u00fdl odstavca",
"Paragraph Style": "\u0160t\u00fdl odstavca",
"Inline Style": "Inline \u0161t\u00fdl",
// Alignment
@ -157,7 +157,7 @@ $.FE.LANGUAGE['sk'] = {
"Insert Table": "Vlo\u017ei\u0165 tabu\u013eku",
"Table Header": "Hlavi\u010dka tabu\u013eky",
"Remove Table": "Odstrani\u0165 tabu\u013eku",
"Table Style": "\u0165t\u00fdl tabu\u013eky",
"Table Style": "\u0160t\u00fdl tabu\u013eky",
"Horizontal Align": "Horizont\u00e1lne zarovnanie",
"Row": "Riadok",
"Insert row above": "Vlo\u017ei\u0165 riadok nad",
@ -179,9 +179,11 @@ $.FE.LANGUAGE['sk'] = {
"Align Top": "Zarovnat na vrch",
"Align Middle": "Zarovnat na stred",
"Align Bottom": "Zarovnat na spodok",
"Cell Style": "\u0165t\u00fdl bunky",
"Cell Style": "\u0160t\u00fdl bunky",
// Files
"Insert Audio": "Vlo\u017Ei\u0165 zvuk",
"Insert File": "Vlo\u017Ei\u0165 s\u00FAbor",
"Upload File": "Nahra\u0165 s\u00fabor",
"Drop file": "Vlo\u017ete s\u00fabor sem",

View File

@ -119,7 +119,7 @@ return [
'role_field' => 'Rôle',
'role_comment' => 'Les rôles définissent les permissions de l\'utilisateur, elles peuvent être écrasés au niveau de l\'utilisateur dans l\'onglet "Permissions".',
'groups' => 'Groupes',
'groups_comment' => 'Préciser les groupes auxquels ce compte doit appartenir. Les groupes définissent les permissions des utilisateurs, qui peuvent être surchargées au niveau de lutilisateur, dans longlet Permissions.',
'groups_comment' => 'Préciser les groupes auxquels ce compte doit appartenir.',
'avatar' => 'Avatar',
'password' => 'Mot de passe',
'password_confirmation' => 'Confirmer le mot de passe',

View File

@ -8,7 +8,8 @@ return [
'field' => [
'invalid_type' => 'A(z) :type mezőtípus érvénytelen.',
'options_method_invalid_model' => "A(z) ':field' tulajdonság nem passzol a modellhez. Próbálja meghatározni a beállítást, ami megfelelő a(z) :model osztály számára.",
'options_method_not_exists' => "A(z) :model modell osztálynak egy :method() nevű metódust kell definiálnia a(z) ':field' űrlapmező számára, ami visszaadja a beállításokat.",
'options_method_not_exists' => "A(z) :model osztálynak egy :method() nevű metódust kell definiálnia a(z) ':field' űrlapmező számára, ami visszaadja a beállításokat.",
'options_static_method_invalid_value' => "A(z) :class osztályban lévő ':method()' nevű metódus nem ad vissza érvényes tömböt.",
'colors_method_not_exists' => "A(z) :model modell osztálynak egy :method() nevű metódust kell definiálnia a(z) ':field' űrlapmező számára, ami visszaadja a html HEX kódot."
],
'widget' => [
@ -43,11 +44,15 @@ return [
],
'account' => [
'impersonate' => 'Átjelentkezés a fiókba',
'impersonate_confirm' => 'Biztos benne, hogy átjelentkezik a felhasználó saját fiókjába? Ezáltal a jelenlegi munkamenetből ki lesz jelentkeztetve.',
'impersonate_confirm' => 'Biztos, hogy átjelentkezik a felhasználó saját fiókjába? Ezáltal a jelenlegi munkamenetből ki lesz jelentkeztetve.',
'impersonate_success' => 'Sikeresen átjelentkezett a másik fiókba',
'impersonate_working' => 'Átjelentkezés...',
'impersonating' => 'Átjelentkezve mint :full_name',
'stop_impersonating' => 'Visszajelentkezés',
'unsuspend' => 'Felfüggesztés',
'unsuspend_confirm' => 'Biztos, hogy felfüggeszti a felhasználót?',
'unsuspend_success' => 'A felfüggesztés sikeresen megtörtént.',
'unsuspend_working' => 'Felfüggesztés folyamatban...',
'signed_in_as' => 'Belépve mint :full_name',
'sign_out' => 'Kijelentkezés',
'login' => 'Belépés',
@ -368,6 +373,7 @@ return [
'editor' => [
'menu_label' => 'Szövegszerkesztő',
'menu_description' => 'A megjelenésének és működésének testreszabása.',
'preview' => 'Előnézet',
'font_size' => 'Betűméret',
'tab_size' => 'Tabulátor mérete',
'use_hard_tabs' => 'Behúzás tabulátorokkal',
@ -402,6 +408,7 @@ return [
'label' => 'Megnevezés',
'class_name' => 'CSS osztály',
'markup_tags' => 'Szabályok',
'markup_tag' => 'Szabály',
'allowed_empty_tags' => 'Engedélyezett üres elemek',
'allowed_empty_tags_comment' => 'Azon HTML elemek, amik üres érték esetén sem lesznek eltávolítva.',
'allowed_tags' => 'Engedélyezett elemek',
@ -412,14 +419,17 @@ return [
'remove_tags_comment' => 'Azon HTML elemek, amik a tartalmukkal együtt törölhetőek.',
'line_breaker_tags' => 'Sortörő elemek',
'line_breaker_tags_comment' => 'Azon HTML elemek, amik végén kötelezően egy új sor jelenik meg.',
'toolbar_buttons' => 'Eszköztár',
'toolbar_options' => 'Eszköztár',
'toolbar_buttons' => 'Saját konfiguráció',
'toolbar_buttons_comment' => 'Az alapértelmezetten megjelenő eszközök listája.',
'toolbar_buttons_preset' => 'Előre beállított eszköztár konfigurációk:',
'toolbar_buttons_preset' => 'Előre beállított konfigurációk:',
'toolbar_buttons_presets' => [
'default' => 'Alapértelmezett',
'minimal' => 'Minimális',
'full' => 'Teljes',
],
'paragraph_formats' => 'Bekezdés formátumok',
'paragraph_formats_comment' => 'Az ehhez tartozó lenyíló listában fognak megjelenni.',
],
'tooltips' => [
'preview_website' => 'Weboldal megtekintése'
@ -562,7 +572,8 @@ return [
]
],
'permissions' => [
'manage_media' => 'Média kezelése'
'manage_media' => 'Média kezelése',
'allow_unsafe_markdown' => 'Nem biztonságos szerkesztő használata',
],
'mediafinder' => [
'label' => 'Média',

View File

@ -9,6 +9,7 @@ return [
'invalid_type' => 'Tipo de campo inválido :type.',
'options_method_invalid_model' => 'O atributo ":field" não resolve a classe. Tente especificar as opções do método para o modelo :model.',
'options_method_not_exists' => 'A classe :model deve definir um método :method() retornando opções para o campo ":field".',
'options_static_method_invalid_value' => "O método estático ':method()' na :class não retornou um array de opções válidas.",
'colors_method_not_exists' => 'A classe de modelo :model deve definir um método :method() retornando códigos HEX de cor html para o campo de formulário ":field".'
],
'widget' => [
@ -48,14 +49,18 @@ return [
'impersonate_working' => 'Representando...',
'impersonating' => 'Representando :full_name',
'stop_impersonating' => 'Pare de representar',
'unsuspend' => 'Reativar',
'unsuspend_confirm' => 'Tem certeza de que deseja reativar este usuário?',
'unsuspend_success' => 'O usuário foi reativado.',
'unsuspend_working' => 'Reativando...',
'signed_in_as' => 'Assinado como :full_name',
'remember_me' => 'Permaneça logado',
'sign_out' => 'Sair',
'login' => 'Entrar',
'reset' => 'Redefinir',
'restore' => 'Restaurar',
'login_placeholder' => 'Usuário',
'password_placeholder' => 'Senha',
'remember_me' => 'Permaneça logado',
'forgot_password' => 'Esqueceu sua senha?',
'enter_email' => 'Entre com seu email',
'enter_login' => 'Entre com seu nome de usuário',
@ -214,8 +219,8 @@ return [
'setup_title' => 'Configuração da Lista',
'setup_help' => 'Selecione as colunas que deseja ver na lista. Você pode alterar as posições das colunas arrastando-as para cima ou para baixo.',
'records_per_page' => 'Registros por página',
'check' => 'Marcar',
'records_per_page_help' => 'Selecione o número de registros a serem exibidos por página. Note que um número grande pode prejudicar a performance.',
'check' => 'Marcar',
'delete_selected' => 'Excluir selecionado',
'delete_selected_empty' => 'Não há registros selecionados para excluir.',
'delete_selected_confirm' => 'Excluir os registros selecionados?',
@ -236,6 +241,7 @@ return [
'remove_file' => 'Remover arquivo'
],
'repeater' => [
'add_new_item' => 'Adicionar novo item',
'min_items_failed' => ':name requer um mínimo de :min itens, apenas :items foram fornecidos',
'max_items_failed' => ':name requer um máximo de :max itens, apenas :items foram fornecidos',
],
@ -246,6 +252,7 @@ return [
'create_success' => ':name foi criado com sucesso',
'update_success' => ':name foi atualizado com sucesso',
'delete_success' => ':name foi apagado com sucesso',
'restore_success' => ':name restaurado',
'reset_success' => 'Reinicialização completada',
'missing_id' => 'O ID do registro não foi fornecido',
'missing_model' => 'Formulário utilizado na classe :class não tem um model definido.',
@ -304,6 +311,10 @@ return [
'invalid_model_class' => 'A classe de modelo fornecida ":modelClass" para o recordfinder é inválida',
'cancel' => 'Cancelar',
],
'pagelist' => [
'page_link' => 'Link da página',
'select_page' => 'Selecione uma página ...',
],
'relation' => [
'missing_config' => 'Comportamento relation não tem uma configuração para ":config".',
'missing_definition' => 'Comportamento relation não contém uma definição para ":field".',
@ -356,21 +367,25 @@ return [
'permissions' => 'Diretório :name ou seus subdiretórios não são graváveis pelo PHP. Por favor, defina permissões de escrita para o servidor neste diretório.',
'extension' => 'A extensão PHP :name não está instalada. Por favor, instale esta biblioteca para ativar a extensão.',
'plugin_missing' => 'O plugin :name é uma dependência, mas não está instalado. Por favor, instale este plugin.',
'debug' => 'O modo de depuração está ativado. Isso não é recomendado para instalações de produção.',
'decompileBackendAssets' => 'Os assets no Backend estão atualmente descompilados. Isso não é recomendado para instalações de produção.',
],
'editor' => [
'menu_label' => 'Definições do Editor',
'menu_description' => 'Gerenciar configurações do editor.',
'preview' => 'Prévia',
'font_size' => 'Tamanho da fonte',
'tab_size' => 'Tamanho do espaçamento',
'use_hard_tabs' => 'Recuo usando guias',
'code_folding' => 'Código flexível',
'code_folding_begin' => 'Marca de início',
'code_folding_begin_end' => 'Marca de início e fim',
'autocompletion' => 'Autocompletar',
'code_folding' => 'Código flexível',
'word_wrap' => 'Quebra de linha',
'highlight_active_line' => 'Destaque na linha ativa',
'auto_closing' => 'Auto completar tags e caracteres especiais',
'show_invisibles' => 'Mostrar caracteres invisíveis',
'show_gutter' => 'Mostrar numeração de linhas',
'basic_autocompletion'=> 'Autocompletar básico (Ctrl + Espaço)',
'live_autocompletion'=> 'Autocompletar em tempo real',
'enable_snippets'=> 'Habilitar trechos de códigos (Tab)',
@ -380,7 +395,7 @@ return [
'mode_fluid' => 'Fluido',
'40_characters' => '40 caracteres',
'80_characters' => '80 caracteres',
'show_gutter' => 'Mostrar numeração de linhas',
'theme' => 'Esquema de cores',
'markup_styles' => 'Estilos de marcação',
'custom_styles' => 'Folha de estilo personalizada',
'custom styles_comment' => 'Estilos personalizados para incluir no editor HTML.',
@ -393,6 +408,7 @@ return [
'label' => 'Rótulo',
'class_name' => 'Nome da classe',
'markup_tags' => 'Etiquetas de marcação',
'markup_tag' => 'Tag de marcação',
'allowed_empty_tags' => 'Permitir etiquetas vazias',
'allowed_empty_tags_comment' => 'A lista de etiquetas não é removida quando não há conteúdo.',
'allowed_tags' => 'Etiquetas permitidas',
@ -401,11 +417,19 @@ return [
'no_wrap_comment' => 'Lista de etiquetas que não devem ser agrupadas.',
'remove_tags' => 'Excluir etiqueta',
'remove_tags_comment' => 'Lista de etiquetas que serão exclídas juntas com seu conteúdo.',
'theme' => 'Esquema de cores',
'line_breaker_tags' => 'Tags de quebra de linha',
'line_breaker_tags_comment' => 'A lista de tags usadas para colocar um elemento em quebra de linha.',
'toolbar_options' => 'Opções da barra de ferramentas',
'toolbar_buttons' => 'Botões da barra de ferramentas',
'toolbar_buttons_comment' => 'Os botões da barra de ferramentas a serem exibidos no Rich Editor por padrão.',
'toolbar_buttons_preset' => 'Insira uma configuração predefinida de botãos na barra de ferramentas:',
'toolbar_buttons_presets' => [
'default' => 'Padrão',
'minimal' => 'Mínimo',
'full' => 'Completo',
],
'paragraph_formats' => 'Formatos de parágrafo',
'paragraph_formats_comment' => 'As opções que aparecerão na lista de Formatos do parágrafo.',
],
'tooltips' => [
'preview_website' => 'Visualizar a página'
@ -542,12 +566,14 @@ return [
'iso_8859_13' => 'ISO-8859-13 (Latin-7, Baltic Rim)',
'iso_8859_14' => 'ISO-8859-14 (Latin-8, Celtic)',
'iso_8859_15' => 'ISO-8859-15 (Latin-9, Western European revision with euro sign)',
'windows_1250' => 'Windows-1250 (CP1250, Central and Eastern European)',
'windows_1251' => 'Windows-1251 (CP1251)',
'windows_1252' => 'Windows-1252 (CP1252)'
]
],
'permissions' => [
'manage_media' => 'Gerenciar mídias'
'manage_media' => 'Gerenciar mídias',
'allow_unsafe_markdown' => 'Usar Markdown inseguro (pode incluir Javascript)',
],
'mediafinder' => [
'label' => 'Localizador de Mídia',

View File

@ -1333,7 +1333,7 @@ class Form extends WidgetBase
if (str_contains($fieldOptions, '::')) {
$options = explode('::', $fieldOptions);
if (count($options) === 2 && class_exists($options[0]) && method_exists($options[0], $options[1])) {
$result = $options[0]::{$options[1]}();
$result = $options[0]::{$options[1]}($this, $field);
if (!is_array($result)) {
throw new ApplicationException(Lang::get('backend::lang.field.options_static_method_invalid_value', [
'class' => $options[0],

View File

@ -62,6 +62,12 @@ class Lists extends WidgetBase
* @var int Maximum rows to display for each page.
*/
public $recordsPerPage;
/**
* @var array Options for number of items per page.
*/
public $perPageOptions;
/**
* @var bool Shows the sorting options for each column.
@ -199,6 +205,7 @@ class Lists extends WidgetBase
'noRecordsMessage',
'showPageNumbers',
'recordsPerPage',
'perPageOptions',
'showSorting',
'defaultSort',
'showCheckboxes',
@ -1689,7 +1696,7 @@ class Lists extends WidgetBase
*/
protected function getSetupPerPageOptions()
{
$perPageOptions = [20, 40, 80, 100, 120];
$perPageOptions = is_array($this->perPageOptions) ? $this->perPageOptions : [20, 40, 80, 100, 120];
if (!in_array($this->recordsPerPage, $perPageOptions)) {
$perPageOptions[] = $this->recordsPerPage;
}

View File

@ -14,7 +14,7 @@
$index++;
$checkboxId = 'checkbox_'.$field->getId().'_'.$index;
if (!in_array($value, $checkedValues)) continue;
if (is_string($option)) $option = [$option];
if (!is_array($option)) $option = [$option];
?>
<div class="checkbox custom-checkbox">
<input
@ -71,7 +71,7 @@
<?php
$index++;
$checkboxId = 'checkbox_'.$field->getId().'_'.$index;
if (is_string($option)) $option = [$option];
if (!is_array($option)) $option = [$option];
?>
<div class="checkbox custom-checkbox">
<input

View File

@ -312,6 +312,10 @@ class ServiceProvider extends ModuleServiceProvider
{
$theme = CmsTheme::getActiveTheme();
if (is_null($theme)) {
return;
}
$langPath = $theme->getPath() . '/lang';
if (File::isDirectory($langPath)) {

View File

@ -98,6 +98,16 @@ class CmsCompoundObject extends CmsObject
*/
public function beforeSave()
{
// Ignore line-ending only changes to the code property to avoid triggering safe mode
// when no changes actually occurred, it was just the browser reformatting line endings
if ($this->isDirty('code')) {
$oldCode = str_replace("\n", "\r\n", str_replace("\r", '', $this->getOriginal('code')));
$newCode = str_replace("\n", "\r\n", str_replace("\r", '', $this->code));
if ($oldCode === $newCode) {
$this->code = $this->getOriginal('code');
}
}
$this->checkSafeMode();
}

View File

@ -145,7 +145,7 @@ class Controller
$url = Request::path();
}
if (empty($url)) {
if (trim($url) === '') {
$url = '/';
}

View File

@ -37,7 +37,7 @@
<?php if ($theme->hasCustomData()): ?>
<a
href="<?= Backend::url('cms/themeoptions/update/'.$theme->getDirName()) ?>"
class="btn btn-secondary">
class="btn btn-secondary<?= $theme->isActiveTheme() === false ? ' disabled' : '' ?>">
<i class="icon-paint-brush"></i>
<?= e(trans('cms::lang.theme.customize_button')) ?>
</a>

View File

@ -32,7 +32,7 @@ return [
'edit' => [
'not_set' => 'Nincs beállítva a szerkesztés alatt lévő téma.',
'not_found' => 'A szerkesztés alatt lévő téma nem található.',
'not_match' => 'Az objektum melyhez hozzáférni próbál, nem a szerkesztés alatt lévő témához tartozik. Töltse be újra a lapot.'
'not_match' => 'Az objektum melyhez hozzáférni próbál, nem a szerkesztés alatt lévő témához tartozik. Töltse be újra az oldalt.',
],
'settings_menu' => 'Megjelenés',
'settings_menu_description' => 'A telepített témák listája és azok testreszabása.',
@ -98,28 +98,28 @@ return [
'settings_menu' => 'Karbantartás',
'settings_menu_description' => 'A weboldal ideiglenes felfüggesztése a látogatók számára.',
'is_enabled' => 'Karbantartás engedélyezése',
'is_enabled_comment' => 'Aktiválása esetén a weboldal látogatói csak a kiválasztott lapot fogják látni.',
'hint' => 'Karbantartás módban a lentebb megadott lap fog megjelenni azon látogatók számára, akik nincsenek bejelentkezve az admin felületre.'
'is_enabled_comment' => 'Aktiválása esetén a weboldal látogatói csak a kiválasztott oldalt fogják látni.',
'hint' => 'Karbantartás módban a lentebb megadott oldal fog megjelenni azon látogatók számára, akik nincsenek bejelentkezve az admin felületre.',
],
'page' => [
'not_found_name' => "A következő lap nem található: ':name'",
'not_found_name' => "A következő oldal nem található: ':name'",
'not_found' => [
'label' => 'A lap nem található',
'help' => 'A kért lap nem található.'
'label' => 'Az oldal nem található',
'help' => 'A kért oldal nem található.',
],
'custom_error' => [
'label' => 'Laphiba',
'help' => 'Sajnos valami elromlott, ezért a lap nem jeleníthető meg.'
'label' => 'Oldal hiba',
'help' => 'Sajnos valami elromlott, ezért az oldal nem jeleníthető meg.',
],
'menu_label' => 'Lapok',
'unsaved_label' => 'Nem mentett lap(ok)',
'menu_label' => 'Oldalak',
'unsaved_label' => 'Nem mentett oldal(ok)',
'no_list_records' => 'Nincs találat',
'new' => 'Új lap',
'new' => 'Új oldal',
'invalid_url' => 'Érvénytelen a formátum. A webcímnek perjellel kell kezdődnie, és számokat, latin betűket, valamint a következő karaktereket tartalmazhatja: ._-[]:?|/+*',
'delete_confirm_multiple' => 'Valóban törölni akarja a kijelölt lapokat?',
'delete_confirm_single' => 'Valóban törölni akarja ezt a lapot?',
'delete_confirm_multiple' => 'Valóban törölni akarja a kijelölt oldalakat?',
'delete_confirm_single' => 'Valóban törölni akarja ezt az oldalt?',
'no_layout' => '-- nincs --',
'cms_page' => 'Lapok',
'cms_page' => 'Oldalak',
'title' => 'Elnevezés szerint',
'url' => 'Webcím szerint',
'file_name' => 'Fájlnév szerint'
@ -166,7 +166,7 @@ return [
'editor' => [
'settings' => 'Beállítások',
'title' => 'Elnevezés',
'new_title' => 'Az új lap címe',
'new_title' => 'Az új oldal címe',
'url' => 'Webcím',
'filename' => 'Fájlnév',
'layout' => 'Elrendezés',
@ -185,7 +185,15 @@ return [
'open_searchbox' => 'Keresési panel megnyitása',
'close_searchbox' => 'Keresési panel bezárása',
'open_replacebox' => 'Cserepanel megnyitása',
'close_replacebox' => 'Cserepanel bezárása'
'close_replacebox' => 'Cserepanel bezárása',
'commit' => 'Végrehajtás',
'reset' => 'Visszaállítás',
'commit_confirm' => 'Biztos, hogy végrehajtja a fájl módosításait? Ez felülírja a meglévő fájlt.',
'reset_confirm' => 'Biztos, hogy vissza akarja állítani ezt a fájlt a másolatra? Ez teljesen lecseréli a meglévő fájlt.',
'committing' => 'Végrehajtás',
'resetting' => 'Visszaállítás',
'commit_success' => 'The :type has been committed to the filesystem',
'reset_success' => 'The :type has been reset to the filesystem version',
],
'asset' => [
'menu_label' => 'Fájlok',
@ -236,12 +244,15 @@ return [
'unnamed' => 'Névtelen',
'no_description' => 'Nincs megadott leírás',
'alias' => 'Alias',
'alias_description' => 'Ennek a komponensnek a lap vagy az elrendezés kódjában való használatkor adott egyedi név.',
'alias_description' => 'Ennek a komponensnek az oldal vagy az elrendezés kódjában való használatkor adott egyedi név.',
'validation_message' => 'A komponens aliasok kötelezőek, és csak latin betűket, számokat, valamint aláhúzásokat tartalmazhatnak. Az aliasoknak latin szimbólummal kell kezdődniük.',
'invalid_request' => 'A sablon érvénytelen komponens adatok miatt nem menthető.',
'no_records' => 'Nem találhatók komponensek',
'not_found' => "A(z) ':name' komponens nem található.",
'method_not_found' => "A(z) ':name' komponens nem tartalmaz egy ':method' metódust."
'no_default_partial' => 'Ennek a komponensek nincs alapértelmezett részlapja.',
'method_not_found' => "A(z) ':name' komponens nem tartalmaz a(z) ':method' metódust.",
'soft_component' => 'Opcionális komponens',
'soft_component_description' => 'Ez a komponens hiányzik, viszont nem kötelező.',
],
'template' => [
'invalid_type' => 'Ismeretlen sablon típus.',
@ -255,7 +266,7 @@ return [
'name' => 'Testreszabás',
'manage_content' => 'Tartalom kezelése',
'manage_assets' => 'Fájlok kezelése',
'manage_pages' => 'Lapok kezelése',
'manage_pages' => 'Oldalak kezelése',
'manage_layouts' => 'Elrendezések kezelése',
'manage_partials' => 'Részlapok kezelése',
'manage_themes' => 'Témák kezelése',

View File

@ -249,7 +249,10 @@ return [
'invalid_request' => 'O modelo não pode ser salvo devido a dados inválidos nos componentes.',
'no_records' => 'Nenhum componente encontrado',
'not_found' => 'O componente ":name" não foi encontrado.',
'no_default_partial' => "Este componente não tem um bloco 'padrão'",
'method_not_found' => 'O componente ":name" não tem um método ":method".',
'soft_component' => 'Componente Soft',
'soft_component_description' => 'Este componente está faltando, mas é opcional.',
],
'template' => [
'invalid_type' => 'Tipo de modelo desconhecido.',
@ -267,6 +270,7 @@ return [
'manage_layouts' => 'Gerenciar esboços',
'manage_partials' => 'Gerenciar blocos',
'manage_themes' => 'Gerenciar temas',
'manage_theme_options' => 'Configure as opções de personalização para o tema ativo',
],
'theme_log' => [
'hint' => 'Esses registros exibe as alterações feitas no tema pelos administradores na área de backend.',

View File

@ -18,7 +18,6 @@ return [
'Hash' => Illuminate\Support\Facades\Hash::class,
'Lang' => Illuminate\Support\Facades\Lang::class,
'Log' => Illuminate\Support\Facades\Log::class,
'Mail' => Illuminate\Support\Facades\Mail::class,
'Queue' => Illuminate\Support\Facades\Queue::class,
'Redirect' => Illuminate\Support\Facades\Redirect::class,
'Redis' => Illuminate\Support\Facades\Redis::class,
@ -34,38 +33,40 @@ return [
/*
* October aliases
*/
'Model' => October\Rain\Database\Model::class,
'Block' => October\Rain\Support\Facades\Block::class,
'File' => October\Rain\Support\Facades\File::class,
'Config' => October\Rain\Support\Facades\Config::class,
'Seeder' => October\Rain\Database\Updates\Seeder::class,
'Flash' => October\Rain\Support\Facades\Flash::class,
'Input' => October\Rain\Support\Facades\Input::class,
'Form' => October\Rain\Support\Facades\Form::class,
'Html' => October\Rain\Support\Facades\Html::class,
'Http' => October\Rain\Support\Facades\Http::class,
'Str' => October\Rain\Support\Facades\Str::class,
'Markdown' => October\Rain\Support\Facades\Markdown::class,
'Yaml' => October\Rain\Support\Facades\Yaml::class,
'Ini' => October\Rain\Support\Facades\Ini::class,
'Twig' => October\Rain\Support\Facades\Twig::class,
'DbDongle' => October\Rain\Support\Facades\DbDongle::class,
'Schema' => October\Rain\Support\Facades\Schema::class,
'Validator' => October\Rain\Support\Facades\Validator::class,
'Cms' => Cms\Facades\Cms::class,
'Backend' => Backend\Facades\Backend::class,
'BackendMenu' => Backend\Facades\BackendMenu::class,
'BackendAuth' => Backend\Facades\BackendAuth::class,
'AjaxException' => October\Rain\Exception\AjaxException::class,
'SystemException' => October\Rain\Exception\SystemException::class,
'ApplicationException' => October\Rain\Exception\ApplicationException::class,
'BackendAuth' => Backend\Facades\BackendAuth::class,
'Backend' => Backend\Facades\Backend::class,
'BackendMenu' => Backend\Facades\BackendMenu::class,
'Block' => October\Rain\Support\Facades\Block::class,
'Cms' => Cms\Facades\Cms::class,
'Config' => October\Rain\Support\Facades\Config::class,
'DbDongle' => October\Rain\Support\Facades\DbDongle::class,
'File' => October\Rain\Support\Facades\File::class,
'Flash' => October\Rain\Support\Facades\Flash::class,
'Form' => October\Rain\Support\Facades\Form::class,
'Html' => October\Rain\Support\Facades\Html::class,
'Http' => October\Rain\Support\Facades\Http::class,
'Ini' => October\Rain\Support\Facades\Ini::class,
'Input' => October\Rain\Support\Facades\Input::class,
'Mail' => October\Rain\Support\Facades\Mail::class,
'Markdown' => October\Rain\Support\Facades\Markdown::class,
'Model' => October\Rain\Database\Model::class,
'Schema' => October\Rain\Support\Facades\Schema::class,
'Seeder' => October\Rain\Database\Updates\Seeder::class,
'Str' => October\Rain\Support\Facades\Str::class,
'SystemException' => October\Rain\Exception\SystemException::class,
'Twig' => October\Rain\Support\Facades\Twig::class,
'ValidationException' => October\Rain\Exception\ValidationException::class,
'Validator' => October\Rain\Support\Facades\Validator::class,
'Yaml' => October\Rain\Support\Facades\Yaml::class,
/*
* Fallback aliases
*/
// Input facade was removed in Laravel 6 - we are keeping it in the Rain library for backwards compatibility.
'Illuminate\Support\Facades\Input' => October\Rain\Support\Facades\Input::class,
// Illuminate's HtmlDumper was "dumped" in Laravel 6 - we'll route this to Symfony's HtmlDumper as Laravel have done.
'Illuminate\Support\Debug\HtmlDumper' => Symfony\Component\VarDumper\Dumper\HtmlDumper::class,
];

View File

@ -63,6 +63,14 @@ input[type="checkbox"],
input[type="radio"] {box-sizing:border-box;padding:0}
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {height:auto}
input[type="number"]:focus::-webkit-input-placeholder {margin-right:20px}
input[type="number"]:focus::-moz-placeholder {margin-right:20px}
input[type="number"]:focus:-ms-input-placeholder {margin-right:20px}
input[type="number"]:focus::placeholder {margin-right:20px}
input[type="number"]:hover::-webkit-input-placeholder {margin-right:20px}
input[type="number"]:hover::-moz-placeholder {margin-right:20px}
input[type="number"]:hover:-ms-input-placeholder {margin-right:20px}
input[type="number"]:hover::placeholder {margin-right:20px}
input[type="search"] {-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {-webkit-appearance:none}

View File

@ -5,7 +5,7 @@ if ($.oc === undefined) $.oc = {}
if ($.oc.langMessages === undefined) $.oc.langMessages = {}
$.oc.langMessages['es'] = $.extend(
$.oc.langMessages['es'] || {},
{"markdowneditor":{"formatting":"Formateo","quote":"Cita","code":"C\u00f3digo","header1":"Encabezado 1","header2":"Encabezado 2","header3":"Encabezado 3","header4":"Encabezado 4","header5":"Encabezado 5","header6":"Encabezado 6","bold":"Negrita","italic":"Cursiva","unorderedlist":"Lista Desordenada","orderedlist":"Lista Ordenada","video":"Video","image":"Imagen","link":"V\u00ednculo","horizontalrule":"Insertar Regla Horizontal","fullscreen":"Pantalla completa","preview":"Previsualizar"},"mediamanager":{"insert_link":"Insertar Media V\u00ednculo","insert_image":"Insertar Media Imagen","insert_video":"Insertar Media Video","insert_audio":"Insertar Media Audio","invalid_file_empty_insert":"Por favor seleccione archivo para insertar v\u00ednculo.","invalid_file_single_insert":"Por favor seleccione un solo archivo.","invalid_image_empty_insert":"Por favor seleccione una imagen(es) para insertar.","invalid_video_empty_insert":"Por favor seleccione un archivo de video para insertar.","invalid_audio_empty_insert":"Por favor seleccione un archivo de audio para insertar."},"alert":{"confirm_button_text":"OK","cancel_button_text":"Cancelar","widget_remove_confirm":"Remove this widget?"},"datepicker":{"previousMonth":"Mes Anterior","nextMonth":"Mes Siguiente","months":["Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre"],"weekdays":["Domingo","Lunes","Martes","Miercoles","Jueves","Viernes","Sabado"],"weekdaysShort":["Dom","Lun","Mar","Mie","Jue","Vie","Sab"]},"colorpicker":{"choose":"Ok"},"filter":{"group":{"all":"todos"},"scopes":{"apply_button_text":"Apply","clear_button_text":"Clear"},"dates":{"all":"todos","filter_button_text":"Filtro","reset_button_text":"Restablecer","date_placeholder":"Fecha","after_placeholder":"Despues","before_placeholder":"Antes"},"numbers":{"all":"all","filter_button_text":"Filter","reset_button_text":"Reset","min_placeholder":"Min","max_placeholder":"Max"}},"eventlog":{"show_stacktrace":"Mostrar el seguimiento de la pila","hide_stacktrace":"Ocultar el seguimiento de la pila","tabs":{"formatted":"Formateado","raw":"Sin formato"},"editor":{"title":"Seleccione el editor de c\u00f3digo fuente a usar","description":"Su entorno de sistema operativo debe estar configurado para escuchar a uno de estos esquemas de URL.","openWith":"Abrir con","remember_choice":"Remember selected option for this session","open":"Abrir","cancel":"Cancelar","rememberChoice":"Recuerde que la opci\u00f3n seleccionada para esta sesi\u00f3n del navegador"}}}
{"markdowneditor":{"formatting":"Formateo","quote":"Cita","code":"C\u00f3digo","header1":"Encabezado 1","header2":"Encabezado 2","header3":"Encabezado 3","header4":"Encabezado 4","header5":"Encabezado 5","header6":"Encabezado 6","bold":"Negrita","italic":"Cursiva","unorderedlist":"Lista Desordenada","orderedlist":"Lista Ordenada","video":"Video","image":"Imagen","link":"V\u00ednculo","horizontalrule":"Insertar Regla Horizontal","fullscreen":"Pantalla completa","preview":"Previsualizar"},"mediamanager":{"insert_link":"Insertar Media V\u00ednculo","insert_image":"Insertar Media Imagen","insert_video":"Insertar Media Video","insert_audio":"Insertar Media Audio","invalid_file_empty_insert":"Por favor seleccione archivo para insertar v\u00ednculo.","invalid_file_single_insert":"Por favor seleccione un solo archivo.","invalid_image_empty_insert":"Por favor seleccione una imagen(es) para insertar.","invalid_video_empty_insert":"Por favor seleccione un archivo de video para insertar.","invalid_audio_empty_insert":"Por favor seleccione un archivo de audio para insertar."},"alert":{"confirm_button_text":"OK","cancel_button_text":"Cancelar","widget_remove_confirm":"Remove this widget?"},"datepicker":{"previousMonth":"Mes Anterior","nextMonth":"Mes Siguiente","months":["Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre"],"weekdays":["Domingo","Lunes","Martes","Miercoles","Jueves","Viernes","Sabado"],"weekdaysShort":["Dom","Lun","Mar","Mie","Jue","Vie","Sab"]},"colorpicker":{"choose":"Ok"},"filter":{"group":{"all":"todos"},"scopes":{"apply_button_text":"Aplicar","clear_button_text":"Limpiar"},"dates":{"all":"todas","filter_button_text":"Filtrar","reset_button_text":"Restablecer","date_placeholder":"Fecha","after_placeholder":"Desde","before_placeholder":"Hasta"},"numbers":{"all":"todos","filter_button_text":"Filtrar","reset_button_text":"Restablecer","min_placeholder":"M\u00ednimo","max_placeholder":"M\u00e1ximo","number_placeholder":"N\u00famero"}},"eventlog":{"show_stacktrace":"Mostrar el seguimiento de la pila","hide_stacktrace":"Ocultar el seguimiento de la pila","tabs":{"formatted":"Formateado","raw":"Sin formato"},"editor":{"title":"Seleccione el editor de c\u00f3digo fuente a usar","description":"Su entorno de sistema operativo debe estar configurado para escuchar a uno de estos esquemas de URL.","openWith":"Abrir con","remember_choice":"Remember selected option for this session","open":"Abrir","cancel":"Cancelar","rememberChoice":"Recuerde la opci\u00f3n seleccionada para esta sesi\u00f3n del navegador"}}}
);
//! moment.js locale configuration v2.22.2

View File

@ -5,7 +5,7 @@ if ($.oc === undefined) $.oc = {}
if ($.oc.langMessages === undefined) $.oc.langMessages = {}
$.oc.langMessages['it'] = $.extend(
$.oc.langMessages['it'] || {},
{"markdowneditor":{"formatting":"Formattazione","quote":"Citazione","code":"Codice","header1":"Titolo 1","header2":"Titolo 2","header3":"Titolo 3","header4":"Titolo 4","header5":"Titolo 5","header6":"Titolo 6","bold":"Grassetto","italic":"Corsivo","unorderedlist":"Elenco puntato","orderedlist":"Elenco numerato","video":"Video","image":"Immagine","link":"Collegamento","horizontalrule":"Inserisci linea orizzontale","fullscreen":"Schermo intero","preview":"Anteprima"},"mediamanager":{"insert_link":"Inserisci collegamento elemento multimediale","insert_image":"Inserisci immagine","insert_video":"Inserisci video","insert_audio":"Inserisci audio","invalid_file_empty_insert":"Si prega di selezionare un file di cui inserire il collegamento.","invalid_file_single_insert":"Si prega di selezionare un singolo file.","invalid_image_empty_insert":"Si prega di selezionare l\\'immagine\/le immagini da inserire.","invalid_video_empty_insert":"Si prega di selezionare un file video da inserire.","invalid_audio_empty_insert":"Si prega di selezionare un file audio da inserire."},"alert":{"confirm_button_text":"OK","cancel_button_text":"Annulla","widget_remove_confirm":"Remove this widget?"},"datepicker":{"previousMonth":"Mese precedente","nextMonth":"Mese successivo","months":["Gennaio","Febbraio","Marzo","Aprile","Maggio","Giugno","Luglio","Agosto","Settembre","Ottobre","Novembre","Dicembre"],"weekdays":["Domenica","Luned\u00ec","Marted\u00ec","Mercoled\u00ec","Gioved\u00ec","Venerd\u00ec","Sabato"],"weekdaysShort":["Dom","Lun","Mar","Mer","Gio","Ven","Sab"]},"colorpicker":{"choose":"Ok"},"filter":{"group":{"all":"tutti"},"scopes":{"apply_button_text":"Apply","clear_button_text":"Clear"},"dates":{"all":"tutte","filter_button_text":"Filtra","reset_button_text":"Reimposta","date_placeholder":"Data","after_placeholder":"Dopo","before_placeholder":"Prima"},"numbers":{"all":"all","filter_button_text":"Filter","reset_button_text":"Reset","min_placeholder":"Min","max_placeholder":"Max"}},"eventlog":{"show_stacktrace":"Visualizza la traccia dello stack","hide_stacktrace":"Nascondi la traccia dello stack","tabs":{"formatted":"Formattato","raw":"Grezzo"},"editor":{"title":"Editor codice sorgente","description":"Il tuo sistema operativo deve essere configurato per ascoltare uno di questi schemi URL.","openWith":"Apri con","remember_choice":"Ricorda l'opzione selezionata per questa sessione","open":"Apri","cancel":"Annulla"}}}
{"markdowneditor":{"formatting":"Formattazione","quote":"Citazione","code":"Codice","header1":"Titolo 1","header2":"Titolo 2","header3":"Titolo 3","header4":"Titolo 4","header5":"Titolo 5","header6":"Titolo 6","bold":"Grassetto","italic":"Corsivo","unorderedlist":"Elenco puntato","orderedlist":"Elenco numerato","video":"Video","image":"Immagine","link":"Collegamento","horizontalrule":"Inserisci linea orizzontale","fullscreen":"Schermo intero","preview":"Anteprima"},"mediamanager":{"insert_link":"Inserisci collegamento elemento multimediale","insert_image":"Inserisci immagine","insert_video":"Inserisci video","insert_audio":"Inserisci audio","invalid_file_empty_insert":"Si prega di selezionare un file di cui inserire il collegamento.","invalid_file_single_insert":"Si prega di selezionare un singolo file.","invalid_image_empty_insert":"Si prega di selezionare l\\'immagine\/le immagini da inserire.","invalid_video_empty_insert":"Si prega di selezionare un file video da inserire.","invalid_audio_empty_insert":"Si prega di selezionare un file audio da inserire."},"alert":{"confirm_button_text":"OK","cancel_button_text":"Annulla","widget_remove_confirm":"Rimuovere questo widget?"},"datepicker":{"previousMonth":"Mese precedente","nextMonth":"Mese successivo","months":["Gennaio","Febbraio","Marzo","Aprile","Maggio","Giugno","Luglio","Agosto","Settembre","Ottobre","Novembre","Dicembre"],"weekdays":["Domenica","Luned\u00ec","Marted\u00ec","Mercoled\u00ec","Gioved\u00ec","Venerd\u00ec","Sabato"],"weekdaysShort":["Dom","Lun","Mar","Mer","Gio","Ven","Sab"]},"colorpicker":{"choose":"OK"},"filter":{"group":{"all":"tutti"},"scopes":{"apply_button_text":"Applica","clear_button_text":"Rimuovi"},"dates":{"all":"tutte","filter_button_text":"Filtra","reset_button_text":"Reimposta","date_placeholder":"Data","after_placeholder":"Dopo","before_placeholder":"Prima"},"numbers":{"all":"tutti","filter_button_text":"Filtra","reset_button_text":"Reset","min_placeholder":"Min","max_placeholder":"Max"}},"eventlog":{"show_stacktrace":"Visualizza la traccia dello stack","hide_stacktrace":"Nascondi la traccia dello stack","tabs":{"formatted":"Formattato","raw":"Grezzo"},"editor":{"title":"Editor codice sorgente","description":"Il tuo sistema operativo deve essere configurato per ascoltare uno di questi schemi URL.","openWith":"Apri con","remember_choice":"Ricorda l'opzione selezionata per questa sessione","open":"Apri","cancel":"Annulla"}}}
);
//! moment.js locale configuration v2.22.2

View File

@ -5,7 +5,7 @@ if ($.oc === undefined) $.oc = {}
if ($.oc.langMessages === undefined) $.oc.langMessages = {}
$.oc.langMessages['zh-tw'] = $.extend(
$.oc.langMessages['zh-tw'] || {},
{"markdowneditor":{"formatting":"\u683c\u5f0f","quote":"\u5f15\u8a00","code":"\u7a0b\u5f0f\u78bc","header1":"\u6a19\u984c\u4e00","header2":"\u6a19\u984c\u4e8c","header3":"\u6a19\u984c\u4e09","header4":"\u6a19\u984c\u56db","header5":"\u6a19\u984c\u4e94","header6":"\u6a19\u984c\u516d","bold":"\u7c97\u9ad4","italic":"\u659c\u9ad4","unorderedlist":"\u9805\u76ee\u6e05\u55ae","orderedlist":"\u6578\u5b57\u6e05\u55ae","video":"\u5f71\u7247","image":"\u5716\u7247","link":"\u9023\u7d50","horizontalrule":"\u63d2\u5165\u6c34\u5e73\u7dda","fullscreen":"\u5168\u87a2\u5e55","preview":"\u9810\u89bd"},"mediamanager":{"insert_link":"\u63d2\u5165\u5a92\u9ad4\u6ac3\u9023\u7d50","insert_image":"\u63d2\u5165\u5a92\u9ad4\u6ac3\u5716\u7247","insert_video":"\u63d2\u5165\u5a92\u9ad4\u6ac3\u5f71\u7247","insert_audio":"\u63d2\u5165\u5a92\u9ad4\u6ac3\u97f3\u8a0a","invalid_file_empty_insert":"\u8acb\u9078\u64c7\u6a94\u6848\u4ee5\u63d2\u5165\u9023\u7d50\u3002","invalid_file_single_insert":"\u8acb\u9078\u64c7\u4e00\u500b\u6a94\u6848\u3002","invalid_image_empty_insert":"\u8acb\u9078\u64c7\u63d2\u5165\u7684\u5716\u7247\u3002","invalid_video_empty_insert":"\u8acb\u9078\u64c7\u63d2\u5165\u7684\u5f71\u7247\u3002","invalid_audio_empty_insert":"\u8acb\u9078\u64c7\u63d2\u5165\u7684\u97f3\u8a0a\u3002"},"alert":{"confirm_button_text":"\u78ba\u8a8d","cancel_button_text":"\u53d6\u6d88","widget_remove_confirm":"\u78ba\u5b9a\u79fb\u9664\u6b64\u5143\u4ef6\uff1f"},"datepicker":{"previousMonth":"\u4e0a\u500b\u6708","nextMonth":"\u4e0b\u500b\u6708","months":["\u4e00\u6708","\u4e8c\u6708","\u4e09\u6708","\u56db\u6708","\u4e94\u6708","\u516d\u6708","\u4e03\u6708","\u516b\u6708","\u4e5d\u6708","\u5341\u6708","\u5341\u4e00\u6708","\u5341\u4e8c\u6708"],"weekdays":["\u661f\u671f\u65e5","\u661f\u671f\u4e00","\u661f\u671f\u4e8c","\u661f\u671f\u4e09","\u661f\u671f\u56db","\u661f\u671f\u4e94","\u661f\u671f\u516d"],"weekdaysShort":["\u9031\u65e5","\u9031\u4e00","\u9031\u4e8c","\u9031\u4e09","\u9031\u56db","\u9031\u4e94","\u9031\u516d"]},"colorpicker":{"choose":"\u78ba\u5b9a"},"filter":{"group":{"all":"\u5168\u90e8"},"scopes":{"apply_button_text":"\u78ba\u5b9a","clear_button_text":"\u6e05\u9664"},"dates":{"all":"\u5168\u90e8","filter_button_text":"\u7be9\u9078","reset_button_text":"\u91cd\u7f6e","date_placeholder":"\u65e5\u671f","after_placeholder":"\u5728\u6b64\u4e4b\u5f8c","before_placeholder":"\u5728\u6b64\u4e4b\u524d"},"numbers":{"all":"\u5168\u90e8","filter_button_text":"\u7be9\u9078","reset_button_text":"\u91cd\u7f6e","min_placeholder":"\u6700\u5c0f\u503c","max_placeholder":"\u6700\u5927\u503c"}},"eventlog":{"show_stacktrace":"Show the stacktrace","hide_stacktrace":"Hide the stacktrace","tabs":{"formatted":"Formatted","raw":"Raw"},"editor":{"title":"Source code editor","description":"Your operating system should be configured to listen to one of these URL schemes.","openWith":"Open with","remember_choice":"Remember selected option for this session","open":"Open","cancel":"Cancel"}}}
{"markdowneditor":{"formatting":"\u683c\u5f0f","quote":"\u5f15\u7528","code":"\u7a0b\u5f0f\u78bc","header1":"\u6a19\u984c\u4e00","header2":"\u6a19\u984c\u4e8c","header3":"\u6a19\u984c\u4e09","header4":"\u6a19\u984c\u56db","header5":"\u6a19\u984c\u4e94","header6":"\u6a19\u984c\u516d","bold":"\u7c97\u9ad4","italic":"\u659c\u9ad4","unorderedlist":"\u9805\u76ee\u6e05\u55ae","orderedlist":"\u6578\u5b57\u6e05\u55ae","video":"\u5f71\u7247","image":"\u5716\u7247","link":"\u9023\u7d50","horizontalrule":"\u63d2\u5165\u6c34\u5e73\u7dda","fullscreen":"\u5168\u87a2\u5e55","preview":"\u9810\u89bd"},"mediamanager":{"insert_link":"\u63d2\u5165\u5a92\u9ad4\u6ac3\u9023\u7d50","insert_image":"\u63d2\u5165\u5a92\u9ad4\u6ac3\u5716\u7247","insert_video":"\u63d2\u5165\u5a92\u9ad4\u6ac3\u5f71\u7247","insert_audio":"\u63d2\u5165\u5a92\u9ad4\u6ac3\u97f3\u8a0a","invalid_file_empty_insert":"\u8acb\u9078\u64c7\u6a94\u6848\u4ee5\u63d2\u5165\u9023\u7d50\u3002","invalid_file_single_insert":"\u8acb\u9078\u64c7\u4e00\u500b\u6a94\u6848\u3002","invalid_image_empty_insert":"\u8acb\u9078\u64c7\u63d2\u5165\u7684\u5716\u7247\u3002","invalid_video_empty_insert":"\u8acb\u9078\u64c7\u63d2\u5165\u7684\u5f71\u7247\u3002","invalid_audio_empty_insert":"\u8acb\u9078\u64c7\u63d2\u5165\u7684\u97f3\u8a0a\u3002"},"alert":{"confirm_button_text":"\u78ba\u8a8d","cancel_button_text":"\u53d6\u6d88","widget_remove_confirm":"\u78ba\u5b9a\u79fb\u9664\u6b64\u5143\u4ef6\uff1f"},"datepicker":{"previousMonth":"\u4e0a\u500b\u6708","nextMonth":"\u4e0b\u500b\u6708","months":["\u4e00\u6708","\u4e8c\u6708","\u4e09\u6708","\u56db\u6708","\u4e94\u6708","\u516d\u6708","\u4e03\u6708","\u516b\u6708","\u4e5d\u6708","\u5341\u6708","\u5341\u4e00\u6708","\u5341\u4e8c\u6708"],"weekdays":["\u661f\u671f\u65e5","\u661f\u671f\u4e00","\u661f\u671f\u4e8c","\u661f\u671f\u4e09","\u661f\u671f\u56db","\u661f\u671f\u4e94","\u661f\u671f\u516d"],"weekdaysShort":["\u9031\u65e5","\u9031\u4e00","\u9031\u4e8c","\u9031\u4e09","\u9031\u56db","\u9031\u4e94","\u9031\u516d"]},"colorpicker":{"choose":"\u78ba\u5b9a"},"filter":{"group":{"all":"\u5168\u90e8"},"scopes":{"apply_button_text":"\u78ba\u5b9a","clear_button_text":"\u6e05\u9664"},"dates":{"all":"\u5168\u90e8","filter_button_text":"\u7be9\u9078","reset_button_text":"\u91cd\u7f6e","date_placeholder":"\u65e5\u671f","after_placeholder":"\u5728\u6b64\u4e4b\u5f8c","before_placeholder":"\u5728\u6b64\u4e4b\u524d"},"numbers":{"all":"\u5168\u90e8","filter_button_text":"\u7be9\u9078","reset_button_text":"\u91cd\u7f6e","min_placeholder":"\u6700\u5c0f\u503c","max_placeholder":"\u6700\u5927\u503c"}},"eventlog":{"show_stacktrace":"Show the stacktrace","hide_stacktrace":"Hide the stacktrace","tabs":{"formatted":"Formatted","raw":"Raw"},"editor":{"title":"Source code editor","description":"Your operating system should be configured to listen to one of these URL schemes.","openWith":"Open with","remember_choice":"Remember selected option for this session","open":"Open","cancel":"Cancel"}}}
);
//! moment.js locale configuration v2.22.2

View File

@ -75,7 +75,7 @@ Use the `data-handler` attribute to source the select options from an AJAX handl
class="form-control custom-select"
data-handler="onGetOptions"
data-minimum-input-length="2"
data-ajax--delay="300"
data-ajax-delay="300"
data-request-data="foo: 'bar'"
></select>
```

View File

@ -156,7 +156,7 @@
$(event.relatedTarget).on('input', '#controlFilterPopover input[data-search]', function (e) {
self.searchQuery($(this))
});
})
})
// Setup event handler to apply selected options when closing the type: group scope popup
@ -176,7 +176,7 @@
*/
FilterWidget.prototype.bindDependants = function() {
if (!$('[data-scope-depends]', this.$el).length) {
return;
return
}
var self = this,
@ -399,8 +399,8 @@
if (!data.active) data.active = []
if (!data.available) data.available = []
this.scopeValues[scopeName] = data.active;
this.scopeAvailable[scopeName] = data.available;
this.scopeValues[scopeName] = data.active
this.scopeAvailable[scopeName] = data.available
// Do not render if scope has changed
if (scopeName != this.activeScopeName)
@ -552,11 +552,12 @@
if (isReset) {
this.scopeValues[scopeName] = null
this.scopeAvailable[scopeName] = null
this.isActiveScopeDirty = true
this.updateScopeSetting(this.$activeScope, 0)
}
this.pushOptions(scopeName);
this.isActiveScopeDirty = true;
this.pushOptions(scopeName)
this.isActiveScopeDirty = false
this.$activeScope.data('oc.popover').hide()
}

View File

@ -344,6 +344,42 @@ input[type="number"]::-webkit-outer-spin-button {
height: auto;
}
//
// Prevents the placeholder getting displayed behind the incremental counter
// See github issue: https://github.com/octobercms/october/issues/5397
//
input[type="number"] {
&:focus {
&::-webkit-input-placeholder {
margin-right: 20px;
}
&::-moz-placeholder {
margin-right: 20px;
}
&:-ms-input-placeholder {
margin-right: 20px;
}
&::placeholder {
margin-right: 20px;
}
}
&:hover {
&::-webkit-input-placeholder {
margin-right: 20px;
}
&::-moz-placeholder {
margin-right: 20px;
}
&:-ms-input-placeholder {
margin-right: 20px;
}
&::placeholder {
margin-right: 20px;
}
}
}
//
// 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome.
// 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome

View File

@ -2422,8 +2422,7 @@ module.exports=factory(moment);}else if(typeof define==='function'&&define.amd){
return factory(moment);});}else{root.Pikaday=factory(root.moment);}}(this,function(moment)
{'use strict';var hasMoment=typeof moment==='function',hasEventListeners=!!window.addEventListener,document=window.document,sto=window.setTimeout,addEvent=function(el,e,callback,capture)
{if(hasEventListeners){el.addEventListener(e,callback,!!capture);}else{el.attachEvent('on'+e,callback);}},removeEvent=function(el,e,callback,capture)
{if(hasEventListeners){el.removeEventListener(e,callback,!!capture);}else{el.detachEvent('on'+e,callback);}},fireEvent=function(el,eventName,data)
{var ev;if(document.createEvent){ev=document.createEvent('HTMLEvents');ev.initEvent(eventName,true,false);ev=extend(ev,data);el.dispatchEvent(ev);}else if(document.createEventObject){ev=document.createEventObject();ev=extend(ev,data);el.fireEvent('on'+eventName,ev);}},trim=function(str)
{if(hasEventListeners){el.removeEventListener(e,callback,!!capture);}else{el.detachEvent('on'+e,callback);}},trim=function(str)
{return str.trim?str.trim():str.replace(/^\s+|\s+$/g,'');},hasClass=function(el,cn)
{return(' '+el.className+' ').indexOf(' '+cn+' ')!==-1;},addClass=function(el,cn)
{if(!hasClass(el,cn)){el.className=(el.className==='')?cn:el.className+' '+cn;}},removeClass=function(el,cn)
@ -2431,58 +2430,61 @@ return factory(moment);});}else{root.Pikaday=factory(root.moment);}}(this,functi
{return(/Array/).test(Object.prototype.toString.call(obj));},isDate=function(obj)
{return(/Date/).test(Object.prototype.toString.call(obj))&&!isNaN(obj.getTime());},isWeekend=function(date)
{var day=date.getDay();return day===0||day===6;},isLeapYear=function(year)
{return year%4===0&&year%100!==0||year%400===0;},getDaysInMonth=function(year,month)
{return((year%4===0&&year%100!==0)||year%400===0);},getDaysInMonth=function(year,month)
{return[31,isLeapYear(year)?29:28,31,30,31,30,31,31,30,31,30,31][month];},setToStartOfDay=function(date)
{if(isDate(date))date.setHours(0,0,0,0);},compareDates=function(a,b)
{return a.getTime()===b.getTime();},extend=function(to,from,overwrite)
{var prop,hasProp;for(prop in from){hasProp=to[prop]!==undefined;if(hasProp&&typeof from[prop]==='object'&&from[prop]!==null&&from[prop].nodeName===undefined){if(isDate(from[prop])){if(overwrite){to[prop]=new Date(from[prop].getTime());}}
else if(isArray(from[prop])){if(overwrite){to[prop]=from[prop].slice(0);}}else{to[prop]=extend({},from[prop],overwrite);}}else if(overwrite||!hasProp){to[prop]=from[prop];}}
return to;},adjustCalendar=function(calendar){if(calendar.month<0){calendar.year-=Math.ceil(Math.abs(calendar.month)/12);calendar.month+=12;}
return to;},fireEvent=function(el,eventName,data)
{var ev;if(document.createEvent){ev=document.createEvent('HTMLEvents');ev.initEvent(eventName,true,false);ev=extend(ev,data);el.dispatchEvent(ev);}else if(document.createEventObject){ev=document.createEventObject();ev=extend(ev,data);el.fireEvent('on'+eventName,ev);}},adjustCalendar=function(calendar){if(calendar.month<0){calendar.year-=Math.ceil(Math.abs(calendar.month)/12);calendar.month+=12;}
if(calendar.month>11){calendar.year+=Math.floor(Math.abs(calendar.month)/12);calendar.month-=12;}
return calendar;},defaults={field:null,bound:undefined,position:'bottom left',reposition:true,format:'YYYY-MM-DD',defaultDate:null,setDefaultDate:false,firstDay:0,minDate:null,maxDate:null,yearRange:10,showWeekNumber:false,minYear:0,maxYear:9999,minMonth:undefined,maxMonth:undefined,startRange:null,endRange:null,isRTL:false,yearSuffix:'',showMonthAfterYear:false,numberOfMonths:1,mainCalendar:'left',container:undefined,i18n:{previousMonth:'Previous Month',nextMonth:'Next Month',months:['January','February','March','April','May','June','July','August','September','October','November','December'],weekdays:['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],weekdaysShort:['Sun','Mon','Tue','Wed','Thu','Fri','Sat']},theme:null,onSelect:null,onOpen:null,onClose:null,onDraw:null},renderDayName=function(opts,day,abbr)
return calendar;},defaults={field:null,bound:undefined,ariaLabel:'Use the arrow keys to pick a date',position:'bottom left',reposition:true,format:'YYYY-MM-DD',toString:null,parse:null,defaultDate:null,setDefaultDate:false,firstDay:0,firstWeekOfYearMinDays:4,formatStrict:false,minDate:null,maxDate:null,yearRange:10,showWeekNumber:false,pickWholeWeek:false,minYear:0,maxYear:9999,minMonth:undefined,maxMonth:undefined,startRange:null,endRange:null,isRTL:false,yearSuffix:'',showMonthAfterYear:false,showDaysInNextAndPreviousMonths:false,enableSelectionDaysInNextAndPreviousMonths:false,numberOfMonths:1,mainCalendar:'left',container:undefined,blurFieldOnSelect:true,i18n:{previousMonth:'Previous Month',nextMonth:'Next Month',months:['January','February','March','April','May','June','July','August','September','October','November','December'],weekdays:['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],weekdaysShort:['Sun','Mon','Tue','Wed','Thu','Fri','Sat']},theme:null,events:[],onSelect:null,onOpen:null,onClose:null,onDraw:null,keyboardInput:true},renderDayName=function(opts,day,abbr)
{day+=opts.firstDay;while(day>=7){day-=7;}
return abbr?opts.i18n.weekdaysShort[day]:opts.i18n.weekdays[day];},renderDay=function(opts)
{if(opts.isEmpty){return'<td class="is-empty"></td>';}
var arr=[];if(opts.isDisabled){arr.push('is-disabled');}
{var arr=[];var ariaSelected='false';if(opts.isEmpty){if(opts.showDaysInNextAndPreviousMonths){arr.push('is-outside-current-month');if(!opts.enableSelectionDaysInNextAndPreviousMonths){arr.push('is-selection-disabled');}}else{return'<td class="is-empty"></td>';}}
if(opts.isDisabled){arr.push('is-disabled');}
if(opts.isToday){arr.push('is-today');}
if(opts.isSelected){arr.push('is-selected');}
if(opts.isSelected){arr.push('is-selected');ariaSelected='true';}
if(opts.hasEvent){arr.push('has-event');}
if(opts.isInRange){arr.push('is-inrange');}
if(opts.isStartRange){arr.push('is-startrange');}
if(opts.isEndRange){arr.push('is-endrange');}
return'<td data-day="'+opts.day+'" class="'+arr.join(' ')+'">'+'<button class="pika-button pika-day" type="button" '+'data-pika-year="'+opts.year+'" data-pika-month="'+opts.month+'" data-pika-day="'+opts.day+'">'+
opts.day+'</button>'+'</td>';},renderWeek=function(d,m,y){var onejan=new Date(y,0,1),weekNum=Math.ceil((((new Date(y,m,d)-onejan)/86400000)+onejan.getDay()+1)/7);return'<td class="pika-week">'+weekNum+'</td>';},renderRow=function(days,isRTL)
{return'<tr>'+(isRTL?days.reverse():days).join('')+'</tr>';},renderBody=function(rows)
return'<td data-day="'+opts.day+'" class="'+arr.join(' ')+'" aria-selected="'+ariaSelected+'">'+'<button class="pika-button pika-day" type="button" '+'data-pika-year="'+opts.year+'" data-pika-month="'+opts.month+'" data-pika-day="'+opts.day+'">'+
opts.day+'</button>'+'</td>';},isoWeek=function(date,firstWeekOfYearMinDays){date.setHours(0,0,0,0);var yearDay=date.getDate(),weekDay=date.getDay(),dayInFirstWeek=firstWeekOfYearMinDays,dayShift=dayInFirstWeek-1,daysPerWeek=7,prevWeekDay=function(day){return(day+daysPerWeek-1)%daysPerWeek;};date.setDate(yearDay+dayShift-prevWeekDay(weekDay));var jan4th=new Date(date.getFullYear(),0,dayInFirstWeek),msPerDay=24*60*60*1000,daysBetween=(date.getTime()-jan4th.getTime())/msPerDay,weekNum=1+Math.round((daysBetween-dayShift+prevWeekDay(jan4th.getDay()))/daysPerWeek);return weekNum;},renderWeek=function(d,m,y,firstWeekOfYearMinDays){var date=new Date(y,m,d),week=hasMoment?moment(date).isoWeek():isoWeek(date,firstWeekOfYearMinDays);return'<td class="pika-week">'+week+'</td>';},renderRow=function(days,isRTL,pickWholeWeek,isRowSelected)
{return'<tr class="pika-row'+(pickWholeWeek?' pick-whole-week':'')+(isRowSelected?' is-selected':'')+'">'+(isRTL?days.reverse():days).join('')+'</tr>';},renderBody=function(rows)
{return'<tbody>'+rows.join('')+'</tbody>';},renderHead=function(opts)
{var i,arr=[];if(opts.showWeekNumber){arr.push('<th></th>');}
for(i=0;i<7;i++){arr.push('<th scope="col"><abbr title="'+renderDayName(opts,i)+'">'+renderDayName(opts,i,true)+'</abbr></th>');}
return'<thead>'+(opts.isRTL?arr.reverse():arr).join('')+'</thead>';},renderTitle=function(instance,c,year,month,refYear)
{var i,j,arr,opts=instance._o,isMinYear=year===opts.minYear,isMaxYear=year===opts.maxYear,html='<div class="pika-title">',monthHtml,yearHtml,prev=true,next=true;for(arr=[],i=0;i<12;i++){arr.push('<option value="'+(year===refYear?i-c:12+i-c)+'"'+
(i===month?' selected':'')+
((isMinYear&&i<opts.minMonth)||(isMaxYear&&i>opts.maxMonth)?'disabled':'')+'>'+
return'<thead><tr>'+(opts.isRTL?arr.reverse():arr).join('')+'</tr></thead>';},renderTitle=function(instance,c,year,month,refYear,randId)
{var i,j,arr,opts=instance._o,isMinYear=year===opts.minYear,isMaxYear=year===opts.maxYear,html='<div id="'+randId+'" class="pika-title" role="heading" aria-live="assertive">',monthHtml,yearHtml,prev=true,next=true;for(arr=[],i=0;i<12;i++){arr.push('<option value="'+(year===refYear?i-c:12+i-c)+'"'+
(i===month?' selected="selected"':'')+
((isMinYear&&i<opts.minMonth)||(isMaxYear&&i>opts.maxMonth)?' disabled="disabled"':'')+'>'+
opts.i18n.months[i]+'</option>');}
monthHtml='<div class="pika-label">'+opts.i18n.months[month]+'<select class="pika-select pika-select-month" tabindex="-1">'+arr.join('')+'</select></div>';if(isArray(opts.yearRange)){i=opts.yearRange[0];j=opts.yearRange[1]+1;}else{i=year-opts.yearRange;j=1+year+opts.yearRange;}
for(arr=[];i<j&&i<=opts.maxYear;i++){if(i>=opts.minYear){arr.push('<option value="'+i+'"'+(i===year?' selected':'')+'>'+(i)+'</option>');}}
for(arr=[];i<j&&i<=opts.maxYear;i++){if(i>=opts.minYear){arr.push('<option value="'+i+'"'+(i===year?' selected="selected"':'')+'>'+(i)+'</option>');}}
yearHtml='<div class="pika-label">'+year+opts.yearSuffix+'<select class="pika-select pika-select-year" tabindex="-1">'+arr.join('')+'</select></div>';if(opts.showMonthAfterYear){html+=yearHtml+monthHtml;}else{html+=monthHtml+yearHtml;}
if(isMinYear&&(month===0||opts.minMonth>=month)){prev=false;}
if(isMaxYear&&(month===11||opts.maxMonth<=month)){next=false;}
if(c===0){html+='<button class="pika-prev'+(prev?'':' is-disabled')+'" type="button">'+opts.i18n.previousMonth+'</button>';}
if(c===(instance._o.numberOfMonths-1)){html+='<button class="pika-next'+(next?'':' is-disabled')+'" type="button">'+opts.i18n.nextMonth+'</button>';}
return html+='</div>';},renderTable=function(opts,data)
{return'<table cellpadding="0" cellspacing="0" class="pika-table">'+renderHead(opts)+renderBody(data)+'</table>';},Pikaday=function(options)
return html+='</div>';},renderTable=function(opts,data,randId)
{return'<table cellpadding="0" cellspacing="0" class="pika-table" role="grid" aria-labelledby="'+randId+'">'+renderHead(opts)+renderBody(data)+'</table>';},Pikaday=function(options)
{var self=this,opts=self.config(options);self._onMouseDown=function(e)
{if(!self._v){return;}
e=e||window.event;var target=e.target||e.srcElement;if(!target){return;}
if(!hasClass(target,'is-disabled')){if(hasClass(target,'pika-button')&&!hasClass(target,'is-empty')){self.setDate(new Date(target.getAttribute('data-pika-year'),target.getAttribute('data-pika-month'),target.getAttribute('data-pika-day')));if(opts.bound){sto(function(){self.hide();if(opts.field){opts.field.blur();}},100);}}
if(!hasClass(target,'is-disabled')){if(hasClass(target,'pika-button')&&!hasClass(target,'is-empty')&&!hasClass(target.parentNode,'is-disabled')){self.setDate(new Date(target.getAttribute('data-pika-year'),target.getAttribute('data-pika-month'),target.getAttribute('data-pika-day')));if(opts.bound){sto(function(){self.hide();if(opts.blurFieldOnSelect&&opts.field){opts.field.blur();}},100);}}
else if(hasClass(target,'pika-prev')){self.prevMonth();}
else if(hasClass(target,'pika-next')){self.nextMonth();}}
if(!hasClass(target,'pika-select')){if(e.preventDefault){e.preventDefault();}else{e.returnValue=false;return false;}}else{self._c=true;}};self._onChange=function(e)
{e=e||window.event;var target=e.target||e.srcElement;if(!target){return;}
if(hasClass(target,'pika-select-month')){self.gotoMonth(target.value);}
else if(hasClass(target,'pika-select-year')){self.gotoYear(target.value);}};self._onInputChange=function(e)
else if(hasClass(target,'pika-select-year')){self.gotoYear(target.value);}};self._onKeyChange=function(e)
{e=e||window.event;if(self.isVisible()){switch(e.keyCode){case 13:case 27:if(opts.field){opts.field.blur();}
break;case 37:self.adjustDate('subtract',1);break;case 38:self.adjustDate('subtract',7);break;case 39:self.adjustDate('add',1);break;case 40:self.adjustDate('add',7);break;case 8:case 46:self.setDate(null);break;}}};self._parseFieldValue=function()
{if(opts.parse){return opts.parse(opts.field.value,opts.format);}else if(hasMoment){var date=moment(opts.field.value,opts.format,opts.formatStrict);return(date&&date.isValid())?date.toDate():null;}else{return new Date(Date.parse(opts.field.value));}};self._onInputChange=function(e)
{var date;if(e.firedBy===self){return;}
if(hasMoment){date=moment(opts.field.value,opts.format);date=(date&&date.isValid())?date.toDate():null;}
else{date=new Date(Date.parse(opts.field.value));}
if(isDate(date)){self.setDate(date);}
date=self._parseFieldValue();if(isDate(date)){self.setDate(date);}
if(!self._v){self.show();}};self._onInputFocus=function()
{self.show();};self._onInputClick=function()
{self.show();};self._onInputBlur=function()
@ -2492,9 +2494,9 @@ self._c=false;};self._onClick=function(e)
{e=e||window.event;var target=e.target||e.srcElement,pEl=target;if(!target){return;}
if(!hasEventListeners&&hasClass(target,'pika-select')){if(!target.onchange){target.setAttribute('onchange','return;');addEvent(target,'change',self._onChange);}}
do{if(hasClass(pEl,'pika-single')||pEl===opts.trigger){return;}}
while((pEl=pEl.parentNode));if(self._v&&target!==opts.trigger&&pEl!==opts.trigger){self.hide();}};self.el=document.createElement('div');self.el.className='pika-single'+(opts.isRTL?' is-rtl':'')+(opts.theme?' '+opts.theme:'');addEvent(self.el,'mousedown',self._onMouseDown,true);addEvent(self.el,'touchend',self._onMouseDown,true);addEvent(self.el,'change',self._onChange);if(opts.field){if(opts.container){opts.container.appendChild(self.el);}else if(opts.bound){document.body.appendChild(self.el);}else{opts.field.parentNode.insertBefore(self.el,opts.field.nextSibling);}
addEvent(opts.field,'change',self._onInputChange);if(!opts.defaultDate){if(hasMoment&&opts.field.value){opts.defaultDate=moment(opts.field.value,opts.format).toDate();}else{opts.defaultDate=new Date(Date.parse(opts.field.value));}
opts.setDefaultDate=true;}}
while((pEl=pEl.parentNode));if(self._v&&target!==opts.trigger&&pEl!==opts.trigger){self.hide();}};self.el=document.createElement('div');self.el.className='pika-single'+(opts.isRTL?' is-rtl':'')+(opts.theme?' '+opts.theme:'');addEvent(self.el,'mousedown',self._onMouseDown,true);addEvent(self.el,'touchend',self._onMouseDown,true);addEvent(self.el,'change',self._onChange);if(opts.keyboardInput){addEvent(document,'keydown',self._onKeyChange);}
if(opts.field){if(opts.container){opts.container.appendChild(self.el);}else if(opts.bound){document.body.appendChild(self.el);}else{opts.field.parentNode.insertBefore(self.el,opts.field.nextSibling);}
addEvent(opts.field,'change',self._onInputChange);if(!opts.defaultDate){opts.defaultDate=self._parseFieldValue();opts.setDefaultDate=true;}}
var defDate=opts.defaultDate;if(isDate(defDate)){if(opts.setDefaultDate){self.setDate(defDate,true);}else{self.gotoDate(defDate);}}else{self.gotoDate(new Date());}
if(opts.bound){this.hide();self.el.className+=' is-bound';addEvent(opts.trigger,'click',self._onInputClick);addEvent(opts.trigger,'focus',self._onInputFocus);addEvent(opts.trigger,'blur',self._onInputBlur);}else{this.show();}};Pikaday.prototype={config:function(options)
{if(!this._o){this._o=extend({},defaults,true);}
@ -2505,7 +2507,10 @@ if(opts.minDate){this.setMinDate(opts.minDate);}
if(opts.maxDate){this.setMaxDate(opts.maxDate);}
if(isArray(opts.yearRange)){var fallback=new Date().getFullYear()-10;opts.yearRange[0]=parseInt(opts.yearRange[0],10)||fallback;opts.yearRange[1]=parseInt(opts.yearRange[1],10)||fallback;}else{opts.yearRange=Math.abs(parseInt(opts.yearRange,10))||defaults.yearRange;if(opts.yearRange>100){opts.yearRange=100;}}
return opts;},toString:function(format)
{return!isDate(this._d)?'':hasMoment?moment(this._d).format(format||this._o.format):this._d.toDateString();},getMoment:function()
{format=format||this._o.format;if(!isDate(this._d)){return'';}
if(this._o.toString){return this._o.toString(this._d,format);}
if(hasMoment){return moment(this._d).format(format);}
return this._d.toDateString();},getMoment:function()
{return hasMoment?moment(this._d):null;},setMoment:function(date,preventOnSelect)
{if(hasMoment&&moment.isMoment(date)){this.setDate(date.toDate(),preventOnSelect);}},getDate:function()
{return isDate(this._d)?new Date(this._d.getTime()):null;},setDate:function(date,preventOnSelect)
@ -2515,45 +2520,54 @@ if(typeof date==='string'){date=new Date(Date.parse(date));}
if(!isDate(date)){return;}
var min=this._o.minDate,max=this._o.maxDate;if(isDate(min)&&date<min){date=min;}else if(isDate(max)&&date>max){date=max;}
this._d=new Date(date.getTime());setToStartOfDay(this._d);this.gotoDate(this._d);if(this._o.field){this._o.field.value=this.toString();fireEvent(this._o.field,'change',{firedBy:this});}
if(!preventOnSelect&&typeof this._o.onSelect==='function'){this._o.onSelect.call(this,this.getDate());}},gotoDate:function(date)
if(!preventOnSelect&&typeof this._o.onSelect==='function'){this._o.onSelect.call(this,this.getDate());}},clear:function()
{this.setDate(null);},gotoDate:function(date)
{var newCalendar=true;if(!isDate(date)){return;}
if(this.calendars){var firstVisibleDate=new Date(this.calendars[0].year,this.calendars[0].month,1),lastVisibleDate=new Date(this.calendars[this.calendars.length-1].year,this.calendars[this.calendars.length-1].month,1),visibleDate=date.getTime();lastVisibleDate.setMonth(lastVisibleDate.getMonth()+1);lastVisibleDate.setDate(lastVisibleDate.getDate()-1);newCalendar=(visibleDate<firstVisibleDate.getTime()||lastVisibleDate.getTime()<visibleDate);}
if(newCalendar){this.calendars=[{month:date.getMonth(),year:date.getFullYear()}];if(this._o.mainCalendar==='right'){this.calendars[0].month+=1-this._o.numberOfMonths;}}
this.adjustCalendars();},adjustCalendars:function(){this.calendars[0]=adjustCalendar(this.calendars[0]);for(var c=1;c<this._o.numberOfMonths;c++){this.calendars[c]=adjustCalendar({month:this.calendars[0].month+c,year:this.calendars[0].year});}
this.adjustCalendars();},adjustDate:function(sign,days){var day=this.getDate()||new Date();var difference=parseInt(days)*24*60*60*1000;var newDay;if(sign==='add'){newDay=new Date(day.valueOf()+difference);}else if(sign==='subtract'){newDay=new Date(day.valueOf()-difference);}
this.setDate(newDay);},adjustCalendars:function(){this.calendars[0]=adjustCalendar(this.calendars[0]);for(var c=1;c<this._o.numberOfMonths;c++){this.calendars[c]=adjustCalendar({month:this.calendars[0].month+c,year:this.calendars[0].year});}
this.draw();},gotoToday:function()
{this.gotoDate(new Date());},gotoMonth:function(month)
{if(!isNaN(month)){this.calendars[0].month=parseInt(month,10);this.adjustCalendars();}},nextMonth:function()
{this.calendars[0].month++;this.adjustCalendars();},prevMonth:function()
{this.calendars[0].month--;this.adjustCalendars();},gotoYear:function(year)
{if(!isNaN(year)){this.calendars[0].year=parseInt(year,10);this.adjustCalendars();}},setMinDate:function(value)
{setToStartOfDay(value);this._o.minDate=value;this._o.minYear=value.getFullYear();this._o.minMonth=value.getMonth();this.draw();},setMaxDate:function(value)
{setToStartOfDay(value);this._o.maxDate=value;this._o.maxYear=value.getFullYear();this._o.maxMonth=value.getMonth();this.draw();},setStartRange:function(value)
{if(value instanceof Date){setToStartOfDay(value);this._o.minDate=value;this._o.minYear=value.getFullYear();this._o.minMonth=value.getMonth();}else{this._o.minDate=defaults.minDate;this._o.minYear=defaults.minYear;this._o.minMonth=defaults.minMonth;this._o.startRange=defaults.startRange;}
this.draw();},setMaxDate:function(value)
{if(value instanceof Date){setToStartOfDay(value);this._o.maxDate=value;this._o.maxYear=value.getFullYear();this._o.maxMonth=value.getMonth();}else{this._o.maxDate=defaults.maxDate;this._o.maxYear=defaults.maxYear;this._o.maxMonth=defaults.maxMonth;this._o.endRange=defaults.endRange;}
this.draw();},setStartRange:function(value)
{this._o.startRange=value;},setEndRange:function(value)
{this._o.endRange=value;},draw:function(force)
{if(!this._v&&!force){return;}
var opts=this._o,minYear=opts.minYear,maxYear=opts.maxYear,minMonth=opts.minMonth,maxMonth=opts.maxMonth,html='';if(this._y<=minYear){this._y=minYear;if(!isNaN(minMonth)&&this._m<minMonth){this._m=minMonth;}}
var opts=this._o,minYear=opts.minYear,maxYear=opts.maxYear,minMonth=opts.minMonth,maxMonth=opts.maxMonth,html='',randId;if(this._y<=minYear){this._y=minYear;if(!isNaN(minMonth)&&this._m<minMonth){this._m=minMonth;}}
if(this._y>=maxYear){this._y=maxYear;if(!isNaN(maxMonth)&&this._m>maxMonth){this._m=maxMonth;}}
for(var c=0;c<opts.numberOfMonths;c++){html+='<div class="pika-lendar">'+renderTitle(this,c,this.calendars[c].year,this.calendars[c].month,this.calendars[0].year)+this.render(this.calendars[c].year,this.calendars[c].month)+'</div>';}
for(var c=0;c<opts.numberOfMonths;c++){randId='pika-title-'+Math.random().toString(36).replace(/[^a-z]+/g,'').substr(0,2);html+='<div class="pika-lendar">'+renderTitle(this,c,this.calendars[c].year,this.calendars[c].month,this.calendars[0].year,randId)+this.render(this.calendars[c].year,this.calendars[c].month,randId)+'</div>';}
this.el.innerHTML=html;if(opts.bound){if(opts.field.type!=='hidden'){sto(function(){opts.trigger.focus();},1);}}
if(typeof this._o.onDraw==='function'){var self=this;sto(function(){self._o.onDraw.call(self);},0);}},adjustPosition:function()
{var field,pEl,width,height,viewportWidth,viewportHeight,scrollTop,left,top,clientRect;if(this._o.container)return;this.el.style.position='absolute';field=this._o.trigger;pEl=field;width=this.el.offsetWidth;height=this.el.offsetHeight;viewportWidth=window.innerWidth||document.documentElement.clientWidth;viewportHeight=window.innerHeight||document.documentElement.clientHeight;scrollTop=window.pageYOffset||document.body.scrollTop||document.documentElement.scrollTop;if(typeof field.getBoundingClientRect==='function'){clientRect=field.getBoundingClientRect();left=clientRect.left+window.pageXOffset;top=clientRect.bottom+window.pageYOffset;}else{left=pEl.offsetLeft;top=pEl.offsetTop+pEl.offsetHeight;while((pEl=pEl.offsetParent)){left+=pEl.offsetLeft;top+=pEl.offsetTop;}}
if((this._o.reposition&&left+width>viewportWidth)||(this._o.position.indexOf('right')>-1&&left-width+field.offsetWidth>0)){left=left-width+field.offsetWidth;}
if((this._o.reposition&&top+height>viewportHeight+scrollTop)||(this._o.position.indexOf('top')>-1&&top-height-field.offsetHeight>0)){top=top-height-field.offsetHeight;}
this.el.style.left=left+'px';this.el.style.top=top+'px';},render:function(year,month)
if(typeof this._o.onDraw==='function'){this._o.onDraw(this);}
if(opts.bound){opts.field.setAttribute('aria-label',opts.ariaLabel);}},adjustPosition:function()
{var field,pEl,width,height,viewportWidth,viewportHeight,scrollTop,left,top,clientRect,leftAligned,bottomAligned;if(this._o.container)return;this.el.style.position='absolute';field=this._o.trigger;pEl=field;width=this.el.offsetWidth;height=this.el.offsetHeight;viewportWidth=window.innerWidth||document.documentElement.clientWidth;viewportHeight=window.innerHeight||document.documentElement.clientHeight;scrollTop=window.pageYOffset||document.body.scrollTop||document.documentElement.scrollTop;leftAligned=true;bottomAligned=true;if(typeof field.getBoundingClientRect==='function'){clientRect=field.getBoundingClientRect();left=clientRect.left+window.pageXOffset;top=clientRect.bottom+window.pageYOffset;}else{left=pEl.offsetLeft;top=pEl.offsetTop+pEl.offsetHeight;while((pEl=pEl.offsetParent)){left+=pEl.offsetLeft;top+=pEl.offsetTop;}}
if((this._o.reposition&&left+width>viewportWidth)||(this._o.position.indexOf('right')>-1&&left-width+field.offsetWidth>0)){left=left-width+field.offsetWidth;leftAligned=false;}
if((this._o.reposition&&top+height>viewportHeight+scrollTop)||(this._o.position.indexOf('top')>-1&&top-height-field.offsetHeight>0)){top=top-height-field.offsetHeight;bottomAligned=false;}
this.el.style.left=left+'px';this.el.style.top=top+'px';addClass(this.el,leftAligned?'left-aligned':'right-aligned');addClass(this.el,bottomAligned?'bottom-aligned':'top-aligned');removeClass(this.el,!leftAligned?'left-aligned':'right-aligned');removeClass(this.el,!bottomAligned?'bottom-aligned':'top-aligned');},render:function(year,month,randId)
{var opts=this._o,now=new Date(),days=getDaysInMonth(year,month),before=new Date(year,month,1).getDay(),data=[],row=[];setToStartOfDay(now);if(opts.firstDay>0){before-=opts.firstDay;if(before<0){before+=7;}}
var cells=days+before,after=cells;while(after>7){after-=7;}
cells+=7-after;for(var i=0,r=0;i<cells;i++)
{var day=new Date(year,month,1+(i-before)),isSelected=isDate(this._d)?compareDates(day,this._d):false,isToday=compareDates(day,now),isEmpty=i<before||i>=(days+before),isStartRange=opts.startRange&&compareDates(opts.startRange,day),isEndRange=opts.endRange&&compareDates(opts.endRange,day),isInRange=opts.startRange&&opts.endRange&&opts.startRange<day&&day<opts.endRange,isDisabled=(opts.minDate&&day<opts.minDate)||(opts.maxDate&&day>opts.maxDate)||(opts.disableWeekends&&isWeekend(day))||(opts.disableDayFn&&opts.disableDayFn(day)),dayConfig={day:1+(i-before),month:month,year:year,isSelected:isSelected,isToday:isToday,isDisabled:isDisabled,isEmpty:isEmpty,isStartRange:isStartRange,isEndRange:isEndRange,isInRange:isInRange};row.push(renderDay(dayConfig));if(++r===7){if(opts.showWeekNumber){row.unshift(renderWeek(i-before,month,year));}
data.push(renderRow(row,opts.isRTL));row=[];r=0;}}
return renderTable(opts,data);},isVisible:function()
var previousMonth=month===0?11:month-1,nextMonth=month===11?0:month+1,yearOfPreviousMonth=month===0?year-1:year,yearOfNextMonth=month===11?year+1:year,daysInPreviousMonth=getDaysInMonth(yearOfPreviousMonth,previousMonth);var cells=days+before,after=cells;while(after>7){after-=7;}
cells+=7-after;var isWeekSelected=false;for(var i=0,r=0;i<cells;i++)
{var day=new Date(year,month,1+(i-before)),isSelected=isDate(this._d)?compareDates(day,this._d):false,isToday=compareDates(day,now),hasEvent=opts.events.indexOf(day.toDateString())!==-1?true:false,isEmpty=i<before||i>=(days+before),dayNumber=1+(i-before),monthNumber=month,yearNumber=year,isStartRange=opts.startRange&&compareDates(opts.startRange,day),isEndRange=opts.endRange&&compareDates(opts.endRange,day),isInRange=opts.startRange&&opts.endRange&&opts.startRange<day&&day<opts.endRange,isDisabled=(opts.minDate&&day<opts.minDate)||(opts.maxDate&&day>opts.maxDate)||(opts.disableWeekends&&isWeekend(day))||(opts.disableDayFn&&opts.disableDayFn(day));if(isEmpty){if(i<before){dayNumber=daysInPreviousMonth+dayNumber;monthNumber=previousMonth;yearNumber=yearOfPreviousMonth;}else{dayNumber=dayNumber-days;monthNumber=nextMonth;yearNumber=yearOfNextMonth;}}
var dayConfig={day:dayNumber,month:monthNumber,year:yearNumber,hasEvent:hasEvent,isSelected:isSelected,isToday:isToday,isDisabled:isDisabled,isEmpty:isEmpty,isStartRange:isStartRange,isEndRange:isEndRange,isInRange:isInRange,showDaysInNextAndPreviousMonths:opts.showDaysInNextAndPreviousMonths,enableSelectionDaysInNextAndPreviousMonths:opts.enableSelectionDaysInNextAndPreviousMonths};if(opts.pickWholeWeek&&isSelected){isWeekSelected=true;}
row.push(renderDay(dayConfig));if(++r===7){if(opts.showWeekNumber){row.unshift(renderWeek(i-before,month,year,opts.firstWeekOfYearMinDays));}
data.push(renderRow(row,opts.isRTL,opts.pickWholeWeek,isWeekSelected));row=[];r=0;isWeekSelected=false;}}
return renderTable(opts,data,randId);},isVisible:function()
{return this._v;},show:function()
{if(!this._v){removeClass(this.el,'is-hidden');this._v=true;this.draw();if(this._o.bound){addEvent(document,'click',this._onClick);this.adjustPosition();}
{if(!this.isVisible()){this._v=true;this.draw();removeClass(this.el,'is-hidden');if(this._o.bound){addEvent(document,'click',this._onClick);this.adjustPosition();}
if(typeof this._o.onOpen==='function'){this._o.onOpen.call(this);}}},hide:function()
{var v=this._v;if(v!==false){if(this._o.bound){removeEvent(document,'click',this._onClick);}
this.el.style.position='static';this.el.style.left='auto';this.el.style.top='auto';addClass(this.el,'is-hidden');this._v=false;if(v!==undefined&&typeof this._o.onClose==='function'){this._o.onClose.call(this);}}},destroy:function()
{this.hide();removeEvent(this.el,'mousedown',this._onMouseDown,true);removeEvent(this.el,'touchend',this._onMouseDown,true);removeEvent(this.el,'change',this._onChange);if(this._o.field){removeEvent(this._o.field,'change',this._onInputChange);if(this._o.bound){removeEvent(this._o.trigger,'click',this._onInputClick);removeEvent(this._o.trigger,'focus',this._onInputFocus);removeEvent(this._o.trigger,'blur',this._onInputBlur);}}
if(!this._o.container){this.el.style.position='static';this.el.style.left='auto';this.el.style.top='auto';}
addClass(this.el,'is-hidden');this._v=false;if(v!==undefined&&typeof this._o.onClose==='function'){this._o.onClose.call(this);}}},destroy:function()
{var opts=this._o;this.hide();removeEvent(this.el,'mousedown',this._onMouseDown,true);removeEvent(this.el,'touchend',this._onMouseDown,true);removeEvent(this.el,'change',this._onChange);if(opts.keyboardInput){removeEvent(document,'keydown',this._onKeyChange);}
if(opts.field){removeEvent(opts.field,'change',this._onInputChange);if(opts.bound){removeEvent(opts.trigger,'click',this._onInputClick);removeEvent(opts.trigger,'focus',this._onInputFocus);removeEvent(opts.trigger,'blur',this._onInputBlur);}}
if(this.el.parentNode){this.el.parentNode.removeChild(this.el);}}};return Pikaday;}));(function(root,factory)
{'use strict';if(typeof exports==='object'){factory(require('jquery'),require('../pikaday'));}else if(typeof define==='function'&&define.amd){define(['jquery','pikaday'],factory);}else{factory(root.jQuery,root.Pikaday);}}(this,function($,Pikaday)
{'use strict';if(typeof exports==='object'){factory(require('jquery'),require('pikaday'));}else if(typeof define==='function'&&define.amd){define(['jquery','pikaday'],factory);}else{factory(root.jQuery,root.Pikaday);}}(this,function($,Pikaday)
{'use strict';$.fn.pikaday=function()
{var args=arguments;if(!args||!args.length){args=[{}];}
return this.each(function()
@ -3114,13 +3128,13 @@ $(event.relatedTarget).on('click','#controlFilterPopover [data-filter-action="ap
self.filterScope()})
$(event.relatedTarget).on('click','#controlFilterPopover [data-filter-action="clear"]',function(e){e.preventDefault()
self.filterScope(true)})
$(event.relatedTarget).on('input','#controlFilterPopover input[data-search]',function(e){self.searchQuery($(this))});})
$(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
self.$activeScope=null
setTimeout(function(){$scope.removeClass('filter-scope-open')},200)})}
FilterWidget.prototype.bindDependants=function(){if(!$('[data-scope-depends]',this.$el).length){return;}
FilterWidget.prototype.bindDependants=function(){if(!$('[data-scope-depends]',this.$el).length){return}
var self=this,scopeMap={},scopeElements=this.$el.find('.filter-scope')
scopeElements.filter('[data-scope-depends]').each(function(){var name=$(this).data('scope-name'),depends=$(this).data('scope-depends')
$.each(depends,function(index,depend){if(!scopeMap[depend]){scopeMap[depend]={scopes:[]}}
@ -3183,7 +3197,9 @@ FilterWidget.prototype.fillOptions=function(scopeName,data){if(this.scopeValues[
return
if(!data.active)data.active=[]
if(!data.available)data.available=[]
this.scopeValues[scopeName]=data.active;this.scopeAvailable[scopeName]=data.available;if(scopeName!=this.activeScopeName)
this.scopeValues[scopeName]=data.active
this.scopeAvailable[scopeName]=data.available
if(scopeName!=this.activeScopeName)
return
var container=$('#controlFilterPopover .filter-items > ul').empty()
this.addItemsToListElement(container,data.available)
@ -3226,8 +3242,11 @@ $scope.toggleClass('active',!!switchValue)}
FilterWidget.prototype.filterScope=function(isReset){var scopeName=this.$activeScope.data('scope-name')
if(isReset){this.scopeValues[scopeName]=null
this.scopeAvailable[scopeName]=null
this.isActiveScopeDirty=true
this.updateScopeSetting(this.$activeScope,0)}
this.pushOptions(scopeName);this.isActiveScopeDirty=true;this.$activeScope.data('oc.popover').hide()}
this.pushOptions(scopeName)
this.isActiveScopeDirty=false
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)}

View File

@ -63,6 +63,14 @@ input[type="checkbox"],
input[type="radio"] {box-sizing:border-box;padding:0}
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {height:auto}
input[type="number"]:focus::-webkit-input-placeholder {margin-right:20px}
input[type="number"]:focus::-moz-placeholder {margin-right:20px}
input[type="number"]:focus:-ms-input-placeholder {margin-right:20px}
input[type="number"]:focus::placeholder {margin-right:20px}
input[type="number"]:hover::-webkit-input-placeholder {margin-right:20px}
input[type="number"]:hover::-moz-placeholder {margin-right:20px}
input[type="number"]:hover:-ms-input-placeholder {margin-right:20px}
input[type="number"]:hover::placeholder {margin-right:20px}
input[type="search"] {-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {-webkit-appearance:none}

View File

@ -1,19 +1,49 @@
Pikaday
========
[![NPM version][npm-image]][npm-url]
[![License][license-image]][license-url]
[![Downloads][downloads-image]][downloads-url]
### A refreshing JavaScript Datepicker
* Lightweight (less than 5kb minified and gzipped)
* No dependencies (but plays well with [Moment.js][moment]
* No dependencies (but plays well with [Moment.js][moment])
* Modular CSS classes for easy styling
[**Try Pikaday Demo →**][Pikaday]
![Pikaday Screenshot][screenshot]
**Production ready?** Since version 1.0.0 Pikaday is stable and used in production. If you do however find bugs or have feature requests please submit them to the [GitHub issue tracker][issues].
**Production ready?** Since version 1.0.0 Pikaday is stable and used in production. If you do however find bugs or have feature requests please submit them to the [GitHub issue tracker][issues].
Also see the [changelog](CHANGELOG.md)
## Installation
You can install Pikaday as an NPM package:
```shell
npm install pikaday
```
Or link directly to the CDN:
```html
<script src="https://cdn.jsdelivr.net/npm/pikaday/pikaday.js"></script>
```
## Styles
You will also need to include Pikaday CSS file. This step depends on how Pikaday was installed. Either import from NPM:
```css
@import './node_modules/pikaday/css/pikaday.css';
```
Or link to the CDN:
```html
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/pikaday/css/pikaday.css">
```
## Usage
@ -50,11 +80,14 @@ var picker = new Pikaday({
field.parentNode.insertBefore(picker.el, field.nextSibling);
```
For advanced formatting load [Moment.js][moment] prior to Pikaday:
### Formatting
By default, dates are formatted and parsed using standard JavaScript Date object.
If [Moment.js][moment] is available in scope, it will be used to format and parse input values. You can pass an additional `format` option to the configuration which will be passed to the `moment` constructor.
See the [moment.js example][] for a full version.
```html
<input type="text" id="datepicker" value="9 Oct 2012">
<input type="text" id="datepicker" value="9 Oct 2014">
<script src="moment.js"></script>
<script src="pikaday.js"></script>
@ -69,6 +102,40 @@ See the [moment.js example][] for a full version.
</script>
```
For more advanced and flexible formatting you can pass your own `toString` function to the configuration which will be used to format the date object.
This function has the following signature:
`toString(date, format = 'YYYY-MM-DD')`
You should return a string from it.
Be careful, though. If the formatted string that you return cannot be correctly parsed by the `Date.parse` method (or by `moment` if it is available), then you must provide your own `parse` function in the config. This function will be passed the formatted string and the format:
`parse(dateString, format = 'YYYY-MM-DD')`
```javascript
var picker = new Pikaday({
field: document.getElementById('datepicker'),
format: 'D/M/YYYY',
toString(date, format) {
// you should do formatting based on the passed format,
// but we will just return 'D/M/YYYY' for simplicity
const day = date.getDate();
const month = date.getMonth() + 1;
const year = date.getFullYear();
return `${day}/${month}/${year}`;
},
parse(dateString, format) {
// dateString is the result of `toString` method
const parts = dateString.split('/');
const day = parseInt(parts[0], 10);
const month = parseInt(parts[1], 10) - 1;
const year = parseInt(parts[2], 10);
return new Date(year, month, day);
}
});
```
### Configuration
As the examples demonstrate above
@ -77,30 +144,59 @@ Pikaday has many useful options:
* `field` bind the datepicker to a form field
* `trigger` use a different element to trigger opening the datepicker, see [trigger example][] (default to `field`)
* `bound` automatically show/hide the datepicker on `field` focus (default `true` if `field` is set)
* `format` the default output format for `.toString()` and `field` value (requires [Moment.js][moment] for advanced formatting)
* `ariaLabel` data-attribute on the input field with an aria assistance text (only applied when `bound` is set)
* `position` preferred position of the datepicker relative to the form field, e.g.: `top right`, `bottom right` **Note:** automatic adjustment may occur to avoid datepicker from being displayed outside the viewport, see [positions example][] (default to 'bottom left')
* `reposition` can be set to false to not reposition datepicker within the viewport, forcing it to take the configured `position` (default: true)
* `container` DOM node to render calendar into, see [container example][] (default: undefined)
* `format` the default output format for `.toString()` and `field` value (requires [Moment.js][moment] for custom formatting)
* `formatStrict` the default flag for moment's strict date parsing (requires [Moment.js][moment] for custom formatting)
* `toString(date, format)` function which will be used for custom formatting. This function will take precedence over `moment`.
* `parse(dateString, format)` function which will be used for parsing input string and getting a date object from it. This function will take precedence over `moment`.
* `defaultDate` the initial date to view when first opened
* `setDefaultDate` make the `defaultDate` the initial selected value
* `setDefaultDate` Boolean (true/false). make the `defaultDate` the initial selected value
* `firstDay` first day of the week (0: Sunday, 1: Monday, etc)
* `minDate` the minimum/earliest date that can be selected (this should be a native Date object - e.g. `new Date()` or `moment().toDate()`)
* `maxDate` the maximum/latest date that can be selected (this should be a native Date object - e.g. `new Date()` or `moment().toDate()`)
* `yearRange` number of years either side (e.g. `10`) or array of upper/lower range (e.g. `[1900,2012]`)
* `disableWeekends` disallow selection of Saturdays or Sundays
* `disableDayFn` callback function that gets passed a Date object for each day in view. Should return true to disable selection of that day.
* `yearRange` number of years either side (e.g. `10`) or array of upper/lower range (e.g. `[1900,2015]`)
* `showWeekNumber` show the ISO week number at the head of the row (default `false`)
* `pickWholeWeek` select a whole week instead of a day (default `false`)
* `isRTL` reverse the calendar for right-to-left languages
* `i18n` language defaults for month and weekday names (see internationalization below)
* `yearSuffix` additional text to append to the year in the title
* `showMonthAfterYear` render the month after year in the title (default `false`)
* `showDaysInNextAndPreviousMonths` render days of the calendar grid that fall in the next or previous months (default: false)
* `enableSelectionDaysInNextAndPreviousMonths` allows user to select date that is in the next or previous months (default: false)
* `numberOfMonths` number of visible calendars
* `mainCalendar` when `numberOfMonths` is used, this will help you to choose where the main calendar will be (default `left`, can be set to `right`). Only used for the first display or when a selected date is not already visible
* `events` array of dates that you would like to differentiate from regular days (e.g. `['Sat Jun 28 2017', 'Sun Jun 29 2017', 'Tue Jul 01 2017',]`)
* `theme` define a classname that can be used as a hook for styling different themes, see [theme example][] (default `null`)
* `blurFieldOnSelect` defines if the field is blurred when a date is selected (default `true`)
* `onSelect` callback function for when a date is selected
* `onOpen` callback function for when the picker becomes visible
* `onClose` callback function for when the picker is hidden
* `onDraw` callback function for when the picker draws a new month
* `keyboardInput` enable keyboard input support (default `true`)
### Styling
If the `reposition` configuration-option is enabled (default), Pikaday will apply CSS-classes to the datepicker according to how it is positioned:
* `top-aligned`
* `left-aligned`
* `right-aligned`
* `bottom-aligned`
Note that the DOM element at any time will typically have 2 CSS-classes (eg. `top-aligned right-aligned` etc).
## jQuery Plugin
The normal version of Pikaday does not require jQuery, however there is a jQuery plugin if that floats your boat (see `plugins/pikaday.jquery.js` in the repository). This version requires jQuery, naturally, and can be used like other plugins:
The normal version of Pikaday does not require jQuery, however there is a jQuery plugin if that floats your boat (see `plugins/pikaday.jquery.js` in the repository). This version requires jQuery, naturally, and can be used like other plugins:
See the [jQuery example][] for a full version.
```html
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.0/jquery.js" integrity="sha384-WGhEWG1n4j4SSTvTWxHLVbwDs5irzinCJT89aUzyS2H/wY2d2eZrUWSsNyCucTYy" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-migrate/3.0.1/jquery-migrate.min.js" integrity="sha384-w5FBDpYZssTSnIDL59XH9TYLpEJ2dDP4RPhSPtJd2iLxUY5L8AATkjOsbM4Ohmax" crossorigin="anonymous"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="pikaday.js"></script>
<script src="plugins/pikaday.jquery.js"></script>
<script>
@ -116,7 +212,7 @@ $('.datepicker').eq(0).pikaday('show').pikaday('gotoYear', 2042);
## AMD support
If you use a modular script loader than Pikaday is not bound to the global object and will fit nicely in your build process. You can require Pikaday just like any other module.
If you use a modular script loader, Pikaday is not bound to the global object and will fit nicely in your build process. You can require Pikaday just like any other module.
See the [AMD example][] for a full version.
```javascript
@ -124,7 +220,7 @@ require(['pikaday'], function(Pikaday) {
var picker = new Pikaday({ field: document.getElementById('datepicker') });
});
```
The same applies for the jQuery plugin mentioned above.
The same applies for the jQuery plugin mentioned above.
See the [jQuery AMD example][] for a full version.
```javascript
@ -142,7 +238,7 @@ If you use a CommonJS compatible environment you can use the require function to
var pikaday = require('pikaday');
```
When you bundle all your required modules with [Browserify][browserify] and you don't use [Moment.js][moment] specify the ignore opption:
When you bundle all your required modules with [Browserify][browserify] and you don't use [Moment.js][moment] specify the ignore option:
`browserify main.js -o bundle.js -i moment`
@ -162,29 +258,38 @@ var picker = new Pikaday({ field: document.getElementById('datepicker') });
`picker.toString('YYYY-MM-DD')`
Returns the selected date in a string format. If [Moment.js][moment] exists (recommended) then Pikaday can return any format that Moment understands, otherwise you're stuck with JavaScript's default.
Returns the selected date in a string format. If [Moment.js][moment] exists (recommended) then Pikaday can return any format that Moment understands.
You can also provide your own `toString` function and do the formatting yourself. Read more in the [formatting](#formatting) section.
If neither `moment` object exists nor `toString` function is provided, JavaScript's default [`.toDateString()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toDateString) method will be used.
`picker.getDate()`
Returns a basic JavaScript `Date` object of the selected day, or `null` if no selection.
`picker.setDate('2012-01-01'))`
`picker.setDate('2015-01-01')`
Set the current selection. This will be restricted within the bounds of `minDate` and `maxDate` options if they're specified.
Set the current selection. This will be restricted within the bounds of `minDate` and `maxDate` options if they're specified. You can optionally pass a boolean as the second parameter to prevent triggering of the onSelect callback (true), allowing the date to be set silently.
`picker.getMoment()`
Returns a [Moment.js][moment] object for the selected date (Moment must be loaded before Pikaday).
`picker.setMoment(moment('14th Feburary 2013', 'DDo MMMM YYYY'))`
`picker.setMoment(moment('14th February 2014', 'DDo MMMM YYYY'))`
Set the current selection with a [Moment.js][moment] object (passed on to `setDate`).
Set the current selection with a [Moment.js][moment] object (see `setDate` for details).
### Clear and reset date
`picker.clear()`
Will clear and reset the input where picker is bound to.
### Change current view
`picker.gotoDate(new Date(2012, 1))`
`picker.gotoDate(new Date(2014, 1))`
Change the current view to see a specific date. This example will jump to February 2012 ([month is a zero-based index][mdn_date]).
Change the current view to see a specific date. This example will jump to February 2014 ([month is a zero-based index][mdn_date]).
`picker.gotoToday()`
@ -211,6 +316,14 @@ Update the minimum/earliest date that can be selected.
Update the maximum/latest date that can be selected.
`picker.setStartRange()`
Update the range start date. For using two Pikaday instances to select a date range.
`picker.setEndRange()`
Update the range end date. For using two Pikaday instances to select a date range.
### Show and hide datepicker
`picker.isVisible()`
@ -254,11 +367,12 @@ You must provide 12 months and 7 weekdays (with abbreviations). Always specify w
### Timepicker
Pikaday is a pure datepicker. It will not support picking a time of day. However, there have been efforts to add time support to Pikaday.
Pikaday is a pure datepicker. It will not support picking a time of day. However, there have been efforts to add time support to Pikaday.
See [#1][issue1] and [#18][issue18]. These reside in their own fork.
You can use the work [@stas][stas] did at [stas/Pikaday][stas Pika]
or the work [@owenmead][owenmead] did more recently at [owenmead/Pikaday][owen Pika] which is based on version 1.1.0.
You can use the work [@owenmead][owenmead] did most recently at [owenmead/Pikaday][owen Pika]
A more simple time selection approach done by [@xeeali][xeeali] at [xeeali/Pikaday][xeeali Pika] is based on version 1.2.0.
Also [@stas][stas] has a fork [stas/Pikaday][stas Pika], but is now quite old
## Browser Compatibility
@ -269,38 +383,55 @@ or the work [@owenmead][owenmead] did more recently at [owenmead/Pikaday][owen P
* Safari 3+
* Opera 10.6+
[![browser compatibility](https://ci.testling.com/rikkert/pikaday.png)
](https://ci.testling.com/rikkert/pikaday)
* * *
## Authors
* David Bushell [http://dbushell.com][Bushell] [@dbushell][Bushell Twitter]
* David Bushell [https://dbushell.com][Bushell] [@dbushell][Bushell Twitter]
* Ramiro Rikkert [GitHub][Rikkert] [@RamRik][Rikkert Twitter]
Thanks to [@shoogledesigns][shoogledesigns] for the name.
Copyright © 2013 David Bushell | BSD & MIT license
Copyright © 2014 David Bushell | BSD & MIT license
[Pikaday]: http://dbushell.github.com/Pikaday/ "Pikaday"
[Pikaday]: https://pikaday.com/ "Pikaday"
[moment]: http://momentjs.com/ "moment.js"
[browserify]: http://browserify.org/ "browserify"
[screenshot]: https://raw.github.com/dbushell/Pikaday/gh-pages/screenshot.png "Screenshot"
[issues]: https://github.com/dbushell/Pikaday/issues "Issue tracker"
[screenshot]: https://raw.github.com/Pikaday/Pikaday/master/examples/screenshot.png "Screenshot"
[issues]: https://github.com/Pikaday/Pikaday/issues "Issue tracker"
[gem]: https://rubygems.org/gems/pikaday-gem "RoR gem"
[mdn_date]: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date "Date"
[Bushell]: http://dbushell.com/ "dbushell.com"
[Bushell]: https://dbushell.com/ "dbushell.com"
[Bushell Twitter]: https://twitter.com/dbushell "@dbushell"
[Rikkert]: https://github.com/rikkert "Rikkert GitHub"
[Rikkert Twitter]: https://twitter.com/ramrik "@ramrik"
[shoogledesigns]: https://twitter.com/shoogledesigns/status/255209384261586944 "@shoogledesigns"
[issue1]: https://github.com/dbushell/Pikaday/issues/1 "Issue 1"
[issue18]: https://github.com/dbushell/Pikaday/issues/18 "Issue 18"
[issue1]: https://github.com/Pikaday/Pikaday/issues/1 "Issue 1"
[issue18]: https://github.com/Pikaday/Pikaday/issues/18 "Issue 18"
[stas]: https://github.com/stas "@stas"
[stas Pika]: https://github.com/stas/Pikaday "Pikaday"
[owenmead]: https://github.com/owenmead "@owenmead"
[owenmead]: https://github.com/owenmead "@owenmead"
[owen Pika]: https://github.com/owenmead/Pikaday "Pikaday"
[moment.js example]: http://dbushell.github.com/Pikaday/examples/moment.html "Pikaday w/ moment.js"
[jQuery example]: http://dbushell.github.com/Pikaday/examples/jquery.html "Pikaday w/ jQuery"
[AMD example]: http://dbushell.github.com/Pikaday/examples/amd.html "Pikaday w/ AMD"
[jQuery AMD example]: http://dbushell.github.com/Pikaday/examples/jquery-amd.html "Pikaday w/ jQuery + AMD"
[trigger example]: http://dbushell.github.com/Pikaday/examples/trigger.html "Pikaday using custom trigger"
[xeeali]: https://github.com/xeeali "@xeeali"
[xeeali Pika]: https://github.com/xeeali/Pikaday "Pikaday"
[moment.js example]: https://pikaday.com/examples/moment.html "Pikaday w/ moment.js"
[jQuery example]: https://pikaday.com/examples/jquery.html "Pikaday w/ jQuery"
[AMD example]: https://pikaday.com/examples/amd.html "Pikaday w/ AMD"
[jQuery AMD example]: https://pikaday.com/examples/jquery-amd.html "Pikaday w/ jQuery + AMD"
[trigger example]: https://pikaday.com/examples/trigger.html "Pikaday using custom trigger"
[positions example]: https://pikaday.com/examples/positions.html "Pikaday using different position options"
[container example]: https://pikaday.com/examples/container.html "Pikaday using custom calendar container"
[theme example]: https://pikaday.com/examples/theme.html "Pikaday using multiple themes"
[npm-image]: https://img.shields.io/npm/v/pikaday.svg?style=flat-square
[npm-url]: https://npmjs.org/package/pikaday
[license-image]: https://img.shields.io/:license-mit-blue.svg?style=flat-square
[license-url]: LICENSE.md
[downloads-image]: http://img.shields.io/npm/dm/pikaday.svg?style=flat-square
[downloads-url]: https://npmjs.org/package/pikaday

View File

@ -2,7 +2,7 @@
/*!
* Pikaday
* Copyright © 2014 David Bushell | BSD & MIT license | http://dbushell.com/
* Copyright © 2014 David Bushell | BSD & MIT license | https://dbushell.com/
*/
.pika-single {
@ -26,7 +26,6 @@ http://nicolasgallagher.com/micro-clearfix-hack/
display: table;
}
.pika-single:after { clear: both }
.pika-single { *zoom: 1 }
.pika-single.is-hidden {
display: none;
@ -50,7 +49,6 @@ http://nicolasgallagher.com/micro-clearfix-hack/
.pika-label {
display: inline-block;
*display: inline;
position: relative;
z-index: 9999;
overflow: hidden;
@ -68,7 +66,6 @@ http://nicolasgallagher.com/micro-clearfix-hack/
margin: 0;
left: 0;
top: 5px;
filter: alpha(opacity=0);
opacity: 0;
}
@ -91,8 +88,6 @@ http://nicolasgallagher.com/micro-clearfix-hack/
background-repeat: no-repeat;
background-size: 75% 75%;
opacity: .5;
*position: absolute;
*top: 0;
}
.pika-prev:hover,
@ -104,14 +99,12 @@ http://nicolasgallagher.com/micro-clearfix-hack/
.is-rtl .pika-next {
float: left;
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAYAAAAsEj5rAAAAUklEQVR42u3VMQoAIBADQf8Pgj+OD9hG2CtONJB2ymQkKe0HbwAP0xucDiQWARITIDEBEnMgMQ8S8+AqBIl6kKgHiXqQqAeJepBo/z38J/U0uAHlaBkBl9I4GwAAAABJRU5ErkJggg==');
*left: 0;
}
.pika-next,
.is-rtl .pika-prev {
float: right;
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAYAAAAsEj5rAAAAU0lEQVR42u3VOwoAMAgE0dwfAnNjU26bYkBCFGwfiL9VVWoO+BJ4Gf3gtsEKKoFBNTCoCAYVwaAiGNQGMUHMkjGbgjk2mIONuXo0nC8XnCf1JXgArVIZAQh5TKYAAAAASUVORK5CYII=');
*right: 0;
}
.pika-prev.is-disabled,
@ -122,7 +115,6 @@ http://nicolasgallagher.com/micro-clearfix-hack/
.pika-select {
display: inline-block;
*display: inline;
}
.pika-table {
@ -161,6 +153,7 @@ http://nicolasgallagher.com/micro-clearfix-hack/
line-height: 15px;
text-align: right;
background: #f5f5f5;
height: initial;
}
.pika-week {
@ -173,7 +166,8 @@ http://nicolasgallagher.com/micro-clearfix-hack/
font-weight: bold;
}
.is-selected .pika-button {
.is-selected .pika-button,
.has-event .pika-button {
color: #fff;
font-weight: bold;
background: #33aaff;
@ -181,6 +175,12 @@ http://nicolasgallagher.com/micro-clearfix-hack/
border-radius: 3px;
}
.has-event .pika-button {
background: #005da9;
box-shadow: inset 0 1px 3px #0076c9;
}
.is-disabled .pika-button,
.is-inrange .pika-button {
background: #D5E9F7;
}
@ -206,7 +206,18 @@ http://nicolasgallagher.com/micro-clearfix-hack/
opacity: .3;
}
.pika-button:hover {
.is-outside-current-month .pika-button {
color: #999;
opacity: .3;
}
.is-selection-disabled {
pointer-events: none;
cursor: default;
}
.pika-button:hover,
.pika-row.pick-whole-week:hover .pika-button {
color: #fff;
background: #ff8000;
box-shadow: none;
@ -218,4 +229,3 @@ http://nicolasgallagher.com/micro-clearfix-hack/
border-bottom: none;
cursor: help;
}

View File

@ -1,7 +1,7 @@
/*!
* Pikaday jQuery plugin.
*
* Copyright © 2013 David Bushell | BSD & MIT license | https://github.com/dbushell/Pikaday
* Copyright © 2013 David Bushell | BSD & MIT license | https://github.com/Pikaday/Pikaday
*/
(function (root, factory)
@ -10,7 +10,7 @@
if (typeof exports === 'object') {
// CommonJS module
factory(require('jquery'), require('../pikaday'));
factory(require('jquery'), require('pikaday'));
} else if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['jquery', 'pikaday'], factory);

View File

@ -1,7 +1,7 @@
/*!
* Pikaday
*
* Copyright © 2014 David Bushell | BSD & MIT license | https://github.com/dbushell/Pikaday
* Copyright © 2014 David Bushell | BSD & MIT license | https://github.com/Pikaday/Pikaday
*/
(function (root, factory)
@ -59,22 +59,6 @@
}
},
fireEvent = function(el, eventName, data)
{
var ev;
if (document.createEvent) {
ev = document.createEvent('HTMLEvents');
ev.initEvent(eventName, true, false);
ev = extend(ev, data);
el.dispatchEvent(ev);
} else if (document.createEventObject) {
ev = document.createEventObject();
ev = extend(ev, data);
el.fireEvent('on' + eventName, ev);
}
},
trim = function(str)
{
return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g,'');
@ -115,8 +99,8 @@
isLeapYear = function(year)
{
// solution by Matti Virkkunen: http://stackoverflow.com/a/4881951
return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
// solution lifted from date.js (MIT license): https://github.com/datejs/Datejs
return ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0);
},
getDaysInMonth = function(year, month)
@ -160,6 +144,22 @@
return to;
},
fireEvent = function(el, eventName, data)
{
var ev;
if (document.createEvent) {
ev = document.createEvent('HTMLEvents');
ev.initEvent(eventName, true, false);
ev = extend(ev, data);
el.dispatchEvent(ev);
} else if (document.createEventObject) {
ev = document.createEventObject();
ev = extend(ev, data);
el.fireEvent('on' + eventName, ev);
}
},
adjustCalendar = function(calendar) {
if (calendar.month < 0) {
calendar.year -= Math.ceil(Math.abs(calendar.month)/12);
@ -183,6 +183,9 @@
// automatically show/hide the picker on `field` focus (default `true` if `field` is set)
bound: undefined,
// data-attribute on the input field with an aria assistance text (only applied when `bound` is set)
ariaLabel: 'Use the arrow keys to pick a date',
// position of the datepicker, relative to the field (default to bottom & left)
// ('bottom' & 'left' keywords are not used, 'top' & 'right' are modifier on the bottom/left position)
position: 'bottom left',
@ -193,6 +196,13 @@
// the default output format for `.toString()` and `field` value
format: 'YYYY-MM-DD',
// the toString function which gets passed a current date object and format
// and returns a string
toString: null,
// used to create date object from current input string
parse: null,
// the initial date to view when first opened
defaultDate: null,
@ -202,6 +212,13 @@
// first day of week (0: Sunday, 1: Monday etc)
firstDay: 0,
// minimum number of days in the week that gets week number one
// default ISO 8601, week 01 is the week with the first Thursday (4)
firstWeekOfYearMinDays: 4,
// the default flag for moment's strict date parsing
formatStrict: false,
// the minimum/earliest date that can be selected
minDate: null,
// the maximum/latest date that can be selected
@ -213,6 +230,9 @@
// show week numbers at head of row
showWeekNumber: false,
// Week picker mode
pickWholeWeek: false,
// used internally (don't config outside)
minYear: 0,
maxYear: 9999,
@ -230,6 +250,12 @@
// Render the month after year in the calendar title
showMonthAfterYear: false,
// Render days of the calendar grid that fall in the next or previous month
showDaysInNextAndPreviousMonths: false,
// Allows user to select days that fall in the next or previous month
enableSelectionDaysInNextAndPreviousMonths: false,
// how many months are visible
numberOfMonths: 1,
@ -240,6 +266,9 @@
// Specify a DOM element to render the calendar in
container: undefined,
// Blur field when date is selected
blurFieldOnSelect : true,
// internationalization
i18n: {
previousMonth : 'Previous Month',
@ -252,11 +281,17 @@
// Theme Classname
theme: null,
// events array
events: [],
// callback function
onSelect: null,
onOpen: null,
onClose: null,
onDraw: null
onDraw: null,
// Enable keyboard input
keyboardInput: true
},
@ -274,10 +309,20 @@
renderDay = function(opts)
{
if (opts.isEmpty) {
return '<td class="is-empty"></td>';
}
var arr = [];
var ariaSelected = 'false';
if (opts.isEmpty) {
if (opts.showDaysInNextAndPreviousMonths) {
arr.push('is-outside-current-month');
if(!opts.enableSelectionDaysInNextAndPreviousMonths) {
arr.push('is-selection-disabled');
}
} else {
return '<td class="is-empty"></td>';
}
}
if (opts.isDisabled) {
arr.push('is-disabled');
}
@ -286,6 +331,10 @@
}
if (opts.isSelected) {
arr.push('is-selected');
ariaSelected = 'true';
}
if (opts.hasEvent) {
arr.push('has-event');
}
if (opts.isInRange) {
arr.push('is-inrange');
@ -296,7 +345,7 @@
if (opts.isEndRange) {
arr.push('is-endrange');
}
return '<td data-day="' + opts.day + '" class="' + arr.join(' ') + '">' +
return '<td data-day="' + opts.day + '" class="' + arr.join(' ') + '" aria-selected="' + ariaSelected + '">' +
'<button class="pika-button pika-day" type="button" ' +
'data-pika-year="' + opts.year + '" data-pika-month="' + opts.month + '" data-pika-day="' + opts.day + '">' +
opts.day +
@ -304,16 +353,40 @@
'</td>';
},
renderWeek = function (d, m, y) {
// Lifted from http://javascript.about.com/library/blweekyear.htm, lightly modified.
var onejan = new Date(y, 0, 1),
weekNum = Math.ceil((((new Date(y, m, d) - onejan) / 86400000) + onejan.getDay()+1)/7);
return '<td class="pika-week">' + weekNum + '</td>';
isoWeek = function(date, firstWeekOfYearMinDays) {
// Ensure we're at the start of the day.
date.setHours(0, 0, 0, 0);
// Thursday in current week decides the year because January 4th
// is always in the first week according to ISO8601.
var yearDay = date.getDate(),
weekDay = date.getDay(),
dayInFirstWeek = firstWeekOfYearMinDays,
dayShift = dayInFirstWeek - 1, // counting starts at 0
daysPerWeek = 7,
prevWeekDay = function(day) { return (day + daysPerWeek - 1) % daysPerWeek; };
// Adjust to Thursday in week 1 and count number of weeks from date to week 1.
date.setDate(yearDay + dayShift - prevWeekDay(weekDay));
var jan4th = new Date(date.getFullYear(), 0, dayInFirstWeek),
msPerDay = 24 * 60 * 60 * 1000,
daysBetween = (date.getTime() - jan4th.getTime()) / msPerDay,
weekNum = 1 + Math.round((daysBetween - dayShift + prevWeekDay(jan4th.getDay())) / daysPerWeek);
return weekNum;
},
renderRow = function(days, isRTL)
renderWeek = function (d, m, y, firstWeekOfYearMinDays) {
var date = new Date(y, m, d),
week = hasMoment ? moment(date).isoWeek() : isoWeek(date, firstWeekOfYearMinDays);
return '<td class="pika-week">' + week + '</td>';
},
renderRow = function(days, isRTL, pickWholeWeek, isRowSelected)
{
return '<tr>' + (isRTL ? days.reverse() : days).join('') + '</tr>';
return '<tr class="pika-row' + (pickWholeWeek ? ' pick-whole-week' : '') + (isRowSelected ? ' is-selected' : '') + '">' + (isRTL ? days.reverse() : days).join('') + '</tr>';
},
renderBody = function(rows)
@ -330,16 +403,16 @@
for (i = 0; i < 7; i++) {
arr.push('<th scope="col"><abbr title="' + renderDayName(opts, i) + '">' + renderDayName(opts, i, true) + '</abbr></th>');
}
return '<thead>' + (opts.isRTL ? arr.reverse() : arr).join('') + '</thead>';
return '<thead><tr>' + (opts.isRTL ? arr.reverse() : arr).join('') + '</tr></thead>';
},
renderTitle = function(instance, c, year, month, refYear)
renderTitle = function(instance, c, year, month, refYear, randId)
{
var i, j, arr,
opts = instance._o,
isMinYear = year === opts.minYear,
isMaxYear = year === opts.maxYear,
html = '<div class="pika-title">',
html = '<div id="' + randId + '" class="pika-title" role="heading" aria-live="assertive">',
monthHtml,
yearHtml,
prev = true,
@ -347,10 +420,11 @@
for (arr = [], i = 0; i < 12; i++) {
arr.push('<option value="' + (year === refYear ? i - c : 12 + i - c) + '"' +
(i === month ? ' selected': '') +
((isMinYear && i < opts.minMonth) || (isMaxYear && i > opts.maxMonth) ? 'disabled' : '') + '>' +
(i === month ? ' selected="selected"': '') +
((isMinYear && i < opts.minMonth) || (isMaxYear && i > opts.maxMonth) ? ' disabled="disabled"' : '') + '>' +
opts.i18n.months[i] + '</option>');
}
monthHtml = '<div class="pika-label">' + opts.i18n.months[month] + '<select class="pika-select pika-select-month" tabindex="-1">' + arr.join('') + '</select></div>';
if (isArray(opts.yearRange)) {
@ -363,7 +437,7 @@
for (arr = []; i < j && i <= opts.maxYear; i++) {
if (i >= opts.minYear) {
arr.push('<option value="' + i + '"' + (i === year ? ' selected': '') + '>' + (i) + '</option>');
arr.push('<option value="' + i + '"' + (i === year ? ' selected="selected"': '') + '>' + (i) + '</option>');
}
}
yearHtml = '<div class="pika-label">' + year + opts.yearSuffix + '<select class="pika-select pika-select-year" tabindex="-1">' + arr.join('') + '</select></div>';
@ -392,9 +466,9 @@
return html += '</div>';
},
renderTable = function(opts, data)
renderTable = function(opts, data, randId)
{
return '<table cellpadding="0" cellspacing="0" class="pika-table">' + renderHead(opts) + renderBody(data) + '</table>';
return '<table cellpadding="0" cellspacing="0" class="pika-table" role="grid" aria-labelledby="' + randId + '">' + renderHead(opts) + renderBody(data) + '</table>';
},
@ -418,12 +492,12 @@
}
if (!hasClass(target, 'is-disabled')) {
if (hasClass(target, 'pika-button') && !hasClass(target, 'is-empty')) {
if (hasClass(target, 'pika-button') && !hasClass(target, 'is-empty') && !hasClass(target.parentNode, 'is-disabled')) {
self.setDate(new Date(target.getAttribute('data-pika-year'), target.getAttribute('data-pika-month'), target.getAttribute('data-pika-day')));
if (opts.bound) {
sto(function() {
self.hide();
if (opts.field) {
if (opts.blurFieldOnSelect && opts.field) {
opts.field.blur();
}
}, 100);
@ -464,6 +538,51 @@
}
};
self._onKeyChange = function(e)
{
e = e || window.event;
if (self.isVisible()) {
switch(e.keyCode){
case 13:
case 27:
if (opts.field) {
opts.field.blur();
}
break;
case 37:
self.adjustDate('subtract', 1);
break;
case 38:
self.adjustDate('subtract', 7);
break;
case 39:
self.adjustDate('add', 1);
break;
case 40:
self.adjustDate('add', 7);
break;
case 8:
case 46:
self.setDate(null);
break;
}
}
};
self._parseFieldValue = function()
{
if (opts.parse) {
return opts.parse(opts.field.value, opts.format);
} else if (hasMoment) {
var date = moment(opts.field.value, opts.format, opts.formatStrict);
return (date && date.isValid()) ? date.toDate() : null;
} else {
return new Date(Date.parse(opts.field.value));
}
};
self._onInputChange = function(e)
{
var date;
@ -471,13 +590,7 @@
if (e.firedBy === self) {
return;
}
if (hasMoment) {
date = moment(opts.field.value, opts.format);
date = (date && date.isValid()) ? date.toDate() : null;
}
else {
date = new Date(Date.parse(opts.field.value));
}
date = self._parseFieldValue();
if (isDate(date)) {
self.setDate(date);
}
@ -547,6 +660,10 @@
addEvent(self.el, 'touchend', self._onMouseDown, true);
addEvent(self.el, 'change', self._onChange);
if (opts.keyboardInput) {
addEvent(document, 'keydown', self._onKeyChange);
}
if (opts.field) {
if (opts.container) {
opts.container.appendChild(self.el);
@ -558,11 +675,7 @@
addEvent(opts.field, 'change', self._onInputChange);
if (!opts.defaultDate) {
if (hasMoment && opts.field.value) {
opts.defaultDate = moment(opts.field.value, opts.format).toDate();
} else {
opts.defaultDate = new Date(Date.parse(opts.field.value));
}
opts.defaultDate = self._parseFieldValue();
opts.setDefaultDate = true;
}
}
@ -660,7 +773,17 @@
*/
toString: function(format)
{
return !isDate(this._d) ? '' : hasMoment ? moment(this._d).format(format || this._o.format) : this._d.toDateString();
format = format || this._o.format;
if (!isDate(this._d)) {
return '';
}
if (this._o.toString) {
return this._o.toString(this._d, format);
}
if (hasMoment) {
return moment(this._d).format(format);
}
return this._d.toDateString();
},
/**
@ -733,6 +856,14 @@
}
},
/**
* clear and reset the date
*/
clear: function()
{
this.setDate(null);
},
/**
* change view to a specific date
*/
@ -767,6 +898,22 @@
this.adjustCalendars();
},
adjustDate: function(sign, days) {
var day = this.getDate() || new Date();
var difference = parseInt(days)*24*60*60*1000;
var newDay;
if (sign === 'add') {
newDay = new Date(day.valueOf() + difference);
} else if (sign === 'subtract') {
newDay = new Date(day.valueOf() - difference);
}
this.setDate(newDay);
},
adjustCalendars: function() {
this.calendars[0] = adjustCalendar(this.calendars[0]);
for (var c = 1; c < this._o.numberOfMonths; c++) {
@ -822,10 +969,18 @@
*/
setMinDate: function(value)
{
setToStartOfDay(value);
this._o.minDate = value;
this._o.minYear = value.getFullYear();
this._o.minMonth = value.getMonth();
if(value instanceof Date) {
setToStartOfDay(value);
this._o.minDate = value;
this._o.minYear = value.getFullYear();
this._o.minMonth = value.getMonth();
} else {
this._o.minDate = defaults.minDate;
this._o.minYear = defaults.minYear;
this._o.minMonth = defaults.minMonth;
this._o.startRange = defaults.startRange;
}
this.draw();
},
@ -834,10 +989,18 @@
*/
setMaxDate: function(value)
{
setToStartOfDay(value);
this._o.maxDate = value;
this._o.maxYear = value.getFullYear();
this._o.maxMonth = value.getMonth();
if(value instanceof Date) {
setToStartOfDay(value);
this._o.maxDate = value;
this._o.maxYear = value.getFullYear();
this._o.maxMonth = value.getMonth();
} else {
this._o.maxDate = defaults.maxDate;
this._o.maxYear = defaults.maxYear;
this._o.maxMonth = defaults.maxMonth;
this._o.endRange = defaults.endRange;
}
this.draw();
},
@ -864,7 +1027,8 @@
maxYear = opts.maxYear,
minMonth = opts.minMonth,
maxMonth = opts.maxMonth,
html = '';
html = '',
randId;
if (this._y <= minYear) {
this._y = minYear;
@ -880,7 +1044,8 @@
}
for (var c = 0; c < opts.numberOfMonths; c++) {
html += '<div class="pika-lendar">' + renderTitle(this, c, this.calendars[c].year, this.calendars[c].month, this.calendars[0].year) + this.render(this.calendars[c].year, this.calendars[c].month) + '</div>';
randId = 'pika-title-' + Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 2);
html += '<div class="pika-lendar">' + renderTitle(this, c, this.calendars[c].year, this.calendars[c].month, this.calendars[0].year, randId) + this.render(this.calendars[c].year, this.calendars[c].month, randId) + '</div>';
}
this.el.innerHTML = html;
@ -894,16 +1059,18 @@
}
if (typeof this._o.onDraw === 'function') {
var self = this;
sto(function() {
self._o.onDraw.call(self);
}, 0);
this._o.onDraw(this);
}
if (opts.bound) {
// let the screen reader user know to use arrow keys
opts.field.setAttribute('aria-label', opts.ariaLabel);
}
},
adjustPosition: function()
{
var field, pEl, width, height, viewportWidth, viewportHeight, scrollTop, left, top, clientRect;
var field, pEl, width, height, viewportWidth, viewportHeight, scrollTop, left, top, clientRect, leftAligned, bottomAligned;
if (this._o.container) return;
@ -916,6 +1083,8 @@
viewportWidth = window.innerWidth || document.documentElement.clientWidth;
viewportHeight = window.innerHeight || document.documentElement.clientHeight;
scrollTop = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop;
leftAligned = true;
bottomAligned = true;
if (typeof field.getBoundingClientRect === 'function') {
clientRect = field.getBoundingClientRect();
@ -938,6 +1107,7 @@
)
) {
left = left - width + field.offsetWidth;
leftAligned = false;
}
if ((this._o.reposition && top + height > viewportHeight + scrollTop) ||
(
@ -946,16 +1116,22 @@
)
) {
top = top - height - field.offsetHeight;
bottomAligned = false;
}
this.el.style.left = left + 'px';
this.el.style.top = top + 'px';
addClass(this.el, leftAligned ? 'left-aligned' : 'right-aligned');
addClass(this.el, bottomAligned ? 'bottom-aligned' : 'top-aligned');
removeClass(this.el, !leftAligned ? 'left-aligned' : 'right-aligned');
removeClass(this.el, !bottomAligned ? 'bottom-aligned' : 'top-aligned');
},
/**
* render HTML for a particular month
*/
render: function(year, month)
render: function(year, month, randId)
{
var opts = this._o,
now = new Date(),
@ -970,50 +1146,81 @@
before += 7;
}
}
var previousMonth = month === 0 ? 11 : month - 1,
nextMonth = month === 11 ? 0 : month + 1,
yearOfPreviousMonth = month === 0 ? year - 1 : year,
yearOfNextMonth = month === 11 ? year + 1 : year,
daysInPreviousMonth = getDaysInMonth(yearOfPreviousMonth, previousMonth);
var cells = days + before,
after = cells;
while(after > 7) {
after -= 7;
}
cells += 7 - after;
var isWeekSelected = false;
for (var i = 0, r = 0; i < cells; i++)
{
var day = new Date(year, month, 1 + (i - before)),
isSelected = isDate(this._d) ? compareDates(day, this._d) : false,
isToday = compareDates(day, now),
hasEvent = opts.events.indexOf(day.toDateString()) !== -1 ? true : false,
isEmpty = i < before || i >= (days + before),
dayNumber = 1 + (i - before),
monthNumber = month,
yearNumber = year,
isStartRange = opts.startRange && compareDates(opts.startRange, day),
isEndRange = opts.endRange && compareDates(opts.endRange, day),
isInRange = opts.startRange && opts.endRange && opts.startRange < day && day < opts.endRange,
isDisabled = (opts.minDate && day < opts.minDate) ||
(opts.maxDate && day > opts.maxDate) ||
(opts.disableWeekends && isWeekend(day)) ||
(opts.disableDayFn && opts.disableDayFn(day)),
dayConfig = {
day: 1 + (i - before),
month: month,
year: year,
(opts.disableDayFn && opts.disableDayFn(day));
if (isEmpty) {
if (i < before) {
dayNumber = daysInPreviousMonth + dayNumber;
monthNumber = previousMonth;
yearNumber = yearOfPreviousMonth;
} else {
dayNumber = dayNumber - days;
monthNumber = nextMonth;
yearNumber = yearOfNextMonth;
}
}
var dayConfig = {
day: dayNumber,
month: monthNumber,
year: yearNumber,
hasEvent: hasEvent,
isSelected: isSelected,
isToday: isToday,
isDisabled: isDisabled,
isEmpty: isEmpty,
isStartRange: isStartRange,
isEndRange: isEndRange,
isInRange: isInRange
isInRange: isInRange,
showDaysInNextAndPreviousMonths: opts.showDaysInNextAndPreviousMonths,
enableSelectionDaysInNextAndPreviousMonths: opts.enableSelectionDaysInNextAndPreviousMonths
};
if (opts.pickWholeWeek && isSelected) {
isWeekSelected = true;
}
row.push(renderDay(dayConfig));
if (++r === 7) {
if (opts.showWeekNumber) {
row.unshift(renderWeek(i - before, month, year));
row.unshift(renderWeek(i - before, month, year, opts.firstWeekOfYearMinDays));
}
data.push(renderRow(row, opts.isRTL));
data.push(renderRow(row, opts.isRTL, opts.pickWholeWeek, isWeekSelected));
row = [];
r = 0;
isWeekSelected = false;
}
}
return renderTable(opts, data);
return renderTable(opts, data, randId);
},
isVisible: function()
@ -1023,10 +1230,10 @@
show: function()
{
if (!this._v) {
removeClass(this.el, 'is-hidden');
if (!this.isVisible()) {
this._v = true;
this.draw();
removeClass(this.el, 'is-hidden');
if (this._o.bound) {
addEvent(document, 'click', this._onClick);
this.adjustPosition();
@ -1044,9 +1251,12 @@
if (this._o.bound) {
removeEvent(document, 'click', this._onClick);
}
this.el.style.position = 'static'; // reset
this.el.style.left = 'auto';
this.el.style.top = 'auto';
if (!this._o.container) {
this.el.style.position = 'static'; // reset
this.el.style.left = 'auto';
this.el.style.top = 'auto';
}
addClass(this.el, 'is-hidden');
this._v = false;
if (v !== undefined && typeof this._o.onClose === 'function') {
@ -1060,16 +1270,21 @@
*/
destroy: function()
{
var opts = this._o;
this.hide();
removeEvent(this.el, 'mousedown', this._onMouseDown, true);
removeEvent(this.el, 'touchend', this._onMouseDown, true);
removeEvent(this.el, 'change', this._onChange);
if (this._o.field) {
removeEvent(this._o.field, 'change', this._onInputChange);
if (this._o.bound) {
removeEvent(this._o.trigger, 'click', this._onInputClick);
removeEvent(this._o.trigger, 'focus', this._onInputFocus);
removeEvent(this._o.trigger, 'blur', this._onInputBlur);
if (opts.keyboardInput) {
removeEvent(document, 'keydown', this._onKeyChange);
}
if (opts.field) {
removeEvent(opts.field, 'change', this._onInputChange);
if (opts.bound) {
removeEvent(opts.trigger, 'click', this._onInputClick);
removeEvent(opts.trigger, 'focus', this._onInputFocus);
removeEvent(opts.trigger, 'blur', this._onInputBlur);
}
}
if (this.el.parentNode) {
@ -1080,5 +1295,4 @@
};
return Pikaday;
}));

View File

@ -464,7 +464,7 @@ class CombineAssets
*/
protected function setHashOnCombinerFilters($hash)
{
$allFilters = call_user_func_array('array_merge', $this->getFilters());
$allFilters = array_merge(...array_values($this->getFilters()));
foreach ($allFilters as $filter) {
if (method_exists($filter, 'setHash')) {

View File

@ -29,9 +29,9 @@ use October\Rain\Database\Attach\Resizer as DefaultResizer;
*
* The functionality of this class is controlled by these config items:
*
* - cms.resized.disk - The disk to store resized images on
* - cms.resized.folder - The folder on the disk to store resized images in
* - cms.resized.path - The public path to the resized images as returned
* - cms.storage.resized.disk - The disk to store resized images on
* - cms.storage.resized.folder - The folder on the disk to store resized images in
* - cms.storage.resized.path - The public path to the resized images as returned
* by the storage disk's URL method, used to identify
* already resized images
*
@ -427,7 +427,7 @@ class ImageResizer
$disk = $fileModel->getDisk();
$path = $fileModel->getDiskPath($fileModel->getThumbFilename($this->width, $this->height, $this->options));
} else {
$disk = Storage::disk(Config::get('cms.resized.disk', 'local'));
$disk = Storage::disk(Config::get('cms.storage.resized.disk', 'local'));
$path = $this->getPathToResizedImage();
}
@ -464,7 +464,7 @@ class ImageResizer
$folder = implode('/', array_slice(str_split(str_limit($fileIdentifier, 9), 3), 0, 3));
// Generate and return the full path
return Config::get('cms.resized.folder', 'resized') . '/' . $folder . '/' . $name;
return Config::get('cms.storage.resized.folder', 'resized') . '/' . $folder . '/' . $name;
}
/**
@ -499,7 +499,13 @@ class ImageResizer
// Store the current configuration
$this->storeConfig();
return Url::to("/resizer/$identifier/$resizedUrl");
$url = "/resizer/$identifier/$resizedUrl";
if (Config::get('cms.linkPolicy', 'detect') === 'force') {
$url = Url::to($url);
}
return $url;
}
/**
@ -516,14 +522,20 @@ class ImageResizer
$thumbFile = $model->getThumbFilename($this->width, $this->height, $this->options);
$url = $model->getPath($thumbFile);
} else {
$resizedDisk = Storage::disk(Config::get('cms.resized.disk', 'local'));
$resizedDisk = Storage::disk(Config::get('cms.storage.resized.disk', 'local'));
$url = $resizedDisk->url($this->getPathToResizedImage());
}
// Ensure that a properly encoded URL is returned
$segments = explode('/', $url);
$lastSegment = array_pop($segments);
return implode('/', $segments) . '/' . rawurlencode(rawurldecode($lastSegment));
$url = implode('/', $segments) . '/' . rawurlencode(rawurldecode($lastSegment));
if (Config::get('cms.linkPolicy', 'detect') === 'force') {
$url = Url::to($url);
}
return $url;
}
/**
@ -758,8 +770,8 @@ class ImageResizer
* ['disk' => Illuminate\Filesystem\FilesystemAdapter, 'path' => string, 'source' => string, 'fileModel' => FileModel|void],
* instance of October\Rain\Database\Attach\File,
* string containing URL or path accessible to the application's filesystem manager
* @param integer|bool|null $width Desired width of the resized image
* @param integer|bool|null $height Desired height of the resized image
* @param integer|string|bool|null $width Desired width of the resized image
* @param integer|string|bool|null $height Desired height of the resized image
* @param array|null $options Array of options to pass to the resizer
* @throws Exception If the provided image was unable to be processed
* @return string

View File

@ -291,6 +291,10 @@ class MediaLibrary
if (Str::startsWith($folder, $exclude)) {
continue;
}
if (!$this->isVisible($folder)) {
$exclude[] = $folder . '/';
continue;
}
$result[] = $folder;
}

View File

@ -330,7 +330,7 @@ class UpdateManager
/*
* Rollback plugins
*/
$plugins = $this->pluginManager->getPlugins();
$plugins = array_reverse($this->pluginManager->getPlugins());
foreach ($plugins as $name => $plugin) {
$this->rollbackPlugin($name);
}
@ -1025,6 +1025,10 @@ class UpdateManager
*/
protected function addMessage($class, $message)
{
if (empty($message)) {
return;
}
if (is_object($class)) {
$class = get_class($class);
}
@ -1034,7 +1038,7 @@ class UpdateManager
if (is_string($message)) {
$this->messages[$class][] = $message;
} else if (is_array($message)) {
} elseif (is_array($message)) {
array_merge($this->messages[$class], $message);
}
}

View File

@ -112,7 +112,23 @@ class OctoberInstall extends Command
protected function setupCommonValues()
{
$url = $this->ask('Application URL', Config::get('app.url'));
$this->writeToConfig('app', ['url' => $url]);
try {
$availableLocales = (new \Backend\Models\Preference)->getLocaleOptions();
$localesByName = [];
foreach ($availableLocales as $locale => $name) {
$localesByName[$name[0]] = $locale;
}
$localeName = $this->choice('Default Backend Locale', array_keys($localesByName));
$locale = $localesByName[$localeName];
} catch (\Exception $e) {
// Installation failed halfway through, recover gracefully
$locale = $this->ask('Default Backend Locale', 'en');
}
$this->writeToConfig('app', ['url' => $url, 'locale' => $locale]);
}
protected function setupAdvancedValues()

View File

@ -23,55 +23,6 @@ class OctoberVersion extends \Illuminate\Console\Command
*/
public function handle()
{
$this->comment('*** Detecting October CMS build...');
if (!App::hasDatabase()) {
$build = UpdateManager::instance()->getBuildNumberManually($this->option('changes'));
// Skip setting the build number if no database is detected to set it within
$this->comment('*** No database detected - skipping setting the build number.');
} else {
$build = UpdateManager::instance()->setBuildNumberManually($this->option('changes'));
}
if (!$build['confident']) {
$this->warn('*** We could not accurately determine your October CMS build due to the number of modifications. The closest detected build is October CMS build ' . $build['build'] . '.');
} else if ($build['modified']) {
$this->info('*** Detected a modified version of October CMS build ' . $build['build'] . '.');
} else {
$this->info('*** Detected October CMS build ' . $build['build'] . '.');
}
if ($this->option('changes')) {
$this->line('');
$this->comment('We have detected the following modifications:');
if (count($build['changes']['added'] ?? [])) {
$this->line('');
$this->info('Files added:');
foreach (array_keys($build['changes']['added']) as $file) {
$this->line(' - ' . $file);
}
}
if (count($build['changes']['modified'] ?? [])) {
$this->line('');
$this->info('Files modified:');
foreach (array_keys($build['changes']['modified']) as $file) {
$this->line(' - ' . $file);
}
}
if (count($build['changes']['removed'] ?? [])) {
$this->line('');
$this->info('Files removed:');
foreach (array_keys($build['changes']['removed']) as $file) {
$this->line(' - ' . $file);
}
}
}
$this->comment('*** Thanks for using October CMS!');
}
}

View File

@ -48,11 +48,18 @@ class PluginInstall extends Command
$this->output->writeln(sprintf('<info>Unpacking plugin: %s</info>', $code));
$manager->extractPlugin($code, $hash);
/*
* Make sure plugin is registered
*/
$pluginManager = PluginManager::instance();
$pluginManager->loadPlugins();
$plugin = $pluginManager->findByIdentifier($code);
$pluginManager->registerPlugin($plugin, $code);
/*
* Migrate plugin
*/
$this->output->writeln(sprintf('<info>Migrating plugin...</info>', $code));
PluginManager::instance()->loadPlugins();
$manager->updatePlugin($code);
}

View File

@ -200,11 +200,11 @@ return [
'ses_key_comment' => 'Enter your SES API key',
'ses_secret' => 'SES secret',
'ses_secret_comment' => 'Enter your SES API secret key',
'ses_region' => 'SES region',
'ses_region_comment' => 'Enter your SES region (e.g. us-east-1)',
'sparkpost' => 'SparkPost',
'sparkpost_secret' => 'SparkPost secret',
'sparkpost_secret_comment' => 'Enter your SparkPost API secret key',
'ses_region' => 'SES region',
'ses_region_comment' => 'Enter your SES region (e.g. us-east-1)',
'drivers_hint_header' => 'Drivers not installed',
'drivers_hint_content' => 'This mail method requires the plugin ":plugin" be installed before you can send mail.',
],

View File

@ -33,7 +33,6 @@ return [
'fullscreen' => 'Teljes képernyő',
'preview' => 'Előnézet'
],
'mediamanager' => [
'insert_link' => 'Hivatkozás beszúrása',
'insert_image' => 'Kép beszúrása',
@ -45,13 +44,11 @@ return [
'invalid_video_empty_insert' => 'Válasszon ki legalább egy videót a beszúráshoz.',
'invalid_audio_empty_insert' => 'Válasszon ki legalább egy audiót a beszúráshoz.'
],
'alert' => [
'confirm_button_text' => 'Igen',
'cancel_button_text' => 'Mégsem',
'widget_remove_confirm' => 'Valóban törölni akarja?'
],
'datepicker' => [
'previousMonth' => 'Előző hónap',
'nextMonth' => 'Következő hónap',
@ -59,11 +56,9 @@ return [
'weekdays' => ['vasárnap', 'hétfő', 'kedd', 'szerda', 'csütörtök', 'péntek', 'szombat'],
'weekdaysShort' => ['va', 'hé', 'ke', 'sze', 'cs', 'pé', 'szo']
],
'colorpicker' => [
'choose' => 'Mentés',
],
'filter' => [
'group' => [
'all' => 'összes'
@ -88,7 +83,6 @@ return [
'max_placeholder' => 'Maximum'
]
],
'eventlog' => [
'show_stacktrace' => 'Részletek',
'hide_stacktrace' => 'Rejtés',

View File

@ -113,7 +113,7 @@ return [
'settings' => [
'menu_label' => 'Beállítások',
'not_found' => 'Nem létezik a megadott beállítás oldal.',
'missing_model' => 'A beállítások lap egy modell definíciót hiányol.',
'missing_model' => 'A beállítások oldal egy modell definíciót hiányol.',
'update_success' => 'A(z) :name beállításainak frissítése sikerült.',
'return' => 'Vissza a beállításokhoz',
'search' => 'Keresés...'
@ -278,6 +278,7 @@ return [
'plugin_version' => 'Verzió',
'plugin_author' => 'Fejlesztő',
'plugin_not_found' => 'A bővítmény nem található',
'plugin_version_not_found' => 'Bővítmény verzió nem található',
'core_current_build' => 'Verziószám',
'core_view_changelog' => 'Részletek',
'core_build' => 'Új verzió: :build',
@ -285,6 +286,8 @@ return [
'core_downloading' => 'Rendszer letöltése...',
'core_extracting' => 'Rendszer kicsomagolása...',
'core_set_build' => 'Rendszer beállítása...',
'update_warnings_title' => 'Néhány probléma, amelyek figyelmet igényelnek:',
'update_warnings_plugin_missing' => 'A(z) :parent_code bővítmény használatához szükséges a(z) :code bővítményt telepíteni.',
'changelog' => 'Kiadott verziók',
'changelog_view_details' => 'Részletek',
'plugins' => 'Bővítmény',
@ -394,6 +397,7 @@ return [
'impersonate_users' => 'Átjelentkezés felhasználók fiókjába',
'manage_preferences' => 'Saját beállítások kezelése',
'manage_editor' => 'Kódszerkesztő testreszabása',
'manage_own_editor' => 'Saját kódszerkesztő testreszabása',
'view_the_dashboard' => 'Vezérlőpult elérése',
'manage_default_dashboard' => 'Vezérlőpult testreszabása',
'manage_branding' => 'Kinézet testreszabása'
@ -415,7 +419,7 @@ return [
],
'page' => [
'custom_error' => [
'label' => 'Laphiba',
'label' => 'Oldal hiba',
'help' => 'Sajnáljuk, de hiba történt, ezért az oldal nem megjeleníthető.'
],
'invalid_token' => [

View File

@ -13,62 +13,107 @@ return [
|
*/
'accepted' => 'A(z) :attribute-t el kell fogadni.',
'active_url' => 'A(z) :attribute nem érvényes webcím.',
'after' => 'A(z) :attribute :date utáni dátum kell, hogy legyen.',
'alpha' => 'A(z) :attribute csak betűket tartalmazhat.',
'alpha_dash' => 'A(z) :attribute csak betűket, számokat és kötőjeleket tartalmazhat.',
'alpha_num' => 'A(z) :attribute csak betűket és számokat tartalmazhat.',
'array' => 'A(z) :attribute tömb kell, hogy legyen.',
'before' => 'A(z) :attribute :date előtti dátum kell, hogy legyen.',
'between' => [
'numeric' => 'A(z) :attribute :min - :max között kell, hogy legyen.',
'file' => 'A(z) :attribute :min - :max kilobájt között kell, hogy legyen.',
'string' => 'A(z) :attribute :min - :max karakter között kell, hogy legyen.',
'array' => 'A(z) :attribute :min - :max elem között kell, hogy legyen.',
'accepted' => 'A(z) :attribute-t el kell fogadni.',
'active_url' => 'A(z) :attribute nem érvényes webcím.',
'after' => 'A(z) :attribute :date utáni dátum kell legyen.',
'after_or_equal' => 'A(z) :attribute :date utáni vagy vele egyenlő dátum kell legyen.',
'alpha' => 'A(z) :attribute csak betűket tartalmazhat.',
'alpha_dash' => 'A(z) :attribute csak betűket, számokat és kötőjeleket tartalmazhat.',
'alpha_num' => 'A(z) :attribute csak betűket és számokat tartalmazhat.',
'array' => 'A(z) :attribute tömb kell legyen.',
'before' => 'A(z) :attribute :date előtti dátum kell legyen.',
'between' => [
'numeric' => 'A(z) :attribute :min - :max között kell legyen.',
'file' => 'A(z) :attribute :min - :max kilobájt között kell legyen.',
'string' => 'A(z) :attribute :min - :max karakter között kell legyen.',
'array' => 'A(z) :attribute :min - :max elem között kell legyen.',
],
'boolean' => 'A(z) :attribute igaz vagy hamis kell legyen.',
'confirmed' => 'A(z) :attribute megerősítés nem egyezik.',
'date' => 'A(z) :attribute nem érvényes dátum.',
'date_equals' => 'A(z) :attribute :date vele egyenlő dátum kell legyen.',
'date_format' => 'A(z) :attribute nem egyezik a(z) :format formátummal.',
'different' => 'A(z) :attribute és a(z) :other eltérő kell legyen.',
'digits' => 'A(z) :attribute :digits számból kell álljon.',
'digits_between' => 'A(z) :attribute :min és :max közti számból kell álljon.',
'dimensions' => 'A(z) :attribute kép mérete helytelen.',
'distinct' => 'A(z) :attribute mező többször szerepel.',
'email' => 'A(z) :attribute formátuma érvénytelen.',
'ends_with' => 'A(z) :attribute végének ennek kell lennie: :values.',
'exists' => 'A kiválasztott :attribute érvénytelen.',
'file' => 'A(z) :attribute fájlnak kell lennie.',
'filled' => 'A(z) :attribute értéknek kell lennie.',
'gt' => [
'numeric' => 'A(z) :attribute nagyobbnak kell lennie mint :value.',
'file' => 'A(z) :attribute nagyobbnak kell lennie mint :value kilobájt.',
'string' => 'A(z) :attribute nagyobbnak kell lennie mint :value karakter.',
'array' => 'A(z) :attribute többnek kell lennie mint :value elem.',
],
'gte' => [
'numeric' => 'A(z) :attribute nagyobbnak vagy egyenlőnek kell lennie mint :value.',
'file' => 'A(z) :attribute nagyobbnak vagy egyenlőnek kell lennie mint :value kilobájt.',
'string' => 'A(z) :attribute nagyobbnak vagy egyenlőnek kell lennie mint :value karakter.',
'array' => 'A(z) :attribute többnek vagy egyenlőnek kell lennie mint :value elem.',
],
'image' => 'A(z) :attribute kép kell legyen.',
'in' => 'A kiválasztott :attribute érvénytelen.',
'in_array' => 'A(z) :attribute mező nem létezik itt: :other.',
'integer' => 'A(z) :attribute egész szám kell legyen.',
'ip' => 'A(z) :attribute érvényes IP cím kell legyen.',
'ipv4' => 'A(z) :attribute értéke IPv4 szabvány legyen.',
'ipv6' => 'A(z) :attribute értéke IPv6 szabvány legyen.',
'json' => 'A(z) :attribute értéke JSON formátum legyen.',
'lt' => [
'numeric' => 'A(z) :attribute kisebbnek kell lennie mint :value.',
'file' => 'A(z) :attribute kisebbnek kell lennie mint :value kilobájt.',
'string' => 'A(z) :attribute kisebbnek kell lennie mint :value karakter.',
'array' => 'A(z) :attribute kevesebbnek kell lennie mint :value elem.',
],
'lte' => [
'numeric' => 'A(z) :attribute kisebbnek vagy egyenlőnek kell lennie mint :value.',
'file' => 'A(z) :attribute kisebbnek vagy egyenlőnek kell lennie mint :value kilobájt.',
'string' => 'A(z) :attribute kisebbnek vagy egyenlőnek kell lennie mint :value karakter.',
'array' => 'A(z) :attribute kevesebbnek vagy egyenlőnek kell lennie mint :value elem.',
],
'confirmed' => 'A(z) :attribute megerősítés nem egyezik.',
'date' => 'A(z) :attribute nem érvényes dátum.',
'date_format' => 'A(z) :attribute nem egyezik a(z) :format formátummal.',
'different' => 'A(z) :attribute és a(z) :other eltérő kell, hogy legyen.',
'digits' => 'A(z) :attribute :digits számból kell, hogy álljon.',
'digits_between' => 'A(z) :attribute :min és :max közti számból kell, hogy álljon.',
'email' => 'A(z) :attribute formátuma érvénytelen.',
'exists' => 'A kiválasztott :attribute érvénytelen.',
'image' => 'A(z) :attribute kép kell, hogy legyen.',
'in' => 'A kiválasztott :attribute érvénytelen.',
'integer' => 'A(z) :attribute egész szám kell, hogy legyen.',
'ip' => 'A(z) :attribute érvényes IP cím kell, legyen.',
'max' => [
'numeric' => 'A(z) :attribute nem lehet nagyobb, mint :max.',
'file' => 'A(z) :attribute nem lehet nagyobb :max kilobájtnál.',
'string' => 'A(z) :attribute nem lehet nagyobb :max karakternél.',
'array' => 'A(z) :attribute tömbnek nem lehet több, mint :max eleme.',
],
'mimes' => 'A(z) :attribute fájltípus kell, hogy legyen: :values.',
"extensions" => 'A(z) :attribute kiterjesztés kell, hogy legyen: :values.',
'min' => [
'numeric' => 'A(z) :attribute legalább :min kell, hogy legyen.',
'file' => 'A(z) :attribute legalább :min kilobájt kell, hogy legyen.',
'string' => 'A(z) :attribute legalább :min karakter kell, hogy legyen.',
'array' => 'A(z) :attribute tömbnek legalább :min eleme kell, hogy legyen.',
'mimes' => 'A(z) :attribute fájltípus kell legyen: :values.',
'mimetypes' => 'A(z) :attribute fájltípus kell legyen: :values.',
'min' => [
'numeric' => 'A(z) :attribute legalább :min kell legyen.',
'file' => 'A(z) :attribute legalább :min kilobájt kell legyen.',
'string' => 'A(z) :attribute legalább :min karakter kell legyen.',
'array' => 'A(z) :attribute tömbnek legalább :min eleme kell legyen.',
],
'not_in' => 'A kiválasztott :attribute érvénytelen.',
'numeric' => 'A(z) :attribute szám kell, hogy legyen.',
'regex' => 'A(z) :attribute formátuma érvénytelen.',
'required' => 'A(z) :attribute megadása kötelező.',
'required_if' => 'A(z) :attribute megadása kötelező, ha a(z) :other :value.',
'required_with' => 'A(z) :attribute megadása kötelező, ha a(z) :values jelen van.',
'required_without' => 'A(z) :attribute megadása kötelező, ha a(z) :values nincs jelen.',
'same' => 'A(z) :attribute és a(z) :other egyező kell, hogy legyen.',
'size' => [
'numeric' => 'A(z) :attribute :size kell, hogy legyen.',
'file' => 'A(z) :attribute :size kilobájt kell, hogy legyen.',
'string' => 'A(z) :attribute :size karakter kell, hogy legyen.',
'array' => 'A(z) :attribute :size elemeket kell, hogy tartalmazzon.',
'not_in' => 'A kiválasztott :attribute érvénytelen.',
'not_regex' => 'A(z) :attribute formátuma érvénytelen.',
'numeric' => 'A(z) :attribute szám kell legyen.',
'regex' => 'A(z) :attribute formátuma érvénytelen.',
'required' => 'A(z) :attribute megadása kötelező.',
'required_if' => 'A(z) :attribute megadása kötelező, ha a(z) :other :value.',
'required_unless' => 'A(z) :attribute megadása kötelező, hacsak a(z) :other :value.',
'required_with' => 'A(z) :attribute megadása kötelező, ha a(z) :values jelen van.',
'required_with_all' => 'A(z) :attribute megadása kötelező, ha az összes :values jelen van.',
'required_without' => 'A(z) :attribute megadása kötelező, ha a(z) :values nincs jelen.',
'required_without_all' => 'A(z) :attribute megadása kötelező, ha az összes :values nincs jelen.',
'same' => 'A(z) :attribute és a(z) :other egyező kell legyen.',
'size' => [
'numeric' => 'A(z) :attribute :size kell legyen.',
'file' => 'A(z) :attribute :size kilobájt kell legyen.',
'string' => 'A(z) :attribute :size karakter kell legyen.',
'array' => 'A(z) :attribute :size elemeket kell tartalmazzon.',
],
'unique' => 'A(z) :attribute már foglalt.',
'url' => 'A(z) :attribute formátuma érvénytelen.',
'starts_with' => 'A(z) :attribute a következőkkel kell kezdődnie: :values.',
'string' => 'A(z) :attribute szövegnek kell lennie.',
'timezone' => 'A(z) :attribute időzónának kell lennie.',
'unique' => 'A(z) :attribute már foglalt.',
'uploaded' => 'A(z) :attribute feltöltése sikertelen.',
'url' => 'A(z) :attribute formátuma érvénytelen.',
'uuid' => 'A(z) :attribute formátuma UUID kell legyen.',
/*
|--------------------------------------------------------------------------
@ -99,7 +144,9 @@ return [
'title' => 'cím',
'slug' => 'webcím',
'image' => 'kép',
'picture' => 'kép',
'content' => 'tartalom',
'text' => 'szöveg',
'summary' => 'összegzés',
'email' => 'e-mail cím',
'subject' => 'tárgy',

View File

@ -252,7 +252,7 @@ return [
'mail_brand' => [
'menu_label' => 'E-mail branding',
'menu_description' => 'Aanpassen van kleuren en weergave van e-mailsjablonen.',
'page_title' => 'Aanpaasen e-mailweergave',
'page_title' => 'Aanpassen e-mailweergave',
'sample_template' => [
'heading' => 'Kop',
'paragraph' => 'Dit is een paragraaf gevuld met Lorem Ipsum en een link. Cumque dicta <a>doloremque eaque</a>, enim error laboriosam pariatur possimus tenetur veritatis voluptas.',

View File

@ -33,7 +33,6 @@ return [
'fullscreen' => 'Tela cheia',
'preview' => 'Visualizar',
],
'mediamanager' => [
'insert_link' => "Inserir link",
'insert_image' => "Inserir imagem",
@ -45,13 +44,11 @@ return [
'invalid_video_empty_insert' => "Por favor, selecione os vídeos que deseja inserir.",
'invalid_audio_empty_insert' => "Por favor, selecione os áudios que deseja inserir.",
],
'alert' => [
'confirm_button_text' => 'OK',
'cancel_button_text' => 'Cancelar',
'widget_remove_confirm' => 'Remover este widget?'
],
'datepicker' => [
'previousMonth' => 'Mês anterior',
'nextMonth' => 'Próximo mês',
@ -86,7 +83,6 @@ return [
'max_placeholder' => 'Max'
]
],
'eventlog' => [
'show_stacktrace' => 'Exibir o rastreamento',
'hide_stacktrace' => 'Ocultar o rastreamento',

View File

@ -5,6 +5,51 @@ return [
'name' => 'October CMS',
'tagline' => 'Voltando ao básico',
],
'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ă',
'rs' => 'Srpski',
'ru' => 'Русский',
'fi' => 'Suomi',
'sv' => 'Svenska',
'sk' => 'Slovenský',
'sl' => 'Slovenščina',
'th' => 'ไทย',
'tr' => 'Türkçe',
'uk' => 'Українська мова',
'zh-cn' => '简体中文',
'zh-tw' => '繁體中文',
'vn' => 'Tiếng việt',
],
'directory' => [
'create_fail' => 'Não é possível criar o diretório: :name',
],
@ -27,6 +72,7 @@ return [
'users' => 'Usuários',
'system' => 'Sistema',
'social' => 'Social',
'backend' => 'Backend',
'events' => 'Eventos',
'customers' => 'Clientes',
'my_settings' => 'Configurações',
@ -60,8 +106,6 @@ return [
],
'plugins' => [
'manage' => 'Gerenciar plugins',
'enable_or_disable' => 'Habilitar ou desabilitar',
'enable_or_disable_title' => 'Habilitar ou Desabilitar Plugins',
'install' => 'Instalar plugins',
'install_products' => 'Instalar produtos',
'search' => 'Buscar plugin para instalar...',
@ -69,6 +113,7 @@ return [
'no_plugins' => 'Não há plugins instalados.',
'recommended' => 'Recomendado',
'plugin_label' => 'Plugin',
'unknown_plugin' => 'Plugin removido do sistema de arquivos.',
'select_label' => 'Selecionar ação...',
'bulk_actions_label' => 'Ações em massa',
'check_yes' => 'Sim',
@ -79,16 +124,8 @@ return [
'unfreeze' => 'ativar atualizações para',
'enable' => 'ativo',
'disable' => 'inativo',
'remove' => 'Remover',
'refresh' => 'Atualizar',
'remove_confirm' => 'Tem certeza de que deseja remover os plug-ins selecionados? Isso também removerá todos os dados associados.',
'remove_success' => 'Plugins removidos com sucesso do sistema.',
'refresh_confirm' => 'Tem certeza de que deseja redefinir os plugins selecionados? Isso redefinirá os dados de cada plugin, restaurando-os para o estado de inicial.',
'refresh_success' => 'Plugins atualizados com sucesso.',
'disable_confirm' => 'Você tem certeza?',
'disable_success' => 'Plugins desabilitados com sucesso.',
'enable_success' => 'Plugins habilitados com sucesso.',
'unknown_plugin' => 'Plugin removido do sistema de arquivos.',
'remove' => 'Remover',
'freeze_label' => 'Desativar Atualizações',
'unfreeze_label' => 'Ativar Atualizações',
'enable_label' => 'Ativar plugins',
@ -97,6 +134,12 @@ return [
'action_confirm' => 'Tem certeza de que deseja :action esses plugins?',
'freeze_success' => 'Plugins selecionados foram desativados com sucesso.',
'unfreeze_success' => 'Plugins selecionados foram ativados com sucesso.',
'enable_success' => 'Plugins habilitados com sucesso.',
'disable_success' => 'Plugins desabilitados com sucesso.',
'refresh_confirm' => 'Tem certeza de que deseja redefinir os plugins selecionados? Isso redefinirá os dados de cada plugin, restaurando-os para o estado de inicial.',
'refresh_success' => 'Plugins atualizados com sucesso.',
'remove_confirm' => 'Tem certeza de que deseja remover os plug-ins selecionados? Isso também removerá todos os dados associados.',
'remove_success' => 'Plugins removidos com sucesso do sistema.',
],
'project' => [
'name' => 'Projeto',
@ -159,6 +202,9 @@ return [
'ses_secret_comment' => 'Forneça sua chave de API do SES.',
'ses_region' => 'Região SES',
'ses_region_comment' => 'Entre com sua região SES (exemplo: us-east-1)',
'sparkpost' => 'SparkPost',
'sparkpost_secret' => 'SparkPost chave secreta',
'sparkpost_secret_comment' => 'Insira sua chave secreta da API SparkPost',
'drivers_hint_header' => 'Drivers não instalados',
'drivers_hint_content' => 'Este método requer que o plugin ":plugin" esteja instalado.'
],
@ -285,6 +331,8 @@ return [
'core_downloading' => 'Baixando arquivos do aplicativo',
'core_extracting' => 'Desempacotando arquivos do aplicativo',
'core_set_build' => 'Configurando o número de compilação',
'update_warnings_title' => 'Alguns problemas foram detectados e requerem atenção:',
'update_warnings_plugin_missing' => 'O plugin :parent_code requer que o :code seja instalado antes de funcionar',
'changelog' => 'Changelog',
'changelog_view_details' => 'Ver detalhes',
'plugins' => 'Plugins',
@ -394,6 +442,7 @@ return [
'impersonate_users' => 'Representar usuários',
'manage_preferences' => 'Gerenciar preferências da área administrativa',
'manage_editor' => 'Gerenciar preferências do editor de código',
'manage_own_editor' => 'Gerenciar preferências pessoais do editor de código',
'view_the_dashboard' => 'Visualizar o painel',
'manage_default_dashboard' => 'Gerenciar o painel padrão',
'manage_branding' => 'Personalizar o painel'
@ -421,6 +470,12 @@ return [
'invalid_token' => [
'label' => 'Token de segurança inválido',
],
'maintenance' => [
'label' => "Voltamos em breve!",
'help' => "No momento, estamos em manutenção, tente novamente mais tarde!",
'message' => 'Mensagem:',
'available_at' => 'Tente novamente após after:',
],
],
'pagination' => [
'previous' => 'Anterior',

View File

@ -13,81 +13,110 @@ return [
|
*/
'after_or_equal' => 'O campo :attribute deve ser uma data posterior ou igual a :date.',
'before_or_equal' => 'O campo :attribute deve ser uma data anterior ou igual a :date.',
'accepted' => ':attribute deve ser aceito.',
'active_url' => ':attribute não é uma URL válida.',
'after' => ':attribute deve ser uma data após :date.',
'after' => ':attribute deve ser uma data posterior a :date.',
'after_or_equal' => ':attribute deve ser uma data posterior ou igual a :date.',
'alpha' => ':attribute só pode conter letras.',
'alpha_dash' => ':attribute só pode conter letras, números e traços.',
'alpha_num' => ':attribute só pode conter letras e números.',
'array' => ':attribute deve ser uma matriz.',
'before' => ':attribute deve ser uma data antes :date.',
'before' => ':attribute deve ser uma data anterior :date.',
'before_or_equal' => ':attribute deve ser uma data anterior ou igual a :date.',
'between' => [
'numeric' => ':attribute deve situar-se entre :min e :max.',
'file' => ':attribute deve ter entre :min e :max kilobytes.',
'string' => ':attribute deve ter entre :min e :max caracteres.',
'numeric' => ':attribute deve ser entre :min e :max.',
'file' => ':attribute deve ser entre :min e :max kilobytes.',
'string' => ':attribute deve ser entre :min e :max caracteres.',
'array' => ':attribute deve ter entre :min e :max itens.',
],
'boolean' => 'O campo :attribute deve ser verdadeiro ou falso.',
'dimensions' => 'O campo :attribute tem dimensões de imagem inválidas.',
'distinct' => 'O campo :attribute campo tem um valor duplicado.',
'file' => 'O campo :attribute deve ser um arquivo.',
'filled' => 'O campo :attribute deve ter um valor.',
'in_array' => 'O campo :attribute não existe em :other.',
'ipv4' => 'O campo :attribute deve ser um endereço IPv4 válido.',
'ipv6' => 'O campo :attribute deve ser um endereço IPv6 válido.',
'json' => 'O campo :attribute deve ser uma string JSON válida.',
'confirmed' => 'A confirmação de :attribute não corresponde.',
'boolean' => ':attribute deve ser verdadeiro ou falso.',
'confirmed' => ':attribute de confirmação não confere.',
'date' => ':attribute não é uma data válida.',
'date_format' => ':attribute não coincide com o formato :format.',
'date_equals' => ':attribute deve ser uma data igual a :date.',
'date_format' => ':attribute não corresponde ao formato :format.',
'different' => ':attribute e :other devem ser diferentes.',
'digits' => ':attribute deve ser :digits dígitos.',
'digits' => ':attribute deve ter :digits dígitos.',
'digits_between' => ':attribute deve ter entre :min e :max dígitos.',
'email' => 'Formato de :attribute é inválido.',
'dimensions' => ':attribute tem dimensões de imagem inválidas.',
'distinct' => ':attribute campo tem um valor duplicado.',
'email' => ':attribute deve ser um endereço de e-mail válido.',
'ends_with' => ':attribute deve terminar com um dos seguintes: :values',
'exists' => ':attribute selecionado é inválido.',
'file' => ':attribute deve ser um arquivo.',
'filled' => ':attribute deve ter um valor.',
'gt' => [
'numeric' => ':attribute deve ser maior que :value.',
'file' => ':attribute deve ser maior que :value kilobytes.',
'string' => ':attribute deve ser maior que :value caracteres.',
'array' => ':attribute deve conter mais de :value itens.',
],
'gte' => [
'numeric' => ':attribute deve ser maior ou igual a :value.',
'file' => ':attribute deve ser maior ou igual a :value kilobytes.',
'string' => ':attribute deve ser maior ou igual a :value caracteres.',
'array' => ':attribute deve conter :value itens ou mais.',
],
'image' => ':attribute deve ser uma imagem.',
'in' => ':attribute selecionado é inválido.',
'in_array' => ':attribute não existe em :other.',
'integer' => ':attribute deve ser um número inteiro.',
'ip' => ':attribute deve ser um endereço IP válido.',
'max' => [
'numeric' => ':attribute não pode ser maior do que :max.',
'file' => ':attribute não pode ser maior do que :max kilobytes.',
'string' => ':attribute não pode ser maior do que :max caracteres.',
'array' => ':attribute não pode ter mais que :max itens.',
'ip' => ':attribute deve ser um endereço de IP válido.',
'ipv4' => ':attribute deve ser um endereço IPv4 válido.',
'ipv6' => ':attribute deve ser um endereço IPv6 válido.',
'json' => ':attribute deve ser uma string JSON válida.',
'lt' => [
'numeric' => ':attribute deve ser menor que :value.',
'file' => ':attribute deve ser menor que :value kilobytes.',
'string' => ':attribute deve ser menor que :value caracteres.',
'array' => ':attribute deve conter menos de :value itens.',
],
'lte' => [
'numeric' => ':attribute deve ser menor ou igual a :value.',
'file' => ':attribute deve ser menor ou igual a :value kilobytes.',
'string' => ':attribute deve ser menor ou igual a :value caracteres.',
'array' => ':attribute não deve conter mais que :value itens.',
],
'max' => [
'numeric' => ':attribute não pode ser superior a :max.',
'file' => ':attribute não pode ser superior a :max kilobytes.',
'string' => ':attribute não pode ser superior a :max caracteres.',
'array' => ':attribute não pode ter mais do que :max itens.',
],
'mimes' => ':attribute deve ser um arquivo do tipo: :values.',
'extensions' => 'O :attribute deve conter uma extensão: :values.',
'mimetypes' => 'O campo :attribute deve ser um arquivo do tipo: :values.',
'min' => [
'numeric' => ':attribute deve ser no mínimo :min.',
'mimetypes' => ':attribute deve ser um arquivo do tipo: :values.',
'min' => [
'numeric' => ':attribute deve ser pelo menos :min.',
'file' => ':attribute deve ter pelo menos :min kilobytes.',
'string' => ':attribute deve ter pelo menos :min caracteres.',
'array' => ':attribute deve ter pelo menos :min itens.',
],
'present' => 'O campo :attribute deve estar presente.',
'required_unless' => 'O campo :attribute é obrigatório exceto quando :other for :values.',
'required_with_all' => 'O campo :attribute é obrigatório quando :values está presente.',
'required_without_all' => 'O campo :attribute é obrigatório quando nenhum dos :values estão presentes.',
'not_in' => ':attribute selecionado é inválido.',
'not_regex' => ':attribute possui um formato inválido.',
'numeric' => ':attribute deve ser um número.',
'regex' => 'Formato de :attribute é inválido.',
'required' => 'O campo :attribute é obrigatório.',
'required_if' => 'O campo :attribute é obrigatório quando :other é :value.',
'required_with' => 'O campo :attribute é obrigatório quando :values está presente.',
'required_without' => 'O campo :attribute é obrigatório quando :values não está presente.',
'same' => 'O campo :attribute e :other devem corresponder.',
'password' => 'A senha está incorreta.',
'present' => ':attribute deve estar presente.',
'regex' => ':attribute tem um formato inválido.',
'required' => ':attribute é obrigatório.',
'required_if' => ':attribute é obrigatório quando :other for :value.',
'required_unless' => ':attribute é obrigatório exceto quando :other for :values.',
'required_with' => ':attribute é obrigatório quando :values está presente.',
'required_with_all' => ':attribute é obrigatório quando :values está presente.',
'required_without' => ':attribute é obrigatório quando :values não está presente.',
'required_without_all' => ':attribute é obrigatório quando nenhum dos :values estão presentes.',
'same' => ':attribute e :other devem corresponder.',
'size' => [
'numeric' => ':attribute deve ser :size.',
'file' => ':attribute deve ser :size kilobytes.',
'string' => ':attribute deve ter :size caracteres.',
'string' => ':attribute deve ser :size caracteres.',
'array' => ':attribute deve conter :size itens.',
],
'string' => 'O campo :attribute deve ser uma string.',
'timezone' => 'O campo :attribute deve ser uma zona válida.',
'uploaded' => 'Ocorreu uma falha no upload do campo :attribute.',
'starts_with' => ':attribute deve começar com um dos seguintes valores: :values',
'string' => ':attribute deve ser uma string.',
'timezone' => ':attribute deve ser uma zona válida.',
'unique' => ':attribute já está sendo utilizado.',
'url' => 'Formato de :attribute é inválido.',
'uploaded' => 'Ocorreu uma falha no upload do campo :attribute.',
'url' => ':attribute tem um formato inválido.',
'uuid' => ':attribute deve ser um UUID válido.',
/*
|--------------------------------------------------------------------------

View File

@ -105,7 +105,7 @@ trait AssetMaker
/**
* Adds JavaScript asset to the asset list. Call $this->makeAssets() in a view
* to output corresponding markup.
* @param string $name Specifies a path (URL) to the script.
* @param array|string $name Specifies a path (URL) or an array of paths to the script(s).
* @param array $attributes Adds extra HTML attributes to the asset link.
* @return void
*/
@ -133,7 +133,7 @@ trait AssetMaker
/**
* Adds StyleSheet asset to the asset list. Call $this->makeAssets() in a view
* to output corresponding markup.
* @param string $name Specifies a path (URL) to the script.
* @param array|string $name Specifies a path (URL) or an array of paths to the stylesheet(s).
* @param array $attributes Adds extra HTML attributes to the asset link.
* @return void
*/

View File

@ -18,10 +18,18 @@ final class SecurityPolicy implements SecurityPolicyInterface
* @var array List of forbidden methods.
*/
protected $blockedMethods = [
// \October\Rain\Extension\ExtendableTrait
'addDynamicMethod',
'addDynamicProperty',
// \October\Rain\Support\Traits\Emitter
'bindEvent',
'bindEventOnce',
// Eloquent & Halcyon data modification
'insert',
'update',
'delete',
];
/**

View File

@ -20,11 +20,6 @@
{
"name": "Samuel Georges",
"email": "daftspunky@gmail.com"
},
{
"name": "Luke Towers",
"email": "octobercms@luketowers.ca",
"url": "https://luketowers.ca"
}
],
"license": "MIT",

View File

@ -13,9 +13,6 @@
<testsuite name="October CMS Test Suite">
<directory>./tests/unit</directory>
</testsuite>
<testsuite name="October Rain Test Suite">
<directory>./vendor/october/rain/tests</directory>
</testsuite>
</testsuites>
<filter>

View File

@ -55,6 +55,9 @@ abstract class PluginTestCase extends TestCase
$app['config']->set('database.default', $dbConnection);
$app['config']->set('database.connections.' . $dbConnection, $dbConnections[$dbConnection]);
// Set random encryption key
$app['config']->set('app.key', bin2hex(random_bytes(16)));
/*
* Modify the plugin path away from the test context
*/

View File

@ -1,4 +1,7 @@
<?php
use PHPUnit\Framework\Assert;
class TestCase extends Illuminate\Foundation\Testing\TestCase
{
/**
@ -15,6 +18,9 @@ class TestCase extends Illuminate\Foundation\Testing\TestCase
$app['cache']->setDefaultDriver('array');
$app->setLocale('en');
// Set random encryption key
$app['config']->set('app.key', bin2hex(random_bytes(16)));
return $app;
}
@ -48,4 +54,38 @@ class TestCase extends Illuminate\Foundation\Testing\TestCase
$property->setAccessible(true);
return $property->setValue($object, $value);
}
/**
* Stub for `assertFileNotExists` to allow compatibility with both PHPUnit 8 and 9.
*
* @param string $filename
* @param string $message
* @return void
*/
public static function assertFileNotExists(string $filename, string $message = ''): void
{
if (method_exists(Assert::class, 'assertFileDoesNotExist')) {
Assert::assertFileDoesNotExist($filename, $message);
return;
}
Assert::assertFileNotExists($filename, $message);
}
/**
* Stub for `assertRegExp` to allow compatibility with both PHPUnit 8 and 9.
*
* @param string $filename
* @param string $message
* @return void
*/
public static function assertRegExp(string $pattern, string $string, string $message = ''): void
{
if (method_exists(Assert::class, 'assertMatchesRegularExpression')) {
Assert::assertMatchesRegularExpression($pattern, $string, $message);
return;
}
Assert::assertRegExp($pattern, $string, $message);
}
}

View File

@ -1,4 +1,4 @@
<?php namespace TestVendor\Goto;
<?php namespace TestVendor\Goto
use System\Classes\PluginBase;

View File

@ -61,7 +61,11 @@ class ExportModelTest extends TestCase
$response->prepare($request);
$this->assertTrue($response->headers->has('Content-Type'), "Response is missing the Content-Type header!");
$this->assertTrue($response->headers->contains('Content-Type', 'text/plain'), "Content-Type is not \"text/plain\"!");
$this->assertTrue(
$response->headers->contains('Content-Type', 'application/csv')
|| $response->headers->contains('Content-Type', 'text/plain'),
"Content-Type is not as expected!"
);
ob_start();
$response->send();

View File

@ -33,6 +33,10 @@ class ThemeTest extends TestCase
public function testGetPath()
{
if (PHP_OS_FAMILY === 'Windows') {
$this->markTestIncomplete('Need to fix Windows testing here');
}
$theme = Theme::load('test');
$this->assertEquals(base_path('tests/fixtures/themes/test'), $theme->getPath());

View File

@ -335,6 +335,32 @@ class ImageResizerTest extends PluginTestCase
$this->assertStringContainsString('october%20space', $imageResizer->getResizedUrl(), 'Resized URLs are not properly URL encoded');
}
public function testGetResizedUrl()
{
$imageResizer = new ImageResizer((new CmsController())->themeUrl('assets/images/october.png'));
Config::set('cms.linkPolicy', 'force');
$url = $imageResizer->getResizedUrl();
$this->assertTrue(starts_with($url, 'http'));
Config::set('cms.linkPolicy', 'detect');
$url = $imageResizer->getResizedUrl();
$this->assertTrue(starts_with($url, Config::get('cms.storage.resized.path', '/storage/app/resized')));
}
public function testGetResizerUrl()
{
$imageResizer = new ImageResizer((new CmsController())->themeUrl('assets/images/october.png'));
Config::set('cms.linkPolicy', 'force');
$url = $imageResizer->getResizerUrl();
$this->assertTrue(starts_with($url, 'http'));
Config::set('cms.linkPolicy', 'detect');
$url = $imageResizer->getResizerUrl();
$this->assertTrue(starts_with($url, '/resizer/'));
}
protected function setUpStorage()
{
$this->app->useStoragePath(base_path('storage/temp'));

View File

@ -1,9 +1,16 @@
<?php
use Illuminate\Filesystem\FilesystemAdapter;
use System\Classes\MediaLibrary;
class MediaLibraryTest extends TestCase // @codingStandardsIgnoreLine
{
public function setUp(): void
{
MediaLibrary::forgetInstance();
parent::setUp();
}
public function tearDown(): void
{
$this->removeMedia();
@ -89,6 +96,33 @@ class MediaLibraryTest extends TestCase // @codingStandardsIgnoreLine
$this->assertNotEmpty($contents[2]->size, 'Media library item size is empty');
}
public function testListAllDirectories()
{
$disk = $this->createConfiguredMock(FilesystemAdapter::class, [
'allDirectories' => [
'/media/.ignore1',
'/media/.ignore2',
'/media/dir',
'/media/dir/sub',
'/media/exclude',
'/media/hidden',
'/media/hidden/sub1',
'/media/hidden/sub1/deep1',
'/media/hidden/sub2',
'/media/hidden but not really',
'/media/name'
]
]);
$this->app['config']->set('cms.storage.media.folder', 'media');
$this->app['config']->set('cms.storage.media.ignore', ['hidden']);
$this->app['config']->set('cms.storage.media.ignorePatterns', ['^\..*']);
$instance = MediaLibrary::instance();
$this->setProtectedProperty($instance, 'storageDisk', $disk);
$this->assertEquals(['/', '/dir', '/dir/sub', '/hidden but not really', '/name'], $instance->listAllDirectories(['/exclude']));
}
protected function setUpStorage()
{
$this->app->useStoragePath(base_path('storage/temp'));