├── config ├── blocks │ ├── line │ │ ├── line.php │ │ └── line.yml │ ├── table │ │ └── table.yml │ ├── list │ │ ├── list.php │ │ └── list.yml │ ├── text │ │ ├── text.php │ │ └── text.yml │ ├── markdown │ │ ├── markdown.php │ │ └── markdown.yml │ ├── heading │ │ ├── heading.php │ │ └── heading.yml │ ├── code │ │ ├── code.php │ │ └── code.yml │ ├── quote │ │ ├── quote.php │ │ └── quote.yml │ ├── video │ │ ├── video.yml │ │ └── video.php │ ├── gallery │ │ ├── gallery.php │ │ └── gallery.yml │ └── image │ │ ├── image.php │ │ └── image.yml ├── fields │ ├── hidden.php │ ├── gap.php │ ├── line.php │ ├── mixins │ │ ├── userpicker.php │ │ ├── filepicker.php │ │ ├── pagepicker.php │ │ ├── min.php │ │ ├── layout.php │ │ ├── datetime.php │ │ └── options.php │ ├── list.php │ ├── range.php │ ├── tel.php │ ├── headline.php │ ├── radio.php │ ├── select.php │ ├── email.php │ ├── url.php │ ├── info.php │ ├── number.php │ ├── toggles.php │ ├── multiselect.php │ ├── slug.php │ ├── writer.php │ └── checkboxes.php ├── blueprints │ ├── files │ │ └── default.yml │ ├── pages │ │ └── default.yml │ ├── blocks │ │ ├── text.yml │ │ ├── video.yml │ │ ├── quote.yml │ │ ├── image.yml │ │ ├── heading.yml │ │ ├── table.yml │ │ └── code.yml │ └── site.yml ├── areas │ ├── files │ │ └── dropdowns.php │ ├── system.php │ ├── languages.php │ ├── account │ │ ├── dropdowns.php │ │ └── views.php │ ├── account.php │ ├── users │ │ ├── dropdowns.php │ │ └── searches.php │ ├── logout.php │ ├── users.php │ ├── languages │ │ └── views.php │ ├── site │ │ ├── dropdowns.php │ │ ├── views.php │ │ └── searches.php │ ├── site.php │ ├── installation.php │ └── login.php ├── templates │ └── emails │ │ └── auth │ │ ├── login.php │ │ └── password-reset.php ├── sections │ ├── mixins │ │ ├── search.php │ │ ├── min.php │ │ ├── empty.php │ │ ├── help.php │ │ ├── max.php │ │ ├── details.php │ │ ├── headline.php │ │ ├── pagination.php │ │ ├── sort.php │ │ └── parent.php │ ├── info.php │ └── fields.php ├── api │ ├── models │ │ ├── SiteBlueprint.php │ │ ├── FileBlueprint.php │ │ ├── UserBlueprint.php │ │ ├── Role.php │ │ ├── Translation.php │ │ ├── PageBlueprint.php │ │ ├── Language.php │ │ ├── Site.php │ │ └── FileVersion.php │ ├── routes │ │ ├── translations.php │ │ ├── roles.php │ │ ├── languages.php │ │ └── lock.php │ ├── authentication.php │ ├── routes.php │ ├── models.php │ └── collections.php ├── presets │ └── files.php └── setup.php ├── views ├── snippets │ ├── footer.php │ └── header.php ├── php.php ├── fatal.php └── browser.php ├── i18n └── rules │ ├── fi.json │ ├── nb.json │ ├── sv_SE.json │ ├── de.json │ ├── uk.json │ ├── da.json │ ├── hr.json │ ├── it.json │ ├── et.json │ ├── tr.json │ ├── eo.json │ ├── rm.json │ ├── az.json │ ├── hu.json │ ├── lv.json │ ├── cs.json │ ├── lt.json │ ├── pl.json │ ├── is_IS.json │ ├── fr.json │ ├── ar.json │ ├── ka.json │ ├── fa.json │ ├── LICENSE │ ├── mk.json │ ├── bg.json │ ├── ru.json │ ├── hi.json │ ├── sr.json │ └── hy.json ├── panel ├── dist │ ├── favicon.png │ ├── apple-touch-icon.png │ └── favicon.svg └── cypress.config.js ├── vendor ├── filp │ └── whoops │ │ ├── src │ │ └── Whoops │ │ │ ├── Resources │ │ │ └── views │ │ │ │ ├── header_outer.html.php │ │ │ │ ├── panel_details.html.php │ │ │ │ ├── panel_details_outer.html.php │ │ │ │ ├── panel_left.html.php │ │ │ │ ├── panel_left_outer.html.php │ │ │ │ ├── frames_container.html.php │ │ │ │ ├── frames_description.html.php │ │ │ │ ├── layout.html.php │ │ │ │ └── frame_list.html.php │ │ │ ├── Exception │ │ │ └── ErrorException.php │ │ │ ├── Handler │ │ │ └── HandlerInterface.php │ │ │ └── Util │ │ │ └── HtmlDumperOutput.php │ │ ├── LICENSE.md │ │ └── composer.json ├── laminas │ └── laminas-escaper │ │ ├── COPYRIGHT.md │ │ └── src │ │ └── Exception │ │ ├── ExceptionInterface.php │ │ ├── RuntimeException.php │ │ └── InvalidArgumentException.php ├── psr │ └── log │ │ ├── src │ │ ├── InvalidArgumentException.php │ │ ├── LoggerAwareInterface.php │ │ ├── LogLevel.php │ │ ├── AbstractLogger.php │ │ ├── LoggerAwareTrait.php │ │ └── NullLogger.php │ │ ├── composer.json │ │ └── LICENSE ├── symfony │ ├── polyfill-intl-idn │ │ ├── Resources │ │ │ └── unidata │ │ │ │ ├── deviation.php │ │ │ │ ├── virama.php │ │ │ │ └── disallowed_STD3_valid.php │ │ ├── Info.php │ │ ├── LICENSE │ │ └── composer.json │ ├── polyfill-intl-normalizer │ │ ├── Resources │ │ │ └── stubs │ │ │ │ └── Normalizer.php │ │ ├── bootstrap80.php │ │ ├── bootstrap.php │ │ ├── LICENSE │ │ └── composer.json │ └── polyfill-mbstring │ │ ├── LICENSE │ │ └── composer.json ├── composer │ ├── autoload_namespaces.php │ ├── autoload_files.php │ ├── autoload_psr4.php │ ├── semver │ │ └── LICENSE │ └── LICENSE ├── michelf │ └── php-smartypants │ │ ├── Michelf │ │ ├── SmartyPants.inc.php │ │ └── SmartyPantsTypographer.inc.php │ │ └── composer.json ├── claviska │ └── simpleimage │ │ ├── composer.json │ │ └── LICENSE.md ├── autoload.php ├── league │ └── color-extractor │ │ ├── composer.json │ │ ├── LICENSE │ │ └── src │ │ └── League │ │ └── ColorExtractor │ │ └── Color.php └── phpmailer │ └── phpmailer │ ├── src │ └── Exception.php │ └── language │ ├── phpmailer.lang-zh_cn.php │ ├── phpmailer.lang-zh.php │ └── phpmailer.lang-ko.php ├── src ├── Form │ ├── Mixin │ │ ├── Max.php │ │ ├── Min.php │ │ └── EmptyState.php │ └── Fields.php ├── Cms │ ├── FilePermissions.php │ ├── SitePermissions.php │ ├── LayoutColumns.php │ ├── R.php │ ├── S.php │ ├── Visitor.php │ ├── Response.php │ ├── NestCollection.php │ ├── NestObject.php │ ├── Nest.php │ ├── UserBlueprint.php │ ├── SiteBlueprint.php │ └── UserPermissions.php ├── Http │ ├── Exceptions │ │ └── NextRouteException.php │ ├── Request │ │ ├── Auth │ │ │ ├── BearerAuth.php │ │ │ ├── SessionAuth.php │ │ │ └── BasicAuth.php │ │ └── Auth.php │ ├── Path.php │ └── Query.php ├── Toolkit │ ├── Config.php │ ├── Facade.php │ ├── Tpl.php │ ├── Silo.php │ └── Controller.php ├── Uuid │ ├── Identifiable.php │ ├── HasUuids.php │ ├── BlockUuid.php │ ├── StructureUuid.php │ ├── UserUuid.php │ ├── PageUuid.php │ └── SiteUuid.php ├── Exception │ ├── NotFoundException.php │ ├── LogicException.php │ ├── ErrorPageException.php │ ├── DuplicateException.php │ ├── PermissionException.php │ ├── BadMethodCallException.php │ └── InvalidArgumentException.php ├── Blueprint │ ├── NodeIcon.php │ ├── NodeProperty.php │ ├── NodeText.php │ ├── NodeString.php │ ├── NodeI18n.php │ └── Extension.php ├── Panel │ ├── Search.php │ ├── Dialog.php │ └── Redirect.php ├── Parsley │ ├── Schema.php │ └── Schema │ │ └── Plain.php ├── Option │ └── OptionsProvider.php ├── Template │ └── Slots.php ├── Data │ ├── Json.php │ └── Handler.php └── Image │ └── Camera.php ├── SECURITY.md ├── router.php ├── kirby.pub ├── .editorconfig ├── bootstrap.php ├── dependencies └── spyc │ └── COPYING └── assets └── whoops.css /config/blocks/line/line.php: -------------------------------------------------------------------------------- 1 |
2 | -------------------------------------------------------------------------------- /views/snippets/footer.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /config/fields/hidden.php: -------------------------------------------------------------------------------- 1 | false 5 | ]; 6 | -------------------------------------------------------------------------------- /config/fields/line.php: -------------------------------------------------------------------------------- 1 | false 5 | ]; 6 | -------------------------------------------------------------------------------- /config/blocks/table/table.yml: -------------------------------------------------------------------------------- 1 | name: Table 2 | icon: menu 3 | preview: table 4 | -------------------------------------------------------------------------------- /config/blocks/list/list.php: -------------------------------------------------------------------------------- 1 | 2 | text(); 3 | -------------------------------------------------------------------------------- /config/blocks/text/text.php: -------------------------------------------------------------------------------- 1 | 2 | text(); 3 | -------------------------------------------------------------------------------- /i18n/rules/fi.json: -------------------------------------------------------------------------------- 1 | { 2 | "Ä": "A", 3 | "Ö": "O", 4 | "ä": "a", 5 | "ö": "o" 6 | } 7 | -------------------------------------------------------------------------------- /config/blueprints/blocks/text.yml: -------------------------------------------------------------------------------- 1 | name: Text 2 | icon: text 3 | fields: 4 | text: 5 | type: writer 6 | -------------------------------------------------------------------------------- /panel/dist/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plain-solutions-gmbh/kirby/main/panel/dist/favicon.png -------------------------------------------------------------------------------- /config/blocks/line/line.yml: -------------------------------------------------------------------------------- 1 | name: field.blocks.line.name 2 | icon: divider 3 | preview: line 4 | wysiwyg: true 5 | -------------------------------------------------------------------------------- /config/blocks/markdown/markdown.php: -------------------------------------------------------------------------------- 1 | 2 | text()->kt(); 3 | -------------------------------------------------------------------------------- /panel/dist/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plain-solutions-gmbh/kirby/main/panel/dist/apple-touch-icon.png -------------------------------------------------------------------------------- /config/blueprints/site.yml: -------------------------------------------------------------------------------- 1 | name: Site 2 | title: Site 3 | sections: 4 | pages: 5 | headline: Pages 6 | type: pages 7 | 8 | -------------------------------------------------------------------------------- /i18n/rules/nb.json: -------------------------------------------------------------------------------- 1 | { 2 | "Æ": "AE", 3 | "Ø": "OE", 4 | "Å": "AA", 5 | "æ": "ae", 6 | "ø": "oe", 7 | "å": "aa" 8 | } 9 | -------------------------------------------------------------------------------- /vendor/filp/whoops/src/Whoops/Resources/views/header_outer.html.php: -------------------------------------------------------------------------------- 1 |
2 | render($header) ?> 3 |
4 | -------------------------------------------------------------------------------- /vendor/laminas/laminas-escaper/COPYRIGHT.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC. (https://getlaminas.org/) 2 | -------------------------------------------------------------------------------- /i18n/rules/sv_SE.json: -------------------------------------------------------------------------------- 1 | { 2 | "Ä": "A", 3 | "Å": "a", 4 | "Ö": "O", 5 | "ä": "a", 6 | "å": "a", 7 | "ö": "o" 8 | } 9 | -------------------------------------------------------------------------------- /vendor/filp/whoops/src/Whoops/Resources/views/panel_details.html.php: -------------------------------------------------------------------------------- 1 | render($frame_code) ?> 2 | render($env_details) ?> -------------------------------------------------------------------------------- /config/blocks/heading/heading.php: -------------------------------------------------------------------------------- 1 | 2 | <level()->or('h2') ?>>text() ?>> 3 | -------------------------------------------------------------------------------- /config/blueprints/blocks/video.yml: -------------------------------------------------------------------------------- 1 | name: Video 2 | icon: video 3 | label: "{{ url }}" 4 | fields: 5 | url: 6 | type: url 7 | caption: 8 | type: writer 9 | -------------------------------------------------------------------------------- /i18n/rules/de.json: -------------------------------------------------------------------------------- 1 | { 2 | "Ä": "AE", 3 | "Ö": "OE", 4 | "Ü": "UE", 5 | "ß": "ss", 6 | "ä": "ae", 7 | "ö": "oe", 8 | "ü": "ue" 9 | } 10 | -------------------------------------------------------------------------------- /vendor/filp/whoops/src/Whoops/Resources/views/panel_details_outer.html.php: -------------------------------------------------------------------------------- 1 |
2 | render($panel_details) ?> 3 |
-------------------------------------------------------------------------------- /vendor/psr/log/src/InvalidArgumentException.php: -------------------------------------------------------------------------------- 1 | 'ss', 5 | 962 => 'σ', 6 | 8204 => '', 7 | 8205 => '', 8 | ); 9 | -------------------------------------------------------------------------------- /i18n/rules/uk.json: -------------------------------------------------------------------------------- 1 | { 2 | "Ґ": "G", 3 | "І": "I", 4 | "Ї": "Ji", 5 | "Є": "Ye", 6 | "ґ": "g", 7 | "і": "i", 8 | "ї": "ji", 9 | "є": "ye" 10 | } 11 | -------------------------------------------------------------------------------- /vendor/filp/whoops/src/Whoops/Resources/views/panel_left.html.php: -------------------------------------------------------------------------------- 1 | render($header_outer); 3 | $tpl->render($frames_description); 4 | $tpl->render($frames_container); 5 | -------------------------------------------------------------------------------- /i18n/rules/da.json: -------------------------------------------------------------------------------- 1 | { 2 | "Æ": "Ae", 3 | "æ": "ae", 4 | "Ø": "Oe", 5 | "ø": "oe", 6 | "Å": "Aa", 7 | "å": "aa", 8 | "É": "E", 9 | "é": "e" 10 | } 11 | -------------------------------------------------------------------------------- /config/blocks/code/code.php: -------------------------------------------------------------------------------- 1 | 2 |
code()->html(false) ?>
3 | -------------------------------------------------------------------------------- /i18n/rules/hr.json: -------------------------------------------------------------------------------- 1 | { 2 | "Č": "C", 3 | "Ć": "C", 4 | "Ž": "Z", 5 | "Š": "S", 6 | "Đ": "Dj", 7 | "č": "c", 8 | "ć": "c", 9 | "ž": "z", 10 | "š": "s", 11 | "đ": "dj" 12 | } -------------------------------------------------------------------------------- /config/blocks/list/list.yml: -------------------------------------------------------------------------------- 1 | name: field.blocks.list.name 2 | icon: list-bullet 3 | wysiwyg: true 4 | preview: list 5 | fields: 6 | text: 7 | label: field.blocks.list.name 8 | type: list 9 | -------------------------------------------------------------------------------- /vendor/filp/whoops/src/Whoops/Resources/views/panel_left_outer.html.php: -------------------------------------------------------------------------------- 1 |
2 | render($panel_left) ?> 3 |
-------------------------------------------------------------------------------- /i18n/rules/it.json: -------------------------------------------------------------------------------- 1 | { 2 | "À": "a", 3 | "È": "e", 4 | "Ì": "i", 5 | "Ò": "o", 6 | "Ù": "u", 7 | "à": "a", 8 | "é": "e", 9 | "è": "e", 10 | "ì": "i", 11 | "ò": "o", 12 | "ù": "u" 13 | } 14 | -------------------------------------------------------------------------------- /i18n/rules/et.json: -------------------------------------------------------------------------------- 1 | { 2 | "Š": "S", 3 | "Ž": "Z", 4 | "Õ": "O", 5 | "Ä": "A", 6 | "Ö": "O", 7 | "Ü": "U", 8 | "š": "s", 9 | "ž": "z", 10 | "õ": "o", 11 | "ä": "a", 12 | "ö": "o", 13 | "ü": "u" 14 | } -------------------------------------------------------------------------------- /config/blocks/text/text.yml: -------------------------------------------------------------------------------- 1 | name: field.blocks.text.name 2 | icon: text 3 | wysiwyg: true 4 | preview: text 5 | fields: 6 | text: 7 | type: writer 8 | nodes: false 9 | placeholder: field.blocks.text.placeholder 10 | -------------------------------------------------------------------------------- /config/areas/files/dropdowns.php: -------------------------------------------------------------------------------- 1 | function (string $parent, string $filename) { 7 | return Find::file($parent, $filename)->panel()->dropdown(); 8 | } 9 | ]; 10 | -------------------------------------------------------------------------------- /vendor/filp/whoops/src/Whoops/Resources/views/frames_container.html.php: -------------------------------------------------------------------------------- 1 |
2 | render($frame_list) ?> 3 |
-------------------------------------------------------------------------------- /i18n/rules/tr.json: -------------------------------------------------------------------------------- 1 | { 2 | "Ç": "C", 3 | "Ğ": "G", 4 | "İ": "I", 5 | "Ş": "S", 6 | "Ö": "O", 7 | "Ü": "U", 8 | "ç": "c", 9 | "ğ": "g", 10 | "ı": "i", 11 | "ş": "s", 12 | "ö": "o", 13 | "ü": "u" 14 | } 15 | -------------------------------------------------------------------------------- /vendor/laminas/laminas-escaper/src/Exception/ExceptionInterface.php: -------------------------------------------------------------------------------- 1 | 2 |
3 | text() ?> 4 | citation()->isNotEmpty()): ?> 5 | 8 | 9 |
10 | -------------------------------------------------------------------------------- /i18n/rules/az.json: -------------------------------------------------------------------------------- 1 | { 2 | "Ə": "E", 3 | "Ç": "C", 4 | "Ğ": "G", 5 | "İ": "I", 6 | "Ş": "S", 7 | "Ö": "O", 8 | "Ü": "U", 9 | "ə": "e", 10 | "ç": "c", 11 | "ğ": "g", 12 | "ı": "i", 13 | "ş": "s", 14 | "ö": "o", 15 | "ü": "u" 16 | } 17 | -------------------------------------------------------------------------------- /config/fields/mixins/userpicker.php: -------------------------------------------------------------------------------- 1 | [ 7 | 'userpicker' => function (array $params = []) { 8 | $params['model'] = $this->model(); 9 | 10 | return (new UserPicker($params))->toArray(); 11 | } 12 | ] 13 | ]; 14 | -------------------------------------------------------------------------------- /src/Form/Mixin/Max.php: -------------------------------------------------------------------------------- 1 | max; 12 | } 13 | 14 | protected function setMax(int $max = null) 15 | { 16 | $this->max = $max; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Form/Mixin/Min.php: -------------------------------------------------------------------------------- 1 | min; 12 | } 13 | 14 | protected function setMin(int $min = null) 15 | { 16 | $this->min = $min; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | 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. 4 | -------------------------------------------------------------------------------- /config/blueprints/blocks/image.yml: -------------------------------------------------------------------------------- 1 | name: Image 2 | icon: image 3 | fields: 4 | image: 5 | type: files 6 | multiple: false 7 | alt: 8 | type: text 9 | icon: title 10 | caption: 11 | type: writer 12 | inline: true 13 | icon: text 14 | link: 15 | type: text 16 | icon: url 17 | -------------------------------------------------------------------------------- /vendor/laminas/laminas-escaper/src/Exception/RuntimeException.php: -------------------------------------------------------------------------------- 1 | [ 7 | 'filepicker' => function (array $params = []) { 8 | // fetch the parent model 9 | $params['model'] = $this->model(); 10 | 11 | return (new FilePicker($params))->toArray(); 12 | } 13 | ] 14 | ]; 15 | -------------------------------------------------------------------------------- /config/fields/mixins/pagepicker.php: -------------------------------------------------------------------------------- 1 | [ 7 | 'pagepicker' => function (array $params = []) { 8 | // inject the current model 9 | $params['model'] = $this->model(); 10 | 11 | return (new PagePicker($params))->toArray(); 12 | } 13 | ] 14 | ]; 15 | -------------------------------------------------------------------------------- /config/blocks/video/video.yml: -------------------------------------------------------------------------------- 1 | name: field.blocks.video.name 2 | icon: video 3 | preview: video 4 | fields: 5 | url: 6 | label: field.blocks.video.url.label 7 | type: url 8 | placeholder: field.blocks.video.url.placeholder 9 | caption: 10 | label: field.blocks.video.caption 11 | type: writer 12 | inline: true 13 | -------------------------------------------------------------------------------- /vendor/laminas/laminas-escaper/src/Exception/InvalidArgumentException.php: -------------------------------------------------------------------------------- 1 | array($vendorDir . '/claviska/simpleimage/src'), 10 | 'Michelf' => array($vendorDir . '/michelf/php-smartypants'), 11 | ); 12 | -------------------------------------------------------------------------------- /config/areas/system.php: -------------------------------------------------------------------------------- 1 | 'settings', 8 | 'label' => I18n::translate('view.system'), 9 | 'menu' => true, 10 | 'dialogs' => require __DIR__ . '/system/dialogs.php', 11 | 'views' => require __DIR__ . '/system/views.php' 12 | ]; 13 | }; 14 | -------------------------------------------------------------------------------- /config/areas/languages.php: -------------------------------------------------------------------------------- 1 | 'globe', 8 | 'label' => I18n::translate('view.languages'), 9 | 'menu' => true, 10 | 'dialogs' => require __DIR__ . '/languages/dialogs.php', 11 | 'views' => require __DIR__ . '/languages/views.php' 12 | ]; 13 | }; 14 | -------------------------------------------------------------------------------- /config/templates/emails/auth/login.php: -------------------------------------------------------------------------------- 1 | language() 16 | ); 17 | -------------------------------------------------------------------------------- /i18n/rules/cs.json: -------------------------------------------------------------------------------- 1 | { 2 | "Č": "C", 3 | "Ď": "D", 4 | "Ě": "E", 5 | "Ň": "N", 6 | "Ř": "R", 7 | "Š": "S", 8 | "Ť": "T", 9 | "Ů": "U", 10 | "Ž": "Z", 11 | "č": "c", 12 | "ď": "d", 13 | "ě": "e", 14 | "ň": "n", 15 | "ř": "r", 16 | "š": "s", 17 | "ť": "t", 18 | "ů": "u", 19 | "ž": "z" 20 | } 21 | -------------------------------------------------------------------------------- /i18n/rules/lt.json: -------------------------------------------------------------------------------- 1 | { 2 | "Ą": "A", 3 | "Č": "C", 4 | "Ę": "E", 5 | "Ė": "E", 6 | "Į": "I", 7 | "Š": "S", 8 | "Ų": "U", 9 | "Ū": "U", 10 | "Ž": "Z", 11 | "ą": "a", 12 | "č": "c", 13 | "ę": "e", 14 | "ė": "e", 15 | "į": "i", 16 | "š": "s", 17 | "ų": "u", 18 | "ū": "u", 19 | "ž": "z" 20 | } 21 | -------------------------------------------------------------------------------- /i18n/rules/pl.json: -------------------------------------------------------------------------------- 1 | { 2 | "Ą": "A", 3 | "Ć": "C", 4 | "Ę": "E", 5 | "Ł": "L", 6 | "Ń": "N", 7 | "Ó": "O", 8 | "Ś": "S", 9 | "Ź": "Z", 10 | "Ż": "Z", 11 | "ą": "a", 12 | "ć": "c", 13 | "ę": "e", 14 | "ł": "l", 15 | "ń": "n", 16 | "ó": "o", 17 | "ś": "s", 18 | "ź": "z", 19 | "ż": "z" 20 | } 21 | -------------------------------------------------------------------------------- /src/Form/Mixin/EmptyState.php: -------------------------------------------------------------------------------- 1 | empty = $this->i18n($empty); 12 | } 13 | 14 | public function empty(): string|null 15 | { 16 | return $this->stringTemplate($this->empty); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /config/blocks/video/video.php: -------------------------------------------------------------------------------- 1 | 6 | url())): ?> 7 |
8 | 9 | caption()->isNotEmpty()): ?> 10 |
caption() ?>
11 | 12 |
13 | 14 | -------------------------------------------------------------------------------- /config/areas/account/dropdowns.php: -------------------------------------------------------------------------------- 1 | [ 7 | 'pattern' => '(account)', 8 | 'options' => $dropdowns['user']['options'] 9 | ], 10 | 'account.file' => [ 11 | 'pattern' => '(account)/files/(:any)', 12 | 'options' => $dropdowns['user.file']['options'] 13 | ], 14 | ]; 15 | -------------------------------------------------------------------------------- /config/templates/emails/auth/password-reset.php: -------------------------------------------------------------------------------- 1 | language() 16 | ); 17 | -------------------------------------------------------------------------------- /router.php: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | -------------------------------------------------------------------------------- /src/Cms/FilePermissions.php: -------------------------------------------------------------------------------- 1 | 10 | * @link https://getkirby.com 11 | * @copyright Bastian Allgeier 12 | * @license https://getkirby.com/license 13 | */ 14 | class FilePermissions extends ModelPermissions 15 | { 16 | protected $category = 'files'; 17 | } 18 | -------------------------------------------------------------------------------- /src/Cms/SitePermissions.php: -------------------------------------------------------------------------------- 1 | 10 | * @link https://getkirby.com 11 | * @copyright Bastian Allgeier 12 | * @license https://getkirby.com/license 13 | */ 14 | class SitePermissions extends ModelPermissions 15 | { 16 | protected $category = 'site'; 17 | } 18 | -------------------------------------------------------------------------------- /src/Http/Exceptions/NextRouteException.php: -------------------------------------------------------------------------------- 1 | 10 | * @link https://getkirby.com 11 | * @copyright Bastian Allgeier 12 | * @license https://opensource.org/licenses/MIT 13 | */ 14 | class NextRouteException extends \Exception 15 | { 16 | } 17 | -------------------------------------------------------------------------------- /config/areas/account.php: -------------------------------------------------------------------------------- 1 | 'account', 8 | 'label' => I18n::translate('view.account'), 9 | 'search' => 'users', 10 | 'dialogs' => require __DIR__ . '/account/dialogs.php', 11 | 'dropdowns' => require __DIR__ . '/account/dropdowns.php', 12 | 'views' => require __DIR__ . '/account/views.php' 13 | ]; 14 | }; 15 | -------------------------------------------------------------------------------- /config/blueprints/blocks/heading.yml: -------------------------------------------------------------------------------- 1 | icon: title 2 | fields: 3 | text: 4 | type: text 5 | level: 6 | type: select 7 | width: 1/2 8 | empty: false 9 | default: "2" 10 | options: 11 | - value: "1" 12 | text: Heading 1 13 | - value: "2" 14 | text: Heading 2 15 | - value: "3" 16 | text: Heading 3 17 | id: 18 | type: text 19 | label: ID 20 | width: 1/2 21 | -------------------------------------------------------------------------------- /config/sections/mixins/search.php: -------------------------------------------------------------------------------- 1 | [ 7 | /** 8 | * Enable/disable the search in the sections 9 | */ 10 | 'search' => function (bool $search = false): bool { 11 | return $search; 12 | } 13 | ], 14 | 'methods' => [ 15 | 'searchterm' => function (): string|null { 16 | return App::instance()->request()->get('searchterm'); 17 | } 18 | ] 19 | ]; 20 | -------------------------------------------------------------------------------- /config/areas/users/dropdowns.php: -------------------------------------------------------------------------------- 1 | [ 9 | 'pattern' => 'users/(:any)', 10 | 'options' => function (string $id) { 11 | return Find::user($id)->panel()->dropdown(); 12 | } 13 | ], 14 | 'user.file' => [ 15 | 'pattern' => '(users/.*?)/files/(:any)', 16 | 'options' => $files['file'] 17 | ] 18 | ]; 19 | -------------------------------------------------------------------------------- /config/sections/mixins/min.php: -------------------------------------------------------------------------------- 1 | [ 5 | /** 6 | * Sets the minimum number of required entries in the section 7 | */ 8 | 'min' => function (int $min = null) { 9 | return $min; 10 | } 11 | ], 12 | 'methods' => [ 13 | 'validateMin' => function () { 14 | if ($this->min && $this->min > $this->total) { 15 | return false; 16 | } 17 | 18 | return true; 19 | } 20 | ] 21 | ]; 22 | -------------------------------------------------------------------------------- /vendor/psr/log/src/LogLevel.php: -------------------------------------------------------------------------------- 1 | 2 | 3 |

