init
0
site/accounts/index.html
Normal file
16
site/blueprints/blocks/audio.yml
Normal file
@@ -0,0 +1,16 @@
|
||||
name: Audio
|
||||
icon: audio
|
||||
wysiwyg: true
|
||||
preview: fields
|
||||
label: false
|
||||
fields:
|
||||
file:
|
||||
label: File
|
||||
type: files
|
||||
min: 1
|
||||
query: page.audio
|
||||
width: 3/4
|
||||
loop:
|
||||
label: Wiederholen
|
||||
type: toggle
|
||||
width: 1/4
|
||||
17
site/blueprints/blocks/embed.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
name: Embed
|
||||
icon: video
|
||||
wysiwyg: true
|
||||
preview: fields
|
||||
label: false
|
||||
fields:
|
||||
embed:
|
||||
label: Embed
|
||||
type: embed
|
||||
text:
|
||||
label: Untertitel
|
||||
type: text
|
||||
width: 3/4
|
||||
loop:
|
||||
label: Wiederholen (loop, nur youtube)
|
||||
type: toggle
|
||||
width: 1/4
|
||||
22
site/blueprints/blocks/image.yml
Normal file
@@ -0,0 +1,22 @@
|
||||
name: field.blocks.image.name
|
||||
icon: image
|
||||
preview: image
|
||||
fields:
|
||||
image:
|
||||
label: field.blocks.image.name
|
||||
type: files
|
||||
query: model.images
|
||||
multiple: false
|
||||
image:
|
||||
back: black
|
||||
uploads:
|
||||
template: blocks/image
|
||||
alt:
|
||||
label: field.blocks.image.alt
|
||||
type: text
|
||||
icon: title
|
||||
caption:
|
||||
label: field.blocks.image.caption
|
||||
type: writer
|
||||
icon: text
|
||||
inline: true
|
||||
16
site/blueprints/blocks/image_gallery.yml
Normal file
@@ -0,0 +1,16 @@
|
||||
name: field.blocks.gallery.name
|
||||
icon: dashboard
|
||||
preview: fields
|
||||
fields:
|
||||
images:
|
||||
label: field.blocks.gallery.images.label
|
||||
type: files
|
||||
query: model.images
|
||||
multiple: true
|
||||
layout: list
|
||||
size: tiny
|
||||
empty: field.blocks.gallery.images.empty
|
||||
uploads:
|
||||
template: blocks/image
|
||||
image:
|
||||
ratio: 1/1
|
||||
31
site/blueprints/blocks/texts.yml
Normal file
@@ -0,0 +1,31 @@
|
||||
name: Text
|
||||
icon: text
|
||||
wysiwyg: true
|
||||
preview: fields
|
||||
|
||||
fields:
|
||||
text:
|
||||
type: writer
|
||||
toolbar:
|
||||
inline: false
|
||||
headings:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
- 4
|
||||
- 5
|
||||
marks:
|
||||
- code
|
||||
- '|'
|
||||
- link
|
||||
- email
|
||||
- '|'
|
||||
- clear
|
||||
center_horizontal:
|
||||
label: Horizontal Zentrieren?
|
||||
type: toggle
|
||||
width: 1/2
|
||||
center_vertical:
|
||||
label: Vertikal Zentrieren?
|
||||
type: toggle
|
||||
width: 1/2
|
||||
10
site/blueprints/blocks/twitch.yml
Normal file
@@ -0,0 +1,10 @@
|
||||
name: Twitch
|
||||
icon: live
|
||||
wysiwyg: true
|
||||
preview: fields
|
||||
label: false
|
||||
fields:
|
||||
channel:
|
||||
label: Channel Name
|
||||
type: text
|
||||
help: Nur der Channel Name, eg der letzte Teil der Url
|
||||
27
site/blueprints/blocks/video.yml
Normal file
@@ -0,0 +1,27 @@
|
||||
name: Video
|
||||
icon: video
|
||||
wysiwyg: true
|
||||
preview: fields
|
||||
label: false
|
||||
fields:
|
||||
file:
|
||||
label: Video File
|
||||
type: files
|
||||
query: page.video
|
||||
multiple: false
|
||||
width: 2/4
|
||||
poster:
|
||||
label: Poster Image
|
||||
type: files
|
||||
query: page.images
|
||||
multiple: false
|
||||
width: 1/4
|
||||
loop:
|
||||
label: Wiederholen
|
||||
type: toggle
|
||||
width: 1/4
|
||||
caption:
|
||||
label: field.blocks.image.caption
|
||||
type: writer
|
||||
icon: text
|
||||
inline: true
|
||||
23
site/blueprints/fields/block_settings.yml
Normal file
@@ -0,0 +1,23 @@
|
||||
fields:
|
||||
background:
|
||||
label: Hintergrund
|
||||
type: color
|
||||
mode: options
|
||||
options:
|
||||
- "#f1edeb"
|
||||
- "#ff00ff"
|
||||
- "#48bd8d"
|
||||
- "#8200ff"
|
||||
- "#ff6700"
|
||||
- "#000000"
|
||||
grid:
|
||||
label: Raster
|
||||
type: color
|
||||
mode: options
|
||||
options:
|
||||
- "#f1edeb"
|
||||
- "#ff00ff"
|
||||
- "#48bd8d"
|
||||
- "#8200ff"
|
||||
- "#ff6700"
|
||||
- "#000000"
|
||||
16
site/blueprints/pages/calendar.yml
Normal file
@@ -0,0 +1,16 @@
|
||||
title: Kalender
|
||||
|
||||
columns:
|
||||
- width: 1/3
|
||||
sections:
|
||||
drafts:
|
||||
extends: sections/calendar
|
||||
label: Drafts
|
||||
status: draft
|
||||
|
||||
- width: 2/3
|
||||
sections:
|
||||
listed:
|
||||
extends: sections/calendar
|
||||
label: Veröffentlich
|
||||
status: listed
|
||||
52
site/blueprints/pages/calendar_entry.yml
Normal file
@@ -0,0 +1,52 @@
|
||||
title: Kalender Eintrag
|
||||
|
||||
icon: calendar
|
||||
|
||||
status:
|
||||
draft: Draft
|
||||
listed: Published
|
||||
|
||||
sections:
|
||||
fields:
|
||||
type: fields
|
||||
fields:
|
||||
date:
|
||||
label: Date
|
||||
type: writer
|
||||
toolbar:
|
||||
inline: false
|
||||
headings:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
- 4
|
||||
- 5
|
||||
marks:
|
||||
- code
|
||||
- clear
|
||||
width: 1/3
|
||||
required: true
|
||||
description:
|
||||
label: Beschreibung
|
||||
type: writer
|
||||
toolbar:
|
||||
inline: false
|
||||
headings:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
- 4
|
||||
- 5
|
||||
marks:
|
||||
- code
|
||||
- clear
|
||||
width: 2/3
|
||||
page:
|
||||
label: Projekt
|
||||
type: pages
|
||||
query: site.find('projects')
|
||||
multiple: false
|
||||
required: true
|
||||
|
||||
options:
|
||||
preview: false
|
||||
28
site/blueprints/pages/default.yml
Normal file
@@ -0,0 +1,28 @@
|
||||
title: Default Page
|
||||
|
||||
status:
|
||||
draft: Draft
|
||||
unlisted: Online
|
||||
|
||||
columns:
|
||||
main:
|
||||
width: 2/3
|
||||
sections:
|
||||
fields:
|
||||
type: fields
|
||||
fields:
|
||||
layout:
|
||||
label: Layout
|
||||
type: layout
|
||||
layouts:
|
||||
- "1/1"
|
||||
- "1/2, 1/2"
|
||||
fieldsets:
|
||||
- image
|
||||
- image_gallery
|
||||
- embed
|
||||
- audio
|
||||
- twitch
|
||||
- video
|
||||
- texts
|
||||
settings: fields/block_settings
|
||||
49
site/blueprints/pages/project.yml
Normal file
@@ -0,0 +1,49 @@
|
||||
title: Künstler*innen & Projekte
|
||||
|
||||
tabs:
|
||||
general:
|
||||
label: General
|
||||
columns:
|
||||
- width: 2/3
|
||||
sections:
|
||||
content:
|
||||
type: fields
|
||||
fields:
|
||||
start_date:
|
||||
label: Start Date
|
||||
type: date
|
||||
width: 1/2
|
||||
required: true
|
||||
translate: false
|
||||
end_date:
|
||||
label: End Date
|
||||
type: date
|
||||
width: 1/2
|
||||
translate: false
|
||||
- width: 1/3
|
||||
sections:
|
||||
content_right:
|
||||
type: fields
|
||||
fields:
|
||||
files:
|
||||
label: files
|
||||
type: files
|
||||
|
||||
work:
|
||||
label: Projekt
|
||||
fields:
|
||||
layout:
|
||||
label: Layout
|
||||
type: layout
|
||||
layouts:
|
||||
- "1/1"
|
||||
- "1/2, 1/2"
|
||||
fieldsets:
|
||||
- image
|
||||
- image_gallery
|
||||
- embed
|
||||
- audio
|
||||
- twitch
|
||||
- video
|
||||
- texts
|
||||
settings: fields/block_settings
|
||||
38
site/blueprints/pages/projects.yml
Normal file
@@ -0,0 +1,38 @@
|
||||
title: Projects
|
||||
|
||||
columns:
|
||||
- width: 1/3
|
||||
sections:
|
||||
drafts:
|
||||
extends: sections/projects
|
||||
label: Drafts
|
||||
status: draft
|
||||
parent: page
|
||||
|
||||
- width: 2/3
|
||||
sections:
|
||||
listed:
|
||||
extends: sections/projects
|
||||
label: Veröffentlich
|
||||
status: listed
|
||||
parent: page
|
||||
- width: 1
|
||||
sections:
|
||||
fields:
|
||||
type: fields
|
||||
fields:
|
||||
layout:
|
||||
label: Layout
|
||||
type: layout
|
||||
layouts:
|
||||
- "1/1"
|
||||
- "1/2, 1/2"
|
||||
fieldsets:
|
||||
- image
|
||||
- image_gallery
|
||||
- embed
|
||||
- audio
|
||||
- twitch
|
||||
- video
|
||||
- texts
|
||||
settings: fields/block_settings
|
||||
5
site/blueprints/sections/calendar.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
type: pages
|
||||
label: Kalender
|
||||
parent: kirby.page("calendar")
|
||||
info: "{{ page.date }}"
|
||||
template: calendar_entry
|
||||
5
site/blueprints/sections/projects.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
type: pages
|
||||
label: Künstler*innen & Projekte 2024/25
|
||||
parent: kirby.page("projects")
|
||||
info: "{{ page.start_date.toDate('d.m.') }} — {{ page.end_date.toDate('d.m.y') }}"
|
||||
template: project
|
||||
20
site/blueprints/site.yml
Normal file
@@ -0,0 +1,20 @@
|
||||
title: Re Capitulating. Queer
|
||||
|
||||
columns:
|
||||
- width: 2/3
|
||||
sections:
|
||||
calendar_entry: sections/calendar
|
||||
projects: sections/projects
|
||||
- width: 1/3
|
||||
sections:
|
||||
menus:
|
||||
type: fields
|
||||
fields:
|
||||
menuItems:
|
||||
type: pages
|
||||
label: Menu item
|
||||
pages:
|
||||
type: pages
|
||||
templates:
|
||||
- default
|
||||
- home
|
||||
0
site/cache/index.html
vendored
Normal file
24
site/config/config.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'languages' => true,
|
||||
'debug' => true,
|
||||
'thumbs' => [
|
||||
'srcsets' => [
|
||||
'full' => [
|
||||
'1x' => [
|
||||
'width' => 960,
|
||||
'height' => 960,
|
||||
'crop' => false,
|
||||
'quality' => 90,
|
||||
],
|
||||
'2x' => [
|
||||
'width' => 960 * 2,
|
||||
'height' => 960 * 2,
|
||||
'crop' => false,
|
||||
'quality' => 90,
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
];
|
||||
15
site/languages/de.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'code' => 'de',
|
||||
'default' => true,
|
||||
'direction' => 'ltr',
|
||||
'locale' => [
|
||||
'LC_ALL' => 'de_DE'
|
||||
],
|
||||
'name' => 'Deutsch',
|
||||
'translations' => [
|
||||
|
||||
],
|
||||
'url' => NULL
|
||||
];
|
||||
15
site/languages/en.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'code' => 'en',
|
||||
'default' => false,
|
||||
'direction' => 'ltr',
|
||||
'locale' => [
|
||||
'LC_ALL' => 'en_US'
|
||||
],
|
||||
'name' => 'Englisch',
|
||||
'translations' => [
|
||||
|
||||
],
|
||||
'url' => NULL
|
||||
];
|
||||
9
site/plugins/embed/.editorconfig
Normal file
@@ -0,0 +1,9 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
5
site/plugins/embed/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
.DS_Store
|
||||
.cache
|
||||
node_modules
|
||||
package-lock.json
|
||||
composer.lock
|
||||
125
site/plugins/embed/README.md
Normal file
@@ -0,0 +1,125 @@
|
||||
# Kirby Embed
|
||||
|
||||
Embed field for Kirby 3 and 4. Display embeds from various media sites (Youtube, Vimeo, Souncloud, Instagram, etc.) by only providing the url to the medium.
|
||||
Built on top of [oscarotero/Embed](https://github.com/oscarotero/Embed).
|
||||
|
||||

|
||||
|
||||
## Overview
|
||||
|
||||
> This plugin is completely free and published under the MIT license. However, if you are using it in a commercial project and want to help me keep up with maintenance, please consider [making a donation of your choice](https://www.paypal.me/sylvainjl) or purchasing your license(s) through [my affiliate link](https://a.paddle.com/v2/click/1129/36369?link=1170).
|
||||
|
||||
- [1. Installation](#1-installation)
|
||||
- [2. Blueprint usage](#2-blueprint-usage)
|
||||
- [3. Front-end usage](#3-front-end-usage)
|
||||
- [4. License](#4-license)
|
||||
- [5. Credits](#5-credits)
|
||||
|
||||
## 1. Installation
|
||||
|
||||
> Kirby 3: up to 1.1.0
|
||||
> Kirby 4: 1.1.1+
|
||||
|
||||
Download and copy this repository to ```/site/plugins/embed```
|
||||
|
||||
Alternatively, you can install it with composer: ```composer require sylvainjule/embed```
|
||||
|
||||
<br/>
|
||||
|
||||
## 2. Blueprint usage
|
||||
|
||||
The plugin provides a `embed` field that you can include in any blueprint:
|
||||
|
||||
```yaml
|
||||
fields:
|
||||
embed:
|
||||
label: Embed
|
||||
type: embed
|
||||
```
|
||||
|
||||
You have access to all providers supported by [oscarotero/Embed](https://github.com/oscarotero/Embed). Please note that I won't include any provider unsupported by this library.
|
||||
|
||||
You can optionally limit the allowed provider to one within this list : `youtube`, `vimeo`, `flickr`, `instagram`, `twitter`, `soundcloud`. If any other link is pasted, the field won't request the embed.
|
||||
|
||||
```yaml
|
||||
embed:
|
||||
type: embed
|
||||
provider: youtube
|
||||
```
|
||||
|
||||
If you are using this field in a structure field, it comes with a built-in preview. You can optionally set `icons: true` (default is `false`) to display some providers logos in this preview.
|
||||
|
||||
```yaml
|
||||
embed:
|
||||
type: embed
|
||||
icons: true
|
||||
```
|
||||
|
||||

|
||||
|
||||
The field also has all the `url` field's options, except those which wouldn't make much sense for such a plugin (`default` for example), won't fetch anything in the backstage.
|
||||
|
||||
<br/>
|
||||
|
||||
## 3. Front-end usage
|
||||
|
||||
The plugin provides a `->toEmbed()` method, which is useful to get all the stored data of the embed (its html code, and a few other informations detailed below).
|
||||
|
||||
It also allows you to make sure your embed is successfully synced before trying to access the data:
|
||||
|
||||
```php
|
||||
if($embed = $page->myfield()->toEmbed()) {
|
||||
echo $embed->code()
|
||||
}
|
||||
```
|
||||
|
||||
Once you have access to the structured embed, here are the options you will have access to as if they were fields (this comes handy because depending on the provider, some informations might be empty. You can therefore check them with the usual Kirby field methods, like `$embed->license()->isEmpty()`).
|
||||
|
||||
```php
|
||||
$embed->title(); // The page title
|
||||
$embed->description(); // The page description
|
||||
$embed->url(); // The canonical url
|
||||
$embed->type(); // The page type (link, video, image, rich)
|
||||
$embed->tags(); // The page keywords (tags)
|
||||
|
||||
$embed->image(); // The main image found in the page
|
||||
|
||||
$embed->code(); // The code to embed the image, video, etc
|
||||
$embed->width(); // The width of the embed code
|
||||
$embed->height(); // The height of the embed code
|
||||
$embed->aspectRatio(); // The aspect ratio (width / height)
|
||||
|
||||
$embed->authorName(); // The resource author
|
||||
$embed->authorUrl(); // The author url
|
||||
|
||||
$embed->providerName(); // The provider name of the page (Youtube, Twitter, Instagram, etc)
|
||||
$embed->providerUrl(); // The provider url
|
||||
$embed->providerIcon(); // The main icon found in the page
|
||||
|
||||
$embed->publishedDate(); // The published date of the resource
|
||||
$embed->license(); // The license url of the resource
|
||||
$embed->feeds(); // The RSS/Atom feeds
|
||||
```
|
||||
|
||||
A global site method is available to request embed data `$site->getEmbedData($url)`).
|
||||
|
||||
```php
|
||||
$url = 'https://www.youtube.com/watch?v=XXX';
|
||||
$site->getEmbedData($url);
|
||||
```
|
||||
|
||||
<br/>
|
||||
|
||||
## 4. License
|
||||
|
||||
MIT
|
||||
|
||||
<br/>
|
||||
|
||||
## 5. Credits
|
||||
|
||||
Built on top of [oscarotero/Embed](https://github.com/oscarotero/Embed).
|
||||
|
||||
With the help of [@tristantbg](https://github.com/tristantbg). 👨💻
|
||||
|
||||
Kirby 2 field by [@distantnative](https://github.com/distantnative/embed), from which I've copy-pasted some bits of this readme. 👀
|
||||
1
site/plugins/embed/assets/svg/embed-icon-failed.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg id="Calque_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style>.cls-1{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;}.cls-2{fill:#f6cbcc;}</style></defs><rect class="cls-2" width="24" height="24"/><g><line class="cls-1" x1="16" y1="8.3" x2="8.47" y2="15.84"/><line class="cls-1" x1="8.47" y1="8.3" x2="16" y2="15.84"/></g></svg>
|
||||
|
After Width: | Height: | Size: 409 B |
1
site/plugins/embed/assets/svg/embed-icon-flickr.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg id="Calque_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style>.cls-1{fill:#005fdf;}.cls-2{fill:#ececec;}.cls-3{fill:#ff0083;}</style></defs><rect class="cls-2" width="24" height="24"/><circle class="cls-1" cx="7.56" cy="12" r="3.56"/><circle class="cls-3" cx="16.44" cy="12" r="3.56"/></svg>
|
||||
|
After Width: | Height: | Size: 354 B |
1
site/plugins/embed/assets/svg/embed-icon-instagram.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg id="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24"><defs><style>.cls-1{fill:#fff;}.cls-2{fill:url(#Dégradé_sans_nom_3);}</style><radialGradient id="Dégradé_sans_nom_3" cx="-265.25" cy="986.76" fx="-265.25" fy="986.76" r="12" gradientTransform="translate(-1813.25 -500.1) rotate(-90) scale(1.98 1.84)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#fd5"/><stop offset=".1" stop-color="#fd5"/><stop offset=".5" stop-color="#ff543e"/><stop offset="1" stop-color="#c837ab"/></radialGradient></defs><path class="cls-2" d="M0,0V24H11.98c-3.03,0,6.02,0,6.02,0h6V0h-5c-1,0-.22,0-3.09,0h-3.9C6.99,0,5,0,5,0"/><path class="cls-1" d="M12.3,4.3c-2.09,0-2.35,0-3.17,.05-.64,.01-1.27,.13-1.87,.36-1.03,.4-1.85,1.22-2.25,2.25-.22,.6-.35,1.23-.36,1.87-.04,.82-.05,1.08-.05,3.18s0,2.35,.05,3.17c.01,.64,.13,1.27,.36,1.87,.4,1.03,1.22,1.85,2.25,2.25,.6,.22,1.23,.34,1.87,.36,.82,.04,1.08,.05,3.17,.05s2.35,0,3.17-.05c.64-.01,1.27-.13,1.87-.36,1.03-.4,1.85-1.22,2.25-2.25,.22-.6,.34-1.23,.36-1.87,.04-.82,.05-1.08,.05-3.17s0-2.35-.05-3.18c-.01-.64-.14-1.27-.36-1.87-.4-1.03-1.22-1.85-2.25-2.25-.6-.22-1.23-.35-1.87-.36-.82-.04-1.08-.05-3.17-.05h0Zm-.69,1.39h.69c2.06,0,2.3,0,3.11,.04,.49,0,.97,.1,1.43,.27,.67,.26,1.2,.79,1.46,1.46,.17,.46,.26,.94,.27,1.43,.04,.81,.05,1.06,.05,3.11s0,2.3-.05,3.11c0,.49-.1,.97-.27,1.43-.26,.67-.79,1.2-1.46,1.46-.46,.17-.94,.26-1.43,.27-.81,.04-1.06,.04-3.11,.04s-2.3,0-3.11-.04c-.49,0-.97-.1-1.43-.27-.67-.26-1.2-.79-1.46-1.46-.17-.46-.26-.94-.27-1.43-.04-.81-.04-1.06-.04-3.11s0-2.3,.04-3.11c0-.49,.1-.97,.27-1.43,.26-.67,.79-1.2,1.46-1.46,.46-.17,.94-.26,1.43-.27,.71-.03,.99-.04,2.42-.04h0Zm4.8,1.28c-.51,0-.92,.41-.92,.92s.41,.92,.92,.92,.92-.41,.92-.92h0c0-.51-.41-.92-.92-.92h0Zm-4.11,1.08c-2.18,0-3.96,1.77-3.96,3.95,0,2.18,1.77,3.96,3.95,3.96,2.18,0,3.96-1.77,3.96-3.95h0c0-2.19-1.77-3.96-3.95-3.96Zm0,1.39c1.42,0,2.57,1.15,2.57,2.57,0,1.42-1.15,2.57-2.57,2.57s-2.57-1.15-2.57-2.57h0c0-1.42,1.15-2.57,2.57-2.57h0Z"/></svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
1
site/plugins/embed/assets/svg/embed-icon-soundcloud.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg id="Calque_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style>.cls-1{fill:#f26e20;}.cls-2{fill:#fff;}</style></defs><rect class="cls-1" x="0" width="24" height="24"/><g><path class="cls-2" d="M4.44,11.53s-.03-.07-.07-.07-.06,.03-.07,.07l-.16,1.47,.16,1.44s.03,.07,.07,.07,.06-.03,.07-.07l.18-1.44-.18-1.47Z"/><path class="cls-2" d="M6.98,10.17c-.07,0-.12,.05-.12,.12l-.13,2.71,.13,1.75c0,.07,.06,.12,.12,.12s.12-.05,.12-.12h0l.15-1.75-.15-2.71c0-.07-.06-.12-.12-.12Z"/><path class="cls-2" d="M5.67,11.11c-.05,0-.09,.04-.1,.09l-.14,1.8,.14,1.74c0,.05,.05,.09,.1,.09s.09-.04,.1-.09l.16-1.74-.16-1.8c0-.05-.05-.09-.1-.09Z"/><path class="cls-2" d="M8.32,14.88c.08,0,.15-.07,.15-.15l.13-1.72-.13-3.61c0-.08-.07-.15-.15-.15s-.15,.07-.15,.15l-.11,3.61,.11,1.72c0,.08,.07,.15,.15,.15Z"/><path class="cls-2" d="M11.06,14.89c.11,0,.21-.09,.21-.21h0l.09-1.67-.09-4.17c0-.11-.1-.21-.21-.21s-.21,.09-.21,.21l-.08,4.17,.08,1.68c0,.11,.1,.21,.21,.21Z"/><path class="cls-2" d="M9.68,14.88c.1,0,.18-.08,.18-.18h0l.11-1.7-.11-3.64c0-.1-.08-.18-.18-.18s-.18,.08-.18,.18l-.1,3.64,.1,1.7c0,.1,.08,.18,.18,.18Z"/><path class="cls-2" d="M17.98,10.85c-.28,0-.54,.06-.78,.16-.16-1.82-1.69-3.25-3.55-3.25-.46,0-.9,.09-1.29,.24-.15,.06-.19,.12-.19,.24v6.41c0,.12,.1,.23,.22,.24,0,0,5.56,0,5.6,0,1.12,0,2.02-.9,2.02-2.02s-.9-2.02-2.02-2.02Z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
1
site/plugins/embed/assets/svg/embed-icon-spotify.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg id="Calque_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style>.cls-1{fill:#1ed75f;}.cls-2{fill:#191515;}</style></defs><rect class="cls-1" x="0" width="24" height="24"/><path class="cls-2" d="M16.36,16.3c-.19,.29-.53,.39-.83,.19-2.28-1.41-5.15-1.7-8.55-.92-.34,.1-.63-.15-.73-.44-.1-.34,.15-.63,.44-.73,3.69-.83,6.9-.49,9.42,1.07,.34,.15,.39,.53,.24,.83Zm1.17-2.67c-.24,.34-.68,.49-1.02,.24-2.62-1.6-6.61-2.09-9.67-1.12-.39,.1-.83-.1-.92-.49-.1-.39,.1-.83,.49-.92,3.55-1.07,7.92-.53,10.93,1.31,.29,.15,.44,.63,.19,.97Zm.1-2.72c-3.11-1.85-8.31-2.04-11.27-1.12-.49,.15-.97-.15-1.12-.58-.15-.49,.15-.97,.58-1.12,3.45-1.02,9.13-.83,12.73,1.31,.44,.24,.58,.83,.34,1.26-.24,.34-.83,.49-1.26,.24Z"/></svg>
|
||||
|
After Width: | Height: | Size: 761 B |
1
site/plugins/embed/assets/svg/embed-icon-synced.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg id="Calque_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style>.cls-1{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;}.cls-2{fill:#dceeb5;}</style></defs><rect class="cls-2" width="24" height="24"/><g><polyline class="cls-1" points="10 7.82 6 11.82 10 15.82"/><polyline class="cls-1" points="14 15.82 18 11.82 14 7.82"/></g></svg>
|
||||
|
After Width: | Height: | Size: 410 B |
1
site/plugins/embed/assets/svg/embed-icon-twitter.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg id="Calque_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style>.cls-1{fill:#fff;}.cls-2{fill:#0f1419;}</style></defs><rect class="cls-2" x="0" width="24" height="24"/><g><polygon class="cls-1" points="11.61 13.88 7.88 18.13 5.82 18.13 10.64 12.62 11.61 13.88"/><polygon class="cls-1" points="12.73 9.88 16.14 5.98 18.21 5.98 13.69 11.14 12.73 9.88"/><path class="cls-1" d="M19,18.13h-4.15L5.55,5.98h4.25l9.19,12.15Zm-3.58-1.23h1.14L9.19,7.15h-1.23l7.46,9.75h0Z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 535 B |
1
site/plugins/embed/assets/svg/embed-icon-vimeo.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg id="Calque_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style>.cls-1{fill:#fff;}.cls-2{fill:#25a1dd;}</style></defs><rect class="cls-2" width="24" height="24"/><path class="cls-1" d="M17.99,8.84c-.08,1.32-.99,3.05-2.72,5.28-1.82,2.31-3.3,3.47-4.54,3.47-.74,0-1.4-.74-1.98-2.15-.66-1.98-1.16-6.03-2.31-6.03-.08,0-.41,.25-.99,.66l-.66-.83c.66-.58,2.89-2.81,3.88-2.89,.99-.08,1.65,.58,1.9,2.06,.25,1.65,.66,5.04,1.49,5.04,.74,0,2.06-2.81,2.15-3.3,.08-.74-.25-1.57-1.9-.91,.66-2.15,1.9-3.14,3.72-3.14,1.4,.08,2.06,.99,1.98,2.72Z"/></svg>
|
||||
|
After Width: | Height: | Size: 596 B |
1
site/plugins/embed/assets/svg/embed-icon-youtube.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg id="Calque_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style>.cls-1{fill:#fff;}.cls-2{fill:#dc2217;}</style></defs><rect class="cls-2" x="0" width="24" height="24"/><path class="cls-1" d="M9.09,16.32c-.47,.24-.86,0-.86-.52v-7.71c0-.53,.38-.77,.86-.52l7.56,3.95c.47,.25,.47,.65,0,.89l-7.56,3.92Z"/></svg>
|
||||
|
After Width: | Height: | Size: 367 B |
27
site/plugins/embed/composer.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "sylvainjule/embed",
|
||||
"description": "Embed field for Kirby 3",
|
||||
"type": "kirby-plugin",
|
||||
"license": "MIT",
|
||||
"version": "1.1.2",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Sylvain Julé",
|
||||
"email": "contact@sylvain-jule.fr"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"getkirby/composer-installer": "^1.1",
|
||||
"embed/embed": "4.4.8",
|
||||
"guzzlehttp/psr7": "^2.6"
|
||||
},
|
||||
"extra": {
|
||||
"installer-name": "embed"
|
||||
},
|
||||
"minimum-stability": "beta",
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
"getkirby/composer-installer": true
|
||||
}
|
||||
}
|
||||
}
|
||||
1
site/plugins/embed/index.css
Normal file
@@ -0,0 +1 @@
|
||||
@charset "UTF-8";.k-embed-field .k-input-icon{width:auto}.k-embed-field .k-input-icon .k-embed-infos{display:flex;align-items:center;line-height:1}.k-embed-field .k-input-icon .k-embed-infos .k-embed-status{margin-right:3px}.k-embed-field .k-input-icon .k-embed-infos .k-embed-status-loading{display:inline-block}.k-embed-field .k-input-icon .k-embed-infos .k-embed-status-loading .loader{display:inline-block;overflow:hidden;height:1.3em;margin-top:-.3em;line-height:1.5em;font-size:1rem;vertical-align:text-bottom}.k-embed-field .k-input-icon .k-embed-infos .k-embed-status-loading .loader:after{content:"\280b\a\2819\a\2839\a\2838\a\283c\a\2834\a\2826\a\2827\a\2807\a\280f";display:inline-table;white-space:pre;text-align:left;animation:spin10 .8s steps(10) infinite}@keyframes spin10{to{transform:translateY(-15em)}}.k-embed-field .k-input-icon .k-embed-infos .k-embed-status-synced,.k-embed-field .k-input-icon .k-embed-infos .k-embed-status-failed{font-size:.8rem;padding:2px 5px 2px 6px;display:inline-block;border-radius:3px}.k-embed-field .k-input-icon .k-embed-infos .k-embed-status-synced{background:var(--color-green-300);display:flex;align-items:center}.k-embed-field .k-input-icon .k-embed-infos .k-embed-status-synced .checkmark{position:relative;width:20px;height:20px}.k-embed-field .k-input-icon .k-embed-infos .k-embed-status-synced .checkmark:before{content:"";position:absolute;top:5px;left:7px;width:9px;height:6px;transform:rotate(-45deg);background:none;border:solid black;border-width:0 0 1px 1px}.k-embed-field .k-input-icon .k-embed-infos .k-embed-status-failed{background:var(--color-red-300);display:flex;align-items:center}.k-embed-field .k-input-icon .k-embed-infos .k-embed-status-failed .cross{position:relative;width:20px;height:20px}.k-embed-field .k-input-icon .k-embed-infos .k-embed-status-failed .cross:before,.k-embed-field .k-input-icon .k-embed-infos .k-embed-status-failed .cross:after{content:"";position:absolute;left:11px;top:5px;height:10px;width:1px;background-color:#000}.k-embed-field .k-input-icon .k-embed-infos .k-embed-status-failed .cross:before{transform:rotate(45deg)}.k-embed-field .k-input-icon .k-embed-infos .k-embed-status-failed .cross:after{transform:rotate(-45deg)}.k-embed-field .k-input-icon-button{width:2.5em}.preview{position:relative;margin-bottom:.5rem}.preview-content{padding:1rem;position:relative;z-index:1;display:flex;justify-content:center;align-items:center}.preview-content iframe{max-width:100%!important}.preview-content img{width:auto!important;height:30vh!important}.preview-background{position:absolute;top:0;left:0;z-index:0;width:100%;height:100%;background:#efefef url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXR0ZXJuIGlkPSJhIiB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHBhdHRlcm5Vbml0cz0idXNlclNwYWNlT25Vc2UiPjxwYXRoIGZpbGw9InJnYmEoMCwgMCwgMCwgMC4yKSIgZD0iTTAgMGgxMHYxMEgwem0xMCAxMGgxMHYxMEgxMHoiLz48L3BhdHRlcm4+PHJlY3QgZmlsbD0idXJsKCNhKSIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIvPjwvc3ZnPg==);opacity:.45}.preview[data-provider=youtube] .preview-content,.preview[data-provider=vimeo] .preview-content{padding:0}.preview[data-provider=youtube] .preview-content iframe,.preview[data-provider=vimeo] .preview-content iframe{width:100%;aspect-ratio:16/9;height:auto}.k-embed-field-preview{padding:.375rem var(--table-cell-padding)}.k-embed-field-preview-inner{overflow:hidden}.k-embed-field-preview .k-embed-icon{--fit: cover;--back: var(--pattern)}
|
||||
1
site/plugins/embed/index.js
Normal file
14
site/plugins/embed/index.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
@include_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
Kirby::plugin('sylvainjule/embed', [
|
||||
'fields' => require_once __DIR__ . '/lib/fields.php',
|
||||
'fieldMethods' => require_once __DIR__ . '/lib/fieldMethods.php',
|
||||
'siteMethods' => require_once __DIR__ . '/lib/siteMethods.php',
|
||||
'api' => require_once __DIR__ . '/lib/api.php',
|
||||
'translations' => array(
|
||||
'en' => require_once __DIR__ . '/lib/languages/en.php',
|
||||
'fr' => require_once __DIR__ . '/lib/languages/fr.php',
|
||||
),
|
||||
]);
|
||||
14
site/plugins/embed/lib/api.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
'routes' => function ($kirby) {
|
||||
return array(
|
||||
array(
|
||||
'pattern' => 'kirby-embed/get-data',
|
||||
'action' => function () {
|
||||
return kirby()->site()->getEmbedData(get('url'));
|
||||
}
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
14
site/plugins/embed/lib/fieldMethods.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
use Kirby\Cms\Content;
|
||||
|
||||
return array(
|
||||
'toEmbed' => function($field) {
|
||||
// allows if($embed = $page->myfield()->toEmbed()) { echo $embed->code() }
|
||||
if($field->isEmpty() || !count(Yaml::decode($field->value)) || empty($field->yaml()['media'])) {
|
||||
return null;
|
||||
}
|
||||
$content = new Content($field->yaml()['media'], $field->parent());
|
||||
return $content;
|
||||
},
|
||||
);
|
||||
22
site/plugins/embed/lib/fields.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
'embed' => array(
|
||||
'extends' => 'url',
|
||||
'props' => array(
|
||||
'provider' > function($provider = null) {
|
||||
return $provider;
|
||||
},
|
||||
'icons' > function($icons = false) {
|
||||
return $icons;
|
||||
},
|
||||
),
|
||||
'computed' => array(
|
||||
'value' => function() {
|
||||
$yaml = Yaml::decode($this->value);
|
||||
return count($yaml) ? $yaml : $this->value;
|
||||
},
|
||||
),
|
||||
'validations' => null
|
||||
)
|
||||
);
|
||||
6
site/plugins/embed/lib/languages/en.php
Normal file
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
'embed.synced' => 'Synced',
|
||||
'embed.failed' => 'Sync failed',
|
||||
);
|
||||
6
site/plugins/embed/lib/languages/fr.php
Normal file
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
'embed.synced' => 'Synchronisé',
|
||||
'embed.failed' => 'Échec de synchronisation',
|
||||
);
|
||||
99
site/plugins/embed/lib/siteMethods.php
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
'getEmbedData' => function ($url = '') {
|
||||
$response = [];
|
||||
|
||||
if (!V::url($url)) {
|
||||
$response['status'] = 'error';
|
||||
$response['error'] = 'The $url variable is not an url';
|
||||
}
|
||||
else {
|
||||
try {
|
||||
$embed = new Embed\Embed();
|
||||
$embed = $embed->get($url);
|
||||
|
||||
$response['status'] = 'success';
|
||||
$response['data'] = array(
|
||||
'title' => $embed->title,
|
||||
'description' => $embed->description,
|
||||
'url' => $embed->url,
|
||||
'tags' => $embed->keywords,
|
||||
'image' => $embed->image,
|
||||
'feeds' => $embed->feeds,
|
||||
'code' => $embed->code ? $embed->code->html : null,
|
||||
'width' => $embed->code ? $embed->code->width : null,
|
||||
'height' => $embed->code ? $embed->code->height : null,
|
||||
'aspectRatio' => $embed->code ? $embed->code->ratio : null,
|
||||
'authorName' => $embed->authorName,
|
||||
'authorUrl' => $embed->authorUrl,
|
||||
'providerIcon' => $embed->icon,
|
||||
'providerName' => $embed->providerName,
|
||||
'providerUrl' => $embed->providerUrl,
|
||||
'publishedTime' => $embed->publishedTime,
|
||||
'license' => $embed->license,
|
||||
);
|
||||
|
||||
if ($response['data']['providerName'] === 'Instagram') {
|
||||
$response['data']['code'] = '
|
||||
<blockquote class="instagram-media" data-instgrm-permalink="' . $response['data']['url'] . '?utm_source=ig_embed&utm_campaign=loading" data-instgrm-version="14" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);">
|
||||
<div style="padding:16px;">
|
||||
<a href="' . $response['data']['url'] . '?utm_source=ig_embed&utm_campaign=loading" style=" background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;" target="_blank">
|
||||
<div style=" display: flex; flex-direction: row; align-items: center;">
|
||||
<div style="background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;"></div>
|
||||
<div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center;">
|
||||
<div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;"></div>
|
||||
<div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="padding: 19% 0;"></div>
|
||||
<div style="display:block; height:50px; margin:0 auto 12px; width:50px;">
|
||||
<svg width="50px" height="50px" viewBox="0 0 60 60" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink">
|
||||
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g transform="translate(-511.000000, -20.000000)" fill="#000000">
|
||||
<g>
|
||||
<path d="M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
<div style="padding-top: 8px;">
|
||||
<div style=" color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;"></div>
|
||||
</div>
|
||||
<div style="padding: 12.5% 0;"></div>
|
||||
<div style="display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;">
|
||||
<div>
|
||||
<div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);"></div>
|
||||
<div style="background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;"></div>
|
||||
<div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);"></div>
|
||||
</div>
|
||||
<div style="margin-left: 8px;">
|
||||
<div style=" background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;"></div>
|
||||
<div style=" width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)"></div>
|
||||
</div>
|
||||
<div style="margin-left: auto;">
|
||||
<div style=" width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);"></div>
|
||||
<div style=" background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);"></div>
|
||||
<div style=" width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center; margin-bottom: 24px;">
|
||||
<div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 224px;"></div>
|
||||
<div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 144px;"></div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</blockquote>
|
||||
<script async src="https://www.instagram.com/embed.js"></script>';
|
||||
}
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$response['status'] = 'error';
|
||||
$response['error'] = $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
);
|
||||
30
site/plugins/embed/package.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "kirby-embed",
|
||||
"version": "0.0.1",
|
||||
"description": "Embed field for Kirby 3",
|
||||
"main": "index.js",
|
||||
"author": "Sylvain Julé",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"dev": "kirbyup src/index.js --watch",
|
||||
"build": "kirbyup src/index.js",
|
||||
"lint": "eslint \"src/**/*.{js,vue}\"",
|
||||
"lint:fix": "npm run lint -- --fix",
|
||||
"format": "prettier --write \"src/**/*.{css,js,vue}\""
|
||||
},
|
||||
"posthtml": {
|
||||
"recognizeSelfClosing": true
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not ie <= 11"
|
||||
],
|
||||
"devDependencies": {
|
||||
"eslint": "^8.2.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-vue": "^8.0.3",
|
||||
"kirbyup": "^0.21.0",
|
||||
"prettier": "^2.4.1"
|
||||
}
|
||||
}
|
||||
38
site/plugins/embed/src/assets/css/_variables.scss
Normal file
@@ -0,0 +1,38 @@
|
||||
/* Colors
|
||||
---------------------------------*/
|
||||
|
||||
$color-white: #fff;
|
||||
$color-light: #efefef;
|
||||
$color-light-grey: #999;
|
||||
$color-dark: #16171a;
|
||||
$color-dark-grey: #777;
|
||||
$color-background: $color-light;
|
||||
$color-border: #ccc;
|
||||
$color-focus: #4271ae;
|
||||
$color-focus-border: $color-focus;
|
||||
|
||||
|
||||
/* Pattern
|
||||
---------------------------------*/
|
||||
|
||||
$pattern: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXR0ZXJuIGlkPSJhIiB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHBhdHRlcm5Vbml0cz0idXNlclNwYWNlT25Vc2UiPjxwYXRoIGZpbGw9InJnYmEoMCwgMCwgMCwgMC4yKSIgZD0iTTAgMGgxMHYxMEgwem0xMCAxMGgxMHYxMEgxMHoiLz48L3BhdHRlcm4+PHJlY3QgZmlsbD0idXJsKCNhKSIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIvPjwvc3ZnPg==";
|
||||
|
||||
|
||||
/* Breakpoint
|
||||
---------------------------------*/
|
||||
|
||||
$breakpoint-medium: 65em;
|
||||
|
||||
|
||||
/* Input size
|
||||
---------------------------------*/
|
||||
|
||||
$field-input-padding: .5rem;
|
||||
$field-input-height: 2.25rem;
|
||||
$field-input-line-height: 1.25rem;
|
||||
|
||||
|
||||
/* Font size
|
||||
---------------------------------*/
|
||||
|
||||
$font-size-small: 0.875rem;
|
||||
143
site/plugins/embed/src/assets/css/styles.scss
Normal file
@@ -0,0 +1,143 @@
|
||||
@import '_variables.scss';
|
||||
|
||||
.k-embed-field {
|
||||
.k-input-icon {
|
||||
width: auto;
|
||||
.k-embed-infos {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 1;
|
||||
.k-embed-status {
|
||||
margin-right: 3px;
|
||||
&-loading {
|
||||
display: inline-block;
|
||||
.loader {
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
height: 1.3em;
|
||||
margin-top: -0.3em;
|
||||
line-height: 1.5em;
|
||||
font-size: 1rem;
|
||||
vertical-align: text-bottom;
|
||||
&::after {
|
||||
content: "⠋\A⠙\A⠹\A⠸\A⠼\A⠴\A⠦\A⠧\A⠇\A⠏";
|
||||
display: inline-table;
|
||||
white-space: pre;
|
||||
text-align: left;
|
||||
animation: spin10 0.8s steps(10) infinite;
|
||||
}
|
||||
}
|
||||
@keyframes spin10 { to { transform: translateY(-15.0em); } }
|
||||
}
|
||||
&-synced, &-failed {
|
||||
font-size: 0.8rem;
|
||||
padding: 2px 5px 2px 6px;
|
||||
display: inline-block;
|
||||
border-radius: 3px;
|
||||
}
|
||||
&-synced {
|
||||
background: var(--color-green-300);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.checkmark {
|
||||
position: relative;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
&:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
left: 7px;
|
||||
width: 9px;
|
||||
height: 6px;
|
||||
transform: rotate(-45deg);
|
||||
background: none;
|
||||
border: solid black;
|
||||
border-width: 0 0 1px 1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
&-failed {
|
||||
background: var(--color-red-300);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.cross {
|
||||
position: relative;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
&:before, &:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 11px;
|
||||
top: 5px;
|
||||
height: 10px;
|
||||
width: 1px;
|
||||
background-color: black;
|
||||
}
|
||||
&:before {
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
&:after {
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&-button {
|
||||
width: 2.5em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.preview {
|
||||
position: relative;
|
||||
margin-bottom: 0.5rem;
|
||||
&-content {
|
||||
padding: 1rem;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
iframe {
|
||||
max-width: 100% !important;
|
||||
}
|
||||
img {
|
||||
width: auto !important;
|
||||
height: 30vh !important;
|
||||
}
|
||||
}
|
||||
&-background {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: $color-light url($pattern);
|
||||
opacity: 0.45;
|
||||
}
|
||||
&[data-provider=youtube],
|
||||
&[data-provider=vimeo] {
|
||||
.preview-content {
|
||||
padding: 0;
|
||||
iframe {
|
||||
width: 100%;
|
||||
aspect-ratio: 16 / 9;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.k-embed-field-preview {
|
||||
padding: 0.375rem var(--table-cell-padding);
|
||||
&-inner {
|
||||
overflow: hidden;
|
||||
}
|
||||
.k-embed-icon {
|
||||
--fit: cover;
|
||||
--back: var(--pattern);
|
||||
}
|
||||
}
|
||||
99
site/plugins/embed/src/components/embedField.vue
Normal file
@@ -0,0 +1,99 @@
|
||||
<template>
|
||||
<k-field :input="_uid" v-bind="$props" class="k-embed-field k-url-field k-field">
|
||||
|
||||
<div class="preview" v-if="hasMedia" :data-provider="providerName">
|
||||
<div class="preview-content" v-html="media.code"></div>
|
||||
<div class="preview-background"></div>
|
||||
</div>
|
||||
|
||||
<k-input ref="input" :id="_uid" v-bind="$props" :value="inputValue" :media="media" theme="field" v-on="$listeners" @setMedia="setMedia" @startLoading="startLoading">
|
||||
<div class="k-embed-infos" slot="icon">
|
||||
<div class="k-embed-status">
|
||||
<span v-if="loading" class="k-embed-status-loading"><span class="loader"></span></span>
|
||||
<span v-else-if="hasMedia" class="k-embed-status-synced">{{ $t('embed.synced') }} <span class="checkmark"></span></span>
|
||||
<span v-else-if="syncFailed" class="k-embed-status-failed">{{ $t('embed.failed') }} <span class="cross"></span></span>
|
||||
</div>
|
||||
<k-button v-if="link"
|
||||
:icon="icon"
|
||||
:link="inputValue"
|
||||
:tooltip="$t('open')"
|
||||
class="k-input-icon-button"
|
||||
tabindex="-1"
|
||||
target="_blank"
|
||||
rel="noopener" />
|
||||
</div>
|
||||
|
||||
</k-input>
|
||||
|
||||
</k-field>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { isUrl, matchProvider } from '../helpers/validators.js'
|
||||
|
||||
export default {
|
||||
extends: 'k-url-field',
|
||||
data() {
|
||||
return {
|
||||
media: Object,
|
||||
loading: false,
|
||||
}
|
||||
},
|
||||
props: {
|
||||
provider: String,
|
||||
},
|
||||
created() {
|
||||
if(this.value && this.value.media && this.hasLength(this.value.media)) {
|
||||
this.media = this.value.media
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
inputValue() {
|
||||
if(this.value && this.value.media && this.hasLength(this.value.media)) {
|
||||
this.media = this.value.media
|
||||
}
|
||||
else {
|
||||
this.media = {}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
hasMedia() {
|
||||
return this.hasLength(this.media) && this.media.code
|
||||
},
|
||||
providerName() {
|
||||
return this.hasMedia && this.media.providerName ? this.media.providerName.toLowerCase() : null
|
||||
},
|
||||
syncFailed() {
|
||||
return this.inputValue != '' && this.isEmbeddableUrl(this.inputValue) && !this.hasMedia
|
||||
},
|
||||
inputValue() {
|
||||
return this.value && this.value.input ? this.value.input : ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setMedia(media) {
|
||||
this.media = media
|
||||
this.stopLoading()
|
||||
},
|
||||
hasLength(obj) {
|
||||
return Object.keys(obj).length
|
||||
},
|
||||
startLoading() {
|
||||
this.loading = true
|
||||
},
|
||||
stopLoading() {
|
||||
this.loading = false
|
||||
},
|
||||
isEmbeddableUrl(value) {
|
||||
if(!isUrl(value)) return false
|
||||
if(this.provider && !matchProvider(value, this.provider)) return false
|
||||
return true
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import '../assets/css/styles.scss'
|
||||
</style>
|
||||
88
site/plugins/embed/src/components/embedInput.vue
Normal file
@@ -0,0 +1,88 @@
|
||||
<script>
|
||||
import { isUrl, matchProvider } from '../helpers/validators.js'
|
||||
|
||||
export default {
|
||||
extends: 'k-url-input',
|
||||
props: {
|
||||
provider: String,
|
||||
media: Object,
|
||||
},
|
||||
mounted() {
|
||||
this.loadEmbedScripts()
|
||||
},
|
||||
methods: {
|
||||
onInput(value) {
|
||||
if(value == '' || !this.isEmbeddableUrl(value)) {
|
||||
this.media = {}
|
||||
this.emitInput(value)
|
||||
return false;
|
||||
}
|
||||
if(value.includes('https://www.instagram.com')) {
|
||||
value = value.split('?')[0].replace(/\/$/, "");
|
||||
}
|
||||
|
||||
this.$emit('startLoading')
|
||||
this.$api
|
||||
.get('kirby-embed/get-data', { url: value })
|
||||
.then(response => {
|
||||
if(response['status'] == 'success' && response['data']) {
|
||||
if(response['data']['providerName'] == 'Vimeo') {
|
||||
let iframe = response['data']['code']
|
||||
iframe = this.htmlToElement(iframe)
|
||||
iframe.setAttribute('referrerpolicy', 'strict-origin-when-cross-origin')
|
||||
|
||||
response['data']['code'] = iframe.outerHTML
|
||||
}
|
||||
this.media = response['data']
|
||||
}
|
||||
else {
|
||||
this.media = {}
|
||||
}
|
||||
|
||||
this.emitInput(value)
|
||||
})
|
||||
.catch(error => {
|
||||
this.media = {}
|
||||
this.emitInput(value)
|
||||
})
|
||||
},
|
||||
emitInput(value) {
|
||||
this.$emit("input", { input: value, media: this.media });
|
||||
this.$emit("setMedia", this.media)
|
||||
|
||||
this.loadEmbedScripts()
|
||||
},
|
||||
loadEmbedScripts() {
|
||||
if (window.twttr) {
|
||||
window.twttr.widgets.load();
|
||||
}
|
||||
else if (this.media && Object.keys(this.media).length && this.media.providerName.toLowerCase() == 'twitter') {
|
||||
const embed = document.createElement('script');
|
||||
embed.src = 'https://platform.twitter.com/widgets.js';
|
||||
document.body.appendChild(embed);
|
||||
}
|
||||
|
||||
if (window.instgrm) {
|
||||
window.instgrm.Embeds.process();
|
||||
}
|
||||
else if (this.media && Object.keys(this.media).length && this.media.providerName.toLowerCase() == 'instagram') {
|
||||
const embed = document.createElement('script');
|
||||
embed.src = 'https://www.instagram.com/embed.js';
|
||||
document.body.appendChild(embed);
|
||||
}
|
||||
},
|
||||
isEmbeddableUrl(value) {
|
||||
if(!isUrl(value)) return false
|
||||
if(this.provider && !matchProvider(value, this.provider)) return false
|
||||
return true
|
||||
},
|
||||
htmlToElement(html) {
|
||||
let template = document.createElement('template')
|
||||
html = html.trim()
|
||||
|
||||
template.innerHTML = html
|
||||
return template.content.firstChild
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
53
site/plugins/embed/src/components/embedPreview.vue
Normal file
@@ -0,0 +1,53 @@
|
||||
<template>
|
||||
<div class="k-embed-field-preview">
|
||||
<div class="k-embed-field-preview-inner k-bubble" data-has-text="true">
|
||||
<div class="k-embed-icon k-frame">
|
||||
<img :src="iconSrc">
|
||||
</div>
|
||||
<div class="k-embed-url">
|
||||
{{ url }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
value: String,
|
||||
field: Object
|
||||
},
|
||||
computed: {
|
||||
url() {
|
||||
return this.value.input.replace(/^\/\/|^.*?:\/\//, '')
|
||||
},
|
||||
isSynced() {
|
||||
return Object.keys(this.value.media).length && this.value.media.code !== null
|
||||
},
|
||||
iconSrc() {
|
||||
return this.$panel.$urls.site +'/media/plugins/sylvainjule/embed/svg/'+ this.providerIcon;
|
||||
},
|
||||
providerIcon() {
|
||||
if(this.isSynced) {
|
||||
if(this.field.icons) {
|
||||
let provider = this.value.media.providerName
|
||||
let icons = ['Vimeo', 'Flickr', 'Instagram', 'SoundCloud', 'Spotify', 'Twitter', 'YouTube'];
|
||||
|
||||
if(icons.includes(provider)) {
|
||||
return 'embed-icon-'+ provider.toLowerCase() +'.svg'
|
||||
}
|
||||
else {
|
||||
return 'embed-icon-synced.svg';
|
||||
}
|
||||
}
|
||||
else {
|
||||
return 'embed-icon-synced.svg'
|
||||
}
|
||||
}
|
||||
else {
|
||||
return 'embed-icon-failed.svg'
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
21
site/plugins/embed/src/helpers/validators.js
Normal file
@@ -0,0 +1,21 @@
|
||||
export function isUrl(value) {
|
||||
const pattern = /^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$/g
|
||||
const regex = new RegExp(pattern)
|
||||
return !value || value.match(regex)
|
||||
}
|
||||
|
||||
export function matchProvider(value, provider) {
|
||||
const patterns = {
|
||||
'youtube': /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/,
|
||||
'vimeo': /vimeo\.com\/([0-9]+)/,
|
||||
'flickr': /^.*(flickr\.com)\/(.*)/,
|
||||
'soundcloud': /^.*(soundcloud\.com|snd\.sc)\/(.*)/,
|
||||
'twitter': /^.*(twitter\.com)\/(.*)/,
|
||||
'instagram': /^.*(instagram\.com)\/(.*)/
|
||||
};
|
||||
|
||||
const patternKeys = Object.keys(patterns)
|
||||
if (patternKeys.indexOf(provider) == -1) return false
|
||||
|
||||
return value.match(patterns[provider])
|
||||
}
|
||||
13
site/plugins/embed/src/index.js
Normal file
@@ -0,0 +1,13 @@
|
||||
import embedField from './components/embedField.vue'
|
||||
import embedInput from './components/embedInput.vue'
|
||||
import embedPreview from './components/embedPreview.vue'
|
||||
|
||||
panel.plugin('sylvainjule/embed', {
|
||||
fields: {
|
||||
embed: embedField,
|
||||
},
|
||||
components: {
|
||||
'k-embed-input': embedInput,
|
||||
'k-embed-field-preview': embedPreview,
|
||||
}
|
||||
});
|
||||
25
site/plugins/embed/vendor/autoload.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
// autoload.php @generated by Composer
|
||||
|
||||
if (PHP_VERSION_ID < 50600) {
|
||||
if (!headers_sent()) {
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
}
|
||||
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
|
||||
if (!ini_get('display_errors')) {
|
||||
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
||||
fwrite(STDERR, $err);
|
||||
} elseif (!headers_sent()) {
|
||||
echo $err;
|
||||
}
|
||||
}
|
||||
trigger_error(
|
||||
$err,
|
||||
E_USER_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInit15b4b4f6c06d13a66170930d082a8cbf::getLoader();
|
||||
581
site/plugins/embed/vendor/composer/ClassLoader.php
vendored
Normal file
@@ -0,0 +1,581 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
/**
|
||||
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
|
||||
*
|
||||
* $loader = new \Composer\Autoload\ClassLoader();
|
||||
*
|
||||
* // register classes with namespaces
|
||||
* $loader->add('Symfony\Component', __DIR__.'/component');
|
||||
* $loader->add('Symfony', __DIR__.'/framework');
|
||||
*
|
||||
* // activate the autoloader
|
||||
* $loader->register();
|
||||
*
|
||||
* // to enable searching the include path (eg. for PEAR packages)
|
||||
* $loader->setUseIncludePath(true);
|
||||
*
|
||||
* In this example, if you try to use a class in the Symfony\Component
|
||||
* namespace or one of its children (Symfony\Component\Console for instance),
|
||||
* the autoloader will first look for the class under the component/
|
||||
* directory, and it will then fallback to the framework/ directory if not
|
||||
* found before giving up.
|
||||
*
|
||||
* This class is loosely based on the Symfony UniversalClassLoader.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
* @see https://www.php-fig.org/psr/psr-0/
|
||||
* @see https://www.php-fig.org/psr/psr-4/
|
||||
*/
|
||||
class ClassLoader
|
||||
{
|
||||
/** @var \Closure(string):void */
|
||||
private static $includeFile;
|
||||
|
||||
/** @var ?string */
|
||||
private $vendorDir;
|
||||
|
||||
// PSR-4
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array<string, int>>
|
||||
*/
|
||||
private $prefixLengthsPsr4 = array();
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array<int, string>>
|
||||
*/
|
||||
private $prefixDirsPsr4 = array();
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, string>
|
||||
*/
|
||||
private $fallbackDirsPsr4 = array();
|
||||
|
||||
// PSR-0
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array<string, string[]>>
|
||||
*/
|
||||
private $prefixesPsr0 = array();
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, string>
|
||||
*/
|
||||
private $fallbackDirsPsr0 = array();
|
||||
|
||||
/** @var bool */
|
||||
private $useIncludePath = false;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
* @psalm-var array<string, string>
|
||||
*/
|
||||
private $classMap = array();
|
||||
|
||||
/** @var bool */
|
||||
private $classMapAuthoritative = false;
|
||||
|
||||
/**
|
||||
* @var bool[]
|
||||
* @psalm-var array<string, bool>
|
||||
*/
|
||||
private $missingClasses = array();
|
||||
|
||||
/** @var ?string */
|
||||
private $apcuPrefix;
|
||||
|
||||
/**
|
||||
* @var self[]
|
||||
*/
|
||||
private static $registeredLoaders = array();
|
||||
|
||||
/**
|
||||
* @param ?string $vendorDir
|
||||
*/
|
||||
public function __construct($vendorDir = null)
|
||||
{
|
||||
$this->vendorDir = $vendorDir;
|
||||
self::initializeIncludeClosure();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getPrefixes()
|
||||
{
|
||||
if (!empty($this->prefixesPsr0)) {
|
||||
return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return array<string, array<int, string>>
|
||||
*/
|
||||
public function getPrefixesPsr4()
|
||||
{
|
||||
return $this->prefixDirsPsr4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return array<string, string>
|
||||
*/
|
||||
public function getFallbackDirs()
|
||||
{
|
||||
return $this->fallbackDirsPsr0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return array<string, string>
|
||||
*/
|
||||
public function getFallbackDirsPsr4()
|
||||
{
|
||||
return $this->fallbackDirsPsr4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[] Array of classname => path
|
||||
* @psalm-return array<string, string>
|
||||
*/
|
||||
public function getClassMap()
|
||||
{
|
||||
return $this->classMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $classMap Class to filename map
|
||||
* @psalm-param array<string, string> $classMap
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addClassMap(array $classMap)
|
||||
{
|
||||
if ($this->classMap) {
|
||||
$this->classMap = array_merge($this->classMap, $classMap);
|
||||
} else {
|
||||
$this->classMap = $classMap;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix, either
|
||||
* appending or prepending to the ones previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param string[]|string $paths The PSR-0 root directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add($prefix, $paths, $prepend = false)
|
||||
{
|
||||
if (!$prefix) {
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
(array) $paths,
|
||||
$this->fallbackDirsPsr0
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
$this->fallbackDirsPsr0,
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$first = $prefix[0];
|
||||
if (!isset($this->prefixesPsr0[$first][$prefix])) {
|
||||
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
|
||||
|
||||
return;
|
||||
}
|
||||
if ($prepend) {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$this->prefixesPsr0[$first][$prefix]
|
||||
);
|
||||
} else {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
$this->prefixesPsr0[$first][$prefix],
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace, either
|
||||
* appending or prepending to the ones previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param string[]|string $paths The PSR-4 base directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addPsr4($prefix, $paths, $prepend = false)
|
||||
{
|
||||
if (!$prefix) {
|
||||
// Register directories for the root namespace.
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
(array) $paths,
|
||||
$this->fallbackDirsPsr4
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
$this->fallbackDirsPsr4,
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
|
||||
// Register directories for a new namespace.
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
} elseif ($prepend) {
|
||||
// Prepend directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$this->prefixDirsPsr4[$prefix]
|
||||
);
|
||||
} else {
|
||||
// Append directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
$this->prefixDirsPsr4[$prefix],
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix,
|
||||
* replacing any others previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param string[]|string $paths The PSR-0 base directories
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function set($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr0 = (array) $paths;
|
||||
} else {
|
||||
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace,
|
||||
* replacing any others previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param string[]|string $paths The PSR-4 base directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setPsr4($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr4 = (array) $paths;
|
||||
} else {
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns on searching the include path for class files.
|
||||
*
|
||||
* @param bool $useIncludePath
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUseIncludePath($useIncludePath)
|
||||
{
|
||||
$this->useIncludePath = $useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used to check if the autoloader uses the include path to check
|
||||
* for classes.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getUseIncludePath()
|
||||
{
|
||||
return $this->useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns off searching the prefix and fallback directories for classes
|
||||
* that have not been registered with the class map.
|
||||
*
|
||||
* @param bool $classMapAuthoritative
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setClassMapAuthoritative($classMapAuthoritative)
|
||||
{
|
||||
$this->classMapAuthoritative = $classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should class lookup fail if not found in the current class map?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isClassMapAuthoritative()
|
||||
{
|
||||
return $this->classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
|
||||
*
|
||||
* @param string|null $apcuPrefix
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setApcuPrefix($apcuPrefix)
|
||||
{
|
||||
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The APCu prefix in use, or null if APCu caching is not enabled.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getApcuPrefix()
|
||||
{
|
||||
return $this->apcuPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers this instance as an autoloader.
|
||||
*
|
||||
* @param bool $prepend Whether to prepend the autoloader or not
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register($prepend = false)
|
||||
{
|
||||
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
|
||||
|
||||
if (null === $this->vendorDir) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($prepend) {
|
||||
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
|
||||
} else {
|
||||
unset(self::$registeredLoaders[$this->vendorDir]);
|
||||
self::$registeredLoaders[$this->vendorDir] = $this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters this instance as an autoloader.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function unregister()
|
||||
{
|
||||
spl_autoload_unregister(array($this, 'loadClass'));
|
||||
|
||||
if (null !== $this->vendorDir) {
|
||||
unset(self::$registeredLoaders[$this->vendorDir]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the given class or interface.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
* @return true|null True if loaded, null otherwise
|
||||
*/
|
||||
public function loadClass($class)
|
||||
{
|
||||
if ($file = $this->findFile($class)) {
|
||||
(self::$includeFile)($file);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the path to the file where the class is defined.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
*
|
||||
* @return string|false The path if found, false otherwise
|
||||
*/
|
||||
public function findFile($class)
|
||||
{
|
||||
// class map lookup
|
||||
if (isset($this->classMap[$class])) {
|
||||
return $this->classMap[$class];
|
||||
}
|
||||
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
|
||||
return false;
|
||||
}
|
||||
if (null !== $this->apcuPrefix) {
|
||||
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
|
||||
if ($hit) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
$file = $this->findFileWithExtension($class, '.php');
|
||||
|
||||
// Search for Hack files if we are running on HHVM
|
||||
if (false === $file && defined('HHVM_VERSION')) {
|
||||
$file = $this->findFileWithExtension($class, '.hh');
|
||||
}
|
||||
|
||||
if (null !== $this->apcuPrefix) {
|
||||
apcu_add($this->apcuPrefix.$class, $file);
|
||||
}
|
||||
|
||||
if (false === $file) {
|
||||
// Remember that this class does not exist.
|
||||
$this->missingClasses[$class] = true;
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currently registered loaders indexed by their corresponding vendor directories.
|
||||
*
|
||||
* @return self[]
|
||||
*/
|
||||
public static function getRegisteredLoaders()
|
||||
{
|
||||
return self::$registeredLoaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $class
|
||||
* @param string $ext
|
||||
* @return string|false
|
||||
*/
|
||||
private function findFileWithExtension($class, $ext)
|
||||
{
|
||||
// PSR-4 lookup
|
||||
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
|
||||
|
||||
$first = $class[0];
|
||||
if (isset($this->prefixLengthsPsr4[$first])) {
|
||||
$subPath = $class;
|
||||
while (false !== $lastPos = strrpos($subPath, '\\')) {
|
||||
$subPath = substr($subPath, 0, $lastPos);
|
||||
$search = $subPath . '\\';
|
||||
if (isset($this->prefixDirsPsr4[$search])) {
|
||||
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
|
||||
foreach ($this->prefixDirsPsr4[$search] as $dir) {
|
||||
if (file_exists($file = $dir . $pathEnd)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-4 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr4 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 lookup
|
||||
if (false !== $pos = strrpos($class, '\\')) {
|
||||
// namespaced class name
|
||||
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
|
||||
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
|
||||
} else {
|
||||
// PEAR-like class name
|
||||
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
|
||||
}
|
||||
|
||||
if (isset($this->prefixesPsr0[$first])) {
|
||||
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
|
||||
if (0 === strpos($class, $prefix)) {
|
||||
foreach ($dirs as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr0 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 include paths.
|
||||
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static function initializeIncludeClosure(): void
|
||||
{
|
||||
if (self::$includeFile !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope isolated include.
|
||||
*
|
||||
* Prevents access to $this/self from included files.
|
||||
*
|
||||
* @param string $file
|
||||
* @return void
|
||||
*/
|
||||
self::$includeFile = static function($file) {
|
||||
include $file;
|
||||
};
|
||||
}
|
||||
}
|
||||
352
site/plugins/embed/vendor/composer/InstalledVersions.php
vendored
Normal file
@@ -0,0 +1,352 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer;
|
||||
|
||||
use Composer\Autoload\ClassLoader;
|
||||
use Composer\Semver\VersionParser;
|
||||
|
||||
/**
|
||||
* This class is copied in every Composer installed project and available to all
|
||||
*
|
||||
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
|
||||
*
|
||||
* To require its presence, you can require `composer-runtime-api ^2.0`
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class InstalledVersions
|
||||
{
|
||||
/**
|
||||
* @var mixed[]|null
|
||||
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
|
||||
*/
|
||||
private static $installed;
|
||||
|
||||
/**
|
||||
* @var bool|null
|
||||
*/
|
||||
private static $canGetVendors;
|
||||
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||
*/
|
||||
private static $installedByVendor = array();
|
||||
|
||||
/**
|
||||
* Returns a list of all package names which are present, either by being installed, replaced or provided
|
||||
*
|
||||
* @return string[]
|
||||
* @psalm-return list<string>
|
||||
*/
|
||||
public static function getInstalledPackages()
|
||||
{
|
||||
$packages = array();
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
$packages[] = array_keys($installed['versions']);
|
||||
}
|
||||
|
||||
if (1 === \count($packages)) {
|
||||
return $packages[0];
|
||||
}
|
||||
|
||||
return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all package names with a specific type e.g. 'library'
|
||||
*
|
||||
* @param string $type
|
||||
* @return string[]
|
||||
* @psalm-return list<string>
|
||||
*/
|
||||
public static function getInstalledPackagesByType($type)
|
||||
{
|
||||
$packagesByType = array();
|
||||
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
foreach ($installed['versions'] as $name => $package) {
|
||||
if (isset($package['type']) && $package['type'] === $type) {
|
||||
$packagesByType[] = $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $packagesByType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given package is installed
|
||||
*
|
||||
* This also returns true if the package name is provided or replaced by another package
|
||||
*
|
||||
* @param string $packageName
|
||||
* @param bool $includeDevRequirements
|
||||
* @return bool
|
||||
*/
|
||||
public static function isInstalled($packageName, $includeDevRequirements = true)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (isset($installed['versions'][$packageName])) {
|
||||
return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given package satisfies a version constraint
|
||||
*
|
||||
* e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
|
||||
*
|
||||
* Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
|
||||
*
|
||||
* @param VersionParser $parser Install composer/semver to have access to this class and functionality
|
||||
* @param string $packageName
|
||||
* @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
|
||||
* @return bool
|
||||
*/
|
||||
public static function satisfies(VersionParser $parser, $packageName, $constraint)
|
||||
{
|
||||
$constraint = $parser->parseConstraints($constraint);
|
||||
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
|
||||
|
||||
return $provided->matches($constraint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a version constraint representing all the range(s) which are installed for a given package
|
||||
*
|
||||
* It is easier to use this via isInstalled() with the $constraint argument if you need to check
|
||||
* whether a given version of a package is installed, and not just whether it exists
|
||||
*
|
||||
* @param string $packageName
|
||||
* @return string Version constraint usable with composer/semver
|
||||
*/
|
||||
public static function getVersionRanges($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$ranges = array();
|
||||
if (isset($installed['versions'][$packageName]['pretty_version'])) {
|
||||
$ranges[] = $installed['versions'][$packageName]['pretty_version'];
|
||||
}
|
||||
if (array_key_exists('aliases', $installed['versions'][$packageName])) {
|
||||
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
|
||||
}
|
||||
if (array_key_exists('replaced', $installed['versions'][$packageName])) {
|
||||
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
|
||||
}
|
||||
if (array_key_exists('provided', $installed['versions'][$packageName])) {
|
||||
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
|
||||
}
|
||||
|
||||
return implode(' || ', $ranges);
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
||||
*/
|
||||
public static function getVersion($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($installed['versions'][$packageName]['version'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $installed['versions'][$packageName]['version'];
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
||||
*/
|
||||
public static function getPrettyVersion($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($installed['versions'][$packageName]['pretty_version'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $installed['versions'][$packageName]['pretty_version'];
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
|
||||
*/
|
||||
public static function getReference($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($installed['versions'][$packageName]['reference'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $installed['versions'][$packageName]['reference'];
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
|
||||
*/
|
||||
public static function getInstallPath($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
|
||||
*/
|
||||
public static function getRootPackage()
|
||||
{
|
||||
$installed = self::getInstalled();
|
||||
|
||||
return $installed[0]['root'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw installed.php data for custom implementations
|
||||
*
|
||||
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
|
||||
* @return array[]
|
||||
* @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
|
||||
*/
|
||||
public static function getRawData()
|
||||
{
|
||||
@trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
|
||||
|
||||
if (null === self::$installed) {
|
||||
// only require the installed.php file if this file is loaded from its dumped location,
|
||||
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
||||
if (substr(__DIR__, -8, 1) !== 'C') {
|
||||
self::$installed = include __DIR__ . '/installed.php';
|
||||
} else {
|
||||
self::$installed = array();
|
||||
}
|
||||
}
|
||||
|
||||
return self::$installed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw data of all installed.php which are currently loaded for custom implementations
|
||||
*
|
||||
* @return array[]
|
||||
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||
*/
|
||||
public static function getAllRawData()
|
||||
{
|
||||
return self::getInstalled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lets you reload the static array from another file
|
||||
*
|
||||
* This is only useful for complex integrations in which a project needs to use
|
||||
* this class but then also needs to execute another project's autoloader in process,
|
||||
* and wants to ensure both projects have access to their version of installed.php.
|
||||
*
|
||||
* A typical case would be PHPUnit, where it would need to make sure it reads all
|
||||
* the data it needs from this class, then call reload() with
|
||||
* `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
|
||||
* the project in which it runs can then also use this class safely, without
|
||||
* interference between PHPUnit's dependencies and the project's dependencies.
|
||||
*
|
||||
* @param array[] $data A vendor/composer/installed.php data set
|
||||
* @return void
|
||||
*
|
||||
* @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
|
||||
*/
|
||||
public static function reload($data)
|
||||
{
|
||||
self::$installed = $data;
|
||||
self::$installedByVendor = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||
*/
|
||||
private static function getInstalled()
|
||||
{
|
||||
if (null === self::$canGetVendors) {
|
||||
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
|
||||
}
|
||||
|
||||
$installed = array();
|
||||
|
||||
if (self::$canGetVendors) {
|
||||
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
|
||||
if (isset(self::$installedByVendor[$vendorDir])) {
|
||||
$installed[] = self::$installedByVendor[$vendorDir];
|
||||
} elseif (is_file($vendorDir.'/composer/installed.php')) {
|
||||
$installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
|
||||
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
|
||||
self::$installed = $installed[count($installed) - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (null === self::$installed) {
|
||||
// only require the installed.php file if this file is loaded from its dumped location,
|
||||
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
||||
if (substr(__DIR__, -8, 1) !== 'C') {
|
||||
self::$installed = require __DIR__ . '/installed.php';
|
||||
} else {
|
||||
self::$installed = array();
|
||||
}
|
||||
}
|
||||
$installed[] = self::$installed;
|
||||
|
||||
return $installed;
|
||||
}
|
||||
}
|
||||
21
site/plugins/embed/vendor/composer/LICENSE
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
|
||||
Copyright (c) Nils Adermann, Jordi Boggiano
|
||||
|
||||
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:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
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
site/plugins/embed/vendor/composer/autoload_classmap.php
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
// autoload_classmap.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||
);
|
||||
11
site/plugins/embed/vendor/composer/autoload_files.php
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
// autoload_files.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
|
||||
'09fc349b549513bf7f4291502426f919' => $vendorDir . '/embed/embed/src/functions.php',
|
||||
);
|
||||
10
site/plugins/embed/vendor/composer/autoload_namespaces.php
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
// autoload_namespaces.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'ML\\IRI' => array($vendorDir . '/ml/iri'),
|
||||
);
|
||||
17
site/plugins/embed/vendor/composer/autoload_psr4.php
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
// autoload_psr4.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-factory/src', $vendorDir . '/psr/http-message/src'),
|
||||
'Psr\\Http\\Client\\' => array($vendorDir . '/psr/http-client/src'),
|
||||
'ML\\JsonLD\\' => array($vendorDir . '/ml/json-ld'),
|
||||
'Kirby\\' => array($vendorDir . '/getkirby/composer-installer/src'),
|
||||
'HtmlParser\\' => array($vendorDir . '/oscarotero/html-parser/src'),
|
||||
'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'),
|
||||
'Embed\\' => array($vendorDir . '/embed/embed/src'),
|
||||
'Composer\\CaBundle\\' => array($vendorDir . '/composer/ca-bundle/src'),
|
||||
);
|
||||
50
site/plugins/embed/vendor/composer/autoload_real.php
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
// autoload_real.php @generated by Composer
|
||||
|
||||
class ComposerAutoloaderInit15b4b4f6c06d13a66170930d082a8cbf
|
||||
{
|
||||
private static $loader;
|
||||
|
||||
public static function loadClassLoader($class)
|
||||
{
|
||||
if ('Composer\Autoload\ClassLoader' === $class) {
|
||||
require __DIR__ . '/ClassLoader.php';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Composer\Autoload\ClassLoader
|
||||
*/
|
||||
public static function getLoader()
|
||||
{
|
||||
if (null !== self::$loader) {
|
||||
return self::$loader;
|
||||
}
|
||||
|
||||
require __DIR__ . '/platform_check.php';
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInit15b4b4f6c06d13a66170930d082a8cbf', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInit15b4b4f6c06d13a66170930d082a8cbf', 'loadClassLoader'));
|
||||
|
||||
require __DIR__ . '/autoload_static.php';
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInit15b4b4f6c06d13a66170930d082a8cbf::getInitializer($loader));
|
||||
|
||||
$loader->register(true);
|
||||
|
||||
$filesToLoad = \Composer\Autoload\ComposerStaticInit15b4b4f6c06d13a66170930d082a8cbf::$files;
|
||||
$requireFile = static function ($fileIdentifier, $file) {
|
||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||
|
||||
require $file;
|
||||
}
|
||||
};
|
||||
foreach ($filesToLoad as $fileIdentifier => $file) {
|
||||
($requireFile)($fileIdentifier, $file);
|
||||
}
|
||||
|
||||
return $loader;
|
||||
}
|
||||
}
|
||||
106
site/plugins/embed/vendor/composer/autoload_static.php
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
// autoload_static.php @generated by Composer
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
class ComposerStaticInit15b4b4f6c06d13a66170930d082a8cbf
|
||||
{
|
||||
public static $files = array (
|
||||
'7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
|
||||
'09fc349b549513bf7f4291502426f919' => __DIR__ . '/..' . '/embed/embed/src/functions.php',
|
||||
);
|
||||
|
||||
public static $prefixLengthsPsr4 = array (
|
||||
'P' =>
|
||||
array (
|
||||
'Psr\\Http\\Message\\' => 17,
|
||||
'Psr\\Http\\Client\\' => 16,
|
||||
),
|
||||
'M' =>
|
||||
array (
|
||||
'ML\\JsonLD\\' => 10,
|
||||
),
|
||||
'K' =>
|
||||
array (
|
||||
'Kirby\\' => 6,
|
||||
),
|
||||
'H' =>
|
||||
array (
|
||||
'HtmlParser\\' => 11,
|
||||
),
|
||||
'G' =>
|
||||
array (
|
||||
'GuzzleHttp\\Psr7\\' => 16,
|
||||
),
|
||||
'E' =>
|
||||
array (
|
||||
'Embed\\' => 6,
|
||||
),
|
||||
'C' =>
|
||||
array (
|
||||
'Composer\\CaBundle\\' => 18,
|
||||
),
|
||||
);
|
||||
|
||||
public static $prefixDirsPsr4 = array (
|
||||
'Psr\\Http\\Message\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/psr/http-factory/src',
|
||||
1 => __DIR__ . '/..' . '/psr/http-message/src',
|
||||
),
|
||||
'Psr\\Http\\Client\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/psr/http-client/src',
|
||||
),
|
||||
'ML\\JsonLD\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/ml/json-ld',
|
||||
),
|
||||
'Kirby\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/getkirby/composer-installer/src',
|
||||
),
|
||||
'HtmlParser\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/oscarotero/html-parser/src',
|
||||
),
|
||||
'GuzzleHttp\\Psr7\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/guzzlehttp/psr7/src',
|
||||
),
|
||||
'Embed\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/embed/embed/src',
|
||||
),
|
||||
'Composer\\CaBundle\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/composer/ca-bundle/src',
|
||||
),
|
||||
);
|
||||
|
||||
public static $prefixesPsr0 = array (
|
||||
'M' =>
|
||||
array (
|
||||
'ML\\IRI' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/ml/iri',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
public static $classMap = array (
|
||||
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
||||
);
|
||||
|
||||
public static function getInitializer(ClassLoader $loader)
|
||||
{
|
||||
return \Closure::bind(function () use ($loader) {
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInit15b4b4f6c06d13a66170930d082a8cbf::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInit15b4b4f6c06d13a66170930d082a8cbf::$prefixDirsPsr4;
|
||||
$loader->prefixesPsr0 = ComposerStaticInit15b4b4f6c06d13a66170930d082a8cbf::$prefixesPsr0;
|
||||
$loader->classMap = ComposerStaticInit15b4b4f6c06d13a66170930d082a8cbf::$classMap;
|
||||
|
||||
}, null, ClassLoader::class);
|
||||
}
|
||||
}
|
||||
19
site/plugins/embed/vendor/composer/ca-bundle/LICENSE
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (C) 2016 Composer
|
||||
|
||||
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:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
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.
|
||||
85
site/plugins/embed/vendor/composer/ca-bundle/README.md
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
composer/ca-bundle
|
||||
==================
|
||||
|
||||
Small utility library that lets you find a path to the system CA bundle,
|
||||
and includes a fallback to the Mozilla CA bundle.
|
||||
|
||||
Originally written as part of [composer/composer](https://github.com/composer/composer),
|
||||
now extracted and made available as a stand-alone library.
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
Install the latest version with:
|
||||
|
||||
```bash
|
||||
$ composer require composer/ca-bundle
|
||||
```
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
* PHP 5.3.2 is required but using the latest version of PHP is highly recommended.
|
||||
|
||||
|
||||
Basic usage
|
||||
-----------
|
||||
|
||||
### `Composer\CaBundle\CaBundle`
|
||||
|
||||
- `CaBundle::getSystemCaRootBundlePath()`: Returns the system CA bundle path, or a path to the bundled one as fallback
|
||||
- `CaBundle::getBundledCaBundlePath()`: Returns the path to the bundled CA file
|
||||
- `CaBundle::validateCaFile($filename)`: Validates a CA file using openssl_x509_parse only if it is safe to use
|
||||
- `CaBundle::isOpensslParseSafe()`: Test if it is safe to use the PHP function openssl_x509_parse()
|
||||
- `CaBundle::reset()`: Resets the static caches
|
||||
|
||||
|
||||
#### To use with curl
|
||||
|
||||
```php
|
||||
$curl = curl_init("https://example.org/");
|
||||
|
||||
$caPathOrFile = \Composer\CaBundle\CaBundle::getSystemCaRootBundlePath();
|
||||
if (is_dir($caPathOrFile)) {
|
||||
curl_setopt($curl, CURLOPT_CAPATH, $caPathOrFile);
|
||||
} else {
|
||||
curl_setopt($curl, CURLOPT_CAINFO, $caPathOrFile);
|
||||
}
|
||||
|
||||
$result = curl_exec($curl);
|
||||
```
|
||||
|
||||
#### To use with php streams
|
||||
|
||||
```php
|
||||
$opts = array(
|
||||
'http' => array(
|
||||
'method' => "GET"
|
||||
)
|
||||
);
|
||||
|
||||
$caPathOrFile = \Composer\CaBundle\CaBundle::getSystemCaRootBundlePath();
|
||||
if (is_dir($caPathOrFile)) {
|
||||
$opts['ssl']['capath'] = $caPathOrFile;
|
||||
} else {
|
||||
$opts['ssl']['cafile'] = $caPathOrFile;
|
||||
}
|
||||
|
||||
$context = stream_context_create($opts);
|
||||
$result = file_get_contents('https://example.com', false, $context);
|
||||
```
|
||||
|
||||
#### To use with Guzzle
|
||||
|
||||
```php
|
||||
$client = new \GuzzleHttp\Client([
|
||||
\GuzzleHttp\RequestOptions::VERIFY => \Composer\CaBundle\CaBundle::getSystemCaRootBundlePath()
|
||||
]);
|
||||
```
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
composer/ca-bundle is licensed under the MIT License, see the LICENSE file for details.
|
||||
54
site/plugins/embed/vendor/composer/ca-bundle/composer.json
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"name": "composer/ca-bundle",
|
||||
"description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.",
|
||||
"type": "library",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"cabundle",
|
||||
"cacert",
|
||||
"certificate",
|
||||
"ssl",
|
||||
"tls"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jordi Boggiano",
|
||||
"email": "j.boggiano@seld.be",
|
||||
"homepage": "http://seld.be"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"irc": "irc://irc.freenode.org/composer",
|
||||
"issues": "https://github.com/composer/ca-bundle/issues"
|
||||
},
|
||||
"require": {
|
||||
"ext-openssl": "*",
|
||||
"ext-pcre": "*",
|
||||
"php": "^5.3.2 || ^7.0 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/phpunit-bridge": "^4.2 || ^5",
|
||||
"phpstan/phpstan": "^0.12.55",
|
||||
"psr/log": "^1.0",
|
||||
"symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0 || ^6.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Composer\\CaBundle\\": "src"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Composer\\CaBundle\\": "tests"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.x-dev"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"test": "SYMFONY_PHPUNIT_REMOVE_RETURN_TYPEHINT=1 vendor/bin/simple-phpunit",
|
||||
"phpstan": "vendor/bin/phpstan analyse"
|
||||
}
|
||||
}
|
||||
3451
site/plugins/embed/vendor/composer/ca-bundle/res/cacert.pem
vendored
Normal file
431
site/plugins/embed/vendor/composer/ca-bundle/src/CaBundle.php
vendored
Normal file
@@ -0,0 +1,431 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of composer/ca-bundle.
|
||||
*
|
||||
* (c) Composer <https://github.com/composer>
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\CaBundle;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Process\PhpProcess;
|
||||
|
||||
/**
|
||||
* @author Chris Smith <chris@cs278.org>
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*/
|
||||
class CaBundle
|
||||
{
|
||||
/** @var string|null */
|
||||
private static $caPath;
|
||||
/** @var array<string, bool> */
|
||||
private static $caFileValidity = array();
|
||||
/** @var bool|null */
|
||||
private static $useOpensslParse;
|
||||
|
||||
/**
|
||||
* Returns the system CA bundle path, or a path to the bundled one
|
||||
*
|
||||
* This method was adapted from Sslurp.
|
||||
* https://github.com/EvanDotPro/Sslurp
|
||||
*
|
||||
* (c) Evan Coury <me@evancoury.com>
|
||||
*
|
||||
* For the full copyright and license information, please see below:
|
||||
*
|
||||
* Copyright (c) 2013, Evan Coury
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @param LoggerInterface $logger optional logger for information about which CA files were loaded
|
||||
* @return string path to a CA bundle file or directory
|
||||
*/
|
||||
public static function getSystemCaRootBundlePath(LoggerInterface $logger = null)
|
||||
{
|
||||
if (self::$caPath !== null) {
|
||||
return self::$caPath;
|
||||
}
|
||||
$caBundlePaths = array();
|
||||
|
||||
// If SSL_CERT_FILE env variable points to a valid certificate/bundle, use that.
|
||||
// This mimics how OpenSSL uses the SSL_CERT_FILE env variable.
|
||||
$caBundlePaths[] = self::getEnvVariable('SSL_CERT_FILE');
|
||||
|
||||
// If SSL_CERT_DIR env variable points to a valid certificate/bundle, use that.
|
||||
// This mimics how OpenSSL uses the SSL_CERT_FILE env variable.
|
||||
$caBundlePaths[] = self::getEnvVariable('SSL_CERT_DIR');
|
||||
|
||||
$caBundlePaths[] = ini_get('openssl.cafile');
|
||||
$caBundlePaths[] = ini_get('openssl.capath');
|
||||
|
||||
$otherLocations = array(
|
||||
'/etc/pki/tls/certs/ca-bundle.crt', // Fedora, RHEL, CentOS (ca-certificates package)
|
||||
'/etc/ssl/certs/ca-certificates.crt', // Debian, Ubuntu, Gentoo, Arch Linux (ca-certificates package)
|
||||
'/etc/ssl/ca-bundle.pem', // SUSE, openSUSE (ca-certificates package)
|
||||
'/usr/local/share/certs/ca-root-nss.crt', // FreeBSD (ca_root_nss_package)
|
||||
'/usr/ssl/certs/ca-bundle.crt', // Cygwin
|
||||
'/opt/local/share/curl/curl-ca-bundle.crt', // OS X macports, curl-ca-bundle package
|
||||
'/usr/local/share/curl/curl-ca-bundle.crt', // Default cURL CA bunde path (without --with-ca-bundle option)
|
||||
'/usr/share/ssl/certs/ca-bundle.crt', // Really old RedHat?
|
||||
'/etc/ssl/cert.pem', // OpenBSD
|
||||
'/usr/local/etc/ssl/cert.pem', // FreeBSD 10.x
|
||||
'/usr/local/etc/openssl/cert.pem', // OS X homebrew, openssl package
|
||||
'/usr/local/etc/openssl@1.1/cert.pem', // OS X homebrew, openssl@1.1 package
|
||||
);
|
||||
|
||||
foreach($otherLocations as $location) {
|
||||
$otherLocations[] = dirname($location);
|
||||
}
|
||||
|
||||
$caBundlePaths = array_merge($caBundlePaths, $otherLocations);
|
||||
|
||||
foreach ($caBundlePaths as $caBundle) {
|
||||
if ($caBundle && self::caFileUsable($caBundle, $logger)) {
|
||||
return self::$caPath = $caBundle;
|
||||
}
|
||||
|
||||
if ($caBundle && self::caDirUsable($caBundle, $logger)) {
|
||||
return self::$caPath = $caBundle;
|
||||
}
|
||||
}
|
||||
|
||||
return self::$caPath = static::getBundledCaBundlePath(); // Bundled CA file, last resort
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path to the bundled CA file
|
||||
*
|
||||
* In case you don't want to trust the user or the system, you can use this directly
|
||||
*
|
||||
* @return string path to a CA bundle file
|
||||
*/
|
||||
public static function getBundledCaBundlePath()
|
||||
{
|
||||
$caBundleFile = __DIR__.'/../res/cacert.pem';
|
||||
|
||||
// cURL does not understand 'phar://' paths
|
||||
// see https://github.com/composer/ca-bundle/issues/10
|
||||
if (0 === strpos($caBundleFile, 'phar://')) {
|
||||
$tempCaBundleFile = tempnam(sys_get_temp_dir(), 'openssl-ca-bundle-');
|
||||
if (false === $tempCaBundleFile) {
|
||||
throw new \RuntimeException('Could not create a temporary file to store the bundled CA file');
|
||||
}
|
||||
|
||||
file_put_contents(
|
||||
$tempCaBundleFile,
|
||||
file_get_contents($caBundleFile)
|
||||
);
|
||||
|
||||
register_shutdown_function(function() use ($tempCaBundleFile) {
|
||||
@unlink($tempCaBundleFile);
|
||||
});
|
||||
|
||||
$caBundleFile = $tempCaBundleFile;
|
||||
}
|
||||
|
||||
return $caBundleFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a CA file using opensl_x509_parse only if it is safe to use
|
||||
*
|
||||
* @param string $filename
|
||||
* @param LoggerInterface $logger optional logger for information about which CA files were loaded
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function validateCaFile($filename, LoggerInterface $logger = null)
|
||||
{
|
||||
static $warned = false;
|
||||
|
||||
if (isset(self::$caFileValidity[$filename])) {
|
||||
return self::$caFileValidity[$filename];
|
||||
}
|
||||
|
||||
$contents = file_get_contents($filename);
|
||||
|
||||
// assume the CA is valid if php is vulnerable to
|
||||
// https://www.sektioneins.de/advisories/advisory-012013-php-openssl_x509_parse-memory-corruption-vulnerability.html
|
||||
if (!static::isOpensslParseSafe()) {
|
||||
if (!$warned && $logger) {
|
||||
$logger->warning(sprintf(
|
||||
'Your version of PHP, %s, is affected by CVE-2013-6420 and cannot safely perform certificate validation, we strongly suggest you upgrade.',
|
||||
PHP_VERSION
|
||||
));
|
||||
$warned = true;
|
||||
}
|
||||
|
||||
$isValid = !empty($contents);
|
||||
} elseif (is_string($contents) && strlen($contents) > 0) {
|
||||
$contents = preg_replace("/^(\\-+(?:BEGIN|END))\\s+TRUSTED\\s+(CERTIFICATE\\-+)\$/m", '$1 $2', $contents);
|
||||
if (null === $contents) {
|
||||
// regex extraction failed
|
||||
$isValid = false;
|
||||
} else {
|
||||
$isValid = (bool) openssl_x509_parse($contents);
|
||||
}
|
||||
} else {
|
||||
$isValid = false;
|
||||
}
|
||||
|
||||
if ($logger) {
|
||||
$logger->debug('Checked CA file '.realpath($filename).': '.($isValid ? 'valid' : 'invalid'));
|
||||
}
|
||||
|
||||
return self::$caFileValidity[$filename] = $isValid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if it is safe to use the PHP function openssl_x509_parse().
|
||||
*
|
||||
* This checks if OpenSSL extensions is vulnerable to remote code execution
|
||||
* via the exploit documented as CVE-2013-6420.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isOpensslParseSafe()
|
||||
{
|
||||
if (null !== self::$useOpensslParse) {
|
||||
return self::$useOpensslParse;
|
||||
}
|
||||
|
||||
if (PHP_VERSION_ID >= 50600) {
|
||||
return self::$useOpensslParse = true;
|
||||
}
|
||||
|
||||
// Vulnerable:
|
||||
// PHP 5.3.0 - PHP 5.3.27
|
||||
// PHP 5.4.0 - PHP 5.4.22
|
||||
// PHP 5.5.0 - PHP 5.5.6
|
||||
if (
|
||||
(PHP_VERSION_ID < 50400 && PHP_VERSION_ID >= 50328)
|
||||
|| (PHP_VERSION_ID < 50500 && PHP_VERSION_ID >= 50423)
|
||||
|| PHP_VERSION_ID >= 50507
|
||||
) {
|
||||
// This version of PHP has the fix for CVE-2013-6420 applied.
|
||||
return self::$useOpensslParse = true;
|
||||
}
|
||||
|
||||
if (defined('PHP_WINDOWS_VERSION_BUILD')) {
|
||||
// Windows is probably insecure in this case.
|
||||
return self::$useOpensslParse = false;
|
||||
}
|
||||
|
||||
$compareDistroVersionPrefix = function ($prefix, $fixedVersion) {
|
||||
$regex = '{^'.preg_quote($prefix).'([0-9]+)$}';
|
||||
|
||||
if (preg_match($regex, PHP_VERSION, $m)) {
|
||||
return ((int) $m[1]) >= $fixedVersion;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
// Hard coded list of PHP distributions with the fix backported.
|
||||
if (
|
||||
$compareDistroVersionPrefix('5.3.3-7+squeeze', 18) // Debian 6 (Squeeze)
|
||||
|| $compareDistroVersionPrefix('5.4.4-14+deb7u', 7) // Debian 7 (Wheezy)
|
||||
|| $compareDistroVersionPrefix('5.3.10-1ubuntu3.', 9) // Ubuntu 12.04 (Precise)
|
||||
) {
|
||||
return self::$useOpensslParse = true;
|
||||
}
|
||||
|
||||
// Symfony Process component is missing so we assume it is unsafe at this point
|
||||
if (!class_exists('Symfony\Component\Process\PhpProcess')) {
|
||||
return self::$useOpensslParse = false;
|
||||
}
|
||||
|
||||
// This is where things get crazy, because distros backport security
|
||||
// fixes the chances are on NIX systems the fix has been applied but
|
||||
// it's not possible to verify that from the PHP version.
|
||||
//
|
||||
// To verify exec a new PHP process and run the issue testcase with
|
||||
// known safe input that replicates the bug.
|
||||
|
||||
// Based on testcase in https://github.com/php/php-src/commit/c1224573c773b6845e83505f717fbf820fc18415
|
||||
// changes in https://github.com/php/php-src/commit/76a7fd893b7d6101300cc656058704a73254d593
|
||||
$cert = 'LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVwRENDQTR5Z0F3SUJBZ0lKQUp6dThyNnU2ZUJjTUEwR0NTcUdTSWIzRFFFQkJRVUFNSUhETVFzd0NRWUQKVlFRR0V3SkVSVEVjTUJvR0ExVUVDQXdUVG05eVpISm9aV2x1TFZkbGMzUm1ZV3hsYmpFUU1BNEdBMVVFQnd3SApTOE9Ed3Jac2JqRVVNQklHQTFVRUNnd0xVMlZyZEdsdmJrVnBibk14SHpBZEJnTlZCQXNNRmsxaGJHbGphVzkxCmN5QkRaWEowSUZObFkzUnBiMjR4SVRBZkJnTlZCQU1NR0cxaGJHbGphVzkxY3k1elpXdDBhVzl1WldsdWN5NWsKWlRFcU1DZ0dDU3FHU0liM0RRRUpBUlliYzNSbFptRnVMbVZ6YzJWeVFITmxhM1JwYjI1bGFXNXpMbVJsTUhVWQpaREU1TnpBd01UQXhNREF3TURBd1dnQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBCkFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUEKQUFBQUFBQVhEVEUwTVRFeU9ERXhNemt6TlZvd2djTXhDekFKQmdOVkJBWVRBa1JGTVJ3d0dnWURWUVFJREJOTwpiM0prY21obGFXNHRWMlZ6ZEdaaGJHVnVNUkF3RGdZRFZRUUhEQWRMdzRQQ3RteHVNUlF3RWdZRFZRUUtEQXRUClpXdDBhVzl1UldsdWN6RWZNQjBHQTFVRUN3d1dUV0ZzYVdOcGIzVnpJRU5sY25RZ1UyVmpkR2x2YmpFaE1COEcKQTFVRUF3d1liV0ZzYVdOcGIzVnpMbk5sYTNScGIyNWxhVzV6TG1SbE1Tb3dLQVlKS29aSWh2Y05BUWtCRmh0egpkR1ZtWVc0dVpYTnpaWEpBYzJWcmRHbHZibVZwYm5NdVpHVXdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCCkR3QXdnZ0VLQW9JQkFRRERBZjNobDdKWTBYY0ZuaXlFSnBTU0RxbjBPcUJyNlFQNjV1c0pQUnQvOFBhRG9xQnUKd0VZVC9OYSs2ZnNnUGpDMHVLOURaZ1dnMnRIV1dvYW5TYmxBTW96NVBINlorUzRTSFJaN2UyZERJalBqZGhqaAowbUxnMlVNTzV5cDBWNzk3R2dzOWxOdDZKUmZIODFNTjJvYlhXczROdHp0TE11RDZlZ3FwcjhkRGJyMzRhT3M4CnBrZHVpNVVhd1Raa3N5NXBMUEhxNWNNaEZHbTA2djY1Q0xvMFYyUGQ5K0tBb2tQclBjTjVLTEtlYno3bUxwazYKU01lRVhPS1A0aWRFcXh5UTdPN2ZCdUhNZWRzUWh1K3ByWTNzaTNCVXlLZlF0UDVDWm5YMmJwMHdLSHhYMTJEWAoxbmZGSXQ5RGJHdkhUY3lPdU4rblpMUEJtM3ZXeG50eUlJdlZBZ01CQUFHalFqQkFNQWtHQTFVZEV3UUNNQUF3CkVRWUpZSVpJQVliNFFnRUJCQVFEQWdlQU1Bc0dBMVVkRHdRRUF3SUZvREFUQmdOVkhTVUVEREFLQmdnckJnRUYKQlFjREFqQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FRRUFHMGZaWVlDVGJkajFYWWMrMVNub2FQUit2SThDOENhRAo4KzBVWWhkbnlVNGdnYTBCQWNEclk5ZTk0ZUVBdTZacXljRjZGakxxWFhkQWJvcHBXb2NyNlQ2R0QxeDMzQ2tsClZBcnpHL0t4UW9oR0QySmVxa2hJTWxEb214SE83a2EzOStPYThpMnZXTFZ5alU4QVp2V01BcnVIYTRFRU55RzcKbFcyQWFnYUZLRkNyOVRuWFRmcmR4R1ZFYnY3S1ZRNmJkaGc1cDVTanBXSDErTXEwM3VSM1pYUEJZZHlWODMxOQpvMGxWajFLRkkyRENML2xpV2lzSlJvb2YrMWNSMzVDdGQwd1lCY3BCNlRac2xNY09QbDc2ZHdLd0pnZUpvMlFnClpzZm1jMnZDMS9xT2xOdU5xLzBUenprVkd2OEVUVDNDZ2FVK1VYZTRYT1Z2a2NjZWJKbjJkZz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K';
|
||||
$script = <<<'EOT'
|
||||
|
||||
error_reporting(-1);
|
||||
$info = openssl_x509_parse(base64_decode('%s'));
|
||||
var_dump(PHP_VERSION, $info['issuer']['emailAddress'], $info['validFrom_time_t']);
|
||||
|
||||
EOT;
|
||||
$script = '<'."?php\n".sprintf($script, $cert);
|
||||
|
||||
try {
|
||||
$process = new PhpProcess($script);
|
||||
$process->mustRun();
|
||||
} catch (\Exception $e) {
|
||||
// In the case of any exceptions just accept it is not possible to
|
||||
// determine the safety of openssl_x509_parse and bail out.
|
||||
return self::$useOpensslParse = false;
|
||||
}
|
||||
|
||||
$output = preg_split('{\r?\n}', trim($process->getOutput()));
|
||||
$errorOutput = trim($process->getErrorOutput());
|
||||
|
||||
if (
|
||||
is_array($output)
|
||||
&& count($output) === 3
|
||||
&& $output[0] === sprintf('string(%d) "%s"', strlen(PHP_VERSION), PHP_VERSION)
|
||||
&& $output[1] === 'string(27) "stefan.esser@sektioneins.de"'
|
||||
&& $output[2] === 'int(-1)'
|
||||
&& preg_match('{openssl_x509_parse\(\): illegal (?:ASN1 data type for|length in) timestamp in - on line \d+}', $errorOutput)
|
||||
) {
|
||||
// This PHP has the fix backported probably by a distro security team.
|
||||
return self::$useOpensslParse = true;
|
||||
}
|
||||
|
||||
return self::$useOpensslParse = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the static caches
|
||||
* @return void
|
||||
*/
|
||||
public static function reset()
|
||||
{
|
||||
self::$caFileValidity = array();
|
||||
self::$caPath = null;
|
||||
self::$useOpensslParse = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return string|false
|
||||
*/
|
||||
private static function getEnvVariable($name)
|
||||
{
|
||||
if (isset($_SERVER[$name])) {
|
||||
return (string) $_SERVER[$name];
|
||||
}
|
||||
|
||||
if (PHP_SAPI === 'cli' && ($value = getenv($name)) !== false && $value !== null) {
|
||||
return (string) $value;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|false $certFile
|
||||
* @param LoggerInterface|null $logger
|
||||
* @return bool
|
||||
*/
|
||||
private static function caFileUsable($certFile, LoggerInterface $logger = null)
|
||||
{
|
||||
return $certFile
|
||||
&& static::isFile($certFile, $logger)
|
||||
&& static::isReadable($certFile, $logger)
|
||||
&& static::validateCaFile($certFile, $logger);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|false $certDir
|
||||
* @param LoggerInterface|null $logger
|
||||
* @return bool
|
||||
*/
|
||||
private static function caDirUsable($certDir, LoggerInterface $logger = null)
|
||||
{
|
||||
return $certDir
|
||||
&& static::isDir($certDir, $logger)
|
||||
&& static::isReadable($certDir, $logger)
|
||||
&& static::glob($certDir . '/*', $logger);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $certFile
|
||||
* @param LoggerInterface|null $logger
|
||||
* @return bool
|
||||
*/
|
||||
private static function isFile($certFile, LoggerInterface $logger = null)
|
||||
{
|
||||
$isFile = @is_file($certFile);
|
||||
if (!$isFile && $logger) {
|
||||
$logger->debug(sprintf('Checked CA file %s does not exist or it is not a file.', $certFile));
|
||||
}
|
||||
|
||||
return $isFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $certDir
|
||||
* @param LoggerInterface|null $logger
|
||||
* @return bool
|
||||
*/
|
||||
private static function isDir($certDir, LoggerInterface $logger = null)
|
||||
{
|
||||
$isDir = @is_dir($certDir);
|
||||
if (!$isDir && $logger) {
|
||||
$logger->debug(sprintf('Checked directory %s does not exist or it is not a directory.', $certDir));
|
||||
}
|
||||
|
||||
return $isDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $certFileOrDir
|
||||
* @param LoggerInterface|null $logger
|
||||
* @return bool
|
||||
*/
|
||||
private static function isReadable($certFileOrDir, LoggerInterface $logger = null)
|
||||
{
|
||||
$isReadable = @is_readable($certFileOrDir);
|
||||
if (!$isReadable && $logger) {
|
||||
$logger->debug(sprintf('Checked file or directory %s is not readable.', $certFileOrDir));
|
||||
}
|
||||
|
||||
return $isReadable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $pattern
|
||||
* @param LoggerInterface|null $logger
|
||||
* @return bool
|
||||
*/
|
||||
private static function glob($pattern, LoggerInterface $logger = null)
|
||||
{
|
||||
$certs = glob($pattern);
|
||||
if ($certs === false) {
|
||||
if ($logger) {
|
||||
$logger->debug(sprintf("An error occurred while trying to find certificates for pattern: %s", $pattern));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (count($certs) === 0) {
|
||||
if ($logger) {
|
||||
$logger->debug(sprintf("No CA files found for pattern: %s", $pattern));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
718
site/plugins/embed/vendor/composer/installed.json
vendored
Normal file
@@ -0,0 +1,718 @@
|
||||
{
|
||||
"packages": [
|
||||
{
|
||||
"name": "composer/ca-bundle",
|
||||
"version": "1.3.7",
|
||||
"version_normalized": "1.3.7.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/composer/ca-bundle.git",
|
||||
"reference": "76e46335014860eec1aa5a724799a00a2e47cc85"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/composer/ca-bundle/zipball/76e46335014860eec1aa5a724799a00a2e47cc85",
|
||||
"reference": "76e46335014860eec1aa5a724799a00a2e47cc85",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-openssl": "*",
|
||||
"ext-pcre": "*",
|
||||
"php": "^5.3.2 || ^7.0 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^0.12.55",
|
||||
"psr/log": "^1.0",
|
||||
"symfony/phpunit-bridge": "^4.2 || ^5",
|
||||
"symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0 || ^6.0"
|
||||
},
|
||||
"time": "2023-08-30T09:31:38+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Composer\\CaBundle\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jordi Boggiano",
|
||||
"email": "j.boggiano@seld.be",
|
||||
"homepage": "http://seld.be"
|
||||
}
|
||||
],
|
||||
"description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.",
|
||||
"keywords": [
|
||||
"cabundle",
|
||||
"cacert",
|
||||
"certificate",
|
||||
"ssl",
|
||||
"tls"
|
||||
],
|
||||
"support": {
|
||||
"irc": "irc://irc.freenode.org/composer",
|
||||
"issues": "https://github.com/composer/ca-bundle/issues",
|
||||
"source": "https://github.com/composer/ca-bundle/tree/1.3.7"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://packagist.com",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/composer",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/composer/composer",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"install-path": "./ca-bundle"
|
||||
},
|
||||
{
|
||||
"name": "embed/embed",
|
||||
"version": "v4.4.8",
|
||||
"version_normalized": "4.4.8.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/oscarotero/Embed.git",
|
||||
"reference": "49134080764018bc6b8a2488dd1c8cc2c47d15fc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/oscarotero/Embed/zipball/49134080764018bc6b8a2488dd1c8cc2c47d15fc",
|
||||
"reference": "49134080764018bc6b8a2488dd1c8cc2c47d15fc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"composer/ca-bundle": "^1.0",
|
||||
"ext-curl": "*",
|
||||
"ext-dom": "*",
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ml/json-ld": "^1.1",
|
||||
"oscarotero/html-parser": "^0.1.4",
|
||||
"php": "^7.4|^8",
|
||||
"psr/http-client": "^1.0",
|
||||
"psr/http-factory": "^1.0",
|
||||
"psr/http-message": "^1.0|^2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"brick/varexporter": "^0.3.1",
|
||||
"friendsofphp/php-cs-fixer": "^2.0",
|
||||
"nyholm/psr7": "^1.2",
|
||||
"oscarotero/php-cs-fixer-config": "^1.0",
|
||||
"phpunit/phpunit": "^9.0",
|
||||
"symfony/css-selector": "^5.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/css-selector": "If you want to get elements using css selectors"
|
||||
},
|
||||
"time": "2023-05-22T18:48:30+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/functions.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Embed\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Oscar Otero",
|
||||
"email": "oom@oscarotero.com",
|
||||
"homepage": "http://oscarotero.com",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "PHP library to retrieve page info using oembed, opengraph, etc",
|
||||
"homepage": "https://github.com/oscarotero/Embed",
|
||||
"keywords": [
|
||||
"embed",
|
||||
"embedly",
|
||||
"oembed",
|
||||
"opengraph",
|
||||
"twitter cards"
|
||||
],
|
||||
"support": {
|
||||
"email": "oom@oscarotero.com",
|
||||
"issues": "https://github.com/oscarotero/Embed/issues",
|
||||
"source": "https://github.com/oscarotero/Embed/tree/v4.4.8"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://paypal.me/oscarotero",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/oscarotero",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://www.patreon.com/misteroom",
|
||||
"type": "patreon"
|
||||
}
|
||||
],
|
||||
"install-path": "../embed/embed"
|
||||
},
|
||||
{
|
||||
"name": "getkirby/composer-installer",
|
||||
"version": "1.2.1",
|
||||
"version_normalized": "1.2.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/getkirby/composer-installer.git",
|
||||
"reference": "c98ece30bfba45be7ce457e1102d1b169d922f3d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/getkirby/composer-installer/zipball/c98ece30bfba45be7ce457e1102d1b169d922f3d",
|
||||
"reference": "c98ece30bfba45be7ce457e1102d1b169d922f3d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"composer-plugin-api": "^1.0 || ^2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"composer/composer": "^1.8 || ^2.0"
|
||||
},
|
||||
"time": "2020-12-28T12:54:39+00:00",
|
||||
"type": "composer-plugin",
|
||||
"extra": {
|
||||
"class": "Kirby\\ComposerInstaller\\Plugin"
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Kirby\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "Kirby's custom Composer installer for the Kirby CMS and for Kirby plugins",
|
||||
"homepage": "https://getkirby.com",
|
||||
"install-path": "../getkirby/composer-installer"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/psr7",
|
||||
"version": "2.6.1",
|
||||
"version_normalized": "2.6.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/psr7.git",
|
||||
"reference": "be45764272e8873c72dbe3d2edcfdfcc3bc9f727"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/psr7/zipball/be45764272e8873c72dbe3d2edcfdfcc3bc9f727",
|
||||
"reference": "be45764272e8873c72dbe3d2edcfdfcc3bc9f727",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2.5 || ^8.0",
|
||||
"psr/http-factory": "^1.0",
|
||||
"psr/http-message": "^1.1 || ^2.0",
|
||||
"ralouphie/getallheaders": "^3.0"
|
||||
},
|
||||
"provide": {
|
||||
"psr/http-factory-implementation": "1.0",
|
||||
"psr/http-message-implementation": "1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"bamarni/composer-bin-plugin": "^1.8.1",
|
||||
"http-interop/http-factory-tests": "^0.9",
|
||||
"phpunit/phpunit": "^8.5.29 || ^9.5.23"
|
||||
},
|
||||
"suggest": {
|
||||
"laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
|
||||
},
|
||||
"time": "2023-08-27T10:13:57+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"bamarni-bin": {
|
||||
"bin-links": true,
|
||||
"forward-command": false
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"GuzzleHttp\\Psr7\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Graham Campbell",
|
||||
"email": "hello@gjcampbell.co.uk",
|
||||
"homepage": "https://github.com/GrahamCampbell"
|
||||
},
|
||||
{
|
||||
"name": "Michael Dowling",
|
||||
"email": "mtdowling@gmail.com",
|
||||
"homepage": "https://github.com/mtdowling"
|
||||
},
|
||||
{
|
||||
"name": "George Mponos",
|
||||
"email": "gmponos@gmail.com",
|
||||
"homepage": "https://github.com/gmponos"
|
||||
},
|
||||
{
|
||||
"name": "Tobias Nyholm",
|
||||
"email": "tobias.nyholm@gmail.com",
|
||||
"homepage": "https://github.com/Nyholm"
|
||||
},
|
||||
{
|
||||
"name": "Márk Sági-Kazár",
|
||||
"email": "mark.sagikazar@gmail.com",
|
||||
"homepage": "https://github.com/sagikazarmark"
|
||||
},
|
||||
{
|
||||
"name": "Tobias Schultze",
|
||||
"email": "webmaster@tubo-world.de",
|
||||
"homepage": "https://github.com/Tobion"
|
||||
},
|
||||
{
|
||||
"name": "Márk Sági-Kazár",
|
||||
"email": "mark.sagikazar@gmail.com",
|
||||
"homepage": "https://sagikazarmark.hu"
|
||||
}
|
||||
],
|
||||
"description": "PSR-7 message implementation that also provides common utility methods",
|
||||
"keywords": [
|
||||
"http",
|
||||
"message",
|
||||
"psr-7",
|
||||
"request",
|
||||
"response",
|
||||
"stream",
|
||||
"uri",
|
||||
"url"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/guzzle/psr7/issues",
|
||||
"source": "https://github.com/guzzle/psr7/tree/2.6.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/GrahamCampbell",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/Nyholm",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"install-path": "../guzzlehttp/psr7"
|
||||
},
|
||||
{
|
||||
"name": "ml/iri",
|
||||
"version": "1.1.4",
|
||||
"version_normalized": "1.1.4.0",
|
||||
"target-dir": "ML/IRI",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/lanthaler/IRI.git",
|
||||
"reference": "cbd44fa913e00ea624241b38cefaa99da8d71341"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/lanthaler/IRI/zipball/cbd44fa913e00ea624241b38cefaa99da8d71341",
|
||||
"reference": "cbd44fa913e00ea624241b38cefaa99da8d71341",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"lib-pcre": ">=4.0",
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"time": "2014-01-21T13:43:39+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"ML\\IRI": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Markus Lanthaler",
|
||||
"email": "mail@markus-lanthaler.com",
|
||||
"homepage": "http://www.markus-lanthaler.com",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "IRI handling for PHP",
|
||||
"homepage": "http://www.markus-lanthaler.com",
|
||||
"keywords": [
|
||||
"URN",
|
||||
"iri",
|
||||
"uri",
|
||||
"url"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/lanthaler/IRI/issues",
|
||||
"source": "https://github.com/lanthaler/IRI/tree/master"
|
||||
},
|
||||
"install-path": "../ml/iri/ML/IRI"
|
||||
},
|
||||
{
|
||||
"name": "ml/json-ld",
|
||||
"version": "1.2.1",
|
||||
"version_normalized": "1.2.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/lanthaler/JsonLD.git",
|
||||
"reference": "537e68e87a6bce23e57c575cd5dcac1f67ce25d8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/lanthaler/JsonLD/zipball/537e68e87a6bce23e57c575cd5dcac1f67ce25d8",
|
||||
"reference": "537e68e87a6bce23e57c575cd5dcac1f67ce25d8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"ml/iri": "^1.1.1",
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"json-ld/tests": "1.0",
|
||||
"phpunit/phpunit": "^4"
|
||||
},
|
||||
"time": "2022-09-29T08:45:17+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"ML\\JsonLD\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Markus Lanthaler",
|
||||
"email": "mail@markus-lanthaler.com",
|
||||
"homepage": "http://www.markus-lanthaler.com",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "JSON-LD Processor for PHP",
|
||||
"homepage": "http://www.markus-lanthaler.com",
|
||||
"keywords": [
|
||||
"JSON-LD",
|
||||
"jsonld"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/lanthaler/JsonLD/issues",
|
||||
"source": "https://github.com/lanthaler/JsonLD/tree/1.2.1"
|
||||
},
|
||||
"install-path": "../ml/json-ld"
|
||||
},
|
||||
{
|
||||
"name": "oscarotero/html-parser",
|
||||
"version": "v0.1.7",
|
||||
"version_normalized": "0.1.7.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/oscarotero/html-parser.git",
|
||||
"reference": "0c5b619bdc7ac061f06a667d913e2af708ee3231"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/oscarotero/html-parser/zipball/0c5b619bdc7ac061f06a667d913e2af708ee3231",
|
||||
"reference": "0c5b619bdc7ac061f06a667d913e2af708ee3231",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2 || ^8"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^2.11",
|
||||
"phpunit/phpunit": "^8.0"
|
||||
},
|
||||
"time": "2022-12-17T09:48:58+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"HtmlParser\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Oscar Otero",
|
||||
"email": "oom@oscarotero.com",
|
||||
"homepage": "http://oscarotero.com",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Parse html strings to DOMDocument",
|
||||
"homepage": "https://github.com/oscarotero/html-parser",
|
||||
"keywords": [
|
||||
"dom",
|
||||
"html",
|
||||
"parser"
|
||||
],
|
||||
"support": {
|
||||
"email": "oom@oscarotero.com",
|
||||
"issues": "https://github.com/oscarotero/html-parser/issues",
|
||||
"source": "https://github.com/oscarotero/html-parser/tree/v0.1.7"
|
||||
},
|
||||
"install-path": "../oscarotero/html-parser"
|
||||
},
|
||||
{
|
||||
"name": "psr/http-client",
|
||||
"version": "1.0.3",
|
||||
"version_normalized": "1.0.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/http-client.git",
|
||||
"reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90",
|
||||
"reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.0 || ^8.0",
|
||||
"psr/http-message": "^1.0 || ^2.0"
|
||||
},
|
||||
"time": "2023-09-23T14:17:50+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Http\\Client\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "https://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interface for HTTP clients",
|
||||
"homepage": "https://github.com/php-fig/http-client",
|
||||
"keywords": [
|
||||
"http",
|
||||
"http-client",
|
||||
"psr",
|
||||
"psr-18"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/php-fig/http-client"
|
||||
},
|
||||
"install-path": "../psr/http-client"
|
||||
},
|
||||
{
|
||||
"name": "psr/http-factory",
|
||||
"version": "1.0.2",
|
||||
"version_normalized": "1.0.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/http-factory.git",
|
||||
"reference": "e616d01114759c4c489f93b099585439f795fe35"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35",
|
||||
"reference": "e616d01114759c4c489f93b099585439f795fe35",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.0.0",
|
||||
"psr/http-message": "^1.0 || ^2.0"
|
||||
},
|
||||
"time": "2023-04-10T20:10:41+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Http\\Message\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "https://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interfaces for PSR-7 HTTP message factories",
|
||||
"keywords": [
|
||||
"factory",
|
||||
"http",
|
||||
"message",
|
||||
"psr",
|
||||
"psr-17",
|
||||
"psr-7",
|
||||
"request",
|
||||
"response"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/php-fig/http-factory/tree/1.0.2"
|
||||
},
|
||||
"install-path": "../psr/http-factory"
|
||||
},
|
||||
{
|
||||
"name": "psr/http-message",
|
||||
"version": "2.0",
|
||||
"version_normalized": "2.0.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/http-message.git",
|
||||
"reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71",
|
||||
"reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2 || ^8.0"
|
||||
},
|
||||
"time": "2023-04-04T09:54:51+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Http\\Message\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "https://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interface for HTTP messages",
|
||||
"homepage": "https://github.com/php-fig/http-message",
|
||||
"keywords": [
|
||||
"http",
|
||||
"http-message",
|
||||
"psr",
|
||||
"psr-7",
|
||||
"request",
|
||||
"response"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/php-fig/http-message/tree/2.0"
|
||||
},
|
||||
"install-path": "../psr/http-message"
|
||||
},
|
||||
{
|
||||
"name": "ralouphie/getallheaders",
|
||||
"version": "3.0.3",
|
||||
"version_normalized": "3.0.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ralouphie/getallheaders.git",
|
||||
"reference": "120b605dfeb996808c31b6477290a714d356e822"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
|
||||
"reference": "120b605dfeb996808c31b6477290a714d356e822",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.6"
|
||||
},
|
||||
"require-dev": {
|
||||
"php-coveralls/php-coveralls": "^2.1",
|
||||
"phpunit/phpunit": "^5 || ^6.5"
|
||||
},
|
||||
"time": "2019-03-08T08:55:37+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/getallheaders.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ralph Khattar",
|
||||
"email": "ralph.khattar@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "A polyfill for getallheaders.",
|
||||
"support": {
|
||||
"issues": "https://github.com/ralouphie/getallheaders/issues",
|
||||
"source": "https://github.com/ralouphie/getallheaders/tree/develop"
|
||||
},
|
||||
"install-path": "../ralouphie/getallheaders"
|
||||
}
|
||||
],
|
||||
"dev": true,
|
||||
"dev-package-names": []
|
||||
}
|
||||
134
site/plugins/embed/vendor/composer/installed.php
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
<?php return array(
|
||||
'root' => array(
|
||||
'name' => 'sylvainjule/embed',
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'reference' => '14d933e6ae6a85ee874e90e64ab365d19ba7fa68',
|
||||
'type' => 'kirby-plugin',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
'dev' => true,
|
||||
),
|
||||
'versions' => array(
|
||||
'composer/ca-bundle' => array(
|
||||
'pretty_version' => '1.3.7',
|
||||
'version' => '1.3.7.0',
|
||||
'reference' => '76e46335014860eec1aa5a724799a00a2e47cc85',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/./ca-bundle',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'embed/embed' => array(
|
||||
'pretty_version' => 'v4.4.8',
|
||||
'version' => '4.4.8.0',
|
||||
'reference' => '49134080764018bc6b8a2488dd1c8cc2c47d15fc',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../embed/embed',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'getkirby/composer-installer' => array(
|
||||
'pretty_version' => '1.2.1',
|
||||
'version' => '1.2.1.0',
|
||||
'reference' => 'c98ece30bfba45be7ce457e1102d1b169d922f3d',
|
||||
'type' => 'composer-plugin',
|
||||
'install_path' => __DIR__ . '/../getkirby/composer-installer',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'guzzlehttp/psr7' => array(
|
||||
'pretty_version' => '2.6.1',
|
||||
'version' => '2.6.1.0',
|
||||
'reference' => 'be45764272e8873c72dbe3d2edcfdfcc3bc9f727',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../guzzlehttp/psr7',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'ml/iri' => array(
|
||||
'pretty_version' => '1.1.4',
|
||||
'version' => '1.1.4.0',
|
||||
'reference' => 'cbd44fa913e00ea624241b38cefaa99da8d71341',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../ml/iri/ML/IRI',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'ml/json-ld' => array(
|
||||
'pretty_version' => '1.2.1',
|
||||
'version' => '1.2.1.0',
|
||||
'reference' => '537e68e87a6bce23e57c575cd5dcac1f67ce25d8',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../ml/json-ld',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'oscarotero/html-parser' => array(
|
||||
'pretty_version' => 'v0.1.7',
|
||||
'version' => '0.1.7.0',
|
||||
'reference' => '0c5b619bdc7ac061f06a667d913e2af708ee3231',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../oscarotero/html-parser',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/http-client' => array(
|
||||
'pretty_version' => '1.0.3',
|
||||
'version' => '1.0.3.0',
|
||||
'reference' => 'bb5906edc1c324c9a05aa0873d40117941e5fa90',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/http-client',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/http-factory' => array(
|
||||
'pretty_version' => '1.0.2',
|
||||
'version' => '1.0.2.0',
|
||||
'reference' => 'e616d01114759c4c489f93b099585439f795fe35',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/http-factory',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/http-factory-implementation' => array(
|
||||
'dev_requirement' => false,
|
||||
'provided' => array(
|
||||
0 => '1.0',
|
||||
),
|
||||
),
|
||||
'psr/http-message' => array(
|
||||
'pretty_version' => '2.0',
|
||||
'version' => '2.0.0.0',
|
||||
'reference' => '402d35bcb92c70c026d1a6a9883f06b2ead23d71',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/http-message',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/http-message-implementation' => array(
|
||||
'dev_requirement' => false,
|
||||
'provided' => array(
|
||||
0 => '1.0',
|
||||
),
|
||||
),
|
||||
'ralouphie/getallheaders' => array(
|
||||
'pretty_version' => '3.0.3',
|
||||
'version' => '3.0.3.0',
|
||||
'reference' => '120b605dfeb996808c31b6477290a714d356e822',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../ralouphie/getallheaders',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'sylvainjule/embed' => array(
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'reference' => '14d933e6ae6a85ee874e90e64ab365d19ba7fa68',
|
||||
'type' => 'kirby-plugin',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
),
|
||||
);
|
||||
26
site/plugins/embed/vendor/composer/platform_check.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
// platform_check.php @generated by Composer
|
||||
|
||||
$issues = array();
|
||||
|
||||
if (!(PHP_VERSION_ID >= 70400)) {
|
||||
$issues[] = 'Your Composer dependencies require a PHP version ">= 7.4.0". You are running ' . PHP_VERSION . '.';
|
||||
}
|
||||
|
||||
if ($issues) {
|
||||
if (!headers_sent()) {
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
}
|
||||
if (!ini_get('display_errors')) {
|
||||
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
||||
fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
|
||||
} elseif (!headers_sent()) {
|
||||
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
|
||||
}
|
||||
}
|
||||
trigger_error(
|
||||
'Composer detected issues in your platform: ' . implode(' ', $issues),
|
||||
E_USER_ERROR
|
||||
);
|
||||
}
|
||||
246
site/plugins/embed/vendor/embed/embed/CHANGELOG.md
vendored
Normal file
@@ -0,0 +1,246 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## [4.4.8] - 2023-05-22
|
||||
### Fixed
|
||||
- Support for `psr/http-message@2` [#514], [#515]
|
||||
|
||||
## [4.4.7] - 2022-12-12
|
||||
### Fixed
|
||||
- Href attributes with `undefined` values [#501], [#502]
|
||||
- Deprecated warning for var interpolation in PHP 8.2 [#506]
|
||||
- Prevent unsupported operand types exception [#507]
|
||||
|
||||
## [4.4.6] - 2022-10-02
|
||||
### Fixed
|
||||
- Some code issues detected by phpstan: [#495], [#496], [#497], [#498].
|
||||
- Fix for quotation marks in redirect URL [#499]
|
||||
|
||||
## [4.4.5] - 2022-09-06
|
||||
### Fixed
|
||||
- Updated oembed endpoints [#494]
|
||||
|
||||
## [4.4.4] - 2022-04-13
|
||||
### Fixed
|
||||
- Error getting data from Linked data [#481].
|
||||
|
||||
## [4.4.3] - 2022-03-13
|
||||
### Fixed
|
||||
- PHP 8.1 deprecation notice [#480].
|
||||
|
||||
## [4.4.2] - 2022-02-13
|
||||
### Added
|
||||
- Options to customize the CurlClient to perform http queries [#474].
|
||||
|
||||
## [4.4.1] - 2022-02-06
|
||||
### Fixed
|
||||
- PHP 8.1 deprecation notice [#473].
|
||||
|
||||
## [4.4.0] - 2022-01-08
|
||||
### Added
|
||||
- New settings option `twitter:token` to use Twitter API to get the data [#364] [#468].
|
||||
|
||||
### Fixed
|
||||
- Headers not sent properly by curl [#466], [#467].
|
||||
|
||||
## [4.3.5] - 2021-10-10
|
||||
### Fixed
|
||||
- Updated oEmbed endpoints
|
||||
- Fixed embed code for Instagram [#456], [#459]
|
||||
|
||||
### Security
|
||||
- Fixed a possible XML Quadratic Blowup vulnerability.
|
||||
|
||||
## [4.3.4] - 2021-06-22
|
||||
### Fixed
|
||||
- Urls of images should include the same url for the `$info->image` value. [#452]
|
||||
|
||||
## [4.3.3] - 2021-06-22
|
||||
### Fixed
|
||||
- Facebook embed redirects to `/login`. [#450], [#451]
|
||||
|
||||
## [4.3.2] - 2021-04-04
|
||||
### Fixed
|
||||
- Add configured oEmbed query parameters to all oEmbed endpoints [#437]
|
||||
- Updated oEmbed endpoints.
|
||||
- Replaced Travis with Github workflows for testing
|
||||
|
||||
## [4.3.1] - 2021-03-21
|
||||
### Added
|
||||
- Support for binary files (video, audio, images, etc) [#412] [#413]
|
||||
|
||||
### Fixed
|
||||
- Oembed for facebook photos [#405] [#406]
|
||||
- Oembed for facebook videos [#432] [#433]
|
||||
- Added more ways to detect data using meta tags [#427]
|
||||
- Bandcamp provider name [#429] [#430]
|
||||
|
||||
## [4.3.0] - 2020-11-04
|
||||
### Added
|
||||
- New function `$embed->setSettings()` to pass the settings before get the site info
|
||||
|
||||
### Fixed
|
||||
- PHP 8 compatibility [#394]
|
||||
- Facebook and Instagram adapted to the new API changes [#392] [#399]
|
||||
|
||||
## [4.2.7] - 2020-09-23
|
||||
### Added
|
||||
- New option `twitch:parent` to fix Twitch embed with iframes [#384]
|
||||
|
||||
### Fixed
|
||||
- Added `datePublished` check to `PublishedTime` extractor [#385] [#386]
|
||||
- Added `@property-read` for IDE suppport [#387] [#388]
|
||||
|
||||
## [4.2.6] - 2020-08-28
|
||||
### Fixed
|
||||
- Code width and height when the provided value is not numeric (ex: 100%) [#380]
|
||||
|
||||
## [4.2.5] - 2020-08-01
|
||||
### Fixed
|
||||
- Github TypeError exception with some urls [#375]
|
||||
|
||||
## [4.2.4] - 2020-07-06
|
||||
### Fixed
|
||||
- Ignore invalid urls instead throw an exception
|
||||
- Updated oembed list of endpoints
|
||||
|
||||
## [4.2.3] - 2020-06-12
|
||||
### Fixed
|
||||
- Suppport for other non-latin alphabets such Persian or Arabic [#366]
|
||||
|
||||
## [4.2.2] - 2020-05-31
|
||||
### Fixed
|
||||
- Provided a fallback for oEmbed compatible sites like Instagram that redirects to login page [#357]
|
||||
|
||||
## [4.2.1] - 2020-05-25
|
||||
### Fixed
|
||||
- Redirect urls like `t.co`.
|
||||
|
||||
## [4.2.0] - 2020-05-23
|
||||
### Added
|
||||
- Added the `ignored_errors` settings to ignore some curls errors instead throw an exception [#355]
|
||||
- Support for Twitch embeds [#332]
|
||||
|
||||
### Fixed
|
||||
- Ignored linkedData errors [#356]
|
||||
|
||||
## [4.1.1] - 2020-04-24
|
||||
### Added
|
||||
- Updated oembed endpoints from `oembed.com`
|
||||
- Add support for tiktok.com
|
||||
|
||||
## [4.1.0] - 2020-04-19
|
||||
### Added
|
||||
- Ability to send settings to `CurlClient`. Added the `cookies_path` setting to customize the file used for cookies. [#345]
|
||||
- `Document::selectCss()` function to select elements using css selectors instead xpath (it requires `symfony/css-selector`)
|
||||
- `Document::removeCss()` function to remove elements using css selectors instead xpath (it requires `symfony/css-selector`)
|
||||
- Ability to configure OEmbed parameters from the outside using the `oembed:query_parameters` setting [#346]
|
||||
|
||||
## [4.0.0] - 2020-03-13
|
||||
Full library refactoring.
|
||||
|
||||
### Added
|
||||
- Support for multiple parallel request with `curl_multi`
|
||||
- Support for PSR-7 Http Messages, PSR-17 Http Factories and PSR-18 Http Client
|
||||
- `cms` value
|
||||
- `language` to detect the page language
|
||||
- `languages` to detect urls to versions in different languages
|
||||
- `favicon` to detect small favicons (16 or 32px)
|
||||
- `icon` to detect big icons (from 48px)
|
||||
|
||||
### Changed
|
||||
- Changed providers (oEmbed, Html, OpenGraph etc) by independent detectors (title, url, language etc).
|
||||
- The `tags` value is renamed to `keywords`
|
||||
- Use Psr standards instead custom interfaces.
|
||||
- Improved tests using cached responses.
|
||||
|
||||
### Removed
|
||||
- Support for PHP<7.4
|
||||
- `type` value (is was very confusing)
|
||||
- `images` value
|
||||
- `providerImage` (use `favicon` or `icon` instead)
|
||||
- Support for files (pdf, jpg, video, etc).
|
||||
|
||||
[#332]: https://github.com/oscarotero/Embed/issues/332
|
||||
[#345]: https://github.com/oscarotero/Embed/issues/345
|
||||
[#346]: https://github.com/oscarotero/Embed/issues/346
|
||||
[#355]: https://github.com/oscarotero/Embed/issues/355
|
||||
[#356]: https://github.com/oscarotero/Embed/issues/356
|
||||
[#357]: https://github.com/oscarotero/Embed/issues/357
|
||||
[#364]: https://github.com/oscarotero/Embed/issues/364
|
||||
[#366]: https://github.com/oscarotero/Embed/issues/366
|
||||
[#375]: https://github.com/oscarotero/Embed/issues/375
|
||||
[#380]: https://github.com/oscarotero/Embed/issues/380
|
||||
[#384]: https://github.com/oscarotero/Embed/issues/384
|
||||
[#385]: https://github.com/oscarotero/Embed/issues/385
|
||||
[#386]: https://github.com/oscarotero/Embed/issues/386
|
||||
[#387]: https://github.com/oscarotero/Embed/issues/387
|
||||
[#388]: https://github.com/oscarotero/Embed/issues/388
|
||||
[#392]: https://github.com/oscarotero/Embed/issues/392
|
||||
[#394]: https://github.com/oscarotero/Embed/issues/394
|
||||
[#399]: https://github.com/oscarotero/Embed/issues/399
|
||||
[#405]: https://github.com/oscarotero/Embed/issues/405
|
||||
[#406]: https://github.com/oscarotero/Embed/issues/406
|
||||
[#412]: https://github.com/oscarotero/Embed/issues/412
|
||||
[#413]: https://github.com/oscarotero/Embed/issues/413
|
||||
[#427]: https://github.com/oscarotero/Embed/issues/427
|
||||
[#429]: https://github.com/oscarotero/Embed/issues/429
|
||||
[#430]: https://github.com/oscarotero/Embed/issues/430
|
||||
[#432]: https://github.com/oscarotero/Embed/issues/432
|
||||
[#433]: https://github.com/oscarotero/Embed/issues/433
|
||||
[#437]: https://github.com/oscarotero/Embed/issues/437
|
||||
[#450]: https://github.com/oscarotero/Embed/issues/450
|
||||
[#451]: https://github.com/oscarotero/Embed/issues/451
|
||||
[#452]: https://github.com/oscarotero/Embed/issues/452
|
||||
[#456]: https://github.com/oscarotero/Embed/issues/456
|
||||
[#459]: https://github.com/oscarotero/Embed/issues/459
|
||||
[#466]: https://github.com/oscarotero/Embed/issues/466
|
||||
[#467]: https://github.com/oscarotero/Embed/issues/467
|
||||
[#468]: https://github.com/oscarotero/Embed/issues/468
|
||||
[#473]: https://github.com/oscarotero/Embed/issues/473
|
||||
[#474]: https://github.com/oscarotero/Embed/issues/474
|
||||
[#480]: https://github.com/oscarotero/Embed/issues/480
|
||||
[#481]: https://github.com/oscarotero/Embed/issues/481
|
||||
[#494]: https://github.com/oscarotero/Embed/issues/494
|
||||
[#495]: https://github.com/oscarotero/Embed/issues/495
|
||||
[#496]: https://github.com/oscarotero/Embed/issues/496
|
||||
[#497]: https://github.com/oscarotero/Embed/issues/497
|
||||
[#498]: https://github.com/oscarotero/Embed/issues/498
|
||||
[#499]: https://github.com/oscarotero/Embed/issues/499
|
||||
[#501]: https://github.com/oscarotero/Embed/issues/501
|
||||
[#502]: https://github.com/oscarotero/Embed/issues/502
|
||||
[#506]: https://github.com/oscarotero/Embed/issues/506
|
||||
[#507]: https://github.com/oscarotero/Embed/issues/507
|
||||
[#514]: https://github.com/oscarotero/Embed/issues/514
|
||||
[#515]: https://github.com/oscarotero/Embed/issues/515
|
||||
|
||||
[4.4.8]: https://github.com/oscarotero/Embed/compare/v4.4.7...v4.4.8
|
||||
[4.4.7]: https://github.com/oscarotero/Embed/compare/v4.4.6...v4.4.7
|
||||
[4.4.6]: https://github.com/oscarotero/Embed/compare/v4.4.5...v4.4.6
|
||||
[4.4.5]: https://github.com/oscarotero/Embed/compare/v4.4.4...v4.4.5
|
||||
[4.4.4]: https://github.com/oscarotero/Embed/compare/v4.4.3...v4.4.4
|
||||
[4.4.3]: https://github.com/oscarotero/Embed/compare/v4.4.2...v4.4.3
|
||||
[4.4.2]: https://github.com/oscarotero/Embed/compare/v4.4.1...v4.4.2
|
||||
[4.4.1]: https://github.com/oscarotero/Embed/compare/v4.4.0...v4.4.1
|
||||
[4.4.0]: https://github.com/oscarotero/Embed/compare/v4.3.5...v4.4.0
|
||||
[4.3.5]: https://github.com/oscarotero/Embed/compare/v4.3.4...v4.3.5
|
||||
[4.3.4]: https://github.com/oscarotero/Embed/compare/v4.3.3...v4.3.4
|
||||
[4.3.3]: https://github.com/oscarotero/Embed/compare/v4.3.2...v4.3.3
|
||||
[4.3.2]: https://github.com/oscarotero/Embed/compare/v4.3.1...v4.3.2
|
||||
[4.3.1]: https://github.com/oscarotero/Embed/compare/v4.3.0...v4.3.1
|
||||
[4.3.0]: https://github.com/oscarotero/Embed/compare/v4.2.7...v4.3.0
|
||||
[4.2.7]: https://github.com/oscarotero/Embed/compare/v4.2.6...v4.2.7
|
||||
[4.2.6]: https://github.com/oscarotero/Embed/compare/v4.2.5...v4.2.6
|
||||
[4.2.5]: https://github.com/oscarotero/Embed/compare/v4.2.4...v4.2.5
|
||||
[4.2.4]: https://github.com/oscarotero/Embed/compare/v4.2.3...v4.2.4
|
||||
[4.2.3]: https://github.com/oscarotero/Embed/compare/v4.2.2...v4.2.3
|
||||
[4.2.2]: https://github.com/oscarotero/Embed/compare/v4.2.1...v4.2.2
|
||||
[4.2.1]: https://github.com/oscarotero/Embed/compare/v4.2.0...v4.2.1
|
||||
[4.2.0]: https://github.com/oscarotero/Embed/compare/v4.1.1...v4.2.0
|
||||
[4.1.1]: https://github.com/oscarotero/Embed/compare/v4.1.0...v4.1.1
|
||||
[4.1.0]: https://github.com/oscarotero/Embed/compare/v4.0.0...v4.1.0
|
||||
[4.0.0]: https://github.com/oscarotero/Embed/releases/tag/v4.0.0
|
||||
21
site/plugins/embed/vendor/embed/embed/LICENSE
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 Oscar Otero Marzoa
|
||||
|
||||
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:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
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.
|
||||
360
site/plugins/embed/vendor/embed/embed/README.md
vendored
Normal file
@@ -0,0 +1,360 @@
|
||||
|
||||
# Embed
|
||||
|
||||
[![Latest Version on Packagist][ico-version]][link-packagist]
|
||||
[![Total Downloads][ico-downloads]][link-packagist]
|
||||
[![Monthly Downloads][ico-m-downloads]][link-packagist]
|
||||
[![Software License][ico-license]](LICENSE)
|
||||
|
||||
PHP library to get information from any web page (using oembed, opengraph, twitter-cards, scrapping the html, etc). It's compatible with any web service (youtube, vimeo, flickr, instagram, etc) and has adapters to some sites like (archive.org, github, facebook, etc).
|
||||
|
||||
Requirements:
|
||||
|
||||
* PHP 7.4+
|
||||
* Curl library installed
|
||||
* PSR-17 implementation. By default these libraries are detected automatically:
|
||||
* [laminas/laminas-diactoros](https://github.com/laminas/laminas-diactoros)
|
||||
* [guzzle/psr7](https://github.com/guzzle/psr7)
|
||||
* [nyholm/psr7](https://github.com/Nyholm/psr7)
|
||||
* [sunrise/http-message](https://github.com/sunrise-php/http-message)
|
||||
|
||||
> If you need PHP 5.5-7.3 support, [use the 3.x version](https://github.com/oscarotero/Embed/tree/v3.x)
|
||||
|
||||
## Online demo
|
||||
|
||||
http://oscarotero.com/embed/demo
|
||||
|
||||
## Video Tutorial
|
||||
[<img src="https://img.youtube.com/vi/4YCLRpKY1cs/0.jpg" width="250">](https://youtu.be/4YCLRpKY1cs)
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
This package is installable and autoloadable via Composer as [embed/embed](https://packagist.org/packages/embed/embed).
|
||||
|
||||
```
|
||||
$ composer require embed/embed
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```php
|
||||
use Embed\Embed;
|
||||
|
||||
$embed = new Embed();
|
||||
|
||||
//Load any url:
|
||||
$info = $embed->get('https://www.youtube.com/watch?v=PP1xn5wHtxE');
|
||||
|
||||
//Get content info
|
||||
|
||||
$info->title; //The page title
|
||||
$info->description; //The page description
|
||||
$info->url; //The canonical url
|
||||
$info->keywords; //The page keywords
|
||||
|
||||
$info->image; //The thumbnail or main image
|
||||
|
||||
$info->code->html; //The code to embed the image, video, etc
|
||||
$info->code->width; //The exact width of the embed code (if exists)
|
||||
$info->code->height; //The exact height of the embed code (if exists)
|
||||
$info->code->ratio; //The aspect ratio (width/height)
|
||||
|
||||
$info->authorName; //The resource author
|
||||
$info->authorUrl; //The author url
|
||||
|
||||
$info->cms; //The cms used
|
||||
$info->language; //The language of the page
|
||||
$info->languages; //The alternative languages
|
||||
|
||||
$info->providerName; //The provider name of the page (Youtube, Twitter, Instagram, etc)
|
||||
$info->providerUrl; //The provider url
|
||||
$info->icon; //The big icon of the site
|
||||
$info->favicon; //The favicon of the site (an .ico file or a png with up to 32x32px)
|
||||
|
||||
$info->publishedTime; //The published time of the resource
|
||||
$info->license; //The license url of the resource
|
||||
$info->feeds; //The RSS/Atom feeds
|
||||
```
|
||||
|
||||
## Parallel multiple requests
|
||||
|
||||
```php
|
||||
use Embed\Embed;
|
||||
|
||||
$embed = new Embed();
|
||||
|
||||
//Load multiple urls asynchronously:
|
||||
$infos = $embed->getMulti(
|
||||
'https://www.youtube.com/watch?v=PP1xn5wHtxE',
|
||||
'https://twitter.com/carlosmeixidefl/status/1230894146220625933',
|
||||
'https://en.wikipedia.org/wiki/Tordoia',
|
||||
);
|
||||
|
||||
foreach ($infos as $info) {
|
||||
echo $info->title;
|
||||
}
|
||||
```
|
||||
|
||||
## Document
|
||||
|
||||
The document is the object that store the html code of the page. You can use it to extract extra info from the html code:
|
||||
|
||||
```php
|
||||
//Get the document object
|
||||
$document = $info->getDocument();
|
||||
|
||||
$document->link('image_src'); //Returns the href of a <link>
|
||||
$document->getDocument(); //Returns the DOMDocument instance
|
||||
$html = (string) $document; //Returns the html code
|
||||
|
||||
$document->select('.//h1'); //Search
|
||||
```
|
||||
|
||||
You can perform xpath queries in order to select specific elements. A search always return an instance of a `Embed\QueryResult`:
|
||||
|
||||
```php
|
||||
//Search the A elements
|
||||
$result = $document->select('.//a');
|
||||
|
||||
//Filter the results
|
||||
$result->filter(fn ($node) => $node->getAttribute('href'));
|
||||
|
||||
$id = $result->str('id'); //Return the id of the first result as string
|
||||
$text = $result->str(); //Return the content of the first result
|
||||
|
||||
$ids = $result->strAll('id'); //Return an array with the ids of all results as string
|
||||
$texts = $result->strAll(); //Return an array with the content of all results as string
|
||||
|
||||
$tabindex = $result->int('tabindex'); //Return the tabindex attribute of the first result as integer
|
||||
$number = $result->int(); //Return the content of the first result as integer
|
||||
|
||||
$href = $result->url('href'); //Return the href attribute of the first result as url (converts relative urls to absolutes)
|
||||
$url = $result->url(); //Return the content of the first result as url
|
||||
|
||||
$node = $result->node(); //Return the first node found (DOMElement)
|
||||
$nodes = $result->nodes(); //Return all nodes found
|
||||
```
|
||||
|
||||
## Metas
|
||||
|
||||
For convenience, the object `Metas` stores the value of all `<meta>` elements located in the html, so you can get the values easier. The key of every meta is get from the `name`, `property` or `itemprop` attributes and the value is get from `content`.
|
||||
|
||||
```php
|
||||
//Get the Metas object
|
||||
$metas = $info->getMetas();
|
||||
|
||||
$metas->all(); //Return all values
|
||||
$metas->get('og:title'); //Return a key value
|
||||
$metas->str('og:title'); //Return the value as string (remove html tags)
|
||||
$metas->html('og:description'); //Return the value as html
|
||||
$metas->int('og:video:width'); //Return the value as integer
|
||||
$metas->url('og:url'); //Return the value as full url (converts relative urls to absolutes)
|
||||
```
|
||||
|
||||
## OEmbed
|
||||
|
||||
In addition to the html and metas, this library uses [oEmbed](https://oembed.com/) endpoints to get additional data. You can get this data as following:
|
||||
|
||||
```php
|
||||
//Get the oEmbed object
|
||||
$oembed = $info->getOEmbed();
|
||||
|
||||
$oembed->all(); //Return all raw data
|
||||
$oembed->get('title'); //Return a key value
|
||||
$oembed->str('title'); //Return the value as string (remove html tags)
|
||||
$oembed->html('html'); //Return the value as html
|
||||
$oembed->int('width'); //Return the value as integer
|
||||
$oembed->url('url'); //Return the value as full url (converts relative urls to absolutes)
|
||||
```
|
||||
|
||||
Additional oEmbed parameters (like instagrams `hidecaption`) can also be provided:
|
||||
```php
|
||||
$embed = new Embed();
|
||||
|
||||
$result = $embed->get('https://www.instagram.com/p/B_C0wheCa4V/');
|
||||
$result->setSettings([
|
||||
'oembed:query_parameters' => ['hidecaption' => true]
|
||||
]);
|
||||
$oembed = $info->getOEmbed();
|
||||
```
|
||||
|
||||
## LinkedData
|
||||
|
||||
Another API available by default, used to extract info using the [JsonLD](https://www.w3.org/TR/json-ld/) schema.
|
||||
|
||||
```php
|
||||
//Get the linkedData object
|
||||
$ld = $info->getLinkedData();
|
||||
|
||||
$ld->all(); //Return all data
|
||||
$ld->get('name'); //Return a key value
|
||||
$ld->str('name'); //Return the value as string (remove html tags)
|
||||
$ld->html('description'); //Return the value as html
|
||||
$ld->int('width'); //Return the value as integer
|
||||
$ld->url('url'); //Return the value as full url (converts relative urls to absolutes)
|
||||
```
|
||||
|
||||
## Other APIs
|
||||
|
||||
Some sites like Wikipedia or Archive.org provide a custom API that is used to fetch more reliable data. You can get the API object with the method `getApi()` but note that not all results have this method. The Api object has the same methods than oEmbed:
|
||||
|
||||
```php
|
||||
//Get the API object
|
||||
$api = $info->getApi();
|
||||
|
||||
$api->all(); //Return all raw data
|
||||
$api->get('title'); //Return a key value
|
||||
$api->str('title'); //Return the value as string (remove html tags)
|
||||
$api->html('html'); //Return the value as html
|
||||
$api->int('width'); //Return the value as integer
|
||||
$api->url('url'); //Return the value as full url (converts relative urls to absolutes)
|
||||
```
|
||||
|
||||
## Extending Embed
|
||||
|
||||
Depending of your needs, you may want to extend this library with extra features or change the way it makes some operations.
|
||||
|
||||
### PSR
|
||||
|
||||
Embed use some PSR standards to be the most interoperable possible:
|
||||
|
||||
- [PSR-7](https://www.php-fig.org/psr/psr-7/) Standard interfaces to represent http requests, responses and uris
|
||||
- [PSR-17](https://www.php-fig.org/psr/psr-17/) Standard factories to create PSR-7 objects
|
||||
- [PSR-18](https://www.php-fig.org/psr/psr-18/) Standard interface to send a http request and return a response
|
||||
|
||||
Embed comes with a CURL client compatible with PSR-18 but you need to install a PSR-7 / PSR-17 library. [Here you can see a list of popular libraries](https://github.com/middlewares/awesome-psr15-middlewares#psr-7-implementations) and the library can detect automatically 'laminas\diactoros', 'guzzleHttp\psr7', 'slim\psr7', 'nyholm\psr7' and 'sunrise\http' (in this order). If you want to use a different PSR implementation, you can do it in this way:
|
||||
|
||||
```php
|
||||
use Embed\Embed;
|
||||
use Embed\Http\Crawler;
|
||||
|
||||
$client = new CustomHttpClient();
|
||||
$requestFactory = new CustomRequestFactory();
|
||||
$uriFactory = new CustomUriFactory();
|
||||
|
||||
//The Crawler is responsible for perform http queries
|
||||
$crawler = new Crawler($client, $requestFactory, $uriFactory);
|
||||
|
||||
//Create an embed instance passing the Crawler
|
||||
$embed = new Embed($crawler);
|
||||
```
|
||||
|
||||
### Adapters
|
||||
|
||||
There are some sites with special needs: because they provide public APIs that allows to extract more info (like Wikipedia or Archive.org) or because we need to change how to extract the data in this particular site. For all that cases we have the adapters, that are classes extending the default classes to provide extra functionality.
|
||||
|
||||
Before creating an adapter, you need to understand how Embed work: when you execute this code, you get a `Extractor` class
|
||||
|
||||
```php
|
||||
//Get the Extractor with all info
|
||||
$info = $embed->get($url);
|
||||
|
||||
//The extractor have document and oembed:
|
||||
$document = $info->getDocument();
|
||||
$oembed = $info->getOEmbed();
|
||||
```
|
||||
|
||||
The `Extractor` class has many `Detectors`. Each detector is responsible to detect a specific piece of info. For example, there's a detector for the title, other for description, image, code, etc.
|
||||
|
||||
So, an adapter is basically an extractor created specifically for a site. It can contains also custom detectors or apis. If you see the `src/Adapters` folder you can see all adapters.
|
||||
|
||||
If you create an adapter, you need also register to Embed, so it knows in which website needs to use. To do that, there's the `ExtractorFactory` object, that is responsible for instantiate the right extractor for each site.
|
||||
|
||||
```php
|
||||
use Embed\Embed;
|
||||
|
||||
$embed = new Embed();
|
||||
|
||||
$factory = $embed->getExtractorFactory();
|
||||
|
||||
//Use this MySite adapter for mysite.com
|
||||
$factory->addAdapter('mysite.com', MySite::class);
|
||||
|
||||
//Remove the adapter for pinterest.com, so it will use the default extractor
|
||||
$factory->removeAdapter('pinterest.com');
|
||||
|
||||
//Change the default extractor
|
||||
$factory->setDefault(CustomExtractor::class);
|
||||
```
|
||||
|
||||
### Detectors
|
||||
|
||||
Embed comes with several predefined detectors, but you may want to change or add more. Just create a class extending `Embed\Detectors\Detector` class and register it in the extractor factory. For example:
|
||||
|
||||
```php
|
||||
use Embed\Embed;
|
||||
use Embed\Detectors\Detector;
|
||||
|
||||
class Robots extends Detector
|
||||
{
|
||||
public function detect(): ?string
|
||||
{
|
||||
$response = $this->extractor->getResponse();
|
||||
$metas = $this->extractor->getMetas();
|
||||
|
||||
return $response->getHeaderLine('x-robots-tag'),
|
||||
?: $metas->str('robots');
|
||||
}
|
||||
}
|
||||
|
||||
//Register the detector
|
||||
$embed = new Embed();
|
||||
$embed->getExtractorFactory()->addDetector('robots', Robots::class);
|
||||
|
||||
//Use it
|
||||
$info = $embed->get('http://example.com');
|
||||
$robots = $info->robots;
|
||||
```
|
||||
|
||||
### Settings
|
||||
|
||||
If you need to pass settings to the CurlClient to perform http queries:
|
||||
|
||||
```php
|
||||
use Embed\Embed;
|
||||
use Embed\Http\Crawler;
|
||||
use Embed\Http\CurlClient;
|
||||
|
||||
$client = new CurlClient();
|
||||
$client->setSettings([
|
||||
'cookies_path' => $cookies_path,
|
||||
'ignored_errors' => [18],
|
||||
'max_redirs' => 3, // see CURLOPT_MAXREDIRS
|
||||
'connect_timeout' => 2, // see CURLOPT_CONNECTTIMEOUT
|
||||
'timeout' => 2, // see CURLOPT_TIMEOUT
|
||||
'ssl_verify_host' => 2, // see CURLOPT_SSL_VERIFYHOST
|
||||
'ssl_verify_peer' => 1, // see CURLOPT_SSL_VERIFYPEER
|
||||
'follow_location' => true, // see CURLOPT_FOLLOWLOCATION
|
||||
'user_agent' => 'Mozilla', // see CURLOPT_USERAGENT
|
||||
]);
|
||||
|
||||
$embed = new Embed(new Crawler($client));
|
||||
```
|
||||
|
||||
If you need to pass settings to your detectors, you can add settings to the `ExtractorFactory`:
|
||||
|
||||
```php
|
||||
use Embed\Embed;
|
||||
|
||||
$embed = new Embed();
|
||||
$embed->setSettings([
|
||||
'oembed:query_parameters' => [], //Extra parameters send to oembed
|
||||
'twitch:parent' => 'example.com', //Required to embed twitch videos as iframe
|
||||
'facebook:token' => '1234|5678', //Required to embed content from Facebook
|
||||
'instagram:token' => '1234|5678', //Required to embed content from Instagram
|
||||
'twitter:token' => 'asdf', //Improve the data from twitter
|
||||
]);
|
||||
$info = $embed->get($url);
|
||||
```
|
||||
|
||||
Note: The built-in detectors does not require settings. This feature is only for convenience if you create a specific detector that requires settings.
|
||||
|
||||
---
|
||||
|
||||
[ico-version]: https://poser.pugx.org/embed/embed/v/stable
|
||||
[ico-license]: https://poser.pugx.org/embed/embed/license
|
||||
[ico-downloads]: https://poser.pugx.org/embed/embed/downloads
|
||||
[ico-m-downloads]: https://poser.pugx.org/embed/embed/d/monthly
|
||||
|
||||
[link-packagist]: https://packagist.org/packages/embed/embed
|
||||
72
site/plugins/embed/vendor/embed/embed/composer.json
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"name": "embed/embed",
|
||||
"type": "library",
|
||||
"description": "PHP library to retrieve page info using oembed, opengraph, etc",
|
||||
"keywords": [
|
||||
"oembed",
|
||||
"opengraph",
|
||||
"twitter cards",
|
||||
"embed",
|
||||
"embedly"
|
||||
],
|
||||
"homepage": "https://github.com/oscarotero/Embed",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Oscar Otero",
|
||||
"email": "oom@oscarotero.com",
|
||||
"homepage": "http://oscarotero.com",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"email": "oom@oscarotero.com",
|
||||
"issues": "https://github.com/oscarotero/Embed/issues"
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.4|^8",
|
||||
"ext-curl": "*",
|
||||
"ext-dom": "*",
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"composer/ca-bundle": "^1.0",
|
||||
"oscarotero/html-parser": "^0.1.4",
|
||||
"psr/http-message": "^1.0|^2.0",
|
||||
"psr/http-client": "^1.0",
|
||||
"psr/http-factory": "^1.0",
|
||||
"ml/json-ld": "^1.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.0",
|
||||
"friendsofphp/php-cs-fixer": "^2.0",
|
||||
"nyholm/psr7": "^1.2",
|
||||
"oscarotero/php-cs-fixer-config": "^1.0",
|
||||
"brick/varexporter": "^0.3.1",
|
||||
"symfony/css-selector": "^5.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/css-selector": "If you want to get elements using css selectors"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Embed\\": "src"
|
||||
},
|
||||
"files": [
|
||||
"src/functions.php"
|
||||
]
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Embed\\Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"demo": "php -S localhost:8888 demo/index.php",
|
||||
"test": "phpunit",
|
||||
"cs-fix": "php-cs-fixer fix",
|
||||
"update-resources": [
|
||||
"php scripts/update-oembed.php",
|
||||
"php scripts/update-suffix.php"
|
||||
]
|
||||
}
|
||||
}
|
||||
18
site/plugins/embed/vendor/embed/embed/src/Adapters/Archive/Api.php
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Embed\Adapters\Archive;
|
||||
|
||||
use Embed\HttpApiTrait;
|
||||
|
||||
class Api
|
||||
{
|
||||
use HttpApiTrait;
|
||||
|
||||
protected function fetchData(): array
|
||||
{
|
||||
$this->endpoint = $this->extractor->getUri()->withQuery('output=json');
|
||||
|
||||
return $this->fetchJSON($this->endpoint);
|
||||
}
|
||||
}
|
||||
17
site/plugins/embed/vendor/embed/embed/src/Adapters/Archive/Detectors/AuthorName.php
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Embed\Adapters\Archive\Detectors;
|
||||
|
||||
use Embed\Detectors\AuthorName as Detector;
|
||||
|
||||
class AuthorName extends Detector
|
||||
{
|
||||
public function detect(): ?string
|
||||
{
|
||||
$api = $this->extractor->getApi();
|
||||
|
||||
return $api->str('metadata', 'creator')
|
||||
?: parent::detect();
|
||||
}
|
||||
}
|
||||
37
site/plugins/embed/vendor/embed/embed/src/Adapters/Archive/Detectors/Code.php
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Embed\Adapters\Archive\Detectors;
|
||||
|
||||
use Embed\Detectors\Code as Detector;
|
||||
use Embed\EmbedCode;
|
||||
use function Embed\html;
|
||||
use function Embed\matchPath;
|
||||
|
||||
class Code extends Detector
|
||||
{
|
||||
public function detect(): ?EmbedCode
|
||||
{
|
||||
$uri = $this->extractor->getUri();
|
||||
$path = $uri->getPath();
|
||||
|
||||
if (!matchPath('/details/*', $path)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$src = $uri->withPath(str_replace('/details/', '/embed/', $path));
|
||||
$width = 640;
|
||||
$height = 480;
|
||||
|
||||
$html = html('iframe', [
|
||||
'src' => $src,
|
||||
'width' => $width,
|
||||
'height' => $height,
|
||||
'style' => 'border:none',
|
||||
'frameborder' => 0,
|
||||
'allowTransparency' => 'true',
|
||||
]);
|
||||
|
||||
return new EmbedCode($html, $width, $height);
|
||||
}
|
||||
}
|
||||
17
site/plugins/embed/vendor/embed/embed/src/Adapters/Archive/Detectors/Description.php
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Embed\Adapters\Archive\Detectors;
|
||||
|
||||
use Embed\Detectors\Description as Detector;
|
||||
|
||||
class Description extends Detector
|
||||
{
|
||||
public function detect(): ?string
|
||||
{
|
||||
$api = $this->extractor->getApi();
|
||||
|
||||
return $api->str('metadata', 'extract')
|
||||
?: parent::detect();
|
||||
}
|
||||
}
|
||||
14
site/plugins/embed/vendor/embed/embed/src/Adapters/Archive/Detectors/ProviderName.php
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Embed\Adapters\Archive\Detectors;
|
||||
|
||||
use Embed\Detectors\ProviderName as Detector;
|
||||
|
||||
class ProviderName extends Detector
|
||||
{
|
||||
public function detect(): string
|
||||
{
|
||||
return 'Internet Archive';
|
||||
}
|
||||
}
|
||||
20
site/plugins/embed/vendor/embed/embed/src/Adapters/Archive/Detectors/PublishedTime.php
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Embed\Adapters\Archive\Detectors;
|
||||
|
||||
use DateTime;
|
||||
use Embed\Detectors\PublishedTime as Detector;
|
||||
|
||||
class PublishedTime extends Detector
|
||||
{
|
||||
public function detect(): ?DateTime
|
||||
{
|
||||
$api = $this->extractor->getApi();
|
||||
|
||||
return $api->time('metadata', 'publicdate')
|
||||
?: $api->time('metadata', 'addeddate')
|
||||
?: $api->time('metadata', 'date')
|
||||
?: parent::detect();
|
||||
}
|
||||
}
|
||||
17
site/plugins/embed/vendor/embed/embed/src/Adapters/Archive/Detectors/Title.php
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Embed\Adapters\Archive\Detectors;
|
||||
|
||||
use Embed\Detectors\Title as Detector;
|
||||
|
||||
class Title extends Detector
|
||||
{
|
||||
public function detect(): ?string
|
||||
{
|
||||
$api = $this->extractor->getApi();
|
||||
|
||||
return $api->str('metadata', 'title')
|
||||
?: parent::detect();
|
||||
}
|
||||
}
|
||||
30
site/plugins/embed/vendor/embed/embed/src/Adapters/Archive/Extractor.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Embed\Adapters\Archive;
|
||||
|
||||
use Embed\Extractor as Base;
|
||||
|
||||
class Extractor extends Base
|
||||
{
|
||||
private Api $api;
|
||||
|
||||
public function getApi(): Api
|
||||
{
|
||||
return $this->api;
|
||||
}
|
||||
|
||||
public function createCustomDetectors(): array
|
||||
{
|
||||
$this->api = new Api($this);
|
||||
|
||||
return [
|
||||
'title' => new Detectors\Title($this),
|
||||
'description' => new Detectors\Description($this),
|
||||
'code' => new Detectors\Code($this),
|
||||
'authorName' => new Detectors\AuthorName($this),
|
||||
'providerName' => new Detectors\ProviderName($this),
|
||||
'publishedTime' => new Detectors\PublishedTime($this),
|
||||
];
|
||||
}
|
||||
}
|
||||
14
site/plugins/embed/vendor/embed/embed/src/Adapters/Bandcamp/Detectors/ProviderName.php
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Embed\Adapters\Bandcamp\Detectors;
|
||||
|
||||
use Embed\Detectors\ProviderName as Detector;
|
||||
|
||||
class ProviderName extends Detector
|
||||
{
|
||||
public function detect(): string
|
||||
{
|
||||
return 'Bandcamp';
|
||||
}
|
||||
}
|
||||
16
site/plugins/embed/vendor/embed/embed/src/Adapters/Bandcamp/Extractor.php
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Embed\Adapters\Bandcamp;
|
||||
|
||||
use Embed\Extractor as Base;
|
||||
|
||||
class Extractor extends Base
|
||||
{
|
||||
public function createCustomDetectors(): array
|
||||
{
|
||||
return [
|
||||
'providerName' => new Detectors\ProviderName($this),
|
||||
];
|
||||
}
|
||||
}
|
||||
41
site/plugins/embed/vendor/embed/embed/src/Adapters/CadenaSer/Detectors/Code.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Embed\Adapters\CadenaSer\Detectors;
|
||||
|
||||
use function Embed\cleanPath;
|
||||
use Embed\Detectors\Code as Detector;
|
||||
use Embed\EmbedCode;
|
||||
use function Embed\html;
|
||||
use function Embed\matchPath;
|
||||
|
||||
class Code extends Detector
|
||||
{
|
||||
public function detect(): ?EmbedCode
|
||||
{
|
||||
return parent::detect()
|
||||
?: $this->fallback();
|
||||
}
|
||||
|
||||
private function fallback(): ?EmbedCode
|
||||
{
|
||||
$uri = $this->extractor->getUri();
|
||||
|
||||
if (!matchPath('/audio/*', $uri->getPath())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$path = cleanPath('/widget/'.$uri->getPath());
|
||||
$src = $uri->withPath($path);
|
||||
|
||||
$html = html('iframe', [
|
||||
'src' => $src,
|
||||
'frameborder' => 0,
|
||||
'width' => '100%',
|
||||
'height' => '360',
|
||||
'allowTransparency' => 'true',
|
||||
]);
|
||||
|
||||
return new EmbedCode($html, null, 360);
|
||||
}
|
||||
}
|
||||
16
site/plugins/embed/vendor/embed/embed/src/Adapters/CadenaSer/Extractor.php
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Embed\Adapters\CadenaSer;
|
||||
|
||||
use Embed\Extractor as Base;
|
||||
|
||||
class Extractor extends Base
|
||||
{
|
||||
public function createCustomDetectors(): array
|
||||
{
|
||||
return [
|
||||
'code' => new Detectors\Code($this),
|
||||
];
|
||||
}
|
||||
}
|
||||
21
site/plugins/embed/vendor/embed/embed/src/Adapters/Facebook/Detectors/Title.php
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Embed\Adapters\Facebook\Detectors;
|
||||
|
||||
use Embed\Detectors\Title as Detector;
|
||||
|
||||
class Title extends Detector
|
||||
{
|
||||
/**
|
||||
* Do not use og:title and twitter:title
|
||||
*/
|
||||
public function detect(): ?string
|
||||
{
|
||||
$document = $this->extractor->getDocument();
|
||||
$oembed = $this->extractor->getOEmbed();
|
||||
|
||||
return $oembed->str('title')
|
||||
?: $document->select('.//head/title')->str();
|
||||
}
|
||||
}
|
||||
18
site/plugins/embed/vendor/embed/embed/src/Adapters/Facebook/Extractor.php
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Embed\Adapters\Facebook;
|
||||
|
||||
use Embed\Extractor as Base;
|
||||
|
||||
class Extractor extends Base
|
||||
{
|
||||
public function createCustomDetectors(): array
|
||||
{
|
||||
$this->oembed = new OEmbed($this);
|
||||
|
||||
return [
|
||||
'title' => new Detectors\Title($this),
|
||||
];
|
||||
}
|
||||
}
|
||||
80
site/plugins/embed/vendor/embed/embed/src/Adapters/Facebook/OEmbed.php
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Embed\Adapters\Facebook;
|
||||
|
||||
use Embed\OEmbed as Base;
|
||||
use Psr\Http\Message\UriInterface;
|
||||
|
||||
class OEmbed extends Base
|
||||
{
|
||||
const ENDPOINT_PAGE = 'https://graph.facebook.com/v11.0/oembed_page';
|
||||
const ENDPOINT_POST = 'https://graph.facebook.com/v11.0/oembed_post';
|
||||
const ENDPOINT_VIDEO = 'https://graph.facebook.com/v11.0/oembed_video';
|
||||
|
||||
protected function detectEndpoint(): ?UriInterface
|
||||
{
|
||||
$token = $this->extractor->getSetting('facebook:token');
|
||||
|
||||
if (!$token) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$uri = $this->extractor->getUri();
|
||||
if (strpos($uri->getPath(), 'login') !== false) {
|
||||
parse_str($uri->getQuery(), $params);
|
||||
if (!empty($params['next'])) {
|
||||
$uri = $this->extractor->getCrawler()->createUri($params['next']);
|
||||
}
|
||||
}
|
||||
$queryParameters = $this->getOembedQueryParameters((string) $uri);
|
||||
$queryParameters['access_token'] = $token;
|
||||
|
||||
return $this->extractor->getCrawler()
|
||||
->createUri($this->getEndpointByPath($uri->getPath()))
|
||||
->withQuery(http_build_query($queryParameters));
|
||||
}
|
||||
|
||||
private function getEndpointByPath(string $path): string
|
||||
{
|
||||
/* Videos
|
||||
https://www.facebook.com/{page-name}/videos/{video-id}/
|
||||
https://www.facebook.com/{username}/videos/{video-id}/
|
||||
https://www.facebook.com/video.php?id={video-id}
|
||||
https://www.facebook.com/video.php?v={video-id}
|
||||
*/
|
||||
if (strpos($path, '/video.php') === 0
|
||||
|| strpos($path, '/videos/') !== false
|
||||
) {
|
||||
return self::ENDPOINT_VIDEO;
|
||||
}
|
||||
|
||||
/* Posts
|
||||
https://www.facebook.com/{page-name}/posts/{post-id}
|
||||
https://www.facebook.com/{username}/posts/{post-id}
|
||||
https://www.facebook.com/{username}/activity/{activity-id}
|
||||
https://www.facebook.com/photo.php?fbid={photo-id}
|
||||
https://www.facebook.com/photos/{photo-id}
|
||||
https://www.facebook.com/permalink.php?story_fbid={post-id}
|
||||
https://www.facebook.com/media/set?set={set-id}
|
||||
https://www.facebook.com/questions/{question-id}
|
||||
https://www.facebook.com/notes/{username}/{note-url}/{note-id}
|
||||
|
||||
Not in the facebook docs:
|
||||
https://www.facebook.com/{page-name}/photos/{post-id}/{photo-id}
|
||||
*/
|
||||
if (strpos($path, '/photo.php') === 0
|
||||
|| strpos($path, '/photos/') !== false
|
||||
|| strpos($path, '/permalink.php') === 0
|
||||
|| strpos($path, '/media/') === 0
|
||||
|| strpos($path, '/questions/') === 0
|
||||
|| strpos($path, '/notes/') === 0
|
||||
|| strpos($path, '/posts/') !== false
|
||||
|| strpos($path, '/activity/') !== false
|
||||
) {
|
||||
return self::ENDPOINT_POST;
|
||||
}
|
||||
|
||||
return self::ENDPOINT_PAGE;
|
||||
}
|
||||
}
|
||||
44
site/plugins/embed/vendor/embed/embed/src/Adapters/Flickr/Detectors/Code.php
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Embed\Adapters\Flickr\Detectors;
|
||||
|
||||
use function Embed\cleanPath;
|
||||
use Embed\Detectors\Code as Detector;
|
||||
use Embed\EmbedCode;
|
||||
use function Embed\html;
|
||||
use function Embed\matchPath;
|
||||
|
||||
class Code extends Detector
|
||||
{
|
||||
public function detect(): ?EmbedCode
|
||||
{
|
||||
return parent::detect()
|
||||
?: $this->fallback();
|
||||
}
|
||||
|
||||
private function fallback(): ?EmbedCode
|
||||
{
|
||||
$uri = $this->extractor->getUri();
|
||||
|
||||
if (!matchPath('/photos/*', $uri->getPath())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$path = cleanPath($uri->getPath().'/player');
|
||||
$src = $uri->withPath($path);
|
||||
$width = 640;
|
||||
$height = 425;
|
||||
|
||||
$html = html('iframe', [
|
||||
'src' => $src,
|
||||
'width' => $width,
|
||||
'height' => $height,
|
||||
'style' => 'border:none',
|
||||
'frameborder' => 0,
|
||||
'allowTransparency' => 'true',
|
||||
]);
|
||||
|
||||
return new EmbedCode($html, $width, $height);
|
||||
}
|
||||
}
|
||||
16
site/plugins/embed/vendor/embed/embed/src/Adapters/Flickr/Extractor.php
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Embed\Adapters\Flickr;
|
||||
|
||||
use Embed\Extractor as Base;
|
||||
|
||||
class Extractor extends Base
|
||||
{
|
||||
public function createCustomDetectors(): array
|
||||
{
|
||||
return [
|
||||
'code' => new Detectors\Code($this),
|
||||
];
|
||||
}
|
||||
}
|
||||
19
site/plugins/embed/vendor/embed/embed/src/Adapters/Gist/Api.php
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Embed\Adapters\Gist;
|
||||
|
||||
use Embed\HttpApiTrait;
|
||||
|
||||
class Api
|
||||
{
|
||||
use HttpApiTrait;
|
||||
|
||||
protected function fetchData(): array
|
||||
{
|
||||
$uri = $this->extractor->getUri();
|
||||
$this->endpoint = $uri->withPath($uri->getPath().'.json');
|
||||
|
||||
return $this->fetchJSON($this->endpoint);
|
||||
}
|
||||
}
|
||||
17
site/plugins/embed/vendor/embed/embed/src/Adapters/Gist/Detectors/AuthorName.php
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Embed\Adapters\Gist\Detectors;
|
||||
|
||||
use Embed\Detectors\AuthorName as Detector;
|
||||
|
||||
class AuthorName extends Detector
|
||||
{
|
||||
public function detect(): ?string
|
||||
{
|
||||
$api = $this->extractor->getApi();
|
||||
|
||||
return $api->str('owner')
|
||||
?: parent::detect();
|
||||
}
|
||||
}
|
||||
22
site/plugins/embed/vendor/embed/embed/src/Adapters/Gist/Detectors/AuthorUrl.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Embed\Adapters\Gist\Detectors;
|
||||
|
||||
use Embed\Detectors\AuthorUrl as Detector;
|
||||
use Psr\Http\Message\UriInterface;
|
||||
|
||||
class AuthorUrl extends Detector
|
||||
{
|
||||
public function detect(): ?UriInterface
|
||||
{
|
||||
$api = $this->extractor->getApi();
|
||||
$owner = $api->str('owner');
|
||||
|
||||
if ($owner) {
|
||||
return $this->extractor->getCrawler()->createUri("https://github.com/{$owner}");
|
||||
}
|
||||
|
||||
return parent::detect();
|
||||
}
|
||||
}
|
||||
31
site/plugins/embed/vendor/embed/embed/src/Adapters/Gist/Detectors/Code.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Embed\Adapters\Gist\Detectors;
|
||||
|
||||
use Embed\Detectors\Code as Detector;
|
||||
use Embed\EmbedCode;
|
||||
use function Embed\html;
|
||||
|
||||
class Code extends Detector
|
||||
{
|
||||
public function detect(): ?EmbedCode
|
||||
{
|
||||
return parent::detect()
|
||||
?: $this->fallback();
|
||||
}
|
||||
|
||||
private function fallback(): ?EmbedCode
|
||||
{
|
||||
$api = $this->extractor->getApi();
|
||||
|
||||
$code = $api->html('div');
|
||||
$stylesheet = $api->str('stylesheet');
|
||||
|
||||
if ($code && $stylesheet) {
|
||||
return new EmbedCode(
|
||||
html('link', ['rel' => 'stylesheet', 'href' => $stylesheet]).$code
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
18
site/plugins/embed/vendor/embed/embed/src/Adapters/Gist/Detectors/PublishedTime.php
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Embed\Adapters\Gist\Detectors;
|
||||
|
||||
use DateTime;
|
||||
use Embed\Detectors\PublishedTime as Detector;
|
||||
|
||||
class PublishedTime extends Detector
|
||||
{
|
||||
public function detect(): ?DateTime
|
||||
{
|
||||
$api = $this->extractor->getApi();
|
||||
|
||||
return $api->time('created_at')
|
||||
?: parent::detect();
|
||||
}
|
||||
}
|
||||
28
site/plugins/embed/vendor/embed/embed/src/Adapters/Gist/Extractor.php
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Embed\Adapters\Gist;
|
||||
|
||||
use Embed\Extractor as Base;
|
||||
|
||||
class Extractor extends Base
|
||||
{
|
||||
private Api $api;
|
||||
|
||||
public function getApi(): Api
|
||||
{
|
||||
return $this->api;
|
||||
}
|
||||
|
||||
public function createCustomDetectors(): array
|
||||
{
|
||||
$this->api = new Api($this);
|
||||
|
||||
return [
|
||||
'authorName' => new Detectors\AuthorName($this),
|
||||
'authorUrl' => new Detectors\AuthorUrl($this),
|
||||
'publishedTime' => new Detectors\PublishedTime($this),
|
||||
'code' => new Detectors\Code($this),
|
||||
];
|
||||
}
|
||||
}
|
||||
47
site/plugins/embed/vendor/embed/embed/src/Adapters/Github/Detectors/Code.php
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Embed\Adapters\Github\Detectors;
|
||||
|
||||
use Embed\Detectors\Code as Detector;
|
||||
use Embed\EmbedCode;
|
||||
use function Embed\html;
|
||||
use function Embed\matchPath;
|
||||
|
||||
class Code extends Detector
|
||||
{
|
||||
public function detect(): ?EmbedCode
|
||||
{
|
||||
return parent::detect()
|
||||
?: $this->fallback();
|
||||
}
|
||||
|
||||
private function fallback(): ?EmbedCode
|
||||
{
|
||||
$uri = $this->extractor->getUri();
|
||||
$path = $uri->getPath();
|
||||
|
||||
if (!matchPath('/*/*/blob/*', $path)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$dirs = explode('/', $path);
|
||||
|
||||
$username = $dirs[1];
|
||||
$repo = $dirs[2];
|
||||
$ref = $dirs[4];
|
||||
$file = implode('/', array_slice($dirs, 5));
|
||||
$extension = pathinfo($file, PATHINFO_EXTENSION);
|
||||
|
||||
switch ($extension) {
|
||||
case 'geojson':
|
||||
//https://help.github.com/articles/mapping-geojson-files-on-github/#embedding-your-map-elsewhere
|
||||
return new EmbedCode(html('script', ['src' => "https://embed.githubusercontent.com/view/geojson/{$username}/{$repo}/{$ref}/{$file}"]));
|
||||
case 'stl':
|
||||
//https://help.github.com/articles/3d-file-viewer/#embedding-your-model-elsewhere
|
||||
return new EmbedCode(html('script', ['src' => "https://embed.githubusercontent.com/view/3d/{$username}/{$repo}/{$ref}/{$file}"]));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
16
site/plugins/embed/vendor/embed/embed/src/Adapters/Github/Extractor.php
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Embed\Adapters\Github;
|
||||
|
||||
use Embed\Extractor as Base;
|
||||
|
||||
class Extractor extends Base
|
||||
{
|
||||
public function createCustomDetectors(): array
|
||||
{
|
||||
return [
|
||||
'code' => new Detectors\Code($this),
|
||||
];
|
||||
}
|
||||
}
|
||||
31
site/plugins/embed/vendor/embed/embed/src/Adapters/Ideone/Detectors/Code.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Embed\Adapters\Ideone\Detectors;
|
||||
|
||||
use Embed\Detectors\Code as Detector;
|
||||
use Embed\EmbedCode;
|
||||
use function Embed\html;
|
||||
|
||||
class Code extends Detector
|
||||
{
|
||||
public function detect(): ?EmbedCode
|
||||
{
|
||||
return parent::detect()
|
||||
?: $this->fallback();
|
||||
}
|
||||
|
||||
private function fallback(): ?EmbedCode
|
||||
{
|
||||
$uri = $this->extractor->getUri();
|
||||
$id = explode('/', $uri->getPath())[1];
|
||||
|
||||
if (empty($id)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new EmbedCode(
|
||||
html('script', ['src' => "https://ideone.com/e.js/{$id}"])
|
||||
);
|
||||
}
|
||||
}
|
||||
16
site/plugins/embed/vendor/embed/embed/src/Adapters/Ideone/Extractor.php
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Embed\Adapters\Ideone;
|
||||
|
||||
use Embed\Extractor as Base;
|
||||
|
||||
class Extractor extends Base
|
||||
{
|
||||
public function createCustomDetectors(): array
|
||||
{
|
||||
return [
|
||||
'code' => new Detectors\Code($this),
|
||||
];
|
||||
}
|
||||
}
|
||||