Whoops \ Exception \ ErrorException (E_WARNING)
file_put_contents(/var/www/html/thumbs/_plugins/oembed/56c284953afd7a62280a521c2749ac8b.): failed to open stream: Permission denied Whoops\Exception\ErrorException thrown with message "file_put_contents(/var/www/html/thumbs/_plugins/oembed/56c284953afd7a62280a521c2749ac8b.): failed to open stream: Permission denied" Stacktrace: #16 Whoops\Exception\ErrorException in /var/www/html/site/plugins/oembed/core/lib/thumb.php:33 #15 file_put_contents in /var/www/html/site/plugins/oembed/core/lib/thumb.php:33 #14 Kirby\distantnative\Thumb:cache in /var/www/html/site/plugins/oembed/core/lib/thumb.php:24 #13 Kirby\distantnative\Thumb:__construct in /var/www/html/site/plugins/oembed/core/core.php:71 #12 Kirby\distantnative\oEmbed\Core:thumb in /var/www/html/site/plugins/oembed/core/html.php:106 #11 Kirby\distantnative\oEmbed\Html:lazyVideo in /var/www/html/site/plugins/oembed/core/html.php:91 #10 Kirby\distantnative\oEmbed\Html:prepareVideo in /var/www/html/site/plugins/oembed/core/html.php:70 #9 Kirby\distantnative\oEmbed\Html:prepareType in /var/www/html/site/plugins/oembed/core/html.php:32 #8 Kirby\distantnative\oEmbed\Html:__toString in /var/www/html/site/plugins/oembed/core/core.php:104 #7 Kirby\distantnative\oEmbed\Core:__toString in /var/www/html/site/templates/portfolio-video.php:3 #6 require in /var/www/html/kirby/vendor/getkirby/toolkit/lib/tpl.php:22 #5 Tpl:load in /var/www/html/kirby/kirby/component/template.php:103 #4 Kirby\Component\Template:render in /var/www/html/kirby/kirby.php:681 #3 Kirby:template in /var/www/html/kirby/kirby.php:669 #2 Kirby:render in /var/www/html/kirby/kirby/component/response.php:29 #1 Kirby\Component\Response:make in /var/www/html/kirby/kirby.php:751 #0 Kirby:launch in /var/www/html/index.php:16
Stack frames (17)
16
Whoops
\
Exception
\
ErrorException
/
var
/
www
/
html
/
site
/
plugins
/
oembed
/
core
/
lib
/
thumb.php
33
15
file_put_contents
/
var
/
www
/
html
/
site
/
plugins
/
oembed
/
core
/
lib
/
thumb.php
33
14
Kirby
\
distantnative
\
Thumb
cache
/
var
/
www
/
html
/
site
/
plugins
/
oembed
/
core
/
lib
/
thumb.php
24
13
Kirby
\
distantnative
\
Thumb
__construct
/
var
/
www
/
html
/
site
/
plugins
/
oembed
/
core
/
core.php
71
12
Kirby
\
distantnative
\
oEmbed
\
Core
thumb
/
var
/
www
/
html
/
site
/
plugins
/
oembed
/
core
/
html.php
106
11
Kirby
\
distantnative
\
oEmbed
\
Html
lazyVideo
/
var
/
www
/
html
/
site
/
plugins
/
oembed
/
core
/
html.php
91
10
Kirby
\
distantnative
\
oEmbed
\
Html
prepareVideo
/
var
/
www
/
html
/
site
/
plugins
/
oembed
/
core
/
html.php
70
9
Kirby
\
distantnative
\
oEmbed
\
Html
prepareType
/
var
/
www
/
html
/
site
/
plugins
/
oembed
/
core
/
html.php
32
8
Kirby
\
distantnative
\
oEmbed
\
Html
__toString
/
var
/
www
/
html
/
site
/
plugins
/
oembed
/
core
/
core.php
104
7
Kirby
\
distantnative
\
oEmbed
\
Core
__toString
/
var
/
www
/
html
/
site
/
templates
/
portfolio-video.php
3
6
require
/
vendor
/
getkirby
/
toolkit
/
lib
/
tpl.php
22
5
Tpl
load
/
kirby
/
component
/
template.php
103
4
Kirby
\
Component
\
Template
render
/
kirby.php
681
3
Kirby
template
/
kirby.php
669
2
Kirby
render
/
kirby
/
component
/
response.php
29
1
Kirby
\
Component
\
Response
make
/
kirby.php
751
0
Kirby
launch
/
var
/
www
/
html
/
index.php
16
/
var
/
www
/
html
/
site
/
plugins
/
oembed
/
core
/
lib
/
thumb.php
    $this->plugin    = $plugin;
    $this->source    = $url;
    $this->lifetime  = $lifetime;
 
    $this->root      = kirby()->roots()->thumbs() . DS . '_plugins';
    $this->dir       = $this->root . DS . $this->plugin;
    $this->file      = md5($this->source) . '.' . pathinfo(strtok($this->source, '?'), PATHINFO_EXTENSION);
    $this->path      = $this->dir . DS . $this->file;
 
    $this->dirs();
    $this->cache();
  }
 
  public function __toString() {
    return url('thumbs/_plugins/' . $this->plugin . '/' . $this->file);
  }
 
  protected function cache() {
    if($this->expired() or !f::exists($this->path)) {
      file_put_contents($this->path, file_get_contents($this->source));
    }
  }
 
  protected function expired() {
    if((f::modified($this->path) + $this->lifetime) < time()) {
      return f::remove($this->path);
    }
 
    return false;
  }
 
  protected function dirs() {
    if(!file_exists($this->root)) mkdir($this->root, 0755, true);
    if(!file_exists($this->dir))  mkdir($this->dir, 0755, true);
  }
 
 
}
 