4 | This page is currently offline. We are very sorry for the inconvenience and will fix it as soon as possible. 5 |

6 |

7 | Advice for developers and administrators:
8 | Change the PHP version to one supported by your version of Kirby 9 |

10 | 11 | 12 | -------------------------------------------------------------------------------- /config/sections/mixins/empty.php: -------------------------------------------------------------------------------- 1 | [ 7 | /** 8 | * Sets the text for the empty state box 9 | */ 10 | 'empty' => function ($empty = null) { 11 | return I18n::translate($empty, $empty); 12 | } 13 | ], 14 | 'computed' => [ 15 | 'empty' => function () { 16 | if ($this->empty) { 17 | return $this->model()->toSafeString($this->empty); 18 | } 19 | } 20 | ] 21 | ]; 22 | -------------------------------------------------------------------------------- /src/Cms/LayoutColumns.php: -------------------------------------------------------------------------------- 1 | 11 | * @link https://getkirby.com 12 | * @copyright Bastian Allgeier 13 | * @license https://getkirby.com/license 14 | */ 15 | class LayoutColumns extends Items 16 | { 17 | public const ITEM_CLASS = LayoutColumn::class; 18 | } 19 | -------------------------------------------------------------------------------- /config/areas/logout.php: -------------------------------------------------------------------------------- 1 | 'user', 9 | 'label' => I18n::translate('logout'), 10 | 'views' => [ 11 | 'logout' => [ 12 | 'pattern' => 'logout', 13 | 'auth' => false, 14 | 'action' => function () use ($kirby) { 15 | $kirby->auth()->logout(); 16 | Panel::go('login'); 17 | }, 18 | ] 19 | ] 20 | ]; 21 | }; 22 | -------------------------------------------------------------------------------- /config/fields/mixins/min.php: -------------------------------------------------------------------------------- 1 | [ 5 | 'min' => function () { 6 | // set min to at least 1, if required 7 | if ($this->required === true) { 8 | return $this->min ?? 1; 9 | } 10 | 11 | return $this->min; 12 | }, 13 | 'required' => function () { 14 | // set required to true if min is set 15 | if ($this->min) { 16 | return true; 17 | } 18 | 19 | return $this->required; 20 | } 21 | ] 22 | ]; 23 | -------------------------------------------------------------------------------- /config/fields/list.php: -------------------------------------------------------------------------------- 1 | [ 5 | /** 6 | * Sets the allowed HTML formats. Available formats: `bold`, `italic`, `underline`, `strike`, `code`, `link`. Activate them all by passing `true`. Deactivate them all by passing `false` 7 | */ 8 | 'marks' => function ($marks = true) { 9 | return $marks; 10 | } 11 | ], 12 | 'computed' => [ 13 | 'value' => function () { 14 | return trim($this->value ?? ''); 15 | } 16 | ] 17 | ]; 18 | -------------------------------------------------------------------------------- /vendor/filp/whoops/src/Whoops/Exception/ErrorException.php: -------------------------------------------------------------------------------- 1 | 5 | */ 6 | 7 | namespace Whoops\Exception; 8 | 9 | use ErrorException as BaseErrorException; 10 | 11 | /** 12 | * Wraps ErrorException; mostly used for typing (at least now) 13 | * to easily cleanup the stack trace of redundant info. 14 | */ 15 | class ErrorException extends BaseErrorException 16 | { 17 | } 18 | -------------------------------------------------------------------------------- /kirby.pub: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Ux4q7LmQ5hfTYTtz3/a 3 | mohFJMWo/iCnxVcY84PZjLwWnT+G2DTKGaEWydB77TteJQnmsgtvO5734oj3Ga3r 4 | QCfwr2gxo/0WDEBq7C5HP+YNJiuZ/iD/tYV+gloF+Aaa3Mo8AK5DYH3dnjuyfHc1 5 | veIlYX1D2MXji2IRqdweAzVi1dfI4I3Ys8awhzv653vFLj5LvAtlwlYlmYeRwci7 6 | GkAOWw709CuKQNdPBXGFQQ/pEB5mnp8mI31j8og845u6v/Sk4+85gFORSufIRfnQ 7 | GFYrPOeavxfAWQGjh7JQjr/sbKSXaJ3nDlrYsOPIrC0Rwn/jsQPO7OLdVwkc9ofL 8 | GQIDAQAB 9 | -----END PUBLIC KEY----- 10 | -------------------------------------------------------------------------------- /config/blocks/quote/quote.yml: -------------------------------------------------------------------------------- 1 | name: field.blocks.quote.name 2 | icon: quote 3 | wysiwyg: true 4 | preview: quote 5 | fields: 6 | text: 7 | label: field.blocks.quote.text.label 8 | placeholder: field.blocks.quote.text.placeholder 9 | type: writer 10 | inline: true 11 | icon: quote 12 | citation: 13 | label: field.blocks.quote.citation.label 14 | placeholder: field.blocks.quote.citation.placeholder 15 | type: writer 16 | inline: true 17 | icon: user 18 | -------------------------------------------------------------------------------- /src/Toolkit/Config.php: -------------------------------------------------------------------------------- 1 | 11 | * @link https://getkirby.com 12 | * @copyright Bastian Allgeier 13 | * @license https://opensource.org/licenses/MIT 14 | */ 15 | class Config extends Silo 16 | { 17 | /** 18 | * @var array 19 | */ 20 | public static $data = []; 21 | } 22 | -------------------------------------------------------------------------------- /vendor/michelf/php-smartypants/Michelf/SmartyPantsTypographer.inc.php: -------------------------------------------------------------------------------- 1 | [ 7 | /** 8 | * Sets the help text 9 | */ 10 | 'help' => function ($help = null) { 11 | return I18n::translate($help, $help); 12 | } 13 | ], 14 | 'computed' => [ 15 | 'help' => function () { 16 | if ($this->help) { 17 | $help = $this->model()->toSafeString($this->help); 18 | $help = $this->kirby()->kirbytext($help); 19 | return $help; 20 | } 21 | } 22 | ] 23 | ]; 24 | -------------------------------------------------------------------------------- /vendor/psr/log/src/AbstractLogger.php: -------------------------------------------------------------------------------- 1 | 'users', 8 | 'label' => I18n::translate('view.users'), 9 | 'search' => 'users', 10 | 'menu' => true, 11 | 'dialogs' => require __DIR__ . '/users/dialogs.php', 12 | 'dropdowns' => require __DIR__ . '/users/dropdowns.php', 13 | 'searches' => require __DIR__ . '/users/searches.php', 14 | 'views' => require __DIR__ . '/users/views.php' 15 | ]; 16 | }; 17 | -------------------------------------------------------------------------------- /config/fields/range.php: -------------------------------------------------------------------------------- 1 | 'number', 5 | 'props' => [ 6 | /** 7 | * Unset inherited props 8 | */ 9 | 'placeholder' => null, 10 | 11 | /** 12 | * The maximum value on the slider 13 | */ 14 | 'max' => function (float $max = 100) { 15 | return $max; 16 | }, 17 | /** 18 | * Enables/disables the tooltip and set the before and after values 19 | */ 20 | 'tooltip' => function ($tooltip = true) { 21 | return $tooltip; 22 | }, 23 | ] 24 | ]; 25 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # This file is for unifying the coding style for different editors and IDEs 2 | # editorconfig.org 3 | 4 | # PHP PSR-12 Coding Standards 5 | # https://www.php-fig.org/psr/psr-12/ 6 | 7 | root = true 8 | 9 | [*] 10 | charset = utf-8 11 | end_of_line = lf 12 | indent_style = tab 13 | indent_size = 2 14 | trim_trailing_whitespace = true 15 | 16 | [*.php] 17 | indent_size = 4 18 | insert_final_newline = true 19 | 20 | [*.yml] 21 | indent_style = space 22 | 23 | [*.md] 24 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /config/api/models/SiteBlueprint.php: -------------------------------------------------------------------------------- 1 | [ 10 | 'name' => fn (SiteBlueprint $blueprint) => $blueprint->name(), 11 | 'options' => fn (SiteBlueprint $blueprint) => $blueprint->options(), 12 | 'tabs' => fn (SiteBlueprint $blueprint) => $blueprint->tabs(), 13 | 'title' => fn (SiteBlueprint $blueprint) => $blueprint->title(), 14 | ], 15 | 'type' => 'Kirby\Cms\SiteBlueprint', 16 | 'views' => [], 17 | ]; 18 | -------------------------------------------------------------------------------- /config/api/models/FileBlueprint.php: -------------------------------------------------------------------------------- 1 | [ 10 | 'name' => fn (FileBlueprint $blueprint) => $blueprint->name(), 11 | 'options' => fn (FileBlueprint $blueprint) => $blueprint->options(), 12 | 'tabs' => fn (FileBlueprint $blueprint) => $blueprint->tabs(), 13 | 'title' => fn (FileBlueprint $blueprint) => $blueprint->title(), 14 | ], 15 | 'type' => 'Kirby\Cms\FileBlueprint', 16 | 'views' => [ 17 | ], 18 | ]; 19 | -------------------------------------------------------------------------------- /config/api/models/UserBlueprint.php: -------------------------------------------------------------------------------- 1 | [ 10 | 'name' => fn (UserBlueprint $blueprint) => $blueprint->name(), 11 | 'options' => fn (UserBlueprint $blueprint) => $blueprint->options(), 12 | 'tabs' => fn (UserBlueprint $blueprint) => $blueprint->tabs(), 13 | 'title' => fn (UserBlueprint $blueprint) => $blueprint->title(), 14 | ], 15 | 'type' => 'Kirby\Cms\UserBlueprint', 16 | 'views' => [ 17 | ], 18 | ]; 19 | -------------------------------------------------------------------------------- /config/api/routes/translations.php: -------------------------------------------------------------------------------- 1 | 'translations', 9 | 'method' => 'GET', 10 | 'auth' => false, 11 | 'action' => function () { 12 | return $this->kirby()->translations(); 13 | } 14 | ], 15 | [ 16 | 'pattern' => 'translations/(:any)', 17 | 'method' => 'GET', 18 | 'auth' => false, 19 | 'action' => function (string $code) { 20 | return $this->kirby()->translations()->find($code); 21 | } 22 | ] 23 | 24 | ]; 25 | -------------------------------------------------------------------------------- /config/api/models/Role.php: -------------------------------------------------------------------------------- 1 | [ 10 | 'description' => fn (Role $role) => $role->description(), 11 | 'name' => fn (Role $role) => $role->name(), 12 | 'permissions' => fn (Role $role) => $role->permissions()->toArray(), 13 | 'title' => fn (Role $role) => $role->title(), 14 | ], 15 | 'type' => 'Kirby\Cms\Role', 16 | 'views' => [ 17 | 'compact' => [ 18 | 'description', 19 | 'name', 20 | 'title' 21 | ] 22 | ] 23 | ]; 24 | -------------------------------------------------------------------------------- /vendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php: -------------------------------------------------------------------------------- 1 | 2 | 3 |

4 | This page is currently offline due to an unexpected error. We are very sorry for the inconvenience and will fix it as soon as possible. 5 |

6 |

7 | Advice for developers and administrators:
8 | Enable debug mode to get further information about the error. 9 |

10 | 11 | 12 | -------------------------------------------------------------------------------- /config/blocks/heading/heading.yml: -------------------------------------------------------------------------------- 1 | name: field.blocks.heading.name 2 | icon: title 3 | wysiwyg: true 4 | preview: heading 5 | fields: 6 | level: 7 | label: field.blocks.heading.level 8 | type: select 9 | empty: false 10 | default: "h2" 11 | width: 1/6 12 | options: 13 | - h1 14 | - h2 15 | - h3 16 | - h4 17 | - h5 18 | - h6 19 | text: 20 | label: field.blocks.heading.text 21 | type: writer 22 | inline: true 23 | width: 5/6 24 | placeholder: field.blocks.heading.placeholder 25 | -------------------------------------------------------------------------------- /src/Cms/R.php: -------------------------------------------------------------------------------- 1 | 12 | * @link https://getkirby.com 13 | * @copyright Bastian Allgeier 14 | * @license https://getkirby.com/license 15 | */ 16 | class R extends Facade 17 | { 18 | /** 19 | * @return \Kirby\Http\Request 20 | */ 21 | public static function instance() 22 | { 23 | return App::instance()->request(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Cms/S.php: -------------------------------------------------------------------------------- 1 | 12 | * @link https://getkirby.com 13 | * @copyright Bastian Allgeier 14 | * @license https://getkirby.com/license 15 | */ 16 | class S extends Facade 17 | { 18 | /** 19 | * @return \Kirby\Session\Session 20 | */ 21 | public static function instance() 22 | { 23 | return App::instance()->session(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /config/blueprints/blocks/table.yml: -------------------------------------------------------------------------------- 1 | name: Table 2 | icon: menu 3 | fields: 4 | rows: 5 | label: Menu 6 | type: structure 7 | columns: 8 | dish: true 9 | description: true 10 | price: 11 | before: € 12 | width: 1/4 13 | align: right 14 | fields: 15 | dish: 16 | label: Dish 17 | type: text 18 | description: 19 | label: Description 20 | type: text 21 | price: 22 | label: Price 23 | type: number 24 | before: € 25 | step: 0.01 26 | -------------------------------------------------------------------------------- /i18n/rules/fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "À": "A", 3 | "Â": "A", 4 | "Æ": "AE", 5 | "Ç": "C", 6 | "É": "E", 7 | "È": "E", 8 | "Ê": "E", 9 | "Ë": "E", 10 | "Ï": "I", 11 | "Î": "I", 12 | "Ô": "O", 13 | "Œ": "OE", 14 | "Ù": "U", 15 | "Û": "U", 16 | "Ü": "U", 17 | "à": "a", 18 | "â": "a", 19 | "æ": "ae", 20 | "ç": "c", 21 | "é": "e", 22 | "è": "e", 23 | "ê": "e", 24 | "ë": "e", 25 | "ï": "i", 26 | "î": "i", 27 | "ô": "o", 28 | "œ": "oe", 29 | "ù": "u", 30 | "û": "u", 31 | "ü": "u", 32 | "ÿ": "y", 33 | "Ÿ": "Y" 34 | } 35 | -------------------------------------------------------------------------------- /config/fields/tel.php: -------------------------------------------------------------------------------- 1 | 'text', 5 | 'props' => [ 6 | /** 7 | * Unset inherited props 8 | */ 9 | 'converter' => null, 10 | 'counter' => null, 11 | 'spellcheck' => null, 12 | 13 | /** 14 | * Sets the HTML5 autocomplete attribute 15 | */ 16 | 'autocomplete' => function (string $autocomplete = 'tel') { 17 | return $autocomplete; 18 | }, 19 | 20 | /** 21 | * Changes the phone icon 22 | */ 23 | 'icon' => function (string $icon = 'phone') { 24 | return $icon; 25 | } 26 | ] 27 | ]; 28 | -------------------------------------------------------------------------------- /src/Cms/Visitor.php: -------------------------------------------------------------------------------- 1 | 12 | * @link https://getkirby.com 13 | * @copyright Bastian Allgeier 14 | * @license https://getkirby.com/license 15 | */ 16 | class Visitor extends Facade 17 | { 18 | /** 19 | * @return \Kirby\Http\Visitor 20 | */ 21 | public static function instance() 22 | { 23 | return App::instance()->visitor(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Uuid/Identifiable.php: -------------------------------------------------------------------------------- 1 | 13 | * @link https://getkirby.com 14 | * @copyright Bastian Allgeier 15 | * @license https://getkirby.com/license 16 | */ 17 | interface Identifiable 18 | { 19 | public function id(); 20 | public function uuid(): Uuid|null; 21 | } 22 | -------------------------------------------------------------------------------- /config/fields/mixins/layout.php: -------------------------------------------------------------------------------- 1 | [ 5 | /** 6 | * Changes the layout of the selected entries. 7 | * Available layouts: `list`, `cardlets`, `cards` 8 | */ 9 | 'layout' => function (string $layout = 'list') { 10 | $layouts = ['list', 'cardlets', 'cards']; 11 | return in_array($layout, $layouts) ? $layout : 'list'; 12 | }, 13 | 14 | /** 15 | * Layout size for cards: `tiny`, `small`, `medium`, `large` or `huge` 16 | */ 17 | 'size' => function (string $size = 'auto') { 18 | return $size; 19 | }, 20 | ] 21 | ]; 22 | -------------------------------------------------------------------------------- /i18n/rules/ar.json: -------------------------------------------------------------------------------- 1 | { 2 | "أ" : "a", 3 | "ب" : "b", 4 | "ت" : "t", 5 | "ث" : "th", 6 | "ج" : "g", 7 | "ح" : "h", 8 | "خ" : "kh", 9 | "د" : "d", 10 | "ذ" : "th", 11 | "ر" : "r", 12 | "ز" : "z", 13 | "س" : "s", 14 | "ش" : "sh", 15 | "ص" : "s", 16 | "ض" : "d", 17 | "ط" : "t", 18 | "ظ" : "th", 19 | "ع" : "aa", 20 | "غ" : "gh", 21 | "ف" : "f", 22 | "ق" : "k", 23 | "ك" : "k", 24 | "ل" : "l", 25 | "م" : "m", 26 | "ن" : "n", 27 | "ه" : "h", 28 | "و" : "o", 29 | "ي" : "y" 30 | } 31 | -------------------------------------------------------------------------------- /vendor/claviska/simpleimage/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "claviska/simpleimage", 3 | "description": "A PHP class that makes working with images as simple as possible.", 4 | "license": "MIT", 5 | "require": { 6 | "php": ">=5.6.0", 7 | "ext-gd": "*", 8 | "league/color-extractor": "0.3.*" 9 | }, 10 | "authors": [ 11 | { 12 | "name": "Cory LaViska", 13 | "homepage": "http://www.abeautifulsite.net/", 14 | "role": "Developer" 15 | } 16 | ], 17 | "autoload": { 18 | "psr-0": { 19 | "claviska": "src/" 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /vendor/psr/log/src/LoggerAwareTrait.php: -------------------------------------------------------------------------------- 1 | logger = $logger; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /config/sections/mixins/max.php: -------------------------------------------------------------------------------- 1 | [ 5 | /** 6 | * Sets the maximum number of allowed entries in the section 7 | */ 8 | 'max' => function (int $max = null) { 9 | return $max; 10 | } 11 | ], 12 | 'methods' => [ 13 | 'isFull' => function () { 14 | if ($this->max) { 15 | return $this->total >= $this->max; 16 | } 17 | 18 | return false; 19 | }, 20 | 'validateMax' => function () { 21 | if ($this->max && $this->total > $this->max) { 22 | return false; 23 | } 24 | 25 | return true; 26 | } 27 | ] 28 | ]; 29 | -------------------------------------------------------------------------------- /config/fields/headline.php: -------------------------------------------------------------------------------- 1 | false, 5 | 'props' => [ 6 | /** 7 | * Unset inherited props 8 | */ 9 | 'after' => null, 10 | 'autofocus' => null, 11 | 'before' => null, 12 | 'default' => null, 13 | 'disabled' => null, 14 | 'icon' => null, 15 | 'placeholder' => null, 16 | 'required' => null, 17 | 'translate' => null, 18 | 19 | /** 20 | * If `false`, the prepended number will be hidden 21 | */ 22 | 'numbered' => function (bool $numbered = true) { 23 | return $numbered; 24 | } 25 | ] 26 | ]; 27 | -------------------------------------------------------------------------------- /src/Exception/NotFoundException.php: -------------------------------------------------------------------------------- 1 | 11 | * @link https://getkirby.com 12 | * @copyright Bastian Allgeier 13 | * @license https://opensource.org/licenses/MIT 14 | */ 15 | class NotFoundException extends Exception 16 | { 17 | protected static $defaultKey = 'notFound'; 18 | protected static $defaultFallback = 'Not found'; 19 | protected static $defaultHttpCode = 404; 20 | } 21 | -------------------------------------------------------------------------------- /config/blocks/gallery/gallery.php: -------------------------------------------------------------------------------- 1 | caption(); 4 | $crop = $block->crop()->isTrue(); 5 | $ratio = $block->ratio()->or('auto'); 6 | ?> 7 | $ratio, 'data-crop' => $crop], null, ' ') ?>> 8 |
    9 | images()->toFiles() as $image): ?> 10 |
  • 11 | 12 |
  • 13 | 14 |
