1:   2:   3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14:  15:  16:  17:  18:  19:  20:  21:  22:  23:  24:  25:  26:  27:  28:  29:  30:  31:  32:  33:  34:  35:  36:  37:  38:  39:  40:  41:  42:  43:  44:  45:  46:  47:  48:  49:  50:  51:  52:  53:  54:  55:  56:  57:  58:  59:  60:  61:  62:  63:  64:  65:  66:  67:  68:  69:  70:  71:  72:  73:  74:  75:  76:  77:  78:  79:  80:  81:  82:  83:  84:  85:  86:  87:  88:  89:  90:  91:  92:  93:  94:  95:  96:  97:  98:  99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 
<?php
namespace Omeka\Media\Ingester;

use Omeka\Api\Request;
use Omeka\Entity\Media;
use Omeka\File\Downloader;
use Omeka\Stdlib\ErrorStore;
use Zend\Form\Element\Text;
use Zend\Form\Element\Url as UrlElement;
use Zend\Uri\Http as HttpUri;
use Zend\View\Renderer\PhpRenderer;

class Youtube implements IngesterInterface
{
    /**
     * @var Downloader
     */
    protected $downloader;

    public function __construct(Downloader $downloader)
    {
        $this->downloader = $downloader;
    }

    public function getLabel()
    {
        return 'YouTube'; // @translate
    }

    public function getRenderer()
    {
        return 'youtube';
    }

    public function ingest(Media $media, Request $request, ErrorStore $errorStore)
    {
        $data = $request->getContent();
        if (!isset($data['o:source'])) {
            $errorStore->addError('o:source', 'No YouTube URL specified');
            return;
        }
        $uri = new HttpUri($data['o:source']);
        if (!($uri->isValid() && $uri->isAbsolute())) {
            $errorStore->addError('o:source', 'Invalid YouTube URL specified');
            return;
        }
        switch ($uri->getHost()) {
            case 'www.youtube.com':
                if ('/watch' !== $uri->getPath()) {
                    $errorStore->addError('o:source', 'Invalid YouTube URL specified, missing "/watch" path');
                    return;
                }
                $query = $uri->getQueryAsArray();
                if (!isset($query['v'])) {
                    $errorStore->addError('o:source', 'Invalid YouTube URL specified, missing "v" parameter');
                    return;
                }
                $youtubeId = $query['v'];
                break;
            case 'youtu.be':
                $youtubeId = substr($uri->getPath(), 1);
                break;
            default:
                $errorStore->addError('o:source', 'Invalid YouTube URL specified, not a YouTube URL');
                return;
        }

        $url = sprintf('http://img.youtube.com/vi/%s/0.jpg', $youtubeId);
        $tempFile = $this->downloader->download($url);
        if ($tempFile) {
            if ($tempFile->storeThumbnails()) {
                $media->setStorageId($tempFile->getStorageId());
                $media->setHasThumbnails(true);
            }
            $tempFile->delete();
        }

        $mediaData = ['id' => $youtubeId];
        $start = trim($request->getValue('start'));
        if (is_numeric($start)) {
            $mediaData['start'] = $start;
        }
        $end = trim($request->getValue('end'));
        if (is_numeric($end)) {
            $mediaData['end'] = $end;
        }
        $media->setData($mediaData);
    }

    /**
     * {@inheritDoc}
     */
    public function form(PhpRenderer $view, array $options = [])
    {
        $urlInput = new UrlElement('o:media[__index__][o:source]');
        $urlInput->setOptions([
            'label' => 'Video URL', // @translate
            'info' => 'URL for the video to embed.', // @translate
        ]);
        $urlInput->setAttributes([
            'id' => 'media-youtube-source-__index__',
            'required' => true,
        ]);
        $urlInput->setAttributes([
            'id' => 'media-youtube-source-__index__',
            'required' => true,
        ]);
        $startInput = new Text('o:media[__index__][start]');
        $startInput->setOptions([
            'label' => 'Start', // @translate
            'info' => 'Begin playing the video at the given number of seconds from the start of the video.', // @translate
        ]);
        $endInput = new Text('o:media[__index__][end]');
        $endInput->setOptions([
            'label' => 'End', // @translate
            'info' => 'End playing the video at the given number of seconds from the start of the video.', // @translate
        ]);
        return $view->formRow($urlInput)
            . $view->formRow($startInput)
            . $view->formRow($endInput);
    }
}