/
var
/
www
/
html
/
site
/
plugins
/
oembed
/
core
/
lib
/
thumb.php
    $this->plugin    = $plugin;
    $this->source    = $url;
    $this->lifetime  = $lifetime;
 
    $this->root      = kirby()->roots()->thumbs() . DS . '_plugins';
    $this->dir       = $this->root . DS . $this->plugin;
    $this->file      = md5($this->source) . '.' . pathinfo(strtok($this->source, '?'), PATHINFO_EXTENSION);
    $this->path      = $this->dir . DS . $this->file;
 
    $this->dirs();
    $this->cache();
  }
 
  public function __toString() {
    return url('thumbs/_plugins/' . $this->plugin . '/' . $this->file);
  }
 
  protected function cache() {
    if($this->expired() or !f::exists($this->path)) {
      file_put_contents($this->path, file_get_contents($this->source));
    }
  }
 
  protected function expired() {
    if((f::modified($this->path) + $this->lifetime) < time()) {
      return f::remove($this->path);
    }
 
    return false;
  }
 
  protected function dirs() {
    if(!file_exists($this->root)) mkdir($this->root, 0755, true);
    if(!file_exists($this->dir))  mkdir($this->dir, 0755, true);
  }
 
 
}
 
/
var
/
www
/
html
/
site
/
plugins
/
oembed
/
core
/
lib
/
thumb.php
use C;
use F;
 
class Thumb {
 
  protected $dir;
  protected $root;
 
  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->file      = md5($this->source) . '.' . pathinfo(strtok($this->source, '?'), PATHINFO_EXTENSION);
    $this->path      = $this->dir . DS . $this->file;
 
    $this->dirs();
    $this->cache();
  }
 
  public function __toString() {
    return url('thumbs/_plugins/' . $this->plugin . '/' . $this->file);
  }
 
  protected function cache() {
    if($this->expired() or !f::exists($this->path)) {
      file_put_contents($this->path, file_get_contents($this->source));
    }
  }
 
  protected function expired() {
    if((f::modified($this->path) + $this->lifetime) < time()) {
      return f::remove($this->path);
    }
 
    return false;
  }
 
/
var
/
www
/
html
/
site
/
plugins
/
oembed
/
core
/
core.php
  protected function options($options) {
    return a::merge([
      'class'     => null,
      'thumb'     => null,
      'autoplay'  => c::get('plugin.oembed.video.autoplay', false),
      'lazyvideo' => c::get('plugin.oembed.video.lazyload', true),
      'jsapi'     => c::get('plugin.oembed.providers.jsapi', false),
    ], $options);
  }
 
 
  // ================================================
  //  Thumb
  // ================================================
 
  public function thumb() {
    // if custom thumbnail is set
    $thumb = $this->options['thumb'] ?: $this->image();
 
    return $this->cache ? new Thumb('oembed', $thumb,       (c::get('plugin.oembed.caching.duration', 24) * 60 * 60)) : $thumb;
  }
 
 
  // ================================================
  //  Custom provider instance
  // ================================================
 
  protected function provider() {
    $namespace = 'Kirby\Plugins\distantnative\oEmbed\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) {
/
var
/
www
/
html
/
site
/
plugins
/
oembed
/
core
/
html.php
      $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() . ')' : ''),
      'overlay' => $this->core->supportsPlayBtn()
    ]);
  }
 
  // ================================================
  //  Links
  // ================================================
 
  protected function prepareLink() {
    if(!$this->data['code']) {
      $this->updateData('code', $this->snippet('typeLink', [
        'url'  => $this->core->url(),
        'text' => $this->core->title()
      ]));
    }
  }
 
 
  // ================================================
