Initial commit
This commit is contained in:
commit
65e0da7e11
1397 changed files with 596542 additions and 0 deletions
108
site/OFF_plugins/embed/CHANGELOG.md
Normal file
108
site/OFF_plugins/embed/CHANGELOG.md
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
# Changelog
|
||||
|
||||
## [3.0.2](https://github.com/distantnative/embed/releases/tag/3.0.2) (2017-06-18)
|
||||
:bug: Javascript on IE: workaround for this.remove()
|
||||
|
||||
## [3.0.1](https://github.com/distantnative/embed/releases/tag/3.0.1) (2017-03-31)
|
||||
:balloon: Safer handling of thumb if directory is not writable
|
||||
:balloon: Handle YouTube playlist index URL parameter
|
||||
|
||||
## [3.0.0](https://github.com/distantnative/embed/releases/tag/3.0.0) (2017-03-22)
|
||||
- Renamed: Plugin is now called `embed`
|
||||
- Improved: simplified CSS classes to `embed` root
|
||||
- Fixed: Vimeo play button support
|
||||
- Updated: Embed library to v3.0.5
|
||||
|
||||
## [2.4.0](https://github.com/distantnative/embed/releases/tag/2.4.0) (2016-09-04)
|
||||
- Improved: LazyVideo support and display for certain providers
|
||||
- Improved: Smarter sizing of LazyVideo play overlay
|
||||
- Improved: Preview label hidden in panel field
|
||||
- Improved: Panel field cheatsheet hidden by default, better cursor on hover
|
||||
- Improved: Removed duplicate assets for panel field
|
||||
- Improved: Updated vendor lib Embed to version 2.7
|
||||
- Improved: Internal file structure
|
||||
- Improved: Clearer namespacing, separation between plugin and lib
|
||||
- Fixed: Thumb caching for thumbs with url parameter
|
||||
- Fixed: Correct permissions for thumbs directories
|
||||
|
||||
## [2.3.2](https://github.com/distantnative/embed/releases/tag/2.3.2) (2016-09-03)
|
||||
- Fixed: YouTube timecode URL parameter 't' did not work
|
||||
|
||||
## [2.3.1](https://github.com/distantnative/embed/releases/tag/2.3.1) (2016-09-03)
|
||||
- Fixed: Adding a custom CSS class via the Kirbytag was not working
|
||||
|
||||
## [2.3.0](https://github.com/distantnative/embed/releases/tag/2.3.0) (2016-09-03)
|
||||
- Feature: Support various Vimeo url parameters
|
||||
- Improved: Getting and setting custom url parameters
|
||||
- Improved: Cheatsheet for the panel field is active by default
|
||||
- Fixed: Global helper function was not working
|
||||
|
||||
## [2.2.0](https://github.com/distantnative/embed/releases/tag/2.2.0) (2016-06-10)
|
||||
- Feature: Support for Spotify theme and view parameters
|
||||
- Feature: Set Spotify width and height through url parameters
|
||||
- Feature: Parameter cheatsheet for the panel field
|
||||
- Improved: Updated Embed vendor library
|
||||
- Improved: More specific API calls for the panel field
|
||||
- Fixed: Embeds now respect a max-width of 100%
|
||||
- Fixed: More precise code regular expressions
|
||||
- Docs: Removed example images from repository
|
||||
|
||||
## [2.1.0](https://github.com/distantnative/embed/releases/tag/2.1.0) (2016-05-10)
|
||||
- Lots of panel field improvements:
|
||||
- Feature: Section with information (e.g. title, author, source)
|
||||
- Feature: Options to disable preview and information section
|
||||
- Feature: Option to set a maximum height for the preview section
|
||||
- Improved: Loading indicator for the preview section
|
||||
- Improved: Lots of smaller styling and script improvements
|
||||
- Fixed: ensured lazy loading of videos in the panel
|
||||
- Fixed: border colors on input focus
|
||||
- Moved field css assets to scss (using gulp)
|
||||
- Feature: Config options for provider API keys (`plugin.oembed.providers.facebook.key`, `plugin.oembed.providers.google.key` and `plugin.oembed.providers.soundcloud.key`)
|
||||
- Feature: Config option to enforce W3C validity (`plugin.oembed.w3c.enforce`)
|
||||
- Improved: Title for lazy loading video thumbs
|
||||
- Improved: Fallback for link type with no embed code
|
||||
- Feature: Plugin strings are now translatable (English & German already included)
|
||||
- Improved: Safer autoloading of plugin components
|
||||
- Fixed: styles for specific providers (e.g. Flickr, phorkie, Meetup)
|
||||
- Fixed: error message if information is loaded, but no embed code available
|
||||
- Fixed: error display for videos with no embed code
|
||||
|
||||
|
||||
## [2.0.2](https://github.com/distantnative/embed/releases/tag/2.0.2) (2016-05-08)
|
||||
- Fixed: YouTube timecode handling
|
||||
- Fixed: more secure use of `$kirby`
|
||||
|
||||
|
||||
## [2.0.1](https://github.com/distantnative/embed/releases/tag/2.0.1) (2016-05-07)
|
||||
- Panel field: changed icon click behavior (opens now url in new tab)
|
||||
- Fixed: access to thumb location
|
||||
- Fixed: Included vendor files instead using git submodules
|
||||
|
||||
|
||||
## [2.0.0](https://github.com/distantnative/embed/releases/tag/2.0.0) (2016-05-06)
|
||||
- Requires Kirby 2.3.0
|
||||
- Complete rewrite of PHP, CSS, JS
|
||||
- All new panel field with great instant preview
|
||||
- Works now with a lot more media (Spotify, pastebin, issu among others)
|
||||
- Supports YouTube playlists and timecodes
|
||||
- More reliable caching
|
||||
- More consistent options
|
||||
- Advanced acces to addtional information of the embedded media
|
||||
- Using new library for collecting embed information ([oscarotero/Embed](https://github.com/oscarotero/Embed))
|
||||
|
||||
|
||||
## [1.0.0](https://github.com/distantnative/embed/releases/tag/v1.0) (2015-06-19)
|
||||
- Restructured plugin files and renamed repository to oembed
|
||||
- Updated Essence library to v3
|
||||
- Added custom class option and default container classes
|
||||
- Added jsapi option
|
||||
- Improved frameborder handling and validation
|
||||
- Better thumb caching and low res fallback
|
||||
- Better cache and thumb dir handling
|
||||
- Autoplay only on lazyload or with autoplay option
|
||||
- Enhanced CSS browser support
|
||||
|
||||
|
||||
## [0.7.0](https://github.com/distantnative/embed/releases/tag/v0.7) (2015-05-27)
|
||||
- File structure of plugin repository changed
|
||||
- Improved HTML validation of plugin output
|
||||
244
site/OFF_plugins/embed/README.md
Normal file
244
site/OFF_plugins/embed/README.md
Normal file
|
|
@ -0,0 +1,244 @@
|
|||

|
||||
|
||||
[](https://github.com/distantnative/embed/releases)
|
||||
[](https://github.com/distantnative/embed/issues) 
|
||||
|
||||
Embed extends [Kirby](http://getkirby.com) with some extensive media embed functionalities. It enables Kirby to display embeds from various media sites (e.g. YouTube, Vimeo, Soundcloud, Instagram etc.) by only providing the URL to the medium. It is powered by the [oscarotero/Embed](https://github.com/oscarotero/Embed) library.
|
||||
|
||||
|
||||
## Table of Contents
|
||||
1. [Requirements](#Requirements)
|
||||
2. [Installation & Update](#Installation)
|
||||
3. [Usage](#Usage)
|
||||
4. [Options](#Options)
|
||||
5. [Panel field](#Field)
|
||||
6. [Advanced](#Advanced)
|
||||
7. [Styles, Scripts & Translations](#StylesScripts)
|
||||
8. [Examples](#Examples)
|
||||
9. [Help & Improve](#Help)
|
||||
10. [Version History](#VersionHistory)
|
||||
|
||||
## Requirements <a id="Requirements"></a>
|
||||
Kirby CMS 2.3.0+ and PHP 5.5+.
|
||||
|
||||
|
||||
## Installation & Update <a id="Installation"></a>
|
||||
1. Download [Embed](https://github.com/distantnative/embed/zipball/master/) and add the files to `site/plugins/embed/`
|
||||
2. Add the necessary styles by including the following in the header:
|
||||
```php
|
||||
<?= css('assets/plugins/embed/css/embed.css') ?>
|
||||
```
|
||||
|
||||
#### With video lazyload [option](#Options) (activated by default, include unless deactived)
|
||||
3. Add the necessary script by including the following right before the `</body>` tag:
|
||||
```php
|
||||
<?= js('assets/plugins/embed/js/embed.js') ?>
|
||||
```
|
||||
|
||||
#### With the [Kirby CLI](https://github.com/getkirby/cli)
|
||||
```
|
||||
kirby plugin:install distantnative/embed
|
||||
```
|
||||
And add CSS and JS as outlined above.
|
||||
|
||||
|
||||
|
||||
## Usage <a id="Usage"></a>
|
||||
**As field method in templates:**
|
||||
Use the method on fields that contain a url that points to a supported medium (e.g. YouTube, Vimeo, Twitter, Instagram, Spotify etc.):
|
||||
```php
|
||||
<?= $page->tweet()->embed(); ?>
|
||||
```
|
||||
|
||||
You can use any text field containing a valid URL, but you might want to use the designated [Embed panel field](#Field).
|
||||
|
||||
**As Kirbytext tag:**
|
||||
```
|
||||
You'll be given love. You'll be taken care of. You'll be given love. You have to trust it. Maybe not from the sources. You have poured yours. Maybe not from the directions. You are staring at.
|
||||
|
||||
(embed: https://vimeo.com/43444347)
|
||||
|
||||
Twist your head around. It's all around you. All is full of love. All around you. All is full of love. You just ain't receiving. All is full of love. Your phone is off the hook. All is full of love. Your doors are all shut. All is full of love.
|
||||
```
|
||||
|
||||
**As global PHP helper function:**
|
||||
```php
|
||||
<?= embed('https://www.youtube.com/watch?v=m2ua3O_fdCY') ?>
|
||||
```
|
||||
|
||||
|
||||
## Options <a id="Options"></a>
|
||||
|
||||
#### Per embed
|
||||
You can set the following options on each embed to apply:
|
||||
|
||||
```php
|
||||
// with the field method
|
||||
<?= $page->featured_video()->embed([
|
||||
'lazyvideo' => true
|
||||
]) ?>
|
||||
|
||||
// with the Kirbytext tag
|
||||
(embed: https://www.youtube.com/watch?v=IlV7RhT6zHs lazyvideo: true)
|
||||
```
|
||||
|
||||
| Option | Values | Description |
|
||||
|-------------|----------------|-------------------------------------------|
|
||||
| `class` | (string) | Class to be added to the embed wrapper |
|
||||
| `thumb` | (string) | Custom thumbnail (URL) |
|
||||
| `autoplay` | `true`/`false` | Starts the embedded video automatically |
|
||||
| `lazyvideo` | `true`/`false` | Lazyload the embedded video |
|
||||
| `jsapi` | `true`/`false` | Activates the JS API of certain providers |
|
||||
|
||||
|
||||
#### Global
|
||||
You can set the following options in your `site/config/config.php` to generally apply to all embeds:
|
||||
|
||||
```php
|
||||
c::set('plugin.embed.video.autoplay', false);
|
||||
|
||||
c::set('plugin.embed.video.lazyload', true);
|
||||
c::set('plugin.embed.video.lazyload.btn', 'assets/plugins/embed/images/play.png');
|
||||
|
||||
c::set('plugin.embed.caching', true);
|
||||
c::set('plugin.embed.caching.duration', 24); // in hours
|
||||
|
||||
c::set('plugin.embed.w3c.enforce', false);
|
||||
|
||||
c::set('plugin.embed.providers.jsapi', false);
|
||||
c::set('plugin.embed.providers.google.key', null);
|
||||
c::set('plugin.embed.providers.soundcloud.key', null):
|
||||
```
|
||||
|
||||
#### URL parameters
|
||||
Embed supports various URL parameters of provider that usually get lost during the embed call. To see which parameters are supported, please use the panel field and switch on the cheatsheet option.
|
||||
|
||||
|
||||
## Panel field <a id="Field"></a>
|
||||
Embed also includes its own panel field which provides a preview of the embedded medium right inside the panel:
|
||||
|
||||
```
|
||||
// in your blueprint
|
||||
…
|
||||
fields:
|
||||
…
|
||||
featured_video:
|
||||
label: Featured video
|
||||
type: embed
|
||||
```
|
||||
|
||||
With its additional options you can also disable the preview section, the information section as well as the cheatsheet or set a max-height for the preview:
|
||||
```
|
||||
fields:
|
||||
…
|
||||
featured_video:
|
||||
label: Featured video
|
||||
type: embed
|
||||
preview: false
|
||||
info: false
|
||||
cheatsheet: false
|
||||
height: 250px
|
||||
```
|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
## Advanced <a id="Advanced"></a>
|
||||
Embed does not only provide you an easy way to output the embed code, but also gives you access to a whole array of additional information provided by the [oscarotero/Embed](https://github.com/oscarotero/Embed) library.
|
||||
|
||||
```php
|
||||
// instead of echoing the field method, use it for further details:
|
||||
$page->video()->embed()->title()
|
||||
|
||||
$info = $page->video()->embed();
|
||||
echo $info->description();
|
||||
echo $info->authorName();
|
||||
```
|
||||
|
||||
You can find a full overview of what information can be accessed in the documentation of the [oscarotero/Embed](https://github.com/oscarotero/Embed) library or also just [test your media URL](http://oscarotero.com/embed2/demo) and see what information is available.
|
||||
|
||||
|
||||
## Styles, Scripts & Translations <a id="StylesScripts"></a>
|
||||
Embed comes with very minimal styles, mainly for embedded videos and only a small script necessary when lazyloading videos (activated by default):
|
||||
|
||||
```php
|
||||
// Include styles
|
||||
<?= css('assets/plugins/embed/css/embed.css') ?>
|
||||
|
||||
// Include script
|
||||
<?= js('assets/plugins/embed/js/embed.js') ?>
|
||||
```
|
||||
|
||||
If you want to further customize and work with the embedded medium. The following CSS classes are applied to the main wrapper:
|
||||
```
|
||||
.embed
|
||||
.embed--{TYPE} // e.g. video, rich
|
||||
.embed--{PROVIDER} // e.g. YouTube, Vimeo
|
||||
|
||||
.embed__thumb
|
||||
.embed__thumb > img
|
||||
```
|
||||
|
||||
You can also translate the strings used by Embed. Translations for English and German are already included. To find out what keys to use, check out the [English translation file](translations/en.php).
|
||||
|
||||
|
||||
## Examples <a id="Examples"></a>
|
||||
#### Blog: Featured Embed
|
||||
```
|
||||
// site/blueprints/article.yml
|
||||
…
|
||||
fields:
|
||||
…
|
||||
cover:
|
||||
Cover photo
|
||||
type: image
|
||||
featured:
|
||||
label: Featured embed (instead of cover photo)
|
||||
type: embed
|
||||
```
|
||||
|
||||
```php
|
||||
// site/snippets/article.php
|
||||
<article>
|
||||
<aside class="entry-meta">...</aside>
|
||||
<div class="entry-main">
|
||||
<?php if($page->featured()->isNotEmpty()): ?>
|
||||
<figure class="entry-cover">
|
||||
<?= $page->featured()->embed() ?>
|
||||
</figure>
|
||||
<?php elseif($page->cover()->isNotEmpty()) : ?>
|
||||
<figure class="entry-cover">
|
||||
<?= $page->cover() ?>
|
||||
</figure>
|
||||
<?php endif; ?>
|
||||
<div class="entry-content"><?= $page->text()->kt() ?></div>
|
||||
</div>
|
||||
</article>
|
||||
```
|
||||
|
||||
## Screenshots
|
||||
**Video from Vimeo:**
|
||||

|
||||
|
||||
**Tweet from Twitter:**
|
||||

|
||||
|
||||
**Player from Spotify:**
|
||||

|
||||
|
||||
|
||||
## Help & Improve <a id="Help"></a>
|
||||
*If you have any suggestions for further configuration options, [please let me know](https://github.com/distantnative/embed/issues/new).*
|
||||
|
||||
|
||||
## Version history <a id="VersionHistory"></a>
|
||||
You can find a more or less complete version history in the [changelog](CHANGELOG.md).
|
||||
|
||||
|
||||
## License
|
||||
[MIT License](http://www.opensource.org/licenses/mit-license.php)
|
||||
|
||||
|
||||
## Author
|
||||
Nico Hoffmann - <https://nhoffmann.com>
|
||||
1
site/OFF_plugins/embed/assets/css/embed.css
Normal file
1
site/OFF_plugins/embed/assets/css/embed.css
Normal file
|
|
@ -0,0 +1 @@
|
|||
.embed,.embed iframe,.embed img,.embed object{max-width:100%}.embed{position:relative;margin:0;padding:0}.embed img{display:block;height:auto}.embed--video iframe,.embed--video object,.embed__thumb{top:0;left:0;width:100%;height:100%;position:absolute}.embed--video{background-color:#ddd;overflow:hidden}.embed--error{font-size:.8em}.embed__thumb{background-repeat:no-repeat;background-position:center center;background-size:cover;cursor:pointer}.embed__thumb>img{position:absolute;top:50%;left:50%;width:25%;min-width:75px;max-width:175px;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);-webkit-transition:opacity .3s ease-in-out;transition:opacity .3s ease-in-out;opacity:.65}.embed__thumb:hover>img{opacity:1}
|
||||
BIN
site/OFF_plugins/embed/assets/images/play.png
Normal file
BIN
site/OFF_plugins/embed/assets/images/play.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.6 KiB |
1
site/OFF_plugins/embed/assets/js/embed.js
Normal file
1
site/OFF_plugins/embed/assets/js/embed.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
var pluginEmbedLoadLazyVideo=function(){var e=this.parentNode,d=e.children[0];d.src=d.dataset.src,e.removeChild(this)};document.addEventListener("DOMContentLoaded",function(e){for(var d=document.getElementsByClassName("embed__thumb"),t=0;t<d.length;t++)d[t].addEventListener("click",pluginEmbedLoadLazyVideo,!1)});
|
||||
14
site/OFF_plugins/embed/assets/js/src/embed.js
Normal file
14
site/OFF_plugins/embed/assets/js/src/embed.js
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
var pluginEmbedLoadLazyVideo = function() {
|
||||
var wrapper = this.parentNode;
|
||||
var embed = wrapper.children[0];
|
||||
embed.src = embed.dataset.src;
|
||||
wrapper.removeChild(this);
|
||||
};
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function(event) {
|
||||
var thumb = document.getElementsByClassName('embed__thumb');
|
||||
|
||||
for (var i = 0; i < thumb.length; i++) {
|
||||
thumb[i].addEventListener('click', pluginEmbedLoadLazyVideo, false);
|
||||
}
|
||||
});
|
||||
71
site/OFF_plugins/embed/assets/scss/embed.scss
Normal file
71
site/OFF_plugins/embed/assets/scss/embed.scss
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
|
||||
$col-bg: #ddd;
|
||||
|
||||
.embed {
|
||||
position: relative;
|
||||
max-width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
iframe,
|
||||
object {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
img {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
&--video {
|
||||
background-color: $col-bg;
|
||||
overflow: hidden;
|
||||
|
||||
iframe,
|
||||
object {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&--error {
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
&__thumb {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
background-size: cover;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
> img {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 25%;
|
||||
min-width: 75px;
|
||||
max-width: 175px;
|
||||
transform: translate(-50%, -50%);
|
||||
transition: opacity .3s ease-in-out;
|
||||
opacity: .65;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
> img {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
111
site/OFF_plugins/embed/core/core.php
Normal file
111
site/OFF_plugins/embed/core/core.php
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
<?php
|
||||
|
||||
namespace Kirby\Embed;
|
||||
|
||||
use A;
|
||||
use C;
|
||||
|
||||
use Kirby\Embed\Cache;
|
||||
use Kirby\Embed\Thumb;
|
||||
|
||||
class Core {
|
||||
|
||||
public $provider = null;
|
||||
|
||||
public function __construct($url, $args = []) {
|
||||
$this->input = $url;
|
||||
$this->cache = c::get('plugin.embed.caching', true) ? new Cache('embed', $url) : false;
|
||||
|
||||
$this->load();
|
||||
|
||||
if($this->data !== false) {
|
||||
$this->options = $this->options($args);
|
||||
$this->provider = $this->provider();
|
||||
$this->url = new Url($this->data()->code);
|
||||
}
|
||||
}
|
||||
|
||||
// ================================================
|
||||
// Load remote or cached data
|
||||
// ================================================
|
||||
|
||||
protected function load() {
|
||||
// get data from cache
|
||||
if($this->cache && $this->cache->exists()) {
|
||||
return $this->data = $this->cache->get();
|
||||
|
||||
// load data from source
|
||||
} else {
|
||||
$this->data = Data::get($this->input);
|
||||
}
|
||||
|
||||
// cache the data
|
||||
if($this->cache && $this->data) {
|
||||
$this->cache->set($this->data, c::get('plugin.embed.caching.duration', 24) * 60);
|
||||
}
|
||||
}
|
||||
|
||||
// ================================================
|
||||
// Default options
|
||||
// ================================================
|
||||
|
||||
protected function options($options) {
|
||||
return a::merge([
|
||||
'class' => null,
|
||||
'thumb' => null,
|
||||
'autoplay' => c::get('plugin.embed.video.autoplay', false),
|
||||
'lazyvideo' => c::get('plugin.embed.video.lazyload', true),
|
||||
'jsapi' => c::get('plugin.embed.providers.jsapi', false),
|
||||
], $options);
|
||||
}
|
||||
|
||||
|
||||
// ================================================
|
||||
// Thumb
|
||||
// ================================================
|
||||
|
||||
public function thumb() {
|
||||
if($this->options['thumb']) return $this->options['thumb'];
|
||||
|
||||
$thumb = $this->image();
|
||||
|
||||
if($this->cache) {
|
||||
return new Thumb('embed', $thumb, (c::get('plugin.embed.caching.duration', 24) * 60 * 60));
|
||||
} else {
|
||||
return $thumb;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ================================================
|
||||
// Custom provider instance
|
||||
// ================================================
|
||||
|
||||
protected function provider() {
|
||||
$namespace = 'Kirby\Embed\Providers\\';
|
||||
$class = $namespace . $this->data()->providerName;
|
||||
$class = class_exists($class) ? $class : $namespace . 'Provider';
|
||||
return $this->provider ?: new $class($this, $this->input);
|
||||
}
|
||||
|
||||
|
||||
// ================================================
|
||||
// Magic methods
|
||||
// ================================================
|
||||
|
||||
public function __call($name, $args) {
|
||||
if(method_exists($this->provider, $name)) {
|
||||
return $this->provider->{$name}($this->data()->{$name}, $args);
|
||||
} else {
|
||||
return $this->data()->{$name};
|
||||
}
|
||||
}
|
||||
|
||||
public function data() {
|
||||
return is_array($this->data) ? $this->data[0] : $this->data;
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
return !$this->data ? Html::error($this->input) : (string)new Html($this);
|
||||
}
|
||||
}
|
||||
30
site/OFF_plugins/embed/core/data.php
Normal file
30
site/OFF_plugins/embed/core/data.php
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace Kirby\Embed;
|
||||
|
||||
use C;
|
||||
use Embed\Embed;
|
||||
|
||||
class Data {
|
||||
|
||||
public static function get($url) {
|
||||
try {
|
||||
return Embed::create($url, static::config());
|
||||
} catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected static function config() {
|
||||
return [
|
||||
'choose_bigger_image' => true,
|
||||
'google' => [
|
||||
'key' => c::get('plugin.embed.providers.google.key', null)
|
||||
],
|
||||
'soundcloud' => [
|
||||
'key' => c::get('plugin.embed.providers.soundcloud.key', null)
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
157
site/OFF_plugins/embed/core/html.php
Normal file
157
site/OFF_plugins/embed/core/html.php
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
<?php
|
||||
|
||||
namespace Kirby\Embed;
|
||||
|
||||
use C;
|
||||
use L;
|
||||
use Tpl;
|
||||
|
||||
class Html {
|
||||
|
||||
public function __construct($core) {
|
||||
$this->core = $core;
|
||||
$this->options = $this->core->options;
|
||||
|
||||
$this->data = [
|
||||
'code' => $this->core->code(),
|
||||
'class' => $this->core->options['class'],
|
||||
'type' => $this->core->type(),
|
||||
'provider' => $this->core->providerName(),
|
||||
'style' => null,
|
||||
'more' => null
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
// ================================================
|
||||
// Outputs
|
||||
// ================================================
|
||||
|
||||
public function __toString() {
|
||||
// call preparation method for type
|
||||
$this->prepareType();
|
||||
|
||||
// w3c valid code
|
||||
$this->ensureValidCode();
|
||||
|
||||
// update embed iframe url
|
||||
$this->updateData('code', function($code) {
|
||||
return $this->core->url->update($code);
|
||||
});
|
||||
|
||||
return $this->snippet('wrapper', $this->data);
|
||||
}
|
||||
|
||||
public static function error($url, $msg = null) {
|
||||
if(!$msg) $msg = 'noembed';
|
||||
$msg = l::get('plugin.embed.error.' . $msg);
|
||||
$path = __DIR__ . DS . 'snippets' . DS . 'error.php';
|
||||
|
||||
return tpl::load($path, [
|
||||
'url' => $url,
|
||||
'msg' => $msg
|
||||
]);
|
||||
}
|
||||
|
||||
public static function cheatsheet($parameters) {
|
||||
$path = __DIR__ . DS . 'snippets' . DS . 'cheatsheet.php';
|
||||
return tpl::load($path, [
|
||||
'entries' => $parameters
|
||||
]);
|
||||
}
|
||||
|
||||
// ================================================
|
||||
// Types
|
||||
// ================================================
|
||||
|
||||
protected function prepareType() {
|
||||
$prepareType = 'prepare' . ucfirst($this->core->type());
|
||||
if(method_exists($this, $prepareType)) {
|
||||
$this->{$prepareType}();
|
||||
}
|
||||
|
||||
if(!$this->data['code']) {
|
||||
$this->updateData('code', $this->error($this->core->input, 'nocode'));
|
||||
$this->updateData('class', false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ================================================
|
||||
// Videos
|
||||
// ================================================
|
||||
|
||||
protected function prepareVideo() {
|
||||
if($this->data['code']) {
|
||||
// Container ratio
|
||||
$this->data['style'] = 'padding-top:' . str_replace(',', '.', $this->core->aspectRatio()) . '%';
|
||||
|
||||
// Lazy video
|
||||
if($this->options['lazyvideo'] && $this->core->supportsLazyVideo()) {
|
||||
$this->lazyVideo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function lazyVideo() {
|
||||
// src -> data-src
|
||||
$this->updateData('code', function($code) {
|
||||
$pattern = '/(<iframe.*)(src)(="[^[:space:]]*")/';
|
||||
$replace = '$1data-src$3';
|
||||
return preg_replace($pattern, $replace, $code);
|
||||
});
|
||||
|
||||
// thumb
|
||||
$this->data['more'] = $this->snippet('thumb', [
|
||||
'url' => $this->core->thumb(),
|
||||
'alt' => $this->core->title() . ($this->core->authorName() ? ' (by ' . $this->core->authorName() . ')' : '')
|
||||
]);
|
||||
}
|
||||
|
||||
// ================================================
|
||||
// Links
|
||||
// ================================================
|
||||
|
||||
protected function prepareLink() {
|
||||
if(!$this->data['code']) {
|
||||
$this->updateData('code', $this->snippet('typeLink', [
|
||||
'url' => $this->core->url(),
|
||||
'text' => $this->core->title()
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ================================================
|
||||
// Code validity
|
||||
// ================================================
|
||||
protected function ensureValidCode() {
|
||||
if(c::get('plugin.embed.w3c.enforce', false)) {
|
||||
$this->updateData('code', function($code) {
|
||||
$pattern = '/(frameborder="0"|allowtransparency="true")/';
|
||||
return preg_replace($pattern, '', $code);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// ================================================
|
||||
// Helpers
|
||||
// ================================================
|
||||
|
||||
protected function updateData($data, $value) {
|
||||
if(is_callable($value)) {
|
||||
$this->data[$data] = $value($this->data[$data]);
|
||||
} else {
|
||||
$this->data[$data] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
protected function snippet($name, $data) {
|
||||
return tpl::load(__DIR__ . DS . 'snippets' . DS . $name . '.php', $data);
|
||||
}
|
||||
|
||||
public static function removeEmojis($string) {
|
||||
return trim(preg_replace('/[\x00-\x1F\x80-\xFF]/', '', mb_convert_encoding($string, "UTF-8")));
|
||||
}
|
||||
|
||||
}
|
||||
40
site/OFF_plugins/embed/core/lib/autoloader.php
Normal file
40
site/OFF_plugins/embed/core/lib/autoloader.php
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace Kirby\Embed;
|
||||
|
||||
use Dir;
|
||||
|
||||
class Autoloader {
|
||||
public static function load($paths) {
|
||||
foreach($paths as $group => $files) {
|
||||
|
||||
// single file
|
||||
if(!is_array($files)) {
|
||||
static::loadFile($group . '.php');
|
||||
|
||||
// directory
|
||||
} else {
|
||||
foreach($files as $file) {
|
||||
|
||||
// load all files from this directory
|
||||
if($file === true) {
|
||||
foreach(dir::read(dirname(dirname(__DIR__)) . DS . $group) as $file) {
|
||||
static::loadFile($group . DS . $file);
|
||||
}
|
||||
|
||||
// load specified files
|
||||
} else {
|
||||
static::loadFile($group . DS . $file . '.php');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static function loadFile($path) {
|
||||
$file = dirname(dirname(__DIR__)) . DS . str_replace('/', DS, $path);
|
||||
if(file_exists($file)) {
|
||||
require_once($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
28
site/OFF_plugins/embed/core/lib/cache.php
Normal file
28
site/OFF_plugins/embed/core/lib/cache.php
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace Kirby\Embed;
|
||||
|
||||
class Cache {
|
||||
|
||||
public function __construct($plugin, $url) {
|
||||
$this->plugin = $plugin;
|
||||
$this->key = md5($url);
|
||||
|
||||
// Cache DirectoryIterator
|
||||
$dir = kirby()->roots()->cache() . DS . $this->plugin;
|
||||
if(!file_exists($dir)) mkdir($dir);
|
||||
|
||||
// Cache setup
|
||||
$this->cache = \cache::setup('file', ['root' => $dir]);
|
||||
|
||||
// Cache clean-up
|
||||
if($this->cache->expired($this->key)) {
|
||||
$this->cache->remove($this->key);
|
||||
}
|
||||
}
|
||||
|
||||
public function __call($name, $args = []) {
|
||||
return $this->cache->{$name}($this->key, $args);
|
||||
}
|
||||
|
||||
}
|
||||
57
site/OFF_plugins/embed/core/lib/thumb.php
Normal file
57
site/OFF_plugins/embed/core/lib/thumb.php
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
|
||||
namespace Kirby\Embed;
|
||||
|
||||
use C;
|
||||
use F;
|
||||
|
||||
class Thumb {
|
||||
|
||||
protected $dir;
|
||||
protected $root;
|
||||
protected $url = '';
|
||||
|
||||
public function __construct($plugin, $url, $lifetime) {
|
||||
$this->plugin = $plugin;
|
||||
$this->source = $url;
|
||||
$this->lifetime = $lifetime;
|
||||
|
||||
$this->root = kirby()->roots()->thumbs() . DS . '_plugins';
|
||||
$this->dir = $this->root . DS . $this->plugin;
|
||||
$this->extension = pathinfo(strtok($this->source, '?'), PATHINFO_EXTENSION);
|
||||
$this->file = md5($this->source) . '.' . $this->extension;
|
||||
$this->path = $this->dir . DS . $this->file;
|
||||
$this->url = $url;
|
||||
|
||||
$this->cache();
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
protected function cache() {
|
||||
$cache = url('thumbs/_plugins/' . $this->plugin . '/' . $this->file);
|
||||
|
||||
if(f::exists($this->path) and !$this->expired()) {
|
||||
return $this->url = $cache;
|
||||
} else {
|
||||
try {
|
||||
if(is_writable(kirby()->roots()->thumbs())) {
|
||||
if(!file_exists($this->root)) mkdir($this->root, 0755, true);
|
||||
if(!file_exists($this->dir)) mkdir($this->dir, 0755, true);
|
||||
file_put_contents($this->path, file_get_contents($this->source));
|
||||
$this->url = $cache;
|
||||
}
|
||||
} catch (Exception $e) {}
|
||||
}
|
||||
}
|
||||
|
||||
protected function expired() {
|
||||
if((f::modified($this->path) + $this->lifetime) < time()) {
|
||||
return f::remove($this->path);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
12
site/OFF_plugins/embed/core/providers/collegehumor.php
Normal file
12
site/OFF_plugins/embed/core/providers/collegehumor.php
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
namespace Kirby\Embed\Providers;
|
||||
|
||||
class CollegeHumor extends Provider {
|
||||
|
||||
public function code($code) {
|
||||
$this->setAutoplay();
|
||||
return $code;
|
||||
}
|
||||
|
||||
}
|
||||
21
site/OFF_plugins/embed/core/providers/meetup.php
Normal file
21
site/OFF_plugins/embed/core/providers/meetup.php
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace Kirby\Embed\Providers;
|
||||
|
||||
class Meetup extends Provider {
|
||||
|
||||
public function code($code) {
|
||||
$code .= $this->fixStyles();
|
||||
return $code;
|
||||
}
|
||||
|
||||
|
||||
// ================================================
|
||||
// Fix styles
|
||||
// ================================================
|
||||
|
||||
protected function fixStyles() {
|
||||
return '<style>#meetup_oembed{height: auto !important; text-align: left;}</style>';
|
||||
}
|
||||
|
||||
}
|
||||
21
site/OFF_plugins/embed/core/providers/phorkie.php
Normal file
21
site/OFF_plugins/embed/core/providers/phorkie.php
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace Kirby\Embed\Providers;
|
||||
|
||||
class phorkie extends Provider {
|
||||
|
||||
public function code($code) {
|
||||
$code .= $this->fixStyles();
|
||||
return $code;
|
||||
}
|
||||
|
||||
|
||||
// ================================================
|
||||
// Fix styles
|
||||
// ================================================
|
||||
|
||||
protected function fixStyles() {
|
||||
return '<style>.phork {text-align: left;}</style>';
|
||||
}
|
||||
|
||||
}
|
||||
79
site/OFF_plugins/embed/core/providers/provider.php
Normal file
79
site/OFF_plugins/embed/core/providers/provider.php
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
namespace Kirby\Embed\Providers;
|
||||
|
||||
class Provider {
|
||||
|
||||
public function __construct($core, $url) {
|
||||
$this->core = $core;
|
||||
$this->url = $url;
|
||||
|
||||
$this->init();
|
||||
}
|
||||
|
||||
|
||||
// ================================================
|
||||
// Placeholder methods
|
||||
// ================================================
|
||||
|
||||
protected function init() {}
|
||||
|
||||
public function supportsLazyVideo() { return $this->core->type() === 'video'; }
|
||||
|
||||
// ================================================
|
||||
// Custom URL parameter helpers
|
||||
// ================================================
|
||||
|
||||
protected function set($paramenter) {
|
||||
if($this->{$paramenter} !== false) {
|
||||
$this->parameter($paramenter . '=' . $this->{$paramenter});
|
||||
}
|
||||
}
|
||||
|
||||
protected function get($paramenter, $pattern) {
|
||||
$this->{$paramenter} = preg_match('/' . $paramenter . '=(' . $pattern . ')/', $this->url, $result) ? $result[1] : false;
|
||||
}
|
||||
|
||||
protected function getBool($paramenter) {
|
||||
$this->get($paramenter, '[0-1]');
|
||||
}
|
||||
|
||||
protected function getNumber($paramenter, $offset = 0) {
|
||||
$this->get($paramenter, '[0-9]*');
|
||||
if($offset !== 0) {
|
||||
$this->{$paramenter} += $offset;
|
||||
}
|
||||
}
|
||||
|
||||
protected function getString($paramenter) {
|
||||
$this->get($paramenter, '[a-zA-Z]*');
|
||||
}
|
||||
|
||||
protected function getAll($paramenter) {
|
||||
$this->get($paramenter, '[a-zA-Z0-9]*');
|
||||
}
|
||||
|
||||
|
||||
// ================================================
|
||||
// Video Autoplay
|
||||
// ================================================
|
||||
|
||||
protected function setAutoplay() {
|
||||
if($this->option('lazyvideo') || $this->option('autoplay')) {
|
||||
$this->parameter(['rel=0', 'autoplay=1', 'auto=1']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ================================================
|
||||
// General helpers
|
||||
// ================================================
|
||||
|
||||
protected function option($option) {
|
||||
return $this->core->options[$option];
|
||||
}
|
||||
|
||||
protected function parameter($parameter) {
|
||||
return $this->core->url->parameter($parameter);
|
||||
}
|
||||
}
|
||||
42
site/OFF_plugins/embed/core/providers/slideshare.php
Normal file
42
site/OFF_plugins/embed/core/providers/slideshare.php
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
namespace Kirby\Embed\Providers;
|
||||
|
||||
class Slideshare extends Provider {
|
||||
|
||||
protected function init() {
|
||||
$this->getNumber('width');
|
||||
$this->getNumber('height');
|
||||
}
|
||||
|
||||
public function code($code) {
|
||||
$code = $this->setSizes($code);
|
||||
return $code;
|
||||
}
|
||||
|
||||
|
||||
// ================================================
|
||||
// Parameters for Panel Field Cheatsheet
|
||||
// ================================================
|
||||
|
||||
public function urlParameters() {
|
||||
return [
|
||||
['width', 'Set the width of the embed (e.g. 600)'],
|
||||
['height', 'Set the height of the embed (e.g. 80)'],
|
||||
];
|
||||
}
|
||||
|
||||
// ================================================
|
||||
// Sizes
|
||||
// ================================================
|
||||
|
||||
protected function setSizes($code) {
|
||||
if($this->width !== false) {
|
||||
$code = str_ireplace('<iframe', '<iframe width="' . $this->width . '"', $code);
|
||||
}
|
||||
if($this->height !== false) {
|
||||
$code = str_ireplace('<iframe', '<iframe height="' . $this->height . '"', $code);
|
||||
}
|
||||
return $code;
|
||||
}
|
||||
}
|
||||
48
site/OFF_plugins/embed/core/providers/spotify.php
Normal file
48
site/OFF_plugins/embed/core/providers/spotify.php
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
namespace Kirby\Embed\Providers;
|
||||
|
||||
class Spotify extends Provider {
|
||||
|
||||
protected function init() {
|
||||
$this->getString('theme');
|
||||
$this->getString('view');
|
||||
$this->getNumber('width');
|
||||
$this->getNumber('height');
|
||||
}
|
||||
|
||||
public function code($code) {
|
||||
$this->set('theme');
|
||||
$this->set('view');
|
||||
$code = $this->setSizes($code);
|
||||
return $code;
|
||||
}
|
||||
|
||||
|
||||
// ================================================
|
||||
// Parameters for Panel Field Cheatsheet
|
||||
// ================================================
|
||||
|
||||
public function urlParameters() {
|
||||
return [
|
||||
['view', 'Set the view style (list/coverart)'],
|
||||
['theme', 'Set the theme (white/black)'],
|
||||
['width', 'Set the width of the embed (e.g. 600)'],
|
||||
['height', 'Set the height of the embed (e.g. 80)'],
|
||||
];
|
||||
}
|
||||
|
||||
// ================================================
|
||||
// Sizes
|
||||
// ================================================
|
||||
|
||||
protected function setSizes($code) {
|
||||
if($this->width !== false) {
|
||||
$code = str_ireplace('<iframe', '<iframe width="' . $this->width . '"', $code);
|
||||
}
|
||||
if($this->height !== false) {
|
||||
$code = str_ireplace('<iframe', '<iframe height="' . $this->height . '"', $code);
|
||||
}
|
||||
return $code;
|
||||
}
|
||||
}
|
||||
9
site/OFF_plugins/embed/core/providers/ted.php
Normal file
9
site/OFF_plugins/embed/core/providers/ted.php
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Kirby\Embed\Providers;
|
||||
|
||||
class TED extends Provider {
|
||||
|
||||
public function supportsLazyVideo() { return false; }
|
||||
|
||||
}
|
||||
23
site/OFF_plugins/embed/core/providers/ustream.php
Normal file
23
site/OFF_plugins/embed/core/providers/ustream.php
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace Kirby\Embed\Providers;
|
||||
|
||||
class Ustream extends Provider {
|
||||
|
||||
public function code($code) {
|
||||
$this->setAutoplay();
|
||||
return $code;
|
||||
}
|
||||
|
||||
|
||||
// ================================================
|
||||
// Autoplay
|
||||
// ================================================
|
||||
|
||||
protected function setAutoplay() {
|
||||
if($this->option('lazyvideo') || $this->option('autoplay')) {
|
||||
$this->parameter('autoplay=true');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
53
site/OFF_plugins/embed/core/providers/vimeo.php
Normal file
53
site/OFF_plugins/embed/core/providers/vimeo.php
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
namespace Kirby\Embed\Providers;
|
||||
|
||||
class Vimeo extends Provider {
|
||||
|
||||
protected function init() {
|
||||
$this->getBool('autopause');
|
||||
$this->getBool('badge');
|
||||
$this->getBool('byline');
|
||||
$this->getAll('color');
|
||||
$this->getBool('loop');
|
||||
$this->getBool('portrait');
|
||||
$this->getBool('title');
|
||||
}
|
||||
|
||||
public function code($code) {
|
||||
$this->setAutoplay();
|
||||
$this->set('autopause');
|
||||
$this->set('badge');
|
||||
$this->set('byline');
|
||||
$this->set('color');
|
||||
$this->set('loop');
|
||||
$this->set('portrait');
|
||||
$this->set('title');
|
||||
$this->setJsApi();
|
||||
return $code;
|
||||
}
|
||||
|
||||
public function urlParameters() {
|
||||
return [
|
||||
['autopause', 'Enables or disables pausing this video when another video is played (1/0)'],
|
||||
['badge', 'Enables or disables the badge on the video (1/0)'],
|
||||
['byline', 'Show the user’s byline on the video (1/0)'],
|
||||
['color', 'Specify the color of the video controls (e.g. 00aa00)'],
|
||||
['loop', 'Play the video again when it reaches the end (1/0)'],
|
||||
['portrait', 'Show the user’s portrait on the video (1/0)'],
|
||||
['title', 'Show the title on the video (1/0)'],
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
// ================================================
|
||||
// JS API
|
||||
// ================================================
|
||||
|
||||
protected function setJsApi() {
|
||||
if($this->option('jsapi')) {
|
||||
$this->parameter('api=1');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
9
site/OFF_plugins/embed/core/providers/vine.php
Normal file
9
site/OFF_plugins/embed/core/providers/vine.php
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Kirby\Embed\Providers;
|
||||
|
||||
class Vine extends Provider {
|
||||
|
||||
public function supportsLazyVideo() { return false; }
|
||||
|
||||
}
|
||||
65
site/OFF_plugins/embed/core/providers/youtube.php
Normal file
65
site/OFF_plugins/embed/core/providers/youtube.php
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
namespace Kirby\Embed\Providers;
|
||||
|
||||
class YouTube extends Provider {
|
||||
|
||||
protected function init() {
|
||||
$this->getAll('t');
|
||||
$this->getNumber('index');
|
||||
}
|
||||
|
||||
public function code($code) {
|
||||
$this->setAutoplay();
|
||||
$this->setTimecode();
|
||||
$this->set('index');
|
||||
$this->setJsApi();
|
||||
return $code;
|
||||
}
|
||||
|
||||
|
||||
// ================================================
|
||||
// Parameters for Panel Field Cheatsheet
|
||||
// ================================================
|
||||
|
||||
public function urlParameters() {
|
||||
return [
|
||||
['t', 'Timecode where the video should start (e.g. 1m4s)'],
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ================================================
|
||||
// Timecode
|
||||
// ================================================
|
||||
|
||||
protected function setTimecode() {
|
||||
if($this->t !== false) {
|
||||
$this->parameter('start=' . $this->calculateTimecode());
|
||||
}
|
||||
}
|
||||
|
||||
protected function calculateTimecode() {
|
||||
$time = $this->disectTimecode('h') * 60 * 60;
|
||||
$time += $this->disectTimecode('m') * 60 ;
|
||||
$time += $this->disectTimecode('s');
|
||||
return $time;
|
||||
}
|
||||
|
||||
protected function disectTimecode($identifier) {
|
||||
return preg_match('/([0-9]+)' . $identifier . '/i', $this->t, $match) ? $match[0] : 0;
|
||||
}
|
||||
|
||||
|
||||
// ================================================
|
||||
// JS API
|
||||
// ================================================
|
||||
|
||||
protected function setJsApi() {
|
||||
if($this->option('jsapi')) {
|
||||
$this->parameter('enablejsapi=1');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
14
site/OFF_plugins/embed/core/snippets/cheatsheet.php
Normal file
14
site/OFF_plugins/embed/core/snippets/cheatsheet.php
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<?php if(is_array($entries)) : ?>
|
||||
<table class="field-embed-cheatsheet__table">
|
||||
<tr class="field-embed-cheatsheet__th">
|
||||
<td>URL parameter</td>
|
||||
<td>Description</td>
|
||||
</tr>
|
||||
<?php foreach($entries as $entry) : ?>
|
||||
<tr>
|
||||
<td><?= $entry[0] ?></td>
|
||||
<td><?= $entry[1] ?></td>
|
||||
</tr>
|
||||
<?php endforeach ?>
|
||||
</table>
|
||||
<?php endif ?>
|
||||
1
site/OFF_plugins/embed/core/snippets/error.php
Normal file
1
site/OFF_plugins/embed/core/snippets/error.php
Normal file
|
|
@ -0,0 +1 @@
|
|||
<figure class="embed embed--error"><?= $msg ?> <span><?= $url ?></span></figure>
|
||||
1
site/OFF_plugins/embed/core/snippets/thumb.php
Normal file
1
site/OFF_plugins/embed/core/snippets/thumb.php
Normal file
|
|
@ -0,0 +1 @@
|
|||
<div class="embed__thumb" style="background-image:url('<?= $url ?>');" title="<?= $alt ?>"><img src="<?= url(c::get('plugin.embed.video.lazyload.btn', 'assets/plugins/embed/images/play.png')) ?>" alt="" width="175" height="110" /></div>
|
||||
1
site/OFF_plugins/embed/core/snippets/typeLink.php
Normal file
1
site/OFF_plugins/embed/core/snippets/typeLink.php
Normal file
|
|
@ -0,0 +1 @@
|
|||
<div class="embed--link__fallback"><a href="<?= $url ?>"><?= $text ?></a></div>
|
||||
1
site/OFF_plugins/embed/core/snippets/wrapper.php
Normal file
1
site/OFF_plugins/embed/core/snippets/wrapper.php
Normal file
|
|
@ -0,0 +1 @@
|
|||
<figure class="embed <?php e($class !== false, 'embed--' . $type) ?> embed--<?= $provider ?> <?= $class ?>" style="<?= $style ?>"><?= $code ?><?= $more ?></figure>
|
||||
60
site/OFF_plugins/embed/core/url.php
Normal file
60
site/OFF_plugins/embed/core/url.php
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
|
||||
namespace Kirby\Embed;
|
||||
|
||||
|
||||
class Url {
|
||||
|
||||
public $parameters = [];
|
||||
|
||||
// ================================================
|
||||
// Extract URL from code
|
||||
// ================================================
|
||||
|
||||
public function __construct($code) {
|
||||
if(preg_match('/(src=")(.*)(")/U', $code, $match)) {
|
||||
$this->url = $match[2];
|
||||
} else {
|
||||
$this->url = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ================================================
|
||||
// Get new URL with parameters
|
||||
// ================================================
|
||||
|
||||
public function get() {
|
||||
$newParameters = implode('&', $this->parameters);
|
||||
$hasParameter = preg_match('/\?/', $this->url);
|
||||
|
||||
return $this->url . ($hasParameter ? '&' : '?') . $newParameters;
|
||||
}
|
||||
|
||||
|
||||
// ================================================
|
||||
// Update code with new URL
|
||||
// ================================================
|
||||
|
||||
public function update($code) {
|
||||
if($this->url !== false) {
|
||||
$pattern = '/(src|data-src)(=")(.*)(")/U';
|
||||
$order = '$1$2' . $this->get() . '$4';
|
||||
$code = preg_replace($pattern, $order, $code);
|
||||
}
|
||||
|
||||
return $code;
|
||||
}
|
||||
|
||||
|
||||
// ================================================
|
||||
// Add parameter(s)
|
||||
// ================================================
|
||||
|
||||
public function parameter($parameter) {
|
||||
if(!is_array($parameter)) $parameter = [$parameter];
|
||||
|
||||
$this->parameters = array_merge($this->parameters, $parameter);
|
||||
}
|
||||
|
||||
}
|
||||
35
site/OFF_plugins/embed/embed.php
Normal file
35
site/OFF_plugins/embed/embed.php
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Kirby\Embed {
|
||||
|
||||
use Kirby\Embed\Autoloader;
|
||||
require_once('core/lib/autoloader.php');
|
||||
|
||||
$kirby = kirby();
|
||||
$language = $kirby->site()->language();
|
||||
|
||||
Autoloader::load([
|
||||
'vendor' => ['Embed/src/autoloader'],
|
||||
'translations' => ['en', $language ? $language->code() : null],
|
||||
'core' => ['core', 'data', 'url', 'html'],
|
||||
'core/lib' => ['cache', 'thumb'],
|
||||
'core/providers' => ['provider', true],
|
||||
]);
|
||||
|
||||
include('registry/field-method.php');
|
||||
include('registry/tag.php');
|
||||
include('registry/field.php');
|
||||
include('registry/route.php');
|
||||
|
||||
}
|
||||
|
||||
|
||||
// ================================================
|
||||
// Global helper
|
||||
// ================================================
|
||||
|
||||
namespace {
|
||||
function embed($url, $args = []) {
|
||||
return new Kirby\Embed\Core($url, $args);
|
||||
}
|
||||
}
|
||||
1
site/OFF_plugins/embed/field/assets/css/field.css
Normal file
1
site/OFF_plugins/embed/field/assets/css/field.css
Normal file
|
|
@ -0,0 +1 @@
|
|||
.field-embed-preview{position:relative;margin-top:-2px;border:2px solid #ddd;border-top-width:0;background-color:#ddd;overflow-y:auto}.field-embed-preview__bucket{-webkit-transition:opacity .5s;transition:opacity .5s;text-align:center}.field-embed-preview__bucket iframe,.field-embed-preview__bucket object{margin-right:auto;margin-left:auto}.field-embed-preview__bucket .embed--rich{padding:.6em}.field-embed-preview__bucket .embed--link>.embed--link__fallback{display:inline-block;padding:.6em}.field-embed-preview__bucket .embed--link>.embed--link__fallback>a{border-bottom:2px solid #bbb}.field-embed-preview__bucket .embed--error{padding:.6em;font-size:.75em;font-weight:600}.field-embed-preview__bucket .embed--error>span{display:block;font-weight:400}.field-embed-preview__loading{position:absolute;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);-webkit-transition:opacity .5s;transition:opacity .5s;font-size:.8em;font-weight:600;opacity:0}.field-embed-info{display:none;position:relative;margin-top:-2px;padding:.6em;border:2px solid #ddd;border-top-width:0;background-color:#fff}.field-embed-info a{font-weight:600}.field-embed-info a[href]{color:#8dad28}.field-embed-info a[href]:hover{opacity:.75}.field-embed-info__title{display:block;font-size:.95em;font-weight:600;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.field-embed-info>span:not(.field-embed-info__title){font-size:.8em}.field-embed-info>span:not(:first-child):not(:last-child)::after{content:' / '}.field-content+.field-embed-info{border-top-width:1px;border-top-color:#ddd!important}.field-embed-cheatsheet{position:absolute;top:1px;right:4px}.field-embed-cheatsheet__icon{cursor:help}.field-embed-cheatsheet__bucket{display:none;position:absolute;width:100%;margin-top:8px;padding:.35em .5em;background-color:rgba(255,255,255,.95);z-index:1}.field-embed-cheatsheet:hover+.field-embed-cheatsheet__bucket{display:block}.field-embed-cheatsheet__table{width:100%;font-size:.8em;font-weight:400}.field-embed-cheatsheet__table td{padding:0 .5em}.field-embed-cheatsheet__th{font-weight:700}.field-embed-cheatsheet__th td{border-bottom:1px solid #ddd}
|
||||
229
site/OFF_plugins/embed/field/assets/js/field.js
Normal file
229
site/OFF_plugins/embed/field/assets/js/field.js
Normal file
|
|
@ -0,0 +1,229 @@
|
|||
(function($) {
|
||||
$.fn.embedfield = function() {
|
||||
|
||||
// ================================================
|
||||
// Make icon clickable
|
||||
// ================================================
|
||||
|
||||
var clickableIcon = function($this) {
|
||||
var icon = $this.next('.field-icon');
|
||||
|
||||
icon.css({
|
||||
'cursor': 'pointer',
|
||||
'pointer-events': 'auto'
|
||||
});
|
||||
|
||||
icon.on('click', function() {
|
||||
var url = $.trim($this.val());
|
||||
if(url !== '' && $this.is(':valid')) {
|
||||
window.open(url);
|
||||
} else {
|
||||
$this.focus();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// ================================================
|
||||
// Update embed
|
||||
// ================================================
|
||||
|
||||
var updateEmbed = function($this, preview, info, sheet) {
|
||||
var url = $.trim($this.val());
|
||||
|
||||
if(!$this.data('embedurl') || url !== $this.data('embedurl')) {
|
||||
$this.data('embedurl', url);
|
||||
|
||||
if(url === '') {
|
||||
hidePreview(preview);
|
||||
hideInfo(info);
|
||||
setCheatsheet(sheet, {parameters: ''});
|
||||
|
||||
} else if($this.is(':valid')) {
|
||||
clearPreview(preview);
|
||||
|
||||
$.ajax({
|
||||
url: $this.data('ajax') + 'preview',
|
||||
type: 'POST',
|
||||
data: {
|
||||
url: url,
|
||||
code: preview.wrapper.length === 0 ? 'false' : 'true'
|
||||
},
|
||||
success: function(data) {
|
||||
showPreview(preview, data);
|
||||
setCheatsheet(sheet, data);
|
||||
|
||||
if(data.success !== 'false') {
|
||||
showInfo(info, data);
|
||||
} else {
|
||||
hideInfo(info);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// ================================================
|
||||
// Set preview section
|
||||
// ================================================
|
||||
|
||||
var showPreview = function(preview, data) {
|
||||
preview.load.css('opacity', '0');
|
||||
preview.bucket.html(data.code).css('opacity', '1');
|
||||
preview.bucket.find('.embed__thumb').click(pluginEmbedLoadLazyVideo);
|
||||
};
|
||||
|
||||
var clearPreview = function(preview) {
|
||||
preview.bucket.css('opacity', '0');
|
||||
preview.load.css('opacity', '1');
|
||||
};
|
||||
|
||||
var hidePreview = function(preview) {
|
||||
preview.bucket.css('opacity', '0').html('');
|
||||
};
|
||||
|
||||
|
||||
// ================================================
|
||||
// Set info section
|
||||
// ================================================
|
||||
|
||||
var showInfo = function(info, data) {
|
||||
if(data.title) {
|
||||
info.title.html(data.title).show();
|
||||
} else {
|
||||
info.title.hide();
|
||||
}
|
||||
|
||||
if(data.authorName) {
|
||||
info.author.show().find('a').attr('href', data.authorUrl ).html(data.authorName);
|
||||
} else {
|
||||
info.author.hide();
|
||||
}
|
||||
|
||||
if(data.providerName) {
|
||||
info.provider.show().find('a').attr('href', data.providerUrl ).html(data.providerName);
|
||||
} else {
|
||||
info.provider.hide();
|
||||
}
|
||||
|
||||
if(data.type) {
|
||||
info.type.show().html(data.type);
|
||||
} else {
|
||||
info.type.hide();
|
||||
}
|
||||
|
||||
if(info.wrapper.prop('style').display === '') {
|
||||
info.wrapper.show();
|
||||
} else {
|
||||
info.wrapper.slideDown();
|
||||
}
|
||||
};
|
||||
|
||||
var hideInfo = function(info) {
|
||||
info.wrapper.hide();
|
||||
};
|
||||
|
||||
|
||||
// ================================================
|
||||
// Set cheatsheet
|
||||
// ================================================
|
||||
|
||||
var setCheatsheet = function(sheet, data) {
|
||||
sheet.bucket.html(data.parameters);
|
||||
if(data.parameters === '') {
|
||||
sheet.icon.hide();
|
||||
} else {
|
||||
sheet.icon.show();
|
||||
}
|
||||
};
|
||||
|
||||
// ================================================
|
||||
// Fix borders
|
||||
// ================================================
|
||||
|
||||
var showBorder = function($this, preview, info) {
|
||||
if(!$this.parents('.field').hasClass('field-with-error')) {
|
||||
setBorder(preview, info, '#8dae28');
|
||||
} else {
|
||||
setBorder(preview, info, '#000');
|
||||
}
|
||||
};
|
||||
|
||||
var hideBorder = function(preview, info) {
|
||||
setBorder(preview, info, '');
|
||||
};
|
||||
|
||||
var setBorder = function(preview, info, color) {
|
||||
preview.wrapper.add(info.wrapper).css('border-color', color);
|
||||
};
|
||||
|
||||
|
||||
// ================================================
|
||||
// Initialization
|
||||
// ================================================
|
||||
|
||||
return this.each(function() {
|
||||
|
||||
var $this = $(this);
|
||||
|
||||
if($this.data('embedfield')) {
|
||||
return;
|
||||
} else {
|
||||
$this.data('embedfield', true);
|
||||
}
|
||||
|
||||
// make icon clickable
|
||||
clickableIcon($this);
|
||||
|
||||
// collect all elements
|
||||
var inputTimer;
|
||||
var preview = $this.parent().nextAll('.field-embed-preview');
|
||||
preview = {
|
||||
wrapper: preview,
|
||||
bucket: preview.find('.field-embed-preview__bucket'),
|
||||
load: preview.find('.field-embed-preview__loading'),
|
||||
};
|
||||
var info = $this.parent().nextAll('.field-embed-info');
|
||||
info = {
|
||||
wrapper: info,
|
||||
title: info.find('.field-embed-info__title'),
|
||||
author: info.find('.field-embed-info__author'),
|
||||
provider: info.find('.field-embed-info__provider'),
|
||||
type: info.find('.field-embed-info__type')
|
||||
};
|
||||
var sheet = $this.parent().prev().find('.field-embed-cheatsheet');
|
||||
sheet = {
|
||||
wrapper: sheet,
|
||||
icon: sheet.find('.field-embed-cheatsheet__icon'),
|
||||
bucket: sheet.next(),
|
||||
};
|
||||
|
||||
// update embed on input blur
|
||||
$this.on('blur', function() {
|
||||
window.clearTimeout(inputTimer);
|
||||
updateEmbed($this, preview, info, sheet);
|
||||
});
|
||||
|
||||
// update embed on input change (delayed)
|
||||
$this.bind('input embed.change', function() {
|
||||
window.clearTimeout(inputTimer);
|
||||
inputTimer = window.setTimeout(function(){
|
||||
updateEmbed($this, preview, info, sheet);
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
// update embed on load
|
||||
updateEmbed($this, preview, info, sheet);
|
||||
|
||||
// fix border colors on input focus and blur
|
||||
$this.focus(function(){
|
||||
showBorder($this, preview, info);
|
||||
}).blur(function(){
|
||||
hideBorder(preview, info);
|
||||
});
|
||||
});
|
||||
};
|
||||
})(jQuery);
|
||||
152
site/OFF_plugins/embed/field/assets/scss/field.scss
Normal file
152
site/OFF_plugins/embed/field/assets/scss/field.scss
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
|
||||
$bgcolor: #ddd;
|
||||
$link: #bbb;
|
||||
$green: #8dad28;
|
||||
$white: #fff;
|
||||
|
||||
.field-embed {
|
||||
|
||||
// ================================================
|
||||
// Preview display section
|
||||
// ================================================
|
||||
|
||||
&-preview {
|
||||
position: relative;
|
||||
margin-top: -2px;
|
||||
border: 2px solid $bgcolor;
|
||||
border-top-width: 0;
|
||||
background-color: $bgcolor;
|
||||
overflow-y: auto;
|
||||
|
||||
&__bucket {
|
||||
transition: opacity .5s;
|
||||
text-align: center;
|
||||
|
||||
iframe,
|
||||
object {
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
// actual embed
|
||||
.embed {
|
||||
&--rich { padding: .6em; }
|
||||
|
||||
&--link > .embed--link__fallback {
|
||||
display: inline-block;
|
||||
padding: .6em;
|
||||
|
||||
> a { border-bottom: 2px solid $link; }
|
||||
}
|
||||
|
||||
&--error {
|
||||
padding: .6em;
|
||||
font-size: .75em;
|
||||
font-weight: 600;
|
||||
|
||||
> span {
|
||||
display: block;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__loading {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
transition: opacity .5s;
|
||||
font-size: .8em;
|
||||
font-weight: 600;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ================================================
|
||||
// Info section
|
||||
// ================================================
|
||||
|
||||
&-info {
|
||||
display: none;
|
||||
position: relative;
|
||||
margin-top: -2px;
|
||||
padding: .6em;
|
||||
border: 2px solid $bgcolor;
|
||||
border-top-width: 0;
|
||||
background-color: $white;
|
||||
|
||||
a {
|
||||
font-weight: 600;
|
||||
|
||||
&[href] {
|
||||
color: $green;
|
||||
|
||||
&:hover { opacity: .75; }
|
||||
}
|
||||
}
|
||||
|
||||
&__title {
|
||||
display: block;
|
||||
font-size: .95em;
|
||||
font-weight: 600;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
> span {
|
||||
&:not(.field-embed-info__title) { font-size: .8em; }
|
||||
&:not(:first-child):not(:last-child)::after { content: ' / '; }
|
||||
}
|
||||
|
||||
.field-content + & {
|
||||
border-top-width: 1px;
|
||||
border-top-color: $bgcolor !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ================================================
|
||||
// Cheatsheet overlay
|
||||
// ================================================
|
||||
|
||||
&-cheatsheet {
|
||||
position: absolute;
|
||||
top: 1px;
|
||||
right: 4px;
|
||||
|
||||
&__icon { cursor: help; }
|
||||
|
||||
&__bucket {
|
||||
display: none;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
margin-top: 8px;
|
||||
padding: .35em .5em;
|
||||
background-color: rgba($white, .95);
|
||||
z-index: 1;
|
||||
|
||||
.field-embed-cheatsheet:hover + & { display: block; }
|
||||
}
|
||||
|
||||
&__table {
|
||||
width: 100%;
|
||||
font-size: .8em;
|
||||
font-weight: 400;
|
||||
|
||||
td { padding: 0 .5em; }
|
||||
}
|
||||
|
||||
&__th {
|
||||
font-weight: 700;
|
||||
|
||||
td { border-bottom: 1px solid $bgcolor; }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
75
site/OFF_plugins/embed/field/embed.php
Normal file
75
site/OFF_plugins/embed/field/embed.php
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
class EmbedField extends UrlField {
|
||||
|
||||
public $preview = true;
|
||||
public $info = true;
|
||||
public $cheatsheet = false;
|
||||
public $height = 'none';
|
||||
|
||||
public static $assets = [
|
||||
'css' => [
|
||||
'../../../assets/css/embed.css',
|
||||
'field.css'
|
||||
],
|
||||
'js' => [
|
||||
'../../../assets/js/embed.js',
|
||||
'field.js'
|
||||
]
|
||||
];
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
|
||||
$this->type = 'embed';
|
||||
$this->icon = 'object-group';
|
||||
|
||||
$this->translations();
|
||||
}
|
||||
|
||||
public function input() {
|
||||
$input = parent::input();
|
||||
$input->data('field', 'embedfield');
|
||||
$input->data('ajax', url('api/plugin/embed/'));
|
||||
return $input;
|
||||
}
|
||||
|
||||
public function template() {
|
||||
$template = parent::template();
|
||||
|
||||
if($this->preview) {
|
||||
$template->append($this->tpl('preview', [
|
||||
'height' => $this->height,
|
||||
]));
|
||||
}
|
||||
|
||||
if($this->info) $template->append($this->tpl('info'));
|
||||
|
||||
return $template;
|
||||
}
|
||||
|
||||
public function label() {
|
||||
$label = parent::label();
|
||||
|
||||
if($this->cheatsheet) $label->append($this->tpl('cheatsheet'));
|
||||
|
||||
return $label;
|
||||
}
|
||||
|
||||
protected function translations() {
|
||||
$root = dirname(__DIR__) . DS . 'translations' . DS;
|
||||
|
||||
// Default (English)
|
||||
require($root . 'en.php');
|
||||
|
||||
// Current panel language
|
||||
if(file_exists($root . panel()->language()->code() . '.php')) {
|
||||
require($root . panel()->language()->code() . '.php');
|
||||
}
|
||||
}
|
||||
|
||||
protected function tpl($file, $args = []) {
|
||||
return tpl::load(__DIR__ . DS . 'templates' . DS . $file . '.php', $args);
|
||||
}
|
||||
|
||||
}
|
||||
4
site/OFF_plugins/embed/field/templates/cheatsheet.php
Normal file
4
site/OFF_plugins/embed/field/templates/cheatsheet.php
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<div class="field-embed-cheatsheet">
|
||||
<i class="field-embed-cheatsheet__icon fa fa-info-circle"></i>
|
||||
</div>
|
||||
<div class="field-embed-cheatsheet__bucket"></div>
|
||||
10
site/OFF_plugins/embed/field/templates/info.php
Normal file
10
site/OFF_plugins/embed/field/templates/info.php
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<div class="field-embed-info">
|
||||
<span class="field-embed-info__title"></span>
|
||||
<span class="field-embed-info__type"></span>
|
||||
<span class="field-embed-info__author">
|
||||
<?= l('plugin.embed.panelfield.by') ?> <a href=""></a>
|
||||
</span>
|
||||
<span class="field-embed-info__provider">
|
||||
<?= l('plugin.embed.panelfield.provider') ?> <a href=""></a>
|
||||
</span>
|
||||
</div>
|
||||
6
site/OFF_plugins/embed/field/templates/preview.php
Normal file
6
site/OFF_plugins/embed/field/templates/preview.php
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<div class="field-embed-preview" style="max-height: <?= $height ?>">
|
||||
<div class="field-embed-preview__loading">
|
||||
<?= l('plugin.embed.panelfield.loading') ?>
|
||||
</div>
|
||||
<div class="field-embed-preview__bucket"></div>
|
||||
</div>
|
||||
36
site/OFF_plugins/embed/gulpfile.js
Normal file
36
site/OFF_plugins/embed/gulpfile.js
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
var gulp = require('gulp');
|
||||
var autoprefixer = require('gulp-autoprefixer');
|
||||
var sass = require('gulp-sass');
|
||||
var cssmin = require('gulp-cssmin');
|
||||
var rename = require('gulp-rename');
|
||||
var uglify = require('gulp-uglify');
|
||||
|
||||
gulp.task('css', function() {
|
||||
return gulp.src('assets/scss/oembed.scss')
|
||||
.pipe(sass().on('error', sass.logError))
|
||||
.pipe(autoprefixer())
|
||||
.pipe(rename('oembed.css'))
|
||||
.pipe(cssmin())
|
||||
.pipe(gulp.dest('assets/css'));
|
||||
});
|
||||
|
||||
gulp.task('css-field', function() {
|
||||
return gulp.src('field/assets/scss/field.scss')
|
||||
.pipe(sass().on('error', sass.logError))
|
||||
.pipe(autoprefixer())
|
||||
.pipe(rename('field.css'))
|
||||
.pipe(cssmin())
|
||||
.pipe(gulp.dest('field/assets/css'));
|
||||
});
|
||||
|
||||
gulp.task('js', function() {
|
||||
return gulp.src('assets/js/src/embed.js')
|
||||
.pipe(uglify())
|
||||
.pipe(gulp.dest('assets/js'));
|
||||
});
|
||||
|
||||
gulp.task('watch', function() {
|
||||
gulp.watch('assets/scss/**/*.scss', ['css']);
|
||||
gulp.watch('field/assets/scss/**/*.scss', ['css-field']);
|
||||
gulp.watch('assets/js/src/*.js', ['js']);
|
||||
});
|
||||
20
site/OFF_plugins/embed/package.json
Normal file
20
site/OFF_plugins/embed/package.json
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"name": "embed",
|
||||
"description": "Kirby Embed Plugin",
|
||||
"author": "Nico Hoffmann <nico@getkirby.com>",
|
||||
"version": "3.0.2",
|
||||
"type": "kirby-plugin",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/distantnative/embed"
|
||||
},
|
||||
"dependencies": {
|
||||
"gulp": "^3.9.1",
|
||||
"gulp-autoprefixer": "^4.0.0",
|
||||
"gulp-cssmin": "^0.2.0",
|
||||
"gulp-rename": "^1.2.2",
|
||||
"gulp-sass": "^3.1.0",
|
||||
"gulp-uglify": "^3.0.0"
|
||||
}
|
||||
}
|
||||
9
site/OFF_plugins/embed/registry/field-method.php
Normal file
9
site/OFF_plugins/embed/registry/field-method.php
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
// ================================================
|
||||
// $page->video()->embed()
|
||||
// ================================================
|
||||
|
||||
$kirby->set('field::method', 'embed', function($field, $args = []) {
|
||||
return embed($field->value, $args);
|
||||
});
|
||||
7
site/OFF_plugins/embed/registry/field.php
Normal file
7
site/OFF_plugins/embed/registry/field.php
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
// ================================================
|
||||
// Register panel field
|
||||
// ================================================
|
||||
|
||||
$kirby->set('field', 'embed', dirname(__DIR__) . DS . 'field');
|
||||
32
site/OFF_plugins/embed/registry/route.php
Normal file
32
site/OFF_plugins/embed/registry/route.php
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Embed\Html;
|
||||
|
||||
$kirby->set('route', [
|
||||
'pattern' => 'api/plugin/embed/preview',
|
||||
'action' => function() {
|
||||
$embed = embed(get('url'), ['lazyvideo' => true]);
|
||||
$response = [];
|
||||
|
||||
if($embed->data === false) {
|
||||
$response['success'] = 'false';
|
||||
|
||||
} else {
|
||||
$response['success'] = 'true';
|
||||
$response['title'] = Html::removeEmojis($embed->title());
|
||||
$response['authorName'] = $embed->authorName();
|
||||
$response['authorUrl'] = $embed->authorUrl();
|
||||
$response['providerName'] = $embed->providerName();
|
||||
$response['providerUrl'] = $embed->url();
|
||||
$response['type'] = ucfirst($embed->type());
|
||||
$response['parameters'] = Html::cheatsheet($embed->urlParameters());
|
||||
}
|
||||
|
||||
if(get('code') === 'true') {
|
||||
$response['code'] = (string)$embed;
|
||||
}
|
||||
|
||||
return \response::json($response);
|
||||
},
|
||||
'method' => 'POST'
|
||||
]);
|
||||
31
site/OFF_plugins/embed/registry/tag.php
Normal file
31
site/OFF_plugins/embed/registry/tag.php
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
// ================================================
|
||||
// (embed: …)
|
||||
// ================================================
|
||||
|
||||
$options = [
|
||||
'class' => 'string',
|
||||
'thumb' => 'string',
|
||||
'autoload' => 'bool',
|
||||
'lazyvideo' => 'bool',
|
||||
'jsapi' => 'bool',
|
||||
];
|
||||
|
||||
$kirby->set('tag', 'embed', [
|
||||
'attr' => array_keys($options),
|
||||
'html' => function($tag) use($options) {
|
||||
$args = [];
|
||||
|
||||
foreach($options as $option => $mode) {
|
||||
if($mode === 'bool') {
|
||||
if($tag->attr($option) === 'true') $args[$option] = true;
|
||||
if($tag->attr($option) === 'false') $args[$option] = false;
|
||||
} elseif ($mode === 'string') {
|
||||
if($tag->attr($option)) $args[$option] = $tag->attr($option);
|
||||
}
|
||||
}
|
||||
|
||||
return embed($tag->attr('embed'), $args);
|
||||
}
|
||||
]);
|
||||
8
site/OFF_plugins/embed/translations/de.php
Normal file
8
site/OFF_plugins/embed/translations/de.php
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
|
||||
l::set('plugin.embed.error.noembed', 'Kein Medium gefunden für');
|
||||
l::set('plugin.embed.error.nocode', 'Kein Embed-Code gefunden für');
|
||||
|
||||
l::set('plugin.embed.panelfield.loading', 'Lädt…');
|
||||
l::set('plugin.embed.panelfield.by', 'von');
|
||||
l::set('plugin.embed.panelfield.provider', 'auf');
|
||||
8
site/OFF_plugins/embed/translations/en.php
Normal file
8
site/OFF_plugins/embed/translations/en.php
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
|
||||
l::set('plugin.embed.error.noembed', 'No medium found for URL');
|
||||
l::set('plugin.embed.error.nocode', 'No embed code found for URL');
|
||||
|
||||
l::set('plugin.embed.panelfield.loading', 'Loading…');
|
||||
l::set('plugin.embed.panelfield.by', 'by');
|
||||
l::set('plugin.embed.panelfield.provider', 'on');
|
||||
21
site/OFF_plugins/embed/vendor/Embed/LICENSE
vendored
Normal file
21
site/OFF_plugins/embed/vendor/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.
|
||||
267
site/OFF_plugins/embed/vendor/Embed/README.md
vendored
Normal file
267
site/OFF_plugins/embed/vendor/Embed/README.md
vendored
Normal file
|
|
@ -0,0 +1,267 @@
|
|||
# Embed
|
||||
|
||||
[](https://travis-ci.org/oscarotero/Embed)
|
||||
[](https://scrutinizer-ci.com/g/oscarotero/Embed/)
|
||||
[](https://www.versioneye.com/php/embed:embed/references)
|
||||
[](https://packagist.org/packages/embed/embed)
|
||||
[](https://packagist.org/packages/embed/embed)
|
||||
[](https://packagist.org/packages/embed/embed)
|
||||
[](https://packagist.org/packages/embed/embed)
|
||||
|
||||
[](https://insight.sensiolabs.com/projects/f0beab9f-fe41-47db-8806-373f80c50f9e)
|
||||
|
||||
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 5.5+
|
||||
* Curl library installed
|
||||
|
||||
>
|
||||
* If you need PHP 5.3 support, use the 1.x version
|
||||
* If you need PHP 5.4 support, use the 2.x version
|
||||
|
||||
## Online demo
|
||||
|
||||
http://oscarotero.com/embed3/demo
|
||||
|
||||
## Installation
|
||||
|
||||
This package is installable and autoloadable via Composer as [embed/embed](https://packagist.org/packages/embed/embed).
|
||||
|
||||
```
|
||||
$ composer require embed/embed
|
||||
```
|
||||
|
||||
If you cannot (or don't want to) use composer, just include the [PSR-4 autoload.php file](src/autoloader.php) in your code.
|
||||
|
||||
## Usage
|
||||
|
||||
```php
|
||||
use Embed\Embed;
|
||||
|
||||
//Load any url:
|
||||
$info = Embed::create('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->type; //The page type (link, video, image, rich)
|
||||
$info->tags; //The page keywords (tags)
|
||||
|
||||
$info->images; //List of all images found in the page
|
||||
$info->image; //The image choosen as main image
|
||||
$info->imageWidth; //The width of the main image
|
||||
$info->imageHeight; //The height of the main image
|
||||
|
||||
$info->code; //The code to embed the image, video, etc
|
||||
$info->width; //The width of the embed code
|
||||
$info->height; //The height of the embed code
|
||||
$info->aspectRatio; //The aspect ratio (width/height)
|
||||
|
||||
$info->authorName; //The resource author
|
||||
$info->authorUrl; //The author url
|
||||
|
||||
$info->providerName; //The provider name of the page (Youtube, Twitter, Instagram, etc)
|
||||
$info->providerUrl; //The provider url
|
||||
$info->providerIcons; //All provider icons found in the page
|
||||
$info->providerIcon; //The icon choosen as main icon
|
||||
|
||||
$info->publishedDate; //The published date of the resource
|
||||
$info->license; //The license url of the resource
|
||||
$info->linkedData; //The linked-data info (http://json-ld.org/)
|
||||
$info->feeds; //The RSS/Atom feeds
|
||||
```
|
||||
|
||||
## The adapter
|
||||
|
||||
The adapter is the class that get all information of the page from the providers and choose the best result for each value. For example, a page can provide multiple titles from opengraph, twitter cards, oembed, the `<title>` html element, etc, so the adapter get all this titles and choose the best one.
|
||||
|
||||
Embed has an generic adapter called "Webpage" to use with any web but has also some specific adapters for sites like archive.org, facebook, google, github, spotify, etc, that provides information using their own apis, or need to fix any specific issue.
|
||||
|
||||
The available options for the adapters are:
|
||||
|
||||
Name | Type | Description
|
||||
-----|------|------------
|
||||
`min_image_width` | `int` | Minimal image width used to choose the main image
|
||||
`min_image_height` | `int` | Minimal image height used to choose the main image
|
||||
`images_blacklist` | `string|array` | Images that you don't want to be used. Could be plain text or [Uri](https://github.com/oscarotero/Embed/blob/master/src/Uri.php) match pattern.
|
||||
`choose_bigger_image` | `bool` | Choose the bigger image as the main image (instead the first found, that usually is the most relevant).
|
||||
|
||||
## The providers
|
||||
|
||||
The providers get the data from different sources. Each source has it's own provider. For example, there is a provider for opengraph, other for twitter cards, for oembed, html, etc. Some providers can be configured and are the following:
|
||||
|
||||
### oembed
|
||||
|
||||
Used to get data from oembed api if it's available:
|
||||
|
||||
Name | Type | Description
|
||||
-----|------|------------
|
||||
`parameters` | `array` | Extra query parameters to send with the oembed request
|
||||
`embedly_key` | `string` | If it's defined, use embed.ly api as fallback oembed provider.
|
||||
`iframely_key` | `string` | If it's defined, use iframe.ly api as fallback oembed provider.
|
||||
|
||||
### html
|
||||
|
||||
Used to get data directly from the html code of the page:
|
||||
|
||||
Name | Type | Description
|
||||
-----|------|------------
|
||||
`max_images` | `int` | Max number of images fetched from the html code (searching for the `<img>` elements). By default is -1 (no limit). Use 0 to no get images.
|
||||
`external_images` | `bool|array` | By default is false, this means that images located in other domains are not allowed. You can set true (allow all) or provide an array of url patterns.
|
||||
|
||||
### google
|
||||
|
||||
Used only for google maps to generate the embed code.
|
||||
|
||||
Name | Type | Description
|
||||
-----|------|------------
|
||||
`key` | `string` | The key used [for the embed api](https://developers.google.com/maps/documentation/embed/)
|
||||
|
||||
### soundcloud
|
||||
|
||||
Used only for soundcloud pages, to get information using its api.
|
||||
|
||||
Name | Type | Description
|
||||
-----|------|------------
|
||||
`key` | `string` | The key used to get info from soundcloud API.
|
||||
|
||||
## Example with all options:
|
||||
|
||||
The options are passed as the second argument as you can see in the following example:
|
||||
|
||||
```php
|
||||
$info = Embed::create($url, [
|
||||
'min_image_width' => 100,
|
||||
'min_image_height' => 100,
|
||||
'images_blacklist' => 'example.com/*',
|
||||
'choose_bigger_image' => true,
|
||||
|
||||
'html' => [
|
||||
'max_images' => 10,
|
||||
'external_images' => true
|
||||
],
|
||||
|
||||
'oembed' => [
|
||||
'parameters' => [],
|
||||
'embedly_key' => 'YOUR_KEY',
|
||||
'iframely_key' => 'YOUR_KEY',
|
||||
],
|
||||
|
||||
'google' => [
|
||||
'key' => 'YOUR_KEY',
|
||||
],
|
||||
|
||||
'soundcloud' => [
|
||||
'key' => 'YOUR_KEY',
|
||||
],
|
||||
]);
|
||||
```
|
||||
|
||||
## The dispatcher
|
||||
|
||||
To dispatch the http request, Embed includes the interface `Embed\Http\DispatcherInterface`. By default the curl library is used but you can create your own dispatcher to use any other library like [guzzle](https://github.com/guzzle/guzzle):
|
||||
|
||||
```php
|
||||
use Embed\Embed;
|
||||
use Embed\Http\DispatcherInteface;
|
||||
use Embed\Http\Url;
|
||||
use Embed\Http\Response;
|
||||
use Embed\Http\ImageResponse;
|
||||
|
||||
class MyDispatcher implements DispatcherInterface
|
||||
{
|
||||
public function dispatch(Url $url)
|
||||
{
|
||||
$result = function_to_execute_request($url);
|
||||
|
||||
return new Response($url, $result['url'], $result['status'], $result['type'], $result['content'], $result['headers']);
|
||||
}
|
||||
|
||||
public function dispatchImages(array $urls)
|
||||
{
|
||||
$responses = [];
|
||||
|
||||
foreach ($urls as $url) {
|
||||
$result = function_to_get_image_size($url);
|
||||
|
||||
if ($result) {
|
||||
$responses[] = new ImageResponse($url, $result['url'], $result['status'], $result['type'], $result['size'], $result['headers']);
|
||||
}
|
||||
}
|
||||
|
||||
return $responses;
|
||||
}
|
||||
}
|
||||
|
||||
//Use the dispatcher passing as third argument
|
||||
$info = Embed::create('http://example.com', [], new MyDispatcher());
|
||||
```
|
||||
|
||||
The default curl dispatcher accepts the same options that the [curl_setopt PHP function](http://php.net/manual/en/function.curl-setopt.php). You can edit the default values:
|
||||
|
||||
```php
|
||||
use Embed\Embed;
|
||||
use Embed\Http\CurlDispatcher;
|
||||
|
||||
$dispatcher = new CurlDispatcher([
|
||||
CURLOPT_MAXREDIRS => 20,
|
||||
CURLOPT_CONNECTTIMEOUT => 10,
|
||||
CURLOPT_TIMEOUT => 10,
|
||||
CURLOPT_SSL_VERIFYPEER => false,
|
||||
CURLOPT_SSL_VERIFYHOST => false,
|
||||
CURLOPT_ENCODING => '',
|
||||
CURLOPT_AUTOREFERER => true,
|
||||
CURLOPT_USERAGENT => 'Embed PHP Library',
|
||||
CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4,
|
||||
]);
|
||||
|
||||
$info = Embed::create('http://example.com', [], $dispatcher);
|
||||
```
|
||||
|
||||
## Accessing to advanced data
|
||||
|
||||
The adapter get the data from all providers and choose the best values. But you can get all available values accessing directly to each provider. There's also the possibility to inspect all http requests executed for debug purposes:
|
||||
|
||||
```php
|
||||
use Embed\Embed;
|
||||
|
||||
//Get the info
|
||||
$info = Embed::create('https://www.youtube.com/watch?v=PP1xn5wHtxE');
|
||||
|
||||
//Get all providers
|
||||
$providers = $info->getProviders();
|
||||
|
||||
//Get the oembed provider
|
||||
$oembed = $providers['oembed'];
|
||||
|
||||
//Get the oembed title value:
|
||||
echo $oembed->getTitle();
|
||||
|
||||
//Get any value returned by the oembed api
|
||||
echo $oembed->bag->get('author_name');
|
||||
|
||||
//Get the main response object
|
||||
$response = $info->getResponse();
|
||||
|
||||
//Get any http response header
|
||||
$lastModified = $response->getHeader('Last-Modifier');
|
||||
|
||||
//Get the html body as DOMDocument
|
||||
$html = $response->getHtmlContent();
|
||||
|
||||
//Get all http request executed (oembed endpoints, images, apis, etc...)
|
||||
$dispatcher = $adapter->getDispatcher();
|
||||
|
||||
foreach ($dispatcher->getAllResponses() as $response) {
|
||||
echo 'The request to '.$response->getStartingUrl();
|
||||
echo ' is resolved to '.$response->getUrl();
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
If this library is useful for you, say thanks [buying me a beer :beer:](https://www.paypal.me/oscarotero)!
|
||||
49
site/OFF_plugins/embed/vendor/Embed/composer.json
vendored
Normal file
49
site/OFF_plugins/embed/vendor/Embed/composer.json
vendored
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
{
|
||||
"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": "^5.5|^7.0",
|
||||
"ext-curl": "*",
|
||||
"ext-mbstring": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8|^5.7",
|
||||
"friendsofphp/php-cs-fixer": "^2.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Embed\\": "src"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Embed\\Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"test": "phpunit",
|
||||
"cs-fix": "php-cs-fixer fix ."
|
||||
}
|
||||
}
|
||||
648
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Adapter.php
vendored
Normal file
648
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Adapter.php
vendored
Normal file
|
|
@ -0,0 +1,648 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Adapters;
|
||||
|
||||
use Embed\Http\Url;
|
||||
use Embed\Http\Response;
|
||||
use Embed\Http\ImageResponse;
|
||||
use Embed\Http\DispatcherInterface;
|
||||
use Embed\DataInterface;
|
||||
use Embed\Providers\Provider;
|
||||
use Embed\Bag;
|
||||
|
||||
/**
|
||||
* Base class extended by all adapters.
|
||||
*
|
||||
* @property null|string $title
|
||||
* @property null|string $description
|
||||
* @property null|string $url
|
||||
* @property null|string $type
|
||||
* @property array $tags
|
||||
* @property array $feeds
|
||||
* @property array $images
|
||||
* @property array $imagesUrls
|
||||
* @property null|string $image
|
||||
* @property null|int $imageWidth
|
||||
* @property null|int $imageHeight
|
||||
* @property null|string $code
|
||||
* @property null|int $width
|
||||
* @property null|int $height
|
||||
* @property null|float $aspectRatio
|
||||
* @property null|string $authorName
|
||||
* @property null|string $authorUrl
|
||||
* @property array $providerIcons
|
||||
* @property array $providerIconsUrls
|
||||
* @property null|string $providerIcon
|
||||
* @property null|string $providerName
|
||||
* @property null|string $providerUrl
|
||||
* @property null|string $publishedTime
|
||||
*/
|
||||
abstract class Adapter implements DataInterface
|
||||
{
|
||||
protected $config;
|
||||
protected $dispatcher;
|
||||
protected $response;
|
||||
protected $providers = [];
|
||||
|
||||
/**
|
||||
* Checks whether the response is valid to this Adapter.
|
||||
*
|
||||
* @param Response $response
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function check(Response $response)
|
||||
{
|
||||
return $response->isValid();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Response $response
|
||||
* @param array $config
|
||||
* @param DispatcherInterface $dispatcher
|
||||
*/
|
||||
public function __construct(Response $response, array $config, DispatcherInterface $dispatcher)
|
||||
{
|
||||
$this->response = $response;
|
||||
$this->config = new Bag($config);
|
||||
$this->dispatcher = $dispatcher;
|
||||
|
||||
$this->init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the providers
|
||||
*/
|
||||
abstract protected function init();
|
||||
|
||||
/**
|
||||
* Magic method to execute methods to return paramaters
|
||||
* For example, $source->sourceUrl executes $source->getSourceUrl().
|
||||
*
|
||||
* @param string $name The property name
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
$method = 'get'.$name;
|
||||
|
||||
if (method_exists($this, $method)) {
|
||||
return $this->$name = $this->$method();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic method to execute methods to check if parameters are empty
|
||||
*
|
||||
* @param string $name The property name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function __isset($name)
|
||||
{
|
||||
$value = $this->$name;
|
||||
|
||||
return !empty($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the dispatcher used.
|
||||
*
|
||||
* @return DispatcherInterface
|
||||
*/
|
||||
public function getDispatcher()
|
||||
{
|
||||
return $this->dispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the main response instance.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function getResponse()
|
||||
{
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a config value.
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $default
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getConfig($name, $default = null)
|
||||
{
|
||||
$value = $this->config->get($name);
|
||||
|
||||
return $value === null ? $default : $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all providers.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getProviders()
|
||||
{
|
||||
return $this->providers;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
$default = $this->url;
|
||||
|
||||
return $this->getFirstFromProviders(function (Provider $provider) {
|
||||
return $provider->getTitle();
|
||||
}, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->getFirstFromProviders(function (Provider $provider) {
|
||||
return $provider->getDescription();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
$code = $this->code;
|
||||
|
||||
if (empty($code)) {
|
||||
return 'link';
|
||||
}
|
||||
|
||||
if (strpos($code, '</video>')) {
|
||||
return 'video';
|
||||
}
|
||||
|
||||
//Get the most repeated type
|
||||
$types = [];
|
||||
|
||||
foreach ($this->providers as $provider) {
|
||||
$type = $provider->getType();
|
||||
|
||||
if ($type !== null) {
|
||||
if (!isset($types[$type])) {
|
||||
$types[$type] = 0;
|
||||
}
|
||||
|
||||
++$types[$type];
|
||||
}
|
||||
}
|
||||
|
||||
//If it has code, it's not a link
|
||||
unset($types['link']);
|
||||
|
||||
return static::getBigger($types) ?: 'rich';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTags()
|
||||
{
|
||||
return $this->getAllFromProviders(function (Provider $provider) {
|
||||
return $provider->getTags();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFeeds()
|
||||
{
|
||||
return $this->getAllFromProviders(function (Provider $provider) {
|
||||
return $provider->getFeeds();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
//Width and height deppends to the code
|
||||
$this->width = null;
|
||||
$this->height = null;
|
||||
|
||||
$codes = [];
|
||||
|
||||
foreach ($this->providers as $provider) {
|
||||
$code = $provider->getCode();
|
||||
|
||||
if (!empty($code)) {
|
||||
$codes[] = [
|
||||
'code' => $code,
|
||||
'width' => $provider->getWidth(),
|
||||
'height' => $provider->getHeight(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($codes)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Use only html5 codes
|
||||
$html5 = array_filter($codes, function (array $code) {
|
||||
return strpos($code['code'], '</object>') === false && strpos($code['code'], '</embed>') === false;
|
||||
});
|
||||
|
||||
//If it's not html5 codes, returns flash
|
||||
if (empty($html5)) {
|
||||
$code = current($codes);
|
||||
} else {
|
||||
$code = current($html5);
|
||||
}
|
||||
|
||||
$this->width = is_numeric($code['width']) ? (int) $code['width'] : $code['width'];
|
||||
$this->height = is_numeric($code['height']) ? (int) $code['height'] : $code['height'];
|
||||
|
||||
return $code['code'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getUrl()
|
||||
{
|
||||
$default = (string) $this->getResponse()->getUrl();
|
||||
|
||||
return $this->getFirstFromProviders(function (Provider $provider) {
|
||||
return $provider->getUrl();
|
||||
}, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAuthorName()
|
||||
{
|
||||
return $this->getFirstFromProviders(function (Provider $provider) {
|
||||
return $provider->getAuthorName();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAuthorUrl()
|
||||
{
|
||||
return $this->getFirstFromProviders(function (Provider $provider) {
|
||||
return $provider->getAuthorUrl();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getProviderIconsUrls()
|
||||
{
|
||||
$urls = [
|
||||
$this->getResponse()->getUrl()->getAbsolute('/favicon.ico'),
|
||||
$this->getResponse()->getUrl()->getAbsolute('/favicon.png'),
|
||||
];
|
||||
|
||||
foreach ($this->providers as $provider) {
|
||||
foreach ($provider->getProviderIconsUrls() as $url) {
|
||||
if (!in_array($url, $urls, true)) {
|
||||
$urls[] = $url;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $urls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all icon provider urls found
|
||||
* It returns also the width, height and mime-type.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getProviderIcons()
|
||||
{
|
||||
return $this->dispatchImagesInfo($this->providerIconsUrls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the best icon provider
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getProviderIcon()
|
||||
{
|
||||
$icons = $this->providerIcons;
|
||||
|
||||
if (empty($icons)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$sizes = [];
|
||||
|
||||
foreach ($icons as $icon) {
|
||||
$sizes[$icon['url']] = $icon['size'];
|
||||
}
|
||||
|
||||
return static::getBigger($sizes);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getProviderName()
|
||||
{
|
||||
$default = $this->getResponse()->getUrl()->getDomain();
|
||||
|
||||
return $this->getFirstFromProviders(function (Provider $provider) {
|
||||
return $provider->getProviderName();
|
||||
}, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getProviderUrl()
|
||||
{
|
||||
$url = $this->getResponse()->getUrl();
|
||||
$default = $url->getScheme().'://'.$url->getDomain(true);
|
||||
|
||||
return $this->getFirstFromProviders(function (Provider $provider) {
|
||||
return $provider->getProviderUrl();
|
||||
}, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getImagesUrls()
|
||||
{
|
||||
$urls = $this->getAllFromProviders(function (Provider $provider) {
|
||||
return $provider->getImagesUrls();
|
||||
});
|
||||
|
||||
$blacklist = $this->getConfig('images_blacklist');
|
||||
|
||||
if (!empty($blacklist)) {
|
||||
$urls = array_filter($urls, function ($url) use ($blacklist) {
|
||||
return !Url::create($url)->match($blacklist);
|
||||
});
|
||||
}
|
||||
|
||||
return array_values($urls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all images found in the webpage
|
||||
* It returns also the width, height and mime-type.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getImages()
|
||||
{
|
||||
return $this->dispatchImagesInfo($this->imagesUrls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the best image
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getImage()
|
||||
{
|
||||
$this->imageWidth = null;
|
||||
$this->imageHeight = null;
|
||||
|
||||
$images = $this->images;
|
||||
$bigger = (bool) $this->getConfig('choose_bigger_image');
|
||||
$minWidth = $this->getConfig('min_image_width', 1);
|
||||
$minHeight = $this->getConfig('min_image_height', 1);
|
||||
|
||||
$images = array_filter($images, function ($image) use ($minWidth, $minHeight) {
|
||||
return $image['width'] >= $minWidth && $image['height'] >= $minHeight;
|
||||
});
|
||||
|
||||
if (empty($images)) {
|
||||
return;
|
||||
}
|
||||
|
||||
reset($images);
|
||||
$image = current($images);
|
||||
|
||||
if ($bigger) {
|
||||
$sizes = [];
|
||||
|
||||
foreach ($images as $img) {
|
||||
$sizes[$img['url']] = $img['size'];
|
||||
}
|
||||
|
||||
$biggest = static::getBigger($sizes);
|
||||
|
||||
foreach ($images as $img) {
|
||||
if ($biggest == $img['url']) {
|
||||
$image = $img;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->imageWidth = $image['width'];
|
||||
$this->imageHeight = $image['height'];
|
||||
|
||||
return $image['url'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the image width.
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getImageWidth()
|
||||
{
|
||||
$this->image = $this->getImage();
|
||||
|
||||
return $this->imageWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the image height.
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getImageHeight()
|
||||
{
|
||||
$this->image = $this->getImage();
|
||||
|
||||
return $this->imageHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getWidth()
|
||||
{
|
||||
$this->code = $this->getCode();
|
||||
|
||||
return $this->width;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getHeight()
|
||||
{
|
||||
$this->code = $this->getCode();
|
||||
|
||||
return $this->height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the aspect ratio of the embedded widget
|
||||
* (useful to make it responsive).
|
||||
*
|
||||
* @return float|null
|
||||
*/
|
||||
public function getAspectRatio()
|
||||
{
|
||||
if ($this->width !== null
|
||||
&& (strpos($this->width, '%') === false)
|
||||
&& $this->height !== null && (strpos($this->height, '%') === false)) {
|
||||
return round(($this->height / $this->width) * 100, 3);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPublishedTime()
|
||||
{
|
||||
return $this->getFirstFromProviders(function (Provider $provider) {
|
||||
return $provider->getPublishedTime();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLicense()
|
||||
{
|
||||
return $this->getFirstFromProviders(function (Provider $provider) {
|
||||
return $provider->getLicense();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLinkedData()
|
||||
{
|
||||
return $this->getAllFromProviders(function (Provider $provider) {
|
||||
return $provider->getLinkedData();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get images info.
|
||||
*
|
||||
* @param array $urls
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function dispatchImagesInfo($urls)
|
||||
{
|
||||
if (empty($urls)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$requests = [];
|
||||
|
||||
foreach ($urls as $url) {
|
||||
$requests[] = Url::create($url);
|
||||
}
|
||||
|
||||
return array_map(
|
||||
function (ImageResponse $response) {
|
||||
return [
|
||||
'url' => (string) $response->getUrl(),
|
||||
'width' => $response->getWidth(),
|
||||
'height' => $response->getHeight(),
|
||||
'size' => $response->getWidth() * $response->getHeight(),
|
||||
'mime' => $response->getContentType(),
|
||||
];
|
||||
},
|
||||
$this->getDispatcher()->dispatchImages($requests)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key of the bigger value in an array
|
||||
*
|
||||
* @param array $values
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
protected static function getBigger(array $values)
|
||||
{
|
||||
$bigger = null;
|
||||
|
||||
foreach ($values as $value => $repeat) {
|
||||
if ($bigger === null || $repeat > $values[$bigger]) {
|
||||
$bigger = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $bigger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first value of the providers
|
||||
*
|
||||
* @param callable $callable
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
protected function getFirstFromProviders(callable $callable, $default = null)
|
||||
{
|
||||
$values = array_filter(array_map($callable, $this->providers));
|
||||
|
||||
return empty($values) ? $default : current($values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the all values from the providers
|
||||
*
|
||||
* @param callable $callable
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
protected function getAllFromProviders(callable $callable)
|
||||
{
|
||||
$values = array_filter(array_map($callable, $this->providers));
|
||||
$all = [];
|
||||
|
||||
foreach ($values as $value) {
|
||||
foreach ($value as $v) {
|
||||
if (!in_array($v, $all, true)) {
|
||||
$all[] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $all;
|
||||
}
|
||||
}
|
||||
57
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Archive.php
vendored
Normal file
57
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Archive.php
vendored
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Adapters;
|
||||
|
||||
use Embed\Http\Response;
|
||||
use Embed\Utils;
|
||||
use Embed\Providers\Api;
|
||||
|
||||
/**
|
||||
* Adapter to provide information from archive.org API.
|
||||
*/
|
||||
class Archive extends Webpage
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function check(Response $response)
|
||||
{
|
||||
return $response->isValid() && $response->getUrl()->match([
|
||||
'archive.org/details/*',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function init()
|
||||
{
|
||||
parent::init();
|
||||
|
||||
$this->providers = ['archive' => new Api\Archive($this)] + $this->providers;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
return Utils::iframe(str_replace('/details/', '/embed/', $this->url), $this->width, $this->height);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getWidth()
|
||||
{
|
||||
return 640;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getHeight()
|
||||
{
|
||||
return 480;
|
||||
}
|
||||
}
|
||||
48
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Cadenaser.php
vendored
Normal file
48
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Cadenaser.php
vendored
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Adapters;
|
||||
|
||||
use Embed\Utils;
|
||||
use Embed\Http\Response;
|
||||
|
||||
/**
|
||||
* Adapter to get the embed code from play.cadenaser.com.
|
||||
*/
|
||||
class Cadenaser extends Webpage
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function check(Response $response)
|
||||
{
|
||||
return $response->isValid() && $response->getUrl()->match([
|
||||
'play.cadenaser.com/audio/*',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
$url = $this->getResponse()->getUrl();
|
||||
|
||||
return Utils::iframe($url->withPath('/widget/'.$url->getPath()), $this->width, $this->height);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getWidth()
|
||||
{
|
||||
return 620;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getHeight()
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
}
|
||||
35
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Carto.php
vendored
Normal file
35
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Carto.php
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Adapters;
|
||||
|
||||
use Embed\Http\Response;
|
||||
use Embed\Utils;
|
||||
|
||||
/**
|
||||
* Adapter to get the embed code from cartodb.
|
||||
*/
|
||||
class Carto extends Webpage
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function check(Response $response)
|
||||
{
|
||||
return $response->isValid() && $response->getUrl()->match([
|
||||
'*.carto.com/viz/*/public_map',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
$this->width = null;
|
||||
$this->height = 520;
|
||||
|
||||
$url = $this->getResponse()->getUrl()->withDirectoryPosition(2, 'embed_map');
|
||||
|
||||
return Utils::iframe($url, '100%', $this->height);
|
||||
}
|
||||
}
|
||||
97
site/OFF_plugins/embed/vendor/Embed/src/Adapters/File.php
vendored
Normal file
97
site/OFF_plugins/embed/vendor/Embed/src/Adapters/File.php
vendored
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Adapters;
|
||||
|
||||
use Embed\Http\Response;
|
||||
use Embed\Utils;
|
||||
use Embed\Providers;
|
||||
|
||||
/**
|
||||
* Adapter to provide information from raw files.
|
||||
*/
|
||||
class File extends Adapter
|
||||
{
|
||||
private static $contentTypes = [
|
||||
'video/ogg' => ['video', 'videoHtml'],
|
||||
'application/ogg' => ['video', 'videoHtml'],
|
||||
'video/ogv' => ['video', 'videoHtml'],
|
||||
'video/webm' => ['video', 'videoHtml'],
|
||||
'video/mp4' => ['video', 'videoHtml'],
|
||||
'audio/ogg' => ['audio', 'audioHtml'],
|
||||
'audio/mp3' => ['audio', 'audioHtml'],
|
||||
'audio/mpeg' => ['audio', 'audioHtml'],
|
||||
'audio/webm' => ['audio', 'audioHtml'],
|
||||
'image/jpeg' => ['photo', 'imageHtml'],
|
||||
'image/gif' => ['photo', 'imageHtml'],
|
||||
'image/png' => ['photo', 'imageHtml'],
|
||||
'image/bmp' => ['photo', 'imageHtml'],
|
||||
'image/ico' => ['photo', 'imageHtml'],
|
||||
'text/rtf' => ['rich', 'google'],
|
||||
'application/pdf' => ['rich', 'google'],
|
||||
'application/msword' => ['rich', 'google'],
|
||||
'application/vnd.ms-powerpoint' => ['rich', 'google'],
|
||||
'application/vnd.ms-excel' => ['rich', 'google'],
|
||||
'application/zip' => ['rich', 'google'],
|
||||
'application/postscript' => ['rich', 'google'],
|
||||
'application/octet-stream' => ['rich', 'google'],
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function check(Response $response)
|
||||
{
|
||||
return $response->isValid() && isset(self::$contentTypes[$response->getContentType()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function init()
|
||||
{
|
||||
$this->providers = [
|
||||
'oembed' => new Providers\OEmbed($this),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return self::$contentTypes[$this->getResponse()->getContentType()][0];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
if (($code = parent::getcode())) {
|
||||
return $code;
|
||||
}
|
||||
|
||||
switch (self::$contentTypes[$this->getResponse()->getContentType()][1]) {
|
||||
case 'videoHtml':
|
||||
return Utils::videoHtml($this->image, $this->url, $this->imageWidth, $this->imageHeight);
|
||||
|
||||
case 'audioHtml':
|
||||
return Utils::audioHtml($this->url);
|
||||
|
||||
case 'google':
|
||||
return Utils::google($this->url);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getImagesUrls()
|
||||
{
|
||||
if ($this->type === 'photo') {
|
||||
return [$this->url];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
47
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Flickr.php
vendored
Normal file
47
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Flickr.php
vendored
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Adapters;
|
||||
|
||||
use Embed\Http\Response;
|
||||
use Embed\Utils;
|
||||
|
||||
/**
|
||||
* Adapter provider more information from flickr.
|
||||
*/
|
||||
class Flickr extends Webpage
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function check(Response $response)
|
||||
{
|
||||
return $response->isValid() && $response->getUrl()->match([
|
||||
'www.flickr.com/photos/*',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
$code = parent::getCode();
|
||||
|
||||
if (empty($code)) {
|
||||
$this->width = 640;
|
||||
$this->height = 425;
|
||||
|
||||
$code = Utils::iframe($this->getResponse()->getUrl()->withAddedPath('player'), $this->width, $this->height);
|
||||
}
|
||||
|
||||
return $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getProviderName()
|
||||
{
|
||||
return 'Flickr';
|
||||
}
|
||||
}
|
||||
74
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Github.php
vendored
Normal file
74
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Github.php
vendored
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Adapters;
|
||||
|
||||
use Embed\Http\Response;
|
||||
use Embed\Providers\Api;
|
||||
|
||||
/**
|
||||
* Adapter to get the embed code from gist.github.com.
|
||||
*/
|
||||
class Github extends Webpage
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function check(Response $response)
|
||||
{
|
||||
return $response->isValid() && $response->getUrl()->match([
|
||||
'gist.github.com/*/*',
|
||||
'github.com/*',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function init()
|
||||
{
|
||||
parent::init();
|
||||
|
||||
if ($this->getResponse()->getUrl()->getHost() === 'gist.github.com') {
|
||||
$this->providers = ['gist' => new Api\Gist($this)] + $this->providers;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getUrl()
|
||||
{
|
||||
//Open graph returns as canonical url the main repo url, instead the file
|
||||
return (string) $this->getResponse()->getUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
$this->width = null;
|
||||
$this->height = null;
|
||||
|
||||
$url = $this->getResponse()->getUrl();
|
||||
|
||||
if ($url->match('github.com/*/*/blob/*')) {
|
||||
$username = $url->getDirectoryPosition(0);
|
||||
$repo = $url->getDirectoryPosition(1);
|
||||
$ref = $url->getDirectoryPosition(3);
|
||||
$path_to_file = implode('/', $url->getSlicePath(4));
|
||||
|
||||
switch ($url->getExtension()) {
|
||||
case 'geojson':
|
||||
//https://help.github.com/articles/mapping-geojson-files-on-github/#embedding-your-map-elsewhere
|
||||
return "<script src=\"https://embed.githubusercontent.com/view/geojson/{$username}/{$repo}/{$ref}/{$path_to_file}\"></script>";
|
||||
|
||||
case 'stl':
|
||||
//https://help.github.com/articles/3d-file-viewer/#embedding-your-model-elsewhere
|
||||
return "<script src=\"https://embed.githubusercontent.com/view/3d/{$username}/{$repo}/{$ref}/{$path_to_file}\"></script>";
|
||||
}
|
||||
}
|
||||
|
||||
return parent::getCode();
|
||||
}
|
||||
}
|
||||
91
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Google.php
vendored
Normal file
91
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Google.php
vendored
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Adapters;
|
||||
|
||||
use Embed\Http\Response;
|
||||
use Embed\Utils;
|
||||
use Embed\Providers\Api;
|
||||
|
||||
/**
|
||||
* Adapter provider more information from google maps and google drive.
|
||||
*/
|
||||
class Google extends Webpage
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function check(Response $response)
|
||||
{
|
||||
return $response->isValid() && $response->getUrl()->match([
|
||||
'maps.google.*',
|
||||
'www.google.*/maps*',
|
||||
'calendar.google.com/calendar/*',
|
||||
'drive.google.com/file/*/view',
|
||||
'plus.google.com/*/posts/*',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function init()
|
||||
{
|
||||
parent::init();
|
||||
|
||||
if ($this->getResponse()->getUrl()->match('*/maps/*')) {
|
||||
$this->providers = ['google' => new Api\GoogleMaps($this)] + $this->providers;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
$this->width = null;
|
||||
$this->height = null;
|
||||
|
||||
$url = $this->getResponse()->getUrl();
|
||||
|
||||
if ($url->getHost() === 'plus.google.com') {
|
||||
return '<script src="https://apis.google.com/js/plusone.js" type="text/javascript"></script>'
|
||||
.'<div class="g-post" data-href="'.$url.'"></div>';
|
||||
}
|
||||
|
||||
if ($url->getHost() === 'calendar.google.com') {
|
||||
return Utils::iframe($url);
|
||||
}
|
||||
|
||||
if (isset($this->providers['google'])) {
|
||||
return $this->providers['google']->getCode();
|
||||
}
|
||||
|
||||
return Utils::iframe($url
|
||||
->withDirectoryPosition(3, 'preview')
|
||||
->withQueryParameters([]));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getImagesUrls()
|
||||
{
|
||||
if ($this->getResponse()->getUrl()->getHost() === 'plus.google.com') {
|
||||
return parent::getImagesUrls();
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getProviderName()
|
||||
{
|
||||
if ($this->getResponse()->getUrl()->getHost() === 'plus.google.com') {
|
||||
return 'Google Plus';
|
||||
}
|
||||
|
||||
return parent::getProviderName();
|
||||
}
|
||||
}
|
||||
39
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Howcast.php
vendored
Normal file
39
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Howcast.php
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Adapters;
|
||||
|
||||
use Embed\Http\Response;
|
||||
|
||||
/**
|
||||
* Adapter to get the embed code from howcast.com.
|
||||
*/
|
||||
class Howcast extends Webpage
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function check(Response $response)
|
||||
{
|
||||
return $response->isValid() && $response->getUrl()->match([
|
||||
'www.howcast.com/videos/*',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
$this->width = null;
|
||||
$this->height = null;
|
||||
|
||||
$dom = $this->getResponse()->getHtmlContent();
|
||||
$modal = $dom->getElementById('embedModal');
|
||||
|
||||
if ($modal) {
|
||||
foreach ($dom->getElementsByTagName('textarea') as $textarea) {
|
||||
return $textarea->nodeValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
36
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Ideone.php
vendored
Normal file
36
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Ideone.php
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Adapters;
|
||||
|
||||
use Embed\Http\Response;
|
||||
use Embed\Utils;
|
||||
|
||||
/**
|
||||
* Adapter to generate embed code from ideone.com.
|
||||
*/
|
||||
class Ideone extends Webpage
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function check(Response $response)
|
||||
{
|
||||
return $response->isValid() && $response->getUrl()->match([
|
||||
'ideone.com/*',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
$this->width = null;
|
||||
$this->height = null;
|
||||
|
||||
$url = $this->getResponse()->getUrl();
|
||||
$path = '/e.js'.$url->getPath();
|
||||
|
||||
return Utils::script($url->getAbsolute($path));
|
||||
}
|
||||
}
|
||||
32
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Imageshack.php
vendored
Normal file
32
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Imageshack.php
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Adapters;
|
||||
|
||||
use Embed\Http\Response;
|
||||
use Embed\Providers\Api;
|
||||
|
||||
/**
|
||||
* Adapter to provide information from imageshack.
|
||||
*/
|
||||
class Imageshack extends Webpage
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function check(Response $response)
|
||||
{
|
||||
return $response->isValid() && $response->getUrl()->match([
|
||||
'imageshack.com/i/*',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function init()
|
||||
{
|
||||
parent::init();
|
||||
|
||||
$this->providers = ['imageshack' => new Api\Imageshack($this)] + $this->providers;
|
||||
}
|
||||
}
|
||||
25
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Jsfiddle.php
vendored
Normal file
25
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Jsfiddle.php
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Adapters;
|
||||
|
||||
use Embed\Utils;
|
||||
|
||||
/**
|
||||
* Adapter to fix some issues from jsfiddle.
|
||||
*/
|
||||
class Jsfiddle extends Webpage
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
$this->width = null;
|
||||
$this->height = null;
|
||||
|
||||
$url = $this->url;
|
||||
$embed_url = $url.((substr($url, -1) === '/') ? 'embedded/' : '/embedded/');
|
||||
|
||||
return Utils::iframe($embed_url);
|
||||
}
|
||||
}
|
||||
33
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Lavozdegalicia.php
vendored
Normal file
33
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Lavozdegalicia.php
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Adapters;
|
||||
|
||||
use Embed\Http\Response;
|
||||
|
||||
/**
|
||||
* Adapter to provide all information from lavozdegalicia.es that needs a special query parameter to generate a session cookie.
|
||||
*/
|
||||
class Lavozdegalicia extends Webpage
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function check(Response $response)
|
||||
{
|
||||
return $response->isValid() && $response->getUrl()->match([
|
||||
'www.lavozdegalicia.es/*',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function init()
|
||||
{
|
||||
parent::init();
|
||||
|
||||
$url = $this->getResponse()->getStartingUrl();
|
||||
|
||||
$this->response = $this->getDispatcher()->dispatch($url->withQueryParameter('piano_d', '1'));
|
||||
}
|
||||
}
|
||||
49
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Line.php
vendored
Normal file
49
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Line.php
vendored
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Adapters;
|
||||
|
||||
use Embed\Utils;
|
||||
use Embed\Http\Response;
|
||||
|
||||
/**
|
||||
* Adapter to get the embed code from line.do.
|
||||
*/
|
||||
class Line extends Webpage
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function check(Response $response)
|
||||
{
|
||||
return $response->isValid() && $response->getUrl()->match([
|
||||
'line.do/*',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
$url = $this->getResponse()->getUrl();
|
||||
$id = $url->getDirectoryPosition(2);
|
||||
|
||||
return Utils::iframe($url->withPath("embed/{$id}/vertical"), $this->width, $this->height, 'border:1px solid #e7e7e7;');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getWidth()
|
||||
{
|
||||
return 640;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getHeight()
|
||||
{
|
||||
return 640;
|
||||
}
|
||||
}
|
||||
64
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Mit.php
vendored
Normal file
64
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Mit.php
vendored
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Adapters;
|
||||
|
||||
use Embed\Http\Response;
|
||||
use Embed\Utils;
|
||||
|
||||
/**
|
||||
* Adapter to fix some issues from mit.edu (not complete yet).
|
||||
*/
|
||||
class Mit extends Webpage
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function check(Response $response)
|
||||
{
|
||||
return $response->isValid() && $response->getUrl()->match([
|
||||
'video.mit.edu/watch/*',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
$url = preg_replace('|(/watch/[\w-]+)-([\d]+)|', '/embed/$2', $this->url);
|
||||
|
||||
return Utils::iframe($url, $this->width, $this->height);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getWidth()
|
||||
{
|
||||
return 600;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getHeight()
|
||||
{
|
||||
return 337;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getProviderName()
|
||||
{
|
||||
return 'MIT Media Lab';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return 'video';
|
||||
}
|
||||
}
|
||||
54
site/OFF_plugins/embed/vendor/Embed/src/Adapters/N500px.php
vendored
Normal file
54
site/OFF_plugins/embed/vendor/Embed/src/Adapters/N500px.php
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Adapters;
|
||||
|
||||
use Embed\Http\Response;
|
||||
use Embed\Utils;
|
||||
|
||||
/**
|
||||
* Adapter get embed code from 500px.com.
|
||||
*/
|
||||
class N500px extends Webpage
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function check(Response $response)
|
||||
{
|
||||
return $response->isValid() && $response->getUrl()->match([
|
||||
'500px.com/photo/*',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
$url = $this->getResponse()->getUrl();
|
||||
|
||||
if (is_numeric($url->getDirectoryPosition(1))) {
|
||||
return Utils::iframe($url->withDirectoryPosition(2, 'embed.html'), $this->width, $this->height);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getWidth()
|
||||
{
|
||||
if (is_numeric($this->getResponse()->getUrl()->getDirectoryPosition(1))) {
|
||||
return $this->imageWidth;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getHeight()
|
||||
{
|
||||
if (is_numeric($this->getResponse()->getUrl()->getDirectoryPosition(1))) {
|
||||
return $this->imageHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
55
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Parleys.php
vendored
Normal file
55
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Parleys.php
vendored
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Adapters;
|
||||
|
||||
use Embed\Http\Response;
|
||||
|
||||
/**
|
||||
* Adapter to get more info from parleys.com.
|
||||
*/
|
||||
class Parleys extends Webpage
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function check(Response $response)
|
||||
{
|
||||
return $response->isValid() && $response->getUrl()->match([
|
||||
'www.parleys.com/play/*',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
$id = $this->getResponse()->getUrl()->getDirectoryPosition(1);
|
||||
|
||||
return '<div data-parleys-presentation="'.$id.'" style="width:'.$this->width.';height:'.$this->height.'px"><script type = "text/javascript" src="//parleys.com/js/parleys-share.js"></script></div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getWidth()
|
||||
{
|
||||
return '100%';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getHeight()
|
||||
{
|
||||
return 300;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return 'video';
|
||||
}
|
||||
}
|
||||
36
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Pastebin.php
vendored
Normal file
36
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Pastebin.php
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Adapters;
|
||||
|
||||
use Embed\Http\Response;
|
||||
use Embed\Utils;
|
||||
|
||||
/**
|
||||
* Adapter to generate embed code from pastebin.
|
||||
*/
|
||||
class Pastebin extends Webpage
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function check(Response $response)
|
||||
{
|
||||
return $response->isValid() && $response->getUrl()->match([
|
||||
'pastebin.com/*',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
$this->width = null;
|
||||
$this->height = null;
|
||||
|
||||
$url = $this->getResponse()->getUrl();
|
||||
$embed_url = 'http://pastebin.com/embed_iframe.php?i='.($url->getQueryParameter('i') ?: $url->getDirectoryPosition(0));
|
||||
|
||||
return Utils::iframe($embed_url);
|
||||
}
|
||||
}
|
||||
35
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Pastie.php
vendored
Normal file
35
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Pastie.php
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Adapters;
|
||||
|
||||
use Embed\Http\Response;
|
||||
use Embed\Utils;
|
||||
|
||||
/**
|
||||
* Adapter to generate embed code from pastie.org.
|
||||
*/
|
||||
class Pastie extends Webpage
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function check(Response $response)
|
||||
{
|
||||
return $response->isValid() && $response->getUrl()->match([
|
||||
'pastie.org/pastes/*',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
$this->width = null;
|
||||
$this->height = null;
|
||||
|
||||
$path = '/'.$this->getResponse()->getUrl()->getDirectoryPosition(1).'.js';
|
||||
|
||||
return Utils::script($this->getResponse()->getUrl()->getAbsolute($path));
|
||||
}
|
||||
}
|
||||
37
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Sassmeister.php
vendored
Normal file
37
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Sassmeister.php
vendored
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Adapters;
|
||||
|
||||
use Embed\Http\Response;
|
||||
|
||||
/**
|
||||
* Adapter to generate embed code from SassMeister.
|
||||
*/
|
||||
class Sassmeister extends Webpage
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function check(Response $response)
|
||||
{
|
||||
return $response->isValid() && $response->getUrl()->match([
|
||||
'sassmeister.com/gist/*',
|
||||
'www.sassmeister.com/gist/*',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
$this->width = null;
|
||||
$this->height = 480;
|
||||
$id = $this->getResponse()->getUrl()->getDirectoryPosition(1);
|
||||
|
||||
return "<p class=\"sassmeister\" data-gist-id=\"{$id}\" data-height=\"480\" data-theme=\"tomorrow\">".
|
||||
"<a href=\"http://sassmeister.com/gist/{$id}\">Play with this gist on SassMeister.</a>".
|
||||
'</p>'.
|
||||
'<script src="http://cdn.sassmeister.com/js/embed.js" async></script>';
|
||||
}
|
||||
}
|
||||
46
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Slides.php
vendored
Normal file
46
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Slides.php
vendored
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Adapters;
|
||||
|
||||
use Embed\Utils;
|
||||
use Embed\Http\Response;
|
||||
|
||||
/**
|
||||
* Adapter to get the embed code from slides.com.
|
||||
*/
|
||||
class Slides extends Webpage
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function check(Response $response)
|
||||
{
|
||||
return $response->isValid() && $response->getUrl()->match([
|
||||
'slides.com/*',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
return Utils::iframe($this->getResponse()->getUrl()->withAddedPath('embed'), $this->width, $this->height);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getWidth()
|
||||
{
|
||||
return 576;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getHeight()
|
||||
{
|
||||
return 420;
|
||||
}
|
||||
}
|
||||
36
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Snipplr.php
vendored
Normal file
36
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Snipplr.php
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Adapters;
|
||||
|
||||
use Embed\Http\Response;
|
||||
|
||||
/**
|
||||
* Adapter to generate embed code from snipplr.com.
|
||||
*/
|
||||
class Snipplr extends Webpage
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function check(Response $response)
|
||||
{
|
||||
return $response->isValid() && $response->getUrl()->match([
|
||||
'snipplr.com/view/*',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
$this->width = null;
|
||||
$this->height = null;
|
||||
|
||||
$id = $this->getResponse()->getUrl()->getDirectoryPosition(1);
|
||||
|
||||
return <<<CODE
|
||||
<div id="snipplr_embed_{$id}" class="snipplr_embed"><a target_"blank" href="http://snipplr.com/view/{$id}">View this snippet</a> on Snipplr</div><script type="text/javascript" src="http://snipplr.com/js/embed.js"></script><script type="text/javascript" src="http://snipplr.com/json/{$id}"></script>
|
||||
CODE;
|
||||
}
|
||||
}
|
||||
65
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Spreaker.php
vendored
Normal file
65
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Spreaker.php
vendored
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Adapters;
|
||||
|
||||
use Embed\Utils;
|
||||
use Embed\Http\Response;
|
||||
use Embed\Http\Url;
|
||||
|
||||
/**
|
||||
* Adapter to get the embed code from spreaker.com.
|
||||
*/
|
||||
class Spreaker extends Webpage
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function check(Response $response)
|
||||
{
|
||||
return $response->isValid() && $response->getUrl()->match([
|
||||
'www.spreaker.com/*',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
$dom = $this->getResponse()->getHtmlContent();
|
||||
|
||||
foreach ($dom->getElementsByTagName('a') as $a) {
|
||||
if ($a->hasAttribute('data-episode_id')) {
|
||||
$id = (int) $a->getAttribute('data-episode_id');
|
||||
|
||||
if ($id) {
|
||||
$url = Url::create('https://www.spreaker.com/embed/player/standard')
|
||||
->withQueryParameters([
|
||||
'autoplay' => 'false',
|
||||
'episode_id' => $id,
|
||||
]);
|
||||
|
||||
return Utils::iframe($url, $this->width, $this->height, 'min-width:400px;border:none;overflow:hidden;');
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getWidth()
|
||||
{
|
||||
return '100%';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getHeight()
|
||||
{
|
||||
return 131;
|
||||
}
|
||||
}
|
||||
65
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Thematic.php
vendored
Normal file
65
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Thematic.php
vendored
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Adapters;
|
||||
|
||||
use Embed\Http\Response;
|
||||
|
||||
/**
|
||||
* Adapter to provide information from thematic.
|
||||
*/
|
||||
class Thematic extends Webpage
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function check(Response $response)
|
||||
{
|
||||
return $response->isValid() && $response->getUrl()->match([
|
||||
'www.thematic.co/stories/*',
|
||||
'www.thematic.co/album/*',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
$this->width = null;
|
||||
$this->height = null;
|
||||
|
||||
$html = $this->getResponse()->getHtmlContent();
|
||||
|
||||
foreach ($html->getElementsByTagName('div') as $div) {
|
||||
if ($div->hasAttribute('class') && $div->getAttribute('class') === 'code') {
|
||||
$code = (string) $div->nodeValue;
|
||||
|
||||
preg_match('/width="(\d+)" height="(\d+)"/', $code, $matches);
|
||||
$this->width = (int) $matches[1];
|
||||
$this->height = (int) $matches[2];
|
||||
|
||||
return $code;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getWidth()
|
||||
{
|
||||
$this->code = $this->getCode();
|
||||
|
||||
return $this->width;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getHeight()
|
||||
{
|
||||
$this->code = $this->getCode();
|
||||
|
||||
return $this->height;
|
||||
}
|
||||
}
|
||||
26
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Webpage.php
vendored
Normal file
26
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Webpage.php
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Adapters;
|
||||
|
||||
use Embed\Providers;
|
||||
|
||||
/**
|
||||
* Adapter to provide all information from any webpage.
|
||||
*/
|
||||
class Webpage extends Adapter
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function init()
|
||||
{
|
||||
$this->providers = [
|
||||
'oembed' => new Providers\OEmbed($this),
|
||||
'opengraph' => new Providers\OpenGraph($this),
|
||||
'twittercards' => new Providers\TwitterCards($this),
|
||||
'dcterms' => new Providers\Dcterms($this),
|
||||
'sailthru' => new Providers\Sailthru($this),
|
||||
'html' => new Providers\Html($this),
|
||||
];
|
||||
}
|
||||
}
|
||||
40
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Wikipedia.php
vendored
Normal file
40
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Wikipedia.php
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Adapters;
|
||||
|
||||
use Embed\Http\Response;
|
||||
use Embed\Providers\Api;
|
||||
|
||||
/**
|
||||
* Adapter to provide information from wikipedia.
|
||||
*/
|
||||
class Wikipedia extends Webpage
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function check(Response $response)
|
||||
{
|
||||
return $response->isValid() && $response->getUrl()->match([
|
||||
'*.wikipedia.org/wiki/*',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function init()
|
||||
{
|
||||
parent::init();
|
||||
|
||||
$this->providers = ['wikipedia' => new Api\Wikipedia($this)] + $this->providers;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getProviderName()
|
||||
{
|
||||
return 'Wikipedia';
|
||||
}
|
||||
}
|
||||
22
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Youtube.php
vendored
Normal file
22
site/OFF_plugins/embed/vendor/Embed/src/Adapters/Youtube.php
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Adapters;
|
||||
|
||||
use Embed\Http\Response;
|
||||
|
||||
/**
|
||||
* Adapter to provide information from youtube.
|
||||
* Required when youtube returns a 429 status code.
|
||||
*/
|
||||
class Youtube extends Webpage
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function check(Response $response)
|
||||
{
|
||||
return $response->isValid([200, 429]) && $response->getUrl()->match([
|
||||
'*.youtube.*',
|
||||
]);
|
||||
}
|
||||
}
|
||||
196
site/OFF_plugins/embed/vendor/Embed/src/Bag.php
vendored
Normal file
196
site/OFF_plugins/embed/vendor/Embed/src/Bag.php
vendored
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
<?php
|
||||
|
||||
namespace Embed;
|
||||
|
||||
/**
|
||||
* Class to store and access to data.
|
||||
*/
|
||||
class Bag
|
||||
{
|
||||
private $parameters = [];
|
||||
|
||||
/**
|
||||
* Set the initial parameters.
|
||||
*
|
||||
* @param array $parameters
|
||||
*/
|
||||
public function __construct(array $parameters = [])
|
||||
{
|
||||
$this->set($parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a value.
|
||||
*
|
||||
* @param string|array $name
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function set($name, $value = null)
|
||||
{
|
||||
if (!is_array($name)) {
|
||||
$name = [$name => $value];
|
||||
}
|
||||
|
||||
foreach ($name as $name => $value) {
|
||||
$name = self::normalizeName($name);
|
||||
$value = self::normalizeValue($value);
|
||||
|
||||
$this->parameters[$name] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a subvalue.
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function add($name, $value = null)
|
||||
{
|
||||
$name = self::normalizeName($name);
|
||||
$value = self::normalizeValue($value);
|
||||
|
||||
if (!isset($this->parameters[$name])) {
|
||||
$this->parameters[$name] = [];
|
||||
} elseif (!is_array($this->parameters[$name])) {
|
||||
$this->parameters[$name] = (array) $this->parameters[$name];
|
||||
}
|
||||
|
||||
$this->parameters[$name][] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a value.
|
||||
*
|
||||
* @param string $name
|
||||
* @param bool $isHtml
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get($name, $isHtml = false)
|
||||
{
|
||||
$name = self::normalizeName($name);
|
||||
|
||||
if (strpos($name, '[') !== false) {
|
||||
$names = explode('[', str_replace(']', '', $name));
|
||||
$key = array_shift($names);
|
||||
$item = isset($this->parameters[$key]) ? $this->parameters[$key] : [];
|
||||
|
||||
foreach ($names as $key) {
|
||||
if (!isset($item[$key])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$item = $item[$key];
|
||||
}
|
||||
|
||||
return $isHtml ? $item : self::toPlainValue($item);
|
||||
}
|
||||
|
||||
if (isset($this->parameters[$name])) {
|
||||
return $isHtml ? $this->parameters[$name] : self::toPlainValue($this->parameters[$name]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all stored values keys.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getKeys()
|
||||
{
|
||||
return array_keys($this->parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the raw stored values.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAll()
|
||||
{
|
||||
return $this->parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a value exists and is not empty.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has($name)
|
||||
{
|
||||
$name = self::normalizeName($name);
|
||||
|
||||
if (strpos($name, '[') !== false) {
|
||||
$names = explode('[', str_replace(']', '', $name));
|
||||
$key = array_shift($names);
|
||||
$item = isset($this->parameters[$key]) ? $this->parameters[$key] : [];
|
||||
|
||||
foreach ($names as $key) {
|
||||
if (!isset($item[$key])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$item = $item[$key];
|
||||
}
|
||||
|
||||
return !empty($item);
|
||||
}
|
||||
|
||||
return !empty($this->parameters[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a variable name.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function normalizeName($name)
|
||||
{
|
||||
return strtolower(trim($name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a value.
|
||||
* If it's a string, removes spaces and normalize some utf-8 chars.
|
||||
*
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private static function normalizeValue($value)
|
||||
{
|
||||
if (is_string($value)) {
|
||||
$value = str_ireplace([' ', ' '], ' ', $value);
|
||||
$value = trim($value);
|
||||
|
||||
return ($value === '') ? null : $value;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the html code and entities in a value
|
||||
*
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private static function toPlainValue($value)
|
||||
{
|
||||
if (is_string($value)) {
|
||||
$value = strip_tags($value);
|
||||
$value = html_entity_decode($value, ENT_QUOTES | ENT_XML1, 'UTF-8');
|
||||
$value = trim($value);
|
||||
|
||||
return ($value === '') ? null : $value;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
139
site/OFF_plugins/embed/vendor/Embed/src/DataInterface.php
vendored
Normal file
139
site/OFF_plugins/embed/vendor/Embed/src/DataInterface.php
vendored
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
<?php
|
||||
|
||||
namespace Embed;
|
||||
|
||||
/**
|
||||
* Interface used by all adapters and providers.
|
||||
*/
|
||||
interface DataInterface
|
||||
{
|
||||
/**
|
||||
* Gets the title.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getTitle();
|
||||
|
||||
/**
|
||||
* Gets the description.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getDescription();
|
||||
|
||||
/**
|
||||
* Gets the type of the url
|
||||
* The types are the same than the oEmbed types:
|
||||
* video, photo, link, rich.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getType();
|
||||
|
||||
/**
|
||||
* Gets the tags of the url.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTags();
|
||||
|
||||
/**
|
||||
* Gets the feeds urls.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFeeds();
|
||||
|
||||
/**
|
||||
* Gets the embed code.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getCode();
|
||||
|
||||
/**
|
||||
* Gets the canonical url.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getUrl();
|
||||
|
||||
/**
|
||||
* Gets the author name.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getAuthorName();
|
||||
|
||||
/**
|
||||
* Gets the author url.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getAuthorUrl();
|
||||
|
||||
/**
|
||||
* Gets the urls of all icons of the provider
|
||||
* Note: it doesn't check whether the image exists or not.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getProviderIconsUrls();
|
||||
|
||||
/**
|
||||
* Gets the provider name.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getProviderName();
|
||||
|
||||
/**
|
||||
* Gets the provider url (usually the home url of the link).
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getProviderUrl();
|
||||
|
||||
/**
|
||||
* Gets the urls of all images found in the webpage
|
||||
* Note: it doesn't check whether the image exists or not.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getImagesUrls();
|
||||
|
||||
/**
|
||||
* Gets the width of the embedded widget.
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getWidth();
|
||||
|
||||
/**
|
||||
* Gets the height of the embedded widget.
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getHeight();
|
||||
|
||||
/**
|
||||
* Gets the published time, if the webpage is an article.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getPublishedTime();
|
||||
|
||||
/**
|
||||
* Gets the license info.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getLicense();
|
||||
|
||||
/**
|
||||
* Returns all linked data found.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getLinkedData();
|
||||
}
|
||||
85
site/OFF_plugins/embed/vendor/Embed/src/Embed.php
vendored
Normal file
85
site/OFF_plugins/embed/vendor/Embed/src/Embed.php
vendored
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
|
||||
namespace Embed;
|
||||
|
||||
use Embed\Adapters\Adapter;
|
||||
use Embed\Http\Url;
|
||||
use Embed\Http\DispatcherInterface;
|
||||
use Embed\Http\CurlDispatcher;
|
||||
|
||||
abstract class Embed
|
||||
{
|
||||
/**
|
||||
* Gets the info from an url.
|
||||
*
|
||||
* @param Url|string $url
|
||||
* @param array $config
|
||||
* @param DispatcherInterface|null $dispatcher
|
||||
*
|
||||
* @return Adapter
|
||||
*/
|
||||
public static function create($url, array $config = [], DispatcherInterface $dispatcher = null)
|
||||
{
|
||||
if (!($url instanceof Url)) {
|
||||
$url = Url::create($url);
|
||||
}
|
||||
|
||||
if ($dispatcher === null) {
|
||||
$dispatcher = new CurlDispatcher();
|
||||
}
|
||||
|
||||
$info = self::process($url, $config, $dispatcher);
|
||||
|
||||
// Repeat the process if:
|
||||
// - The canonical url is different
|
||||
// - No embed code has found
|
||||
$from = preg_replace('|^(\w+://)|', '', rtrim((string) $info->getResponse()->getUrl(), '/'));
|
||||
$to = preg_replace('|^(\w+://)|', '', rtrim($info->url, '/'));
|
||||
|
||||
if ($from !== $to && empty($info->code)) {
|
||||
return self::process(Url::create($info->url), $config, $dispatcher);
|
||||
}
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the url.
|
||||
*
|
||||
* @param Url $url
|
||||
* @param array $config
|
||||
* @param DispatcherInterface $dispatcher
|
||||
*
|
||||
* @throws Exceptions\InvalidUrlException If the urls is not valid
|
||||
*
|
||||
* @return Adapter
|
||||
*/
|
||||
private static function process(Url $url, array $config, DispatcherInterface $dispatcher)
|
||||
{
|
||||
$response = $dispatcher->dispatch($url);
|
||||
|
||||
//If is a file use File Adapter
|
||||
if (Adapters\File::check($response)) {
|
||||
return new Adapters\File($response, $config, $dispatcher);
|
||||
}
|
||||
|
||||
//Search the adapter using the domain
|
||||
$adapter = 'Embed\\Adapters\\'.$response->getUrl()->getClassNameForDomain();
|
||||
|
||||
if (class_exists($adapter) && $adapter::check($response)) {
|
||||
return new $adapter($response, $config, $dispatcher);
|
||||
}
|
||||
|
||||
//Use the default webpage adapter
|
||||
if (Adapters\Webpage::check($response)) {
|
||||
return new Adapters\Webpage($response, $config, $dispatcher);
|
||||
}
|
||||
|
||||
$exception = new Exceptions\InvalidUrlException(sprintf("Invalid url '%s' (Status code %s)", (string) $url, $response->getStatusCode()));
|
||||
|
||||
$exception->setResponse($response);
|
||||
|
||||
throw $exception;
|
||||
|
||||
}
|
||||
}
|
||||
9
site/OFF_plugins/embed/vendor/Embed/src/Exceptions/EmbedException.php
vendored
Normal file
9
site/OFF_plugins/embed/vendor/Embed/src/Exceptions/EmbedException.php
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
class EmbedException extends Exception
|
||||
{
|
||||
}
|
||||
33
site/OFF_plugins/embed/vendor/Embed/src/Exceptions/InvalidUrlException.php
vendored
Normal file
33
site/OFF_plugins/embed/vendor/Embed/src/Exceptions/InvalidUrlException.php
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Exceptions;
|
||||
|
||||
use Embed\Http\Response;
|
||||
|
||||
class InvalidUrlException extends EmbedException
|
||||
{
|
||||
/**
|
||||
* @var Response|null
|
||||
*/
|
||||
private $response;
|
||||
|
||||
/**
|
||||
* Set the response related with this error
|
||||
*
|
||||
* @param Response
|
||||
*/
|
||||
public function setResponse(Response $response)
|
||||
{
|
||||
$this->response = $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the response related with this error
|
||||
*
|
||||
* @return Response|null
|
||||
*/
|
||||
public function getResponse()
|
||||
{
|
||||
return $this->response;
|
||||
}
|
||||
}
|
||||
116
site/OFF_plugins/embed/vendor/Embed/src/Http/AbstractResponse.php
vendored
Normal file
116
site/OFF_plugins/embed/vendor/Embed/src/Http/AbstractResponse.php
vendored
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Http;
|
||||
|
||||
/**
|
||||
* Class to consume http responses.
|
||||
*/
|
||||
abstract class AbstractResponse
|
||||
{
|
||||
protected $startingUrl;
|
||||
protected $url;
|
||||
protected $statusCode;
|
||||
protected $contentType;
|
||||
protected $headers;
|
||||
protected $info;
|
||||
|
||||
public function __construct(Url $startingUrl, Url $url, $statusCode, $contentType, array $headers, array $info)
|
||||
{
|
||||
$this->startingUrl = $startingUrl;
|
||||
$this->url = $url;
|
||||
$this->statusCode = $statusCode;
|
||||
$this->contentType = $contentType;
|
||||
$this->headers = $headers;
|
||||
$this->info = $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the starting url.
|
||||
*
|
||||
* @return Url
|
||||
*/
|
||||
public function getStartingUrl()
|
||||
{
|
||||
return $this->startingUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the http code of the response, for example: 200.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getStatusCode()
|
||||
{
|
||||
return $this->statusCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the content-type of the response, for example: text/html.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getContentType()
|
||||
{
|
||||
return $this->contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the final url.
|
||||
*
|
||||
* @return Url
|
||||
*/
|
||||
public function getUrl()
|
||||
{
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the http headers.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getHeaders()
|
||||
{
|
||||
return $this->headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns extra http info.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getInfo()
|
||||
{
|
||||
return $this->info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a header.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getHeader($name)
|
||||
{
|
||||
$name = strtolower($name);
|
||||
|
||||
return isset($this->headers[$name]) ? implode(',', $this->headers[$name]) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the response is valid or not.
|
||||
*
|
||||
* @param array $codes
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isValid(array $codes = null)
|
||||
{
|
||||
if ($codes === null) {
|
||||
return $this->statusCode === 200;
|
||||
}
|
||||
|
||||
return in_array($this->statusCode, $codes);
|
||||
}
|
||||
}
|
||||
242
site/OFF_plugins/embed/vendor/Embed/src/Http/CurlDispatcher.php
vendored
Normal file
242
site/OFF_plugins/embed/vendor/Embed/src/Http/CurlDispatcher.php
vendored
Normal file
|
|
@ -0,0 +1,242 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Http;
|
||||
|
||||
use Embed\Exceptions\EmbedException;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Curl dispatcher.
|
||||
*/
|
||||
class CurlDispatcher implements DispatcherInterface
|
||||
{
|
||||
private $responses = [];
|
||||
|
||||
private $config = [
|
||||
CURLOPT_MAXREDIRS => 10,
|
||||
CURLOPT_CONNECTTIMEOUT => 10,
|
||||
CURLOPT_TIMEOUT => 10,
|
||||
CURLOPT_SSL_VERIFYHOST => false,
|
||||
CURLOPT_SSL_VERIFYPEER => false,
|
||||
CURLOPT_ENCODING => '',
|
||||
CURLOPT_AUTOREFERER => true,
|
||||
CURLOPT_FOLLOWLOCATION => true,
|
||||
CURLOPT_USERAGENT => 'Embed PHP library',
|
||||
CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4,
|
||||
];
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $config
|
||||
*/
|
||||
public function __construct(array $config = [])
|
||||
{
|
||||
$this->config = $config + $this->config;
|
||||
|
||||
if (!isset($this->config[CURLOPT_COOKIEJAR])) {
|
||||
$cookies = str_replace('//', '/', sys_get_temp_dir().'/embed-cookies.'.uniqid());
|
||||
|
||||
if (is_file($cookies)) {
|
||||
if (!is_writable($cookies)) {
|
||||
throw new EmbedException(sprintf('The temporary cookies file "%s" is not writable', $cookies));
|
||||
}
|
||||
} elseif (!is_writable(dirname($cookies))) {
|
||||
throw new EmbedException(sprintf('The temporary folder "%s" is not writable', dirname($cookies)));
|
||||
}
|
||||
|
||||
$this->config[CURLOPT_COOKIEJAR] = $cookies;
|
||||
$this->config[CURLOPT_COOKIEFILE] = $cookies;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all responses for debug purposes
|
||||
*
|
||||
* @return AbstractResponse[]
|
||||
*/
|
||||
public function getAllResponses()
|
||||
{
|
||||
return $this->responses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the cookies file on destruct the instance.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$cookies = $this->config[CURLOPT_COOKIEJAR];
|
||||
|
||||
if (is_file($cookies)) {
|
||||
unlink($cookies);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function dispatch(Url $url)
|
||||
{
|
||||
$options = $this->config;
|
||||
$options[CURLOPT_HTTPHEADER] = ['Accept: text/html'];
|
||||
|
||||
$response = $this->exec($url, $options);
|
||||
|
||||
//Some sites returns 403 with the default user-agent
|
||||
if ($response->getStatusCode() === 403) {
|
||||
$options[CURLOPT_USERAGENT] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36';
|
||||
|
||||
return $this->exec($url, $options);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a curl request
|
||||
*
|
||||
* @param Url $url
|
||||
* @param array $options
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
protected function exec(Url $url, array $options)
|
||||
{
|
||||
$connection = curl_init((string) $url);
|
||||
curl_setopt_array($connection, $options);
|
||||
|
||||
$curl = new CurlResult($connection);
|
||||
|
||||
//Get only text responses
|
||||
$curl->onHeader(function ($name, $value, $data) {
|
||||
if ($name === 'content-type') {
|
||||
$data->isBinary = !preg_match('/(text|html|json)/', strtolower($value));
|
||||
}
|
||||
});
|
||||
|
||||
$curl->onBody(function ($string, stdClass $data) {
|
||||
return !$data->isBinary;
|
||||
});
|
||||
|
||||
curl_exec($connection);
|
||||
|
||||
$result = $curl->getResult();
|
||||
|
||||
curl_close($connection);
|
||||
|
||||
return $this->responses[] = new Response(
|
||||
$url,
|
||||
Url::create($result['url']),
|
||||
$result['statusCode'],
|
||||
$result['contentType'],
|
||||
$result['content'],
|
||||
$result['headers'],
|
||||
$result['info']
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function dispatchImages(array $urls)
|
||||
{
|
||||
if (empty($urls)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$finfo = finfo_open(FILEINFO_MIME_TYPE);
|
||||
$mimetypes = [
|
||||
'image/jpeg',
|
||||
'image/png',
|
||||
'image/gif',
|
||||
'image/bmp',
|
||||
'image/x-icon',
|
||||
];
|
||||
$curl_multi = curl_multi_init();
|
||||
$responses = [];
|
||||
$connections = [];
|
||||
|
||||
foreach ($urls as $k => $url) {
|
||||
if ($url->getScheme() === 'data') {
|
||||
$response = ImageResponse::createFromBase64($url);
|
||||
|
||||
if ($response) {
|
||||
$responses[$k] = $response;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$connection = curl_init((string) $url);
|
||||
|
||||
curl_setopt_array($connection, $this->config);
|
||||
curl_multi_add_handle($curl_multi, $connection);
|
||||
|
||||
$curl = new CurlResult($connection);
|
||||
|
||||
$curl->onBody(function ($body, stdClass $data) use ($finfo, $mimetypes) {
|
||||
if (empty($data->mime)) {
|
||||
$data->mime = finfo_buffer($finfo, $body);
|
||||
|
||||
if (!in_array($data->mime, $mimetypes, true)) {
|
||||
$data->mime = null;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (($info = getimagesizefromstring($body))) {
|
||||
$data->width = $info[0];
|
||||
$data->height = $info[1];
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
$connections[$k] = $curl;
|
||||
}
|
||||
|
||||
if (!empty($connections)) {
|
||||
do {
|
||||
$return = curl_multi_exec($curl_multi, $active);
|
||||
} while ($return === CURLM_CALL_MULTI_PERFORM);
|
||||
|
||||
while ($active && $return === CURLM_OK) {
|
||||
if (curl_multi_select($curl_multi) === -1) {
|
||||
usleep(100);
|
||||
}
|
||||
|
||||
do {
|
||||
$return = curl_multi_exec($curl_multi, $active);
|
||||
} while ($return === CURLM_CALL_MULTI_PERFORM);
|
||||
}
|
||||
|
||||
foreach ($connections as $k => $connection) {
|
||||
$resource = $connection->getResource();
|
||||
|
||||
curl_multi_remove_handle($curl_multi, $resource);
|
||||
$result = $connection->getResult();
|
||||
|
||||
if (!empty($result['data']->mime)) {
|
||||
$responses[$k] = $this->responses[] = new ImageResponse(
|
||||
$urls[$k],
|
||||
Url::create($result['url']),
|
||||
$result['statusCode'],
|
||||
$result['contentType'],
|
||||
[$result['data']->width, $result['data']->height],
|
||||
$result['headers'],
|
||||
$result['info']
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
finfo_close($finfo);
|
||||
curl_multi_close($curl_multi);
|
||||
|
||||
ksort($responses, SORT_NUMERIC);
|
||||
|
||||
return array_values($responses);
|
||||
}
|
||||
}
|
||||
131
site/OFF_plugins/embed/vendor/Embed/src/Http/CurlResult.php
vendored
Normal file
131
site/OFF_plugins/embed/vendor/Embed/src/Http/CurlResult.php
vendored
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Http;
|
||||
|
||||
/**
|
||||
* Class to dispatch urls using curl and get the result.
|
||||
*/
|
||||
class CurlResult
|
||||
{
|
||||
protected $resource;
|
||||
protected $body;
|
||||
protected $headers = [];
|
||||
protected $onHeader;
|
||||
protected $onBody;
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* Creates a new response.
|
||||
*
|
||||
* @param resource $resource The curl resource
|
||||
*/
|
||||
public function __construct($resource)
|
||||
{
|
||||
$this->resource = $resource;
|
||||
$this->data = (object) [];
|
||||
|
||||
curl_setopt($this->resource, CURLOPT_HEADERFUNCTION, [$this, 'headerCallback']);
|
||||
curl_setopt($this->resource, CURLOPT_WRITEFUNCTION, [$this, 'writeCallback']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the response result.
|
||||
*/
|
||||
public function getResult()
|
||||
{
|
||||
$result = curl_getinfo($this->resource);
|
||||
|
||||
return [
|
||||
'url' => isset($result['url']) ? $result['url'] : null,
|
||||
'statusCode' => isset($result['http_code']) ? $result['http_code'] : null,
|
||||
'contentType' => isset($result['content_type']) ? $result['content_type'] : null,
|
||||
'info' => $result,
|
||||
'content' => $this->body,
|
||||
'headers' => $this->headers,
|
||||
'data' => $this->data,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the resource.
|
||||
*
|
||||
* @return resource
|
||||
*/
|
||||
public function getResource()
|
||||
{
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback used on receive a header.
|
||||
*
|
||||
* @param callable $callback
|
||||
*/
|
||||
public function onHeader(callable $callback)
|
||||
{
|
||||
$this->onHeader = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback used on receive a body string portion.
|
||||
*
|
||||
* @param callable $callback
|
||||
*/
|
||||
public function onBody(callable $callback)
|
||||
{
|
||||
$this->onBody = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback used to collect the headers.
|
||||
*
|
||||
* @param resource $resource
|
||||
* @param string $string
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function headerCallback($resource, $string)
|
||||
{
|
||||
if (!strpos($string, ':')) {
|
||||
return strlen($string);
|
||||
}
|
||||
|
||||
list($name, $value) = array_map('trim', explode(':', $string, 2));
|
||||
|
||||
$name = strtolower($name);
|
||||
|
||||
if (!isset($this->headers[$name])) {
|
||||
$this->headers[$name] = [];
|
||||
}
|
||||
|
||||
$this->headers[$name][] = $value;
|
||||
|
||||
if ($this->onHeader === null || call_user_func($this->onHeader, $name, $value, $this->data) !== false) {
|
||||
return strlen($string);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback used to get the body content.
|
||||
*
|
||||
* @param resource $resource
|
||||
* @param string $string
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function writeCallback($resource, $string)
|
||||
{
|
||||
$this->body .= $string;
|
||||
|
||||
if ($this->onBody === null || call_user_func($this->onBody, $this->body, $this->data) !== false) {
|
||||
return strlen($string);
|
||||
}
|
||||
|
||||
//Cancel
|
||||
$this->body = null;
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
27
site/OFF_plugins/embed/vendor/Embed/src/Http/DispatcherInterface.php
vendored
Normal file
27
site/OFF_plugins/embed/vendor/Embed/src/Http/DispatcherInterface.php
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Http;
|
||||
|
||||
/**
|
||||
* Interface used to create http responses.
|
||||
*/
|
||||
interface DispatcherInterface
|
||||
{
|
||||
/**
|
||||
* Dispatch an url.
|
||||
*
|
||||
* @param Url $url
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function dispatch(Url $url);
|
||||
|
||||
/**
|
||||
* Resolve multiple image urls at once.
|
||||
*
|
||||
* @param Url[] $urls
|
||||
*
|
||||
* @return ImageResponse[]
|
||||
*/
|
||||
public function dispatchImages(array $urls);
|
||||
}
|
||||
65
site/OFF_plugins/embed/vendor/Embed/src/Http/ImageResponse.php
vendored
Normal file
65
site/OFF_plugins/embed/vendor/Embed/src/Http/ImageResponse.php
vendored
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Http;
|
||||
|
||||
/**
|
||||
* Class to consume http responses.
|
||||
*/
|
||||
class ImageResponse extends AbstractResponse
|
||||
{
|
||||
protected $size;
|
||||
|
||||
/**
|
||||
* Create a ImageResponse using a bas64 url.
|
||||
*
|
||||
* @param Url $url
|
||||
*
|
||||
* @return static|null
|
||||
*/
|
||||
public static function createFromBase64(Url $url)
|
||||
{
|
||||
$pieces = explode(';', $url->getContent(), 2);
|
||||
|
||||
if ((count($pieces) !== 2) || (strpos($pieces[0], 'image/') === false) || (strpos($pieces[1], 'base64,') !== 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (($info = getimagesizefromstring(base64_decode(substr($pieces[1], 7)))) !== false) {
|
||||
return new self(
|
||||
$url,
|
||||
$url,
|
||||
200,
|
||||
$info['mime'],
|
||||
[$info[0], $info[1]],
|
||||
[],
|
||||
[]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function __construct(Url $startingUrl, Url $url, $statusCode, $contentType, $size, array $headers, array $info)
|
||||
{
|
||||
parent::__construct($startingUrl, $url, $statusCode, $contentType, $headers, $info);
|
||||
$this->size = $size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the image width.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getWidth()
|
||||
{
|
||||
return (int) $this->size[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the image height.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getHeight()
|
||||
{
|
||||
return (int) $this->size[1];
|
||||
}
|
||||
}
|
||||
94
site/OFF_plugins/embed/vendor/Embed/src/Http/Redirects.php
vendored
Normal file
94
site/OFF_plugins/embed/vendor/Embed/src/Http/Redirects.php
vendored
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Http;
|
||||
|
||||
/**
|
||||
* Class to resolve some specific redirections.
|
||||
*/
|
||||
abstract class Redirects
|
||||
{
|
||||
private static $patterns = [
|
||||
'google' => 'www.google.com/url*',
|
||||
'googleTranslator' => 'translate.google.com/translate',
|
||||
'hashBang' => '*#!*',
|
||||
'spotify' => 'play.spotify.com/*',
|
||||
];
|
||||
|
||||
/**
|
||||
* Resolve the url redirection.
|
||||
*
|
||||
* @param Url $url
|
||||
*
|
||||
* @return Url
|
||||
*/
|
||||
public static function resolve(Url $url)
|
||||
{
|
||||
foreach (self::$patterns as $method => $pattern) {
|
||||
if ($url->match($pattern)) {
|
||||
return self::$method($url);
|
||||
}
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a google redirection url.
|
||||
*
|
||||
* @param Url $url
|
||||
*
|
||||
* @return Url
|
||||
*/
|
||||
public static function google(Url $url)
|
||||
{
|
||||
if (($value = $url->getQueryParameter('url'))) {
|
||||
return Url::create($value);
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a google translation url.
|
||||
*
|
||||
* @param Url $url
|
||||
*
|
||||
* @return Url
|
||||
*/
|
||||
public static function googleTranslator(Url $url)
|
||||
{
|
||||
if (($value = $url->getQueryParameter('u'))) {
|
||||
return Url::create($value);
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve an url with hashbang.
|
||||
*
|
||||
* @param Url $url
|
||||
*
|
||||
* @return Url
|
||||
*/
|
||||
public static function hashBang(Url $url)
|
||||
{
|
||||
if (($path = preg_replace('|^(/?!)|', '', $url->getFragment()))) {
|
||||
return $url->withPath($url->getPath().$path);
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect the player of spotify.
|
||||
*
|
||||
* @param Url $url
|
||||
*
|
||||
* @return Url
|
||||
*/
|
||||
public static function spotify(Url $url)
|
||||
{
|
||||
return $url->withHost('open.spotify.com');
|
||||
}
|
||||
}
|
||||
138
site/OFF_plugins/embed/vendor/Embed/src/Http/Response.php
vendored
Normal file
138
site/OFF_plugins/embed/vendor/Embed/src/Http/Response.php
vendored
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Http;
|
||||
|
||||
use Embed\Utils;
|
||||
use Exception;
|
||||
use DOMDocument;
|
||||
use SimpleXMLElement;
|
||||
|
||||
/**
|
||||
* Class to consume http responses.
|
||||
*/
|
||||
class Response extends AbstractResponse
|
||||
{
|
||||
protected $content;
|
||||
protected $xmlContent;
|
||||
protected $jsonContent;
|
||||
protected $htmlContent;
|
||||
|
||||
public function __construct(Url $startingUrl, Url $url, $statusCode, $contentType, $content, array $headers, array $info)
|
||||
{
|
||||
parent::__construct($startingUrl, $url, $statusCode, $contentType, $headers, $info);
|
||||
$this->setContent($content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the content.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getContent()
|
||||
{
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the content as HTML.
|
||||
*
|
||||
* @return DOMDocument|false
|
||||
*/
|
||||
public function getHtmlContent()
|
||||
{
|
||||
if ($this->htmlContent === null) {
|
||||
try {
|
||||
if (empty($content = $this->content)) {
|
||||
return $this->htmlContent = false;
|
||||
}
|
||||
|
||||
$errors = libxml_use_internal_errors(true);
|
||||
$entities = libxml_disable_entity_loader(true);
|
||||
|
||||
$this->htmlContent = new DOMDocument();
|
||||
|
||||
if (mb_detect_encoding($content) === 'UTF-8') {
|
||||
$content = mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8');
|
||||
$content = preg_replace('/<head[^>]*>/', '<head><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">', $content);
|
||||
}
|
||||
|
||||
$this->htmlContent->loadHTML(trim($content));
|
||||
|
||||
libxml_use_internal_errors($errors);
|
||||
libxml_disable_entity_loader($entities);
|
||||
} catch (Exception $exception) {
|
||||
return $this->htmlContent = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->htmlContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the content as an array from JSON.
|
||||
*
|
||||
* @return array|false
|
||||
*/
|
||||
public function getJsonContent()
|
||||
{
|
||||
if ($this->jsonContent === null) {
|
||||
try {
|
||||
if (($content = $this->content) === '') {
|
||||
return $this->jsonContent = false;
|
||||
}
|
||||
|
||||
$this->jsonContent = json_decode($content, true);
|
||||
} catch (\Exception $exception) {
|
||||
return $this->jsonContent = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->jsonContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the content as XML.
|
||||
*
|
||||
* @return SimpleXMLElement|false
|
||||
*/
|
||||
public function getXMLContent()
|
||||
{
|
||||
if ($this->xmlContent === null) {
|
||||
try {
|
||||
if (($content = $this->content) === '') {
|
||||
return $this->xmlContent = false;
|
||||
}
|
||||
|
||||
$errors = libxml_use_internal_errors(true);
|
||||
$this->xmlContent = new SimpleXMLElement($content);
|
||||
libxml_use_internal_errors($errors);
|
||||
} catch (Exception $exception) {
|
||||
return $this->xmlContent = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->xmlContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the response content.
|
||||
*
|
||||
* @param string $content
|
||||
*/
|
||||
private function setContent($content)
|
||||
{
|
||||
$this->content = $content;
|
||||
|
||||
if (empty($this->contentType)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Remove charset from Content-Type
|
||||
if (strpos($this->contentType, ';') !== false) {
|
||||
list($mime, $charset) = array_map('trim', explode(';', $this->contentType));
|
||||
|
||||
$this->contentType = $mime;
|
||||
$this->content = Utils::toUtf8($content, substr(strstr($charset, '='), 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
652
site/OFF_plugins/embed/vendor/Embed/src/Http/Url.php
vendored
Normal file
652
site/OFF_plugins/embed/vendor/Embed/src/Http/Url.php
vendored
Normal file
|
|
@ -0,0 +1,652 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Http;
|
||||
|
||||
/**
|
||||
* Class to split and manipulate urls.
|
||||
*/
|
||||
class Url
|
||||
{
|
||||
private $info;
|
||||
private $url;
|
||||
private static $public_suffix_list;
|
||||
|
||||
/**
|
||||
* Create a new Url instance.
|
||||
*
|
||||
* @param string $url
|
||||
*
|
||||
* @return Url
|
||||
*/
|
||||
public static function create($url)
|
||||
{
|
||||
return Redirects::resolve(new static($url));
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor. Sets the url.
|
||||
*
|
||||
* @param string $url
|
||||
*/
|
||||
private function __construct($url)
|
||||
{
|
||||
$this->parseUrl($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the url.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
if ($this->url === null) {
|
||||
return $this->url = $this->buildUrl();
|
||||
}
|
||||
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the built url on clone.
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
$this->url = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the url match with a specific pattern. The patterns only accepts * and ?
|
||||
*
|
||||
* @param string|array $patterns The pattern or an array with various patterns
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function match($patterns)
|
||||
{
|
||||
if (!is_array($patterns)) {
|
||||
$patterns = [$patterns];
|
||||
}
|
||||
|
||||
//Remove scheme and query
|
||||
$url = preg_replace('|(\?.*)?$|', '', (string) $this);
|
||||
$url = preg_replace('|^(\w+://)|', '', $url);
|
||||
|
||||
foreach ($patterns as $pattern) {
|
||||
$pattern = str_replace(['\\*', '\\?'], ['.+', '?'], preg_quote($pattern, '|'));
|
||||
|
||||
if (preg_match('|^'.$pattern.'$|i', $url)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the content of the url (for embedded images).
|
||||
*
|
||||
* @return string The content or null
|
||||
*/
|
||||
public function getContent()
|
||||
{
|
||||
return isset($this->info['content']) ? $this->info['content'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the extension of the url (html, php, jpg, etc).
|
||||
*
|
||||
* @return string The scheme or null
|
||||
*/
|
||||
public function getExtension()
|
||||
{
|
||||
return isset($this->info['extension']) ? $this->info['extension'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new instance with other relative url.
|
||||
*
|
||||
* @param string $url
|
||||
*
|
||||
* @return Url
|
||||
*/
|
||||
public function createAbsolute($url)
|
||||
{
|
||||
return self::create($this->getAbsolute($url));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a clone with other extension.
|
||||
*
|
||||
* @param string $extension
|
||||
*
|
||||
* @return Url
|
||||
*/
|
||||
public function withExtension($extension)
|
||||
{
|
||||
$clone = clone $this;
|
||||
$clone->info['extension'] = $extension;
|
||||
|
||||
if (empty($clone->info['file'])) {
|
||||
$clone->info['file'] = array_pop($clone->info['path']);
|
||||
}
|
||||
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the scheme of the url (for example http, https, ftp, etc).
|
||||
*
|
||||
* @return string The scheme or null
|
||||
*/
|
||||
public function getScheme()
|
||||
{
|
||||
return isset($this->info['scheme']) ? $this->info['scheme'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a clone with other scheme.
|
||||
*
|
||||
* @param string $scheme
|
||||
*
|
||||
* @return Url
|
||||
*/
|
||||
public function withScheme($scheme)
|
||||
{
|
||||
$clone = clone $this;
|
||||
$clone->info['scheme'] = $scheme;
|
||||
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the host of the url (for example: google.com).
|
||||
*
|
||||
* @return string The host or null
|
||||
*/
|
||||
public function getHost()
|
||||
{
|
||||
return isset($this->info['host']) ? $this->info['host'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a clone with other host.
|
||||
*
|
||||
* @param string $host
|
||||
*
|
||||
* @return Url
|
||||
*/
|
||||
public function withHost($host)
|
||||
{
|
||||
$clone = clone $this;
|
||||
$clone->info['host'] = $host;
|
||||
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the domain of the url (for example: google).
|
||||
*
|
||||
* @param bool $first_level True to return the first level domain (.com, .es, etc)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDomain($first_level = false)
|
||||
{
|
||||
$host = $this->getHost();
|
||||
|
||||
if (empty($host)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$host = array_reverse(explode('.', $host));
|
||||
|
||||
switch (count($host)) {
|
||||
case 1:
|
||||
return $host[0];
|
||||
|
||||
case 2:
|
||||
return $first_level ? ($host[1].'.'.$host[0]) : $host[1];
|
||||
|
||||
default:
|
||||
$tld = $host[1].'.'.$host[0];
|
||||
$suffixes = self::getSuffixes();
|
||||
|
||||
if (in_array($tld, $suffixes, true)) {
|
||||
return $first_level ? $host[2].'.'.$tld : $host[2];
|
||||
}
|
||||
|
||||
return $first_level ? $host[1].'.'.$host[0] : $host[1];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a specific directory position in the path of the url.
|
||||
*
|
||||
* @param int $position The position of the directory (0 based index)
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getDirectoryPosition($position)
|
||||
{
|
||||
if ($position === count($this->info['path'])) {
|
||||
return $this->info['file'];
|
||||
}
|
||||
|
||||
return isset($this->info['path'][$position]) ? $this->info['path'][$position] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a clone with other directory in a specific position.
|
||||
*
|
||||
* @param int|null $key The position of the subdirectory (0 based index)
|
||||
* @param string $value The new value
|
||||
*
|
||||
* @return Url
|
||||
*/
|
||||
public function withDirectoryPosition($key, $value)
|
||||
{
|
||||
$clone = clone $this;
|
||||
|
||||
$pos = $clone->info['path'];
|
||||
$hasFile = isset($clone->info['file']);
|
||||
|
||||
if ($hasFile) {
|
||||
$pos[] = $clone->info['file'];
|
||||
}
|
||||
|
||||
$pos[$key] = $value;
|
||||
|
||||
if ($hasFile) {
|
||||
$clone->info['file'] = array_pop($pos);
|
||||
}
|
||||
|
||||
$clone->info['path'] = $pos;
|
||||
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all directories.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDirectories()
|
||||
{
|
||||
return !empty($this->info['path']) ? '/'.implode('/', $this->info['path']).'/' : '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Slice path.
|
||||
*
|
||||
* @param int $offset
|
||||
* @param int|null $length
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getSlicePath($offset, $length = null)
|
||||
{
|
||||
$array = explode('/', $this->getPath());
|
||||
|
||||
if (empty($array[0])) {
|
||||
array_shift($array);
|
||||
}
|
||||
|
||||
return array_slice($array, $offset, $length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the url path.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
$path = !empty($this->info['path']) ? '/'.implode('/', array_map('urlencode', $this->info['path'])).'/' : '/';
|
||||
|
||||
if (isset($this->info['file'])) {
|
||||
$path .= $this->info['file'];
|
||||
|
||||
if (isset($this->info['extension'])) {
|
||||
$path .= '.'.$this->info['extension'];
|
||||
}
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a clone with other path.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return Url
|
||||
*/
|
||||
public function withPath($path)
|
||||
{
|
||||
$clone = clone $this;
|
||||
|
||||
$clone->setPath($path);
|
||||
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a clone with path appended.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return Url
|
||||
*/
|
||||
public function withAddedPath($path)
|
||||
{
|
||||
$path = $this->getPath().'/'.$path;
|
||||
|
||||
return $this->withPath($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the url has a query parameter.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasQueryParameter($name)
|
||||
{
|
||||
return isset($this->info['query'][$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all query parameters.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getQueryParameters()
|
||||
{
|
||||
return $this->info['query'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a query parameter value.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getQueryParameter($name)
|
||||
{
|
||||
return isset($this->info['query'][$name]) ? $this->info['query'][$name] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a clone with a new query parameter.
|
||||
*
|
||||
* @param string $name The parameter name
|
||||
* @param string $value The parameter value
|
||||
*
|
||||
* @return Url
|
||||
*/
|
||||
public function withQueryParameter($name, $value)
|
||||
{
|
||||
$clone = clone $this;
|
||||
|
||||
$clone->info['query'][$name] = $value;
|
||||
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a clone with new query parameters merged.
|
||||
*
|
||||
* @param array $parameters
|
||||
*
|
||||
* @return Url
|
||||
*/
|
||||
public function withAddedQueryParameters(array $parameters)
|
||||
{
|
||||
$clone = clone $this;
|
||||
|
||||
$clone->info['query'] = empty($clone->info['query']) ? $parameters : array_replace($clone->info['query'], $parameters);
|
||||
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a clone with new query parameters.
|
||||
*
|
||||
* @param array $parameters
|
||||
*
|
||||
* @return Url
|
||||
*/
|
||||
public function withQueryParameters(array $parameters)
|
||||
{
|
||||
$clone = clone $this;
|
||||
|
||||
$clone->info['query'] = $parameters;
|
||||
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the url fragment.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFragment()
|
||||
{
|
||||
return isset($this->info['fragment']) ? $this->info['fragment'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return ClassName for domain.
|
||||
*
|
||||
* Domains started with numbers will get N prepended to their class name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getClassNameForDomain()
|
||||
{
|
||||
$className = str_replace(array('-', ' '), '', ucwords(strtolower($this->getDomain())));
|
||||
|
||||
if (is_numeric(mb_substr($className, 0, 1))) {
|
||||
$className = 'N'.$className;
|
||||
}
|
||||
|
||||
return $className;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the url using the splitted data.
|
||||
*/
|
||||
protected function buildUrl()
|
||||
{
|
||||
$url = '';
|
||||
|
||||
if (isset($this->info['content'])) {
|
||||
return 'data:'.$this->info['content'];
|
||||
}
|
||||
|
||||
if (isset($this->info['scheme'])) {
|
||||
$url .= $this->info['scheme'].'://';
|
||||
}
|
||||
|
||||
$user = isset($this->info['user']) ? $this->info['user'] : '';
|
||||
$pass = isset($this->info['pass']) ? ':'.$this->info['pass'] : '';
|
||||
if ($user || $pass) {
|
||||
$url .= $user.$pass.'@';
|
||||
}
|
||||
|
||||
if (isset($this->info['host'])) {
|
||||
$url .= $this->info['host'];
|
||||
}
|
||||
|
||||
if (isset($this->info['port'])) {
|
||||
$url .= ':'.$this->info['port'];
|
||||
}
|
||||
|
||||
$url .= $this->getPath();
|
||||
|
||||
if (!empty($this->info['query'])) {
|
||||
$url .= '?'.http_build_query($this->info['query']);
|
||||
}
|
||||
if (isset($this->info['fragment'])) {
|
||||
$url .= '#'.$this->info['fragment'];
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an url and split into different pieces.
|
||||
*
|
||||
* @param string $url The url to parse
|
||||
*/
|
||||
protected function parseUrl($url)
|
||||
{
|
||||
$this->info = self::parse($url);
|
||||
|
||||
if (isset($this->info['path'])) {
|
||||
$this->setPath($this->info['path']);
|
||||
}
|
||||
|
||||
if (empty($this->info['query'])) {
|
||||
$this->info['query'] = [];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Fix dots and other characters used in query's variables names
|
||||
// https://github.com/oscarotero/Embed/issues/101
|
||||
$queryString = preg_replace_callback('/(^|(?<=&))[^=[&]+/', function ($key) {
|
||||
return bin2hex(urldecode($key[0]));
|
||||
}, $this->info['query']);
|
||||
|
||||
parse_str($queryString, $query);
|
||||
|
||||
$this->info['query'] = [];
|
||||
|
||||
foreach ((array) $query as $key => $value) {
|
||||
$this->info['query'][hex2bin($key)] = $value;
|
||||
}
|
||||
|
||||
array_walk_recursive($this->info['query'], function (&$value) {
|
||||
$value = urldecode($value);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an absolute url based in a relative.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAbsolute($url)
|
||||
{
|
||||
$url = trim($url);
|
||||
|
||||
if (empty($url)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (strpos($url, 'data:') === 0) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
if (preg_match('|^\w+://|', $url)) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
if (strpos($url, '://') === 0) {
|
||||
return $this->getScheme().$url;
|
||||
}
|
||||
|
||||
if (strpos($url, '//') === 0) {
|
||||
return $this->getScheme().":$url";
|
||||
}
|
||||
|
||||
if ($url[0] === '/') {
|
||||
return $this->getScheme().'://'.$this->getHost().$url;
|
||||
}
|
||||
|
||||
return $this->getScheme().'://'.$this->getHost().$this->getDirectories().$url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses and adds path and file value.
|
||||
*
|
||||
* @param string $path
|
||||
*/
|
||||
private function setPath($path)
|
||||
{
|
||||
$this->info['path'] = $this->info['file'] = $this->info['extension'] = $this->info['content'] = null;
|
||||
|
||||
if ($this->getScheme() === 'data') {
|
||||
$this->info['content'] = $path;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$file = substr(strrchr($path, '/'), 1);
|
||||
|
||||
if (strlen($file)) {
|
||||
$path = substr($path, 0, -strlen($file));
|
||||
|
||||
if (preg_match('/(.*)\.([\w]+)$/', $file, $match)) {
|
||||
$this->info['file'] = urldecode($match[1]);
|
||||
$this->info['extension'] = $match[2];
|
||||
} else {
|
||||
$this->info['file'] = urldecode($file);
|
||||
}
|
||||
}
|
||||
|
||||
$this->info['path'] = [];
|
||||
|
||||
foreach (explode('/', $path) as $dir) {
|
||||
$dir = urldecode($dir);
|
||||
|
||||
if ($dir !== '') {
|
||||
$this->info['path'][] = $dir;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static function getSuffixes()
|
||||
{
|
||||
if (self::$public_suffix_list === null) {
|
||||
self::$public_suffix_list = include __DIR__.'/../resources/public_suffix_list.php';
|
||||
}
|
||||
|
||||
return self::$public_suffix_list;
|
||||
}
|
||||
|
||||
/**
|
||||
* UTF-8 compatible parse_url
|
||||
* http://php.net/manual/en/function.parse-url.php#114817
|
||||
*
|
||||
* @param string $url
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function parse($url)
|
||||
{
|
||||
$enc_url = preg_replace_callback(
|
||||
'%[^:/@?&=#]+%usD',
|
||||
function ($matches) {
|
||||
return urlencode($matches[0]);
|
||||
},
|
||||
$url
|
||||
);
|
||||
|
||||
$parts = parse_url($enc_url);
|
||||
|
||||
if ($parts === false) {
|
||||
throw new \InvalidArgumentException('Malformed URL: ' . $url);
|
||||
}
|
||||
|
||||
foreach($parts as $name => $value) {
|
||||
$parts[$name] = urldecode($value);
|
||||
}
|
||||
|
||||
return $parts;
|
||||
}
|
||||
}
|
||||
98
site/OFF_plugins/embed/vendor/Embed/src/Providers/Api/Archive.php
vendored
Normal file
98
site/OFF_plugins/embed/vendor/Embed/src/Providers/Api/Archive.php
vendored
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Providers\Api;
|
||||
|
||||
use Embed\Adapters\Adapter;
|
||||
use Embed\Providers\Provider;
|
||||
|
||||
/**
|
||||
* Provider to use the API of archive.org.
|
||||
*/
|
||||
class Archive extends Provider
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(Adapter $adapter)
|
||||
{
|
||||
parent::__construct($adapter);
|
||||
|
||||
$endPoint = $adapter->getResponse()->getUrl()->withQueryParameter('output', 'json');
|
||||
$response = $adapter->getDispatcher()->dispatch($endPoint);
|
||||
|
||||
if (($json = $response->getJsonContent())) {
|
||||
$this->bag->set($json);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->bag->get('metadata[title][0]');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->bag->get('metadata[description][0]');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
switch ($this->bag->get('metadata[mediatype][0]')) {
|
||||
case 'movies':
|
||||
return 'video';
|
||||
|
||||
case 'audio':
|
||||
return 'audio';
|
||||
|
||||
case 'texts':
|
||||
return 'rich';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getProviderName()
|
||||
{
|
||||
return 'Internet Archive';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getUrl()
|
||||
{
|
||||
return $this->normalizeUrl($this->bag->get('url'));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAuthorName()
|
||||
{
|
||||
$this->bag->get('metadata[creator][0]');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getImagesUrls()
|
||||
{
|
||||
$images = (array) $this->bag->get('misc[image]');
|
||||
|
||||
foreach (array_keys((array) $this->bag->get('files')) as $url) {
|
||||
$images[] = $url;
|
||||
}
|
||||
|
||||
return $this->normalizeUrls($images);
|
||||
}
|
||||
}
|
||||
71
site/OFF_plugins/embed/vendor/Embed/src/Providers/Api/Gist.php
vendored
Normal file
71
site/OFF_plugins/embed/vendor/Embed/src/Providers/Api/Gist.php
vendored
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Providers\Api;
|
||||
|
||||
use Embed\Adapters\Adapter;
|
||||
use Embed\Providers\Provider;
|
||||
|
||||
/**
|
||||
* Provider to use the API of gist.github.com.
|
||||
*/
|
||||
class Gist extends Provider
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(Adapter $adapter)
|
||||
{
|
||||
parent::__construct($adapter);
|
||||
|
||||
$endPoint = $adapter->getResponse()->getUrl()->withExtension('json');
|
||||
$response = $adapter->getDispatcher()->dispatch($endPoint);
|
||||
|
||||
if (($json = $response->getJsonContent())) {
|
||||
$this->bag->set($json);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->bag->get('description');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
if ($this->getCode() !== null) {
|
||||
return 'rich';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAuthorName()
|
||||
{
|
||||
return $this->bag->get('owner');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPublishedTime()
|
||||
{
|
||||
return $this->bag->get('created_at');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
if (($code = $this->bag->get('div', true)) && ($stylesheet = $this->normalizeUrl($this->bag->get('stylesheet')))) {
|
||||
return '<link href="'.$stylesheet.'" rel="stylesheet">'.$code;
|
||||
}
|
||||
}
|
||||
}
|
||||
93
site/OFF_plugins/embed/vendor/Embed/src/Providers/Api/GoogleMaps.php
vendored
Normal file
93
site/OFF_plugins/embed/vendor/Embed/src/Providers/Api/GoogleMaps.php
vendored
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Providers\Api;
|
||||
|
||||
use Embed\Adapters\Adapter;
|
||||
use Embed\Providers\Provider;
|
||||
use Embed\Utils;
|
||||
|
||||
/**
|
||||
* Provider to use the API of google.com
|
||||
*/
|
||||
class GoogleMaps extends Provider
|
||||
{
|
||||
protected $mode;
|
||||
protected $config = [
|
||||
'key' => null,
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(Adapter $adapter)
|
||||
{
|
||||
parent::__construct($adapter);
|
||||
|
||||
$mode = $adapter->getResponse()->getUrl()->getDirectoryPosition(1);
|
||||
|
||||
switch ($mode) {
|
||||
case 'place':
|
||||
case 'dir':
|
||||
case 'search':
|
||||
$this->mode = $mode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
$url = $this->adapter->getResponse()->getUrl();
|
||||
|
||||
if ($this->mode === 'place') {
|
||||
return $url->getDirectoryPosition(2);
|
||||
}
|
||||
|
||||
if ($this->mode === 'dir') {
|
||||
return $url->getDirectoryPosition(2).' / '.$url->getDirectoryPosition(3);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getProviderName()
|
||||
{
|
||||
return 'Google Maps';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
$url = $this->adapter->getResponse()->getUrl();
|
||||
$key = $this->adapter->getConfig('google[key]');
|
||||
|
||||
if (empty($key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch ($this->mode) {
|
||||
case 'place':
|
||||
case 'search':
|
||||
return Utils::iframe($url
|
||||
->withPath('maps/embed/v1/'.$this->mode)
|
||||
->withQueryParameters([
|
||||
'q' => $url->getDirectoryPosition(2),
|
||||
'key' => $key,
|
||||
]));
|
||||
|
||||
case 'dir':
|
||||
return Utils::iframe($url
|
||||
->withPath('maps/embed/v1/directions')
|
||||
->withQueryParameters([
|
||||
'origin' => $url->getDirectoryPosition(2),
|
||||
'destination' => $url->getDirectoryPosition(3),
|
||||
'key' => $key,
|
||||
]));
|
||||
}
|
||||
}
|
||||
}
|
||||
105
site/OFF_plugins/embed/vendor/Embed/src/Providers/Api/Imageshack.php
vendored
Normal file
105
site/OFF_plugins/embed/vendor/Embed/src/Providers/Api/Imageshack.php
vendored
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Providers\Api;
|
||||
|
||||
use Embed\Http\Url;
|
||||
use Embed\Adapters\Adapter;
|
||||
use Embed\Providers\Provider;
|
||||
|
||||
/**
|
||||
* Provider to use the API of imageshack.com.
|
||||
*/
|
||||
class Imageshack extends Provider
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(Adapter $adapter)
|
||||
{
|
||||
parent::__construct($adapter);
|
||||
|
||||
$id = $adapter->getResponse()->getUrl()->getDirectoryPosition(1);
|
||||
$endPoint = Url::create('https://api.imageshack.com/v2/images/'.$id);
|
||||
$response = $adapter->getDispatcher()->dispatch($endPoint);
|
||||
|
||||
if (($json = $response->getJsonContent()) && !empty($json['result'])) {
|
||||
$this->bag->set($json['result']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->bag->get('title');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->bag->get('description');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return 'photo';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPublishedTime()
|
||||
{
|
||||
return $this->bag->get('creation_date');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getWidth()
|
||||
{
|
||||
return $this->bag->get('width');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getHeight()
|
||||
{
|
||||
return $this->bag->get('height');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAuthorName()
|
||||
{
|
||||
return $this->bag->get('owner[username]');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAuthorUrl()
|
||||
{
|
||||
$username = $this->getAuthorName();
|
||||
|
||||
if (!empty($username)) {
|
||||
return 'http://imageshack.com/user/'.$username;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getImagesUrls()
|
||||
{
|
||||
return $this->normalizeUrls($this->bag->get('direct_link'));
|
||||
}
|
||||
}
|
||||
91
site/OFF_plugins/embed/vendor/Embed/src/Providers/Api/Soundcloud.php
vendored
Normal file
91
site/OFF_plugins/embed/vendor/Embed/src/Providers/Api/Soundcloud.php
vendored
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Providers\Api;
|
||||
|
||||
use Embed\Http\Url;
|
||||
use Embed\Adapters\Adapter;
|
||||
use Embed\Providers\Provider;
|
||||
|
||||
/**
|
||||
* Provider to use the API of soundcloud.
|
||||
*/
|
||||
class Soundcloud extends Provider
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(Adapter $adapter)
|
||||
{
|
||||
parent::__construct($adapter);
|
||||
|
||||
$key = $adapter->getConfig('soundcloud[key]');
|
||||
|
||||
if (!empty($key)) {
|
||||
$endPoint = Url::create('http://api.soundcloud.com/resolve.json')
|
||||
->withQueryParameters([
|
||||
'client_id' => $key,
|
||||
'url' => (string) $adapter->getResponse()->getUrl(),
|
||||
]);
|
||||
|
||||
$response = $adapter->getDispatcher()->dispatch($endPoint);
|
||||
|
||||
if ($json = $response->getJsonContent()) {
|
||||
$this->bag->set($json);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->bag->get('title');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->bag->get('description');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getUrl()
|
||||
{
|
||||
return $this->normalizeUrl($this->bag->get('permalink_url'));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getImagesUrls()
|
||||
{
|
||||
$images = [];
|
||||
|
||||
if (empty($this->bag->get('artwork_url')) && ($img = $this->bag->get('user[avatar_url]'))) {
|
||||
$images[] = str_replace('-large.jpg', '-t500x500.jpg', $img);
|
||||
}
|
||||
|
||||
return $this->normalizeUrls($images);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAuthorName()
|
||||
{
|
||||
return $this->bag->get('user[username]');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAuthorUrl()
|
||||
{
|
||||
return $this->normalizeUrl($this->bag->get('user[permalink_url]'));
|
||||
}
|
||||
}
|
||||
134
site/OFF_plugins/embed/vendor/Embed/src/Providers/Api/Wikipedia.php
vendored
Normal file
134
site/OFF_plugins/embed/vendor/Embed/src/Providers/Api/Wikipedia.php
vendored
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Providers\Api;
|
||||
|
||||
use Embed\Adapters\Adapter;
|
||||
use Embed\Providers\Provider;
|
||||
|
||||
/**
|
||||
* Provider to use the API of wikipedia.
|
||||
*/
|
||||
class Wikipedia extends Provider
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(Adapter $adapter)
|
||||
{
|
||||
parent::__construct($adapter);
|
||||
|
||||
$titles = $adapter->getResponse()->getUrl()->getDirectoryPosition(1);
|
||||
|
||||
if (!empty($titles)) {
|
||||
//extract images
|
||||
$endPoint = $adapter->getResponse()->getUrl()
|
||||
->withPath('/w/api.php')
|
||||
->withQueryParameters([
|
||||
'action' => 'query',
|
||||
'format' => 'json',
|
||||
'continue' => '',
|
||||
'titles' => $titles,
|
||||
'prop' => 'images',
|
||||
]);
|
||||
|
||||
$response = $adapter->getDispatcher()->dispatch($endPoint);
|
||||
|
||||
if (($json = $response->getJsonContent())) {
|
||||
$this->bag->set('images', $json);
|
||||
}
|
||||
|
||||
//extract content
|
||||
$endPoint = $endPoint
|
||||
->withQueryParameter('prop', 'extracts')
|
||||
->withQueryParameter('exchars', 1500);
|
||||
|
||||
$response = $adapter->getDispatcher()->dispatch($endPoint);
|
||||
|
||||
if (($json = $response->getJsonContent())) {
|
||||
$this->bag->set('extracts', $json);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
$pages = $this->bag->get('extracts[query][pages]');
|
||||
|
||||
if (!empty($pages)) {
|
||||
$page = current($pages);
|
||||
|
||||
return strip_tags($page['title']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
$pages = $this->bag->get('extracts[query][pages]');
|
||||
|
||||
if (!empty($pages)) {
|
||||
return $this->bag->get('extracts[query][pages]['.key($pages).'][extract]');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getImagesUrls()
|
||||
{
|
||||
$images = [];
|
||||
|
||||
$pages = $this->bag->get('images[query][pages]');
|
||||
|
||||
if (!empty($pages)) {
|
||||
$page = current($pages);
|
||||
|
||||
$imgs = [];
|
||||
|
||||
if (isset($page['images'])) {
|
||||
foreach ($page['images'] as $image) {
|
||||
switch (strrchr($image['title'], '.')) {
|
||||
case '.png':
|
||||
case '.jpg':
|
||||
case '.gif':
|
||||
case '.jpeg':
|
||||
$imgs[] = $image['title'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Get image urls
|
||||
if (!empty($imgs)) {
|
||||
$endPoint = $this->adapter->getResponse()->getUrl()
|
||||
->withPath('/w/api.php')
|
||||
->withQueryParameters([
|
||||
'action' => 'query',
|
||||
'prop' => 'imageinfo',
|
||||
'iiprop' => 'url',
|
||||
'format' => 'json',
|
||||
'continue' => '',
|
||||
'titles' => implode('|', $imgs),
|
||||
]);
|
||||
|
||||
$response = $this->adapter->getDispatcher()->dispatch($endPoint);
|
||||
$json = $response->getJsonContent();
|
||||
|
||||
if (isset($json['query']['pages'])) {
|
||||
foreach ($json['query']['pages'] as $page) {
|
||||
if (isset($page['imageinfo'][0]['url'])) {
|
||||
$images[] = $page['imageinfo'][0]['url'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->normalizeUrls($images);
|
||||
}
|
||||
}
|
||||
75
site/OFF_plugins/embed/vendor/Embed/src/Providers/Dcterms.php
vendored
Normal file
75
site/OFF_plugins/embed/vendor/Embed/src/Providers/Dcterms.php
vendored
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Providers;
|
||||
|
||||
use Embed\Adapters\Adapter;
|
||||
|
||||
/**
|
||||
* Provider to get the data from the Dublin Core data elements in the HTML
|
||||
*/
|
||||
class Dcterms extends Provider
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(Adapter $adapter)
|
||||
{
|
||||
parent::__construct($adapter);
|
||||
|
||||
if (!($html = $adapter->getResponse()->getHtmlContent())) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($html->getElementsByTagName('meta') as $meta) {
|
||||
$name = trim(strtolower($meta->getAttribute('name')));
|
||||
$value = $meta->getAttribute('content');
|
||||
|
||||
if (empty($name) || empty($value)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (['dc.', 'dc:', 'dcterms:'] as $prefix) {
|
||||
if (stripos($name, $prefix) === 0) {
|
||||
$name = substr($name, strlen($prefix));
|
||||
$this->bag->set($name, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->bag->get('title');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->bag->get('description');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAuthorName()
|
||||
{
|
||||
return $this->bag->get('creator') ?: $this->bag->get('author');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPublishedTime()
|
||||
{
|
||||
foreach (['date', 'date.created', 'date.issued'] as $key) {
|
||||
if ($found = $this->bag->get($key)) {
|
||||
return $found;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
424
site/OFF_plugins/embed/vendor/Embed/src/Providers/Html.php
vendored
Normal file
424
site/OFF_plugins/embed/vendor/Embed/src/Providers/Html.php
vendored
Normal file
|
|
@ -0,0 +1,424 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Providers;
|
||||
|
||||
use Embed\Utils;
|
||||
use Embed\Adapters\Adapter;
|
||||
use Embed\Http\Url;
|
||||
use DOMDocument;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Provider to get the data from the HTML code
|
||||
*/
|
||||
class Html extends Provider
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(Adapter $adapter)
|
||||
{
|
||||
parent::__construct($adapter);
|
||||
|
||||
if (!($html = $adapter->getResponse()->getHtmlContent())) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->extractLinks($html);
|
||||
$this->extractMetas($html);
|
||||
$this->extractImages($html);
|
||||
|
||||
//Title
|
||||
$title = $html->getElementsByTagName('title');
|
||||
|
||||
if ($title->length) {
|
||||
$this->bag->set('title', $title->item(0)->nodeValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->bag->get('title');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->bag->get('description');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return $this->bag->has('video_src') ? 'video' : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTags()
|
||||
{
|
||||
$keywords = $this->bag->get('keywords').','.$this->bag->get('news_keywords');
|
||||
|
||||
return array_filter(array_map('trim', explode(',', $keywords)));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFeeds()
|
||||
{
|
||||
return $this->normalizeUrls($this->bag->get('feeds'));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
$src = $this->normalizeUrl($this->bag->get('video_src'));
|
||||
|
||||
if ($src !== null) {
|
||||
switch ($this->bag->get('video_type')) {
|
||||
case 'application/x-shockwave-flash':
|
||||
return Utils::flash($src, $this->getWidth(), $this->getHeight());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getUrl()
|
||||
{
|
||||
return $this->normalizeUrl($this->bag->get('canonical'));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAuthorName()
|
||||
{
|
||||
return $this->bag->get('author') ?: $this->bag->get('article:author') ?: $this->bag->get('contributors');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getProviderIconsUrls()
|
||||
{
|
||||
return $this->normalizeUrls($this->bag->get('icons'));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getImagesUrls()
|
||||
{
|
||||
$images = $this->normalizeUrls($this->bag->get('images'));
|
||||
|
||||
if (!empty($images)) {
|
||||
$maxImages = $this->adapter->getConfig('html[max_images]', -1);
|
||||
|
||||
if ($maxImages > -1) {
|
||||
return array_slice($images, 0, $maxImages);
|
||||
}
|
||||
}
|
||||
|
||||
return $images;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getWidth()
|
||||
{
|
||||
return ((int) $this->bag->get('video_width')) ?: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getHeight()
|
||||
{
|
||||
return ((int) $this->bag->get('video_height')) ?: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPublishedTime()
|
||||
{
|
||||
$keys = [
|
||||
'article:published_time',
|
||||
'created',
|
||||
'date',
|
||||
'datepublished',
|
||||
'datePublished',
|
||||
'newsrepublic:publish_date',
|
||||
'pagerender',
|
||||
'pub_date',
|
||||
'publication-date',
|
||||
'publish-date',
|
||||
'rc.datecreation',
|
||||
'timestamp',
|
||||
'article:modified_time',
|
||||
'eomportal-lastupdate',
|
||||
'shareaholic:article_published_time',
|
||||
];
|
||||
|
||||
foreach ($keys as $key) {
|
||||
if ($found = $this->bag->get($key)) {
|
||||
return $found;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLicense()
|
||||
{
|
||||
return $this->bag->get('copyright');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLinkedData()
|
||||
{
|
||||
$data = [];
|
||||
|
||||
if (!($html = $this->adapter->getResponse()->getHtmlContent())) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
foreach ($html->getElementsByTagName('script') as $script) {
|
||||
if ($script->hasAttribute('type') && strtolower($script->getAttribute('type')) === 'application/ld+json') {
|
||||
$value = trim($script->nodeValue);
|
||||
|
||||
if (empty($value)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
$data[] = json_decode($value);
|
||||
} catch (Exception $exception) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract information from the <link> elements.
|
||||
*
|
||||
* @param DOMDocument $html
|
||||
*/
|
||||
private function extractLinks(DOMDocument $html)
|
||||
{
|
||||
foreach ($html->getElementsByTagName('link') as $link) {
|
||||
if ($link->hasAttribute('rel') && $link->hasAttribute('href')) {
|
||||
$rel = trim(strtolower($link->getAttribute('rel')));
|
||||
$href = $link->getAttribute('href');
|
||||
|
||||
if (empty($href)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch ($rel) {
|
||||
case 'favicon':
|
||||
case 'favico':
|
||||
case 'icon':
|
||||
case 'shortcut icon':
|
||||
case 'apple-touch-icon-precomposed':
|
||||
case 'apple-touch-icon':
|
||||
$this->bag->add('icons', $href);
|
||||
break;
|
||||
|
||||
case 'image_src':
|
||||
$this->bag->add('images', $href);
|
||||
break;
|
||||
|
||||
case 'alternate':
|
||||
switch ($link->getAttribute('type')) {
|
||||
case 'application/rss+xml':
|
||||
case 'application/atom+xml':
|
||||
$this->bag->add('feeds', $href);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->bag->set($rel, $href);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract information from the <meta> elements.
|
||||
*
|
||||
* @param DOMDocument $html
|
||||
*/
|
||||
private function extractMetas(DOMDocument $html)
|
||||
{
|
||||
foreach ($html->getElementsByTagName('meta') as $meta) {
|
||||
$value = $meta->getAttribute('content');
|
||||
|
||||
if (empty($value)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($meta->hasAttribute('name')) {
|
||||
$name = trim(strtolower($meta->getAttribute('name')));
|
||||
|
||||
switch ($name) {
|
||||
case 'msapplication-tileimage':
|
||||
$this->bag->add('icons', $value);
|
||||
continue 2;
|
||||
|
||||
default:
|
||||
$this->bag->set($name, $value);
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
|
||||
if ($meta->hasAttribute('itemprop')) {
|
||||
$this->bag->set($meta->getAttribute('itemprop'), $value);
|
||||
}
|
||||
|
||||
if ($meta->hasAttribute('http-equiv')) {
|
||||
$this->bag->set($meta->getAttribute('http-equiv'), $value);
|
||||
}
|
||||
|
||||
if ($meta->hasAttribute('property')) {
|
||||
$this->bag->set($meta->getAttribute('property'), $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract <img> elements.
|
||||
*
|
||||
* @param DOMDocument $html
|
||||
*/
|
||||
private function extractImages(DOMDocument $html)
|
||||
{
|
||||
if ($this->adapter->getConfig('html[max_images]') === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Extract only from the main element
|
||||
$main = self::getMainElement($html);
|
||||
|
||||
if (!$main) {
|
||||
return;
|
||||
}
|
||||
|
||||
$url = $this->adapter->getResponse()->getUrl();
|
||||
$externalImages = $this->adapter->getConfig('html[external_images]');
|
||||
|
||||
foreach ($main->getElementsByTagName('img') as $img) {
|
||||
if (!$img->hasAttribute('src')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$src = $url->createAbsolute($img->getAttribute('src'));
|
||||
|
||||
//Avoid external images
|
||||
if (!self::imageIsValid($src, $url, $externalImages)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$parent = $img->parentNode;
|
||||
|
||||
//The image is in a link
|
||||
while ($parent && isset($parent->tagName)) {
|
||||
if ($parent->tagName === 'a') {
|
||||
//The link is external
|
||||
if ($parent->hasAttribute('href')) {
|
||||
$href = $url->createAbsolute($parent->getAttribute('href'));
|
||||
|
||||
if (!self::imageIsValid($href, $url, $externalImages)) {
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
|
||||
//The link has rel=nofollow
|
||||
if ($parent->hasAttribute('rel') && (string) $parent->getAttribute('rel') === 'nofollow') {
|
||||
continue 2;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
$parent = $parent->parentNode;
|
||||
}
|
||||
|
||||
$this->bag->add('images', (string) $src);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a image url is valid or not.
|
||||
*
|
||||
* @param Url $url
|
||||
* @param Url $baseUrl
|
||||
* @param mixed $externalImages
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function imageIsValid(Url $url, Url $baseUrl, $externalImages)
|
||||
{
|
||||
//base64 or same domain
|
||||
if ($url->getContent() !== null || $url->getDomain() === $baseUrl->getDomain()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return is_bool($externalImages) ? $externalImages : $url->match($externalImages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the main element of the document.
|
||||
*
|
||||
* @param DOMDocument $html
|
||||
*
|
||||
* @return DOMElement
|
||||
*/
|
||||
private static function getMainElement(DOMDocument $html)
|
||||
{
|
||||
// <main>
|
||||
$content = $html->getElementsByTagName('main');
|
||||
|
||||
if ($content->length !== 0) {
|
||||
return $content->item(0);
|
||||
}
|
||||
|
||||
// Popular ids: #main, #content, #page
|
||||
$content = $html->getElementById('main') ?: $html->getElementById('content') ?: $html->getElementById('page');
|
||||
|
||||
if ($content) {
|
||||
return $content;
|
||||
}
|
||||
|
||||
// Wordpress ids: #post-*
|
||||
foreach ($html->getElementsByTagName('article') as $article) {
|
||||
if ($article->hasAttribute('id') && (strpos($article->getAttribute('id'), 'post-') === 0)) {
|
||||
return $article;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns <body> or <html>
|
||||
return $html->getElementsByTagName('body')->item(0) ?: $html->getElementsByTagName('html')->item(0);
|
||||
}
|
||||
}
|
||||
248
site/OFF_plugins/embed/vendor/Embed/src/Providers/OEmbed.php
vendored
Normal file
248
site/OFF_plugins/embed/vendor/Embed/src/Providers/OEmbed.php
vendored
Normal file
|
|
@ -0,0 +1,248 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Providers;
|
||||
|
||||
use Embed\Adapters\Adapter;
|
||||
use Embed\Http\Response;
|
||||
use Embed\Http\Url;
|
||||
|
||||
/**
|
||||
* Provider to get the data using the oEmbed API
|
||||
*/
|
||||
class OEmbed extends Provider
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(Adapter $adapter)
|
||||
{
|
||||
parent::__construct($adapter);
|
||||
|
||||
$endPoint = $this->getEndPoint();
|
||||
|
||||
if ($endPoint) {
|
||||
$this->extractOembed($adapter->getDispatcher()->dispatch($endPoint));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->bag->get('title');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->bag->get('description');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
$type = $this->bag->get('type');
|
||||
|
||||
if (strpos($type, ':') !== false) {
|
||||
$type = substr(strrchr($type, ':'), 1);
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
case 'video':
|
||||
case 'photo':
|
||||
case 'link':
|
||||
case 'rich':
|
||||
return $type;
|
||||
|
||||
case 'movie':
|
||||
return 'video';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTags()
|
||||
{
|
||||
if ($this->bag->has('meta[keywords]')) {
|
||||
//it means we are using iframe.ly api
|
||||
return array_map('trim', explode(',', $this->bag->get('meta[keywords]')));
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
return $this->bag->get('html', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getUrl()
|
||||
{
|
||||
if ($this->getType() === 'photo') {
|
||||
return $this->normalizeUrl($this->bag->get('web_page'));
|
||||
}
|
||||
|
||||
return $this->normalizeUrl($this->bag->get('url') ?: $this->bag->get('web_page'));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAuthorName()
|
||||
{
|
||||
return $this->bag->get('author_name');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAuthorUrl()
|
||||
{
|
||||
return $this->normalizeUrl($this->bag->get('author_url'));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getProviderName()
|
||||
{
|
||||
return $this->bag->get('provider_name');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getProviderUrl()
|
||||
{
|
||||
return $this->normalizeUrl($this->bag->get('provider_url'));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getImagesUrls()
|
||||
{
|
||||
$images = [];
|
||||
|
||||
if ($this->getType() === 'photo') {
|
||||
$images[] = $this->bag->get('url');
|
||||
}
|
||||
|
||||
foreach (['image', 'thumbnail', 'thumbnail_url'] as $type) {
|
||||
if ($this->bag->has($type)) {
|
||||
$ret = $this->bag->get($type);
|
||||
|
||||
if (is_array($ret)) {
|
||||
$images = array_merge($images, $ret);
|
||||
} else {
|
||||
$images[] = $ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->normalizeUrls($images);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getWidth()
|
||||
{
|
||||
return $this->bag->get('width');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getHeight()
|
||||
{
|
||||
return $this->bag->get('height');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLicense()
|
||||
{
|
||||
return $this->bag->get('license_url');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Url|null
|
||||
*/
|
||||
private function getEndPoint()
|
||||
{
|
||||
//Search using the domain
|
||||
$class = 'Embed\\Providers\\OEmbed\\'.$this->adapter->getResponse()->getUrl()->getClassNameForDomain();
|
||||
$extraParameters = (array) $this->adapter->getConfig('oembed[parameters]');
|
||||
|
||||
if (class_exists($class)) {
|
||||
$endPoint = $class::create($this->adapter);
|
||||
|
||||
if ($endPoint && ($url = $endPoint->getEndPoint())) {
|
||||
return $url->withAddedQueryParameters($extraParameters);
|
||||
}
|
||||
}
|
||||
|
||||
//Search in the DOM
|
||||
$endPoint = OEmbed\DOM::create($this->adapter);
|
||||
|
||||
if ($endPoint && ($url = $endPoint->getEndPoint())) {
|
||||
return $url->withAddedQueryParameters($extraParameters);
|
||||
}
|
||||
|
||||
//Try with embedly
|
||||
$endPoint = OEmbed\Embedly::create($this->adapter);
|
||||
|
||||
if ($endPoint && ($url = $endPoint->getEndPoint())) {
|
||||
return $url->withAddedQueryParameters($extraParameters);
|
||||
}
|
||||
|
||||
//Try with iframely
|
||||
$endPoint = OEmbed\Iframely::create($this->adapter);
|
||||
|
||||
if ($endPoint && ($url = $endPoint->getEndPoint())) {
|
||||
return $url->withAddedQueryParameters($extraParameters);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the oembed data in the bag.
|
||||
*
|
||||
* @param Response $response
|
||||
*/
|
||||
private function extractOembed(Response $response)
|
||||
{
|
||||
// extract from xml
|
||||
if (($response->getUrl()->getExtension() === 'xml') || ($response->getUrl()->getQueryParameter('format') === 'xml')) {
|
||||
if ($xml = $response->getXmlContent()) {
|
||||
foreach ($xml as $element) {
|
||||
$content = trim((string) $element);
|
||||
|
||||
if (stripos($content, '<![CDATA[') === 0) {
|
||||
$content = substr($content, 9, -3);
|
||||
}
|
||||
|
||||
$this->bag->set($element->getName(), $content);
|
||||
}
|
||||
}
|
||||
// extract from json
|
||||
} else {
|
||||
if (($json = $response->getJsonContent()) && empty($json['Error'])) {
|
||||
$this->bag->set($json);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
9
site/OFF_plugins/embed/vendor/Embed/src/Providers/OEmbed/Amcharts.php
vendored
Normal file
9
site/OFF_plugins/embed/vendor/Embed/src/Providers/OEmbed/Amcharts.php
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Providers\OEmbed;
|
||||
|
||||
class Amcharts extends EndPoint implements EndPointInterface
|
||||
{
|
||||
protected static $pattern = 'live.amcharts.com/*';
|
||||
protected static $endPoint = 'https://live.amcharts.com/oembed';
|
||||
}
|
||||
9
site/OFF_plugins/embed/vendor/Embed/src/Providers/OEmbed/Bambuser.php
vendored
Normal file
9
site/OFF_plugins/embed/vendor/Embed/src/Providers/OEmbed/Bambuser.php
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Embed\Providers\OEmbed;
|
||||
|
||||
class Bambuser extends EndPoint implements EndPointInterface
|
||||
{
|
||||
protected static $pattern = 'bambuser.com/v/*';
|
||||
protected static $endPoint = 'https://api.bambuser.com/oembed.json';
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue