Seditio Source
Root |
./othercms/xenForo 2.2.8/src/XF/Entity/Oembed.php
<?php

namespace XF\Entity;

use
XF\Mvc\Entity\Entity;
use
XF\Mvc\Entity\Structure;

/**
 * COLUMNS
 * @property int|null $oembed_id
 * @property string $media_site_id
 * @property string $media_id
 * @property string $media_hash
 * @property string|null $title
 * @property int $fetch_date
 * @property int $first_request_date
 * @property int $last_request_date
 * @property int $views
 * @property bool $pruned
 * @property int $is_processing
 * @property int $failed_date
 * @property int $fail_count
 *
 * GETTERS
 * @property string $url
 *
 * RELATIONS
 * @property \XF\Entity\BbCodeMediaSite $BbCodeMediaSite
 * @property \XF\Mvc\Entity\AbstractCollection|\XF\Entity\OembedReferrer[] $Referrers
 */
class Oembed extends Entity
{
    const
FAILURE = 1;

    protected
$failure = null;

    public function
getAbstractedJsonPath()
    {
        return
sprintf('internal-data://oembed_cache/%d/%d-%s.json',
           
floor($this->oembed_id / 1000),
           
$this->oembed_id,
           
$this->media_hash
       
);
    }

    public function
isValid()
    {
        if (
$this->pruned)
        {
            return
false;
        }

        return
$this->app()->fs()->has($this->getAbstractedJsonPath());
    }

    public function
setAsFailure()
    {
       
$this->failure = self::FAILURE;
       
$this->setReadOnly(true);
    }

    public function
isFailure()
    {
        return
$this->failure ? true : false;
    }

    public function
isRefreshRequired()
    {
       
$filePath = $this->getAbstractedJsonPath();
       
$fs = $this->app()->fs();

        if (
$this->is_processing && \XF::$time - $this->is_processing < 5)
        {
            if (
$fs->has($filePath))
            {
                return
false;
            }

           
$maxSleep = 5 - (\XF::$time - $this->is_processing);
            for (
$i = 0; $i < $maxSleep; $i++)
            {
                if (
$fs->has($filePath))
                {
                    return
false;
                }
            }
        }

        if (
$this->failed_date && $this->fail_count)
        {
            return
$this->isFailureRefreshRequired();
        }

        if (
$this->pruned)
        {
            return
true;
        }

       
$ttl = $this->app()->options()->oEmbedCacheTTL;
        if (
$ttl && $this->fetch_date < \XF::$time - $ttl * 86400)
        {
            return
true;
        }

        if (!
$fs->has($filePath))
        {
            return
true;
        }

       
$refresh = $this->app()->options()->oEmbedCacheRefresh;
        if (
$refresh && !$this->fail_count && $this->fetch_date < \XF::$time - $refresh * 86400)
        {
            return
true;
        }

        return
false;
    }

   
/**
     * @return string
     */
   
public function getUrl()
    {
        return
str_replace('{$id}', $this->media_id, $this->BbCodeMediaSite->oembed_url_scheme);
    }

    public function
isFailureRefreshRequired()
    {
        if (!
$this->failed_date || !$this->fail_count)
        {
            return
false;
        }

        switch (
$this->fail_count)
        {
            case
1: $delay = 30; break; // 30 seconds
           
case 2: $delay = 2.5 * 60; break; // 2.5 minutes
           
case 3: $delay = 10 * 60; break; // 10 minutes
           
case 4: $delay = 1800; break; // 30 mins
           
case 5: $delay = 2 * 3600; break; // 2 hours

           
default:
               
$delay = ($this->fail_count - 5) * 86400; // 1, 2, 3... days
       
}

        return \
XF::$time >= ($this->failed_date + $delay);
    }

    public function
prune()
    {
       
$this->pruned = true;
       
$this->save();

        \
XF\Util\File::deleteFromAbstractedPath($this->getAbstractedJsonPath());

        return
true;
    }

    protected function
_preSave()
    {
        if (
$this->isChanged('media_site_id') || $this->isChanged('media_id'))
        {
           
$this->media_hash = md5($this->media_site_id . $this->media_id);
        }
    }

    public static function
getStructure(Structure $structure)
    {
       
$structure->table = 'xf_oembed';
       
$structure->shortName = 'XF:Oembed';
       
$structure->primaryKey = 'oembed_id';
       
$structure->columns = [
           
'oembed_id' => ['type' => self::UINT, 'nullable' => true, 'autoIncrement' => true],
           
'media_site_id' => ['type' => self::STR, 'maxLength' => 25, 'required' => true],
           
'media_id' => ['type' => self::STR, 'maxLength' => 250, 'required' => true],
           
'media_hash' => ['type' => self::STR, 'maxLength' => 32, 'required' => true],
           
'title' => ['type' => self::STR, 'nullable' => true , 'default' => null],
           
'fetch_date' => ['type' => self::UINT, 'default' => 0],
           
'first_request_date' => ['type' => self::UINT, 'default' => \XF::$time],
           
'last_request_date' => ['type' => self::UINT, 'default' => \XF::$time],
           
'views' => ['type' => self::UINT, 'default' => 0],
           
'pruned' => ['type' => self::BOOL, 'default' => false],
           
'is_processing' => ['type' => self::UINT, 'default' => 0],
           
'failed_date' => ['type' => self::UINT, 'default' => 0],
           
'fail_count' => ['type' => self::UINT, 'default' => 0],
        ];
       
$structure->getters = ['url' => true];
       
$structure->relations = [
           
'BbCodeMediaSite' => [
               
'entity' => 'XF:BbCodeMediaSite',
               
'type' => self::TO_ONE,
               
'conditions' => 'media_site_id',
               
'primary' => true
           
],
           
'Referrers' => [
               
'entity' => 'XF:OembedReferrer',
               
'type' => self::TO_MANY,
               
'conditions' => 'oembed_id',
               
'order' => ['last_date', 'DESC']
            ]
        ];

        return
$structure;
    }
}