/
var
/
www
/
html
/
site
/
plugins
/
oembed
/
core
/
html.php
 
    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() . ')' : ''),
      'overlay' => $this->core->supportsPlayBtn()
    ]);
  }
 
/
var
/
www
/
html
/
site
/
plugins
/
oembed
/
core
/
html.php
      '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()) {
/
var
/
www
/
html
/
site
/
plugins
/
oembed
/
core
/
html.php
    $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.oembed.error.' . $msg);
    $path = __DIR__ . DS . 'snippets' . DS . 'error.php';
 
    return tpl::load($path, [
      'url' => $url,
      'msg' => $msg
/
var
/
www
/
html
/
site
/
plugins
/
oembed
/
core
/
core.php
 
 
  // ================================================
  //  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);
  }
}
 
/
var
/
www
/
html
/
site
/
templates
/
portfolio-video.php
<?php snippet('header') ?>
 
<?= $page->featured_video()->oembed() ?>
 
<?php if(!$page->text()->empty()): ?>
    <hr class="invisible space">
    <?php echo $page->text()->kirbytext() ?>
<?php endif ?>
 
<?php snippet('footer') ?>
/
var
/
www
/
html
/
kirby
/
vendor
/
getkirby
/
toolkit
/
lib
/
tpl.php
/**
 * Tpl
 *
 * Super simple template engine
 *
 * @package   Kirby Toolkit
 * @author    Bastian Allgeier <bastian@getkirby.com>
 * @link      http://getkirby.com
 * @copyright Bastian Allgeier
 * @license   http://www.opensource.org/licenses/mit-license.php MIT License
 */
class Tpl extends Silo {
 
  public static $data = array();
 
  public static function load($_file, $_data = array(), $_return = true) {
    if(!file_exists($_file)) return false;
    ob_start();
    extract(array_merge(static::$data, (array)$_data));
    require($_file);
    $_content = ob_get_contents();
    ob_end_clean();
    if($_return) return $_content;
    echo $_content;
  }
 
}
/
var
/
www
/
html
/
kirby
/
kirby
/
component
/
template.php
    if($template instanceof Page) {
      $page = $template;
      $file = $page->templateFile();
      $data = $this->data($page, $data);
    } else {
      $file = $template;
      $data = $this->data(null, $data);
    }
 
    // check for an existing template
    if(!file_exists($file)) {
      throw new Exception('The template could not be found');
    }
 
    // merge and register the template data globally
    $tplData = tpl::$data;
    tpl::$data = array_merge(tpl::$data, $data);
 
    // load the template
    $result = tpl::load($file, null, $return);
 
    // reset the template data
    tpl::$data = $tplData;
 
    return $result;
 
  }
 
}
 
/
var
/
www
/
html
/
kirby
/
kirby.php
      }
 
      return $template;
 
    }
 
    // return a fresh template
    return $this->template($page, $data);
 
  }
 
  /**
   * Template configuration
   *
   * @param Page $page
   * @param array $data
   * @return string
   */
  public function template(Page $page, $data = array()) {
    return $this->component('template')->render($page, $data);
  }
 
  public function request() {
    if(!is_null($this->request)) return $this->request;
    return $this->request = new Request($this);
  }
 
  public function router() {
    return $this->router;
  }
 
  public function route() {
    return $this->route;
  }
 
  /**
   * Starts the router, renders the page and returns the response
   *
   * @return mixed
   */