15 | isNotEmpty()): ?> 16 |
17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /src/Exception/LogicException.php: -------------------------------------------------------------------------------- 1 | 11 | * @link https://getkirby.com 12 | * @copyright Bastian Allgeier 13 | * @license https://opensource.org/licenses/MIT 14 | */ 15 | class LogicException extends Exception 16 | { 17 | protected static $defaultKey = 'logic'; 18 | protected static $defaultFallback = 'This task cannot be finished'; 19 | protected static $defaultHttpCode = 400; 20 | } 21 | -------------------------------------------------------------------------------- /vendor/symfony/polyfill-intl-idn/Info.php: -------------------------------------------------------------------------------- 1 | and Trevor Rowbotham 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Symfony\Polyfill\Intl\Idn; 13 | 14 | /** 15 | * @internal 16 | */ 17 | class Info 18 | { 19 | public $bidiDomain = false; 20 | public $errors = 0; 21 | public $validBidiDomain = true; 22 | public $transitionalDifferent = false; 23 | } 24 | -------------------------------------------------------------------------------- /src/Exception/ErrorPageException.php: -------------------------------------------------------------------------------- 1 | 12 | * @link https://getkirby.com 13 | * @copyright Bastian Allgeier 14 | * @license https://opensource.org/licenses/MIT 15 | */ 16 | class ErrorPageException extends Exception 17 | { 18 | protected static $defaultKey = 'errorPage'; 19 | protected static $defaultFallback = 'Triggered error page'; 20 | protected static $defaultHttpCode = 404; 21 | } 22 | -------------------------------------------------------------------------------- /config/api/routes/roles.php: -------------------------------------------------------------------------------- 1 | 'roles', 9 | 'method' => 'GET', 10 | 'action' => function () { 11 | $kirby = $this->kirby(); 12 | 13 | return match ($kirby->request()->get('canBe')) { 14 | 'changed' => $kirby->roles()->canBeChanged(), 15 | 'created' => $kirby->roles()->canBeCreated(), 16 | default => $kirby->roles() 17 | }; 18 | } 19 | ], 20 | [ 21 | 'pattern' => 'roles/(:any)', 22 | 'method' => 'GET', 23 | 'action' => function (string $name) { 24 | return $this->kirby()->roles()->find($name); 25 | } 26 | ] 27 | ]; 28 | -------------------------------------------------------------------------------- /i18n/rules/ka.json: -------------------------------------------------------------------------------- 1 | { 2 | "ა": "a", 3 | "ბ": "b", 4 | "გ": "g", 5 | "დ": "d", 6 | "ე": "e", 7 | "ვ": "v", 8 | "ზ": "z", 9 | "თ": "t", 10 | "ი": "i", 11 | "კ": "k", 12 | "ლ": "l", 13 | "მ": "m", 14 | "ნ": "n", 15 | "ო": "o", 16 | "პ": "p", 17 | "ჟ": "zh", 18 | "რ": "r", 19 | "ს": "s", 20 | "ტ": "t", 21 | "უ": "u", 22 | "ფ": "f", 23 | "ქ": "k", 24 | "ღ": "gh", 25 | "ყ": "q", 26 | "შ": "sh", 27 | "ჩ": "ch", 28 | "ც": "ts", 29 | "ძ": "dz", 30 | "წ": "ts", 31 | "ჭ": "ch", 32 | "ხ": "kh", 33 | "ჯ": "j", 34 | "ჰ": "h" 35 | } 36 | -------------------------------------------------------------------------------- /src/Exception/DuplicateException.php: -------------------------------------------------------------------------------- 1 | 12 | * @link https://getkirby.com 13 | * @copyright Bastian Allgeier 14 | * @license https://opensource.org/licenses/MIT 15 | */ 16 | class DuplicateException extends Exception 17 | { 18 | protected static $defaultKey = 'duplicate'; 19 | protected static $defaultFallback = 'The entry exists'; 20 | protected static $defaultHttpCode = 400; 21 | } 22 | -------------------------------------------------------------------------------- /config/areas/languages/views.php: -------------------------------------------------------------------------------- 1 | [ 8 | 'pattern' => 'languages', 9 | 'action' => function () { 10 | $kirby = App::instance(); 11 | 12 | return [ 13 | 'component' => 'k-languages-view', 14 | 'props' => [ 15 | 'languages' => $kirby->languages()->values(fn ($language) => [ 16 | 'default' => $language->isDefault(), 17 | 'id' => $language->code(), 18 | 'info' => Escape::html($language->code()), 19 | 'text' => Escape::html($language->name()), 20 | ]) 21 | ] 22 | ]; 23 | } 24 | ], 25 | ]; 26 | -------------------------------------------------------------------------------- /config/areas/site/dropdowns.php: -------------------------------------------------------------------------------- 1 | [ 9 | 'pattern' => 'changes', 10 | 'options' => fn () => Dropdown::changes() 11 | ], 12 | 'page' => [ 13 | 'pattern' => 'pages/(:any)', 14 | 'options' => function (string $path) { 15 | return Find::page($path)->panel()->dropdown(); 16 | } 17 | ], 18 | 'page.file' => [ 19 | 'pattern' => '(pages/.*?)/files/(:any)', 20 | 'options' => $files['file'] 21 | ], 22 | 'site.file' => [ 23 | 'pattern' => '(site)/files/(:any)', 24 | 'options' => $files['file'] 25 | ] 26 | ]; 27 | -------------------------------------------------------------------------------- /config/areas/account/views.php: -------------------------------------------------------------------------------- 1 | [ 8 | 'pattern' => 'account', 9 | 'action' => fn () => [ 10 | 'component' => 'k-account-view', 11 | 'props' => App::instance()->user()->panel()->props(), 12 | ], 13 | ], 14 | 'account.file' => [ 15 | 'pattern' => 'account/files/(:any)', 16 | 'action' => function (string $filename) { 17 | return Find::file('account', $filename)->panel()->view(); 18 | } 19 | ], 20 | 'account.password' => [ 21 | 'pattern' => 'reset-password', 22 | 'action' => fn () => ['component' => 'k-reset-password-view'] 23 | ] 24 | ]; 25 | -------------------------------------------------------------------------------- /config/areas/site.php: -------------------------------------------------------------------------------- 1 | function () use ($kirby) { 8 | return $kirby->site()->title()->or(I18n::translate('view.site'))->toString(); 9 | }, 10 | 'icon' => 'home', 11 | 'label' => $kirby->site()->blueprint()->title() ?? I18n::translate('view.site'), 12 | 'menu' => true, 13 | 'dialogs' => require __DIR__ . '/site/dialogs.php', 14 | 'dropdowns' => require __DIR__ . '/site/dropdowns.php', 15 | 'searches' => require __DIR__ . '/site/searches.php', 16 | 'views' => require __DIR__ . '/site/views.php', 17 | ]; 18 | }; 19 | -------------------------------------------------------------------------------- /src/Exception/PermissionException.php: -------------------------------------------------------------------------------- 1 | 12 | * @link https://getkirby.com 13 | * @copyright Bastian Allgeier 14 | * @license https://opensource.org/licenses/MIT 15 | */ 16 | class PermissionException extends Exception 17 | { 18 | protected static $defaultKey = 'permission'; 19 | protected static $defaultFallback = 'You are not allowed to do this'; 20 | protected static $defaultHttpCode = 403; 21 | } 22 | -------------------------------------------------------------------------------- /vendor/composer/autoload_files.php: -------------------------------------------------------------------------------- 1 | $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php', 10 | 'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php', 11 | '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', 12 | 'f864ae44e8154e5ff6f4eec32f46d37f' => $baseDir . '/config/setup.php', 13 | '87988fc7b1c1f093da22a1a3de972f3a' => $baseDir . '/config/helpers.php', 14 | ); 15 | -------------------------------------------------------------------------------- /config/fields/radio.php: -------------------------------------------------------------------------------- 1 | ['options'], 5 | 'props' => [ 6 | /** 7 | * Unset inherited props 8 | */ 9 | 'after' => null, 10 | 'before' => null, 11 | 'icon' => null, 12 | 'placeholder' => null, 13 | 14 | /** 15 | * Arranges the radio buttons in the given number of columns 16 | */ 17 | 'columns' => function (int $columns = 1) { 18 | return $columns; 19 | }, 20 | ], 21 | 'computed' => [ 22 | 'default' => function () { 23 | return $this->sanitizeOption($this->default); 24 | }, 25 | 'value' => function () { 26 | return $this->sanitizeOption($this->value) ?? ''; 27 | } 28 | ] 29 | ]; 30 | -------------------------------------------------------------------------------- /config/presets/files.php: -------------------------------------------------------------------------------- 1 | [ 8 | 'label' => $props['label'] ?? $props['headline'] ?? I18n::translate('files'), 9 | 'type' => 'files', 10 | 'layout' => $props['layout'] ?? 'cards', 11 | 'template' => $props['template'] ?? null, 12 | 'image' => $props['image'] ?? null, 13 | 'info' => '{{ file.dimensions }}' 14 | ] 15 | ]; 16 | 17 | // remove global options 18 | unset( 19 | $props['headline'], 20 | $props['label'], 21 | $props['layout'], 22 | $props['template'], 23 | $props['image'] 24 | ); 25 | 26 | return $props; 27 | }; 28 | -------------------------------------------------------------------------------- /vendor/psr/log/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "psr/log", 3 | "description": "Common interface for logging libraries", 4 | "keywords": ["psr", "psr-3", "log"], 5 | "homepage": "https://github.com/php-fig/log", 6 | "license": "MIT", 7 | "authors": [ 8 | { 9 | "name": "PHP-FIG", 10 | "homepage": "https://www.php-fig.org/" 11 | } 12 | ], 13 | "require": { 14 | "php": ">=8.0.0" 15 | }, 16 | "autoload": { 17 | "psr-4": { 18 | "Psr\\Log\\": "src" 19 | } 20 | }, 21 | "extra": { 22 | "branch-alias": { 23 | "dev-master": "3.x-dev" 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /i18n/rules/fa.json: -------------------------------------------------------------------------------- 1 | { 2 | "آ" : "A", 3 | "ا" : "a", 4 | "ب" : "b", 5 | "پ" : "p", 6 | "ت" : "t", 7 | "ث" : "th", 8 | "ج" : "j", 9 | "چ" : "ch", 10 | "ح" : "h", 11 | "خ" : "kh", 12 | "د" : "d", 13 | "ذ" : "th", 14 | "ر" : "r", 15 | "ز" : "z", 16 | "ژ" : "zh", 17 | "س" : "s", 18 | "ش" : "sh", 19 | "ص" : "s", 20 | "ض" : "z", 21 | "ط" : "t", 22 | "ظ" : "z", 23 | "ع" : "a", 24 | "غ" : "gh", 25 | "ف" : "f", 26 | "ق" : "g", 27 | "ك" : "k", 28 | "ک" : "k", 29 | "گ" : "g", 30 | "ل" : "l", 31 | "م" : "m", 32 | "ن" : "n", 33 | "و" : "o", 34 | "ه" : "h", 35 | "ی" : "y" 36 | } 37 | -------------------------------------------------------------------------------- /src/Blueprint/NodeIcon.php: -------------------------------------------------------------------------------- 1 | 10 | * @link https://getkirby.com 11 | * @copyright Bastian Allgeier 12 | * @license https://opensource.org/licenses/MIT 13 | * 14 | * // TODO: include in test coverage in 3.10 15 | * @codeCoverageIgnore 16 | */ 17 | class NodeIcon extends NodeString 18 | { 19 | public static function field() 20 | { 21 | $field = parent::field(); 22 | $field->id = 'icon'; 23 | $field->label->translations = ['en' => 'Icon']; 24 | 25 | return $field; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Blueprint/NodeProperty.php: -------------------------------------------------------------------------------- 1 | 12 | * @link https://getkirby.com 13 | * @copyright Bastian Allgeier 14 | * @license https://opensource.org/licenses/MIT 15 | * 16 | * // TODO: include in test coverage in 3.10 17 | * @codeCoverageIgnore 18 | */ 19 | abstract class NodeProperty 20 | { 21 | abstract public static function factory($value = null): static|null; 22 | 23 | public function render(ModelWithContent $model) 24 | { 25 | return null; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /config/api/models/Translation.php: -------------------------------------------------------------------------------- 1 | [ 10 | 'author' => fn (Translation $translation) => $translation->author(), 11 | 'data' => fn (Translation $translation) => $translation->dataWithFallback(), 12 | 'direction' => fn (Translation $translation) => $translation->direction(), 13 | 'id' => fn (Translation $translation) => $translation->id(), 14 | 'name' => fn (Translation $translation) => $translation->name(), 15 | ], 16 | 'type' => 'Kirby\Cms\Translation', 17 | 'views' => [ 18 | 'compact' => [ 19 | 'direction', 20 | 'id', 21 | 'name' 22 | ] 23 | ] 24 | ]; 25 | -------------------------------------------------------------------------------- /config/areas/users/searches.php: -------------------------------------------------------------------------------- 1 | [ 9 | 'label' => I18n::translate('users'), 10 | 'icon' => 'users', 11 | 'query' => function (string $query = null) { 12 | $users = App::instance()->users()->search($query)->limit(10); 13 | $results = []; 14 | 15 | foreach ($users as $user) { 16 | $results[] = [ 17 | 'image' => $user->panel()->image(), 18 | 'text' => Escape::html($user->username()), 19 | 'link' => $user->panel()->url(true), 20 | 'info' => Escape::html($user->role()->title()) 21 | ]; 22 | } 23 | 24 | return $results; 25 | } 26 | ] 27 | ]; 28 | -------------------------------------------------------------------------------- /src/Exception/BadMethodCallException.php: -------------------------------------------------------------------------------- 1 | 11 | * @link https://getkirby.com 12 | * @copyright Bastian Allgeier 13 | * @license https://opensource.org/licenses/MIT 14 | */ 15 | class BadMethodCallException extends Exception 16 | { 17 | protected static $defaultKey = 'invalidMethod'; 18 | protected static $defaultFallback = 'The method "{ method }" does not exist'; 19 | protected static $defaultHttpCode = 400; 20 | protected static $defaultData = ['method' => null]; 21 | } 22 | -------------------------------------------------------------------------------- /src/Http/Request/Auth/BearerAuth.php: -------------------------------------------------------------------------------- 1 | 12 | * @link https://getkirby.com 13 | * @copyright Bastian Allgeier 14 | * @license https://opensource.org/licenses/MIT 15 | */ 16 | class BearerAuth extends Auth 17 | { 18 | /** 19 | * Returns the authentication token 20 | */ 21 | public function token(): string 22 | { 23 | return $this->data; 24 | } 25 | 26 | /** 27 | * Returns the auth type 28 | */ 29 | public function type(): string 30 | { 31 | return 'bearer'; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /vendor/michelf/php-smartypants/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "michelf/php-smartypants", 3 | "type": "library", 4 | "description": "PHP SmartyPants", 5 | "homepage": "https://michelf.ca/projects/php-smartypants/", 6 | "keywords": ["quotes", "dashes", "spaces", "typography", "typographer"], 7 | "license": "BSD-3-Clause", 8 | "authors": [ 9 | { 10 | "name": "Michel Fortin", 11 | "email": "michel.fortin@michelf.ca", 12 | "homepage": "https://michelf.ca/", 13 | "role": "Developer" 14 | }, 15 | { 16 | "name": "John Gruber", 17 | "homepage": "https://daringfireball.net/" 18 | } 19 | ], 20 | "require": { 21 | "php": ">=5.3.0" 22 | }, 23 | "autoload": { 24 | "psr-0": { "Michelf": "" } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Cms/Response.php: -------------------------------------------------------------------------------- 1 | 11 | * @link https://getkirby.com 12 | * @copyright Bastian Allgeier 13 | * @license https://getkirby.com/license 14 | */ 15 | class Response extends \Kirby\Http\Response 16 | { 17 | /** 18 | * Adjusted redirect creation which 19 | * parses locations with the Url::to method 20 | * first. 21 | */ 22 | public static function redirect(string $location = '/', int $code = 302): static 23 | { 24 | return parent::redirect(Url::to($location), $code); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /config/sections/info.php: -------------------------------------------------------------------------------- 1 | [ 7 | 'headline', 8 | ], 9 | 'props' => [ 10 | 'text' => function ($text = null) { 11 | return I18n::translate($text, $text); 12 | }, 13 | 'theme' => function (string $theme = null) { 14 | return $theme; 15 | } 16 | ], 17 | 'computed' => [ 18 | 'text' => function () { 19 | if ($this->text) { 20 | $text = $this->model()->toSafeString($this->text); 21 | $text = $this->kirby()->kirbytext($text); 22 | return $text; 23 | } 24 | }, 25 | ], 26 | 'toArray' => function () { 27 | return [ 28 | 'label' => $this->headline, 29 | 'text' => $this->text, 30 | 'theme' => $this->theme 31 | ]; 32 | } 33 | ]; 34 | -------------------------------------------------------------------------------- /config/api/models/PageBlueprint.php: -------------------------------------------------------------------------------- 1 | [ 10 | 'name' => fn (PageBlueprint $blueprint) => $blueprint->name(), 11 | 'num' => fn (PageBlueprint $blueprint) => $blueprint->num(), 12 | 'options' => fn (PageBlueprint $blueprint) => $blueprint->options(), 13 | 'preview' => fn (PageBlueprint $blueprint) => $blueprint->preview(), 14 | 'status' => fn (PageBlueprint $blueprint) => $blueprint->status(), 15 | 'tabs' => fn (PageBlueprint $blueprint) => $blueprint->tabs(), 16 | 'title' => fn (PageBlueprint $blueprint) => $blueprint->title(), 17 | ], 18 | 'type' => 'Kirby\Cms\PageBlueprint', 19 | 'views' => [ 20 | ], 21 | ]; 22 | -------------------------------------------------------------------------------- /src/Exception/InvalidArgumentException.php: -------------------------------------------------------------------------------- 1 | 11 | * @link https://getkirby.com 12 | * @copyright Bastian Allgeier 13 | * @license https://opensource.org/licenses/MIT 14 | */ 15 | class InvalidArgumentException extends Exception 16 | { 17 | protected static $defaultKey = 'invalidArgument'; 18 | protected static $defaultFallback = 'Invalid argument "{ argument }" in method "{ method }"'; 19 | protected static $defaultHttpCode = 400; 20 | protected static $defaultData = ['argument' => null, 'method' => null]; 21 | } 22 | -------------------------------------------------------------------------------- /src/Blueprint/NodeText.php: -------------------------------------------------------------------------------- 1 | 13 | * @link https://getkirby.com 14 | * @copyright Bastian Allgeier 15 | * @license https://opensource.org/licenses/MIT 16 | * 17 | * // TODO: include in test coverage in 3.10 18 | * @codeCoverageIgnore 19 | */ 20 | class NodeText extends NodeI18n 21 | { 22 | public function render(ModelWithContent $model): ?string 23 | { 24 | if ($text = parent::render($model)) { 25 | return $model->toSafeString($text); 26 | } 27 | 28 | return $text; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Cms/NestCollection.php: -------------------------------------------------------------------------------- 1 | 13 | * @link https://getkirby.com 14 | * @copyright Bastian Allgeier 15 | * @license https://getkirby.com/license 16 | */ 17 | class NestCollection extends BaseCollection 18 | { 19 | /** 20 | * Converts all objects in the collection 21 | * to an array. This can also take a callback 22 | * function to further modify the array result. 23 | */ 24 | public function toArray(Closure $map = null): array 25 | { 26 | return parent::toArray($map ?? fn ($object) => $object->toArray()); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /config/areas/site/views.php: -------------------------------------------------------------------------------- 1 | [ 8 | 'pattern' => 'pages/(:any)', 9 | 'action' => fn (string $path) => Find::page($path)->panel()->view() 10 | ], 11 | 'page.file' => [ 12 | 'pattern' => 'pages/(:any)/files/(:any)', 13 | 'action' => function (string $id, string $filename) { 14 | return Find::file('pages/' . $id, $filename)->panel()->view(); 15 | } 16 | ], 17 | 'site' => [ 18 | 'pattern' => 'site', 19 | 'action' => fn () => App::instance()->site()->panel()->view() 20 | ], 21 | 'site.file' => [ 22 | 'pattern' => 'site/files/(:any)', 23 | 'action' => function (string $filename) { 24 | return Find::file('site', $filename)->panel()->view(); 25 | } 26 | ], 27 | ]; 28 | -------------------------------------------------------------------------------- /vendor/filp/whoops/src/Whoops/Resources/views/frames_description.html.php: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | Application frames (countIsApplication() ?>) 5 | 6 | 7 | All frames () 8 | 9 | 10 | 11 | Stack frames () 12 | 13 | 14 |
15 | -------------------------------------------------------------------------------- /src/Uuid/HasUuids.php: -------------------------------------------------------------------------------- 1 | 10 | * @link https://getkirby.com 11 | * @copyright Bastian Allgeier 12 | * @license https://getkirby.com/license 13 | */ 14 | trait HasUuids 15 | { 16 | /** 17 | * Find a single element by global UUID 18 | * @since 3.8.0 19 | */ 20 | protected function findByUuid( 21 | string $uuid, 22 | string|null $scheme = null 23 | ): Identifiable|null { 24 | if (Uuid::is($uuid, $scheme) === true) { 25 | // look up model by UUID while prioritizing 26 | // $this collection when searching 27 | return Uuid::for($uuid, $this)->model(); 28 | } 29 | 30 | return null; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /config/api/authentication.php: -------------------------------------------------------------------------------- 1 | kirby()->auth(); 7 | $allowImpersonation = $this->kirby()->option('api.allowImpersonation') ?? false; 8 | 9 | // csrf token check 10 | if ( 11 | $auth->type($allowImpersonation) === 'session' && 12 | $auth->csrf() === false 13 | ) { 14 | throw new PermissionException('Unauthenticated'); 15 | } 16 | 17 | // get user from session or basic auth 18 | if ($user = $auth->user(null, $allowImpersonation)) { 19 | if ($user->role()->permissions()->for('access', 'panel') === false) { 20 | throw new PermissionException(['key' => 'access.panel']); 21 | } 22 | 23 | return $user; 24 | } 25 | 26 | throw new PermissionException('Unauthenticated'); 27 | }; 28 | -------------------------------------------------------------------------------- /src/Panel/Search.php: -------------------------------------------------------------------------------- 1 | 15 | * @link https://getkirby.com 16 | * @copyright Bastian Allgeier 17 | * @license https://getkirby.com/license 18 | */ 19 | class Search extends Json 20 | { 21 | protected static string $key = '$search'; 22 | 23 | public static function response($data, array $options = []): Response 24 | { 25 | if (is_array($data) === true) { 26 | $data = [ 27 | 'results' => $data 28 | ]; 29 | } 30 | 31 | return parent::response($data, $options); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /config/api/routes.php: -------------------------------------------------------------------------------- 1 | option('languages', false) !== false) { 22 | $routes = array_merge($routes, include __DIR__ . '/routes/languages.php'); 23 | } 24 | 25 | return $routes; 26 | }; 27 | -------------------------------------------------------------------------------- /config/fields/mixins/datetime.php: -------------------------------------------------------------------------------- 1 | [ 7 | /** 8 | * Defines a custom format that is used when the field is saved 9 | */ 10 | 'format' => function (string $format = null) { 11 | return $format; 12 | } 13 | ], 14 | 'methods' => [ 15 | 'toDatetime' => function ($value, string $format = 'Y-m-d H:i:s') { 16 | if ($date = Date::optional($value)) { 17 | if ($this->step) { 18 | $step = Date::stepConfig($this->step); 19 | $date->round($step['unit'], $step['size']); 20 | } 21 | 22 | return $date->format($format); 23 | } 24 | 25 | return null; 26 | } 27 | ], 28 | 'save' => function ($value) { 29 | if ($date = Date::optional($value)) { 30 | return $date->format($this->format); 31 | } 32 | 33 | return ''; 34 | }, 35 | ]; 36 | -------------------------------------------------------------------------------- /vendor/symfony/polyfill-intl-normalizer/bootstrap80.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | use Symfony\Polyfill\Intl\Normalizer as p; 13 | 14 | if (!function_exists('normalizer_is_normalized')) { 15 | function normalizer_is_normalized(?string $string, ?int $form = p\Normalizer::FORM_C): bool { return p\Normalizer::isNormalized((string) $string, (int) $form); } 16 | } 17 | if (!function_exists('normalizer_normalize')) { 18 | function normalizer_normalize(?string $string, ?int $form = p\Normalizer::FORM_C): string|false { return p\Normalizer::normalize((string) $string, (int) $form); } 19 | } 20 | -------------------------------------------------------------------------------- /config/api/models/Language.php: -------------------------------------------------------------------------------- 1 | [ 10 | 'code' => fn (Language $language) => $language->code(), 11 | 'default' => fn (Language $language) => $language->isDefault(), 12 | 'direction' => fn (Language $language) => $language->direction(), 13 | 'locale' => fn (Language $language) => $language->locale(), 14 | 'name' => fn (Language $language) => $language->name(), 15 | 'rules' => fn (Language $language) => $language->rules(), 16 | 'url' => fn (Language $language) => $language->url(), 17 | ], 18 | 'type' => 'Kirby\Cms\Language', 19 | 'views' => [ 20 | 'default' => [ 21 | 'code', 22 | 'default', 23 | 'direction', 24 | 'locale', 25 | 'name', 26 | 'rules', 27 | 'url' 28 | ] 29 | ] 30 | ]; 31 | -------------------------------------------------------------------------------- /config/setup.php: -------------------------------------------------------------------------------- 1 | 2 | 3 |

