downgrade to kirby v3
This commit is contained in:
30
README.md
30
README.md
@@ -1,36 +1,34 @@
|
||||
<img src="http://getkirby.com/assets/images/github/plainkit.jpg" width="300">
|
||||
|
||||
**Kirby: the CMS that adapts to any project, loved by developers and editors alike.**
|
||||
|
||||
**Kirby: the CMS that adapts to any project, loved by developers and editors alike.**
|
||||
The Plainkit is a minimal Kirby setup with the basics you need to start a project from scratch. It is the ideal choice if you are already familiar with Kirby and want to start step-by-step.
|
||||
|
||||
You can learn more about Kirby at [getkirby.com](https://getkirby.com).
|
||||
|
||||
### Try Kirby for free
|
||||
|
||||
### Try Kirby for free
|
||||
You can try Kirby and the Plainkit on your local machine or on a test server as long as you need to make sure it is the right tool for your next project. … and when you’re convinced, [buy your license](https://getkirby.com/buy).
|
||||
|
||||
### Get going
|
||||
|
||||
Read our guide on [how to get started with Kirby](https://getkirby.com/docs/guide/quickstart).
|
||||
|
||||
You can [download the latest version](https://github.com/getkirby/plainkit/archive/main.zip) of the Plainkit.
|
||||
You can [download the latest version](https://github.com/getkirby/plainkit/archive/main.zip) of the Plainkit.
|
||||
If you are familiar with Git, you can clone Kirby's Plainkit repository from Github.
|
||||
|
||||
git clone https://github.com/getkirby/plainkit.git
|
||||
|
||||
## What's Kirby?
|
||||
|
||||
- **[getkirby.com](https://getkirby.com)** – Get to know the CMS.
|
||||
- **[Try it](https://getkirby.com/try)** – Take a test ride with our online demo. Or download one of our kits to get started.
|
||||
- **[Documentation](https://getkirby.com/docs/guide)** – Read the official guide, reference and cookbook recipes.
|
||||
- **[Issues](https://github.com/getkirby/kirby/issues)** – Report bugs and other problems.
|
||||
- **[Feedback](https://feedback.getkirby.com)** – You have an idea for Kirby? Share it.
|
||||
- **[Forum](https://forum.getkirby.com)** – Whenever you get stuck, don't hesitate to reach out for questions and support.
|
||||
- **[Discord](https://chat.getkirby.com)** – Hang out and meet the community.
|
||||
- **[Mastodon](https://mastodon.social/@getkirby)** – Spread the word.
|
||||
- **[Instagram](https://www.instagram.com/getkirby/)** – Share your creations: #madewithkirby.
|
||||
- **[getkirby.com](https://getkirby.com)** – Get to know the CMS.
|
||||
- **[Try it](https://getkirby.com/try)** – Take a test ride with our online demo. Or download one of our kits to get started.
|
||||
- **[Documentation](https://getkirby.com/docs/guide)** – Read the official guide, reference and cookbook recipes.
|
||||
- **[Issues](https://github.com/getkirby/kirby/issues)** – Report bugs and other problems.
|
||||
- **[Feedback](https://feedback.getkirby.com)** – You have an idea for Kirby? Share it.
|
||||
- **[Forum](https://forum.getkirby.com)** – Whenever you get stuck, don't hesitate to reach out for questions and support.
|
||||
- **[Discord](https://chat.getkirby.com)** – Hang out and meet the community.
|
||||
- **[Twitter](https://twitter.com/getkirby)** – Spread the word.
|
||||
- **[Instagram](https://www.instagram.com/getkirby/)** – Share your creations: #madewithkirby.
|
||||
|
||||
---
|
||||
|
||||
© 2009 Bastian Allgeier
|
||||
© 2009-2022 Bastian Allgeier
|
||||
[getkirby.com](https://getkirby.com) · [License agreement](https://getkirby.com/license)
|
||||
|
||||
@@ -12,7 +12,7 @@ h1, .text-40 { font-size: 40pt; line-height: 58pt; font-weight: normal }
|
||||
h2, .text-30 { font-size: 30pt; line-height: 29pt; font-weight: normal }
|
||||
h3, .text-22 { font-size: 22pt; line-height: 29pt; font-weight: normal }
|
||||
h4, .text-16, html { font-size: 16pt; line-height: 29pt; font-weight: normal }
|
||||
h5, .text-12 { font-size: 12pt; line-height: 15pt; font-weight: normal }
|
||||
h5, h6, .text-12 { font-size: 12pt; line-height: 15pt; font-weight: normal }
|
||||
|
||||
h2 { margin-top: 16pt }
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"keywords": [
|
||||
"kirby",
|
||||
"cms",
|
||||
"plainkit"
|
||||
"starterkit"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
@@ -17,12 +17,16 @@
|
||||
"homepage": "https://getkirby.com",
|
||||
"support": {
|
||||
"email": "support@getkirby.com",
|
||||
"issues": "https://github.com/getkirby/starterkit/issues",
|
||||
"forum": "https://forum.getkirby.com",
|
||||
"source": "https://github.com/getkirby/plainkit"
|
||||
"source": "https://github.com/getkirby/starterkit"
|
||||
},
|
||||
"require": {
|
||||
"php": "~8.1.0 || ~8.2.0 || ~8.3.0",
|
||||
"getkirby/cms": "^4.0"
|
||||
"php": ">=7.4.0 <8.0.0",
|
||||
"getkirby/cms": "^3.6",
|
||||
"sylvainjule/embed": "^1.0",
|
||||
"jg/kirby-fields-block": "^1.1",
|
||||
"sylvainjule/color-palette": "^1.0"
|
||||
},
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
|
||||
1595
composer.lock
generated
Normal file
1595
composer.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -17,10 +17,6 @@ trim_trailing_whitespace = true
|
||||
indent_size = 4
|
||||
insert_final_newline = true
|
||||
|
||||
[*.vue.php]
|
||||
indent_size = 2
|
||||
insert_final_newline = false
|
||||
|
||||
[*.yml]
|
||||
indent_style = space
|
||||
|
||||
|
||||
@@ -6,47 +6,43 @@
|
||||
|
||||
To keep track of different states of our code (current release, bugfixes, features) we use branches:
|
||||
|
||||
| Branch | Used for | PRs allowed? |
|
||||
| --------------- | ------------------------------------------------------------------------ | --------------------------- |
|
||||
| `main` | Latest released version | ❌ |
|
||||
| `develop-patch` | Working branch for next patch release, e.g. `4.0.x` | ✅ |
|
||||
| `develop-minor` | Working branch for next minor release, e.g. `4.x.0` | ✅ |
|
||||
| `v5/develop` | Working branch for next major release, e.g. `5.0.0` | ✅ |
|
||||
| `fix/*` | Temporary branches for single bugfix | - |
|
||||
| `feature/*` | Temporary branches for single feature | - |
|
||||
| `release/*` | Pre-releases in testing before they are merged into `main` when released | only during release testing |
|
||||
| Branch | Used for | PRs allowed? |
|
||||
| ----------- | ------------------------------------------------------------------------ | --------------------------- |
|
||||
| `main` | Latest released version | - |
|
||||
| `develop` | Working branch for next release, e.g. `3.7.x` | ✅ |
|
||||
| `fix/*` | Temporary branches for single patch | - |
|
||||
| `feature/*` | Temporary branches for single feature | - |
|
||||
| `release/*` | Pre-releases in testing before they are merged into `main` when released | only during release testing |
|
||||
|
||||
We will review all pull requests (PRs) to `develop-patch`, `develop-minor` and `v5/develop` and merge them if accepted, once an appropriate version is upcoming. Please understand that this might not be the immediate next release and might take some time.
|
||||
We will review all pull requests (PRs) to `develop` and merge them if accepted, once an appropriate version is upcoming. Please understand that this might not be the immediate next release and might take some time.
|
||||
|
||||
## How you can contribute
|
||||
|
||||
### Report a bug
|
||||
|
||||
When you find a bug, the first step to fixing it is to help us understand and reproduce the bug as best as possible. When you create a bug report, please include as many details as possible. Fill out [the template](https://github.com/getkirby/kirby/issues/new?template=bug_report.md) because the requested information helps us resolve issues so much faster.
|
||||
When you find a bug, the first step to fixing it is to help us understand and reproduce the bug as best as possible. When you create a bug report, please include as many details as possible. Fill out [the template](ISSUE_TEMPLATE/bug_report.md) because the requested information helps us resolve issues so much faster.
|
||||
|
||||
### Bug fixes
|
||||
|
||||
For bug fixes, please create a new branch following the name scheme: `fix/issue_number-bug-x`, e.g. `fix/234-this-nasty-bug`. Limit bug fix PRs to a single bug. **Do not mix multiple bug fixes in a single PR.** This will make it easier for us to review the fix and merge it.
|
||||
|
||||
- Always send bug fix PRs against the `develop-patch` branch––not `main`.
|
||||
- Always send bug fix PRs against the `develop` branch––not `main`.
|
||||
- Add a helpful description of what the PR does if it is not 100% self-explanatory.
|
||||
- Every bug fix should include a [unit test](#tests) to avoid future regressions. Let us know if you need help with that.
|
||||
- Make sure your code [style](#style) matches ours and includes [comments/in-code documentation](#documentation).
|
||||
- Make sure your branch is up to date with the latest state on the `develop-patch` branch. [Rebase](https://help.github.com/articles/about-pull-request-merges/) changes before you send the PR.
|
||||
- Please *don't* commit updated dist files in the `panel/dist` folder to avoid merge conflicts. We only build the dist files on release. Your branch should only contain changes to the source files.
|
||||
- Make sure your branch is up to date with the latest state on the `develop` branch. [Rebase](https://help.github.com/articles/about-pull-request-merges/) changes before you send the PR.
|
||||
|
||||
### Features
|
||||
|
||||
For features create a new branch following the name scheme: `feature/issue_number-feature-x`, e.g. `feature/123-awesome-function`. Our [feedback platform](https://feedback.getkirby.com) can be a good source of highly requested features. Maybe your feature idea already exists and you can get valuable feedback from other Kirby users. Focus on a single feature per PR. Don't mix features!
|
||||
|
||||
- Always send feature PRs against the `develop-minor` branch––not `main`.
|
||||
- Always send feature PRs against the `develop` branch––not `main`.
|
||||
- Add a helpful description of what the PR does.
|
||||
- New features should include [unit tests](#tests). Let us know if you need help with that.
|
||||
- Make your code [style](#style) matches ours and includes [comments/in-code documentation](#documentation).
|
||||
- Make sure your branch is up to date with the latest state on the `develop-minor` branch. [Rebase](https://help.github.com/articles/about-pull-request-merges/) changes before you send the PR.
|
||||
- Please *don't* commit updated dist files in the `panel/dist` folder to avoid merge conflicts. We only build the dist files on release. Your branch should only contain changes to the source files.
|
||||
- Make sure your branch is up to date with the latest state on the `develop` branch. [Rebase](https://help.github.com/articles/about-pull-request-merges/) changes before you send the PR.
|
||||
|
||||
We try to bundle features in our major releases, e.g. `5.0`. That is why we might only review and, if accepted, merge your PR once an appropriate release is upcoming. Please understand that we cannot merge all feature ideas or that it might take a while. Check out the [roadmap](https://roadmap.getkirby.com) to see upcoming releases.
|
||||
We try to bundle features in our major releases, e.g. `3.x`. That is why we might only review and, if accepted, merge your PR once an appropriate release is upcoming. Please understand that we cannot merge all feature ideas or that it might take a while. Check out the [roadmap](https://roadmap.getkirby.com) to see upcoming releases.
|
||||
|
||||
### Translations
|
||||
|
||||
|
||||
147
kirby/LICENSE.md
147
kirby/LICENSE.md
@@ -1,7 +1,7 @@
|
||||
# Kirby License Agreement
|
||||
|
||||
Published: November 28, 2023
|
||||
Source: https://getkirby.com/license/2023-11-28
|
||||
Published: March 15, 2022
|
||||
Source: https://getkirby.com/license/2022-03-15
|
||||
|
||||
## About this Agreement
|
||||
|
||||
@@ -11,86 +11,49 @@ This End User License Agreement (the **"Agreement"**) is fundamental to the rela
|
||||
|
||||
If you do not agree to this Agreement, please do not download, install or use Kirby. Installation or use of Kirby signifies that you have read, understood, and agreed to be bound by this Agreement.
|
||||
|
||||
## Summary
|
||||
|
||||
This section summarizes the most important conditions of this Agreement to give you a quick overview:
|
||||
|
||||
- With your purchase you obtain a license. A license allows you to use Kirby according to this Agreement.
|
||||
- Each project (defined by its URL) needs its own license. You need to purchase the right license for your project and/or client. You can find our license variants on <https://getkirby.com/buy>. In some explicitly listed cases, you can use Kirby without having to purchase a license.
|
||||
- Each license includes any Kirby version that gets released within three years from the date when you first activated your license. We also provide free security updates for older versions that may protect your project beyond three years.
|
||||
- After those three years, you can continue to use Kirby for your project with any of these versions as long as you want.
|
||||
- To use any newer version released after this time, you will need to upgrade your license.
|
||||
- Upgrading your license extends the timeframe for an additional three years during which you can use new releases. You can perform the upgrade at any time.
|
||||
- You have the right to transfer or reassign a license to another person or project if needed.
|
||||
- There are some restrictions for use of Kirby that you can find below.
|
||||
|
||||
For the full license details, please read the Agreement in full. Only the following sections are legally binding.
|
||||
|
||||
## Definitions
|
||||
|
||||
Before we get started with the conditions of the Agreement, let's define the terms that will be used throughout it:
|
||||
|
||||
- When we refer to **"You"**, we mean the licensee. Before purchasing Kirby, that's the individual or company that has downloaded and/or installed Kirby for a Development Installation, Private Installation or Extension Demo. When used for a Public Site, the licensee is the individual or company that has purchased the Kirby license. If you work on a client project and have purchased the Kirby license for your client, you (and _not_ the client) are the licensee.
|
||||
- When we refer to **"We"**/**"Us"**/**"Our"**, we mean the licensor, the Content Folder GmbH & Co. KG. You can find Our company and contact information on Our [contact page](https://getkirby.com/contact).
|
||||
- **"Client"** is the individual or company on whose behalf You create or work on a Website. This only applies if the client is not the licensee.
|
||||
- When we refer to **"You"**, we mean the licensee. Before purchasing Kirby, that's the individual or company that has downloaded and/or installed Kirby for a Development Installation, Private Installation or Extension Demo. When used for a Public Site, the licensee is the individual or company that has purchased the Kirby license. If you work on a client project and have purchased the Kirby license for your client, you (and _not_ the client) are the licensee.
|
||||
- When we refer to **"We"**/**"Us"**/**"Our"**, we mean the licensor, the Content Folder GmbH & Co. KG. You can find Our company and contact information on Our [contact page](https://getkirby.com/contact).
|
||||
- A **"Website"** is a single Kirby project that is defined by its domain name and root directory (e.g. `https://sub.example.com` or `https://example.com/example/`). Each (sub)domain and root directory is a separate Website, even if the projects are related in any way. Exception: If You use the cross-domain multi-language feature with the same `content` folder, these domains count as the same Website.
|
||||
You may use Kirby as a headless backend or as a static site generator. In these cases the Website is defined by the domain and root directory of the user- or visitor-facing frontend(s).
|
||||
- A **"Development Installation"** is a Website that is installed purely for the purposes of development and client preview. It must only be accessible by a restricted number of users (like on a personal computer, on a server in a network with restricted access or when protecting a staging website with a password that only a restricted number of users know).
|
||||
- A **"Private Installation"** is a Website that is installed purely for personal use. It must only be accessible by You and Your family.
|
||||
- An **"Extension Demo"** is a Website with the single purpose to showcase a free or commercial Kirby theme or Kirby plugin, as long as that Website only contains demo content. If the showcased extension is a Kirby theme, the demo content must be exactly as shipped with the theme. Demos for Kirby plugins may _not_ contain any additional content that is not needed to showcase the plugin in use.
|
||||
- A **"Public Site"** is a Website that is _neither_ a Development Installation, a Private Installation nor an Extension Demo.
|
||||
- A **"Minor Release"** is a stable Kirby release which adds smaller new features, minor functionality enhancements or bug fixes. This class of release is identified by the change of the revision to the right of the first decimal point, e.g. 4.1 to 4.2, 4.X.1 to 4.X.2.
|
||||
- A **"Major Release"** is a stable Kirby release which incorporates major new features or enhancements that increase or change the core functionality of Kirby to a larger extent. It may also deprecate existing parts of the Source Code or change them in a breaking way. This class of release is identified by the change of the revision to the left of the first decimal point, e.g. 4.X to 5.0.
|
||||
- A **"Major Generation"** is defined as all releases that share the revision to the left of the first decimal point, e.g. 4.0.0, 4.0.X, 4.X.0 and 4.X.X.
|
||||
- An **"Update"** is defined as a Kirby release which adds smaller new features, minor functionality enhancements or bug fixes. This class of release is identified by the change of the revision to the right of the first decimal point, e.g. 3.1 to 3.2, 3.X.1 to 3.X.2 or 3.X.X.1 to 3.X.X.2.
|
||||
- An **"Upgrade"** is a major Kirby release which incorporates major new features or enhancements that increase the core functionality of Kirby to a larger extent. This class of release is identified by the change of the revision to the left of the first decimal point, e.g. 3.X to 4.0.
|
||||
- The **"Source Code"** is defined as the contents of all files that are provided with Kirby and that make Kirby work. This includes (but is not limited to) all PHP, JavaScript, JSON, HTML and CSS files as well as all related image and other media files.
|
||||
- The **"Activation Date"** determines the included updates. It is defined like this:
|
||||
- For a newly purchased license, it is the date when the license was first activated for use with a Public Site.
|
||||
- When You upgrade an already activated license, it is the date on which the upgrade was performed in Our license hub. If the license is still within the Included Updates Period, the Activation Date of the upgrade license will be set to the end of the Included Updates Period of the existing license.
|
||||
- When You upgrade a license that had _not_ been activated before, the upgrade license adopts the unactivated state of the existing license. The Activation Date is set on first activation for use with a Public Site.
|
||||
- The **"Included Updates Period"** is the time span of three (3) years after the Activation Date.
|
||||
- Licensees (You), Clients and Websites are **"Qualified"** if they satisfy the purchase requirements from the ["Order Process" section](#order-process) of this Agreement.
|
||||
|
||||
Every time you see one of these capitalized terms in the following text, it has the meaning that has been explained above.
|
||||
|
||||
## Usage for a Public Site
|
||||
|
||||
Installing Kirby on or using it for a Public Site requires a [paid license](https://getkirby.com/buy). Once a paid license is needed, the license must be immediately activated to the Public Site’s domain name and root directory via our license hub or the activation feature in the Kirby Panel.
|
||||
Installing Kirby on or using it for a Public Site requires a [paid license](https://getkirby.com/buy).
|
||||
|
||||
As Kirby is software and software is intangible, We don't sell it as such. Instead, this Agreement grants a license for each purchase to install and use a single instance of Kirby on a **specific Website**. Additional Kirby licenses must be purchased in order to install and use Kirby on **additional Websites**.
|
||||
|
||||
The license is **non-exclusive** (meaning that You are not the only one to whom We will issue a license) and **generally non-transferable** (meaning that the one who purchases the license is the licensee).
|
||||
The license is **non-exclusive** (meaning that You are not the only one who We will issue a license) and **generally non-transferable** (meaning that the one who purchases the license is the licensee).
|
||||
|
||||
On request, We will **transfer** a license to anyone who would be allowed and Qualified to purchase the license by law and this Agreement. The new licensee will take over all rights and obligations of this Agreement from You at the moment We confirm the license transfer.
|
||||
On request, We will **transfer** a license to anyone who is also allowed to buy Kirby licenses by law and this Agreement.
|
||||
|
||||
We will also **reassign** a license to another Qualified Website domain and root directory, if You confirm that the previous Website is no longer in operation and will not be operated with the same license in the future.
|
||||
We will also **reassign** a license to another Website domain and root directory of Your choice, provided that You confirm that the previous Website is no longer in operation and will not be operated with the same license in the future.
|
||||
|
||||
If the new licensee, Website or Client in a transfer or reassignment is not Qualified for the existing license, You or the new licensee need to **upgrade the license to the qualifying terms and conditions** before the transfer or reassignment can be performed.
|
||||
If you need to transfer your Kirby license to another individual or company (for example to your client or a new agency) or reassign it to a different project, please get in touch directly at <support@getkirby.com>.
|
||||
|
||||
> [!NOTE]
|
||||
> If you need to transfer your Kirby license to another individual or company (for example to your client or a new agency) or reassign it to a different project, please get in touch directly at <support@getkirby.com>.
|
||||
|
||||
A license is valid for all Major Releases that We publish before the end of the Included Updates Period. It is also valid for all releases in those Major Generations independent of their release date. Whether a release is a Minor Release or Major Release is at Our sole discretion.
|
||||
|
||||
The use of releases in Major Generations that We publish after the Included Updates Period requires a **paid license upgrade**. An upgrade license replaces the existing license.
|
||||
A license is valid for all Updates of the same major Kirby release. We reserve the right to charge an **upgrade fee for Upgrade releases**. Whether a release is an Update or Upgrade is at Our sole discretion.
|
||||
|
||||
## Order Process
|
||||
|
||||
Our order process is conducted by Our online reseller [Paddle.com](https://paddle.com). Paddle.com is the Merchant of Record for all Our orders. Paddle provides all customer service inquiries and handles returns.
|
||||
|
||||
When purchasing a license, You are **responsible to choose the right license** based on You and the Website project. Different license variants can come with certain requirements towards You and/or the Website project. We publish all such requirements on <https://getkirby.com/buy> in a way that makes them clearly visible before the purchase. With Your purchase, You confirm that You and the Website project qualify for the selected license variant.
|
||||
|
||||
If the Website is created for a Client, You need to make sure that the **Client qualifies for the selected license**.
|
||||
|
||||
If You purchase licenses **in advance**, You need to ensure to only use the license(s) for projects that satisfy the requirements for the selected license variant(s).
|
||||
|
||||
We **reserve the right to verify** at any time after the purchase whether You, the Website and (if applicable) the Client are Qualified. Changes to the situation of You, the Website or the Client as well as changes to the published information on Our "Buy" page after the purchase or after the assignment to a Client do _not_ take effect on an existing license unless You upgrade the license or We transfer or reassign the license on Your request.
|
||||
|
||||
## Free Licenses
|
||||
|
||||
Kirby can be used **for free in the following cases**.
|
||||
|
||||
> [!NOTE]
|
||||
> Please note that the restrictions and all other clauses of this Agreement also apply to free licenses. You may especially _not_ alter or circumvent the licensing features.
|
||||
Please note that the restrictions and all other clauses of this Agreement also apply to free licenses. You may especially _not_ alter or circumvent the licensing features.
|
||||
|
||||
### Usage for a Development Installation
|
||||
|
||||
@@ -98,28 +61,26 @@ We believe that it should be possible to test and evaluate software before havin
|
||||
|
||||
Therefore, installing and using Kirby on a personal computer (like a desktop PC, notebook or tablet) or server for a Development Installation is **free** for as long as You need.
|
||||
|
||||
> [!NOTE]
|
||||
> The usage of Kirby in production (with the intention to handle production data or content) is _never_ considered a Development Installation, even in internal apps or systems.
|
||||
The usage of Kirby in production (with the intention to handle production data or content) is _never_ considered a Development Installation, even in internal apps or systems.
|
||||
|
||||
### Usage for a Private Installation
|
||||
|
||||
You may also install and use Kirby for **free** in Private Installations as long as they are not accessible by anyone except You and Your family.
|
||||
|
||||
> [!NOTE]
|
||||
> Our [definition](#definitions) of a Private Installation allows the following use cases:
|
||||
>
|
||||
> - Private sites for personal use, for example:
|
||||
> - Apps for You personally (like a personal diary)
|
||||
> - Apps for You as a freelancer (like a bookkeeping, invoicing or project management app)
|
||||
> - Apps for Your family (like a private photo gallery)
|
||||
> - Experimental local Kirby setups for Your personal use (for example to try out Kirby features)
|
||||
>
|
||||
> However, the following use cases are _not_ covered and need a **[paid license](#usage-for-a-public-site)**:
|
||||
>
|
||||
> - Intranets for companies, authorities or organizations, no matter if on a local or public server
|
||||
> - (Internal) apps for teams or entire companies, authorities or organizations
|
||||
> - Websites that are accessible by the public, even for personal/non-commercial purposes
|
||||
> - Use of Kirby as a local CMS for a static or headless site without a license for the frontend domain(s)
|
||||
Our [definition](#definitions) of a Private Installation allows the following use cases:
|
||||
|
||||
- Private sites for personal use, for example:
|
||||
- Apps for You personally (like a personal diary)
|
||||
- Apps for You as a freelancer (like a bookkeeping, invoicing or project management app)
|
||||
- Apps for Your family (like a private photo gallery)
|
||||
- Experimental local Kirby setups for Your personal use (for example to try out Kirby features)
|
||||
|
||||
However, the following use cases are _not_ covered and need a **[paid license](#usage-for-a-public-site)**:
|
||||
|
||||
- Intranets for companies, authorities or organizations, no matter if on a local or public server
|
||||
- (Internal) apps for teams or entire companies, authorities or organizations
|
||||
- Websites that are accessible by the public, even for personal/non-commercial purposes
|
||||
- Use of Kirby as a local CMS for a static or headless site without a license for the frontend domain(s)
|
||||
|
||||
### Usage for an Extension Demo
|
||||
|
||||
@@ -127,8 +88,7 @@ Extension Demos are not real Websites. We want to encourage you to build and sho
|
||||
|
||||
Therefore, You may **operate Extension Demos without purchasing a license**.
|
||||
|
||||
> [!NOTE]
|
||||
> Please note that this does _not_ apply to store fronts or other types of sites used to promote free or commercial themes or plugins. If such a site is built with Kirby as well, it is a Public Site and needs a **[paid license](#usage-for-a-public-site)**.
|
||||
Please note that this does _not_ apply to store fronts or other types of sites used to promote free or commercial themes or plugins. If such a site is built with Kirby as well, it is a Public Site and needs a **[paid license](#usage-for-a-public-site)**.
|
||||
|
||||
## Restrictions
|
||||
|
||||
@@ -138,26 +98,20 @@ You may only use Kirby in a manner that complies with any and all **applicable l
|
||||
|
||||
### Making Copies
|
||||
|
||||
You may make **copies of Kirby** in any machine readable form solely for the **following purposes**, provided that You reproduce Kirby in its original form and with all proprietary notices on the copy:
|
||||
|
||||
- when deploying a Website to a server,
|
||||
- when developing a Website on a personal computer or server,
|
||||
- when working on code contributions to Kirby or
|
||||
- as a backup.
|
||||
You may make **copies of Kirby** in any machine readable form solely for purposes of **deploying a Website to a server, developing a Website on a personal computer or server or as a backup**, provided that You reproduce Kirby in its original form and with all proprietary notices on the copy.
|
||||
|
||||
You may _not_ reproduce Kirby or its Source Code, in whole or in part, for **any other purpose**.
|
||||
|
||||
### Modification of the Source Code
|
||||
|
||||
You may **alter, modify or extend the Source Code** for Your own use or with the intention to contribute Your changes back to Kirby. You may also **commission a third party** to perform those modifications for You.
|
||||
You may **alter, modify or extend the Source Code** for Your own use. You may also **commission a third party** to perform those modifications for You.
|
||||
|
||||
However You may _not_:
|
||||
|
||||
- **alter or circumvent the licensing features**, including (but not limited to) the license validation and payment prompts or
|
||||
- **resell, redistribute or transfer** the modified or derivative version.
|
||||
|
||||
> [!NOTE]
|
||||
> Please note that We **can't provide technical support** for modified or derivative versions of the Source Code.
|
||||
Please note that We **can't provide technical support** for modified or derivative versions of the Source Code.
|
||||
|
||||
### Your Relationship to Third Parties
|
||||
|
||||
@@ -171,13 +125,12 @@ The following cases are exempted from this restriction:
|
||||
- You may make a Kirby installation available to employees or partners of You or Your Website client. You may also disclose and distribute Kirby’s Source Code to Your client together with the source code of the Website You created for them.
|
||||
- You may disclose the Source Code to individuals or companies that are involved in the development or operation of Your Website (e.g. agencies, design or development freelancers, hosting providers or administrators).
|
||||
|
||||
> [!NOTE]
|
||||
> E.g. the following cases are explicitly **_not_ allowed**:
|
||||
>
|
||||
> - Selling, licensing or distributing a new product based on Kirby that modifies or hides Kirby’s identity as a Content Management System (CMS)
|
||||
> - Forking Kirby and selling the modified version ([see above](#modification-of-the-source-code))
|
||||
> - Buying licenses in bulk and reselling them in your own shop
|
||||
> - Bundling or including Kirby’s Source Code in the publication and/or distribution of a Website’s source code or a (free or paid) theme or plugin (please use Git submodules or Composer or provide a link to Our repository or website instead)
|
||||
E.g. the following cases are explicitly **_not_ allowed**:
|
||||
|
||||
- Selling, licensing or distributing a new product based on Kirby that modifies or hides Kirby’s identity as a Content Management System (CMS)
|
||||
- Forking Kirby and selling the modified version ([see above](#restrictions__modification-of-the-source-code))
|
||||
- Buying licenses in bulk and reselling them in your own shop
|
||||
- Bundling or including Kirby’s Source Code in the publication and/or distribution of a Website’s source code or a (free or paid) theme or plugin (please use Git submodules or Composer or provide a link to Our repository or website instead)
|
||||
|
||||
### Disallowed Uses
|
||||
|
||||
@@ -210,23 +163,13 @@ You may also _not_:
|
||||
|
||||
Technical support is **provided as described on Our website** at <https://getkirby.com>. **No representations or guarantees** are made regarding the response time in which support questions are answered, however We will do Our best to respond quickly.
|
||||
|
||||
For each Major Generation, We aim to provide **security support for three (3) years** after the Major Release. Security support means that We will provide free security updates for the supported releases, which will include fixes for security vulnerabilities according to the following rules:
|
||||
- We published a security advisory on <https://getkirby.com/security> within the respective security support period. We will publish vulnerabilities on this page as soon as they are known to Us and an official fix for any supported release is available.
|
||||
- The latest release of the supported Major Generation is affected by the vulnerability.
|
||||
|
||||
With each vulnerability, We aim to publish the security advisory and security updates for all supported Major Generations at the same time.
|
||||
|
||||
> [!NOTE]
|
||||
> You can find up-to-date information on our currently supported versions in our [public security policy](https://getkirby.com/security).
|
||||
|
||||
We reserve the right to **limit technical support for free licenses**.
|
||||
|
||||
## Refund Policy
|
||||
|
||||
We offer a **14-day**, money back refund policy if Kirby didn't work out for Your project.
|
||||
|
||||
> [!NOTE]
|
||||
> If you need a refund, please get in touch directly at <support@getkirby.com>.
|
||||
If you need a refund, please get in touch directly at <support@getkirby.com>.
|
||||
|
||||
## No Warranty
|
||||
|
||||
@@ -234,13 +177,7 @@ KIRBY IS OFFERED ON AN **"AS-IS" BASIS** AND **NO WARRANTY**, EITHER EXPRESSED O
|
||||
|
||||
## Term, Termination and Modification
|
||||
|
||||
You may **indefinitely use** all Kirby versions that are covered by Your license under this Agreement until either party **terminates this Agreement** as described in this section.
|
||||
|
||||
**You** may terminate the Agreement at any time.
|
||||
|
||||
**We** may only terminate the Agreement if You or any individual or company who works with Kirby or uses it on Your behalf has violated or failed to comply with terms of this Agreement. If Your compliance with the Agreement can be restored by fixing the violation or non-compliance, We will first contact You with information on the specific term that was violated or not complied with and will allow reasonable time of at least 14 days before We will decide on a license termination. Should We be in the position to terminate a license according to this paragraph, other or all licenses granted to You may be terminated for the same reason(s) at the same time or at any later date.
|
||||
|
||||
Termination takes effect upon notice to the other party in textual form (via email or letter). Upon termination, the specified **licenses granted to You will terminate**, and You will **immediately uninstall and cease all use** of Kirby. If not all licenses are terminated, You may continue to use Kirby for the Websites with active licenses. The sections entitled "No Warranty", "Indemnification" and "Limitation of Liability" will **survive any termination** of this Agreement.
|
||||
You may use Kirby under this Agreement until either party terminates this Agreement as described in this paragraph. Either party may **terminate the Agreement** at any time, upon notice to the other party in textual form (via email or letter). Upon termination, all or the specified **licenses granted to You will terminate**, and You will **immediately uninstall and cease all use** of Kirby. If not all licenses are terminated, You may continue to use Kirby for the Websites with active licenses. The sections entitled "No Warranty", "Indemnification" and "Limitation of Liability" will **survive any termination** of this Agreement.
|
||||
|
||||
We may **modify Kirby and this Agreement** with notice to You either via email or by publishing content on the Kirby website at https://getkirby.com, including but not limited to changing the functionality or appearance of Kirby. Any such modification will **become binding on You** unless You terminate this Agreement. Changes to this Agreement that constrain Your rights to a great extent will only become effective with Your approval in textual or electronic form.
|
||||
|
||||
@@ -256,8 +193,6 @@ YOU EXPRESSLY UNDERSTAND AND AGREE THAT **WE SHALL NOT BE LIABLE** FOR ANY DIREC
|
||||
|
||||
Bastian Allgeier **owns all rights**, title and interest to Kirby (including all intellectual property rights) and **reserves all rights to Kirby** that are not expressly granted in this Agreement.
|
||||
|
||||
In the event that Kirby will no longer be actively maintained, Bastian Allgeier will provide the Source Code under the terms of a free and open source software (FOSS) license as far as legally and contractually possible.
|
||||
|
||||
## Applicable Law & Place of Jurisdiction
|
||||
|
||||
1. For all disputes arising out of or in connection with this Agreement, the courts competent for Neckargemünd, Germany, shall have exclusive jurisdiction. However, We shall have the choice to file lawsuits against You before the courts competent for Your place of business.
|
||||
@@ -273,4 +208,4 @@ Should any provision of this Agreement be or become invalid, void or unenforceab
|
||||
|
||||
Due to Kirby's flexibility, you may have special use cases or requirements that don't fit this Agreement.
|
||||
|
||||
If that's the case or if you have any questions, feel free to [get in touch](mailto:support@getkirby.com). We are happy to think outside the box and find custom license solutions for your creative application of Kirby.
|
||||
If that's the case or if you have any questions, feel free to get in touch: <support@getkirby.com>. We are happy to think outside the box and find custom license solutions for your creative application of Kirby.
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
[<img src="https://getkirby.com/assets/images/github/kirby.jpg" width="300">](https://getkirby.com)
|
||||
[<img src="http://getkirby.com/assets/images/github/kirby.jpg" width="300">](https://getkirby.com)
|
||||
|
||||
[](https://github.com/getkirby/kirby/releases/latest)
|
||||
[](https://github.com/getkirby/kirby/actions?query=workflow%3ACI+branch%3Amain)
|
||||
[](https://codecov.io/gh/getkirby/kirby)
|
||||
[](https://github.com/getkirby/kirby/releases/latest)
|
||||
[](https://github.com/getkirby/kirby/releases/latest)
|
||||
[](https://github.com/getkirby/kirby/actions?query=workflow%3ACI)
|
||||
[](https://codecov.io/gh/getkirby/kirby)
|
||||
[](https://github.com/getkirby/kirby/releases/latest)
|
||||
[](https://twitter.com/getkirby)
|
||||
|
||||
**Kirby: the CMS that adapts to any project, loved by developers and editors alike.**
|
||||
With Kirby, you build your own ideal interface. Combine forms, galleries, articles, spreadsheets and more into an amazing editing experience. You can learn more about Kirby at [getkirby.com](https://getkirby.com).
|
||||
With Kirby, you build your own ideal interface. Combine forms, galleries, articles, spreadsheets and more into an amazing editing experience. You can learn more about Kirby at [getkirby.com](https://getkirby.com).
|
||||
|
||||
This is Kirby's core application folder. Get started with one of the following repositories instead:
|
||||
|
||||
- [Starterkit](https://github.com/getkirby/starterkit)
|
||||
- [Plainkit](https://github.com/getkirby/plainkit)
|
||||
|
||||
<img src="https://getkirby.com/assets/images/github/kirby-screen.png" />
|
||||
|
||||
### Try Kirby for free
|
||||
<img src="http://getkirby.com/assets/images/github/kirby-screen.png" />
|
||||
|
||||
### Try Kirby for free
|
||||
Kirby is not free software. However, you can try Kirby and the Starterkit on your local machine or on a test server as long as you need to make sure it is the right tool for your next project. … and when you’re convinced, [buy your license](https://getkirby.com/buy).
|
||||
|
||||
### Contribute
|
||||
|
||||
**Found a bug?**
|
||||
Please post all bugs as individual reports in our [issue tracker](https://github.com/getkirby/kirby/issues).
|
||||
Please post all bug reports in our [issue tracker](https://github.com/getkirby/kirby/issues).
|
||||
|
||||
**Suggest a feature**
|
||||
If you have ideas for a feature or enhancement for Kirby, please use our [feedback platform](https://feedback.getkirby.com).
|
||||
@@ -30,8 +30,9 @@ If you have ideas for a feature or enhancement for Kirby, please use our [feedba
|
||||
**Translations, bug fixes, code contributions ...**
|
||||
Read about how to contribute to the development in our [contributing guide](/CONTRIBUTING.md).
|
||||
|
||||
## What's Kirby?
|
||||
|
||||
|
||||
## What's Kirby?
|
||||
- **[getkirby.com](https://getkirby.com)** – Get to know the CMS.
|
||||
- **[Try it](https://getkirby.com/try)** – Take a test ride with our online demo. Or download one of our kits to get started.
|
||||
- **[Documentation](https://getkirby.com/docs/guide)** – Read the official guide, reference and cookbook recipes.
|
||||
@@ -39,11 +40,10 @@ Read about how to contribute to the development in our [contributing guide](/CON
|
||||
- **[Feedback](https://feedback.getkirby.com)** – You have an idea for Kirby? Share it.
|
||||
- **[Forum](https://forum.getkirby.com)** – Whenever you get stuck, don't hesitate to reach out for questions and support.
|
||||
- **[Discord](https://chat.getkirby.com)** – Hang out and meet the community.
|
||||
- **[YouTube](https://youtube.com/kirbyCasts)** - Watch the latest video tutorials visually with Bastian.
|
||||
- **[Mastodon](https://mastodon.social/@getkirby)** – Spread the word.
|
||||
- **[Twitter](https://twitter.com/getkirby)** – Spread the word.
|
||||
- **[Instagram](https://www.instagram.com/getkirby/)** – Share your creations: #madewithkirby.
|
||||
|
||||
---
|
||||
|
||||
© 2009 Bastian Allgeier
|
||||
© 2009-2022 Bastian Allgeier
|
||||
[getkirby.com](https://getkirby.com) · [License agreement](https://getkirby.com/license)
|
||||
|
||||
@@ -1,27 +1,3 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported versions and past security incidents
|
||||
|
||||
You can find up-to-date information on the security status of each version on <https://getkirby.com/security>.
|
||||
|
||||
## Security of your Kirby site
|
||||
|
||||
We have a detailed [security guide](https://getkirby.com/docs/guide/security) with information on how to keep your Kirby installation secure.
|
||||
|
||||
## Reporting a vulnerability
|
||||
|
||||
If you have spotted a vulnerability in Kirby's core or the Panel, please make sure to let us know immediately. We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions.
|
||||
|
||||
You can always contact us directly at **<security@getkirby.com>**.
|
||||
If you want to encrypt your message, our GPG key is [6E6B 057A F491 FFAD 363F 6F49 9101 10FA A459 E120](https://getkirby.com/pgp.asc).
|
||||
|
||||
You can also use the [security advisory form on GitHub](https://github.com/getkirby/kirby/security/advisories/new) to securely and privately report a vulnerability to us.
|
||||
|
||||
We will send you a response as soon as possible and will keep you informed on our progress towards a fix and announcement.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Please do not write to us publicly, e.g. in the forum, on Discord or in a GitHub issue. A public report can give attackers valuable time to exploit the issue before it is fixed.
|
||||
>
|
||||
> By letting us know directly and coordinating the disclosure with us, you can help to protect other Kirby users from such attacks.
|
||||
>
|
||||
> Also please do *not* request a CVE ID from organizations like MITRE. The responsible CVE Numbering Authority (CNA) for Kirby is GitHub. We can and will request a CVE ID for each confirmed vulnerability and will provide it to you in advance of the coordinated release.
|
||||
Please see the [Security Policy on the Kirby website](https://getkirby.com/security) for a list of the currently supported Kirby versions and of past security incidents as well as for information on how to report security vulnerabilities in the Kirby core or in the Panel.
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
* stop at older or too recent versions
|
||||
*/
|
||||
if (
|
||||
version_compare(PHP_VERSION, '8.1.0', '>=') === false ||
|
||||
version_compare(PHP_VERSION, '8.4.0', '<') === false
|
||||
version_compare(PHP_VERSION, '7.4.0', '>=') === false ||
|
||||
version_compare(PHP_VERSION, '8.2.0', '<') === false
|
||||
) {
|
||||
die(include __DIR__ . '/views/php.php');
|
||||
}
|
||||
@@ -16,15 +16,11 @@ if (is_file($autoloader = dirname(__DIR__) . '/vendor/autoload.php')) {
|
||||
* Always prefer a site-wide Composer autoloader
|
||||
* if it exists, it means that the user has probably
|
||||
* installed additional packages
|
||||
*
|
||||
* @psalm-suppress MissingFile
|
||||
*/
|
||||
include $autoloader;
|
||||
} elseif (is_file($autoloader = __DIR__ . '/vendor/autoload.php')) {
|
||||
/**
|
||||
* Fall back to the local autoloader if that exists
|
||||
*
|
||||
* @psalm-suppress MissingFile
|
||||
*/
|
||||
include $autoloader;
|
||||
} else {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"name": "getkirby/cms",
|
||||
"description": "The Kirby core",
|
||||
"description": "The Kirby 3 core",
|
||||
"license": "proprietary",
|
||||
"type": "kirby-cms",
|
||||
"version": "4.3.1",
|
||||
"version": "3.7.5.5",
|
||||
"keywords": [
|
||||
"kirby",
|
||||
"cms",
|
||||
@@ -24,7 +24,7 @@
|
||||
"source": "https://github.com/getkirby/kirby"
|
||||
},
|
||||
"require": {
|
||||
"php": "~8.1.0 || ~8.2.0 || ~8.3.0",
|
||||
"php": ">=7.4.0 <8.2.0",
|
||||
"ext-SimpleXML": "*",
|
||||
"ext-ctype": "*",
|
||||
"ext-curl": "*",
|
||||
@@ -36,17 +36,14 @@
|
||||
"ext-libxml": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-openssl": "*",
|
||||
"christian-riesen/base32": "1.6.0",
|
||||
"claviska/simpleimage": "4.2.0",
|
||||
"composer/semver": "3.4.0",
|
||||
"filp/whoops": "2.15.4",
|
||||
"claviska/simpleimage": "3.7.0",
|
||||
"filp/whoops": "2.14.5",
|
||||
"getkirby/composer-installer": "^1.2.1",
|
||||
"laminas/laminas-escaper": "2.13.0",
|
||||
"laminas/laminas-escaper": "2.10.0",
|
||||
"michelf/php-smartypants": "1.8.1",
|
||||
"phpmailer/phpmailer": "6.9.1",
|
||||
"symfony/polyfill-intl-idn": "1.29.0",
|
||||
"symfony/polyfill-mbstring": "1.29.0",
|
||||
"symfony/yaml": "6.4.8"
|
||||
"phpmailer/phpmailer": "6.6.4",
|
||||
"symfony/polyfill-intl-idn": "1.26.0",
|
||||
"symfony/polyfill-mbstring": "1.26.0"
|
||||
},
|
||||
"replace": {
|
||||
"symfony/polyfill-php72": "*"
|
||||
@@ -58,7 +55,6 @@
|
||||
"ext-fileinfo": "Improved mime type detection for files",
|
||||
"ext-intl": "Improved i18n number formatting",
|
||||
"ext-memcached": "Support for the Memcached cache driver",
|
||||
"ext-sodium": "Support for the crypto class and more robust session handling",
|
||||
"ext-zip": "Support for ZIP archive file functions",
|
||||
"ext-zlib": "Sanitization and validation for svgz files"
|
||||
},
|
||||
@@ -80,7 +76,7 @@
|
||||
},
|
||||
"optimize-autoloader": true,
|
||||
"platform": {
|
||||
"php": "8.1.0"
|
||||
"php": "7.4.0"
|
||||
},
|
||||
"platform-check": false
|
||||
},
|
||||
@@ -94,13 +90,13 @@
|
||||
"analyze": [
|
||||
"@analyze:composer",
|
||||
"@analyze:psalm",
|
||||
"@analyze:phpcpd",
|
||||
"@analyze:phpmd"
|
||||
],
|
||||
"analyze:composer": "composer validate --strict --no-check-version --no-check-all",
|
||||
"analyze:phpcpd": "phpcpd --fuzzy --exclude tests --exclude vendor .",
|
||||
"analyze:phpmd": "phpmd . ansi phpmd.xml.dist --exclude 'dependencies/*,tests/*,vendor/*'",
|
||||
"analyze:psalm": "psalm",
|
||||
"bench": "phpbench run --report=aggregate --ref baseline",
|
||||
"bench:baseline": "phpbench run --report=aggregate --tag baseline",
|
||||
"build": "./scripts/build",
|
||||
"ci": [
|
||||
"@fix",
|
||||
@@ -108,8 +104,7 @@
|
||||
"@test"
|
||||
],
|
||||
"fix": "php-cs-fixer fix",
|
||||
"test": "phpunit",
|
||||
"test:coverage": "XDEBUG_MODE=coverage phpunit --coverage-html=tests/coverage",
|
||||
"test": "phpunit --stderr --coverage-html=tests/coverage",
|
||||
"zip": "composer archive --format=zip --file=dist"
|
||||
}
|
||||
}
|
||||
|
||||
526
kirby/composer.lock
generated
526
kirby/composer.lock
generated
@@ -4,89 +4,26 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "5c5a02ed090776d3c703adfc737f316b",
|
||||
"content-hash": "615bb9a6346016f0be80b1805212a9df",
|
||||
"packages": [
|
||||
{
|
||||
"name": "christian-riesen/base32",
|
||||
"version": "1.6.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ChristianRiesen/base32.git",
|
||||
"reference": "2e82dab3baa008e24a505649b0d583c31d31e894"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/ChristianRiesen/base32/zipball/2e82dab3baa008e24a505649b0d583c31d31e894",
|
||||
"reference": "2e82dab3baa008e24a505649b0d583c31d31e894",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^2.17",
|
||||
"phpstan/phpstan": "^0.12",
|
||||
"phpunit/phpunit": "^8.5.13 || ^9.5"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Base32\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Christian Riesen",
|
||||
"email": "chris.riesen@gmail.com",
|
||||
"homepage": "http://christianriesen.com",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Base32 encoder/decoder according to RFC 4648",
|
||||
"homepage": "https://github.com/ChristianRiesen/base32",
|
||||
"keywords": [
|
||||
"base32",
|
||||
"decode",
|
||||
"encode",
|
||||
"rfc4648"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/ChristianRiesen/base32/issues",
|
||||
"source": "https://github.com/ChristianRiesen/base32/tree/1.6.0"
|
||||
},
|
||||
"time": "2021-02-26T10:19:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "claviska/simpleimage",
|
||||
"version": "4.2.0",
|
||||
"version": "3.7.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/claviska/SimpleImage.git",
|
||||
"reference": "dfbe53c01dae8467468ef2b817c09b786a7839d2"
|
||||
"reference": "abd15ced313c7b8041d7d73d8d2398b4f2510cf1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/claviska/SimpleImage/zipball/dfbe53c01dae8467468ef2b817c09b786a7839d2",
|
||||
"reference": "dfbe53c01dae8467468ef2b817c09b786a7839d2",
|
||||
"url": "https://api.github.com/repos/claviska/SimpleImage/zipball/abd15ced313c7b8041d7d73d8d2398b4f2510cf1",
|
||||
"reference": "abd15ced313c7b8041d7d73d8d2398b4f2510cf1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-gd": "*",
|
||||
"league/color-extractor": "0.4.*",
|
||||
"php": ">=8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "^1.5",
|
||||
"phpstan/phpstan": "^1.10"
|
||||
"league/color-extractor": "0.3.*",
|
||||
"php": ">=5.6.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@@ -108,7 +45,7 @@
|
||||
"description": "A PHP class that makes working with images as simple as possible.",
|
||||
"support": {
|
||||
"issues": "https://github.com/claviska/SimpleImage/issues",
|
||||
"source": "https://github.com/claviska/SimpleImage/tree/4.2.0"
|
||||
"source": "https://github.com/claviska/SimpleImage/tree/3.7.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -116,101 +53,20 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2024-04-15T16:07:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "composer/semver",
|
||||
"version": "3.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/composer/semver.git",
|
||||
"reference": "35e8d0af4486141bc745f23a29cc2091eb624a32"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/composer/semver/zipball/35e8d0af4486141bc745f23a29cc2091eb624a32",
|
||||
"reference": "35e8d0af4486141bc745f23a29cc2091eb624a32",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.3.2 || ^7.0 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^1.4",
|
||||
"symfony/phpunit-bridge": "^4.2 || ^5"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Composer\\Semver\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nils Adermann",
|
||||
"email": "naderman@naderman.de",
|
||||
"homepage": "http://www.naderman.de"
|
||||
},
|
||||
{
|
||||
"name": "Jordi Boggiano",
|
||||
"email": "j.boggiano@seld.be",
|
||||
"homepage": "http://seld.be"
|
||||
},
|
||||
{
|
||||
"name": "Rob Bast",
|
||||
"email": "rob.bast@gmail.com",
|
||||
"homepage": "http://robbast.nl"
|
||||
}
|
||||
],
|
||||
"description": "Semver library that offers utilities, version constraint parsing and validation.",
|
||||
"keywords": [
|
||||
"semantic",
|
||||
"semver",
|
||||
"validation",
|
||||
"versioning"
|
||||
],
|
||||
"support": {
|
||||
"irc": "ircs://irc.libera.chat:6697/composer",
|
||||
"issues": "https://github.com/composer/semver/issues",
|
||||
"source": "https://github.com/composer/semver/tree/3.4.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://packagist.com",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/composer",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/composer/composer",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-08-31T09:50:34+00:00"
|
||||
"time": "2022-07-05T13:18:44+00:00"
|
||||
},
|
||||
{
|
||||
"name": "filp/whoops",
|
||||
"version": "2.15.4",
|
||||
"version": "2.14.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/filp/whoops.git",
|
||||
"reference": "a139776fa3f5985a50b509f2a02ff0f709d2a546"
|
||||
"reference": "a63e5e8f26ebbebf8ed3c5c691637325512eb0dc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/filp/whoops/zipball/a139776fa3f5985a50b509f2a02ff0f709d2a546",
|
||||
"reference": "a139776fa3f5985a50b509f2a02ff0f709d2a546",
|
||||
"url": "https://api.github.com/repos/filp/whoops/zipball/a63e5e8f26ebbebf8ed3c5c691637325512eb0dc",
|
||||
"reference": "a63e5e8f26ebbebf8ed3c5c691637325512eb0dc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -260,7 +116,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/filp/whoops/issues",
|
||||
"source": "https://github.com/filp/whoops/tree/2.15.4"
|
||||
"source": "https://github.com/filp/whoops/tree/2.14.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -268,7 +124,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2023-11-03T12:00:00+00:00"
|
||||
"time": "2022-01-07T12:00:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "getkirby/composer-installer",
|
||||
@@ -319,33 +175,33 @@
|
||||
},
|
||||
{
|
||||
"name": "laminas/laminas-escaper",
|
||||
"version": "2.13.0",
|
||||
"version": "2.10.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laminas/laminas-escaper.git",
|
||||
"reference": "af459883f4018d0f8a0c69c7a209daef3bf973ba"
|
||||
"reference": "58af67282db37d24e584a837a94ee55b9c7552be"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/af459883f4018d0f8a0c69c7a209daef3bf973ba",
|
||||
"reference": "af459883f4018d0f8a0c69c7a209daef3bf973ba",
|
||||
"url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/58af67282db37d24e584a837a94ee55b9c7552be",
|
||||
"reference": "58af67282db37d24e584a837a94ee55b9c7552be",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-ctype": "*",
|
||||
"ext-mbstring": "*",
|
||||
"php": "~8.1.0 || ~8.2.0 || ~8.3.0"
|
||||
"php": "^7.4 || ~8.0.0 || ~8.1.0"
|
||||
},
|
||||
"conflict": {
|
||||
"zendframework/zend-escaper": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"infection/infection": "^0.27.0",
|
||||
"laminas/laminas-coding-standard": "~2.5.0",
|
||||
"infection/infection": "^0.26.6",
|
||||
"laminas/laminas-coding-standard": "~2.3.0",
|
||||
"maglnet/composer-require-checker": "^3.8.0",
|
||||
"phpunit/phpunit": "^9.6.7",
|
||||
"psalm/plugin-phpunit": "^0.18.4",
|
||||
"vimeo/psalm": "^5.9"
|
||||
"phpunit/phpunit": "^9.5.18",
|
||||
"psalm/plugin-phpunit": "^0.16.1",
|
||||
"vimeo/psalm": "^4.22.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@@ -377,40 +233,37 @@
|
||||
"type": "community_bridge"
|
||||
}
|
||||
],
|
||||
"time": "2023-10-10T08:35:13+00:00"
|
||||
"time": "2022-03-08T20:15:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/color-extractor",
|
||||
"version": "0.4.0",
|
||||
"version": "0.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/color-extractor.git",
|
||||
"reference": "21fcac6249c5ef7d00eb83e128743ee6678fe505"
|
||||
"reference": "837086ec60f50c84c611c613963e4ad2e2aec806"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/color-extractor/zipball/21fcac6249c5ef7d00eb83e128743ee6678fe505",
|
||||
"reference": "21fcac6249c5ef7d00eb83e128743ee6678fe505",
|
||||
"url": "https://api.github.com/repos/thephpleague/color-extractor/zipball/837086ec60f50c84c611c613963e4ad2e2aec806",
|
||||
"reference": "837086ec60f50c84c611c613963e4ad2e2aec806",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-gd": "*",
|
||||
"php": "^7.3 || ^8.0"
|
||||
"php": ">=5.4.0"
|
||||
},
|
||||
"replace": {
|
||||
"matthecat/colorextractor": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "~2",
|
||||
"phpunit/phpunit": "^9.5"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-curl": "To download images from remote URLs if allow_url_fopen is disabled for security reasons"
|
||||
"phpunit/phpunit": "~5"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"League\\ColorExtractor\\": "src"
|
||||
"": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
@@ -436,9 +289,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/thephpleague/color-extractor/issues",
|
||||
"source": "https://github.com/thephpleague/color-extractor/tree/0.4.0"
|
||||
"source": "https://github.com/thephpleague/color-extractor/tree/master"
|
||||
},
|
||||
"time": "2022-09-24T15:57:16+00:00"
|
||||
"time": "2016-12-15T09:30:02+00:00"
|
||||
},
|
||||
{
|
||||
"name": "michelf/php-smartypants",
|
||||
@@ -496,16 +349,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpmailer/phpmailer",
|
||||
"version": "v6.9.1",
|
||||
"version": "v6.6.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHPMailer/PHPMailer.git",
|
||||
"reference": "039de174cd9c17a8389754d3b877a2ed22743e18"
|
||||
"reference": "a94fdebaea6bd17f51be0c2373ab80d3d681269b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/039de174cd9c17a8389754d3b877a2ed22743e18",
|
||||
"reference": "039de174cd9c17a8389754d3b877a2ed22743e18",
|
||||
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/a94fdebaea6bd17f51be0c2373ab80d3d681269b",
|
||||
"reference": "a94fdebaea6bd17f51be0c2373ab80d3d681269b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -515,25 +368,22 @@
|
||||
"php": ">=5.5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "^1.0",
|
||||
"doctrine/annotations": "^1.2.6 || ^1.13.3",
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
|
||||
"doctrine/annotations": "^1.2",
|
||||
"php-parallel-lint/php-console-highlighter": "^1.0.0",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.3.2",
|
||||
"phpcompatibility/php-compatibility": "^9.3.5",
|
||||
"roave/security-advisories": "dev-latest",
|
||||
"squizlabs/php_codesniffer": "^3.7.2",
|
||||
"yoast/phpunit-polyfills": "^1.0.4"
|
||||
"squizlabs/php_codesniffer": "^3.6.2",
|
||||
"yoast/phpunit-polyfills": "^1.0.0"
|
||||
},
|
||||
"suggest": {
|
||||
"decomplexity/SendOauth2": "Adapter for using XOAUTH2 authentication",
|
||||
"ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses",
|
||||
"ext-openssl": "Needed for secure SMTP sending and DKIM signing",
|
||||
"greew/oauth2-azure-provider": "Needed for Microsoft Azure XOAUTH2 authentication",
|
||||
"hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication",
|
||||
"league/oauth2-google": "Needed for Google XOAUTH2 authentication",
|
||||
"psr/log": "For optional PSR-3 debug logging",
|
||||
"symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)",
|
||||
"thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication"
|
||||
"stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication",
|
||||
"symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@@ -565,7 +415,7 @@
|
||||
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
|
||||
"support": {
|
||||
"issues": "https://github.com/PHPMailer/PHPMailer/issues",
|
||||
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.9.1"
|
||||
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.6.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -573,34 +423,34 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2023-11-25T22:23:28+00:00"
|
||||
"time": "2022-08-22T09:22:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/log",
|
||||
"version": "3.0.0",
|
||||
"version": "1.1.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/log.git",
|
||||
"reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001"
|
||||
"reference": "d49695b909c3b7628b6289db5479a1c204601f11"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001",
|
||||
"reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001",
|
||||
"url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11",
|
||||
"reference": "d49695b909c3b7628b6289db5479a1c204601f11",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0.0"
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.x-dev"
|
||||
"dev-master": "1.1.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Log\\": "src"
|
||||
"Psr\\Log\\": "Psr/Log/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
@@ -621,168 +471,22 @@
|
||||
"psr-3"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/php-fig/log/tree/3.0.0"
|
||||
"source": "https://github.com/php-fig/log/tree/1.1.4"
|
||||
},
|
||||
"time": "2021-07-14T16:46:02+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/deprecation-contracts",
|
||||
"version": "v3.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/deprecation-contracts.git",
|
||||
"reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1",
|
||||
"reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "3.5-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/contracts",
|
||||
"url": "https://github.com/symfony/contracts"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"function.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "A generic function and convention to trigger deprecation notices",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-04-18T09:32:20+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
"version": "v1.29.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||
"reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4",
|
||||
"reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"provide": {
|
||||
"ext-ctype": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-ctype": "For best performance"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Ctype\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Gert de Pagter",
|
||||
"email": "BackEndTea@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill for ctype functions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"ctype",
|
||||
"polyfill",
|
||||
"portable"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-01-29T20:11:03+00:00"
|
||||
"time": "2021-05-03T11:20:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-intl-idn",
|
||||
"version": "v1.29.0",
|
||||
"version": "v1.26.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-intl-idn.git",
|
||||
"reference": "a287ed7475f85bf6f61890146edbc932c0fff919"
|
||||
"reference": "59a8d271f00dd0e4c2e518104cc7963f655a1aa8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/a287ed7475f85bf6f61890146edbc932c0fff919",
|
||||
"reference": "a287ed7475f85bf6f61890146edbc932c0fff919",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/59a8d271f00dd0e4c2e518104cc7963f655a1aa8",
|
||||
"reference": "59a8d271f00dd0e4c2e518104cc7963f655a1aa8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -795,6 +499,9 @@
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.26-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
@@ -837,7 +544,7 @@
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.29.0"
|
||||
"source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.26.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -853,20 +560,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-01-29T20:11:03+00:00"
|
||||
"time": "2022-05-24T11:49:31+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-intl-normalizer",
|
||||
"version": "v1.29.0",
|
||||
"version": "v1.30.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
|
||||
"reference": "bc45c394692b948b4d383a08d7753968bed9a83d"
|
||||
"reference": "a95281b0be0d9ab48050ebd988b967875cdb9fdb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d",
|
||||
"reference": "bc45c394692b948b4d383a08d7753968bed9a83d",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/a95281b0be0d9ab48050ebd988b967875cdb9fdb",
|
||||
"reference": "a95281b0be0d9ab48050ebd988b967875cdb9fdb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -918,7 +625,7 @@
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.29.0"
|
||||
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.30.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -934,20 +641,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-01-29T20:11:03+00:00"
|
||||
"time": "2024-05-31T15:07:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.29.0",
|
||||
"version": "v1.26.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||
"reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec"
|
||||
"reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
|
||||
"reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e",
|
||||
"reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -961,6 +668,9 @@
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.26-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
@@ -998,7 +708,7 @@
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0"
|
||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1014,79 +724,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-01-29T20:11:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/yaml",
|
||||
"version": "v6.4.8",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/yaml.git",
|
||||
"reference": "52903de178d542850f6f341ba92995d3d63e60c9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/52903de178d542850f6f341ba92995d3d63e60c9",
|
||||
"reference": "52903de178d542850f6f341ba92995d3d63e60c9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.1",
|
||||
"symfony/deprecation-contracts": "^2.5|^3",
|
||||
"symfony/polyfill-ctype": "^1.8"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/console": "<5.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/console": "^5.4|^6.0|^7.0"
|
||||
},
|
||||
"bin": [
|
||||
"Resources/bin/yaml-lint"
|
||||
],
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\Yaml\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Loads and dumps YAML files",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/yaml/tree/v6.4.8"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-05-31T14:49:08+00:00"
|
||||
"time": "2022-05-24T11:49:31+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
@@ -1096,7 +734,7 @@
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
"php": "~8.1.0 || ~8.2.0 || ~8.3.0",
|
||||
"php": ">=7.4.0 <8.2.0",
|
||||
"ext-simplexml": "*",
|
||||
"ext-ctype": "*",
|
||||
"ext-curl": "*",
|
||||
@@ -1111,7 +749,7 @@
|
||||
},
|
||||
"platform-dev": [],
|
||||
"platform-overrides": {
|
||||
"php": "8.1.0"
|
||||
"php": "7.4.0"
|
||||
},
|
||||
"plugin-api-version": "2.6.0"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
return [
|
||||
// cms classes
|
||||
'collection' => 'Kirby\Cms\Collection',
|
||||
'field' => 'Kirby\Cms\Field',
|
||||
'file' => 'Kirby\Cms\File',
|
||||
'files' => 'Kirby\Cms\Files',
|
||||
'find' => 'Kirby\Cms\Find',
|
||||
@@ -23,9 +24,6 @@ return [
|
||||
'users' => 'Kirby\Cms\Users',
|
||||
'visitor' => 'Kirby\Cms\Visitor',
|
||||
|
||||
// content classes
|
||||
'field' => 'Kirby\Content\Field',
|
||||
|
||||
// data handler
|
||||
'data' => 'Kirby\Data\Data',
|
||||
'json' => 'Kirby\Data\Json',
|
||||
@@ -48,6 +46,7 @@ return [
|
||||
'cookie' => 'Kirby\Http\Cookie',
|
||||
'header' => 'Kirby\Http\Header',
|
||||
'remote' => 'Kirby\Http\Remote',
|
||||
'server' => 'Kirby\Http\Server',
|
||||
|
||||
// image classes
|
||||
'dimensions' => 'Kirby\Image\Dimensions',
|
||||
@@ -55,10 +54,6 @@ return [
|
||||
// panel classes
|
||||
'panel' => 'Kirby\Panel\Panel',
|
||||
|
||||
// template classes
|
||||
'snippet' => 'Kirby\Template\Snippet',
|
||||
'slot' => 'Kirby\Template\Slot',
|
||||
|
||||
// toolkit classes
|
||||
'a' => 'Kirby\Toolkit\A',
|
||||
'c' => 'Kirby\Toolkit\Config',
|
||||
@@ -71,25 +66,16 @@ return [
|
||||
'v' => 'Kirby\Toolkit\V',
|
||||
'xml' => 'Kirby\Toolkit\Xml',
|
||||
|
||||
// Deprecated aliases:
|
||||
// Any of these might be removed at any point in the future
|
||||
'kirby\cms\asset' => 'Kirby\Filesystem\Asset',
|
||||
'kirby\cms\content' => 'Kirby\Content\Content',
|
||||
'kirby\cms\contenttranslation' => 'Kirby\Content\ContentTranslation',
|
||||
'kirby\cms\dir' => 'Kirby\Filesystem\Dir',
|
||||
'kirby\cms\filename' => 'Kirby\Filesystem\Filename',
|
||||
'kirby\cms\filefoundation' => 'Kirby\Filesystem\IsFile',
|
||||
'kirby\cms\field' => 'Kirby\Content\Field',
|
||||
'kirby\cms\form' => 'Kirby\Form\Form',
|
||||
'kirby\cms\kirbytag' => 'Kirby\Text\KirbyTag',
|
||||
'kirby\cms\kirbytags' => 'Kirby\Text\KirbyTags',
|
||||
'kirby\cms\template' => 'Kirby\Template\Template',
|
||||
'kirby\form\options' => 'Kirby\Option\Options',
|
||||
'kirby\form\optionsapi' => 'Kirby\Option\OptionsApi',
|
||||
'kirby\form\optionsquery' => 'Kirby\Option\OptionsQuery',
|
||||
'kirby\toolkit\dir' => 'Kirby\Filesystem\Dir',
|
||||
'kirby\toolkit\f' => 'Kirby\Filesystem\F',
|
||||
'kirby\toolkit\file' => 'Kirby\Filesystem\File',
|
||||
'kirby\toolkit\mime' => 'Kirby\Filesystem\Mime',
|
||||
'kirby\toolkit\query' => 'Kirby\Query\Query',
|
||||
// TODO: remove in 4.0.0
|
||||
'kirby\cms\asset' => 'Kirby\Filesystem\Asset',
|
||||
'kirby\cms\dir' => 'Kirby\Filesystem\Dir',
|
||||
'kirby\cms\filename' => 'Kirby\Filesystem\Filename',
|
||||
'kirby\cms\filefoundation' => 'Kirby\Filesystem\IsFile',
|
||||
'kirby\cms\form' => 'Kirby\Form\Form',
|
||||
'kirby\cms\kirbytag' => 'Kirby\Text\KirbyTag',
|
||||
'kirby\cms\kirbytags' => 'Kirby\Text\KirbyTags',
|
||||
'kirby\toolkit\dir' => 'Kirby\Filesystem\Dir',
|
||||
'kirby\toolkit\f' => 'Kirby\Filesystem\F',
|
||||
'kirby\toolkit\file' => 'Kirby\Filesystem\File',
|
||||
'kirby\toolkit\mime' => 'Kirby\Filesystem\Mime',
|
||||
];
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
use Kirby\Exception\AuthException;
|
||||
use Kirby\Exception\PermissionException;
|
||||
|
||||
return function () {
|
||||
$auth = $this->kirby()->auth();
|
||||
@@ -11,17 +11,17 @@ return function () {
|
||||
$auth->type($allowImpersonation) === 'session' &&
|
||||
$auth->csrf() === false
|
||||
) {
|
||||
throw new AuthException('Unauthenticated');
|
||||
throw new PermissionException('Unauthenticated');
|
||||
}
|
||||
|
||||
// get user from session or basic auth
|
||||
if ($user = $auth->user(null, $allowImpersonation)) {
|
||||
if ($user->role()->permissions()->for('access', 'panel') === false) {
|
||||
throw new AuthException(['key' => 'access.panel']);
|
||||
throw new PermissionException(['key' => 'access.panel']);
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
throw new AuthException('Unauthenticated');
|
||||
throw new PermissionException('Unauthenticated');
|
||||
};
|
||||
|
||||
@@ -3,14 +3,6 @@
|
||||
/**
|
||||
* Api Collection Definitions
|
||||
*/
|
||||
|
||||
use Kirby\Cms\Files;
|
||||
use Kirby\Cms\Languages;
|
||||
use Kirby\Cms\Pages;
|
||||
use Kirby\Cms\Roles;
|
||||
use Kirby\Cms\Translations;
|
||||
use Kirby\Cms\Users;
|
||||
|
||||
return [
|
||||
|
||||
/**
|
||||
@@ -18,7 +10,7 @@ return [
|
||||
*/
|
||||
'children' => [
|
||||
'model' => 'page',
|
||||
'type' => Pages::class,
|
||||
'type' => 'Kirby\Cms\Pages',
|
||||
'view' => 'compact'
|
||||
],
|
||||
|
||||
@@ -27,7 +19,7 @@ return [
|
||||
*/
|
||||
'files' => [
|
||||
'model' => 'file',
|
||||
'type' => Files::class,
|
||||
'type' => 'Kirby\Cms\Files'
|
||||
],
|
||||
|
||||
/**
|
||||
@@ -35,7 +27,7 @@ return [
|
||||
*/
|
||||
'languages' => [
|
||||
'model' => 'language',
|
||||
'type' => Languages::class,
|
||||
'type' => 'Kirby\Cms\Languages'
|
||||
],
|
||||
|
||||
/**
|
||||
@@ -43,7 +35,7 @@ return [
|
||||
*/
|
||||
'pages' => [
|
||||
'model' => 'page',
|
||||
'type' => Pages::class,
|
||||
'type' => 'Kirby\Cms\Pages',
|
||||
'view' => 'compact'
|
||||
],
|
||||
|
||||
@@ -52,7 +44,7 @@ return [
|
||||
*/
|
||||
'roles' => [
|
||||
'model' => 'role',
|
||||
'type' => Roles::class,
|
||||
'type' => 'Kirby\Cms\Roles',
|
||||
'view' => 'compact'
|
||||
],
|
||||
|
||||
@@ -61,7 +53,7 @@ return [
|
||||
*/
|
||||
'translations' => [
|
||||
'model' => 'translation',
|
||||
'type' => Translations::class,
|
||||
'type' => 'Kirby\Cms\Translations',
|
||||
'view' => 'compact'
|
||||
],
|
||||
|
||||
@@ -71,7 +63,7 @@ return [
|
||||
'users' => [
|
||||
'default' => fn () => $this->users(),
|
||||
'model' => 'user',
|
||||
'type' => Users::class,
|
||||
'type' => 'Kirby\Cms\Users',
|
||||
'view' => 'compact'
|
||||
]
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ return [
|
||||
'FileBlueprint' => include __DIR__ . '/models/FileBlueprint.php',
|
||||
'FileVersion' => include __DIR__ . '/models/FileVersion.php',
|
||||
'Language' => include __DIR__ . '/models/Language.php',
|
||||
'License' => include __DIR__ . '/models/License.php',
|
||||
'Page' => include __DIR__ . '/models/Page.php',
|
||||
'PageBlueprint' => include __DIR__ . '/models/PageBlueprint.php',
|
||||
'Role' => include __DIR__ . '/models/Role.php',
|
||||
|
||||
@@ -57,9 +57,8 @@ return [
|
||||
},
|
||||
'type' => fn (File $file) => $file->type(),
|
||||
'url' => fn (File $file) => $file->url(),
|
||||
'uuid' => fn (File $file) => $file->uuid()?->toString()
|
||||
],
|
||||
'type' => File::class,
|
||||
'type' => 'Kirby\Cms\File',
|
||||
'views' => [
|
||||
'default' => [
|
||||
'content',
|
||||
@@ -80,8 +79,7 @@ return [
|
||||
'size',
|
||||
'template',
|
||||
'type',
|
||||
'url',
|
||||
'uuid'
|
||||
'url'
|
||||
],
|
||||
'compact' => [
|
||||
'filename',
|
||||
@@ -89,7 +87,6 @@ return [
|
||||
'link',
|
||||
'type',
|
||||
'url',
|
||||
'uuid'
|
||||
],
|
||||
'panel' => [
|
||||
'blueprint',
|
||||
@@ -112,8 +109,7 @@ return [
|
||||
'prevWithTemplate' => 'compact',
|
||||
'template',
|
||||
'type',
|
||||
'url',
|
||||
'uuid'
|
||||
'url'
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
@@ -12,6 +12,7 @@ return [
|
||||
'tabs' => fn (FileBlueprint $blueprint) => $blueprint->tabs(),
|
||||
'title' => fn (FileBlueprint $blueprint) => $blueprint->title(),
|
||||
],
|
||||
'type' => FileBlueprint::class,
|
||||
'views' => [],
|
||||
'type' => 'Kirby\Cms\FileBlueprint',
|
||||
'views' => [
|
||||
],
|
||||
];
|
||||
|
||||
@@ -20,7 +20,7 @@ return [
|
||||
'type' => fn (FileVersion $file) => $file->type(),
|
||||
'url' => fn (FileVersion $file) => $file->url(),
|
||||
],
|
||||
'type' => FileVersion::class,
|
||||
'type' => 'Kirby\Cms\FileVersion',
|
||||
'views' => [
|
||||
'default' => [
|
||||
'dimensions',
|
||||
|
||||
@@ -15,7 +15,7 @@ return [
|
||||
'rules' => fn (Language $language) => $language->rules(),
|
||||
'url' => fn (Language $language) => $language->url(),
|
||||
],
|
||||
'type' => Language::class,
|
||||
'type' => 'Kirby\Cms\Language',
|
||||
'views' => [
|
||||
'default' => [
|
||||
'code',
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Kirby\Cms\License;
|
||||
|
||||
/**
|
||||
* Page
|
||||
*/
|
||||
return [
|
||||
'fields' => [
|
||||
'status' => fn (License $license) => $license->status()->value(),
|
||||
'code' => function (License $license) {
|
||||
return $this->kirby()->user()->isAdmin() ? $license->code() : $license->code(true);
|
||||
},
|
||||
'type' => fn (License $license) => $license->type()->label(),
|
||||
],
|
||||
'type' => License::class,
|
||||
];
|
||||
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
use Kirby\Cms\Helpers;
|
||||
use Kirby\Cms\Page;
|
||||
use Kirby\Form\Form;
|
||||
|
||||
@@ -20,34 +21,62 @@ return [
|
||||
'hasFiles' => fn (Page $page) => $page->hasFiles(),
|
||||
'id' => fn (Page $page) => $page->id(),
|
||||
'isSortable' => fn (Page $page) => $page->isSortable(),
|
||||
'num' => fn (Page $page) => $page->num(),
|
||||
'options' => fn (Page $page) => $page->panel()->options(['preview']),
|
||||
'panelImage' => fn (Page $page) => $page->panel()->image(),
|
||||
'parent' => fn (Page $page) => $page->parent(),
|
||||
'parents' => fn (Page $page) => $page->parents()->flip(),
|
||||
'previewUrl' => fn (Page $page) => $page->previewUrl(),
|
||||
'siblings' => function (Page $page) {
|
||||
/**
|
||||
* @deprecated 3.6.0
|
||||
* @todo Remove in 3.8.0
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
'next' => function (Page $page) {
|
||||
Helpers::deprecated('The API field page.next has been deprecated and will be removed in 3.8.0.');
|
||||
|
||||
return $page
|
||||
->nextAll()
|
||||
->filter('intendedTemplate', $page->intendedTemplate())
|
||||
->filter('status', $page->status())
|
||||
->filter('isReadable', true)
|
||||
->first();
|
||||
},
|
||||
'num' => fn (Page $page) => $page->num(),
|
||||
'options' => fn (Page $page) => $page->panel()->options(['preview']),
|
||||
'panelImage' => fn (Page $page) => $page->panel()->image(),
|
||||
'parent' => fn (Page $page) => $page->parent(),
|
||||
'parents' => fn (Page $page) => $page->parents()->flip(),
|
||||
/**
|
||||
* @deprecated 3.6.0
|
||||
* @todo Remove in 3.8.0
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
'prev' => function (Page $page) {
|
||||
Helpers::deprecated('The API field page.prev has been deprecated and will be removed in 3.8.0.');
|
||||
|
||||
return $page
|
||||
->prevAll()
|
||||
->filter('intendedTemplate', $page->intendedTemplate())
|
||||
->filter('status', $page->status())
|
||||
->filter('isReadable', true)
|
||||
->last();
|
||||
},
|
||||
'previewUrl' => fn (Page $page) => $page->previewUrl(),
|
||||
'siblings' => function (Page $page) {
|
||||
if ($page->isDraft() === true) {
|
||||
return $page->parentModel()->children()->not($page);
|
||||
} else {
|
||||
return $page->siblings();
|
||||
}
|
||||
|
||||
return $page->siblings();
|
||||
},
|
||||
'slug' => fn (Page $page) => $page->slug(),
|
||||
'status' => fn (Page $page) => $page->status(),
|
||||
'template' => fn (Page $page) => $page->intendedTemplate()->name(),
|
||||
'title' => fn (Page $page) => $page->title()->value(),
|
||||
'url' => fn (Page $page) => $page->url(),
|
||||
'uuid' => fn (Page $page) => $page->uuid()?->toString()
|
||||
],
|
||||
'type' => Page::class,
|
||||
'type' => 'Kirby\Cms\Page',
|
||||
'views' => [
|
||||
'compact' => [
|
||||
'id',
|
||||
'title',
|
||||
'url',
|
||||
'num',
|
||||
'uuid'
|
||||
'num'
|
||||
],
|
||||
'default' => [
|
||||
'content',
|
||||
@@ -59,8 +88,7 @@ return [
|
||||
'slug',
|
||||
'template',
|
||||
'title',
|
||||
'url',
|
||||
'uuid'
|
||||
'url'
|
||||
],
|
||||
'panel' => [
|
||||
'id',
|
||||
@@ -74,8 +102,7 @@ return [
|
||||
'previewUrl',
|
||||
'slug',
|
||||
'title',
|
||||
'url',
|
||||
'uuid'
|
||||
'url'
|
||||
],
|
||||
'selector' => [
|
||||
'id',
|
||||
|
||||
@@ -15,6 +15,7 @@ return [
|
||||
'tabs' => fn (PageBlueprint $blueprint) => $blueprint->tabs(),
|
||||
'title' => fn (PageBlueprint $blueprint) => $blueprint->title(),
|
||||
],
|
||||
'type' => PageBlueprint::class,
|
||||
'views' => [],
|
||||
'type' => 'Kirby\Cms\PageBlueprint',
|
||||
'views' => [
|
||||
],
|
||||
];
|
||||
|
||||
@@ -12,7 +12,7 @@ return [
|
||||
'permissions' => fn (Role $role) => $role->permissions()->toArray(),
|
||||
'title' => fn (Role $role) => $role->title(),
|
||||
],
|
||||
'type' => Role::class,
|
||||
'type' => 'Kirby\Cms\Role',
|
||||
'views' => [
|
||||
'compact' => [
|
||||
'description',
|
||||
|
||||
@@ -19,7 +19,7 @@ return [
|
||||
'title' => fn (Site $site) => $site->title()->value(),
|
||||
'url' => fn (Site $site) => $site->url(),
|
||||
],
|
||||
'type' => Site::class,
|
||||
'type' => 'Kirby\Cms\Site',
|
||||
'views' => [
|
||||
'compact' => [
|
||||
'title',
|
||||
|
||||
@@ -12,6 +12,6 @@ return [
|
||||
'tabs' => fn (SiteBlueprint $blueprint) => $blueprint->tabs(),
|
||||
'title' => fn (SiteBlueprint $blueprint) => $blueprint->title(),
|
||||
],
|
||||
'type' => SiteBlueprint::class,
|
||||
'type' => 'Kirby\Cms\SiteBlueprint',
|
||||
'views' => [],
|
||||
];
|
||||
|
||||
@@ -32,24 +32,31 @@ return [
|
||||
'slugs' => fn () => Str::$language,
|
||||
'title' => fn () => $this->site()->title()->value(),
|
||||
'translation' => function () {
|
||||
$code = $this->user()?->language() ??
|
||||
$this->kirby()->panelLanguage();
|
||||
if ($user = $this->user()) {
|
||||
$translationCode = $user->language();
|
||||
} else {
|
||||
$translationCode = $this->kirby()->panelLanguage();
|
||||
}
|
||||
|
||||
return
|
||||
$this->kirby()->translation($code) ??
|
||||
$this->kirby()->translation('en');
|
||||
if ($translation = $this->kirby()->translation($translationCode)) {
|
||||
return $translation;
|
||||
} else {
|
||||
return $this->kirby()->translation('en');
|
||||
}
|
||||
},
|
||||
'kirbytext' => fn () => $this->kirby()->option('panel.kirbytext') ?? true,
|
||||
'user' => fn () => $this->user(),
|
||||
'version' => function () {
|
||||
if ($this->user()?->role()->permissions()->for('access', 'system') === true) {
|
||||
return $this->kirby()->version();
|
||||
}
|
||||
$user = $this->user();
|
||||
|
||||
return null;
|
||||
if ($user && $user->role()->permissions()->for('access', 'system') === true) {
|
||||
return $this->kirby()->version();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
],
|
||||
'type' => System::class,
|
||||
'type' => 'Kirby\Cms\System',
|
||||
'views' => [
|
||||
'login' => [
|
||||
'authStatus',
|
||||
|
||||
@@ -13,7 +13,7 @@ return [
|
||||
'id' => fn (Translation $translation) => $translation->id(),
|
||||
'name' => fn (Translation $translation) => $translation->name(),
|
||||
],
|
||||
'type' => Translation::class,
|
||||
'type' => 'Kirby\Cms\Translation',
|
||||
'views' => [
|
||||
'compact' => [
|
||||
'direction',
|
||||
|
||||
@@ -9,7 +9,7 @@ use Kirby\Form\Form;
|
||||
return [
|
||||
'default' => fn () => $this->user(),
|
||||
'fields' => [
|
||||
'avatar' => fn (User $user) => $user->avatar()?->crop(512),
|
||||
'avatar' => fn (User $user) => $user->avatar() ? $user->avatar()->crop(512) : null,
|
||||
'blueprint' => fn (User $user) => $user->blueprint(),
|
||||
'content' => fn (User $user) => Form::for($user)->values(),
|
||||
'email' => fn (User $user) => $user->email(),
|
||||
@@ -24,10 +24,9 @@ return [
|
||||
'prev' => fn (User $user) => $user->prev(),
|
||||
'role' => fn (User $user) => $user->role(),
|
||||
'roles' => fn (User $user) => $user->roles(),
|
||||
'username' => fn (User $user) => $user->username(),
|
||||
'uuid' => fn (User $user) => $user->uuid()?->toString()
|
||||
'username' => fn (User $user) => $user->username()
|
||||
],
|
||||
'type' => User::class,
|
||||
'type' => 'Kirby\Cms\User',
|
||||
'views' => [
|
||||
'default' => [
|
||||
'avatar',
|
||||
@@ -40,8 +39,7 @@ return [
|
||||
'options',
|
||||
'prev' => 'compact',
|
||||
'role',
|
||||
'username',
|
||||
'uuid'
|
||||
'username'
|
||||
],
|
||||
'compact' => [
|
||||
'avatar' => 'compact',
|
||||
@@ -50,8 +48,7 @@ return [
|
||||
'language',
|
||||
'name',
|
||||
'role' => 'compact',
|
||||
'username',
|
||||
'uuid'
|
||||
'username'
|
||||
],
|
||||
'auth' => [
|
||||
'avatar' => 'compact',
|
||||
@@ -75,7 +72,6 @@ return [
|
||||
'prev' => ['id', 'name'],
|
||||
'role',
|
||||
'username',
|
||||
'uuid'
|
||||
],
|
||||
]
|
||||
];
|
||||
|
||||
@@ -12,6 +12,7 @@ return [
|
||||
'tabs' => fn (UserBlueprint $blueprint) => $blueprint->tabs(),
|
||||
'title' => fn (UserBlueprint $blueprint) => $blueprint->title(),
|
||||
],
|
||||
'type' => UserBlueprint::class,
|
||||
'views' => [],
|
||||
'type' => 'Kirby\Cms\UserBlueprint',
|
||||
'views' => [
|
||||
],
|
||||
];
|
||||
|
||||
@@ -19,10 +19,7 @@ return function ($kirby) {
|
||||
// only add the language routes if the
|
||||
// multi language setup is activated
|
||||
if ($kirby->option('languages', false) !== false) {
|
||||
$routes = array_merge(
|
||||
$routes,
|
||||
include __DIR__ . '/routes/languages.php'
|
||||
);
|
||||
$routes = array_merge($routes, include __DIR__ . '/routes/languages.php');
|
||||
}
|
||||
|
||||
return $routes;
|
||||
|
||||
@@ -70,11 +70,13 @@ return [
|
||||
$user = $auth->login($email, $password, $long);
|
||||
}
|
||||
} else {
|
||||
$mode = match (true) {
|
||||
isset($methods['code']) => 'login',
|
||||
isset($methods['password-reset']) => 'password-reset',
|
||||
default => throw new InvalidArgumentException('Login without password is not enabled')
|
||||
};
|
||||
if (isset($methods['code']) === true) {
|
||||
$mode = 'login';
|
||||
} elseif (isset($methods['password-reset']) === true) {
|
||||
$mode = 'password-reset';
|
||||
} else {
|
||||
throw new InvalidArgumentException('Login without password is not enabled');
|
||||
}
|
||||
|
||||
$status = $auth->createChallenge($email, $long, $mode);
|
||||
}
|
||||
@@ -85,13 +87,13 @@ return [
|
||||
'status' => 'ok',
|
||||
'user' => $this->resolve($user)->view('auth')->toArray()
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
'code' => 200,
|
||||
'status' => 'ok',
|
||||
'challenge' => $status->challenge()
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'code' => 200,
|
||||
'status' => 'ok',
|
||||
'challenge' => $status->challenge()
|
||||
];
|
||||
}
|
||||
],
|
||||
[
|
||||
@@ -103,14 +105,4 @@ return [
|
||||
return true;
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'auth/ping',
|
||||
'method' => 'POST',
|
||||
'auth' => false,
|
||||
'action' => function () {
|
||||
// refresh the session timeout
|
||||
$this->kirby()->session();
|
||||
return true;
|
||||
}
|
||||
],
|
||||
];
|
||||
|
||||
@@ -1,148 +1,132 @@
|
||||
<?php
|
||||
|
||||
// routing pattern to match all models with files
|
||||
$filePattern = '(account/|pages/[^/]+/|site/|users/[^/]+/|)files/(:any)';
|
||||
$parentPattern = '(account|pages/[^/]+|site|users/[^/]+)/files';
|
||||
$pattern = '(account|pages/[^/]+|site|users/[^/]+)';
|
||||
|
||||
/**
|
||||
* Files Routes
|
||||
*/
|
||||
return [
|
||||
|
||||
[
|
||||
'pattern' => $filePattern . '/fields/(:any)/(:all?)',
|
||||
'pattern' => $pattern . '/files/(:any)/sections/(:any)',
|
||||
'method' => 'GET',
|
||||
'action' => function (string $path, string $filename, string $sectionName) {
|
||||
if ($section = $this->file($path, $filename)->blueprint()->section($sectionName)) {
|
||||
return $section->toResponse();
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => $pattern . '/files/(:any)/fields/(:any)/(:all?)',
|
||||
'method' => 'ALL',
|
||||
'action' => function (string $parent, string $filename, string $fieldName, string|null $path = null) {
|
||||
'action' => function (string $parent, string $filename, string $fieldName, string $path = null) {
|
||||
if ($file = $this->file($parent, $filename)) {
|
||||
return $this->fieldApi($file, $fieldName, $path);
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => $filePattern . '/sections/(:any)',
|
||||
'method' => 'GET',
|
||||
'action' => function (string $path, string $filename, string $sectionName) {
|
||||
return $this->file($path, $filename)->blueprint()->section($sectionName)?->toResponse();
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => $filePattern . '/sections/(:any)/(:all?)',
|
||||
'method' => 'ALL',
|
||||
'action' => function (string $parent, string $filename, string $sectionName, string|null $path = null) {
|
||||
if ($file = $this->file($parent, $filename)) {
|
||||
return $this->sectionApi($file, $sectionName, $path);
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => $parentPattern,
|
||||
'pattern' => $pattern . '/files',
|
||||
'method' => 'GET',
|
||||
'action' => function (string $path) {
|
||||
return $this->files($path)->sorted();
|
||||
return $this->parent($path)->files()->sorted();
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => $parentPattern,
|
||||
'pattern' => $pattern . '/files',
|
||||
'method' => 'POST',
|
||||
'action' => function (string $path) {
|
||||
// move_uploaded_file() not working with unit test
|
||||
// @codeCoverageIgnoreStart
|
||||
return $this->upload(function ($source, $filename) use ($path) {
|
||||
$props = [
|
||||
return $this->parent($path)->createFile([
|
||||
'content' => [
|
||||
'sort' => $this->requestBody('sort')
|
||||
],
|
||||
'source' => $source,
|
||||
'template' => $this->requestBody('template'),
|
||||
'filename' => $filename
|
||||
];
|
||||
|
||||
// move the source file from the temp dir
|
||||
return $this->parent($path)->createFile($props, true);
|
||||
]);
|
||||
});
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => $parentPattern . '/search',
|
||||
'pattern' => $pattern . '/files/search',
|
||||
'method' => 'GET|POST',
|
||||
'action' => function (string $path) {
|
||||
$files = $this->files($path);
|
||||
$files = $this->parent($path)->files();
|
||||
|
||||
if ($this->requestMethod() === 'GET') {
|
||||
return $files->search($this->requestQuery('q'));
|
||||
} else {
|
||||
return $files->query($this->requestBody());
|
||||
}
|
||||
|
||||
return $files->query($this->requestBody());
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => $parentPattern . '/sort',
|
||||
'pattern' => $pattern . '/files/sort',
|
||||
'method' => 'PATCH',
|
||||
'action' => function (string $path) {
|
||||
return $this->files($path)->changeSort(
|
||||
return $this->parent($path)->files()->changeSort(
|
||||
$this->requestBody('files'),
|
||||
$this->requestBody('index')
|
||||
);
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => $filePattern,
|
||||
'pattern' => $pattern . '/files/(:any)',
|
||||
'method' => 'GET',
|
||||
'action' => function (string $path, string $filename) {
|
||||
return $this->file($path, $filename);
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => $filePattern,
|
||||
'pattern' => $pattern . '/files/(:any)',
|
||||
'method' => 'PATCH',
|
||||
'action' => function (string $path, string $filename) {
|
||||
return $this->file($path, $filename)->update(
|
||||
$this->requestBody(),
|
||||
$this->language(),
|
||||
true
|
||||
);
|
||||
return $this->file($path, $filename)->update($this->requestBody(), $this->language(), true);
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => $filePattern,
|
||||
'pattern' => $pattern . '/files/(:any)',
|
||||
'method' => 'POST',
|
||||
'action' => function (string $path, string $filename) {
|
||||
// move the source file from the temp dir
|
||||
return $this->upload(
|
||||
fn ($source) => $this->file($path, $filename)->replace($source, true)
|
||||
);
|
||||
return $this->upload(function ($source) use ($path, $filename) {
|
||||
return $this->file($path, $filename)->replace($source);
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => $filePattern,
|
||||
'pattern' => $pattern . '/files/(:any)',
|
||||
'method' => 'DELETE',
|
||||
'action' => function (string $path, string $filename) {
|
||||
return $this->file($path, $filename)->delete();
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => $filePattern . '/name',
|
||||
'pattern' => $pattern . '/files/(:any)/name',
|
||||
'method' => 'PATCH',
|
||||
'action' => function (string $path, string $filename) {
|
||||
return $this->file($path, $filename)->changeName($this->requestBody('name'));
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => $parentPattern . '/search',
|
||||
'pattern' => 'files/search',
|
||||
'method' => 'GET|POST',
|
||||
'action' => function () {
|
||||
$files = $this
|
||||
->site()
|
||||
->index(true)
|
||||
->filter('isListable', true)
|
||||
->files()
|
||||
->filter('isListable', true);
|
||||
->filter('isReadable', true)
|
||||
->files();
|
||||
|
||||
if ($this->requestMethod() === 'GET') {
|
||||
return $files->search($this->requestQuery('q'));
|
||||
} else {
|
||||
return $files->query($this->requestBody());
|
||||
}
|
||||
|
||||
return $files->query($this->requestBody());
|
||||
}
|
||||
],
|
||||
];
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
<?php
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
return [
|
||||
'routes' => function ($kirby) {
|
||||
return [
|
||||
[
|
||||
'pattern' => 'query',
|
||||
'method' => 'POST|GET',
|
||||
'auth' => $kirby->option('kql.auth') !== false,
|
||||
'action' => function () use ($kirby) {
|
||||
$kql = '\Kirby\Kql\Kql';
|
||||
|
||||
if (class_exists($kql) === false) {
|
||||
return [
|
||||
'code' => 500,
|
||||
'status' => 'error',
|
||||
'message' => 'KQL plugin is not installed',
|
||||
];
|
||||
}
|
||||
|
||||
$input = $kirby->request()->get();
|
||||
$result = $kql::run($input);
|
||||
|
||||
return [
|
||||
'code' => 200,
|
||||
'result' => $result,
|
||||
'status' => 'ok',
|
||||
];
|
||||
}
|
||||
]
|
||||
];
|
||||
}
|
||||
];
|
||||
// @codeCoverageIgnoreEnd
|
||||
@@ -29,14 +29,18 @@ return [
|
||||
'pattern' => 'languages/(:any)',
|
||||
'method' => 'PATCH',
|
||||
'action' => function (string $code) {
|
||||
return $this->kirby()->languages()->find($code)?->update($this->requestBody());
|
||||
if ($language = $this->kirby()->languages()->find($code)) {
|
||||
return $language->update($this->requestBody());
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'languages/(:any)',
|
||||
'method' => 'DELETE',
|
||||
'action' => function (string $code) {
|
||||
return $this->kirby()->languages()->find($code)?->delete();
|
||||
if ($language = $this->kirby()->languages()->find($code)) {
|
||||
return $language->delete();
|
||||
}
|
||||
}
|
||||
]
|
||||
];
|
||||
|
||||
@@ -4,34 +4,22 @@
|
||||
/**
|
||||
* Content Lock Routes
|
||||
*/
|
||||
|
||||
use Kirby\Exception\NotFoundException;
|
||||
|
||||
return [
|
||||
[
|
||||
'pattern' => '(:all)/lock',
|
||||
'method' => 'GET',
|
||||
'action' => function (string $path) {
|
||||
return [
|
||||
'lock' => $this->parent($path)->lock()?->toArray() ?? false
|
||||
];
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => '(:all)/lock',
|
||||
'method' => 'PATCH',
|
||||
'action' => function (string $path) {
|
||||
return $this->parent($path)->lock()?->create();
|
||||
if ($lock = $this->parent($path)->lock()) {
|
||||
return $lock->create();
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => '(:all)/lock',
|
||||
'method' => 'DELETE',
|
||||
'action' => function (string $path) {
|
||||
try {
|
||||
return $this->parent($path)->lock()?->remove();
|
||||
} catch (NotFoundException) {
|
||||
return true;
|
||||
if ($lock = $this->parent($path)->lock()) {
|
||||
return $lock->remove();
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -39,17 +27,17 @@ return [
|
||||
'pattern' => '(:all)/unlock',
|
||||
'method' => 'PATCH',
|
||||
'action' => function (string $path) {
|
||||
return $this->parent($path)->lock()?->unlock();
|
||||
if ($lock = $this->parent($path)->lock()) {
|
||||
return $lock->unlock();
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => '(:all)/unlock',
|
||||
'method' => 'DELETE',
|
||||
'action' => function (string $path) {
|
||||
try {
|
||||
return $this->parent($path)->lock()?->resolve();
|
||||
} catch (NotFoundException) {
|
||||
return true;
|
||||
if ($lock = $this->parent($path)->lock()) {
|
||||
return $lock->resolve();
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Page Routes
|
||||
*/
|
||||
return [
|
||||
// @codeCoverageIgnoreStart
|
||||
|
||||
[
|
||||
'pattern' => 'pages/(:any)',
|
||||
'method' => 'GET',
|
||||
@@ -100,30 +100,22 @@ return [
|
||||
return $this->page($id)->changeTitle($this->requestBody('title'));
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'pages/(:any)/sections/(:any)',
|
||||
'method' => 'GET',
|
||||
'action' => function (string $id, string $sectionName) {
|
||||
if ($section = $this->page($id)->blueprint()->section($sectionName)) {
|
||||
return $section->toResponse();
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'pages/(:any)/fields/(:any)/(:all?)',
|
||||
'method' => 'ALL',
|
||||
'action' => function (string $id, string $fieldName, string|null $path = null) {
|
||||
'action' => function (string $id, string $fieldName, string $path = null) {
|
||||
if ($page = $this->page($id)) {
|
||||
return $this->fieldApi($page, $fieldName, $path);
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'pages/(:any)/sections/(:any)',
|
||||
'method' => 'GET',
|
||||
'action' => function (string $id, string $sectionName) {
|
||||
return $this->page($id)->blueprint()->section($sectionName)?->toResponse();
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'pages/(:any)/sections/(:any)/(:all?)',
|
||||
'method' => 'ALL',
|
||||
'action' => function (string $id, string $sectionName, string|null $path = null) {
|
||||
if ($page = $this->page($id)) {
|
||||
return $this->sectionApi($page, $sectionName, $path);
|
||||
}
|
||||
}
|
||||
],
|
||||
// @codeCoverageIgnoreEnd
|
||||
];
|
||||
|
||||
@@ -10,11 +10,14 @@ return [
|
||||
'action' => function () {
|
||||
$kirby = $this->kirby();
|
||||
|
||||
return match ($kirby->request()->get('canBe')) {
|
||||
'changed' => $kirby->roles()->canBeChanged(),
|
||||
'created' => $kirby->roles()->canBeCreated(),
|
||||
default => $kirby->roles()
|
||||
};
|
||||
switch ($kirby->request()->get('canBe')) {
|
||||
case 'changed':
|
||||
return $kirby->roles()->canBeChanged();
|
||||
case 'created':
|
||||
return $kirby->roles()->canBeCreated();
|
||||
default:
|
||||
return $kirby->roles();
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Site Routes
|
||||
*/
|
||||
return [
|
||||
// @codeCoverageIgnoreStart
|
||||
|
||||
[
|
||||
'pattern' => 'site',
|
||||
'action' => function () {
|
||||
@@ -75,35 +75,30 @@ return [
|
||||
$pages = $this
|
||||
->site()
|
||||
->index(true)
|
||||
->filter('isListable', true);
|
||||
->filter('isReadable', true);
|
||||
|
||||
if ($this->requestMethod() === 'GET') {
|
||||
return $pages->search($this->requestQuery('q'));
|
||||
} else {
|
||||
return $pages->query($this->requestBody());
|
||||
}
|
||||
|
||||
return $pages->query($this->requestBody());
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'site/fields/(:any)/(:all?)',
|
||||
'method' => 'ALL',
|
||||
'action' => function (string $fieldName, string|null $path = null) {
|
||||
return $this->fieldApi($this->site(), $fieldName, $path);
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'site/sections/(:any)',
|
||||
'method' => 'GET',
|
||||
'action' => function (string $sectionName) {
|
||||
return $this->site()->blueprint()->section($sectionName)?->toResponse();
|
||||
if ($section = $this->site()->blueprint()->section($sectionName)) {
|
||||
return $section->toResponse();
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'site/sections/(:any)/(:all?)',
|
||||
'pattern' => 'site/fields/(:any)/(:all?)',
|
||||
'method' => 'ALL',
|
||||
'action' => function (string $sectionName, string|null $path = null) {
|
||||
return $this->sectionApi($this->site(), $sectionName, $path);
|
||||
'action' => function (string $fieldName, string $path = null) {
|
||||
return $this->fieldApi($this->site(), $fieldName, $path);
|
||||
}
|
||||
],
|
||||
// @codeCoverageIgnoreEnd
|
||||
]
|
||||
|
||||
];
|
||||
|
||||
@@ -17,18 +17,19 @@ return [
|
||||
|
||||
if ($this->kirby()->user()) {
|
||||
return $system;
|
||||
} else {
|
||||
if ($system->isOk() === true) {
|
||||
$info = $this->resolve($system)->view('login')->toArray();
|
||||
} else {
|
||||
$info = $this->resolve($system)->view('troubleshooting')->toArray();
|
||||
}
|
||||
|
||||
return [
|
||||
'status' => 'ok',
|
||||
'data' => $info,
|
||||
'type' => 'model'
|
||||
];
|
||||
}
|
||||
|
||||
$info = match ($system->isOk()) {
|
||||
true => $this->resolve($system)->view('login')->toArray(),
|
||||
false => $this->resolve($system)->view('troubleshooting')->toArray()
|
||||
};
|
||||
|
||||
return [
|
||||
'status' => 'ok',
|
||||
'data' => $info,
|
||||
'type' => 'model'
|
||||
];
|
||||
}
|
||||
],
|
||||
[
|
||||
|
||||
@@ -8,7 +8,6 @@ use Kirby\Toolkit\Str;
|
||||
* User Routes
|
||||
*/
|
||||
return [
|
||||
// @codeCoverageIgnoreStart
|
||||
[
|
||||
'pattern' => 'users',
|
||||
'method' => 'GET',
|
||||
@@ -29,9 +28,9 @@ return [
|
||||
'action' => function () {
|
||||
if ($this->requestMethod() === 'GET') {
|
||||
return $this->users()->search($this->requestQuery('q'));
|
||||
} else {
|
||||
return $this->users()->query($this->requestBody());
|
||||
}
|
||||
|
||||
return $this->users()->query($this->requestBody());
|
||||
}
|
||||
],
|
||||
[
|
||||
@@ -101,18 +100,17 @@ return [
|
||||
}
|
||||
|
||||
// delete the old avatar
|
||||
$this->user($id)->avatar()?->delete();
|
||||
if ($avatar = $this->user($id)->avatar()) {
|
||||
$avatar->delete();
|
||||
}
|
||||
|
||||
$props = [
|
||||
return $this->user($id)->createFile([
|
||||
'filename' => 'profile.' . F::extension($filename),
|
||||
'template' => 'avatar',
|
||||
'source' => $source
|
||||
];
|
||||
|
||||
// move the source file from the temp dir
|
||||
return $this->user($id)->createFile($props, true);
|
||||
]);
|
||||
},
|
||||
single: true
|
||||
$single = true
|
||||
);
|
||||
}
|
||||
],
|
||||
@@ -206,16 +204,6 @@ return [
|
||||
return $this->user($id)->roles();
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => [
|
||||
'(account)/fields/(:any)/(:all?)',
|
||||
'users/(:any)/fields/(:any)/(:all?)',
|
||||
],
|
||||
'method' => 'ALL',
|
||||
'action' => function (string $id, string $fieldName, string|null $path = null) {
|
||||
return $this->fieldApi($this->user($id), $fieldName, $path);
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => [
|
||||
'(account)/sections/(:any)',
|
||||
@@ -230,13 +218,12 @@ return [
|
||||
],
|
||||
[
|
||||
'pattern' => [
|
||||
'(account)/sections/(:any)/(:all?)',
|
||||
'users/(:any)/sections/(:any)/(:all?)',
|
||||
'(account)/fields/(:any)/(:all?)',
|
||||
'users/(:any)/fields/(:any)/(:all?)',
|
||||
],
|
||||
'method' => 'ALL',
|
||||
'action' => function (string $id, string $sectionName, string|null $path = null) {
|
||||
return $this->sectionApi($this->user($id), $sectionName, $path);
|
||||
'action' => function (string $id, string $fieldName, string $path = null) {
|
||||
return $this->fieldApi($this->user($id), $fieldName, $path);
|
||||
}
|
||||
],
|
||||
// @codeCoverageIgnoreEnd
|
||||
];
|
||||
|
||||
@@ -8,7 +8,6 @@ return function () {
|
||||
'label' => I18n::translate('view.account'),
|
||||
'search' => 'users',
|
||||
'dialogs' => require __DIR__ . '/account/dialogs.php',
|
||||
'drawers' => require __DIR__ . '/account/drawers.php',
|
||||
'dropdowns' => require __DIR__ . '/account/dropdowns.php',
|
||||
'views' => require __DIR__ . '/account/views.php'
|
||||
];
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<?php
|
||||
|
||||
use Kirby\Panel\UserTotpEnableDialog;
|
||||
|
||||
$dialogs = require __DIR__ . '/../users/dialogs.php';
|
||||
|
||||
return [
|
||||
@@ -48,13 +46,6 @@ return [
|
||||
'submit' => $dialogs['user.delete']['submit'],
|
||||
],
|
||||
|
||||
// account fields dialogs
|
||||
'account.fields' => [
|
||||
'pattern' => '(account)/files/(:any)/fields/(:any)/(:all?)',
|
||||
'load' => $dialogs['user.fields']['load'],
|
||||
'submit' => $dialogs['user.fields']['submit']
|
||||
],
|
||||
|
||||
// change file name
|
||||
'account.file.changeName' => [
|
||||
'pattern' => '(account)/files/(:any)/changeName',
|
||||
@@ -69,13 +60,6 @@ return [
|
||||
'submit' => $dialogs['user.file.changeSort']['submit'],
|
||||
],
|
||||
|
||||
// change file template
|
||||
'account.file.changeTemplate' => [
|
||||
'pattern' => '(account)/files/(:any)/changeTemplate',
|
||||
'load' => $dialogs['user.file.changeTemplate']['load'],
|
||||
'submit' => $dialogs['user.file.changeTemplate']['submit'],
|
||||
],
|
||||
|
||||
// delete
|
||||
'account.file.delete' => [
|
||||
'pattern' => '(account)/files/(:any)/delete',
|
||||
@@ -83,24 +67,4 @@ return [
|
||||
'submit' => $dialogs['user.file.delete']['submit'],
|
||||
],
|
||||
|
||||
// account file fields dialogs
|
||||
'account.file.fields' => [
|
||||
'pattern' => '(account)/files/(:any)/fields/(:any)/(:all?)',
|
||||
'load' => $dialogs['user.file.fields']['load'],
|
||||
'submit' => $dialogs['user.file.fields']['submit']
|
||||
],
|
||||
|
||||
// account enable TOTP
|
||||
'account.totp.enable' => [
|
||||
'pattern' => '(account)/totp/enable',
|
||||
'load' => fn () => (new UserTotpEnableDialog())->load(),
|
||||
'submit' => fn () => (new UserTotpEnableDialog())->submit()
|
||||
],
|
||||
|
||||
// account disable TOTP
|
||||
'account.totp.disable' => [
|
||||
'pattern' => '(account)/totp/disable',
|
||||
'load' => $dialogs['user.totp.disable']['load'],
|
||||
'submit' => $dialogs['user.totp.disable']['submit']
|
||||
],
|
||||
];
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
$drawers = require __DIR__ . '/../users/drawers.php';
|
||||
|
||||
return [
|
||||
// account fields drawers
|
||||
'account.fields' => [
|
||||
'pattern' => '(account)/files/(:any)/fields/(:any)/(:all?)',
|
||||
'load' => $drawers['user.fields']['load'],
|
||||
'submit' => $drawers['user.fields']['submit']
|
||||
],
|
||||
|
||||
// account file fields drawers
|
||||
'account.file.fields' => [
|
||||
'pattern' => '(account)/files/(:any)/fields/(:any)/(:all?)',
|
||||
'load' => $drawers['user.file.fields']['load'],
|
||||
'submit' => $drawers['user.file.fields']['submit']
|
||||
],
|
||||
];
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
use Kirby\Cms\App;
|
||||
use Kirby\Cms\Find;
|
||||
use Kirby\Toolkit\I18n;
|
||||
|
||||
return [
|
||||
'account' => [
|
||||
@@ -20,13 +19,6 @@ return [
|
||||
],
|
||||
'account.password' => [
|
||||
'pattern' => 'reset-password',
|
||||
'action' => fn () => [
|
||||
'component' => 'k-reset-password-view',
|
||||
'breadcrumb' => [
|
||||
[
|
||||
'label' => I18n::translate('view.resetPassword')
|
||||
]
|
||||
]
|
||||
]
|
||||
'action' => fn () => ['component' => 'k-reset-password-view']
|
||||
]
|
||||
];
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Kirby\Cms\Find;
|
||||
use Kirby\Panel\Field;
|
||||
|
||||
return [
|
||||
'model' => [
|
||||
'load' => function (
|
||||
string $modelPath,
|
||||
string $fieldName,
|
||||
string|null $path = null
|
||||
) {
|
||||
return Field::dialog(
|
||||
model: Find::parent($modelPath),
|
||||
fieldName: $fieldName,
|
||||
path: $path,
|
||||
method: 'GET'
|
||||
);
|
||||
},
|
||||
'submit' => function (
|
||||
string $modelPath,
|
||||
string $fieldName,
|
||||
string|null $path = null
|
||||
) {
|
||||
return Field::dialog(
|
||||
model: Find::parent($modelPath),
|
||||
fieldName: $fieldName,
|
||||
path: $path,
|
||||
method: 'POST'
|
||||
);
|
||||
}
|
||||
],
|
||||
'file' => [
|
||||
'load' => function (
|
||||
string $modelPath,
|
||||
string $filename,
|
||||
string $fieldName,
|
||||
string|null $path = null
|
||||
) {
|
||||
return Field::dialog(
|
||||
model: Find::file($modelPath, $filename),
|
||||
fieldName: $fieldName,
|
||||
path: $path,
|
||||
method: 'GET'
|
||||
);
|
||||
},
|
||||
'submit' => function (
|
||||
string $modelPath,
|
||||
string $filename,
|
||||
string $fieldName,
|
||||
string|null $path = null
|
||||
) {
|
||||
return Field::dialog(
|
||||
model: Find::file($modelPath, $filename),
|
||||
fieldName: $fieldName,
|
||||
path: $path,
|
||||
method: 'POST'
|
||||
);
|
||||
}
|
||||
],
|
||||
];
|
||||
@@ -1,61 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Kirby\Cms\Find;
|
||||
use Kirby\Panel\Field;
|
||||
|
||||
return [
|
||||
'model' => [
|
||||
'load' => function (
|
||||
string $modelPath,
|
||||
string $fieldName,
|
||||
string|null $path = null
|
||||
) {
|
||||
return Field::drawer(
|
||||
model: Find::parent($modelPath),
|
||||
fieldName: $fieldName,
|
||||
path: $path,
|
||||
method: 'GET'
|
||||
);
|
||||
},
|
||||
'submit' => function (
|
||||
string $modelPath,
|
||||
string $fieldName,
|
||||
string|null $path = null
|
||||
) {
|
||||
return Field::drawer(
|
||||
model: Find::parent($modelPath),
|
||||
fieldName: $fieldName,
|
||||
path: $path,
|
||||
method: 'POST'
|
||||
);
|
||||
}
|
||||
],
|
||||
'file' => [
|
||||
'load' => function (
|
||||
string $modelPath,
|
||||
string $filename,
|
||||
string $fieldName,
|
||||
string|null $path = null
|
||||
) {
|
||||
return Field::drawer(
|
||||
model: Find::file($modelPath, $filename),
|
||||
fieldName: $fieldName,
|
||||
path: $path,
|
||||
method: 'GET'
|
||||
);
|
||||
},
|
||||
'submit' => function (
|
||||
string $modelPath,
|
||||
string $filename,
|
||||
string $fieldName,
|
||||
string|null $path = null
|
||||
) {
|
||||
return Field::drawer(
|
||||
model: Find::file($modelPath, $filename),
|
||||
fieldName: $fieldName,
|
||||
path: $path,
|
||||
method: 'POST'
|
||||
);
|
||||
}
|
||||
],
|
||||
];
|
||||
@@ -26,7 +26,7 @@ return [
|
||||
'type' => 'slug',
|
||||
'required' => true,
|
||||
'icon' => 'title',
|
||||
'allow' => 'a-z0-9@._-',
|
||||
'allow' => '@._-',
|
||||
'after' => '.' . $file->extension(),
|
||||
'preselect' => true
|
||||
]
|
||||
@@ -40,8 +40,7 @@ return [
|
||||
},
|
||||
'submit' => function (string $path, string $filename) {
|
||||
$file = Find::file($path, $filename);
|
||||
$name = $file->kirby()->request()->get('name');
|
||||
$renamed = $file->changeName($name);
|
||||
$renamed = $file->changeName($file->kirby()->request()->get('name'));
|
||||
$oldUrl = $file->panel()->url(true);
|
||||
$newUrl = $renamed->panel()->url(true);
|
||||
$response = [
|
||||
@@ -97,44 +96,6 @@ return [
|
||||
}
|
||||
],
|
||||
|
||||
'changeTemplate' => [
|
||||
'load' => function (string $path, string $filename) {
|
||||
$file = Find::file($path, $filename);
|
||||
$blueprints = $file->blueprints();
|
||||
|
||||
return [
|
||||
'component' => 'k-form-dialog',
|
||||
'props' => [
|
||||
'fields' => [
|
||||
'warning' => [
|
||||
'type' => 'info',
|
||||
'theme' => 'notice',
|
||||
'text' => I18n::translate('file.changeTemplate.notice')
|
||||
],
|
||||
'template' => Field::template($blueprints, [
|
||||
'required' => true
|
||||
])
|
||||
],
|
||||
'theme' => 'notice',
|
||||
'submitButton' => I18n::translate('change'),
|
||||
'value' => [
|
||||
'template' => $file->template()
|
||||
]
|
||||
]
|
||||
];
|
||||
},
|
||||
'submit' => function (string $path, string $filename) {
|
||||
$file = Find::file($path, $filename);
|
||||
$template = $file->kirby()->request()->get('template');
|
||||
|
||||
$file->changeTemplate($template);
|
||||
|
||||
return [
|
||||
'event' => 'file.changeTemplate',
|
||||
];
|
||||
}
|
||||
],
|
||||
|
||||
'delete' => [
|
||||
'load' => function (string $path, string $filename) {
|
||||
$file = Find::file($path, $filename);
|
||||
@@ -168,5 +129,4 @@ return [
|
||||
];
|
||||
}
|
||||
],
|
||||
|
||||
];
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
<?php
|
||||
|
||||
return function () {
|
||||
return [
|
||||
'icon' => 'lab',
|
||||
'label' => 'Lab',
|
||||
'menu' => false,
|
||||
'drawers' => require __DIR__ . '/lab/drawers.php',
|
||||
'views' => require __DIR__ . '/lab/views.php'
|
||||
];
|
||||
};
|
||||
@@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Kirby\Panel\Lab\Docs;
|
||||
|
||||
return [
|
||||
'lab.docs' => [
|
||||
'pattern' => 'lab/docs/(:any)',
|
||||
'load' => function (string $component) {
|
||||
if (Docs::installed() === false) {
|
||||
return [
|
||||
'component' => 'k-text-drawer',
|
||||
'props' => [
|
||||
'text' => 'The UI docs are not installed.'
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
$docs = new Docs($component);
|
||||
|
||||
return [
|
||||
'component' => 'k-lab-docs-drawer',
|
||||
'props' => [
|
||||
'icon' => 'book',
|
||||
'title' => $component,
|
||||
'docs' => $docs->toArray()
|
||||
]
|
||||
];
|
||||
},
|
||||
],
|
||||
];
|
||||
@@ -1,148 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Kirby\Panel\Lab\Category;
|
||||
use Kirby\Panel\Lab\Docs;
|
||||
|
||||
return [
|
||||
'lab' => [
|
||||
'pattern' => 'lab',
|
||||
'action' => function () {
|
||||
return [
|
||||
'component' => 'k-lab-index-view',
|
||||
'props' => [
|
||||
'categories' => Category::all(),
|
||||
'info' => Category::installed() ? null : 'The default Lab examples are not installed.',
|
||||
'tab' => 'examples',
|
||||
],
|
||||
];
|
||||
}
|
||||
],
|
||||
'lab.docs' => [
|
||||
'pattern' => 'lab/docs',
|
||||
'action' => function () {
|
||||
$props = match (Docs::installed()) {
|
||||
true => [
|
||||
'categories' => [['examples' => Docs::all()]],
|
||||
'tab' => 'docs',
|
||||
],
|
||||
false => [
|
||||
'info' => 'The UI docs are not installed.',
|
||||
'tab' => 'docs',
|
||||
]
|
||||
};
|
||||
|
||||
return [
|
||||
'component' => 'k-lab-index-view',
|
||||
'title' => 'Docs',
|
||||
'breadcrumb' => [
|
||||
[
|
||||
'label' => 'Docs',
|
||||
'link' => 'lab/docs'
|
||||
]
|
||||
],
|
||||
'props' => $props,
|
||||
];
|
||||
}
|
||||
],
|
||||
'lab.doc' => [
|
||||
'pattern' => 'lab/docs/(:any)',
|
||||
'action' => function (string $component) {
|
||||
$crumbs = [
|
||||
[
|
||||
'label' => 'Docs',
|
||||
'link' => 'lab/docs'
|
||||
],
|
||||
[
|
||||
'label' => $component,
|
||||
'link' => 'lab/docs/' . $component
|
||||
]
|
||||
];
|
||||
|
||||
if (Docs::installed() === false) {
|
||||
return [
|
||||
'component' => 'k-lab-index-view',
|
||||
'title' => $component,
|
||||
'breadcrumb' => $crumbs,
|
||||
'props' => [
|
||||
'info' => 'The UI docs are not installed.',
|
||||
'tab' => 'docs',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
$docs = new Docs($component);
|
||||
|
||||
return [
|
||||
'component' => 'k-lab-docs-view',
|
||||
'title' => $component,
|
||||
'breadcrumb' => $crumbs,
|
||||
'props' => [
|
||||
'component' => $component,
|
||||
'docs' => $docs->toArray(),
|
||||
'lab' => $docs->lab()
|
||||
]
|
||||
];
|
||||
}
|
||||
],
|
||||
'lab.vue' => [
|
||||
'pattern' => [
|
||||
'lab/(:any)/(:any)/index.vue',
|
||||
'lab/(:any)/(:any)/(:any)/index.vue'
|
||||
],
|
||||
'action' => function (
|
||||
string $category,
|
||||
string $id,
|
||||
string|null $tab = null
|
||||
) {
|
||||
return Category::factory($category)->example($id, $tab)->serve();
|
||||
}
|
||||
],
|
||||
'lab.example' => [
|
||||
'pattern' => 'lab/(:any)/(:any)/(:any?)',
|
||||
'action' => function (
|
||||
string $category,
|
||||
string $id,
|
||||
string|null $tab = null
|
||||
) {
|
||||
$category = Category::factory($category);
|
||||
$example = $category->example($id, $tab);
|
||||
$props = $example->props();
|
||||
$vue = $example->vue();
|
||||
|
||||
if (Docs::installed() === true && $docs = $props['docs'] ?? null) {
|
||||
$docs = new Docs($docs);
|
||||
}
|
||||
|
||||
$github = $docs?->github();
|
||||
|
||||
if ($source = $props['source'] ?? null) {
|
||||
$github ??= 'https://github.com/getkirby/kirby/tree/main/' . $source;
|
||||
}
|
||||
|
||||
return [
|
||||
'component' => 'k-lab-playground-view',
|
||||
'breadcrumb' => [
|
||||
[
|
||||
'label' => $category->name(),
|
||||
],
|
||||
[
|
||||
'label' => $example->title(),
|
||||
'link' => $example->url()
|
||||
]
|
||||
],
|
||||
'props' => [
|
||||
'docs' => $docs?->name(),
|
||||
'examples' => $vue['examples'],
|
||||
'file' => $example->module(),
|
||||
'github' => $github,
|
||||
'props' => $props,
|
||||
'styles' => $vue['style'],
|
||||
'tab' => $example->tab(),
|
||||
'tabs' => array_values($example->tabs()),
|
||||
'template' => $vue['template'],
|
||||
'title' => $example->title(),
|
||||
],
|
||||
];
|
||||
}
|
||||
]
|
||||
];
|
||||
@@ -4,7 +4,7 @@ use Kirby\Toolkit\I18n;
|
||||
|
||||
return function ($kirby) {
|
||||
return [
|
||||
'icon' => 'translate',
|
||||
'icon' => 'globe',
|
||||
'label' => I18n::translate('view.languages'),
|
||||
'menu' => true,
|
||||
'dialogs' => require __DIR__ . '/languages/dialogs.php',
|
||||
|
||||
@@ -2,15 +2,13 @@
|
||||
|
||||
use Kirby\Cms\App;
|
||||
use Kirby\Cms\Find;
|
||||
use Kirby\Cms\LanguageVariable;
|
||||
use Kirby\Exception\NotFoundException;
|
||||
use Kirby\Panel\Field;
|
||||
use Kirby\Toolkit\A;
|
||||
use Kirby\Toolkit\Escape;
|
||||
use Kirby\Toolkit\I18n;
|
||||
|
||||
$languageDialogFields = [
|
||||
'name' => [
|
||||
'counter' => false,
|
||||
'label' => I18n::translate('language.name'),
|
||||
'type' => 'text',
|
||||
'required' => true,
|
||||
@@ -21,7 +19,7 @@ $languageDialogFields = [
|
||||
'type' => 'text',
|
||||
'required' => true,
|
||||
'counter' => false,
|
||||
'icon' => 'translate',
|
||||
'icon' => 'globe',
|
||||
'width' => '1/2'
|
||||
],
|
||||
'direction' => [
|
||||
@@ -36,27 +34,11 @@ $languageDialogFields = [
|
||||
'width' => '1/2'
|
||||
],
|
||||
'locale' => [
|
||||
'counter' => false,
|
||||
'label' => I18n::translate('language.locale'),
|
||||
'type' => 'text',
|
||||
'label' => I18n::translate('language.locale'),
|
||||
'type' => 'text',
|
||||
],
|
||||
];
|
||||
|
||||
$translationDialogFields = [
|
||||
'key' => [
|
||||
'counter' => false,
|
||||
'icon' => null,
|
||||
'label' => I18n::translate('language.variable.key'),
|
||||
'type' => 'text'
|
||||
],
|
||||
'value' => [
|
||||
'buttons' => false,
|
||||
'counter' => false,
|
||||
'label' => I18n::translate('language.variable.value'),
|
||||
'type' => 'textarea'
|
||||
]
|
||||
];
|
||||
|
||||
return [
|
||||
|
||||
// create language
|
||||
@@ -110,10 +92,8 @@ return [
|
||||
},
|
||||
'submit' => function (string $id) {
|
||||
Find::language($id)->delete();
|
||||
|
||||
return [
|
||||
'event' => 'language.delete',
|
||||
'redirect' => 'languages'
|
||||
'event' => 'language.delete',
|
||||
];
|
||||
}
|
||||
],
|
||||
@@ -172,95 +152,4 @@ return [
|
||||
];
|
||||
}
|
||||
],
|
||||
|
||||
'language.translation.create' => [
|
||||
'pattern' => 'languages/(:any)/translations/create',
|
||||
'load' => function (string $languageCode) use ($translationDialogFields) {
|
||||
// find the language to make sure it exists
|
||||
Find::language($languageCode);
|
||||
|
||||
return [
|
||||
'component' => 'k-form-dialog',
|
||||
'props' => [
|
||||
'fields' => $translationDialogFields,
|
||||
'size' => 'large',
|
||||
],
|
||||
];
|
||||
},
|
||||
'submit' => function (string $languageCode) {
|
||||
$request = App::instance()->request();
|
||||
$language = Find::language($languageCode);
|
||||
|
||||
$key = $request->get('key', '');
|
||||
$value = $request->get('value', '');
|
||||
|
||||
LanguageVariable::create($key, $value);
|
||||
|
||||
if ($language->isDefault() === false) {
|
||||
$language->variable($key)->update($value);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
],
|
||||
'language.translation.delete' => [
|
||||
'pattern' => 'languages/(:any)/translations/(:any)/delete',
|
||||
'load' => function (string $languageCode, string $translationKey) {
|
||||
$variable = Find::language($languageCode)->variable($translationKey, true);
|
||||
|
||||
if ($variable->exists() === false) {
|
||||
throw new NotFoundException([
|
||||
'key' => 'language.variable.notFound'
|
||||
]);
|
||||
}
|
||||
|
||||
return [
|
||||
'component' => 'k-remove-dialog',
|
||||
'props' => [
|
||||
'text' => I18n::template('language.variable.delete.confirm', [
|
||||
'key' => Escape::html($variable->key())
|
||||
])
|
||||
],
|
||||
];
|
||||
},
|
||||
'submit' => function (string $languageCode, string $translationKey) {
|
||||
return Find::language($languageCode)->variable($translationKey, true)->delete();
|
||||
}
|
||||
],
|
||||
'language.translation.update' => [
|
||||
'pattern' => 'languages/(:any)/translations/(:any)/update',
|
||||
'load' => function (string $languageCode, string $translationKey) use ($translationDialogFields) {
|
||||
$variable = Find::language($languageCode)->variable($translationKey, true);
|
||||
|
||||
if ($variable->exists() === false) {
|
||||
throw new NotFoundException([
|
||||
'key' => 'language.variable.notFound'
|
||||
]);
|
||||
}
|
||||
|
||||
$fields = $translationDialogFields;
|
||||
$fields['key']['disabled'] = true;
|
||||
$fields['value']['autofocus'] = true;
|
||||
|
||||
return [
|
||||
'component' => 'k-form-dialog',
|
||||
'props' => [
|
||||
'fields' => $fields,
|
||||
'size' => 'large',
|
||||
'value' => [
|
||||
'key' => $variable->key(),
|
||||
'value' => $variable->value()
|
||||
]
|
||||
],
|
||||
];
|
||||
},
|
||||
'submit' => function (string $languageCode, string $translationKey) {
|
||||
Find::language($languageCode)->variable($translationKey, true)->update(
|
||||
App::instance()->request()->get('value')
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
]
|
||||
|
||||
];
|
||||
|
||||
@@ -1,110 +1,9 @@
|
||||
<?php
|
||||
|
||||
use Kirby\Cms\App;
|
||||
use Kirby\Cms\Find;
|
||||
use Kirby\Toolkit\Escape;
|
||||
use Kirby\Toolkit\I18n;
|
||||
|
||||
return [
|
||||
'language' => [
|
||||
'pattern' => 'languages/(:any)',
|
||||
'when' => function (): bool {
|
||||
return App::instance()->option('languages.variables', true) !== false;
|
||||
},
|
||||
'action' => function (string $code) {
|
||||
$kirby = App::instance();
|
||||
$language = Find::language($code);
|
||||
$link = '/languages/' . $language->code();
|
||||
$strings = [];
|
||||
$foundation = $kirby->defaultLanguage()->translations();
|
||||
$translations = $language->translations();
|
||||
|
||||
// TODO: update following line and adapt for update and delete options
|
||||
// when new `languageVariables.*` permissions available
|
||||
$canUpdate = $kirby->user()?->role()->permissions()->for('languages', 'update') === true;
|
||||
|
||||
ksort($foundation);
|
||||
|
||||
foreach ($foundation as $key => $value) {
|
||||
$strings[] = [
|
||||
'key' => $key,
|
||||
'value' => $translations[$key] ?? null,
|
||||
'options' => [
|
||||
[
|
||||
'click' => 'update',
|
||||
'disabled' => $canUpdate === false,
|
||||
'icon' => 'edit',
|
||||
'text' => I18n::translate('edit'),
|
||||
],
|
||||
[
|
||||
'click' => 'delete',
|
||||
'disabled' => $canUpdate === false || $language->isDefault() === false,
|
||||
'icon' => 'trash',
|
||||
'text' => I18n::translate('delete'),
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
$next = function () use ($language) {
|
||||
if ($next = $language->next()) {
|
||||
return [
|
||||
'link' => '/languages/' . $next->code(),
|
||||
'title' => $next->name(),
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
$prev = function () use ($language) {
|
||||
if ($prev = $language->prev()) {
|
||||
return [
|
||||
'link' => '/languages/' . $prev->code(),
|
||||
'title' => $prev->name(),
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
return [
|
||||
'component' => 'k-language-view',
|
||||
'breadcrumb' => [
|
||||
[
|
||||
'label' => $name = $language->name(),
|
||||
'link' => $link,
|
||||
]
|
||||
],
|
||||
'props' => [
|
||||
'deletable' => $language->isDeletable(),
|
||||
'code' => Escape::html($language->code()),
|
||||
'default' => $language->isDefault(),
|
||||
'direction' => $language->direction(),
|
||||
'id' => $language->code(),
|
||||
'info' => [
|
||||
[
|
||||
'label' => 'Status',
|
||||
'value' => I18n::translate('language.' . ($language->isDefault() ? 'default' : 'secondary')),
|
||||
],
|
||||
[
|
||||
'label' => I18n::translate('language.code'),
|
||||
'value' => $language->code(),
|
||||
],
|
||||
[
|
||||
'label' => I18n::translate('language.locale'),
|
||||
'value' => $language->locale(LC_ALL)
|
||||
],
|
||||
[
|
||||
'label' => I18n::translate('language.direction'),
|
||||
'value' => I18n::translate('language.direction.' . $language->direction()),
|
||||
],
|
||||
],
|
||||
'name' => $name,
|
||||
'next' => $next,
|
||||
'prev' => $prev,
|
||||
'translations' => $strings,
|
||||
'url' => $language->url(),
|
||||
]
|
||||
];
|
||||
}
|
||||
],
|
||||
'languages' => [
|
||||
'pattern' => 'languages',
|
||||
'action' => function () {
|
||||
@@ -114,15 +13,13 @@ return [
|
||||
'component' => 'k-languages-view',
|
||||
'props' => [
|
||||
'languages' => $kirby->languages()->values(fn ($language) => [
|
||||
'deletable' => $language->isDeletable(),
|
||||
'default' => $language->isDefault(),
|
||||
'id' => $language->code(),
|
||||
'info' => Escape::html($language->code()),
|
||||
'text' => Escape::html($language->name()),
|
||||
]),
|
||||
'variables' => $kirby->option('languages.variables', true)
|
||||
'default' => $language->isDefault(),
|
||||
'id' => $language->code(),
|
||||
'info' => Escape::html($language->code()),
|
||||
'text' => Escape::html($language->name()),
|
||||
])
|
||||
]
|
||||
];
|
||||
}
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Kirby\Toolkit\I18n;
|
||||
|
||||
return function () {
|
||||
return [
|
||||
'icon' => 'search',
|
||||
'label' => I18n::translate('search'),
|
||||
'views' => require __DIR__ . '/search/views.php'
|
||||
];
|
||||
};
|
||||
@@ -1,17 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Kirby\Cms\App;
|
||||
|
||||
return [
|
||||
'search' => [
|
||||
'pattern' => 'search',
|
||||
'action' => function () {
|
||||
return [
|
||||
'component' => 'k-search-view',
|
||||
'props' => [
|
||||
'type' => App::instance()->request()->get('type'),
|
||||
]
|
||||
];
|
||||
}
|
||||
],
|
||||
];
|
||||
@@ -11,9 +11,7 @@ return function ($kirby) {
|
||||
'label' => $kirby->site()->blueprint()->title() ?? I18n::translate('view.site'),
|
||||
'menu' => true,
|
||||
'dialogs' => require __DIR__ . '/site/dialogs.php',
|
||||
'drawers' => require __DIR__ . '/site/drawers.php',
|
||||
'dropdowns' => require __DIR__ . '/site/dropdowns.php',
|
||||
'requests' => require __DIR__ . '/site/requests.php',
|
||||
'searches' => require __DIR__ . '/site/searches.php',
|
||||
'views' => require __DIR__ . '/site/views.php',
|
||||
];
|
||||
|
||||
@@ -2,20 +2,14 @@
|
||||
|
||||
use Kirby\Cms\App;
|
||||
use Kirby\Cms\Find;
|
||||
use Kirby\Cms\PageRules;
|
||||
use Kirby\Exception\Exception;
|
||||
use Kirby\Exception\InvalidArgumentException;
|
||||
use Kirby\Exception\PermissionException;
|
||||
use Kirby\Panel\ChangesDialog;
|
||||
use Kirby\Panel\Field;
|
||||
use Kirby\Panel\PageCreateDialog;
|
||||
use Kirby\Panel\Panel;
|
||||
use Kirby\Toolkit\Escape;
|
||||
use Kirby\Toolkit\I18n;
|
||||
use Kirby\Toolkit\Str;
|
||||
use Kirby\Uuid\Uuids;
|
||||
|
||||
$fields = require __DIR__ . '/../fields/dialogs.php';
|
||||
$files = require __DIR__ . '/../files/dialogs.php';
|
||||
|
||||
return [
|
||||
@@ -161,16 +155,10 @@ return [
|
||||
'component' => 'k-form-dialog',
|
||||
'props' => [
|
||||
'fields' => [
|
||||
'notice' => [
|
||||
'type' => 'info',
|
||||
'theme' => 'notice',
|
||||
'text' => I18n::translate('page.changeTemplate.notice')
|
||||
],
|
||||
'template' => Field::template($blueprints, [
|
||||
'required' => true
|
||||
])
|
||||
],
|
||||
'theme' => 'notice',
|
||||
'submitButton' => I18n::translate('change'),
|
||||
'value' => [
|
||||
'template' => $page->intendedTemplate()->name()
|
||||
@@ -179,10 +167,9 @@ return [
|
||||
];
|
||||
},
|
||||
'submit' => function (string $id) {
|
||||
$page = Find::page($id);
|
||||
$template = App::instance()->request()->get('template');
|
||||
$request = App::instance()->request();
|
||||
|
||||
$page->changeTemplate($template);
|
||||
Find::page($id)->changeTemplate($request->get('template'));
|
||||
|
||||
return [
|
||||
'event' => 'page.changeTemplate',
|
||||
@@ -212,7 +199,7 @@ return [
|
||||
'slug' => Field::slug([
|
||||
'required' => true,
|
||||
'preselect' => $select === 'slug',
|
||||
'path' => $page->parent() ? '/' . $page->parent()->uri() . '/' : '/',
|
||||
'path' => $page->parent() ? '/' . $page->parent()->id() . '/' : '/',
|
||||
'disabled' => $permissions->can('changeSlug') === false,
|
||||
'wizard' => [
|
||||
'text' => I18n::translate('page.changeSlug.fromTitle'),
|
||||
@@ -237,8 +224,17 @@ return [
|
||||
$slug = trim($request->get('slug', ''));
|
||||
|
||||
// basic input validation before we move on
|
||||
PageRules::validateTitleLength($title);
|
||||
PageRules::validateSlugLength($slug);
|
||||
if (Str::length($title) === 0) {
|
||||
throw new InvalidArgumentException([
|
||||
'key' => 'page.changeTitle.empty'
|
||||
]);
|
||||
}
|
||||
|
||||
if (Str::length($slug) === 0) {
|
||||
throw new InvalidArgumentException([
|
||||
'key' => 'page.slug.invalid'
|
||||
]);
|
||||
}
|
||||
|
||||
// nothing changed
|
||||
if ($page->title()->value() === $title && $page->slug() === $slug) {
|
||||
@@ -281,30 +277,93 @@ return [
|
||||
'page.create' => [
|
||||
'pattern' => 'pages/create',
|
||||
'load' => function () {
|
||||
$request = App::instance()->request();
|
||||
$dialog = new PageCreateDialog(
|
||||
parentId: $request->get('parent'),
|
||||
sectionId: $request->get('section'),
|
||||
slug: $request->get('slug'),
|
||||
template: $request->get('template'),
|
||||
title: $request->get('title'),
|
||||
viewId: $request->get('view'),
|
||||
);
|
||||
$kirby = App::instance();
|
||||
$request = $kirby->request();
|
||||
|
||||
return $dialog->load();
|
||||
// the parent model for the new page
|
||||
$parent = $request->get('parent', 'site');
|
||||
|
||||
// the view on which the add button is located
|
||||
// this is important to find the right section
|
||||
// and provide the correct templates for the new page
|
||||
$view = $request->get('view', $parent);
|
||||
|
||||
// templates will be fetched depending on the
|
||||
// section settings in the blueprint
|
||||
$section = $request->get('section');
|
||||
|
||||
// this is the parent model
|
||||
$model = Find::parent($parent);
|
||||
|
||||
// this is the view model
|
||||
// i.e. site if the add button is on
|
||||
// the dashboard
|
||||
$view = Find::parent($view);
|
||||
|
||||
// available blueprints/templates for the new page
|
||||
// are always loaded depending on the matching section
|
||||
// in the view model blueprint
|
||||
$blueprints = $view->blueprints($section);
|
||||
|
||||
// the pre-selected template
|
||||
$template = $blueprints[0]['name'] ?? $blueprints[0]['value'] ?? null;
|
||||
|
||||
$fields = [
|
||||
'parent' => Field::hidden(),
|
||||
'title' => Field::title([
|
||||
'required' => true,
|
||||
'preselect' => true
|
||||
]),
|
||||
'slug' => Field::slug([
|
||||
'required' => true,
|
||||
'sync' => 'title',
|
||||
'path' => empty($model->id()) === false ? '/' . $model->id() . '/' : '/'
|
||||
]),
|
||||
'template' => Field::hidden()
|
||||
];
|
||||
|
||||
// only show template field if > 1 templates available
|
||||
// or when in debug mode
|
||||
if (count($blueprints) > 1 || $kirby->option('debug') === true) {
|
||||
$fields['template'] = Field::template($blueprints, [
|
||||
'required' => true
|
||||
]);
|
||||
}
|
||||
|
||||
return [
|
||||
'component' => 'k-form-dialog',
|
||||
'props' => [
|
||||
'fields' => $fields,
|
||||
'submitButton' => I18n::translate('page.draft.create'),
|
||||
'value' => [
|
||||
'parent' => $parent,
|
||||
'slug' => '',
|
||||
'template' => $template,
|
||||
'title' => '',
|
||||
]
|
||||
]
|
||||
];
|
||||
},
|
||||
'submit' => function () {
|
||||
$request = App::instance()->request();
|
||||
$dialog = new PageCreateDialog(
|
||||
parentId: $request->get('parent'),
|
||||
sectionId: $request->get('section'),
|
||||
slug: $request->get('slug'),
|
||||
template: $request->get('template'),
|
||||
title: $request->get('title'),
|
||||
viewId: $request->get('view'),
|
||||
);
|
||||
$title = trim($request->get('title', ''));
|
||||
|
||||
return $dialog->submit($request->get());
|
||||
if (Str::length($title) === 0) {
|
||||
throw new InvalidArgumentException([
|
||||
'key' => 'page.changeTitle.empty'
|
||||
]);
|
||||
}
|
||||
|
||||
$page = Find::parent($request->get('parent', 'site'))->createChild([
|
||||
'content' => ['title' => $title],
|
||||
'slug' => $request->get('slug'),
|
||||
'template' => $request->get('template'),
|
||||
]);
|
||||
|
||||
return [
|
||||
'event' => 'page.create',
|
||||
'redirect' => $page->panel()->url(true)
|
||||
];
|
||||
}
|
||||
],
|
||||
|
||||
@@ -420,26 +479,6 @@ return [
|
||||
];
|
||||
}
|
||||
|
||||
$slugAppendix = Str::slug(I18n::translate('page.duplicate.appendix'));
|
||||
$titleAppendix = I18n::translate('page.duplicate.appendix');
|
||||
|
||||
// if the item to be duplicated already exists
|
||||
// add a suffix at the end of slug and title
|
||||
$duplicateSlug = $page->slug() . '-' . $slugAppendix;
|
||||
$siblingKeys = $page->parentModel()->childrenAndDrafts()->pluck('uid');
|
||||
|
||||
if (in_array($duplicateSlug, $siblingKeys) === true) {
|
||||
$suffixCounter = 2;
|
||||
$newSlug = $duplicateSlug . $suffixCounter;
|
||||
|
||||
while (in_array($newSlug, $siblingKeys) === true) {
|
||||
$newSlug = $duplicateSlug . ++$suffixCounter;
|
||||
}
|
||||
|
||||
$slugAppendix .= $suffixCounter;
|
||||
$titleAppendix .= ' ' . $suffixCounter;
|
||||
}
|
||||
|
||||
return [
|
||||
'component' => 'k-form-dialog',
|
||||
'props' => [
|
||||
@@ -448,8 +487,8 @@ return [
|
||||
'value' => [
|
||||
'children' => false,
|
||||
'files' => false,
|
||||
'slug' => $page->slug() . '-' . $slugAppendix,
|
||||
'title' => $page->title() . ' ' . $titleAppendix
|
||||
'slug' => $page->slug() . '-' . Str::slug(I18n::translate('page.duplicate.appendix')),
|
||||
'title' => $page->title() . ' ' . I18n::translate('page.duplicate.appendix')
|
||||
]
|
||||
]
|
||||
];
|
||||
@@ -470,13 +509,6 @@ return [
|
||||
}
|
||||
],
|
||||
|
||||
// page field dialogs
|
||||
'page.fields' => [
|
||||
'pattern' => '(pages/.*?)/fields/(:any)/(:all?)',
|
||||
'load' => $fields['model']['load'],
|
||||
'submit' => $fields['model']['submit']
|
||||
],
|
||||
|
||||
// change filename
|
||||
'page.file.changeName' => [
|
||||
'pattern' => '(pages/.*?)/files/(:any)/changeName',
|
||||
@@ -491,13 +523,6 @@ return [
|
||||
'submit' => $files['changeSort']['submit'],
|
||||
],
|
||||
|
||||
// change template
|
||||
'page.file.changeTemplate' => [
|
||||
'pattern' => '(pages/.*?)/files/(:any)/changeTemplate',
|
||||
'load' => $files['changeTemplate']['load'],
|
||||
'submit' => $files['changeTemplate']['submit'],
|
||||
],
|
||||
|
||||
// delete
|
||||
'page.file.delete' => [
|
||||
'pattern' => '(pages/.*?)/files/(:any)/delete',
|
||||
@@ -505,56 +530,6 @@ return [
|
||||
'submit' => $files['delete']['submit'],
|
||||
],
|
||||
|
||||
// page file field dialogs
|
||||
'page.file.fields' => [
|
||||
'pattern' => '(pages/.*?)/files/(:any)/fields/(:any)/(:all?)',
|
||||
'load' => $fields['file']['load'],
|
||||
'submit' => $fields['file']['submit'],
|
||||
],
|
||||
|
||||
// move page
|
||||
'page.move' => [
|
||||
'pattern' => 'pages/(:any)/move',
|
||||
'load' => function (string $id) {
|
||||
$page = Find::page($id);
|
||||
$parent = $page->parentModel();
|
||||
|
||||
if (Uuids::enabled() === false) {
|
||||
$parentId = $parent?->id() ?? '/';
|
||||
} else {
|
||||
$parentId = $parent?->uuid()->toString() ?? 'site://';
|
||||
}
|
||||
|
||||
return [
|
||||
'component' => 'k-page-move-dialog',
|
||||
'props' => [
|
||||
'value' => [
|
||||
'move' => $page->panel()->url(true),
|
||||
'parent' => $parentId
|
||||
]
|
||||
]
|
||||
];
|
||||
},
|
||||
'submit' => function (string $id) {
|
||||
$kirby = App::instance();
|
||||
$parentId = $kirby->request()->get('parent');
|
||||
$parent = (empty($parentId) === true || $parentId === '/' || $parentId === 'site://') ? $kirby->site() : Find::page($parentId);
|
||||
$oldPage = Find::page($id);
|
||||
$newPage = $oldPage->move($parent);
|
||||
|
||||
return [
|
||||
'event' => 'page.move',
|
||||
'redirect' => $newPage->panel()->url(true),
|
||||
'dispatch' => [
|
||||
'content/move' => [
|
||||
$oldPage->panel()->url(true),
|
||||
$newPage->panel()->url(true)
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
],
|
||||
|
||||
// change site title
|
||||
'site.changeTitle' => [
|
||||
'pattern' => 'site/changeTitle',
|
||||
@@ -577,21 +552,14 @@ return [
|
||||
},
|
||||
'submit' => function () {
|
||||
$kirby = App::instance();
|
||||
$kirby->site()->changeTitle($kirby->request()->get('title'));
|
||||
|
||||
$kirby->site()->changeTitle($kirby->request()->get('title'));
|
||||
return [
|
||||
'event' => 'site.changeTitle',
|
||||
];
|
||||
}
|
||||
],
|
||||
|
||||
// site field dialogs
|
||||
'site.fields' => [
|
||||
'pattern' => '(site)/fields/(:any)/(:all?)',
|
||||
'load' => $fields['model']['load'],
|
||||
'submit' => $fields['model']['submit'],
|
||||
],
|
||||
|
||||
// change filename
|
||||
'site.file.changeName' => [
|
||||
'pattern' => '(site)/files/(:any)/changeName',
|
||||
@@ -606,13 +574,6 @@ return [
|
||||
'submit' => $files['changeSort']['submit'],
|
||||
],
|
||||
|
||||
// change template
|
||||
'site.file.changeTemplate' => [
|
||||
'pattern' => '(site)/files/(:any)/changeTemplate',
|
||||
'load' => $files['changeTemplate']['load'],
|
||||
'submit' => $files['changeTemplate']['submit'],
|
||||
],
|
||||
|
||||
// delete
|
||||
'site.file.delete' => [
|
||||
'pattern' => '(site)/files/(:any)/delete',
|
||||
@@ -620,24 +581,4 @@ return [
|
||||
'submit' => $files['delete']['submit'],
|
||||
],
|
||||
|
||||
// site file field dialogs
|
||||
'site.file.fields' => [
|
||||
'pattern' => '(site)/files/(:any)/fields/(:any)/(:all?)',
|
||||
'load' => $fields['file']['load'],
|
||||
'submit' => $fields['file']['submit'],
|
||||
],
|
||||
|
||||
// content changes
|
||||
'changes' => [
|
||||
'pattern' => 'changes',
|
||||
'load' => function () {
|
||||
$dialog = new ChangesDialog();
|
||||
return $dialog->load();
|
||||
},
|
||||
'submit' => function () {
|
||||
$dialog = new ChangesDialog();
|
||||
$ids = App::instance()->request()->get('ids');
|
||||
return $dialog->submit($ids);
|
||||
}
|
||||
],
|
||||
];
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
<?php
|
||||
|
||||
$fields = require __DIR__ . '/../fields/drawers.php';
|
||||
|
||||
return [
|
||||
// page field drawers
|
||||
'page.fields' => [
|
||||
'pattern' => '(pages/.*?)/fields/(:any)/(:all?)',
|
||||
'load' => $fields['model']['load'],
|
||||
'submit' => $fields['model']['submit']
|
||||
],
|
||||
|
||||
// page file field drawers
|
||||
'page.file.fields' => [
|
||||
'pattern' => '(pages/.*?)/files/(:any)/fields/(:any)/(:all?)',
|
||||
'load' => $fields['file']['load'],
|
||||
'submit' => $fields['file']['submit'],
|
||||
],
|
||||
|
||||
// site field drawers
|
||||
'site.fields' => [
|
||||
'pattern' => '(site)/fields/(:any)/(:all?)',
|
||||
'load' => $fields['model']['load'],
|
||||
'submit' => $fields['model']['submit'],
|
||||
],
|
||||
|
||||
// site file field drawers
|
||||
'site.file.fields' => [
|
||||
'pattern' => '(site)/files/(:any)/fields/(:any)/(:all?)',
|
||||
'load' => $fields['file']['load'],
|
||||
'submit' => $fields['file']['submit'],
|
||||
],
|
||||
];
|
||||
@@ -1,9 +1,14 @@
|
||||
<?php
|
||||
|
||||
use Kirby\Panel\Dropdown;
|
||||
|
||||
$files = require __DIR__ . '/../files/dropdowns.php';
|
||||
|
||||
return [
|
||||
'changes' => [
|
||||
'pattern' => 'changes',
|
||||
'options' => fn () => Dropdown::changes()
|
||||
],
|
||||
'page' => [
|
||||
'pattern' => 'pages/(:any)',
|
||||
'options' => function (string $path) {
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Kirby\Cms\App;
|
||||
use Kirby\Cms\Find;
|
||||
use Kirby\Toolkit\I18n;
|
||||
|
||||
return [
|
||||
'tree' => [
|
||||
'pattern' => 'site/tree',
|
||||
'action' => function () {
|
||||
$kirby = App::instance();
|
||||
$request = $kirby->request();
|
||||
$move = $request->get('move');
|
||||
$move = $move ? Find::parent($move) : null;
|
||||
$parent = $request->get('parent');
|
||||
|
||||
if ($parent === null) {
|
||||
$site = $kirby->site();
|
||||
$panel = $site->panel();
|
||||
$uuid = $site->uuid()?->toString();
|
||||
$url = $site->url();
|
||||
$value = $uuid ?? '/';
|
||||
|
||||
return [
|
||||
[
|
||||
'children' => $panel->url(true),
|
||||
'disabled' => $move?->isMovableTo($site) === false,
|
||||
'hasChildren' => true,
|
||||
'icon' => 'home',
|
||||
'id' => '/',
|
||||
'label' => I18n::translate('view.site'),
|
||||
'open' => false,
|
||||
'url' => $url,
|
||||
'uuid' => $uuid,
|
||||
'value' => $value
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
$parent = Find::parent($parent);
|
||||
$pages = [];
|
||||
|
||||
foreach ($parent->childrenAndDrafts()->filterBy('isListable', true) as $child) {
|
||||
$panel = $child->panel();
|
||||
$uuid = $child->uuid()?->toString();
|
||||
$url = $child->url();
|
||||
$value = $uuid ?? $child->id();
|
||||
|
||||
$pages[] = [
|
||||
'children' => $panel->url(true),
|
||||
'disabled' => $move?->isMovableTo($child) === false,
|
||||
'hasChildren' => $child->hasChildren() === true || $child->hasDrafts() === true,
|
||||
'icon' => $panel->image()['icon'] ?? null,
|
||||
'id' => $child->id(),
|
||||
'open' => false,
|
||||
'label' => $child->title()->value(),
|
||||
'url' => $url,
|
||||
'uuid' => $uuid,
|
||||
'value' => $value
|
||||
];
|
||||
}
|
||||
|
||||
return $pages;
|
||||
}
|
||||
]
|
||||
];
|
||||
@@ -8,49 +8,50 @@ return [
|
||||
'pages' => [
|
||||
'label' => I18n::translate('pages'),
|
||||
'icon' => 'page',
|
||||
'query' => function (string $query = null, int $limit, int $page) {
|
||||
$kirby = App::instance();
|
||||
$pages = $kirby->site()
|
||||
'query' => function (string $query = null) {
|
||||
$pages = App::instance()->site()
|
||||
->index(true)
|
||||
->search($query)
|
||||
->filter('isListable', true)
|
||||
->paginate($limit, $page);
|
||||
->filter('isReadable', true)
|
||||
->limit(10);
|
||||
|
||||
return [
|
||||
'results' => $pages->values(fn ($page) => [
|
||||
$results = [];
|
||||
|
||||
foreach ($pages as $page) {
|
||||
$results[] = [
|
||||
'image' => $page->panel()->image(),
|
||||
'text' => Escape::html($page->title()->value()),
|
||||
'link' => $page->panel()->url(true),
|
||||
'info' => Escape::html($page->id()),
|
||||
'uuid' => $page->uuid()?->toString(),
|
||||
]),
|
||||
'pagination' => $pages->pagination()->toArray()
|
||||
];
|
||||
'info' => Escape::html($page->id())
|
||||
];
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
],
|
||||
'files' => [
|
||||
'label' => I18n::translate('files'),
|
||||
'icon' => 'image',
|
||||
'query' => function (string $query = null, int $limit, int $page) {
|
||||
$kirby = App::instance();
|
||||
$files = $kirby->site()
|
||||
'query' => function (string $query = null) {
|
||||
$files = App::instance()->site()
|
||||
->index(true)
|
||||
->filter('isListable', true)
|
||||
->filter('isReadable', true)
|
||||
->files()
|
||||
->filter('isListable', true)
|
||||
->search($query)
|
||||
->paginate($limit, $page);
|
||||
->limit(10);
|
||||
|
||||
return [
|
||||
'results' => $files->values(fn ($file) => [
|
||||
$results = [];
|
||||
|
||||
foreach ($files as $file) {
|
||||
$results[] = [
|
||||
'image' => $file->panel()->image(),
|
||||
'text' => Escape::html($file->filename()),
|
||||
'link' => $file->panel()->url(true),
|
||||
'info' => Escape::html($file->id()),
|
||||
'uuid' => $file->uuid()->toString(),
|
||||
]),
|
||||
'pagination' => $files->pagination()->toArray()
|
||||
];
|
||||
'info' => Escape::html($file->id())
|
||||
];
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
]
|
||||
];
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<?php
|
||||
|
||||
use Kirby\Cms\App;
|
||||
use Kirby\Exception\LogicException;
|
||||
use Kirby\Panel\Field;
|
||||
use Kirby\Toolkit\I18n;
|
||||
|
||||
@@ -9,85 +8,59 @@ return [
|
||||
// license key
|
||||
'license' => [
|
||||
'load' => function () {
|
||||
$kirby = App::instance();
|
||||
$license = $kirby->system()->license();
|
||||
$obfuscated = $kirby->user()->isAdmin() === false;
|
||||
$status = $license->status();
|
||||
$renewable = $status->renewable();
|
||||
$license = App::instance()->system()->license();
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
// the system is registered but the license
|
||||
// key is only visible for admins
|
||||
if ($license === true) {
|
||||
$license = 'Kirby 3';
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
return [
|
||||
'component' => 'k-license-dialog',
|
||||
'component' => 'k-form-dialog',
|
||||
'props' => [
|
||||
'license' => [
|
||||
'code' => $license->code($obfuscated),
|
||||
'icon' => $status->icon(),
|
||||
'info' => $status->info($license->renewal('Y-m-d', 'date')),
|
||||
'theme' => $status->theme(),
|
||||
'type' => $license->label(),
|
||||
'size' => 'medium',
|
||||
'fields' => [
|
||||
'license' => [
|
||||
'type' => 'info',
|
||||
'label' => I18n::translate('license'),
|
||||
'text' => $license ? $license : I18n::translate('license.unregistered.label'),
|
||||
'theme' => $license ? 'code' : 'negative',
|
||||
'help' => $license ?
|
||||
// @codeCoverageIgnoreStart
|
||||
'<a href="https://hub.getkirby.com">' . I18n::translate('license.manage') . ' →</a>' :
|
||||
// @codeCoverageIgnoreEnd
|
||||
'<a href="https://getkirby.com/buy">' . I18n::translate('license.buy') . ' →</a>'
|
||||
]
|
||||
],
|
||||
'cancelButton' => $renewable,
|
||||
'submitButton' => $renewable ? [
|
||||
'icon' => 'refresh',
|
||||
'text' => I18n::translate('renew'),
|
||||
'theme' => 'love',
|
||||
] : false,
|
||||
'submitButton' => false,
|
||||
'cancelButton' => false,
|
||||
]
|
||||
];
|
||||
},
|
||||
'submit' => function () {
|
||||
// @codeCoverageIgnoreStart
|
||||
$response = App::instance()->system()->license()->upgrade();
|
||||
|
||||
// the upgrade is still needed
|
||||
if ($response['status'] === 'upgrade') {
|
||||
return [
|
||||
'redirect' => $response['url']
|
||||
];
|
||||
}
|
||||
|
||||
// the upgrade has already been completed
|
||||
if ($response['status'] === 'complete') {
|
||||
return [
|
||||
'event' => 'system.renew',
|
||||
'message' => I18n::translate('license.success')
|
||||
];
|
||||
}
|
||||
|
||||
throw new LogicException('The upgrade failed');
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
],
|
||||
// license registration
|
||||
'registration' => [
|
||||
'load' => function () {
|
||||
$system = App::instance()->system();
|
||||
$local = $system->isLocal();
|
||||
|
||||
return [
|
||||
'component' => 'k-form-dialog',
|
||||
'props' => [
|
||||
'fields' => [
|
||||
'domain' => [
|
||||
'label' => I18n::translate('license.activate.label'),
|
||||
'type' => 'info',
|
||||
'theme' => $local ? 'warning' : 'info',
|
||||
'text' => I18n::template('license.activate.' . ($local ? 'local' : 'domain'), ['host' => $system->indexUrl()])
|
||||
],
|
||||
'license' => [
|
||||
'label' => I18n::translate('license.code.label'),
|
||||
'label' => I18n::translate('license.register.label'),
|
||||
'type' => 'text',
|
||||
'required' => true,
|
||||
'counter' => false,
|
||||
'placeholder' => 'K-',
|
||||
'help' => I18n::translate('license.code.help') . ' ' . '<a href="https://getkirby.com/buy" target="_blank">' . I18n::translate('license.buy') . ' →</a>'
|
||||
'placeholder' => 'K3-',
|
||||
'help' => I18n::translate('license.register.help')
|
||||
],
|
||||
'email' => Field::email(['required' => true])
|
||||
],
|
||||
'submitButton' => [
|
||||
'icon' => 'key',
|
||||
'text' => I18n::translate('activate'),
|
||||
'theme' => 'love',
|
||||
'email' => Field::email([
|
||||
'required' => true
|
||||
])
|
||||
],
|
||||
'submitButton' => I18n::translate('license.register'),
|
||||
'value' => [
|
||||
'license' => null,
|
||||
'email' => null
|
||||
@@ -105,7 +78,7 @@ return [
|
||||
|
||||
return [
|
||||
'event' => 'system.register',
|
||||
'message' => I18n::translate('license.success')
|
||||
'message' => I18n::translate('license.register.success')
|
||||
];
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
@@ -1,94 +1,48 @@
|
||||
<?php
|
||||
|
||||
use Kirby\Cms\App;
|
||||
use Kirby\Toolkit\I18n;
|
||||
|
||||
return [
|
||||
'system' => [
|
||||
'pattern' => 'system',
|
||||
'action' => function () {
|
||||
$kirby = App::instance();
|
||||
$system = $kirby->system();
|
||||
$updateStatus = $system->updateStatus();
|
||||
$license = $system->license();
|
||||
$kirby = App::instance();
|
||||
$system = $kirby->system();
|
||||
$license = $system->license();
|
||||
|
||||
$environment = [
|
||||
[
|
||||
'label' => $license->status()->label(),
|
||||
'value' => $license->label(),
|
||||
'theme' => $license->status()->theme(),
|
||||
'icon' => $license->status()->icon(),
|
||||
'dialog' => $license->status()->dialog()
|
||||
],
|
||||
[
|
||||
'label' => $updateStatus?->label() ?? I18n::translate('version'),
|
||||
'value' => $kirby->version(),
|
||||
'link' => $updateStatus?->url() ??
|
||||
'https://github.com/getkirby/kirby/releases/tag/' . $kirby->version(),
|
||||
'theme' => $updateStatus?->theme(),
|
||||
'icon' => $updateStatus?->icon() ?? 'info'
|
||||
],
|
||||
[
|
||||
'label' => 'PHP',
|
||||
'value' => phpversion(),
|
||||
'icon' => 'code'
|
||||
],
|
||||
[
|
||||
'label' => I18n::translate('server'),
|
||||
'value' => $system->serverSoftware() ?? '?',
|
||||
'icon' => 'server'
|
||||
]
|
||||
];
|
||||
|
||||
$exceptions = $updateStatus?->exceptionMessages() ?? [];
|
||||
|
||||
$plugins = $system->plugins()->values(function ($plugin) use (&$exceptions) {
|
||||
$authors = $plugin->authorsNames();
|
||||
$updateStatus = $plugin->updateStatus();
|
||||
$version = $updateStatus?->toArray() ?? $plugin->version() ?? '–';
|
||||
|
||||
if ($updateStatus !== null) {
|
||||
$exceptions = array_merge($exceptions, $updateStatus->exceptionMessages());
|
||||
}
|
||||
// @codeCoverageIgnoreStart
|
||||
if ($license === true) {
|
||||
// valid license, but user is not admin
|
||||
$license = 'Kirby 3';
|
||||
} elseif ($license === false) {
|
||||
// no valid license
|
||||
$license = null;
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
$plugins = $system->plugins()->values(function ($plugin) {
|
||||
return [
|
||||
'author' => empty($authors) ? '–' : $authors,
|
||||
'license' => $plugin->license() ?? '–',
|
||||
'author' => $plugin->authorsNames(),
|
||||
'license' => $plugin->license(),
|
||||
'name' => [
|
||||
'text' => $plugin->name() ?? '–',
|
||||
'text' => $plugin->name(),
|
||||
'href' => $plugin->link(),
|
||||
],
|
||||
'version' => $version,
|
||||
'version' => $plugin->version(),
|
||||
];
|
||||
});
|
||||
|
||||
$security = $updateStatus?->messages() ?? [];
|
||||
|
||||
if ($kirby->option('debug', false) === true) {
|
||||
$security[] = [
|
||||
'id' => 'debug',
|
||||
'text' => I18n::translate('system.issues.debug'),
|
||||
'link' => 'https://getkirby.com/security/debug'
|
||||
];
|
||||
}
|
||||
|
||||
if ($kirby->environment()->https() !== true) {
|
||||
$security[] = [
|
||||
'id' => 'https',
|
||||
'text' => I18n::translate('system.issues.https'),
|
||||
'link' => 'https://getkirby.com/security/https'
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'component' => 'k-system-view',
|
||||
'props' => [
|
||||
'environment' => $environment,
|
||||
'exceptions' => $kirby->option('debug') === true ? $exceptions : [],
|
||||
'info' => $system->info(),
|
||||
'plugins' => $plugins,
|
||||
'security' => $security,
|
||||
'urls' => [
|
||||
'debug' => $kirby->option('debug', false),
|
||||
'license' => $license,
|
||||
'plugins' => $plugins,
|
||||
'php' => phpversion(),
|
||||
'server' => $system->serverSoftware(),
|
||||
'https' => $kirby->environment()->https(),
|
||||
'version' => $kirby->version(),
|
||||
'urls' => [
|
||||
'content' => $system->exposedFileUrl('content'),
|
||||
'git' => $system->exposedFileUrl('git'),
|
||||
'kirby' => $system->exposedFileUrl('kirby'),
|
||||
|
||||
@@ -9,7 +9,6 @@ return function ($kirby) {
|
||||
'search' => 'users',
|
||||
'menu' => true,
|
||||
'dialogs' => require __DIR__ . '/users/dialogs.php',
|
||||
'drawers' => require __DIR__ . '/users/drawers.php',
|
||||
'dropdowns' => require __DIR__ . '/users/dropdowns.php',
|
||||
'searches' => require __DIR__ . '/users/searches.php',
|
||||
'views' => require __DIR__ . '/users/views.php'
|
||||
|
||||
@@ -6,11 +6,9 @@ use Kirby\Cms\UserRules;
|
||||
use Kirby\Exception\InvalidArgumentException;
|
||||
use Kirby\Panel\Field;
|
||||
use Kirby\Panel\Panel;
|
||||
use Kirby\Panel\UserTotpDisableDialog;
|
||||
use Kirby\Toolkit\Escape;
|
||||
use Kirby\Toolkit\I18n;
|
||||
|
||||
$fields = require __DIR__ . '/../fields/dialogs.php';
|
||||
$files = require __DIR__ . '/../files/dialogs.php';
|
||||
|
||||
return [
|
||||
@@ -20,12 +18,6 @@ return [
|
||||
'pattern' => 'users/create',
|
||||
'load' => function () {
|
||||
$kirby = App::instance();
|
||||
|
||||
// get default value for role
|
||||
if ($role = $kirby->request()->get('role')) {
|
||||
$role = $kirby->roles()->find($role)?->id();
|
||||
}
|
||||
|
||||
return [
|
||||
'component' => 'k-form-dialog',
|
||||
'props' => [
|
||||
@@ -49,7 +41,7 @@ return [
|
||||
'email' => '',
|
||||
'password' => '',
|
||||
'translation' => $kirby->panelLanguage(),
|
||||
'role' => $role ?? $kirby->user()->role()->name()
|
||||
'role' => $kirby->user()->role()->name()
|
||||
]
|
||||
]
|
||||
];
|
||||
@@ -295,13 +287,6 @@ return [
|
||||
}
|
||||
],
|
||||
|
||||
// user field dialogs
|
||||
'user.fields' => [
|
||||
'pattern' => '(users/.*?)/fields/(:any)/(:all?)',
|
||||
'load' => $fields['model']['load'],
|
||||
'submit' => $fields['model']['submit']
|
||||
],
|
||||
|
||||
// change file name
|
||||
'user.file.changeName' => [
|
||||
'pattern' => '(users/.*?)/files/(:any)/changeName',
|
||||
@@ -316,31 +301,11 @@ return [
|
||||
'submit' => $files['changeSort']['submit'],
|
||||
],
|
||||
|
||||
// change file template
|
||||
'user.file.changeTemplate' => [
|
||||
'pattern' => '(users/.*?)/files/(:any)/changeTemplate',
|
||||
'load' => $files['changeTemplate']['load'],
|
||||
'submit' => $files['changeTemplate']['submit'],
|
||||
],
|
||||
|
||||
// delete file
|
||||
'user.file.delete' => [
|
||||
'pattern' => '(users/.*?)/files/(:any)/delete',
|
||||
'load' => $files['delete']['load'],
|
||||
'submit' => $files['delete']['submit'],
|
||||
],
|
||||
]
|
||||
|
||||
// user file fields dialogs
|
||||
'user.file.fields' => [
|
||||
'pattern' => '(users/.*?)/files/(:any)/fields/(:any)/(:all?)',
|
||||
'load' => $fields['file']['load'],
|
||||
'submit' => $fields['file']['submit']
|
||||
],
|
||||
|
||||
// user disable TOTP
|
||||
'user.totp.disable' => [
|
||||
'pattern' => 'users/(:any)/totp/disable',
|
||||
'load' => fn (string $id) => (new UserTotpDisableDialog($id))->load(),
|
||||
'submit' => fn (string $id) => (new UserTotpDisableDialog($id))->submit()
|
||||
],
|
||||
];
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
<?php
|
||||
|
||||
$fields = require __DIR__ . '/../fields/drawers.php';
|
||||
|
||||
return [
|
||||
// user field drawers
|
||||
'user.fields' => [
|
||||
'pattern' => '(users/.*?)/fields/(:any)/(:all?)',
|
||||
'load' => $fields['model']['load'],
|
||||
'submit' => $fields['model']['submit']
|
||||
],
|
||||
// user file fields drawers
|
||||
'user.file.fields' => [
|
||||
'pattern' => '(users/.*?)/files/(:any)/fields/(:any)/(:all?)',
|
||||
'load' => $fields['file']['load'],
|
||||
'submit' => $fields['file']['submit']
|
||||
],
|
||||
];
|
||||
@@ -8,22 +8,20 @@ return [
|
||||
'users' => [
|
||||
'label' => I18n::translate('users'),
|
||||
'icon' => 'users',
|
||||
'query' => function (string $query = null, int $limit, int $page) {
|
||||
$kirby = App::instance();
|
||||
$users = $kirby->users()
|
||||
->search($query)
|
||||
->paginate($limit, $page);
|
||||
'query' => function (string $query = null) {
|
||||
$users = App::instance()->users()->search($query)->limit(10);
|
||||
$results = [];
|
||||
|
||||
return [
|
||||
'results' => $users->values(fn ($user) => [
|
||||
foreach ($users as $user) {
|
||||
$results[] = [
|
||||
'image' => $user->panel()->image(),
|
||||
'text' => Escape::html($user->username()),
|
||||
'link' => $user->panel()->url(true),
|
||||
'info' => Escape::html($user->role()->title()),
|
||||
'uuid' => $user->uuid()->toString(),
|
||||
]),
|
||||
'pagination' => $users->pagination()->toArray()
|
||||
];
|
||||
'info' => Escape::html($user->role()->title())
|
||||
];
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
]
|
||||
];
|
||||
|
||||
@@ -31,10 +31,6 @@ return [
|
||||
$users = $users->role($role);
|
||||
}
|
||||
|
||||
// sort users alphabetically
|
||||
$users = $users->sortBy('username', 'asc');
|
||||
|
||||
// paginate
|
||||
$users = $users->paginate([
|
||||
'limit' => 20,
|
||||
'page' => $kirby->request()->get('page')
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
<?php
|
||||
/** @var \Kirby\Cms\Block $block */
|
||||
$caption = $block->caption();
|
||||
$crop = $block->crop()->isTrue();
|
||||
$ratio = $block->ratio()->or('auto');
|
||||
?>
|
||||
<figure<?= Html::attr(['data-ratio' => $ratio, 'data-crop' => $crop], null, ' ') ?>>
|
||||
<?php /** @var \Kirby\Cms\Block $block */ ?>
|
||||
<figure>
|
||||
<ul>
|
||||
<?php foreach ($block->images()->toFiles() as $image): ?>
|
||||
<li>
|
||||
@@ -12,9 +7,4 @@ $ratio = $block->ratio()->or('auto');
|
||||
</li>
|
||||
<?php endforeach ?>
|
||||
</ul>
|
||||
<?php if ($caption->isNotEmpty()): ?>
|
||||
<figcaption>
|
||||
<?= $caption ?>
|
||||
</figcaption>
|
||||
<?php endif ?>
|
||||
</figure>
|
||||
|
||||
@@ -8,33 +8,9 @@ fields:
|
||||
query: model.images
|
||||
multiple: true
|
||||
layout: cards
|
||||
size: small
|
||||
size: tiny
|
||||
empty: field.blocks.gallery.images.empty
|
||||
uploads:
|
||||
template: blocks/image
|
||||
image:
|
||||
ratio: 1/1
|
||||
caption:
|
||||
label: field.blocks.image.caption
|
||||
type: writer
|
||||
icon: text
|
||||
inline: true
|
||||
ratio:
|
||||
label: field.blocks.image.ratio
|
||||
type: select
|
||||
placeholder: Auto
|
||||
width: 1/2
|
||||
options:
|
||||
1/1: "1:1"
|
||||
16/9: "16:9"
|
||||
10/8: "10:8"
|
||||
21/9: "21:9"
|
||||
7/5: "7:5"
|
||||
4/3: "4:3"
|
||||
5/3: "5:3"
|
||||
3/2: "3:2"
|
||||
3/1: "3:1"
|
||||
crop:
|
||||
label: field.blocks.image.crop
|
||||
type: toggle
|
||||
width: 1/2
|
||||
|
||||
@@ -5,31 +5,20 @@ preview: heading
|
||||
fields:
|
||||
level:
|
||||
label: field.blocks.heading.level
|
||||
type: toggles
|
||||
type: select
|
||||
empty: false
|
||||
default: "h2"
|
||||
labels: false
|
||||
width: 1/6
|
||||
options:
|
||||
- value: h1
|
||||
icon: h1
|
||||
text: H1
|
||||
- value: h2
|
||||
icon: h2
|
||||
text: H2
|
||||
- value: h3
|
||||
icon: h3
|
||||
text: H3
|
||||
- value: h4
|
||||
icon: h4
|
||||
text: H4
|
||||
- value: h5
|
||||
icon: h5
|
||||
text: H5
|
||||
- value: h6
|
||||
icon: h6
|
||||
text: H6
|
||||
- h1
|
||||
- h2
|
||||
- h3
|
||||
- h4
|
||||
- h5
|
||||
- h6
|
||||
text:
|
||||
label: field.blocks.heading.text
|
||||
type: writer
|
||||
inline: true
|
||||
width: 5/6
|
||||
placeholder: field.blocks.heading.placeholder
|
||||
|
||||
@@ -11,7 +11,7 @@ $src = null;
|
||||
if ($block->location() == 'web') {
|
||||
$src = $block->src()->esc();
|
||||
} elseif ($image = $block->image()->toFile()) {
|
||||
$alt = $alt->or($image->alt());
|
||||
$alt = $alt ?? $image->alt();
|
||||
$src = $image->url();
|
||||
}
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@ fields:
|
||||
columns: 2
|
||||
default: "kirby"
|
||||
options:
|
||||
kirby: "{{ t('field.blocks.image.location.internal') }}"
|
||||
web: "{{ t('field.blocks.image.location.external') }}"
|
||||
kirby: Kirby
|
||||
web: Web
|
||||
image:
|
||||
label: field.blocks.image.name
|
||||
type: files
|
||||
|
||||
@@ -2,30 +2,12 @@
|
||||
use Kirby\Cms\Html;
|
||||
|
||||
/** @var \Kirby\Cms\Block $block */
|
||||
$caption = $block->caption();
|
||||
|
||||
if (
|
||||
$block->location() == 'kirby' &&
|
||||
$video = $block->video()->toFile()
|
||||
) {
|
||||
$url = $video->url();
|
||||
$attrs = array_filter([
|
||||
'autoplay' => $block->autoplay()->toBool(),
|
||||
'controls' => $block->controls()->toBool(),
|
||||
'loop' => $block->loop()->toBool(),
|
||||
'muted' => $block->muted()->toBool(),
|
||||
'poster' => $block->poster()->toFile()?->url(),
|
||||
'preload' => $block->preload()->value(),
|
||||
]);
|
||||
} else {
|
||||
$url = $block->url();
|
||||
}
|
||||
?>
|
||||
<?php if ($video = Html::video($url, [], $attrs ?? [])): ?>
|
||||
<?php if ($video = Html::video($block->url())): ?>
|
||||
<figure>
|
||||
<?= $video ?>
|
||||
<?php if ($caption->isNotEmpty()): ?>
|
||||
<figcaption><?= $caption ?></figcaption>
|
||||
<?php if ($block->caption()->isNotEmpty()): ?>
|
||||
<figcaption><?= $block->caption() ?></figcaption>
|
||||
<?php endif ?>
|
||||
</figure>
|
||||
<?php endif ?>
|
||||
|
||||
@@ -2,77 +2,11 @@ name: field.blocks.video.name
|
||||
icon: video
|
||||
preview: video
|
||||
fields:
|
||||
location:
|
||||
label: field.blocks.video.location
|
||||
type: radio
|
||||
columns: 2
|
||||
default: "web"
|
||||
options:
|
||||
kirby: "{{ t('field.blocks.image.location.internal') }}"
|
||||
web: "{{ t('field.blocks.image.location.external') }}"
|
||||
url:
|
||||
label: field.blocks.video.url.label
|
||||
type: url
|
||||
placeholder: field.blocks.video.url.placeholder
|
||||
when:
|
||||
location: web
|
||||
video:
|
||||
label: field.blocks.video.name
|
||||
type: files
|
||||
query: model.videos
|
||||
multiple: false
|
||||
# you might want to add a template for videos here
|
||||
when:
|
||||
location: kirby
|
||||
poster:
|
||||
label: field.blocks.video.poster
|
||||
type: files
|
||||
query: model.images
|
||||
multiple: false
|
||||
image:
|
||||
back: black
|
||||
uploads:
|
||||
template: blocks/image
|
||||
when:
|
||||
location: kirby
|
||||
caption:
|
||||
label: field.blocks.video.caption
|
||||
type: writer
|
||||
inline: true
|
||||
autoplay:
|
||||
label: field.blocks.video.autoplay
|
||||
type: toggle
|
||||
width: 1/3
|
||||
when:
|
||||
location: kirby
|
||||
muted:
|
||||
label: field.blocks.video.muted
|
||||
type: toggle
|
||||
width: 1/3
|
||||
default: true
|
||||
when:
|
||||
location: kirby
|
||||
loop:
|
||||
label: field.blocks.video.loop
|
||||
type: toggle
|
||||
width: 1/3
|
||||
when:
|
||||
location: kirby
|
||||
controls:
|
||||
label: field.blocks.video.controls
|
||||
type: toggle
|
||||
width: 1/3
|
||||
default: true
|
||||
when:
|
||||
location: kirby
|
||||
preload:
|
||||
label: field.blocks.video.preload
|
||||
type: select
|
||||
width: 2/3
|
||||
default: auto
|
||||
options:
|
||||
- auto
|
||||
- metadata
|
||||
- none
|
||||
when:
|
||||
location: kirby
|
||||
|
||||
56
kirby/config/blueprints/blocks/code.yml
Normal file
56
kirby/config/blueprints/blocks/code.yml
Normal file
@@ -0,0 +1,56 @@
|
||||
name: Code
|
||||
icon: code
|
||||
fields:
|
||||
code:
|
||||
label: Code
|
||||
type: textarea
|
||||
buttons: false
|
||||
font: monospace
|
||||
language:
|
||||
label: Language
|
||||
type: select
|
||||
default: text
|
||||
options:
|
||||
bash: Bash
|
||||
basic: BASIC
|
||||
c: C
|
||||
clojure: Clojure
|
||||
cpp: C++
|
||||
csharp: C#
|
||||
css: CSS
|
||||
diff: Diff
|
||||
elixir: Elixir
|
||||
elm: Elm
|
||||
erlang: Erlang
|
||||
go: Go
|
||||
graphql: GraphQL
|
||||
haskell: Haskell
|
||||
html: HTML
|
||||
java: Java
|
||||
js: JavaScript
|
||||
json: JSON
|
||||
latext: LaTeX
|
||||
less: Less
|
||||
lisp: Lisp
|
||||
lua: Lua
|
||||
makefile: Makefile
|
||||
markdown: Markdown
|
||||
markup: Markup
|
||||
objectivec: Objective-C
|
||||
pascal: Pascal
|
||||
perl: Perl
|
||||
php: PHP
|
||||
text: Plain Text
|
||||
python: Python
|
||||
r: R
|
||||
ruby: Ruby
|
||||
rust: Rust
|
||||
sass: Sass
|
||||
scss: SCSS
|
||||
shell: Shell
|
||||
sql: SQL
|
||||
swift: Swift
|
||||
typescript: TypeScript
|
||||
vbnet: VB.net
|
||||
xml: XML
|
||||
yaml: YAML
|
||||
20
kirby/config/blueprints/blocks/heading.yml
Normal file
20
kirby/config/blueprints/blocks/heading.yml
Normal file
@@ -0,0 +1,20 @@
|
||||
icon: title
|
||||
fields:
|
||||
text:
|
||||
type: text
|
||||
level:
|
||||
type: select
|
||||
width: 1/2
|
||||
empty: false
|
||||
default: "2"
|
||||
options:
|
||||
- value: "1"
|
||||
text: Heading 1
|
||||
- value: "2"
|
||||
text: Heading 2
|
||||
- value: "3"
|
||||
text: Heading 3
|
||||
id:
|
||||
type: text
|
||||
label: ID
|
||||
width: 1/2
|
||||
16
kirby/config/blueprints/blocks/image.yml
Normal file
16
kirby/config/blueprints/blocks/image.yml
Normal file
@@ -0,0 +1,16 @@
|
||||
name: Image
|
||||
icon: image
|
||||
fields:
|
||||
image:
|
||||
type: files
|
||||
multiple: false
|
||||
alt:
|
||||
type: text
|
||||
icon: title
|
||||
caption:
|
||||
type: writer
|
||||
inline: true
|
||||
icon: text
|
||||
link:
|
||||
type: text
|
||||
icon: url
|
||||
12
kirby/config/blueprints/blocks/quote.yml
Normal file
12
kirby/config/blueprints/blocks/quote.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
name: Quote
|
||||
icon: quote
|
||||
fields:
|
||||
text:
|
||||
label: Quote Text
|
||||
type: writer
|
||||
inline: true
|
||||
citation:
|
||||
label: Citation
|
||||
type: writer
|
||||
inline: true
|
||||
placeholder: by …
|
||||
25
kirby/config/blueprints/blocks/table.yml
Normal file
25
kirby/config/blueprints/blocks/table.yml
Normal file
@@ -0,0 +1,25 @@
|
||||
name: Table
|
||||
icon: menu
|
||||
fields:
|
||||
rows:
|
||||
label: Menu
|
||||
type: structure
|
||||
columns:
|
||||
dish: true
|
||||
description: true
|
||||
price:
|
||||
before: €
|
||||
width: 1/4
|
||||
align: right
|
||||
fields:
|
||||
dish:
|
||||
label: Dish
|
||||
type: text
|
||||
description:
|
||||
label: Description
|
||||
type: text
|
||||
price:
|
||||
label: Price
|
||||
type: number
|
||||
before: €
|
||||
step: 0.01
|
||||
5
kirby/config/blueprints/blocks/text.yml
Normal file
5
kirby/config/blueprints/blocks/text.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
name: Text
|
||||
icon: text
|
||||
fields:
|
||||
text:
|
||||
type: writer
|
||||
8
kirby/config/blueprints/blocks/video.yml
Normal file
8
kirby/config/blueprints/blocks/video.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
name: Video
|
||||
icon: video
|
||||
label: "{{ url }}"
|
||||
fields:
|
||||
url:
|
||||
type: url
|
||||
caption:
|
||||
type: writer
|
||||
2
kirby/config/blueprints/files/default.yml
Normal file
2
kirby/config/blueprints/files/default.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
name: File
|
||||
title: file
|
||||
3
kirby/config/blueprints/pages/default.yml
Normal file
3
kirby/config/blueprints/pages/default.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
name: Page
|
||||
title: Page
|
||||
|
||||
7
kirby/config/blueprints/site.yml
Normal file
7
kirby/config/blueprints/site.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
name: Site
|
||||
title: Site
|
||||
sections:
|
||||
pages:
|
||||
headline: Pages
|
||||
type: pages
|
||||
|
||||
@@ -4,69 +4,90 @@ use Kirby\Cms\App;
|
||||
use Kirby\Cms\Collection;
|
||||
use Kirby\Cms\File;
|
||||
use Kirby\Cms\FileVersion;
|
||||
use Kirby\Cms\Page;
|
||||
use Kirby\Cms\User;
|
||||
use Kirby\Cms\Helpers;
|
||||
use Kirby\Cms\Template;
|
||||
use Kirby\Data\Data;
|
||||
use Kirby\Email\PHPMailer as Emailer;
|
||||
use Kirby\Exception\NotFoundException;
|
||||
use Kirby\Filesystem\F;
|
||||
use Kirby\Filesystem\Filename;
|
||||
use Kirby\Http\Uri;
|
||||
use Kirby\Http\Url;
|
||||
use Kirby\Image\Darkroom;
|
||||
use Kirby\Template\Snippet;
|
||||
use Kirby\Template\Template;
|
||||
use Kirby\Text\Markdown;
|
||||
use Kirby\Text\SmartyPants;
|
||||
use Kirby\Toolkit\A;
|
||||
use Kirby\Toolkit\Str;
|
||||
use Kirby\Uuid\Uuid;
|
||||
use Kirby\Toolkit\Tpl as Snippet;
|
||||
|
||||
return [
|
||||
|
||||
/**
|
||||
* Used by the `css()` helper
|
||||
*
|
||||
* @param \Kirby\Cms\App $kirby Kirby instance
|
||||
* @param string $url Relative or absolute URL
|
||||
* @param string|array $options An array of attributes for the link tag or a media attribute string
|
||||
*/
|
||||
'css' => fn (App $kirby, string $url, $options = null): string => $url,
|
||||
|
||||
|
||||
/**
|
||||
* Object and variable dumper
|
||||
* to help with debugging.
|
||||
*
|
||||
* @param \Kirby\Cms\App $kirby Kirby instance
|
||||
* @param mixed $variable
|
||||
* @param bool $echo
|
||||
* @return string
|
||||
*
|
||||
* @deprecated 3.7.0 Disable `dump()` via `KIRBY_HELPER_DUMP` instead and create your own function
|
||||
* @todo move to `Helpers::dump()`, remove component in 3.8.0
|
||||
*/
|
||||
'dump' => function (App $kirby, $variable, bool $echo = true) {
|
||||
if ($kirby->environment()->cli() === true) {
|
||||
$output = print_r($variable, true) . PHP_EOL;
|
||||
} else {
|
||||
$output = '<pre>' . print_r($variable, true) . '</pre>';
|
||||
}
|
||||
|
||||
if ($echo === true) {
|
||||
echo $output;
|
||||
}
|
||||
|
||||
return $output;
|
||||
},
|
||||
|
||||
/**
|
||||
* Add your own email provider
|
||||
*
|
||||
* @param \Kirby\Cms\App $kirby Kirby instance
|
||||
* @param array $props
|
||||
* @param bool $debug
|
||||
*/
|
||||
'email' => function (
|
||||
App $kirby,
|
||||
array $props = [],
|
||||
bool $debug = false
|
||||
) {
|
||||
'email' => function (App $kirby, array $props = [], bool $debug = false) {
|
||||
return new Emailer($props, $debug);
|
||||
},
|
||||
|
||||
/**
|
||||
* Modify URLs for file objects
|
||||
*
|
||||
* @param \Kirby\Cms\App $kirby Kirby instance
|
||||
* @param \Kirby\Cms\File $file The original file object
|
||||
* @return string
|
||||
*/
|
||||
'file::url' => function (
|
||||
App $kirby,
|
||||
File $file
|
||||
): string {
|
||||
'file::url' => function (App $kirby, File $file): string {
|
||||
return $file->mediaUrl();
|
||||
},
|
||||
|
||||
/**
|
||||
* Adapt file characteristics
|
||||
*
|
||||
* @param \Kirby\Cms\App $kirby Kirby instance
|
||||
* @param \Kirby\Cms\File|\Kirby\Filesystem\Asset $file The file object
|
||||
* @param array $options All thumb options (width, height, crop, blur, grayscale)
|
||||
* @return \Kirby\Cms\File|\Kirby\Cms\FileVersion|\Kirby\Filesystem\Asset
|
||||
*/
|
||||
'file::version' => function (
|
||||
App $kirby,
|
||||
$file,
|
||||
array $options = []
|
||||
) {
|
||||
'file::version' => function (App $kirby, $file, array $options = []) {
|
||||
// if file is not resizable, return
|
||||
if ($file->isResizable() === false) {
|
||||
return $file;
|
||||
@@ -87,7 +108,7 @@ return [
|
||||
Data::write($job, array_merge($options, [
|
||||
'filename' => $file->filename()
|
||||
]));
|
||||
} catch (Throwable) {
|
||||
} catch (Throwable $e) {
|
||||
// if thumb doesn't exist yet and job file cannot
|
||||
// be created, return
|
||||
return $file;
|
||||
@@ -105,6 +126,7 @@ return [
|
||||
/**
|
||||
* Used by the `js()` helper
|
||||
*
|
||||
* @param \Kirby\Cms\App $kirby Kirby instance
|
||||
* @param string $url Relative or absolute URL
|
||||
* @param string|array $options An array of attributes for the link tag or a media attribute string
|
||||
*/
|
||||
@@ -113,17 +135,27 @@ return [
|
||||
/**
|
||||
* Add your own Markdown parser
|
||||
*
|
||||
* @param \Kirby\Cms\App $kirby Kirby instance
|
||||
* @param string $text Text to parse
|
||||
* @param array $options Markdown options
|
||||
* @param bool $inline Whether to wrap the text in `<p>` tags (deprecated: set via $options['inline'] instead)
|
||||
* @return string
|
||||
* @todo remove $inline parameter in in 3.8.0
|
||||
*/
|
||||
'markdown' => function (
|
||||
App $kirby,
|
||||
string $text = null,
|
||||
array $options = []
|
||||
): string {
|
||||
'markdown' => function (App $kirby, string $text = null, array $options = [], bool $inline = false): string {
|
||||
static $markdown;
|
||||
static $config;
|
||||
|
||||
// warning for deprecated fourth parameter
|
||||
if (func_num_args() === 4 && isset($options['inline']) === false) {
|
||||
// @codeCoverageIgnoreStart
|
||||
Helpers::deprecated('markdown component: the $inline parameter is deprecated and will be removed in Kirby 3.8.0. Use $options[\'inline\'] instead.');
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
// support for the deprecated fourth argument
|
||||
$options['inline'] ??= $inline;
|
||||
|
||||
// if the config options have changed or the component is called for the first time,
|
||||
// (re-)initialize the parser object
|
||||
if ($config !== $options) {
|
||||
@@ -137,14 +169,17 @@ return [
|
||||
/**
|
||||
* Add your own search engine
|
||||
*
|
||||
* @param \Kirby\Cms\App $kirby Kirby instance
|
||||
* @param \Kirby\Cms\Collection $collection Collection of searchable models
|
||||
* @param string $query
|
||||
* @param mixed $params
|
||||
* @return \Kirby\Cms\Collection|bool
|
||||
*/
|
||||
'search' => function (
|
||||
App $kirby,
|
||||
Collection $collection,
|
||||
string|null $query = null,
|
||||
string|array $params = []
|
||||
): Collection {
|
||||
'search' => function (App $kirby, Collection $collection, string $query = null, $params = []) {
|
||||
if (empty(trim($query ?? '')) === true) {
|
||||
return $collection->limit(0);
|
||||
}
|
||||
|
||||
if (is_string($params) === true) {
|
||||
$params = ['fields' => Str::split($params, '|')];
|
||||
}
|
||||
@@ -156,57 +191,37 @@ return [
|
||||
'words' => false,
|
||||
];
|
||||
|
||||
$collection = clone $collection;
|
||||
$options = array_merge($defaults, $params);
|
||||
$query = trim($query ?? '');
|
||||
|
||||
// empty or too short search query
|
||||
if (Str::length($query) < $options['minlength']) {
|
||||
return $collection->limit(0);
|
||||
}
|
||||
|
||||
$words = preg_replace('/(\s)/u', ',', $query);
|
||||
$words = Str::split($words, ',', $options['minlength']);
|
||||
$collection = clone $collection;
|
||||
$searchWords = preg_replace('/(\s)/u', ',', $query);
|
||||
$searchWords = Str::split($searchWords, ',', $options['minlength']);
|
||||
$lowerQuery = Str::lower($query);
|
||||
$exactQuery = $options['words'] ? '(\b' . preg_quote($query) . '\b)' : preg_quote($query);
|
||||
|
||||
if (empty($options['stopwords']) === false) {
|
||||
$words = array_diff($words, $options['stopwords']);
|
||||
$searchWords = array_diff($searchWords, $options['stopwords']);
|
||||
}
|
||||
|
||||
// returns an empty collection if there is no search word
|
||||
if (empty($words) === true) {
|
||||
return $collection->limit(0);
|
||||
}
|
||||
$searchWords = array_map(function ($value) use ($options) {
|
||||
return $options['words'] ? '\b' . preg_quote($value) . '\b' : preg_quote($value);
|
||||
}, $searchWords);
|
||||
|
||||
$words = A::map(
|
||||
$words,
|
||||
fn ($value) => Str::wrap(preg_quote($value), $options['words'] ? '\b' : '')
|
||||
);
|
||||
|
||||
$exact = preg_quote($query);
|
||||
|
||||
if ($options['words']) {
|
||||
$exact = '(\b' . $exact . '\b)';
|
||||
}
|
||||
|
||||
$query = Str::lower($query);
|
||||
$preg = '!(' . implode('|', $words) . ')!iu';
|
||||
$scores = [];
|
||||
|
||||
$results = $collection->filter(function ($item) use ($query, $exact, $preg, $options, &$scores) {
|
||||
$data = $item->content()->toArray();
|
||||
$keys = array_keys($data);
|
||||
$preg = '!(' . implode('|', $searchWords) . ')!i';
|
||||
$results = $collection->filter(function ($item) use ($query, $preg, $options, $lowerQuery, $exactQuery) {
|
||||
$data = $item->content()->toArray();
|
||||
$keys = array_keys($data);
|
||||
$keys[] = 'id';
|
||||
|
||||
if ($item instanceof User) {
|
||||
if (is_a($item, 'Kirby\Cms\User') === true) {
|
||||
$keys[] = 'name';
|
||||
$keys[] = 'email';
|
||||
$keys[] = 'role';
|
||||
} elseif ($item instanceof Page) {
|
||||
} elseif (is_a($item, 'Kirby\Cms\Page') === true) {
|
||||
// apply the default score for pages
|
||||
$options['score'] = array_merge(
|
||||
['id' => 64, 'title' => 64],
|
||||
$options['score']
|
||||
);
|
||||
$options['score'] = array_merge([
|
||||
'id' => 64,
|
||||
'title' => 64,
|
||||
], $options['score']);
|
||||
}
|
||||
|
||||
if (empty($options['fields']) === false) {
|
||||
@@ -214,10 +229,8 @@ return [
|
||||
$keys = array_intersect($keys, $fields);
|
||||
}
|
||||
|
||||
$scoring = [
|
||||
'hits' => 0,
|
||||
'score' => 0
|
||||
];
|
||||
$item->searchHits = 0;
|
||||
$item->searchScore = 0;
|
||||
|
||||
foreach ($keys as $key) {
|
||||
$score = $options['score'][$key] ?? 1;
|
||||
@@ -226,53 +239,43 @@ return [
|
||||
$lowerValue = Str::lower($value);
|
||||
|
||||
// check for exact matches
|
||||
if ($query == $lowerValue) {
|
||||
$scoring['score'] += 16 * $score;
|
||||
$scoring['hits'] += 1;
|
||||
if ($lowerQuery == $lowerValue) {
|
||||
$item->searchScore += 16 * $score;
|
||||
$item->searchHits += 1;
|
||||
|
||||
// check for exact beginning matches
|
||||
} elseif (
|
||||
$options['words'] === false &&
|
||||
Str::startsWith($lowerValue, $query) === true
|
||||
) {
|
||||
$scoring['score'] += 8 * $score;
|
||||
$scoring['hits'] += 1;
|
||||
} elseif ($options['words'] === false && Str::startsWith($lowerValue, $lowerQuery) === true) {
|
||||
$item->searchScore += 8 * $score;
|
||||
$item->searchHits += 1;
|
||||
|
||||
// check for exact query matches
|
||||
} elseif ($matches = preg_match_all('!' . $exact . '!ui', $value, $r)) {
|
||||
$scoring['score'] += 2 * $score;
|
||||
$scoring['hits'] += $matches;
|
||||
} elseif ($matches = preg_match_all('!' . $exactQuery . '!i', $value, $r)) {
|
||||
$item->searchScore += 2 * $score;
|
||||
$item->searchHits += $matches;
|
||||
}
|
||||
|
||||
// check for any match
|
||||
if ($matches = preg_match_all($preg, $value, $r)) {
|
||||
$scoring['score'] += $matches * $score;
|
||||
$scoring['hits'] += $matches;
|
||||
$item->searchHits += $matches;
|
||||
$item->searchScore += $matches * $score;
|
||||
}
|
||||
}
|
||||
|
||||
$scores[$item->id()] = $scoring;
|
||||
|
||||
return $scoring['hits'] > 0;
|
||||
return $item->searchHits > 0;
|
||||
});
|
||||
|
||||
return $results->sort(
|
||||
fn ($item) => $scores[$item->id()]['score'],
|
||||
'desc'
|
||||
);
|
||||
return $results->sort('searchScore', 'desc');
|
||||
},
|
||||
|
||||
/**
|
||||
* Add your own SmartyPants parser
|
||||
*
|
||||
* @param \Kirby\Cms\App $kirby Kirby instance
|
||||
* @param string $text Text to parse
|
||||
* @param array $options SmartyPants options
|
||||
* @return string
|
||||
*/
|
||||
'smartypants' => function (
|
||||
App $kirby,
|
||||
string $text = null,
|
||||
array $options = []
|
||||
): string {
|
||||
'smartypants' => function (App $kirby, string $text = null, array $options = []): string {
|
||||
static $smartypants;
|
||||
static $config;
|
||||
|
||||
@@ -289,55 +292,59 @@ return [
|
||||
/**
|
||||
* Add your own snippet loader
|
||||
*
|
||||
* @param \Kirby\Cms\App $kirby Kirby instance
|
||||
* @param string|array $name Snippet name
|
||||
* @param array $data Data array for the snippet
|
||||
* @return string|null
|
||||
*/
|
||||
'snippet' => function (
|
||||
App $kirby,
|
||||
string|array|null $name,
|
||||
array $data = [],
|
||||
bool $slots = false
|
||||
): Snippet|string {
|
||||
return Snippet::factory($name, $data, $slots);
|
||||
'snippet' => function (App $kirby, $name, array $data = []): ?string {
|
||||
$snippets = A::wrap($name);
|
||||
|
||||
foreach ($snippets as $name) {
|
||||
$name = (string)$name;
|
||||
$file = $kirby->root('snippets') . '/' . $name . '.php';
|
||||
|
||||
if (file_exists($file) === false) {
|
||||
$file = $kirby->extensions('snippets')[$name] ?? null;
|
||||
}
|
||||
|
||||
if ($file) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return Snippet::load($file, $data);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add your own template engine
|
||||
*
|
||||
* @param \Kirby\Cms\App $kirby Kirby instance
|
||||
* @param string $name Template name
|
||||
* @param string $type Extension type
|
||||
* @param string $defaultType Default extension type
|
||||
* @return \Kirby\Template\Template
|
||||
* @return \Kirby\Cms\Template
|
||||
*/
|
||||
'template' => function (
|
||||
App $kirby,
|
||||
string $name,
|
||||
string $type = 'html',
|
||||
string $defaultType = 'html'
|
||||
) {
|
||||
'template' => function (App $kirby, string $name, string $type = 'html', string $defaultType = 'html') {
|
||||
return new Template($name, $type, $defaultType);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add your own thumb generator
|
||||
*
|
||||
* @param \Kirby\Cms\App $kirby Kirby instance
|
||||
* @param string $src Root of the original file
|
||||
* @param string $dst Template string for the root to the desired destination
|
||||
* @param array $options All thumb options that should be applied: `width`, `height`, `crop`, `blur`, `grayscale`
|
||||
* @return string
|
||||
*/
|
||||
'thumb' => function (
|
||||
App $kirby,
|
||||
string $src,
|
||||
string $dst,
|
||||
array $options
|
||||
): string {
|
||||
'thumb' => function (App $kirby, string $src, string $dst, array $options): string {
|
||||
$darkroom = Darkroom::factory(
|
||||
$kirby->option('thumbs.driver', 'gd'),
|
||||
$kirby->option('thumbs', [])
|
||||
);
|
||||
$options = $darkroom->preprocess($src, $options);
|
||||
$root = (new Filename($src, $dst, $options))->toString();
|
||||
$options = $darkroom->preprocess($src, $options);
|
||||
$root = (new Filename($src, $dst, $options))->toString();
|
||||
|
||||
F::copy($src, $root, true);
|
||||
$darkroom->process($root, $options);
|
||||
@@ -348,15 +355,12 @@ return [
|
||||
/**
|
||||
* Modify all URLs
|
||||
*
|
||||
* @param \Kirby\Cms\App $kirby Kirby instance
|
||||
* @param string|null $path URL path
|
||||
* @param array|string|null $options Array of options for the Uri class
|
||||
* @throws \Kirby\Exception\NotFoundException If an invalid UUID was passed
|
||||
* @return string
|
||||
*/
|
||||
'url' => function (
|
||||
App $kirby,
|
||||
string $path = null,
|
||||
$options = null
|
||||
): string {
|
||||
'url' => function (App $kirby, string $path = null, $options = null): string {
|
||||
$language = null;
|
||||
|
||||
// get language from simple string option
|
||||
@@ -398,23 +402,6 @@ return [
|
||||
return $path;
|
||||
}
|
||||
|
||||
// support UUIDs
|
||||
if (
|
||||
$path !== null &&
|
||||
(
|
||||
Uuid::is($path, 'page') === true ||
|
||||
Uuid::is($path, 'file') === true
|
||||
)
|
||||
) {
|
||||
$model = Uuid::for($path)->model();
|
||||
|
||||
if ($model === null) {
|
||||
throw new NotFoundException('The model could not be found for "' . $path . '" uuid');
|
||||
}
|
||||
|
||||
$path = $model->url();
|
||||
}
|
||||
|
||||
$url = Url::makeAbsolute($path, $kirby->url());
|
||||
|
||||
if ($options === null) {
|
||||
|
||||
@@ -1,145 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Kirby\Exception\InvalidArgumentException;
|
||||
use Kirby\Field\FieldOptions;
|
||||
use Kirby\Toolkit\A;
|
||||
use Kirby\Toolkit\Escape;
|
||||
use Kirby\Toolkit\Str;
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'after' => null,
|
||||
'before' => null,
|
||||
|
||||
/**
|
||||
* Whether to allow alpha transparency in the color
|
||||
*/
|
||||
'alpha' => function (bool $alpha = false) {
|
||||
return $alpha;
|
||||
},
|
||||
/**
|
||||
* The CSS format (hex, rgb, hsl) to display and store the value
|
||||
*/
|
||||
'format' => function (string $format = 'hex'): string {
|
||||
if (in_array($format, ['hex', 'hsl', 'rgb']) === false) {
|
||||
throw new InvalidArgumentException('Unsupported format for color field (supported: hex, rgb, hsl)');
|
||||
}
|
||||
|
||||
return $format;
|
||||
},
|
||||
/**
|
||||
* Change mode to disable the color picker (`input`) or to only
|
||||
* show the `options` as toggles
|
||||
*/
|
||||
'mode' => function (string $mode = 'picker'): string {
|
||||
if (in_array($mode, ['picker', 'input', 'options']) === false) {
|
||||
throw new InvalidArgumentException('Unsupported mode for color field (supported: picker, input, options)');
|
||||
}
|
||||
|
||||
return $mode;
|
||||
},
|
||||
/**
|
||||
* List of colors that will be shown as buttons
|
||||
* to directly select them
|
||||
*/
|
||||
'options' => function (array $options = []): array {
|
||||
return $options;
|
||||
}
|
||||
],
|
||||
'computed' => [
|
||||
'default' => function (): string {
|
||||
return Str::lower($this->default);
|
||||
},
|
||||
'options' => function (): array {
|
||||
// resolve options to support manual arrays
|
||||
// alongside api and query options
|
||||
$props = FieldOptions::polyfill($this->props);
|
||||
$options = FieldOptions::factory([
|
||||
'text' => '{{ item.value }}',
|
||||
'value' => '{{ item.key }}',
|
||||
...$props['options']
|
||||
]);
|
||||
|
||||
$options = $options->render($this->model());
|
||||
|
||||
if (empty($options) === true) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$options = match (true) {
|
||||
// simple array of values
|
||||
// or value=text (from Options class)
|
||||
is_numeric($options[0]['value']) ||
|
||||
$options[0]['value'] === $options[0]['text']
|
||||
=> A::map($options, fn ($option) => [
|
||||
'value' => $option['text']
|
||||
]),
|
||||
|
||||
// deprecated: name => value, flipping
|
||||
// TODO: start throwing in warning in v5
|
||||
$this->isColor($options[0]['text'])
|
||||
=> A::map($options, fn ($option) => [
|
||||
'value' => $option['text'],
|
||||
// ensure that any HTML in the new text is escaped
|
||||
'text' => Escape::html($option['value'])
|
||||
]),
|
||||
|
||||
default
|
||||
=> A::map($options, fn ($option) => [
|
||||
'value' => $option['value'],
|
||||
'text' => $option['text']
|
||||
]),
|
||||
};
|
||||
|
||||
return $options;
|
||||
}
|
||||
],
|
||||
'methods' => [
|
||||
'isColor' => function (string $value): bool {
|
||||
return
|
||||
$this->isHex($value) ||
|
||||
$this->isRgb($value) ||
|
||||
$this->isHsl($value);
|
||||
},
|
||||
'isHex' => function (string $value): bool {
|
||||
return preg_match('/^#([\da-f]{3,4}){1,2}$/i', $value) === 1;
|
||||
},
|
||||
'isHsl' => function (string $value): bool {
|
||||
return preg_match('/^hsla?\(\s*(\d{1,3}\.?\d*)(deg|rad|grad|turn)?(?:,|\s)+(\d{1,3})%(?:,|\s)+(\d{1,3})%(?:,|\s|\/)*(\d*(?:\.\d+)?)(%?)\s*\)?$/i', $value) === 1;
|
||||
},
|
||||
'isRgb' => function (string $value): bool {
|
||||
return preg_match('/^rgba?\(\s*(\d{1,3})(%?)(?:,|\s)+(\d{1,3})(%?)(?:,|\s)+(\d{1,3})(%?)(?:,|\s|\/)*(\d*(?:\.\d+)?)(%?)\s*\)?$/i', $value) === 1;
|
||||
},
|
||||
],
|
||||
'validations' => [
|
||||
'color' => function ($value) {
|
||||
if (empty($value) === true) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->format === 'hex' && $this->isHex($value) === false) {
|
||||
throw new InvalidArgumentException([
|
||||
'key' => 'validation.color',
|
||||
'data' => ['format' => 'hex']
|
||||
]);
|
||||
}
|
||||
|
||||
if ($this->format === 'rgb' && $this->isRgb($value) === false) {
|
||||
throw new InvalidArgumentException([
|
||||
'key' => 'validation.color',
|
||||
'data' => ['format' => 'rgb']
|
||||
]);
|
||||
}
|
||||
|
||||
if ($this->format === 'hsl' && $this->isHsl($value) === false) {
|
||||
throw new InvalidArgumentException([
|
||||
'key' => 'validation.color',
|
||||
'data' => ['format' => 'hsl']
|
||||
]);
|
||||
}
|
||||
}
|
||||
]
|
||||
];
|
||||
@@ -46,13 +46,13 @@ return [
|
||||
/**
|
||||
* Latest date, which can be selected/saved (Y-m-d)
|
||||
*/
|
||||
'max' => function (string $max = null): string|null {
|
||||
'max' => function (string $max = null): ?string {
|
||||
return Date::optional($max);
|
||||
},
|
||||
/**
|
||||
* Earliest date, which can be selected/saved (Y-m-d)
|
||||
*/
|
||||
'min' => function (string $min = null): string|null {
|
||||
'min' => function (string $min = null): ?string {
|
||||
return Date::optional($min);
|
||||
},
|
||||
|
||||
@@ -129,7 +129,7 @@ return [
|
||||
'key' => 'validation.date.between',
|
||||
'data' => [
|
||||
'min' => $min->format($format),
|
||||
'max' => $max->format($format)
|
||||
'max' => $min->format($format)
|
||||
]
|
||||
]);
|
||||
} elseif ($min && $value->isMin($min) === false) {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<?php
|
||||
|
||||
use Kirby\Cms\ModelWithContent;
|
||||
use Kirby\Data\Data;
|
||||
use Kirby\Toolkit\A;
|
||||
|
||||
@@ -35,13 +34,7 @@ return [
|
||||
],
|
||||
'computed' => [
|
||||
'parentModel' => function () {
|
||||
if (
|
||||
is_string($this->parent) === true &&
|
||||
$model = $this->model()->query(
|
||||
$this->parent,
|
||||
ModelWithContent::class
|
||||
)
|
||||
) {
|
||||
if (is_string($this->parent) === true && $model = $this->model()->query($this->parent, 'Kirby\Cms\Model')) {
|
||||
return $model;
|
||||
}
|
||||
|
||||
@@ -75,13 +68,10 @@ return [
|
||||
|
||||
foreach (Data::decode($value, 'yaml') as $id) {
|
||||
if (is_array($id) === true) {
|
||||
$id = $id['uuid'] ?? $id['id'] ?? null;
|
||||
$id = $id['id'] ?? null;
|
||||
}
|
||||
|
||||
if (
|
||||
$id !== null &&
|
||||
($file = $this->kirby()->file($id, $this->model()))
|
||||
) {
|
||||
if ($id !== null && ($file = $this->kirby()->file($id, $this->model()))) {
|
||||
$files[] = $this->fileResponse($file);
|
||||
}
|
||||
}
|
||||
@@ -132,7 +122,7 @@ return [
|
||||
];
|
||||
},
|
||||
'save' => function ($value = null) {
|
||||
return A::pluck($value, $this->store);
|
||||
return A::pluck($value, 'uuid');
|
||||
},
|
||||
'validations' => [
|
||||
'max',
|
||||
|
||||
@@ -14,6 +14,13 @@ return [
|
||||
'icon' => null,
|
||||
'placeholder' => null,
|
||||
'required' => null,
|
||||
'translate' => null
|
||||
'translate' => null,
|
||||
|
||||
/**
|
||||
* If `false`, the prepended number will be hidden
|
||||
*/
|
||||
'numbered' => function (bool $numbered = true) {
|
||||
return $numbered;
|
||||
}
|
||||
]
|
||||
];
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'hidden' => true
|
||||
];
|
||||
return [];
|
||||
|
||||
@@ -12,6 +12,7 @@ return [
|
||||
'before' => null,
|
||||
'default' => null,
|
||||
'disabled' => null,
|
||||
'icon' => null,
|
||||
'placeholder' => null,
|
||||
'required' => null,
|
||||
'translate' => null,
|
||||
|
||||
@@ -1,155 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Kirby\Exception\InvalidArgumentException;
|
||||
use Kirby\Http\Url;
|
||||
use Kirby\Toolkit\Str;
|
||||
use Kirby\Toolkit\V;
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
'after' => null,
|
||||
'before' => null,
|
||||
'icon' => null,
|
||||
'placeholder' => null,
|
||||
|
||||
/**
|
||||
* @values 'anchor', 'url, 'page, 'file', 'email', 'tel', 'custom'
|
||||
*/
|
||||
'options' => function (array|null $options = null): array {
|
||||
return $options ?? [
|
||||
'url',
|
||||
'page',
|
||||
'file',
|
||||
'email',
|
||||
'tel',
|
||||
'anchor'
|
||||
];
|
||||
},
|
||||
'value' => function (string|null $value = null) {
|
||||
return $value ?? '';
|
||||
}
|
||||
],
|
||||
'methods' => [
|
||||
'activeTypes' => function () {
|
||||
return array_filter($this->availableTypes(), function (string $type) {
|
||||
return in_array($type, $this->props['options']) === true;
|
||||
}, ARRAY_FILTER_USE_KEY);
|
||||
},
|
||||
'availableTypes' => function () {
|
||||
return [
|
||||
'anchor' => [
|
||||
'detect' => function (string $value): bool {
|
||||
return Str::startsWith($value, '#') === true;
|
||||
},
|
||||
'link' => function (string $value): string {
|
||||
return $value;
|
||||
},
|
||||
'validate' => function (string $value): bool {
|
||||
return Str::startsWith($value, '#') === true;
|
||||
},
|
||||
],
|
||||
'email' => [
|
||||
'detect' => function (string $value): bool {
|
||||
return Str::startsWith($value, 'mailto:') === true;
|
||||
},
|
||||
'link' => function (string $value): string {
|
||||
return str_replace('mailto:', '', $value);
|
||||
},
|
||||
'validate' => function (string $value): bool {
|
||||
return V::email($value);
|
||||
},
|
||||
],
|
||||
'file' => [
|
||||
'detect' => function (string $value): bool {
|
||||
return Str::startsWith($value, 'file://') === true;
|
||||
},
|
||||
'link' => function (string $value): string {
|
||||
return $value;
|
||||
},
|
||||
'validate' => function (string $value): bool {
|
||||
return V::uuid($value, 'file');
|
||||
},
|
||||
],
|
||||
'page' => [
|
||||
'detect' => function (string $value): bool {
|
||||
return Str::startsWith($value, 'page://') === true;
|
||||
},
|
||||
'link' => function (string $value): string {
|
||||
return $value;
|
||||
},
|
||||
'validate' => function (string $value): bool {
|
||||
return V::uuid($value, 'page');
|
||||
},
|
||||
],
|
||||
'tel' => [
|
||||
'detect' => function (string $value): bool {
|
||||
return Str::startsWith($value, 'tel:') === true;
|
||||
},
|
||||
'link' => function (string $value): string {
|
||||
return str_replace('tel:', '', $value);
|
||||
},
|
||||
'validate' => function (string $value): bool {
|
||||
return V::tel($value);
|
||||
},
|
||||
],
|
||||
'url' => [
|
||||
'detect' => function (string $value): bool {
|
||||
return Str::startsWith($value, 'http://') === true || Str::startsWith($value, 'https://') === true;
|
||||
},
|
||||
'link' => function (string $value): string {
|
||||
return $value;
|
||||
},
|
||||
'validate' => function (string $value): bool {
|
||||
return V::url($value);
|
||||
},
|
||||
],
|
||||
|
||||
// needs to come last
|
||||
'custom' => [
|
||||
'detect' => function (string $value): bool {
|
||||
return true;
|
||||
},
|
||||
'link' => function (string $value): string {
|
||||
return $value;
|
||||
},
|
||||
'validate' => function (): bool {
|
||||
return true;
|
||||
},
|
||||
]
|
||||
];
|
||||
},
|
||||
],
|
||||
'validations' => [
|
||||
'value' => function (string|null $value) {
|
||||
if (empty($value) === true) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$detected = false;
|
||||
|
||||
foreach ($this->activeTypes() as $type => $options) {
|
||||
if ($options['detect']($value) !== true) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$link = $options['link']($value);
|
||||
$detected = true;
|
||||
|
||||
if ($options['validate']($link) === false) {
|
||||
throw new InvalidArgumentException([
|
||||
'key' => 'validation.' . $type
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// none of the configured types has been detected
|
||||
if ($detected === false) {
|
||||
throw new InvalidArgumentException([
|
||||
'key' => 'validation.linkType'
|
||||
]);
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
]
|
||||
];
|
||||
@@ -7,12 +7,6 @@ return [
|
||||
*/
|
||||
'marks' => function ($marks = true) {
|
||||
return $marks;
|
||||
},
|
||||
/**
|
||||
* Sets the allowed nodes. Available nodes: `bulletList`, `orderedList`
|
||||
*/
|
||||
'nodes' => function ($nodes = null) {
|
||||
return $nodes;
|
||||
}
|
||||
],
|
||||
'computed' => [
|
||||
|
||||
@@ -12,7 +12,7 @@ return [
|
||||
},
|
||||
|
||||
/**
|
||||
* Layout size for cards: `tiny`, `small`, `medium`, `large`, `huge`, `full`
|
||||
* Layout size for cards: `tiny`, `small`, `medium`, `large` or `huge`
|
||||
*/
|
||||
'size' => function (string $size = 'auto') {
|
||||
return $size;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
use Kirby\Field\FieldOptions;
|
||||
use Kirby\Form\Options;
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
@@ -30,18 +30,19 @@ return [
|
||||
],
|
||||
'methods' => [
|
||||
'getOptions' => function () {
|
||||
$props = FieldOptions::polyfill($this->props);
|
||||
$options = FieldOptions::factory($props['options']);
|
||||
return $options->render($this->model());
|
||||
return Options::factory(
|
||||
$this->options(),
|
||||
$this->props,
|
||||
$this->model()
|
||||
);
|
||||
},
|
||||
'sanitizeOption' => function ($value) {
|
||||
$options = array_column($this->options(), 'value');
|
||||
return in_array($value, $options) === true ? $value : null;
|
||||
'sanitizeOption' => function ($option) {
|
||||
$allowed = array_column($this->options(), 'value');
|
||||
return in_array($option, $allowed, true) === true ? $option : null;
|
||||
},
|
||||
'sanitizeOptions' => function ($values) {
|
||||
$options = array_column($this->options(), 'value');
|
||||
$options = array_intersect($values, $options);
|
||||
return array_values($options);
|
||||
'sanitizeOptions' => function ($options) {
|
||||
$allowed = array_column($this->options(), 'value');
|
||||
return array_intersect($options, $allowed);
|
||||
},
|
||||
]
|
||||
];
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<?php
|
||||
|
||||
use Kirby\Toolkit\I18n;
|
||||
use Kirby\Toolkit\Str;
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
@@ -68,21 +67,12 @@ return [
|
||||
return $search;
|
||||
},
|
||||
|
||||
/**
|
||||
* Whether to store UUID or ID in the
|
||||
* content file of the model
|
||||
*
|
||||
* @param string $store 'uuid'|'id'
|
||||
*/
|
||||
'store' => function (string $store = 'uuid') {
|
||||
return Str::lower($store);
|
||||
},
|
||||
|
||||
/**
|
||||
* Main text for each item
|
||||
*/
|
||||
'text' => function (string $text = null) {
|
||||
return $text;
|
||||
},
|
||||
|
||||
],
|
||||
];
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
use Kirby\Cms\Api;
|
||||
use Kirby\Cms\File;
|
||||
use Kirby\Exception\Exception;
|
||||
use Kirby\Exception\InvalidArgumentException;
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
@@ -23,23 +22,18 @@ return [
|
||||
$uploads = [];
|
||||
}
|
||||
|
||||
$uploads['accept'] = '*';
|
||||
|
||||
if ($template = $uploads['template'] ?? null) {
|
||||
// get parent object for upload target
|
||||
$parent = $this->uploadParent($uploads['parent'] ?? null);
|
||||
|
||||
if ($parent === null) {
|
||||
throw new InvalidArgumentException('"' . $uploads['parent'] . '" could not be resolved as a valid parent for the upload');
|
||||
}
|
||||
$template = $uploads['template'] ?? null;
|
||||
|
||||
if ($template) {
|
||||
$file = new File([
|
||||
'filename' => 'tmp',
|
||||
'parent' => $parent,
|
||||
'parent' => $this->model(),
|
||||
'template' => $template
|
||||
]);
|
||||
|
||||
$uploads['accept'] = $file->blueprint()->acceptAttribute();
|
||||
$uploads['accept'] = $file->blueprint()->acceptMime();
|
||||
} else {
|
||||
$uploads['accept'] = '*';
|
||||
}
|
||||
|
||||
return $uploads;
|
||||
@@ -51,37 +45,29 @@ return [
|
||||
throw new Exception('Uploads are disabled for this field');
|
||||
}
|
||||
|
||||
$parent = $this->uploadParent($params['parent'] ?? null);
|
||||
if ($parentQuery = ($params['parent'] ?? null)) {
|
||||
$parent = $this->model()->query($parentQuery);
|
||||
} else {
|
||||
$parent = $this->model();
|
||||
}
|
||||
|
||||
if (is_a($parent, 'Kirby\Cms\File') === true) {
|
||||
$parent = $parent->parent();
|
||||
}
|
||||
|
||||
return $api->upload(function ($source, $filename) use ($parent, $params, $map) {
|
||||
$props = [
|
||||
$file = $parent->createFile([
|
||||
'source' => $source,
|
||||
'template' => $params['template'] ?? null,
|
||||
'filename' => $filename,
|
||||
];
|
||||
]);
|
||||
|
||||
// move the source file from the temp dir
|
||||
$file = $parent->createFile($props, true);
|
||||
|
||||
if ($file instanceof File === false) {
|
||||
if (is_a($file, 'Kirby\Cms\File') === false) {
|
||||
throw new Exception('The file could not be uploaded');
|
||||
}
|
||||
|
||||
return $map($file, $parent);
|
||||
});
|
||||
},
|
||||
'uploadParent' => function (string $parentQuery = null) {
|
||||
$parent = $this->model();
|
||||
|
||||
if ($parentQuery) {
|
||||
$parent = $parent->query($parentQuery);
|
||||
}
|
||||
|
||||
if ($parent instanceof File) {
|
||||
$parent = $parent->parent();
|
||||
}
|
||||
|
||||
return $parent;
|
||||
}
|
||||
]
|
||||
];
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user