/
var
/
www
/
html
/
kirby
/
kirby.php
        }
 
      }
 
      // try to fetch the template from cache
      $template = $this->cache()->get($cacheId);
 
      // fetch fresh content if the cache is empty
      if(empty($template)) {
        $template = $this->template($page, $data);
        // store the result for the next round
        $this->cache()->set($cacheId, $template);
      }
 
      return $template;
 
    }
 
    // return a fresh template
    return $this->template($page, $data);
 
  }
 
  /**
   * Template configuration
   *
   * @param Page $page
   * @param array $data
   * @return string
   */
  public function template(Page $page, $data = array()) {
    return $this->component('template')->render($page, $data);
  }
 
  public function request() {
    if(!is_null($this->request)) return $this->request;
    return $this->request = new Request($this);
  }
 
  public function router() {
/
var
/
www
/
html
/
kirby
/
kirby
/
component
/
response.php
 * @link      http://getkirby.com
 * @copyright Bastian Allgeier
 * @license   http://getkirby.com/license
 */
class Response extends \Kirby\Component {
 
  /**
   * Builds and return the response by various input
   * 
   * @param mixed $response
   * @return mixed
   */
  public function make($response) {
 
    if(is_string($response)) {
      return $this->kirby->render(page($response));
    } else if(is_array($response)) {
      return $this->kirby->render(page($response[0]), $response[1]);
    } else if(is_a($response, 'Page')) {
      return $this->kirby->render($response);      
    } else if(is_a($response, 'Response')) {
      return $response;
    } else {
      return null;
    }
 
  }
 
}
/
var
/
www
/
html
/
kirby
/
kirby.php
    // check for a valid route
    if(is_null($this->route)) {
      header::status('500');
      header::type('json');
      die(json_encode(array(
        'status'  => 'error',
        'message' => 'Invalid route or request method'
      )));
    }
 
    // call the router action with all arguments from the pattern
    $response = call($this->route->action(), $this->route->arguments());
 
    // load all language variables
    // this can only be loaded once the router action has been called
    // otherwise the current language is not yet available
    $this->localize();
 
    // build the response
    $this->response = $this->component('response')->make($response);
 
    // store the current language in the session
    if(
        $this->option('language.detect') &&
        $this->site()->multilang() &&
        $this->site()->language()
      ) {
      s::set('kirby_language', $this->site()->language()->code());
    }
 
    return $this->response;
 
  }
 
  /**
   * Register a new hook
   *
   * @param string/array $hook The name of the hook
   * @param closure $callback
   */
/
var
/
www
/
html
/
index.php
<?php
 
define('DS', DIRECTORY_SEPARATOR);
 
// load kirby
require(__DIR__ . DS . 'kirby' . DS . 'bootstrap.php');
 
// check for a custom site.php
if(file_exists(__DIR__ . DS . 'site.php')) {
  require(__DIR__ . DS . 'site.php');
} else {
  $kirby = kirby();
}
 
// render
echo $kirby->launch();

Environment & details:

Key Value
Kirby Toolkit v2.5.10
Kirby CMS v2.5.10
empty
empty
empty
empty
empty
Key Value
REDIRECT_STATUS 200
HTTP_X_REAL_IP 44.192.132.66
HTTP_X_FORWARDED_FOR 44.192.132.66
HTTP_HOST www.annettebehrens.com
HTTP_X_NGINX_PROXY true
HTTP_CONNECTION close
HTTP_ACCEPT */*
HTTP_USER_AGENT claudebot
PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
SERVER_SIGNATURE <address>Apache/2.4.41 (Ubuntu) Server at www.annettebehrens.com Port 80</address>
SERVER_SOFTWARE Apache/2.4.41 (Ubuntu)
SERVER_NAME www.annettebehrens.com
SERVER_ADDR 172.17.0.9
SERVER_PORT 80
REMOTE_ADDR 172.17.0.1
DOCUMENT_ROOT /var/www/html
REQUEST_SCHEME http
CONTEXT_PREFIX
CONTEXT_DOCUMENT_ROOT /var/www/html
SERVER_ADMIN [no address given]
SCRIPT_FILENAME /var/www/html/index.php
REMOTE_PORT 54730
REDIRECT_URL /works/in-matters-of-karl-video
GATEWAY_INTERFACE CGI/1.1
SERVER_PROTOCOL HTTP/1.0
REQUEST_METHOD GET
QUERY_STRING
REQUEST_URI /works/in-matters-of-karl-video
SCRIPT_NAME /index.php
PHP_SELF /index.php
REQUEST_TIME_FLOAT 1711663365.15
REQUEST_TIME 1711663365
empty
0. Whoops\Handler\PrettyPageHandler