4 | We are really sorry, but your browser does not support 5 | all features required for the Kirby Panel. 6 |

7 | 8 |
9 |

10 | Fetch
11 | We use Javascript's new Fetch API. You can find a list of supported browsers for this feature on 12 | caniuse.com 13 |

14 |

15 | CSS Grid
16 | We use CSS Grids for all our layouts. You can find a list of supported browsers for this feature on 17 | caniuse.com 18 |

19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /vendor/symfony/polyfill-intl-normalizer/bootstrap.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | use Symfony\Polyfill\Intl\Normalizer as p; 13 | 14 | if (\PHP_VERSION_ID >= 80000) { 15 | return require __DIR__.'/bootstrap80.php'; 16 | } 17 | 18 | if (!function_exists('normalizer_is_normalized')) { 19 | function normalizer_is_normalized($string, $form = p\Normalizer::FORM_C) { return p\Normalizer::isNormalized($string, $form); } 20 | } 21 | if (!function_exists('normalizer_normalize')) { 22 | function normalizer_normalize($string, $form = p\Normalizer::FORM_C) { return p\Normalizer::normalize($string, $form); } 23 | } 24 | -------------------------------------------------------------------------------- /src/Panel/Dialog.php: -------------------------------------------------------------------------------- 1 | 15 | * @link https://getkirby.com 16 | * @copyright Bastian Allgeier 17 | * @license https://getkirby.com/license 18 | */ 19 | class Dialog extends Json 20 | { 21 | protected static string $key = '$dialog'; 22 | 23 | /** 24 | * Renders dialogs 25 | */ 26 | public static function response($data, array $options = []): Response 27 | { 28 | // interpret true as success 29 | if ($data === true) { 30 | $data = [ 31 | 'code' => 200 32 | ]; 33 | } 34 | 35 | return parent::response($data, $options); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Toolkit/Facade.php: -------------------------------------------------------------------------------- 1 | 11 | * @link https://getkirby.com 12 | * @copyright Bastian Allgeier 13 | * @license https://opensource.org/licenses/MIT 14 | */ 15 | abstract class Facade 16 | { 17 | /** 18 | * Returns the instance that should be 19 | * available statically 20 | * 21 | * @return mixed 22 | */ 23 | abstract public static function instance(); 24 | 25 | /** 26 | * Proxy for all public instance calls 27 | * 28 | * @param string $method 29 | * @param array $args 30 | * @return mixed 31 | */ 32 | public static function __callStatic(string $method, array $args = null) 33 | { 34 | return static::instance()->$method(...$args); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /vendor/autoload.php: -------------------------------------------------------------------------------- 1 | logger) { }` 11 | * blocks. 12 | */ 13 | class NullLogger extends AbstractLogger 14 | { 15 | /** 16 | * Logs with an arbitrary level. 17 | * 18 | * @param mixed $level 19 | * @param string|\Stringable $message 20 | * @param array $context 21 | * 22 | * @return void 23 | * 24 | * @throws \Psr\Log\InvalidArgumentException 25 | */ 26 | public function log($level, string|\Stringable $message, array $context = []): void 27 | { 28 | // noop 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /config/fields/select.php: -------------------------------------------------------------------------------- 1 | 'radio', 7 | 'props' => [ 8 | /** 9 | * Unset inherited props 10 | */ 11 | 'columns' => null, 12 | 13 | /** 14 | * Custom icon to replace the arrow down. 15 | */ 16 | 'icon' => function (string $icon = null) { 17 | return $icon; 18 | }, 19 | /** 20 | * Custom placeholder string for empty option. 21 | */ 22 | 'placeholder' => function (string $placeholder = '—') { 23 | return $placeholder; 24 | }, 25 | ], 26 | 'methods' => [ 27 | 'getOptions' => function () { 28 | $props = FieldOptions::polyfill($this->props); 29 | 30 | // disable safe mode as the select field does not 31 | // render HTML for the option text 32 | $options = FieldOptions::factory($props['options'], false); 33 | 34 | return $options->render($this->model()); 35 | } 36 | ] 37 | ]; 38 | -------------------------------------------------------------------------------- /config/fields/email.php: -------------------------------------------------------------------------------- 1 | 'text', 7 | 'props' => [ 8 | /** 9 | * Unset inherited props 10 | */ 11 | 'converter' => null, 12 | 'counter' => null, 13 | 14 | /** 15 | * Sets the HTML5 autocomplete mode for the input 16 | */ 17 | 'autocomplete' => function (string $autocomplete = 'email') { 18 | return $autocomplete; 19 | }, 20 | 21 | /** 22 | * Changes the email icon to something custom 23 | */ 24 | 'icon' => function (string $icon = 'email') { 25 | return $icon; 26 | }, 27 | 28 | /** 29 | * Custom placeholder text, when the field is empty. 30 | */ 31 | 'placeholder' => function ($value = null) { 32 | return I18n::translate($value, $value) ?? I18n::translate('email.placeholder'); 33 | } 34 | ], 35 | 'validations' => [ 36 | 'minlength', 37 | 'maxlength', 38 | 'email' 39 | ] 40 | ]; 41 | -------------------------------------------------------------------------------- /src/Blueprint/NodeString.php: -------------------------------------------------------------------------------- 1 | 12 | * @link https://getkirby.com 13 | * @copyright Bastian Allgeier 14 | * @license https://opensource.org/licenses/MIT 15 | * 16 | * // TODO: include in test coverage in 3.10 17 | * @codeCoverageIgnore 18 | */ 19 | class NodeString extends NodeProperty 20 | { 21 | public function __construct( 22 | public string $value, 23 | ) { 24 | } 25 | 26 | public static function factory($value = null): static|null 27 | { 28 | if ($value === null) { 29 | return $value; 30 | } 31 | 32 | return new static($value); 33 | } 34 | 35 | public function render(ModelWithContent $model): string|null 36 | { 37 | return $this->value; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /vendor/filp/whoops/src/Whoops/Handler/HandlerInterface.php: -------------------------------------------------------------------------------- 1 | 5 | */ 6 | 7 | namespace Whoops\Handler; 8 | 9 | use Whoops\Exception\Inspector; 10 | use Whoops\RunInterface; 11 | 12 | interface HandlerInterface 13 | { 14 | /** 15 | * @return int|null A handler may return nothing, or a Handler::HANDLE_* constant 16 | */ 17 | public function handle(); 18 | 19 | /** 20 | * @param RunInterface $run 21 | * @return void 22 | */ 23 | public function setRun(RunInterface $run); 24 | 25 | /** 26 | * @param \Throwable $exception 27 | * @return void 28 | */ 29 | public function setException($exception); 30 | 31 | /** 32 | * @param Inspector $inspector 33 | * @return void 34 | */ 35 | public function setInspector(Inspector $inspector); 36 | } 37 | -------------------------------------------------------------------------------- /vendor/filp/whoops/src/Whoops/Util/HtmlDumperOutput.php: -------------------------------------------------------------------------------- 1 | 5 | */ 6 | 7 | namespace Whoops\Util; 8 | 9 | /** 10 | * Used as output callable for Symfony\Component\VarDumper\Dumper\HtmlDumper::dump() 11 | * 12 | * @see TemplateHelper::dump() 13 | */ 14 | class HtmlDumperOutput 15 | { 16 | private $output; 17 | 18 | public function __invoke($line, $depth) 19 | { 20 | // A negative depth means "end of dump" 21 | if ($depth >= 0) { 22 | // Adds a two spaces indentation to the line 23 | $this->output .= str_repeat(' ', $depth) . $line . "\n"; 24 | } 25 | } 26 | 27 | public function getOutput() 28 | { 29 | return $this->output; 30 | } 31 | 32 | public function clear() 33 | { 34 | $this->output = null; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /config/fields/url.php: -------------------------------------------------------------------------------- 1 | 'text', 7 | 'props' => [ 8 | /** 9 | * Unset inherited props 10 | */ 11 | 'converter' => null, 12 | 'counter' => null, 13 | 'pattern' => null, 14 | 'spellcheck' => null, 15 | 16 | /** 17 | * Sets the HTML5 autocomplete attribute 18 | */ 19 | 'autocomplete' => function (string $autocomplete = 'url') { 20 | return $autocomplete; 21 | }, 22 | 23 | /** 24 | * Changes the link icon 25 | */ 26 | 'icon' => function (string $icon = 'url') { 27 | return $icon; 28 | }, 29 | 30 | /** 31 | * Sets custom placeholder text, when the field is empty 32 | */ 33 | 'placeholder' => function ($value = null) { 34 | return I18n::translate($value, $value) ?? 'https://example.com'; 35 | } 36 | ], 37 | 'validations' => [ 38 | 'minlength', 39 | 'maxlength', 40 | 'url' 41 | ], 42 | ]; 43 | -------------------------------------------------------------------------------- /src/Uuid/BlockUuid.php: -------------------------------------------------------------------------------- 1 | 17 | * @link https://getkirby.com 18 | * @copyright Bastian Allgeier 19 | * @license https://getkirby.com/license 20 | */ 21 | class BlockUuid extends FieldUuid 22 | { 23 | protected const TYPE = 'block'; 24 | protected const FIELD = 'blocks'; 25 | 26 | /** 27 | * @var \Kirby\Cms\Block|null 28 | */ 29 | public Identifiable|null $model; 30 | 31 | /** 32 | * Converts content field to a Blocks collection 33 | * @internal 34 | */ 35 | public static function fieldToCollection(Field $field): Blocks 36 | { 37 | return $field->toBlocks(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Cms/NestObject.php: -------------------------------------------------------------------------------- 1 | 12 | * @link https://getkirby.com 13 | * @copyright Bastian Allgeier 14 | * @license https://getkirby.com/license 15 | */ 16 | class NestObject extends Obj 17 | { 18 | /** 19 | * Converts the object to an array 20 | */ 21 | public function toArray(): array 22 | { 23 | $result = []; 24 | 25 | foreach ((array)$this as $key => $value) { 26 | if ($value instanceof Field) { 27 | $result[$key] = $value->value(); 28 | continue; 29 | } 30 | 31 | if ( 32 | is_object($value) === true && 33 | method_exists($value, 'toArray') 34 | ) { 35 | $result[$key] = $value->toArray(); 36 | continue; 37 | } 38 | 39 | $result[$key] = $value; 40 | } 41 | 42 | return $result; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /config/api/models.php: -------------------------------------------------------------------------------- 1 | include __DIR__ . '/models/File.php', 8 | 'FileBlueprint' => include __DIR__ . '/models/FileBlueprint.php', 9 | 'FileVersion' => include __DIR__ . '/models/FileVersion.php', 10 | 'Language' => include __DIR__ . '/models/Language.php', 11 | 'Page' => include __DIR__ . '/models/Page.php', 12 | 'PageBlueprint' => include __DIR__ . '/models/PageBlueprint.php', 13 | 'Role' => include __DIR__ . '/models/Role.php', 14 | 'Site' => include __DIR__ . '/models/Site.php', 15 | 'SiteBlueprint' => include __DIR__ . '/models/SiteBlueprint.php', 16 | 'System' => include __DIR__ . '/models/System.php', 17 | 'Translation' => include __DIR__ . '/models/Translation.php', 18 | 'User' => include __DIR__ . '/models/User.php', 19 | 'UserBlueprint' => include __DIR__ . '/models/UserBlueprint.php', 20 | ]; 21 | -------------------------------------------------------------------------------- /config/blocks/gallery/gallery.yml: -------------------------------------------------------------------------------- 1 | name: field.blocks.gallery.name 2 | icon: dashboard 3 | preview: gallery 4 | fields: 5 | images: 6 | label: field.blocks.gallery.images.label 7 | type: files 8 | query: model.images 9 | multiple: true 10 | layout: cards 11 | size: tiny 12 | empty: field.blocks.gallery.images.empty 13 | uploads: 14 | template: blocks/image 15 | image: 16 | ratio: 1/1 17 | caption: 18 | label: field.blocks.image.caption 19 | type: writer 20 | icon: text 21 | inline: true 22 | ratio: 23 | label: field.blocks.image.ratio 24 | type: select 25 | placeholder: Auto 26 | width: 1/2 27 | options: 28 | 1/1: "1:1" 29 | 16/9: "16:9" 30 | 10/8: "10:8" 31 | 21/9: "21:9" 32 | 7/5: "7:5" 33 | 4/3: "4:3" 34 | 5/3: "5:3" 35 | 3/2: "3:2" 36 | 3/1: "3:1" 37 | crop: 38 | label: field.blocks.image.crop 39 | type: toggle 40 | width: 1/2 41 | -------------------------------------------------------------------------------- /src/Uuid/StructureUuid.php: -------------------------------------------------------------------------------- 1 | 17 | * @link https://getkirby.com 18 | * @copyright Bastian Allgeier 19 | * @license https://getkirby.com/license 20 | */ 21 | class StructureUuid extends FieldUuid 22 | { 23 | protected const TYPE = 'struct'; 24 | protected const FIELD = 'structure'; 25 | 26 | /** 27 | * @var \Kirby\Cms\StructureObject|null 28 | */ 29 | public Identifiable|null $model; 30 | 31 | /** 32 | * Converts content field to a Structure collection 33 | * @internal 34 | */ 35 | public static function fieldToCollection(Field $field): Structure 36 | { 37 | return $field->toStructure(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Http/Request/Auth/SessionAuth.php: -------------------------------------------------------------------------------- 1 | 14 | * @link https://getkirby.com 15 | * @copyright Bastian Allgeier 16 | * @license https://opensource.org/licenses/MIT 17 | */ 18 | class SessionAuth extends Auth 19 | { 20 | /** 21 | * Tries to return the session object 22 | */ 23 | public function session(): Session 24 | { 25 | return App::instance()->sessionHandler()->getManually($this->data); 26 | } 27 | 28 | /** 29 | * Returns the session token 30 | */ 31 | public function token(): string 32 | { 33 | return $this->data; 34 | } 35 | 36 | /** 37 | * Returns the authentication type 38 | */ 39 | public function type(): string 40 | { 41 | return 'session'; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Panel/Redirect.php: -------------------------------------------------------------------------------- 1 | 15 | * @link https://getkirby.com 16 | * @copyright Bastian Allgeier 17 | * @license https://getkirby.com/license 18 | */ 19 | class Redirect extends Exception 20 | { 21 | /** 22 | * Returns the HTTP code for the redirect 23 | */ 24 | public function code(): int 25 | { 26 | $codes = [301, 302, 303, 307, 308]; 27 | 28 | if (in_array($this->getCode(), $codes) === true) { 29 | return $this->getCode(); 30 | } 31 | 32 | return 302; 33 | } 34 | 35 | /** 36 | * Returns the URL for the redirect 37 | */ 38 | public function location(): string 39 | { 40 | return $this->getMessage(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /vendor/league/color-extractor/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "league/color-extractor", 3 | "type": "library", 4 | "description": "Extract colors from an image as a human would do.", 5 | "keywords": ["image", "color", "extract", "palette", "human"], 6 | "homepage": "https://github.com/thephpleague/color-extractor", 7 | "license": "MIT", 8 | "replace": { 9 | "matthecat/colorextractor": "*" 10 | }, 11 | "authors": [ 12 | { 13 | "name": "Mathieu Lechat", 14 | "email": "math.lechat@gmail.com", 15 | "homepage": "http://matthecat.com", 16 | "role": "Developer" 17 | } 18 | ], 19 | "require": { 20 | "php": ">=5.4.0", 21 | "ext-gd": "*" 22 | }, 23 | "require-dev": { 24 | "friendsofphp/php-cs-fixer": "~2", 25 | "phpunit/phpunit": "~5" 26 | }, 27 | "autoload": { 28 | "psr-4": { 29 | "": "src" 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /config/fields/info.php: -------------------------------------------------------------------------------- 1 | [ 7 | /** 8 | * Unset inherited props 9 | */ 10 | 'after' => null, 11 | 'autofocus' => null, 12 | 'before' => null, 13 | 'default' => null, 14 | 'disabled' => null, 15 | 'icon' => null, 16 | 'placeholder' => null, 17 | 'required' => null, 18 | 'translate' => null, 19 | 20 | /** 21 | * Text to be displayed 22 | */ 23 | 'text' => function ($value = null) { 24 | return I18n::translate($value, $value); 25 | }, 26 | 27 | /** 28 | * Change the design of the info box 29 | */ 30 | 'theme' => function (string $theme = null) { 31 | return $theme; 32 | } 33 | ], 34 | 'computed' => [ 35 | 'text' => function () { 36 | if ($text = $this->text) { 37 | $text = $this->model()->toSafeString($text); 38 | $text = $this->kirby()->kirbytext($text); 39 | return $text; 40 | } 41 | } 42 | ], 43 | 'save' => false, 44 | ]; 45 | -------------------------------------------------------------------------------- /config/sections/mixins/details.php: -------------------------------------------------------------------------------- 1 | [ 7 | /** 8 | * Image options to control the source and look of preview 9 | */ 10 | 'image' => function ($image = null) { 11 | return $image ?? []; 12 | }, 13 | /** 14 | * Optional info text setup. Info text is shown on the right (lists, cardlets) or below (cards) the title. 15 | */ 16 | 'info' => function ($info = null) { 17 | return I18n::translate($info, $info); 18 | }, 19 | /** 20 | * Setup for the main text in the list or cards. By default this will display the title. 21 | */ 22 | 'text' => function ($text = '{{ model.title }}') { 23 | return I18n::translate($text, $text); 24 | } 25 | ], 26 | 'methods' => [ 27 | 'link' => function () { 28 | $modelLink = $this->model->panel()->url(true); 29 | $parentLink = $this->parent->panel()->url(true); 30 | 31 | if ($modelLink !== $parentLink) { 32 | return $parentLink; 33 | } 34 | } 35 | ] 36 | ]; 37 | -------------------------------------------------------------------------------- /vendor/composer/autoload_psr4.php: -------------------------------------------------------------------------------- 1 | array($vendorDir . '/filp/whoops/src/Whoops'), 10 | 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'), 11 | 'Symfony\\Polyfill\\Intl\\Normalizer\\' => array($vendorDir . '/symfony/polyfill-intl-normalizer'), 12 | 'Symfony\\Polyfill\\Intl\\Idn\\' => array($vendorDir . '/symfony/polyfill-intl-idn'), 13 | 'Psr\\Log\\' => array($vendorDir . '/psr/log/src'), 14 | 'PHPMailer\\PHPMailer\\' => array($vendorDir . '/phpmailer/phpmailer/src'), 15 | 'Laminas\\Escaper\\' => array($vendorDir . '/laminas/laminas-escaper/src'), 16 | 'Kirby\\' => array($baseDir . '/src', $vendorDir . '/getkirby/composer-installer/src'), 17 | 'Composer\\Semver\\' => array($vendorDir . '/composer/semver/src'), 18 | '' => array($vendorDir . '/league/color-extractor/src'), 19 | ); 20 | -------------------------------------------------------------------------------- /src/Toolkit/Tpl.php: -------------------------------------------------------------------------------- 1 | 13 | * @link https://getkirby.com 14 | * @copyright Bastian Allgeier 15 | * @license https://opensource.org/licenses/MIT 16 | */ 17 | class Tpl 18 | { 19 | /** 20 | * Renders the template 21 | * 22 | * @throws Throwable 23 | */ 24 | public static function load(string|null $file = null, array $data = []): string 25 | { 26 | if ($file === null || is_file($file) === false) { 27 | return ''; 28 | } 29 | 30 | ob_start(); 31 | 32 | $exception = null; 33 | try { 34 | F::load($file, null, $data); 35 | } catch (Throwable $e) { 36 | $exception = $e; 37 | } 38 | 39 | $content = ob_get_contents(); 40 | ob_end_clean(); 41 | 42 | if ($exception === null) { 43 | return $content; 44 | } 45 | 46 | throw $exception; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /views/snippets/header.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Error 8 | 9 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /config/sections/mixins/headline.php: -------------------------------------------------------------------------------- 1 | [ 7 | /** 8 | * The headline for the section. This can be a simple string or a template with additional info from the parent page. 9 | * @deprecated 3.8.0 Use `label` instead 10 | */ 11 | 'headline' => function ($headline = null) { 12 | return I18n::translate($headline, $headline); 13 | }, 14 | /** 15 | * The label for the section. This can be a simple string or 16 | * a template with additional info from the parent page. 17 | * Replaces the `headline` prop. 18 | */ 19 | 'label' => function ($label = null) { 20 | return I18n::translate($label, $label); 21 | } 22 | ], 23 | 'computed' => [ 24 | 'headline' => function () { 25 | if ($this->label) { 26 | return $this->model()->toString($this->label); 27 | } 28 | 29 | if ($this->headline) { 30 | return $this->model()->toString($this->headline); 31 | } 32 | 33 | return ucfirst($this->name); 34 | } 35 | ] 36 | ]; 37 | -------------------------------------------------------------------------------- /config/blocks/image/image.php: -------------------------------------------------------------------------------- 1 | alt(); 5 | $caption = $block->caption(); 6 | $crop = $block->crop()->isTrue(); 7 | $link = $block->link(); 8 | $ratio = $block->ratio()->or('auto'); 9 | $src = null; 10 | 11 | if ($block->location() == 'web') { 12 | $src = $block->src()->esc(); 13 | } elseif ($image = $block->image()->toFile()) { 14 | $alt = $alt ?? $image->alt(); 15 | $src = $image->url(); 16 | } 17 | 18 | ?> 19 | 20 | $ratio, 'data-crop' => $crop], null, ' ') ?>> 21 | isNotEmpty()): ?> 22 | 23 | <?= $alt->esc() ?> 24 | 25 | 26 | <?= $alt->esc() ?> 27 | 28 | 29 | isNotEmpty()): ?> 30 |
31 | 32 |
33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /config/sections/mixins/pagination.php: -------------------------------------------------------------------------------- 1 | [ 8 | /** 9 | * Sets the number of items per page. If there are more items the pagination navigation will be shown at the bottom of the section. 10 | */ 11 | 'limit' => function (int $limit = 20) { 12 | return $limit; 13 | }, 14 | /** 15 | * Sets the default page for the pagination. This will overwrite default pagination. 16 | */ 17 | 'page' => function (int $page = null) { 18 | return App::instance()->request()->get('page', $page); 19 | }, 20 | ], 21 | 'methods' => [ 22 | 'pagination' => function () { 23 | $pagination = new Pagination([ 24 | 'limit' => $this->limit, 25 | 'page' => $this->page, 26 | 'total' => $this->total 27 | ]); 28 | 29 | return [ 30 | 'limit' => $pagination->limit(), 31 | 'offset' => $pagination->offset(), 32 | 'page' => $pagination->page(), 33 | 'total' => $pagination->total(), 34 | ]; 35 | } 36 | ] 37 | ]; 38 | -------------------------------------------------------------------------------- /bootstrap.php: -------------------------------------------------------------------------------- 1 | =') === false || 9 | version_compare(PHP_VERSION, '8.3.0', '<') === false 10 | ) { 11 | die(include __DIR__ . '/views/php.php'); 12 | } 13 | 14 | if (is_file($autoloader = dirname(__DIR__) . '/vendor/autoload.php')) { 15 | /** 16 | * Always prefer a site-wide Composer autoloader 17 | * if it exists, it means that the user has probably 18 | * installed additional packages 19 | * 20 | * @psalm-suppress MissingFile 21 | */ 22 | include $autoloader; 23 | } elseif (is_file($autoloader = __DIR__ . '/vendor/autoload.php')) { 24 | /** 25 | * Fall back to the local autoloader if that exists 26 | * 27 | * @psalm-suppress MissingFile 28 | */ 29 | include $autoloader; 30 | } else { 31 | /** 32 | * If neither one exists, don't bother searching; 33 | * it's a custom directory setup and the users need to 34 | * load the autoloader themselves 35 | */ 36 | } 37 | -------------------------------------------------------------------------------- /config/api/routes/languages.php: -------------------------------------------------------------------------------- 1 | 'languages', 9 | 'method' => 'GET', 10 | 'action' => function () { 11 | return $this->kirby()->languages(); 12 | } 13 | ], 14 | [ 15 | 'pattern' => 'languages', 16 | 'method' => 'POST', 17 | 'action' => function () { 18 | return $this->kirby()->languages()->create($this->requestBody()); 19 | } 20 | ], 21 | [ 22 | 'pattern' => 'languages/(:any)', 23 | 'method' => 'GET', 24 | 'action' => function (string $code) { 25 | return $this->kirby()->languages()->find($code); 26 | } 27 | ], 28 | [ 29 | 'pattern' => 'languages/(:any)', 30 | 'method' => 'PATCH', 31 | 'action' => function (string $code) { 32 | return $this->kirby()->languages()->find($code)?->update($this->requestBody()); 33 | } 34 | ], 35 | [ 36 | 'pattern' => 'languages/(:any)', 37 | 'method' => 'DELETE', 38 | 'action' => function (string $code) { 39 | return $this->kirby()->languages()->find($code)?->delete(); 40 | } 41 | ] 42 | ]; 43 | -------------------------------------------------------------------------------- /vendor/filp/whoops/src/Whoops/Resources/views/layout.html.php: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | <?php echo $tpl->escape($page_title) ?> 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 |
21 | 22 | render($panel_left_outer) ?> 23 | 24 | render($panel_details_outer) ?> 25 | 26 |
27 |
28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /vendor/claviska/simpleimage/LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright 2017 A Beautiful Site, LLC 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /src/Blueprint/NodeI18n.php: -------------------------------------------------------------------------------- 1 | 13 | * @link https://getkirby.com 14 | * @copyright Bastian Allgeier 15 | * @license https://opensource.org/licenses/MIT 16 | * 17 | * // TODO: include in test coverage in 3.10 18 | * @codeCoverageIgnore 19 | */ 20 | class NodeI18n extends NodeProperty 21 | { 22 | public function __construct( 23 | public array $translations, 24 | ) { 25 | } 26 | 27 | public static function factory($value = null): static|null 28 | { 29 | if ($value === false || $value === null) { 30 | return null; 31 | } 32 | 33 | if (is_array($value) === false) { 34 | $value = ['en' => $value]; 35 | } 36 | 37 | return new static($value); 38 | } 39 | 40 | public function render(ModelWithContent $model): string|null 41 | { 42 | return I18n::translate($this->translations, $this->translations); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /i18n/rules/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2012-217 Florian Eckerstorfer 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /src/Parsley/Schema.php: -------------------------------------------------------------------------------- 1 | , 12 | * @link https://getkirby.com 13 | * @copyright Bastian Allgeier 14 | * @license https://getkirby.com/license 15 | */ 16 | class Schema 17 | { 18 | /** 19 | * Returns the fallback block when no 20 | * other block type can be detected 21 | */ 22 | public function fallback(Element|string $element): array|null 23 | { 24 | return null; 25 | } 26 | 27 | /** 28 | * Returns a list of allowed inline marks 29 | * and their parsing rules 30 | */ 31 | public function marks(): array 32 | { 33 | return []; 34 | } 35 | 36 | /** 37 | * Returns a list of allowed nodes and 38 | * their parsing rules 39 | */ 40 | public function nodes(): array 41 | { 42 | return []; 43 | } 44 | 45 | /** 46 | * Returns a list of all elements that should be 47 | * skipped and not be parsed at all 48 | */ 49 | public function skip(): array 50 | { 51 | return []; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /vendor/filp/whoops/LICENSE.md: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /vendor/composer/semver/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2015 Composer 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /config/fields/number.php: -------------------------------------------------------------------------------- 1 | [ 7 | /** 8 | * Default number that will be saved when a new page/user/file is created 9 | */ 10 | 'default' => function ($default = null) { 11 | return $this->toNumber($default); 12 | }, 13 | /** 14 | * The lowest allowed number 15 | */ 16 | 'min' => function (float $min = null) { 17 | return $min; 18 | }, 19 | /** 20 | * The highest allowed number 21 | */ 22 | 'max' => function (float $max = null) { 23 | return $max; 24 | }, 25 | /** 26 | * Allowed incremental steps between numbers (i.e `0.5`) 27 | */ 28 | 'step' => function ($step = null) { 29 | return $this->toNumber($step); 30 | }, 31 | 'value' => function ($value = null) { 32 | return $this->toNumber($value); 33 | } 34 | ], 35 | 'methods' => [ 36 | 'toNumber' => function ($value) { 37 | if ($this->isEmpty($value) === true) { 38 | return null; 39 | } 40 | 41 | return is_float($value) === true ? $value : (float)Str::float($value); 42 | } 43 | ], 44 | 'validations' => [ 45 | 'min', 46 | 'max' 47 | ] 48 | ]; 49 | -------------------------------------------------------------------------------- /config/fields/toggles.php: -------------------------------------------------------------------------------- 1 | ['options'], 5 | 'props' => [ 6 | /** 7 | * Unset inherited props 8 | */ 9 | 'after' => null, 10 | 'before' => null, 11 | 'icon' => null, 12 | 'placeholder' => null, 13 | 14 | /** 15 | * Toggles will automatically span the full width of the field. With the grow option, you can disable this behaviour for a more compact layout. 16 | */ 17 | 'grow' => function (bool $grow = true) { 18 | return $grow; 19 | }, 20 | /** 21 | * If `false` all labels will be hidden for icon-only toggles. 22 | */ 23 | 'labels' => function (bool $labels = true) { 24 | return $labels; 25 | }, 26 | /** 27 | * A toggle can be deactivated on click. If reset is `false` deactivating a toggle is no longer possible. 28 | */ 29 | 'reset' => function (bool $reset = true) { 30 | return $reset; 31 | } 32 | ], 33 | 'computed' => [ 34 | 'default' => function () { 35 | return $this->sanitizeOption($this->default); 36 | }, 37 | 'value' => function () { 38 | return $this->sanitizeOption($this->value) ?? ''; 39 | }, 40 | ] 41 | ]; 42 | -------------------------------------------------------------------------------- /config/fields/multiselect.php: -------------------------------------------------------------------------------- 1 | 'tags', 7 | 'props' => [ 8 | /** 9 | * Unset inherited props 10 | */ 11 | 'accept' => null, 12 | /** 13 | * Custom icon to replace the arrow down. 14 | */ 15 | 'icon' => function (string $icon = null) { 16 | return $icon; 17 | }, 18 | /** 19 | * Enable/disable the search in the dropdown 20 | * Also limit displayed items (display: 20) 21 | * and set minimum number of characters to search (min: 3) 22 | */ 23 | 'search' => function ($search = true) { 24 | return $search; 25 | }, 26 | /** 27 | * If `true`, selected entries will be sorted 28 | * according to their position in the dropdown 29 | */ 30 | 'sort' => function (bool $sort = false) { 31 | return $sort; 32 | }, 33 | ], 34 | 'methods' => [ 35 | 'toValues' => function ($value) { 36 | if (is_null($value) === true) { 37 | return []; 38 | } 39 | 40 | if (is_array($value) === false) { 41 | $value = Str::split($value, $this->separator()); 42 | } 43 | 44 | return $this->sanitizeOptions($value); 45 | } 46 | ], 47 | ]; 48 | -------------------------------------------------------------------------------- /vendor/filp/whoops/src/Whoops/Resources/views/frame_list.html.php: -------------------------------------------------------------------------------- 1 | 4 | $frame): ?> 5 |
6 | 7 |
8 | breakOnDelimiter('\\', $tpl->escape($frame->getClass() ?: '')) ?> 9 | breakOnDelimiter('\\', $tpl->escape($frame->getFunction() ?: '')) ?> 10 |
11 | 12 |
13 | getFile() ? $tpl->breakOnDelimiter('/', $tpl->shorten($tpl->escape($frame->getFile()))) : '<#unknown>' ?>getLine() ?> 15 |
16 |
17 | 15 | * @link https://getkirby.com 16 | * @copyright Bastian Allgeier 17 | * @license https://getkirby.com/license 18 | */ 19 | class UserUuid extends Uuid 20 | { 21 | protected const TYPE = 'user'; 22 | 23 | /** 24 | * @var \Kirby\Cms\User|null 25 | */ 26 | public Identifiable|null $model; 27 | 28 | /** 29 | * Generator for all users 30 | * 31 | * @return \Generator|\Kirby\Cms\User[] 32 | */ 33 | public static function index(): Generator 34 | { 35 | yield from App::instance()->users(); 36 | } 37 | 38 | /** 39 | * Returns the user object 40 | */ 41 | public function model(bool $lazy = false): User|null 42 | { 43 | return $this->model ??= App::instance()->user($this->id()); 44 | } 45 | 46 | /** 47 | * Pretends to fill cache - we don't need it in cache 48 | */ 49 | public function populate(): bool 50 | { 51 | return true; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /vendor/composer/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Copyright (c) Nils Adermann, Jordi Boggiano 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is furnished 9 | to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | 22 | -------------------------------------------------------------------------------- /vendor/psr/log/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 PHP Framework Interoperability Group 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /vendor/symfony/polyfill-mbstring/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015-2019 Fabien Potencier 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /vendor/symfony/polyfill-intl-normalizer/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015-2019 Fabien Potencier 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /config/fields/slug.php: -------------------------------------------------------------------------------- 1 | 'text', 6 | 'props' => [ 7 | /** 8 | * Unset inherited props 9 | */ 10 | 'converter' => null, 11 | 'counter' => null, 12 | 'spellcheck' => null, 13 | 14 | /** 15 | * Set of characters allowed in the slug 16 | */ 17 | 'allow' => function (string $allow = '') { 18 | return $allow; 19 | }, 20 | 21 | /** 22 | * Changes the link icon 23 | */ 24 | 'icon' => function (string $icon = 'url') { 25 | return $icon; 26 | }, 27 | 28 | /** 29 | * Set prefix for the help text 30 | */ 31 | 'path' => function (string $path = null) { 32 | return $path; 33 | }, 34 | 35 | /** 36 | * Name of another field that should be used to 37 | * automatically update this field's value 38 | */ 39 | 'sync' => function (string $sync = null) { 40 | return $sync; 41 | }, 42 | 43 | /** 44 | * Set to object with keys `field` and `text` to add 45 | * button to generate from another field 46 | */ 47 | 'wizard' => function ($wizard = false) { 48 | return $wizard; 49 | } 50 | ], 51 | 'validations' => [ 52 | 'minlength', 53 | 'maxlength' 54 | ], 55 | ]; 56 | -------------------------------------------------------------------------------- /config/areas/installation.php: -------------------------------------------------------------------------------- 1 | 'settings', 9 | 'label' => I18n::translate('view.installation'), 10 | 'views' => [ 11 | 'installation' => [ 12 | 'pattern' => 'installation', 13 | 'auth' => false, 14 | 'action' => function () use ($kirby) { 15 | $system = $kirby->system(); 16 | return [ 17 | 'component' => 'k-installation-view', 18 | 'props' => [ 19 | 'isInstallable' => $system->isInstallable(), 20 | 'isInstalled' => $system->isInstalled(), 21 | 'isOk' => $system->isOk(), 22 | 'requirements' => $system->status(), 23 | 'translations' => $kirby->translations()->values(function ($translation) { 24 | return [ 25 | 'text' => $translation->name(), 26 | 'value' => $translation->code(), 27 | ]; 28 | }), 29 | ] 30 | ]; 31 | } 32 | ], 33 | 'installation.fallback' => [ 34 | 'pattern' => '(:all)', 35 | 'auth' => false, 36 | 'action' => fn () => Panel::go('installation') 37 | ] 38 | ] 39 | ]; 40 | }; 41 | -------------------------------------------------------------------------------- /i18n/rules/mk.json: -------------------------------------------------------------------------------- 1 | { 2 | "А": "A", 3 | "Б": "B", 4 | "В": "V", 5 | "Г": "G", 6 | "Д": "D", 7 | "Ѓ": "Gj", 8 | "Е": "E", 9 | "Ж": "Zh", 10 | "З": "Z", 11 | "Ѕ": "Dz", 12 | "И": "I", 13 | "Ј": "J", 14 | "К": "K", 15 | "Л": "L", 16 | "Љ": "Lj", 17 | "М": "M", 18 | "Н": "N", 19 | "Њ": "Nj", 20 | "О": "O", 21 | "П": "P", 22 | "Р": "R", 23 | "С": "S", 24 | "Т": "T", 25 | "Ќ": "Kj", 26 | "У": "U", 27 | "Ф": "F", 28 | "Х": "H", 29 | "Ц": "C", 30 | "Ч": "Ch", 31 | "Џ": "Dj", 32 | "Ш": "Sh", 33 | "а": "a", 34 | "б": "b", 35 | "в": "v", 36 | "г": "g", 37 | "д": "d", 38 | "ѓ": "gj", 39 | "е": "e", 40 | "ж": "zh", 41 | "з": "z", 42 | "ѕ": "dz", 43 | "и": "i", 44 | "ј": "j", 45 | "к": "k", 46 | "л": "l", 47 | "љ": "lj", 48 | "м": "m", 49 | "н": "n", 50 | "њ": "nj", 51 | "о": "o", 52 | "п": "p", 53 | "р": "r", 54 | "с": "s", 55 | "т": "t", 56 | "ќ": "kj", 57 | "у": "u", 58 | "ф": "f", 59 | "х": "h", 60 | "ц": "c", 61 | "ч": "ch", 62 | "џ": "dj", 63 | "ш": "sh" 64 | } 65 | -------------------------------------------------------------------------------- /src/Option/OptionsProvider.php: -------------------------------------------------------------------------------- 1 | 13 | * @link https://getkirby.com 14 | * @copyright Bastian Allgeier 15 | * @license https://opensource.org/licenses/MIT 16 | */ 17 | abstract class OptionsProvider 18 | { 19 | public Options|null $options = null; 20 | 21 | /** 22 | * Returns options as array 23 | */ 24 | public function render(ModelWithContent $model) 25 | { 26 | return $this->resolve($model)->render($model); 27 | } 28 | 29 | /** 30 | * Dynamically determines the actual options and resolves 31 | * them to the correct text-value entries 32 | * 33 | * @param bool $safeMode Whether to escape special HTML characters in 34 | * the option text for safe output in the Panel; 35 | * only set to `false` if the text is later escaped! 36 | */ 37 | abstract public function resolve(ModelWithContent $model, bool $safeMode = true): Options; 38 | } 39 | -------------------------------------------------------------------------------- /vendor/league/color-extractor/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Mathieu Lechat 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /i18n/rules/bg.json: -------------------------------------------------------------------------------- 1 | { 2 | "А": "A", 3 | "Б": "B", 4 | "В": "V", 5 | "Г": "G", 6 | "Д": "D", 7 | "Е": "E", 8 | "Ж": "J", 9 | "З": "Z", 10 | "И": "I", 11 | "Й": "Y", 12 | "К": "K", 13 | "Л": "L", 14 | "М": "M", 15 | "Н": "N", 16 | "О": "O", 17 | "П": "P", 18 | "Р": "R", 19 | "С": "S", 20 | "Т": "T", 21 | "У": "U", 22 | "Ф": "F", 23 | "Х": "H", 24 | "Ц": "Ts", 25 | "Ч": "Ch", 26 | "Ш": "Sh", 27 | "Щ": "Sht", 28 | "Ъ": "A", 29 | "Ь": "I", 30 | "Ю": "Iu", 31 | "Я": "Ia", 32 | "а": "a", 33 | "б": "b", 34 | "в": "v", 35 | "г": "g", 36 | "д": "d", 37 | "е": "e", 38 | "ж": "j", 39 | "з": "z", 40 | "и": "i", 41 | "й": "y", 42 | "к": "k", 43 | "л": "l", 44 | "м": "m", 45 | "н": "n", 46 | "о": "o", 47 | "п": "p", 48 | "р": "r", 49 | "с": "s", 50 | "т": "t", 51 | "у": "u", 52 | "ф": "f", 53 | "х": "h", 54 | "ц": "ts", 55 | "ч": "ch", 56 | "ш": "sh", 57 | "щ": "sht", 58 | "ъ": "a", 59 | "ь": "i", 60 | "ю": "iu", 61 | "я": "ia", 62 | "ия": "ia", 63 | "йо": "iо", 64 | "ьо": "io" 65 | } 66 | -------------------------------------------------------------------------------- /vendor/symfony/polyfill-intl-idn/Resources/unidata/virama.php: -------------------------------------------------------------------------------- 1 | 9, 5 | 2509 => 9, 6 | 2637 => 9, 7 | 2765 => 9, 8 | 2893 => 9, 9 | 3021 => 9, 10 | 3149 => 9, 11 | 3277 => 9, 12 | 3387 => 9, 13 | 3388 => 9, 14 | 3405 => 9, 15 | 3530 => 9, 16 | 3642 => 9, 17 | 3770 => 9, 18 | 3972 => 9, 19 | 4153 => 9, 20 | 4154 => 9, 21 | 5908 => 9, 22 | 5940 => 9, 23 | 6098 => 9, 24 | 6752 => 9, 25 | 6980 => 9, 26 | 7082 => 9, 27 | 7083 => 9, 28 | 7154 => 9, 29 | 7155 => 9, 30 | 11647 => 9, 31 | 43014 => 9, 32 | 43052 => 9, 33 | 43204 => 9, 34 | 43347 => 9, 35 | 43456 => 9, 36 | 43766 => 9, 37 | 44013 => 9, 38 | 68159 => 9, 39 | 69702 => 9, 40 | 69759 => 9, 41 | 69817 => 9, 42 | 69939 => 9, 43 | 69940 => 9, 44 | 70080 => 9, 45 | 70197 => 9, 46 | 70378 => 9, 47 | 70477 => 9, 48 | 70722 => 9, 49 | 70850 => 9, 50 | 71103 => 9, 51 | 71231 => 9, 52 | 71350 => 9, 53 | 71467 => 9, 54 | 71737 => 9, 55 | 71997 => 9, 56 | 71998 => 9, 57 | 72160 => 9, 58 | 72244 => 9, 59 | 72263 => 9, 60 | 72345 => 9, 61 | 72767 => 9, 62 | 73028 => 9, 63 | 73029 => 9, 64 | 73111 => 9, 65 | ); 66 | -------------------------------------------------------------------------------- /vendor/symfony/polyfill-intl-idn/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018-2019 Fabien Potencier and Trevor Rowbotham 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /config/areas/login.php: -------------------------------------------------------------------------------- 1 | 'user', 9 | 'label' => I18n::translate('login'), 10 | 'views' => [ 11 | 'login' => [ 12 | 'pattern' => 'login', 13 | 'auth' => false, 14 | 'action' => function () use ($kirby) { 15 | $system = $kirby->system(); 16 | $status = $kirby->auth()->status(); 17 | return [ 18 | 'component' => 'k-login-view', 19 | 'props' => [ 20 | 'methods' => array_keys($system->loginMethods()), 21 | 'pending' => [ 22 | 'email' => $status->email(), 23 | 'challenge' => $status->challenge() 24 | ] 25 | ], 26 | ]; 27 | } 28 | ], 29 | 'login.fallback' => [ 30 | 'pattern' => '(:all)', 31 | 'auth' => false, 32 | 'action' => function ($path) use ($kirby) { 33 | /** 34 | * Store the current path in the session 35 | * Once the user is logged in, the path will 36 | * be used to redirect to that view again 37 | */ 38 | $kirby->session()->set('panel.path', $path); 39 | Panel::go('login'); 40 | } 41 | ] 42 | ] 43 | ]; 44 | }; 45 | -------------------------------------------------------------------------------- /config/fields/writer.php: -------------------------------------------------------------------------------- 1 | [ 7 | /** 8 | * Enables inline mode, which will not wrap new lines in paragraphs and creates hard breaks instead. 9 | * 10 | * @param bool $inline 11 | */ 12 | 'inline' => function (bool $inline = false) { 13 | return $inline; 14 | }, 15 | /** 16 | * Sets the allowed HTML formats. Available formats: `bold`, `italic`, `underline`, `strike`, `code`, `link`, `email`. Activate them all by passing `true`. Deactivate them all by passing `false` 17 | * @param array|bool $marks 18 | */ 19 | 'marks' => function ($marks = true) { 20 | return $marks; 21 | }, 22 | /** 23 | * Sets the allowed nodes. Available nodes: `paragraph`, `heading`, `bulletList`, `orderedList`. Activate/deactivate them all by passing `true`/`false`. Default nodes are `paragraph`, `heading`, `bulletList`, `orderedList`. 24 | * @param array|bool|null $nodes 25 | */ 26 | 'nodes' => function ($nodes = null) { 27 | return $nodes; 28 | } 29 | ], 30 | 'computed' => [ 31 | 'value' => function () { 32 | $value = trim($this->value ?? ''); 33 | return Sane::sanitize($value, 'html'); 34 | } 35 | ], 36 | ]; 37 | -------------------------------------------------------------------------------- /config/sections/mixins/sort.php: -------------------------------------------------------------------------------- 1 | [ 5 | /** 6 | * Enables/disables reverse sorting 7 | */ 8 | 'flip' => function (bool $flip = false) { 9 | return $flip; 10 | }, 11 | /** 12 | * Enables/disables manual sorting 13 | */ 14 | 'sortable' => function (bool $sortable = true) { 15 | return $sortable; 16 | }, 17 | /** 18 | * Overwrites manual sorting and sorts by the given field and sorting direction (i.e. `date desc`) 19 | */ 20 | 'sortBy' => function (string $sortBy = null) { 21 | return $sortBy; 22 | }, 23 | ], 24 | 'computed' => [ 25 | 'sortable' => function () { 26 | if ($this->sortable === false) { 27 | return false; 28 | } 29 | 30 | if ( 31 | $this->type === 'pages' && 32 | in_array($this->status, ['listed', 'published', 'all']) === false 33 | ) { 34 | return false; 35 | } 36 | 37 | // don't allow sorting while search filter is active 38 | if (empty($this->searchterm()) === false) { 39 | return false; 40 | } 41 | 42 | if ($this->sortBy !== null) { 43 | return false; 44 | } 45 | 46 | if ($this->flip === true) { 47 | return false; 48 | } 49 | 50 | return true; 51 | } 52 | ] 53 | ]; 54 | -------------------------------------------------------------------------------- /src/Http/Path.php: -------------------------------------------------------------------------------- 1 | 14 | * @link https://getkirby.com 15 | * @copyright Bastian Allgeier 16 | * @license https://opensource.org/licenses/MIT 17 | */ 18 | class Path extends Collection 19 | { 20 | public function __construct(string|array|null $items) 21 | { 22 | if (is_string($items) === true) { 23 | $items = Str::split($items, '/'); 24 | } 25 | 26 | parent::__construct($items ?? []); 27 | } 28 | 29 | public function __toString(): string 30 | { 31 | return $this->toString(); 32 | } 33 | 34 | public function toString( 35 | bool $leadingSlash = false, 36 | bool $trailingSlash = false 37 | ): string { 38 | if (empty($this->data) === true) { 39 | return ''; 40 | } 41 | 42 | $path = implode('/', $this->data); 43 | 44 | $leadingSlash = $leadingSlash === true ? '/' : null; 45 | $trailingSlash = $trailingSlash === true ? '/' : null; 46 | 47 | return $leadingSlash . $path . $trailingSlash; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Http/Request/Auth.php: -------------------------------------------------------------------------------- 1 | 12 | * @link https://getkirby.com 13 | * @copyright Bastian Allgeier 14 | * @license https://opensource.org/licenses/MIT 15 | */ 16 | abstract class Auth 17 | { 18 | /** 19 | * Raw authentication data after the first space 20 | * in the `Authorization` header 21 | */ 22 | protected string $data; 23 | 24 | /** 25 | * Constructor 26 | */ 27 | public function __construct( 28 | #[SensitiveParameter] 29 | string $data 30 | ) { 31 | $this->data = $data; 32 | } 33 | 34 | /** 35 | * Converts the object to a string 36 | */ 37 | public function __toString(): string 38 | { 39 | return ucfirst($this->type()) . ' ' . $this->data(); 40 | } 41 | 42 | /** 43 | * Returns the raw authentication data after the 44 | * first space in the `Authorization` header 45 | */ 46 | public function data(): string 47 | { 48 | return $this->data; 49 | } 50 | 51 | /** 52 | * Returns the name of the auth type (lowercase) 53 | */ 54 | abstract public function type(): string; 55 | } 56 | -------------------------------------------------------------------------------- /config/api/collections.php: -------------------------------------------------------------------------------- 1 | [ 12 | 'model' => 'page', 13 | 'type' => 'Kirby\Cms\Pages', 14 | 'view' => 'compact' 15 | ], 16 | 17 | /** 18 | * Files 19 | */ 20 | 'files' => [ 21 | 'model' => 'file', 22 | 'type' => 'Kirby\Cms\Files' 23 | ], 24 | 25 | /** 26 | * Languages 27 | */ 28 | 'languages' => [ 29 | 'model' => 'language', 30 | 'type' => 'Kirby\Cms\Languages' 31 | ], 32 | 33 | /** 34 | * Pages 35 | */ 36 | 'pages' => [ 37 | 'model' => 'page', 38 | 'type' => 'Kirby\Cms\Pages', 39 | 'view' => 'compact' 40 | ], 41 | 42 | /** 43 | * Roles 44 | */ 45 | 'roles' => [ 46 | 'model' => 'role', 47 | 'type' => 'Kirby\Cms\Roles', 48 | 'view' => 'compact' 49 | ], 50 | 51 | /** 52 | * Translations 53 | */ 54 | 'translations' => [ 55 | 'model' => 'translation', 56 | 'type' => 'Kirby\Cms\Translations', 57 | 'view' => 'compact' 58 | ], 59 | 60 | /** 61 | * Users 62 | */ 63 | 'users' => [ 64 | 'default' => fn () => $this->users(), 65 | 'model' => 'user', 66 | 'type' => 'Kirby\Cms\Users', 67 | 'view' => 'compact' 68 | ] 69 | 70 | ]; 71 | -------------------------------------------------------------------------------- /config/sections/mixins/parent.php: -------------------------------------------------------------------------------- 1 | [ 11 | /** 12 | * Sets the query to a parent to find items for the list 13 | */ 14 | 'parent' => function (string $parent = null) { 15 | return $parent; 16 | } 17 | ], 18 | 'methods' => [ 19 | 'parentModel' => function () { 20 | $parent = $this->parent; 21 | 22 | if (is_string($parent) === true) { 23 | $query = $parent; 24 | $parent = $this->model->query($query); 25 | 26 | if (!$parent) { 27 | throw new Exception('The parent for the query "' . $query . '" cannot be found in the section "' . $this->name() . '"'); 28 | } 29 | 30 | if ( 31 | $parent instanceof Page === false && 32 | $parent instanceof Site === false && 33 | $parent instanceof File === false && 34 | $parent instanceof User === false 35 | ) { 36 | throw new Exception('The parent for the section "' . $this->name() . '" has to be a page, site or user object'); 37 | } 38 | } 39 | 40 | if ($parent === null) { 41 | return $this->model; 42 | } 43 | 44 | return $parent; 45 | } 46 | ] 47 | ]; 48 | -------------------------------------------------------------------------------- /src/Cms/Nest.php: -------------------------------------------------------------------------------- 1 | 15 | * @link https://getkirby.com 16 | * @copyright Bastian Allgeier 17 | * @license https://getkirby.com/license 18 | */ 19 | class Nest 20 | { 21 | public static function create( 22 | $data, 23 | object|null $parent = null 24 | ): NestCollection|NestObject|Field { 25 | if (is_scalar($data) === true) { 26 | return new Field($parent, $data, $data); 27 | } 28 | 29 | $result = []; 30 | 31 | foreach ($data as $key => $value) { 32 | if (is_array($value) === true) { 33 | $result[$key] = static::create($value, $parent); 34 | } elseif (is_scalar($value) === true) { 35 | $result[$key] = new Field($parent, $key, $value); 36 | } 37 | } 38 | 39 | $key = key($data); 40 | 41 | if ($key === null || is_int($key) === true) { 42 | return new NestCollection($result); 43 | } 44 | 45 | return new NestObject($result); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /i18n/rules/ru.json: -------------------------------------------------------------------------------- 1 | { 2 | "Ъ": "", 3 | "Ь": "", 4 | "А": "A", 5 | "Б": "B", 6 | "Ц": "C", 7 | "Ч": "Ch", 8 | "Д": "D", 9 | "Е": "E", 10 | "Ё": "E", 11 | "Э": "E", 12 | "Ф": "F", 13 | "Г": "G", 14 | "Х": "H", 15 | "И": "I", 16 | "Й": "Y", 17 | "Я": "Ya", 18 | "Ю": "Yu", 19 | "К": "K", 20 | "Л": "L", 21 | "М": "M", 22 | "Н": "N", 23 | "О": "O", 24 | "П": "P", 25 | "Р": "R", 26 | "С": "S", 27 | "Ш": "Sh", 28 | "Щ": "Shch", 29 | "Т": "T", 30 | "У": "U", 31 | "В": "V", 32 | "Ы": "Y", 33 | "З": "Z", 34 | "Ж": "Zh", 35 | "ъ": "", 36 | "ь": "", 37 | "а": "a", 38 | "б": "b", 39 | "ц": "c", 40 | "ч": "ch", 41 | "д": "d", 42 | "е": "e", 43 | "ё": "e", 44 | "э": "e", 45 | "ф": "f", 46 | "г": "g", 47 | "х": "h", 48 | "и": "i", 49 | "й": "y", 50 | "я": "ya", 51 | "ю": "yu", 52 | "к": "k", 53 | "л": "l", 54 | "м": "m", 55 | "н": "n", 56 | "о": "o", 57 | "п": "p", 58 | "р": "r", 59 | "с": "s", 60 | "ш": "sh", 61 | "щ": "shch", 62 | "т": "t", 63 | "у": "u", 64 | "в": "v", 65 | "ы": "y", 66 | "з": "z", 67 | "ж": "zh" 68 | } 69 | -------------------------------------------------------------------------------- /src/Template/Slots.php: -------------------------------------------------------------------------------- 1 | heading()` and accessing a non-existing 11 | * slot will simply return null. 12 | * 13 | * @package Kirby Template 14 | * @author Bastian Allgeier 15 | * @link https://getkirby.com 16 | * @copyright Bastian Allgeier 17 | * @license https://getkirby.com/license 18 | */ 19 | class Slots implements Countable 20 | { 21 | /** 22 | * Creates a new slots collection 23 | */ 24 | public function __construct(protected array $slots) 25 | { 26 | } 27 | 28 | /** 29 | * Magic getter for slots; 30 | * e.g. `$slots->heading` 31 | */ 32 | public function __get(string $name): Slot|null 33 | { 34 | return $this->slots[$name] ?? null; 35 | } 36 | 37 | /** 38 | * Magic getter method for slots; 39 | * e.g. `$slots->heading()` 40 | */ 41 | public function __call(string $name, array $args): Slot|null 42 | { 43 | return $this->__get($name); 44 | } 45 | 46 | /** 47 | * Counts the number of defined slots 48 | */ 49 | public function count(): int 50 | { 51 | return count($this->slots); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Uuid/PageUuid.php: -------------------------------------------------------------------------------- 1 | 15 | * @link https://getkirby.com 16 | * @copyright Bastian Allgeier 17 | * @license https://getkirby.com/license 18 | */ 19 | class PageUuid extends ModelUuid 20 | { 21 | protected const TYPE = 'page'; 22 | 23 | /** 24 | * @var \Kirby\Cms\Page|null 25 | */ 26 | public Identifiable|null $model; 27 | 28 | /** 29 | * Looks up UUID in cache and resolves 30 | * to page object 31 | */ 32 | protected function findByCache(): Page|null 33 | { 34 | $key = $this->key(); 35 | $value = Uuids::cache()->get($key); 36 | return App::instance()->page($value); 37 | } 38 | 39 | /** 40 | * Generator for all pages and drafts in the site 41 | * 42 | * @return \Generator|\Kirby\Cms\Page[] 43 | */ 44 | public static function index(Page|null $entry = null): Generator 45 | { 46 | $entry ??= App::instance()->site(); 47 | 48 | foreach ($entry->childrenAndDrafts() as $page) { 49 | yield $page; 50 | yield from static::index($page); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /config/blueprints/blocks/code.yml: -------------------------------------------------------------------------------- 1 | name: Code 2 | icon: code 3 | fields: 4 | code: 5 | label: Code 6 | type: textarea 7 | buttons: false 8 | font: monospace 9 | language: 10 | label: Language 11 | type: select 12 | default: text 13 | options: 14 | bash: Bash 15 | basic: BASIC 16 | c: C 17 | clojure: Clojure 18 | cpp: C++ 19 | csharp: C# 20 | css: CSS 21 | diff: Diff 22 | elixir: Elixir 23 | elm: Elm 24 | erlang: Erlang 25 | go: Go 26 | graphql: GraphQL 27 | haskell: Haskell 28 | html: HTML 29 | java: Java 30 | js: JavaScript 31 | json: JSON 32 | latext: LaTeX 33 | less: Less 34 | lisp: Lisp 35 | lua: Lua 36 | makefile: Makefile 37 | markdown: Markdown 38 | markup: Markup 39 | objectivec: Objective-C 40 | pascal: Pascal 41 | perl: Perl 42 | php: PHP 43 | text: Plain Text 44 | python: Python 45 | r: R 46 | ruby: Ruby 47 | rust: Rust 48 | sass: Sass 49 | scss: SCSS 50 | shell: Shell 51 | sql: SQL 52 | swift: Swift 53 | typescript: TypeScript 54 | vbnet: VB.net 55 | xml: XML 56 | yaml: YAML 57 | -------------------------------------------------------------------------------- /vendor/symfony/polyfill-mbstring/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "symfony/polyfill-mbstring", 3 | "type": "library", 4 | "description": "Symfony polyfill for the Mbstring extension", 5 | "keywords": ["polyfill", "shim", "compatibility", "portable", "mbstring"], 6 | "homepage": "https://symfony.com", 7 | "license": "MIT", 8 | "authors": [ 9 | { 10 | "name": "Nicolas Grekas", 11 | "email": "p@tchwork.com" 12 | }, 13 | { 14 | "name": "Symfony Community", 15 | "homepage": "https://symfony.com/contributors" 16 | } 17 | ], 18 | "require": { 19 | "php": ">=7.1" 20 | }, 21 | "provide": { 22 | "ext-mbstring": "*" 23 | }, 24 | "autoload": { 25 | "psr-4": { "Symfony\\Polyfill\\Mbstring\\": "" }, 26 | "files": [ "bootstrap.php" ] 27 | }, 28 | "suggest": { 29 | "ext-mbstring": "For best performance" 30 | }, 31 | "minimum-stability": "dev", 32 | "extra": { 33 | "branch-alias": { 34 | "dev-main": "1.27-dev" 35 | }, 36 | "thanks": { 37 | "name": "symfony/polyfill", 38 | "url": "https://github.com/symfony/polyfill" 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /vendor/league/color-extractor/src/League/ColorExtractor/Color.php: -------------------------------------------------------------------------------- 1 | $color >> 16 & 0xFF, 37 | 'g' => $color >> 8 & 0xFF, 38 | 'b' => $color & 0xFF, 39 | ]; 40 | } 41 | 42 | /** 43 | * @param array $components 44 | * 45 | * @return int 46 | */ 47 | public static function fromRgbToInt(array $components) 48 | { 49 | return ($components['r'] * 65536) + ($components['g'] * 256) + ($components['b']); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /config/api/models/Site.php: -------------------------------------------------------------------------------- 1 | fn () => $this->site(), 11 | 'fields' => [ 12 | 'blueprint' => fn (Site $site) => $site->blueprint(), 13 | 'children' => fn (Site $site) => $site->children(), 14 | 'content' => fn (Site $site) => Form::for($site)->values(), 15 | 'drafts' => fn (Site $site) => $site->drafts(), 16 | 'files' => fn (Site $site) => $site->files()->sorted(), 17 | 'options' => fn (Site $site) => $site->permissions()->toArray(), 18 | 'previewUrl' => fn (Site $site) => $site->previewUrl(), 19 | 'title' => fn (Site $site) => $site->title()->value(), 20 | 'url' => fn (Site $site) => $site->url(), 21 | ], 22 | 'type' => 'Kirby\Cms\Site', 23 | 'views' => [ 24 | 'compact' => [ 25 | 'title', 26 | 'url' 27 | ], 28 | 'default' => [ 29 | 'content', 30 | 'options', 31 | 'title', 32 | 'url' 33 | ], 34 | 'panel' => [ 35 | 'title', 36 | 'blueprint', 37 | 'content', 38 | 'options', 39 | 'previewUrl', 40 | 'url' 41 | ], 42 | 'selector' => [ 43 | 'title', 44 | 'children' => [ 45 | 'id', 46 | 'title', 47 | 'panelIcon', 48 | 'hasChildren' 49 | ], 50 | ] 51 | ] 52 | ]; 53 | -------------------------------------------------------------------------------- /i18n/rules/hi.json: -------------------------------------------------------------------------------- 1 | { 2 | "अ": "a", 3 | "आ": "aa", 4 | "ए": "e", 5 | "ई": "ii", 6 | "ऍ": "ei", 7 | "ऎ": "ae", 8 | "ऐ": "ai", 9 | "इ": "i", 10 | "ओ": "o", 11 | "ऑ": "oi", 12 | "ऒ": "oii", 13 | "ऊ": "uu", 14 | "औ": "ou", 15 | "उ": "u", 16 | "ब": "B", 17 | "भ": "Bha", 18 | "च": "Ca", 19 | "छ": "Chha", 20 | "ड": "Da", 21 | "ढ": "Dha", 22 | "फ": "Fa", 23 | "फ़": "Fi", 24 | "ग": "Ga", 25 | "घ": "Gha", 26 | "ग़": "Ghi", 27 | "ह": "Ha", 28 | "ज": "Ja", 29 | "झ": "Jha", 30 | "क": "Ka", 31 | "ख": "Kha", 32 | "ख़": "Khi", 33 | "ल": "L", 34 | "ळ": "Li", 35 | "ऌ": "Li", 36 | "ऴ": "Lii", 37 | "ॡ": "Lii", 38 | "म": "Ma", 39 | "न": "Na", 40 | "ङ": "Na", 41 | "ञ": "Nia", 42 | "ण": "Nae", 43 | "ऩ": "Ni", 44 | "ॐ": "oms", 45 | "प": "Pa", 46 | "क़": "Qi", 47 | "र": "Ra", 48 | "ऋ": "Ri", 49 | "ॠ": "Ri", 50 | "ऱ": "Ri", 51 | "स": "Sa", 52 | "श": "Sha", 53 | "ष": "Shha", 54 | "ट": "Ta", 55 | "त": "Ta", 56 | "ठ": "Tha", 57 | "द": "Tha", 58 | "थ": "Tha", 59 | "ध": "Thha", 60 | "ड़": "ugDha", 61 | "ढ़": "ugDhha", 62 | "व": "Va", 63 | "य": "Ya", 64 | "य़": "Yi", 65 | "ज़": "Za" 66 | } 67 | -------------------------------------------------------------------------------- /vendor/symfony/polyfill-intl-normalizer/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "symfony/polyfill-intl-normalizer", 3 | "type": "library", 4 | "description": "Symfony polyfill for intl's Normalizer class and related functions", 5 | "keywords": ["polyfill", "shim", "compatibility", "portable", "intl", "normalizer"], 6 | "homepage": "https://symfony.com", 7 | "license": "MIT", 8 | "authors": [ 9 | { 10 | "name": "Nicolas Grekas", 11 | "email": "p@tchwork.com" 12 | }, 13 | { 14 | "name": "Symfony Community", 15 | "homepage": "https://symfony.com/contributors" 16 | } 17 | ], 18 | "require": { 19 | "php": ">=7.1" 20 | }, 21 | "autoload": { 22 | "psr-4": { "Symfony\\Polyfill\\Intl\\Normalizer\\": "" }, 23 | "files": [ "bootstrap.php" ], 24 | "classmap": [ "Resources/stubs" ] 25 | }, 26 | "suggest": { 27 | "ext-intl": "For best performance" 28 | }, 29 | "minimum-stability": "dev", 30 | "extra": { 31 | "branch-alias": { 32 | "dev-main": "1.27-dev" 33 | }, 34 | "thanks": { 35 | "name": "symfony/polyfill", 36 | "url": "https://github.com/symfony/polyfill" 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /config/api/routes/lock.php: -------------------------------------------------------------------------------- 1 | '(:all)/lock', 13 | 'method' => 'GET', 14 | 'action' => function (string $path) { 15 | return [ 16 | 'lock' => $this->parent($path)->lock()?->toArray() ?? false 17 | ]; 18 | } 19 | ], 20 | [ 21 | 'pattern' => '(:all)/lock', 22 | 'method' => 'PATCH', 23 | 'action' => function (string $path) { 24 | return $this->parent($path)->lock()?->create(); 25 | } 26 | ], 27 | [ 28 | 'pattern' => '(:all)/lock', 29 | 'method' => 'DELETE', 30 | 'action' => function (string $path) { 31 | try { 32 | return $this->parent($path)->lock()?->remove(); 33 | } catch (NotFoundException) { 34 | return true; 35 | } 36 | } 37 | ], 38 | [ 39 | 'pattern' => '(:all)/unlock', 40 | 'method' => 'PATCH', 41 | 'action' => function (string $path) { 42 | return $this->parent($path)->lock()?->unlock(); 43 | } 44 | ], 45 | [ 46 | 'pattern' => '(:all)/unlock', 47 | 'method' => 'DELETE', 48 | 'action' => function (string $path) { 49 | try { 50 | return $this->parent($path)->lock()?->resolve(); 51 | } catch (NotFoundException) { 52 | return true; 53 | } 54 | } 55 | ], 56 | ]; 57 | -------------------------------------------------------------------------------- /src/Cms/UserBlueprint.php: -------------------------------------------------------------------------------- 1 | 11 | * @link https://getkirby.com 12 | * @copyright Bastian Allgeier 13 | * @license https://getkirby.com/license 14 | */ 15 | class UserBlueprint extends Blueprint 16 | { 17 | /** 18 | * UserBlueprint constructor. 19 | * 20 | * @param array $props 21 | * @throws \Kirby\Exception\InvalidArgumentException 22 | */ 23 | public function __construct(array $props) 24 | { 25 | // normalize and translate the description 26 | $props['description'] = $this->i18n($props['description'] ?? null); 27 | 28 | // register the other props 29 | parent::__construct($props); 30 | 31 | // normalize all available page options 32 | $this->props['options'] = $this->normalizeOptions( 33 | $this->props['options'] ?? true, 34 | // defaults 35 | [ 36 | 'create' => null, 37 | 'changeEmail' => null, 38 | 'changeLanguage' => null, 39 | 'changeName' => null, 40 | 'changePassword' => null, 41 | 'changeRole' => null, 42 | 'delete' => null, 43 | 'update' => null, 44 | ] 45 | ); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /i18n/rules/sr.json: -------------------------------------------------------------------------------- 1 | { 2 | "а": "a", 3 | "б": "b", 4 | "в": "v", 5 | "г": "g", 6 | "д": "d", 7 | "ђ": "dj", 8 | "е": "e", 9 | "ж": "z", 10 | "з": "z", 11 | "и": "i", 12 | "ј": "j", 13 | "к": "k", 14 | "л": "l", 15 | "љ": "lj", 16 | "м": "m", 17 | "н": "n", 18 | "њ": "nj", 19 | "о": "o", 20 | "п": "p", 21 | "р": "r", 22 | "с": "s", 23 | "т": "t", 24 | "ћ": "c", 25 | "у": "u", 26 | "ф": "f", 27 | "х": "h", 28 | "ц": "c", 29 | "ч": "c", 30 | "џ": "dz", 31 | "ш": "s", 32 | "А": "A", 33 | "Б": "B", 34 | "В": "V", 35 | "Г": "G", 36 | "Д": "D", 37 | "Ђ": "Dj", 38 | "Е": "E", 39 | "Ж": "Z", 40 | "З": "Z", 41 | "И": "I", 42 | "Ј": "J", 43 | "К": "K", 44 | "Л": "L", 45 | "Љ": "Lj", 46 | "М": "M", 47 | "Н": "N", 48 | "Њ": "Nj", 49 | "О": "O", 50 | "П": "P", 51 | "Р": "R", 52 | "С": "S", 53 | "Т": "T", 54 | "Ћ": "C", 55 | "У": "U", 56 | "Ф": "F", 57 | "Х": "H", 58 | "Ц": "C", 59 | "Ч": "C", 60 | "Џ": "Dz", 61 | "Ш": "S", 62 | "š": "s", 63 | "đ": "dj", 64 | "ž": "z", 65 | "ć": "c", 66 | "č": "c", 67 | "Š": "S", 68 | "Đ": "DJ", 69 | "Ž": "Z", 70 | "Ć": "C", 71 | "Č": "C" 72 | } -------------------------------------------------------------------------------- /vendor/symfony/polyfill-intl-idn/Resources/unidata/disallowed_STD3_valid.php: -------------------------------------------------------------------------------- 1 | true, 5 | 1 => true, 6 | 2 => true, 7 | 3 => true, 8 | 4 => true, 9 | 5 => true, 10 | 6 => true, 11 | 7 => true, 12 | 8 => true, 13 | 9 => true, 14 | 10 => true, 15 | 11 => true, 16 | 12 => true, 17 | 13 => true, 18 | 14 => true, 19 | 15 => true, 20 | 16 => true, 21 | 17 => true, 22 | 18 => true, 23 | 19 => true, 24 | 20 => true, 25 | 21 => true, 26 | 22 => true, 27 | 23 => true, 28 | 24 => true, 29 | 25 => true, 30 | 26 => true, 31 | 27 => true, 32 | 28 => true, 33 | 29 => true, 34 | 30 => true, 35 | 31 => true, 36 | 32 => true, 37 | 33 => true, 38 | 34 => true, 39 | 35 => true, 40 | 36 => true, 41 | 37 => true, 42 | 38 => true, 43 | 39 => true, 44 | 40 => true, 45 | 41 => true, 46 | 42 => true, 47 | 43 => true, 48 | 44 => true, 49 | 47 => true, 50 | 58 => true, 51 | 59 => true, 52 | 60 => true, 53 | 61 => true, 54 | 62 => true, 55 | 63 => true, 56 | 64 => true, 57 | 91 => true, 58 | 92 => true, 59 | 93 => true, 60 | 94 => true, 61 | 95 => true, 62 | 96 => true, 63 | 123 => true, 64 | 124 => true, 65 | 125 => true, 66 | 126 => true, 67 | 127 => true, 68 | 8800 => true, 69 | 8814 => true, 70 | 8815 => true, 71 | ); 72 | -------------------------------------------------------------------------------- /src/Data/Json.php: -------------------------------------------------------------------------------- 1 | 12 | * @link https://getkirby.com 13 | * @copyright Bastian Allgeier 14 | * @license https://opensource.org/licenses/MIT 15 | */ 16 | class Json extends Handler 17 | { 18 | /** 19 | * Converts an array to an encoded JSON string 20 | */ 21 | public static function encode($data): string 22 | { 23 | return json_encode( 24 | $data, 25 | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE 26 | ); 27 | } 28 | 29 | /** 30 | * Parses an encoded JSON string and returns a multi-dimensional array 31 | */ 32 | public static function decode($string): array 33 | { 34 | if ($string === null || $string === '') { 35 | return []; 36 | } 37 | 38 | if (is_array($string) === true) { 39 | return $string; 40 | } 41 | 42 | if (is_string($string) === false) { 43 | throw new InvalidArgumentException('Invalid JSON data; please pass a string'); 44 | } 45 | 46 | $result = json_decode($string, true); 47 | 48 | if (is_array($result) === true) { 49 | return $result; 50 | } 51 | 52 | throw new InvalidArgumentException('JSON string is invalid'); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Http/Query.php: -------------------------------------------------------------------------------- 1 | 14 | * @link https://getkirby.com 15 | * @copyright Bastian Allgeier 16 | * @license https://opensource.org/licenses/MIT 17 | */ 18 | class Query extends Obj 19 | { 20 | public function __construct(string|array|null $query) 21 | { 22 | if (is_string($query) === true) { 23 | parse_str(ltrim($query, '?'), $query); 24 | } 25 | 26 | parent::__construct($query ?? []); 27 | } 28 | 29 | public function isEmpty(): bool 30 | { 31 | return empty((array)$this) === true; 32 | } 33 | 34 | public function isNotEmpty(): bool 35 | { 36 | return empty((array)$this) === false; 37 | } 38 | 39 | public function toString(bool $questionMark = false): string 40 | { 41 | $query = http_build_query($this, '', '&', PHP_QUERY_RFC3986); 42 | 43 | if (empty($query) === true) { 44 | return ''; 45 | } 46 | 47 | if ($questionMark === true) { 48 | $query = '?' . $query; 49 | } 50 | 51 | return $query; 52 | } 53 | 54 | 55 | public function __toString(): string 56 | { 57 | return $this->toString(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /config/blocks/image/image.yml: -------------------------------------------------------------------------------- 1 | name: field.blocks.image.name 2 | icon: image 3 | preview: image 4 | fields: 5 | location: 6 | label: field.blocks.image.location 7 | type: radio 8 | columns: 2 9 | default: "kirby" 10 | options: 11 | kirby: Kirby 12 | web: Web 13 | image: 14 | label: field.blocks.image.name 15 | type: files 16 | query: model.images 17 | multiple: false 18 | image: 19 | back: black 20 | uploads: 21 | template: blocks/image 22 | when: 23 | location: kirby 24 | src: 25 | label: field.blocks.image.url 26 | type: url 27 | when: 28 | location: web 29 | alt: 30 | label: field.blocks.image.alt 31 | type: text 32 | icon: title 33 | caption: 34 | label: field.blocks.image.caption 35 | type: writer 36 | icon: text 37 | inline: true 38 | link: 39 | label: field.blocks.image.link 40 | type: text 41 | icon: url 42 | ratio: 43 | label: field.blocks.image.ratio 44 | type: select 45 | placeholder: Auto 46 | width: 1/2 47 | options: 48 | 1/1: "1:1" 49 | 16/9: "16:9" 50 | 10/8: "10:8" 51 | 21/9: "21:9" 52 | 7/5: "7:5" 53 | 4/3: "4:3" 54 | 5/3: "5:3" 55 | 3/2: "3:2" 56 | 3/1: "3:1" 57 | crop: 58 | label: field.blocks.image.crop 59 | type: toggle 60 | width: 1/2 61 | -------------------------------------------------------------------------------- /src/Data/Handler.php: -------------------------------------------------------------------------------- 1 | 15 | * @link https://getkirby.com 16 | * @copyright Bastian Allgeier 17 | * @license https://opensource.org/licenses/MIT 18 | */ 19 | abstract class Handler 20 | { 21 | /** 22 | * Parses an encoded string and returns a multi-dimensional array 23 | * 24 | * @throws \Exception if the file can't be parsed 25 | */ 26 | abstract public static function decode($string): array; 27 | 28 | /** 29 | * Converts an array to an encoded string 30 | */ 31 | abstract public static function encode($data): string; 32 | 33 | /** 34 | * Reads data from a file 35 | */ 36 | public static function read(string $file): array 37 | { 38 | $contents = F::read($file); 39 | 40 | if ($contents === false) { 41 | throw new Exception('The file "' . $file . '" does not exist or cannot be read'); 42 | } 43 | 44 | return static::decode($contents); 45 | } 46 | 47 | /** 48 | * Writes data to a file 49 | */ 50 | public static function write(string $file, $data = []): bool 51 | { 52 | return F::write($file, static::encode($data)); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /config/blocks/code/code.yml: -------------------------------------------------------------------------------- 1 | name: field.blocks.code.name 2 | icon: code 3 | wysiwyg: true 4 | preview: code 5 | fields: 6 | code: 7 | label: field.blocks.code.name 8 | type: textarea 9 | placeholder: field.blocks.code.placeholder 10 | buttons: false 11 | font: monospace 12 | language: 13 | label: field.blocks.code.language 14 | type: select 15 | default: text 16 | options: 17 | bash: Bash 18 | basic: BASIC 19 | c: C 20 | clojure: Clojure 21 | cpp: C++ 22 | csharp: C# 23 | css: CSS 24 | diff: Diff 25 | elixir: Elixir 26 | elm: Elm 27 | erlang: Erlang 28 | go: Go 29 | graphql: GraphQL 30 | haskell: Haskell 31 | html: HTML 32 | java: Java 33 | js: JavaScript 34 | json: JSON 35 | latext: LaTeX 36 | less: Less 37 | lisp: Lisp 38 | lua: Lua 39 | makefile: Makefile 40 | markdown: Markdown 41 | markup: Markup 42 | objectivec: Objective-C 43 | pascal: Pascal 44 | perl: Perl 45 | php: PHP 46 | text: Plain Text 47 | python: Python 48 | r: R 49 | ruby: Ruby 50 | rust: Rust 51 | sass: Sass 52 | scss: SCSS 53 | shell: Shell 54 | sql: SQL 55 | swift: Swift 56 | typescript: TypeScript 57 | vbnet: VB.net 58 | xml: XML 59 | yaml: YAML 60 | -------------------------------------------------------------------------------- /config/fields/mixins/options.php: -------------------------------------------------------------------------------- 1 | [ 7 | /** 8 | * API settings for options requests. This will only take affect when `options` is set to `api`. 9 | */ 10 | 'api' => function ($api = null) { 11 | return $api; 12 | }, 13 | /** 14 | * An array with options 15 | */ 16 | 'options' => function ($options = []) { 17 | return $options; 18 | }, 19 | /** 20 | * Query settings for options queries. This will only take affect when `options` is set to `query`. 21 | */ 22 | 'query' => function ($query = null) { 23 | return $query; 24 | }, 25 | ], 26 | 'computed' => [ 27 | 'options' => function (): array { 28 | return $this->getOptions(); 29 | } 30 | ], 31 | 'methods' => [ 32 | 'getOptions' => function () { 33 | $props = FieldOptions::polyfill($this->props); 34 | $options = FieldOptions::factory($props['options']); 35 | return $options->render($this->model()); 36 | }, 37 | 'sanitizeOption' => function ($value) { 38 | $options = array_column($this->options(), 'value'); 39 | return in_array($value, $options, true) === true ? $value : null; 40 | }, 41 | 'sanitizeOptions' => function ($values) { 42 | $options = array_column($this->options(), 'value'); 43 | $options = array_intersect($values, $options); 44 | return array_values($options); 45 | }, 46 | ] 47 | ]; 48 | -------------------------------------------------------------------------------- /src/Toolkit/Silo.php: -------------------------------------------------------------------------------- 1 | 12 | * @link https://getkirby.com 13 | * @copyright Bastian Allgeier 14 | * @license https://opensource.org/licenses/MIT 15 | */ 16 | class Silo 17 | { 18 | public static $data = []; 19 | 20 | /** 21 | * Setter for new data 22 | */ 23 | public static function set(string|array $key, $value = null): array 24 | { 25 | if (is_array($key) === true) { 26 | return static::$data = array_merge(static::$data, $key); 27 | } 28 | 29 | static::$data[$key] = $value; 30 | return static::$data; 31 | } 32 | 33 | public static function get(string|array $key = null, $default = null) 34 | { 35 | if ($key === null) { 36 | return static::$data; 37 | } 38 | 39 | return A::get(static::$data, $key, $default); 40 | } 41 | 42 | /** 43 | * Removes an item from the data array 44 | */ 45 | public static function remove(string $key = null): array 46 | { 47 | // reset the entire array 48 | if ($key === null) { 49 | return static::$data = []; 50 | } 51 | 52 | // unset a single key 53 | unset(static::$data[$key]); 54 | 55 | // return the array without the removed key 56 | return static::$data; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Parsley/Schema/Plain.php: -------------------------------------------------------------------------------- 1 | , 17 | * @link https://getkirby.com 18 | * @copyright Bastian Allgeier 19 | * @license https://getkirby.com/license 20 | */ 21 | class Plain extends Schema 22 | { 23 | /** 24 | * Creates the fallback block type 25 | * if no other block can be found 26 | */ 27 | public function fallback(Element|string $element): array|null 28 | { 29 | if ($element instanceof Element) { 30 | $text = $element->innerText(); 31 | } elseif (is_string($element) === true) { 32 | $text = trim($element); 33 | 34 | if (Str::length($text) === 0) { 35 | return null; 36 | } 37 | } else { 38 | return null; 39 | } 40 | 41 | return [ 42 | 'content' => [ 43 | 'text' => $text 44 | ], 45 | 'type' => 'text', 46 | ]; 47 | } 48 | 49 | /** 50 | * Returns a list of all elements that 51 | * should be skipped during parsing 52 | */ 53 | public function skip(): array 54 | { 55 | return [ 56 | 'base', 57 | 'link', 58 | 'meta', 59 | 'script', 60 | 'style', 61 | 'title' 62 | ]; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /config/areas/site/searches.php: -------------------------------------------------------------------------------- 1 | [ 9 | 'label' => I18n::translate('pages'), 10 | 'icon' => 'page', 11 | 'query' => function (string $query = null) { 12 | $pages = App::instance()->site() 13 | ->index(true) 14 | ->search($query) 15 | ->filter('isReadable', true) 16 | ->limit(10); 17 | 18 | $results = []; 19 | 20 | foreach ($pages as $page) { 21 | $results[] = [ 22 | 'image' => $page->panel()->image(), 23 | 'text' => Escape::html($page->title()->value()), 24 | 'link' => $page->panel()->url(true), 25 | 'info' => Escape::html($page->id()) 26 | ]; 27 | } 28 | 29 | return $results; 30 | } 31 | ], 32 | 'files' => [ 33 | 'label' => I18n::translate('files'), 34 | 'icon' => 'image', 35 | 'query' => function (string $query = null) { 36 | $files = App::instance()->site() 37 | ->index(true) 38 | ->filter('isReadable', true) 39 | ->files() 40 | ->search($query) 41 | ->limit(10); 42 | 43 | $results = []; 44 | 45 | foreach ($files as $file) { 46 | $results[] = [ 47 | 'image' => $file->panel()->image(), 48 | 'text' => Escape::html($file->filename()), 49 | 'link' => $file->panel()->url(true), 50 | 'info' => Escape::html($file->id()) 51 | ]; 52 | } 53 | 54 | return $results; 55 | } 56 | ] 57 | ]; 58 | -------------------------------------------------------------------------------- /vendor/phpmailer/phpmailer/src/Exception.php: -------------------------------------------------------------------------------- 1 | 10 | * @author Jim Jagielski (jimjag) 11 | * @author Andy Prevost (codeworxtech) 12 | * @author Brent R. Matzelle (original founder) 13 | * @copyright 2012 - 2020 Marcus Bointon 14 | * @copyright 2010 - 2012 Jim Jagielski 15 | * @copyright 2004 - 2009 Andy Prevost 16 | * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License 17 | * @note This program is distributed in the hope that it will be useful - WITHOUT 18 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 19 | * FITNESS FOR A PARTICULAR PURPOSE. 20 | */ 21 | 22 | namespace PHPMailer\PHPMailer; 23 | 24 | /** 25 | * PHPMailer exception handler. 26 | * 27 | * @author Marcus Bointon 28 | */ 29 | class Exception extends \Exception 30 | { 31 | /** 32 | * Prettify error message output. 33 | * 34 | * @return string 35 | */ 36 | public function errorMessage() 37 | { 38 | return '' . htmlspecialchars($this->getMessage(), ENT_COMPAT | ENT_HTML401) . "
\n"; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Toolkit/Controller.php: -------------------------------------------------------------------------------- 1 | 16 | * @link https://getkirby.com 17 | * @copyright Bastian Allgeier 18 | * @license https://opensource.org/licenses/MIT 19 | */ 20 | class Controller 21 | { 22 | public function __construct(protected Closure $function) 23 | { 24 | } 25 | 26 | public function arguments(array $data = []): array 27 | { 28 | $info = new ReflectionFunction($this->function); 29 | 30 | return A::map( 31 | $info->getParameters(), 32 | fn ($parameter) => $data[$parameter->getName()] ?? null 33 | ); 34 | } 35 | 36 | public function call($bind = null, $data = []) 37 | { 38 | $args = $this->arguments($data); 39 | 40 | if ($bind === null) { 41 | return ($this->function)(...$args); 42 | } 43 | 44 | return $this->function->call($bind, ...$args); 45 | } 46 | 47 | public static function load(string $file) 48 | { 49 | if (is_file($file) === false) { 50 | return null; 51 | } 52 | 53 | $function = F::load($file); 54 | 55 | if ($function instanceof Closure === false) { 56 | return null; 57 | } 58 | 59 | return new static($function); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /vendor/symfony/polyfill-intl-idn/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "symfony/polyfill-intl-idn", 3 | "type": "library", 4 | "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", 5 | "keywords": ["polyfill", "shim", "compatibility", "portable", "intl", "idn"], 6 | "homepage": "https://symfony.com", 7 | "license": "MIT", 8 | "authors": [ 9 | { 10 | "name": "Laurent Bassin", 11 | "email": "laurent@bassin.info" 12 | }, 13 | { 14 | "name": "Trevor Rowbotham", 15 | "email": "trevor.rowbotham@pm.me" 16 | }, 17 | { 18 | "name": "Symfony Community", 19 | "homepage": "https://symfony.com/contributors" 20 | } 21 | ], 22 | "require": { 23 | "php": ">=7.1", 24 | "symfony/polyfill-intl-normalizer": "^1.10", 25 | "symfony/polyfill-php72": "^1.10" 26 | }, 27 | "autoload": { 28 | "psr-4": { "Symfony\\Polyfill\\Intl\\Idn\\": "" }, 29 | "files": [ "bootstrap.php" ] 30 | }, 31 | "suggest": { 32 | "ext-intl": "For best performance" 33 | }, 34 | "minimum-stability": "dev", 35 | "extra": { 36 | "branch-alias": { 37 | "dev-main": "1.27-dev" 38 | }, 39 | "thanks": { 40 | "name": "symfony/polyfill", 41 | "url": "https://github.com/symfony/polyfill" 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Form/Fields.php: -------------------------------------------------------------------------------- 1 | 13 | * @link https://getkirby.com 14 | * @copyright Bastian Allgeier 15 | * @license https://opensource.org/licenses/MIT 16 | */ 17 | class Fields extends Collection 18 | { 19 | /** 20 | * Internal setter for each object in the Collection. 21 | * This takes care of validation and of setting 22 | * the collection prop on each object correctly. 23 | * 24 | * @param string $name 25 | * @param object|array $field 26 | * @return void 27 | */ 28 | public function __set(string $name, $field): void 29 | { 30 | if (is_array($field) === true) { 31 | // use the array key as name if the name is not set 32 | $field['name'] ??= $name; 33 | $field = Field::factory($field['type'], $field, $this); 34 | } 35 | 36 | parent::__set($field->name(), $field); 37 | } 38 | 39 | /** 40 | * Converts the fields collection to an 41 | * array and also does that for every 42 | * included field. 43 | * 44 | * @param \Closure|null $map 45 | * @return array 46 | */ 47 | public function toArray(Closure $map = null): array 48 | { 49 | $array = []; 50 | 51 | foreach ($this as $field) { 52 | $array[$field->name()] = $field->toArray(); 53 | } 54 | 55 | return $array; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /i18n/rules/hy.json: -------------------------------------------------------------------------------- 1 | { 2 | "Ա": "A", 3 | "Բ": "B", 4 | "Գ": "G", 5 | "Դ": "D", 6 | "Ե": "E", 7 | "Զ": "Z", 8 | "Է": "E", 9 | "Ը": "Y", 10 | "Թ": "Th", 11 | "Ժ": "Zh", 12 | "Ի": "I", 13 | "Լ": "L", 14 | "Խ": "Kh", 15 | "Ծ": "Ts", 16 | "Կ": "K", 17 | "Հ": "H", 18 | "Ձ": "Dz", 19 | "Ղ": "Gh", 20 | "Ճ": "Tch", 21 | "Մ": "M", 22 | "Յ": "Y", 23 | "Ն": "N", 24 | "Շ": "Sh", 25 | "Ո": "Vo", 26 | "Չ": "Ch", 27 | "Պ": "P", 28 | "Ջ": "J", 29 | "Ռ": "R", 30 | "Ս": "S", 31 | "Վ": "V", 32 | "Տ": "T", 33 | "Ր": "R", 34 | "Ց": "C", 35 | "Ւ": "u", 36 | "Փ": "Ph", 37 | "Ք": "Q", 38 | "և": "ev", 39 | "Օ": "O", 40 | "Ֆ": "F", 41 | "ա": "a", 42 | "բ": "b", 43 | "գ": "g", 44 | "դ": "d", 45 | "ե": "e", 46 | "զ": "z", 47 | "է": "e", 48 | "ը": "y", 49 | "թ": "th", 50 | "ժ": "zh", 51 | "ի": "i", 52 | "լ": "l", 53 | "խ": "kh", 54 | "ծ": "ts", 55 | "կ": "k", 56 | "հ": "h", 57 | "ձ": "dz", 58 | "ղ": "gh", 59 | "ճ": "tch", 60 | "մ": "m", 61 | "յ": "y", 62 | "ն": "n", 63 | "շ": "sh", 64 | "ո": "vo", 65 | "չ": "ch", 66 | "պ": "p", 67 | "ջ": "j", 68 | "ռ": "r", 69 | "ս": "s", 70 | "վ": "v", 71 | "տ": "t", 72 | "ր": "r", 73 | "ց": "c", 74 | "ւ": "u", 75 | "փ": "ph", 76 | "ք": "q", 77 | "օ": "o", 78 | "ֆ": "f" 79 | } 80 | -------------------------------------------------------------------------------- /src/Blueprint/Extension.php: -------------------------------------------------------------------------------- 1 | 10 | * @link https://getkirby.com 11 | * @copyright Bastian Allgeier 12 | * @license https://opensource.org/licenses/MIT 13 | * 14 | * // TODO: include in test coverage in 3.10 15 | * @codeCoverageIgnore 16 | */ 17 | class Extension 18 | { 19 | public function __construct( 20 | public string $path 21 | ) { 22 | } 23 | 24 | public static function apply(array $props): array 25 | { 26 | if (isset($props['extends']) === false) { 27 | return $props; 28 | } 29 | 30 | // already extended 31 | if (is_a($props['extends'], Extension::class) === true) { 32 | return $props; 33 | } 34 | 35 | $extension = new static($props['extends']); 36 | return $extension->extend($props); 37 | } 38 | 39 | public function extend(array $props): array 40 | { 41 | $props = array_replace_recursive( 42 | $this->read(), 43 | $props 44 | ); 45 | 46 | $props['extends'] = $this; 47 | 48 | return $props; 49 | } 50 | 51 | public static function factory(string|array $path): static 52 | { 53 | if (is_string($path) === true) { 54 | return new static(path: $path); 55 | } 56 | 57 | return new static(...$path); 58 | } 59 | 60 | public function read(): array 61 | { 62 | $config = new Config($this->path); 63 | return $config->read(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/Cms/SiteBlueprint.php: -------------------------------------------------------------------------------- 1 | 11 | * @link https://getkirby.com 12 | * @copyright Bastian Allgeier 13 | * @license https://getkirby.com/license 14 | */ 15 | class SiteBlueprint extends Blueprint 16 | { 17 | /** 18 | * Creates a new page blueprint object 19 | * with the given props 20 | * 21 | * @param array $props 22 | */ 23 | public function __construct(array $props) 24 | { 25 | parent::__construct($props); 26 | 27 | // normalize all available page options 28 | $this->props['options'] = $this->normalizeOptions( 29 | $this->props['options'] ?? true, 30 | // defaults 31 | [ 32 | 'changeTitle' => null, 33 | 'update' => null, 34 | ], 35 | // aliases 36 | [ 37 | 'title' => 'changeTitle', 38 | ] 39 | ); 40 | } 41 | 42 | /** 43 | * Returns the preview settings 44 | * The preview setting controls the "Open" 45 | * button in the panel and redirects it to a 46 | * different URL if necessary. 47 | * 48 | * @return string|bool 49 | */ 50 | public function preview() 51 | { 52 | $preview = $this->props['options']['preview'] ?? true; 53 | 54 | if (is_string($preview) === true) { 55 | return $this->model->toString($preview); 56 | } 57 | 58 | return $preview; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /config/fields/checkboxes.php: -------------------------------------------------------------------------------- 1 | ['min', 'options'], 8 | 'props' => [ 9 | /** 10 | * Unset inherited props 11 | */ 12 | 'after' => null, 13 | 'before' => null, 14 | 'icon' => null, 15 | 'placeholder' => null, 16 | 17 | /** 18 | * Arranges the checkboxes in the given number of columns 19 | */ 20 | 'columns' => function (int $columns = 1) { 21 | return $columns; 22 | }, 23 | /** 24 | * Default value for the field, which will be used when a page/file/user is created 25 | */ 26 | 'default' => function ($default = null) { 27 | return Str::split($default, ','); 28 | }, 29 | /** 30 | * Maximum number of checked boxes 31 | */ 32 | 'max' => function (int $max = null) { 33 | return $max; 34 | }, 35 | /** 36 | * Minimum number of checked boxes 37 | */ 38 | 'min' => function (int $min = null) { 39 | return $min; 40 | }, 41 | 'value' => function ($value = null) { 42 | return Str::split($value, ','); 43 | }, 44 | ], 45 | 'computed' => [ 46 | 'default' => function () { 47 | return $this->sanitizeOptions($this->default); 48 | }, 49 | 'value' => function () { 50 | return $this->sanitizeOptions($this->value); 51 | }, 52 | ], 53 | 'save' => function ($value): string { 54 | return A::join($value, ', '); 55 | }, 56 | 'validations' => [ 57 | 'options', 58 | 'max', 59 | 'min' 60 | ] 61 | ]; 62 | -------------------------------------------------------------------------------- /vendor/filp/whoops/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "filp/whoops", 3 | "license": "MIT", 4 | "description": "php error handling for cool kids", 5 | "keywords": ["library", "error", "handling", "exception", "whoops", "throwable"], 6 | "homepage": "https://filp.github.io/whoops/", 7 | "authors": [ 8 | { 9 | "name": "Filipe Dobreira", 10 | "homepage": "https://github.com/filp", 11 | "role": "Developer" 12 | } 13 | ], 14 | "scripts": { 15 | "test": "phpunit --testdox tests" 16 | }, 17 | "require": { 18 | "php": "^5.5.9 || ^7.0 || ^8.0", 19 | "psr/log": "^1.0.1 || ^2.0 || ^3.0" 20 | }, 21 | "require-dev": { 22 | "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.3", 23 | "mockery/mockery": "^0.9 || ^1.0", 24 | "symfony/var-dumper": "^2.6 || ^3.0 || ^4.0 || ^5.0" 25 | }, 26 | "suggest": { 27 | "symfony/var-dumper": "Pretty print complex values better with var-dumper available", 28 | "whoops/soap": "Formats errors as SOAP responses" 29 | }, 30 | "autoload": { 31 | "psr-4": { 32 | "Whoops\\": "src/Whoops/" 33 | } 34 | }, 35 | "autoload-dev": { 36 | "psr-4": { 37 | "Whoops\\": "tests/Whoops/" 38 | } 39 | }, 40 | "extra": { 41 | "branch-alias": { 42 | "dev-master": "2.7-dev" 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /vendor/phpmailer/phpmailer/language/phpmailer.lang-zh_cn.php: -------------------------------------------------------------------------------- 1 | 7 | * @author young 8 | * @author Teddysun 9 | */ 10 | 11 | $PHPMAILER_LANG['authenticate'] = 'SMTP 错误:登录失败。'; 12 | $PHPMAILER_LANG['connect_host'] = 'SMTP 错误:无法连接到 SMTP 主机。'; 13 | $PHPMAILER_LANG['data_not_accepted'] = 'SMTP 错误:数据不被接受。'; 14 | $PHPMAILER_LANG['empty_message'] = '邮件正文为空。'; 15 | $PHPMAILER_LANG['encoding'] = '未知编码:'; 16 | $PHPMAILER_LANG['execute'] = '无法执行:'; 17 | $PHPMAILER_LANG['file_access'] = '无法访问文件:'; 18 | $PHPMAILER_LANG['file_open'] = '文件错误:无法打开文件:'; 19 | $PHPMAILER_LANG['from_failed'] = '发送地址错误:'; 20 | $PHPMAILER_LANG['instantiate'] = '未知函数调用。'; 21 | $PHPMAILER_LANG['invalid_address'] = '发送失败,电子邮箱地址是无效的:'; 22 | $PHPMAILER_LANG['mailer_not_supported'] = '发信客户端不被支持。'; 23 | $PHPMAILER_LANG['provide_address'] = '必须提供至少一个收件人地址。'; 24 | $PHPMAILER_LANG['recipients_failed'] = 'SMTP 错误:收件人地址错误:'; 25 | $PHPMAILER_LANG['signing'] = '登录失败:'; 26 | $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP服务器连接失败。'; 27 | $PHPMAILER_LANG['smtp_error'] = 'SMTP服务器出错:'; 28 | $PHPMAILER_LANG['variable_set'] = '无法设置或重置变量:'; 29 | $PHPMAILER_LANG['extension_missing'] = '丢失模块 Extension:'; 30 | -------------------------------------------------------------------------------- /vendor/phpmailer/phpmailer/language/phpmailer.lang-zh.php: -------------------------------------------------------------------------------- 1 | 7 | * @author Peter Dave Hello <@PeterDaveHello/> 8 | * @author Jason Chiang 9 | */ 10 | 11 | $PHPMAILER_LANG['authenticate'] = 'SMTP 錯誤:登入失敗。'; 12 | $PHPMAILER_LANG['connect_host'] = 'SMTP 錯誤:無法連線到 SMTP 主機。'; 13 | $PHPMAILER_LANG['data_not_accepted'] = 'SMTP 錯誤:無法接受的資料。'; 14 | $PHPMAILER_LANG['empty_message'] = '郵件內容為空'; 15 | $PHPMAILER_LANG['encoding'] = '未知編碼: '; 16 | $PHPMAILER_LANG['execute'] = '無法執行:'; 17 | $PHPMAILER_LANG['file_access'] = '無法存取檔案:'; 18 | $PHPMAILER_LANG['file_open'] = '檔案錯誤:無法開啟檔案:'; 19 | $PHPMAILER_LANG['from_failed'] = '發送地址錯誤:'; 20 | $PHPMAILER_LANG['instantiate'] = '未知函數呼叫。'; 21 | $PHPMAILER_LANG['invalid_address'] = '因為電子郵件地址無效,無法傳送: '; 22 | $PHPMAILER_LANG['mailer_not_supported'] = '不支援的發信客戶端。'; 23 | $PHPMAILER_LANG['provide_address'] = '必須提供至少一個收件人地址。'; 24 | $PHPMAILER_LANG['recipients_failed'] = 'SMTP 錯誤:以下收件人地址錯誤:'; 25 | $PHPMAILER_LANG['signing'] = '電子簽章錯誤: '; 26 | $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP 連線失敗'; 27 | $PHPMAILER_LANG['smtp_error'] = 'SMTP 伺服器錯誤: '; 28 | $PHPMAILER_LANG['variable_set'] = '無法設定或重設變數: '; 29 | $PHPMAILER_LANG['extension_missing'] = '遺失模組 Extension: '; 30 | -------------------------------------------------------------------------------- /vendor/phpmailer/phpmailer/language/phpmailer.lang-ko.php: -------------------------------------------------------------------------------- 1 | 7 | */ 8 | 9 | $PHPMAILER_LANG['authenticate'] = 'SMTP 오류: 인증할 수 없습니다.'; 10 | $PHPMAILER_LANG['connect_host'] = 'SMTP 오류: SMTP 호스트에 접속할 수 없습니다.'; 11 | $PHPMAILER_LANG['data_not_accepted'] = 'SMTP 오류: 데이터가 받아들여지지 않았습니다.'; 12 | $PHPMAILER_LANG['empty_message'] = '메세지 내용이 없습니다'; 13 | $PHPMAILER_LANG['encoding'] = '알 수 없는 인코딩: '; 14 | $PHPMAILER_LANG['execute'] = '실행 불가: '; 15 | $PHPMAILER_LANG['file_access'] = '파일 접근 불가: '; 16 | $PHPMAILER_LANG['file_open'] = '파일 오류: 파일을 열 수 없습니다: '; 17 | $PHPMAILER_LANG['from_failed'] = '다음 From 주소에서 오류가 발생했습니다: '; 18 | $PHPMAILER_LANG['instantiate'] = 'mail 함수를 인스턴스화할 수 없습니다'; 19 | $PHPMAILER_LANG['invalid_address'] = '잘못된 주소: '; 20 | $PHPMAILER_LANG['mailer_not_supported'] = ' 메일러는 지원되지 않습니다.'; 21 | $PHPMAILER_LANG['provide_address'] = '적어도 한 개 이상의 수신자 메일 주소를 제공해야 합니다.'; 22 | $PHPMAILER_LANG['recipients_failed'] = 'SMTP 오류: 다음 수신자에서 오류가 발생했습니다: '; 23 | $PHPMAILER_LANG['signing'] = '서명 오류: '; 24 | $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP 연결을 실패하였습니다.'; 25 | $PHPMAILER_LANG['smtp_error'] = 'SMTP 서버 오류: '; 26 | $PHPMAILER_LANG['variable_set'] = '변수 설정 및 초기화 불가: '; 27 | $PHPMAILER_LANG['extension_missing'] = '확장자 없음: '; 28 | -------------------------------------------------------------------------------- /src/Uuid/SiteUuid.php: -------------------------------------------------------------------------------- 1 | 15 | * @link https://getkirby.com 16 | * @copyright Bastian Allgeier 17 | * @license https://getkirby.com/license 18 | */ 19 | class SiteUuid extends Uuid 20 | { 21 | protected const TYPE = 'site'; 22 | 23 | /** 24 | * @var \Kirby\Cms\Site|null 25 | */ 26 | public Identifiable|null $model; 27 | 28 | /** 29 | * Generator for the one and only site object 30 | * 31 | * @return \Generator|\Kirby\Cms\Site[] 32 | */ 33 | public static function index(): Generator 34 | { 35 | yield App::instance()->site(); 36 | } 37 | 38 | /** 39 | * Returns the site object 40 | */ 41 | public function model(bool $lazy = false): Site 42 | { 43 | return $this->model ??= App::instance()->site(); 44 | } 45 | 46 | /** 47 | * Pretends to fill cache - we don't need it in cache 48 | */ 49 | public function populate(): bool 50 | { 51 | return true; 52 | } 53 | 54 | /** 55 | * Returns empty string since 56 | * site doesn't really need an ID 57 | */ 58 | public static function retrieveId(Identifiable $model): string 59 | { 60 | return ''; 61 | } 62 | 63 | /** 64 | * Returns the full UUID string including scheme 65 | */ 66 | public function toString(): string 67 | { 68 | return 'site://'; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /assets/whoops.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: #efefef; 3 | font: normal normal 400 12px/1.5 -apple-system, BlinkMacSystemFont, Segoe UI, 4 | Roboto, Helvetica, Arial, sans-serif; 5 | } 6 | 7 | .left-panel { 8 | background: transparent; 9 | } 10 | 11 | header { 12 | background-color: #313740; 13 | } 14 | 15 | .exc-title-primary { 16 | color: hsl(0, 71%, 55%); 17 | } 18 | 19 | .frame.active { 20 | color: hsl(0, 71%, 55%); 21 | box-shadow: inset -5px 0 0 0 #d16464; 22 | } 23 | 24 | .frame:not(.active):hover { 25 | background: rgba(203, 215, 229, 0.5); 26 | } 27 | 28 | .rightButton { 29 | color: #999; 30 | box-shadow: inset 0 0 0 1px #777; 31 | border-radius: 0; 32 | } 33 | 34 | .rightButton:hover { 35 | box-shadow: inset 0 0 0 1px #555; 36 | color: #777; 37 | } 38 | 39 | .details-heading { 40 | color: #7e9abf; 41 | font-weight: 500; 42 | } 43 | 44 | .frame-code { 45 | background: #000; 46 | } 47 | 48 | pre.code-block, 49 | code.code-block, 50 | .frame-args.code-block, 51 | .frame-args.code-block samp { 52 | background: #16171a; 53 | } 54 | 55 | .linenums li.current { 56 | background: transparent; 57 | } 58 | 59 | .linenums li.current.active { 60 | background: rgba(209, 100, 100, 0.3); 61 | } 62 | 63 | pre .atv, 64 | code .atv, 65 | pre .str, 66 | code .str { 67 | color: #a7bd68; 68 | } 69 | 70 | pre .tag, 71 | code .tag { 72 | color: #d16464; 73 | } 74 | 75 | pre .kwd, 76 | code .kwd { 77 | color: #8abeb7; 78 | } 79 | 80 | pre .atn, 81 | code .atn { 82 | color: #de935f; 83 | } 84 | -------------------------------------------------------------------------------- /src/Cms/UserPermissions.php: -------------------------------------------------------------------------------- 1 | 10 | * @link https://getkirby.com 11 | * @copyright Bastian Allgeier 12 | * @license https://getkirby.com/license 13 | */ 14 | class UserPermissions extends ModelPermissions 15 | { 16 | /** 17 | * @var string 18 | */ 19 | protected $category = 'users'; 20 | 21 | /** 22 | * UserPermissions constructor 23 | * 24 | * @param \Kirby\Cms\Model $model 25 | */ 26 | public function __construct(Model $model) 27 | { 28 | parent::__construct($model); 29 | 30 | // change the scope of the permissions, when the current user is this user 31 | $this->category = $this->user && $this->user->is($model) ? 'user' : 'users'; 32 | } 33 | 34 | /** 35 | * @return bool 36 | */ 37 | protected function canChangeRole(): bool 38 | { 39 | return $this->model->roles()->count() > 1; 40 | } 41 | 42 | /** 43 | * @return bool 44 | */ 45 | protected function canCreate(): bool 46 | { 47 | // the admin can always create new users 48 | if ($this->user->isAdmin() === true) { 49 | return true; 50 | } 51 | 52 | // users who are not admins cannot create admins 53 | if ($this->model->isAdmin() === true) { 54 | return false; 55 | } 56 | 57 | return true; 58 | } 59 | 60 | /** 61 | * @return bool 62 | */ 63 | protected function canDelete(): bool 64 | { 65 | return $this->model->isLastAdmin() !== true; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/Http/Request/Auth/BasicAuth.php: -------------------------------------------------------------------------------- 1 | 14 | * @link https://getkirby.com 15 | * @copyright Bastian Allgeier 16 | * @license https://opensource.org/licenses/MIT 17 | */ 18 | class BasicAuth extends Auth 19 | { 20 | protected string $credentials; 21 | protected string|null $password; 22 | protected string|null $username; 23 | 24 | public function __construct( 25 | #[SensitiveParameter] 26 | string $data 27 | ) { 28 | parent::__construct($data); 29 | 30 | $this->credentials = base64_decode($data); 31 | $this->username = Str::before($this->credentials, ':'); 32 | $this->password = Str::after($this->credentials, ':'); 33 | } 34 | 35 | /** 36 | * Returns the entire unencoded credentials string 37 | */ 38 | public function credentials(): string 39 | { 40 | return $this->credentials; 41 | } 42 | 43 | /** 44 | * Returns the password 45 | */ 46 | public function password(): string|null 47 | { 48 | return $this->password; 49 | } 50 | 51 | /** 52 | * Returns the authentication type 53 | */ 54 | public function type(): string 55 | { 56 | return 'basic'; 57 | } 58 | 59 | /** 60 | * Returns the username 61 | */ 62 | public function username(): string|null 63 | { 64 | return $this->username; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /config/sections/fields.php: -------------------------------------------------------------------------------- 1 | [ 9 | 'fields' => function (array $fields = []) { 10 | return $fields; 11 | } 12 | ], 13 | 'computed' => [ 14 | 'form' => function () { 15 | $fields = $this->fields; 16 | $disabled = $this->model->permissions()->update() === false; 17 | $lang = $this->model->kirby()->languageCode(); 18 | $content = $this->model->content($lang)->toArray(); 19 | 20 | if ($disabled === true) { 21 | foreach ($fields as $key => $props) { 22 | $fields[$key]['disabled'] = true; 23 | } 24 | } 25 | 26 | return new Form([ 27 | 'fields' => $fields, 28 | 'values' => $content, 29 | 'model' => $this->model, 30 | 'strict' => true 31 | ]); 32 | }, 33 | 'fields' => function () { 34 | $fields = $this->form->fields()->toArray(); 35 | 36 | if ( 37 | $this->model instanceof Page || 38 | $this->model instanceof Site 39 | ) { 40 | // the title should never be updated directly via 41 | // fields section to avoid conflicts with the rename dialog 42 | unset($fields['title']); 43 | } 44 | 45 | foreach ($fields as $index => $props) { 46 | unset($fields[$index]['value']); 47 | } 48 | 49 | return $fields; 50 | } 51 | ], 52 | 'methods' => [ 53 | 'errors' => function () { 54 | return $this->form->errors(); 55 | } 56 | ], 57 | 'toArray' => function () { 58 | return [ 59 | 'fields' => $this->fields, 60 | ]; 61 | } 62 | ]; 63 | -------------------------------------------------------------------------------- /src/Image/Camera.php: -------------------------------------------------------------------------------- 1 | 10 | * @link https://getkirby.com 11 | * @copyright Bastian Allgeier 12 | * @license https://opensource.org/licenses/MIT 13 | */ 14 | class Camera 15 | { 16 | /** 17 | * Make exif data 18 | */ 19 | protected string|null $make; 20 | 21 | /** 22 | * Model exif data 23 | * 24 | * @var 25 | */ 26 | protected string|null $model; 27 | 28 | public function __construct(array $exif) 29 | { 30 | $this->make = $exif['Make'] ?? null; 31 | $this->model = $exif['Model'] ?? null; 32 | } 33 | 34 | /** 35 | * Returns the make of the camera 36 | */ 37 | public function make(): string|null 38 | { 39 | return $this->make; 40 | } 41 | 42 | /** 43 | * Returns the camera model 44 | */ 45 | public function model(): string|null 46 | { 47 | return $this->model; 48 | } 49 | 50 | /** 51 | * Converts the object into a nicely readable array 52 | */ 53 | public function toArray(): array 54 | { 55 | return [ 56 | 'make' => $this->make, 57 | 'model' => $this->model 58 | ]; 59 | } 60 | 61 | /** 62 | * Returns the full make + model name 63 | */ 64 | public function __toString(): string 65 | { 66 | return trim($this->make . ' ' . $this->model); 67 | } 68 | 69 | /** 70 | * Improved `var_dump` output 71 | */ 72 | public function __debugInfo(): array 73 | { 74 | return $this->toArray(); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /config/api/models/FileVersion.php: -------------------------------------------------------------------------------- 1 | [ 10 | 'dimensions' => fn (FileVersion $file) => $file->dimensions()->toArray(), 11 | 'exists' => fn (FileVersion $file) => $file->exists(), 12 | 'extension' => fn (FileVersion $file) => $file->extension(), 13 | 'filename' => fn (FileVersion $file) => $file->filename(), 14 | 'id' => fn (FileVersion $file) => $file->id(), 15 | 'mime' => fn (FileVersion $file) => $file->mime(), 16 | 'modified' => fn (FileVersion $file) => $file->modified('c'), 17 | 'name' => fn (FileVersion $file) => $file->name(), 18 | 'niceSize' => fn (FileVersion $file) => $file->niceSize(), 19 | 'size' => fn (FileVersion $file) => $file->size(), 20 | 'type' => fn (FileVersion $file) => $file->type(), 21 | 'url' => fn (FileVersion $file) => $file->url(), 22 | ], 23 | 'type' => 'Kirby\Cms\FileVersion', 24 | 'views' => [ 25 | 'default' => [ 26 | 'dimensions', 27 | 'exists', 28 | 'extension', 29 | 'filename', 30 | 'id', 31 | 'mime', 32 | 'modified', 33 | 'name', 34 | 'niceSize', 35 | 'size', 36 | 'type', 37 | 'url' 38 | ], 39 | 'compact' => [ 40 | 'filename', 41 | 'id', 42 | 'type', 43 | 'url', 44 | ], 45 | 'panel' => [ 46 | 'dimensions', 47 | 'extension', 48 | 'filename', 49 | 'id', 50 | 'mime', 51 | 'modified', 52 | 'name', 53 | 'niceSize', 54 | 'template', 55 | 'type', 56 | 'url' 57 | ] 58 | ], 59 | ]; 60 | --------------------------------------------------------------------------------