Use media endpoint to build an array of known media

@param string $url The URL of the book.

@return bool|\Pressbooks\Entities\Cloner\Media[] False if the operation failed; known images assoc array if succeeded.
768898
public function buildListOfKnownMedia( $url ) {
		// Handle request (local or global)
		$params = [
			'per_page' => 100,
		];
		$response = $this->handleGetRequest( $url, 'wp/v2', 'media', $params );

		// Handle errors
		if ( is_wp_error( $response ) ) {
			$_SESSION['pb_errors'][] = sprintf(
				'<p>%1$s</p><p>%2$s</p>',
				__( 'The source book&rsquo;s media could not be read.', 'pressbooks' ),
				$response->get_error_message()
			);
			return false;
		}

		$known_media = [];
		foreach ( $response as $item ) {
			$m = $this->createMediaEntity( $item );
			if ( $item['media_type'] === 'image' ) {
				foreach ( $item['media_details']['sizes'] as $size => $info ) {
					$attached_file = image_strip_baseurl( $info['source_url'] ); // 2017/08/foo-bar-300x225.png
					$known_media[ $attached_file ] = $m;
				}
			} else {
				$attached_file = media_strip_baseurl( $m->sourceUrl ); // 2017/08/foo-bar.ext
				$known_media[ $attached_file ] = $m;
			}
		}

		return $known_media;
	}
1135993
protected function doFetch($url)
    {
        foreach ($this->crawlers as $crawler) {
            $data = $crawler->crawl($url);

            if (is_array($data)) {
                $title = isset($data['title']) ? $data['title'] : null;
                $description = isset($data['description']) ? $data['description'] : null;
                $type = isset($data['type']) ? $data['type'] : 'unknown';
                $images = isset($data['images']) ? (array) $data['images'] : array();

                return array(
                    'title'        => $title,
                    'description'  => $description,
                    'type'         => $type,
                    'images'       => $images,
                    'total_images' => count($images)
                );
            }
        }

        return false;
    }
696962
public function metaCanonical($url = null, $full = false) {
		$canonical = $this->Url->build($url, $full);
		$options = ['rel' => 'canonical', 'link' => $canonical];
		return $this->Html->meta($options);
	}
36621
public function parseUrl($url) : array
    {
        $url = (string) $url;

        $parsedUrl = $this->doParseUrl($url);

        if ($parsedUrl === []) {
            throw new InvalidArgumentException(sprintf('Invalid url %s', $url));
        }

        $parsedUrl = array_merge(self::$defaultParts, $parsedUrl);

        if (isset($parsedUrl['host'])) {
            $parsedUrl['canonical'] = implode('.', array_reverse(explode('.', $parsedUrl['host']))) . ($parsedUrl['path'] ?? '') . (isset($parsedUrl['query']) ? '?' . $parsedUrl['query'] : '');

            $parsedUrl['resource'] = $parsedUrl['path'] ?? '';

            if (isset($parsedUrl['query'])) {
                $parsedUrl['resource'] .= '?' . $parsedUrl['query'];
            }
        }

        return $parsedUrl;
    }
574409
protected function fetchAndSaveUniqueImage( $url ) {

		if ( ! filter_var( $url, FILTER_VALIDATE_URL ) ) {
			return '';
		}

		$remote_img_location = $url;

		// Cheap cache
		static $already_done = [];
		if ( isset( $already_done[ $remote_img_location ] ) ) {
			return $already_done[ $remote_img_location ];
		}

		/* Process */

		// Basename without query string
		$filename = explode( '?', basename( $url ) );
		$filename = array_shift( $filename );

		$filename = sanitize_file_name( urldecode( $filename ) );

		if ( ! preg_match( '/\.(jpe?g|gif|png)$/i', $filename ) ) {
			// Unsupported image type
			$already_done[ $remote_img_location ] = '';
			return '';
		}

		$tmp_name = download_url( $remote_img_location );
		if ( is_wp_error( $tmp_name ) ) {
			// Download failed
			$already_done[ $remote_img_location ] = '';
			return '';
		}

		if ( ! \Pressbooks\Image\is_valid_image( $tmp_name, $filename ) ) {

			try { // changing the file name so that extension matches the mime type
				$filename = $this->properImageExtension( $tmp_name, $filename );

				if ( ! \Pressbooks\Image\is_valid_image( $tmp_name, $filename ) ) {
					throw new \Exception( 'Image is corrupt, and file extension matches the mime type' );
				}
			} catch ( \Exception $exc ) {
				// Garbage, don't import
				$already_done[ $remote_img_location ] = '';
				unlink( $tmp_name );
				return '';
			}
		}

		$pid = media_handle_sideload(
			[
				'name' => $filename,
				'tmp_name' => $tmp_name,
			], 0
		);
		$src = wp_get_attachment_url( $pid );
		if ( ! $src ) {
			$src = ''; // Change false to empty string
		}
		$already_done[ $remote_img_location ] = $src;
		@unlink( $tmp_name ); // @codingStandardsIgnoreLine

		return $src;
	}
417561
private function doFetchContent($url)
    {
        $url = $this->validateUrl($url);
        $siteConfig = $this->configBuilder->buildFromUrl($url);

        $this->logger->info('Fetching url: {url}', ['url' => $url]);

        $response = $this->httpClient->fetch($url, false, $siteConfig->http_header);

        $effectiveUrl = $response['effective_url'];
        $effectiveUrl = str_replace(' ', '%20', $effectiveUrl);
        if (!$this->isUrlAllowed($effectiveUrl)) {
            throw new \Exception(sprintf('Url "%s" is not allowed to be parsed.', $effectiveUrl));
        }

        // check if action defined for returned Content-Type, like image, pdf, audio or video
        $mimeInfo = $this->getMimeActionInfo($response['all_headers']);
        $infos = $this->handleMimeAction($mimeInfo, $effectiveUrl, $response);
        if (\is_array($infos)) {
            return $infos;
        }

        $html = $this->convert2Utf8($response['body'], $response['all_headers']);

        $this->logger->debug('Fetched HTML', ['html' => $html]);

        // Remove empty lines to avoid runaway evaluation of following regex
        // on badly coded websites
        $re = '/^[ \t]*[\r\n]+/m';
        $html = preg_replace($re, '', $html);

        // Remove empty nodes (except iframe)
        $re = '/<(?!iframe)([^>\s]+)[^>]*>(?:<br \/>|&nbsp;|&thinsp;|&ensp;|&emsp;|&#8201;|&#8194;|&#8195;|\s)*<\/\1>/m';
        $html = preg_replace($re, '', $html);

        $this->logger->debug('HTML after regex empty nodes stripping', ['html' => $html]);

        // some non utf8 enconding might be breaking after converting to utf8
        // when it happen the string (usually) starts with this character
        // in that case, we'll take the default response instead of the utf8 forced one
        if (0 === strpos(utf8_encode($response['body']), 'ÿþ')) {
            $html = $response['body'];
        }

        $ogData = $this->extractOpenGraph($html, $effectiveUrl);

        $this->logger->info('Opengraph data: {ogData}', ['ogData' => $ogData]);

        // @TODO: log raw html + headers

        // check site config for single page URL - fetch it if found
        $isSinglePage = false;
        if ($this->config['singlepage'] && ($singlePageResponse = $this->getSinglePage($html, $effectiveUrl))) {
            $isSinglePage = true;
            $effectiveUrl = $singlePageResponse['effective_url'];

            // check if action defined for returned Content-Type
            $mimeInfo = $this->getMimeActionInfo($singlePageResponse['all_headers']);
            $infos = $this->handleMimeAction($mimeInfo, $effectiveUrl, $singlePageResponse);
            if (\is_array($infos)) {
                return $infos;
            }

            $html = $this->convert2Utf8($singlePageResponse['body'], $singlePageResponse['all_headers']);
            $this->logger->info('Retrieved single-page view from "{url}"', ['url' => $effectiveUrl]);

            unset($singlePageResponse);
        }

        $this->logger->info('Attempting to extract content');

        $extractResult = $this->extractor->process($html, $effectiveUrl);
        $readability = $this->extractor->readability;
        $contentBlock = $this->extractor->getContent();
        $extractedTitle = $this->extractor->getTitle();
        $extractedLanguage = $this->extractor->getLanguage();
        $extractedDate = $this->extractor->getDate();
        $extractedAuthors = $this->extractor->getAuthors();

        // in case of no language were found, try using headers Content-Language
        if (empty($extractedLanguage) && !empty($response['all_headers']['content-language'])) {
            $extractedLanguage = $response['all_headers']['content-language'];
        }

        // Deal with multi-page articles
        $isMultiPage = (!$isSinglePage && $extractResult && null !== $this->extractor->getNextPageUrl());
        if ($this->config['multipage'] && $isMultiPage) {
            $this->logger->info('Attempting to process multi-page article');
            // store first page to avoid parsing it again (previous url content is in `$contentBlock`)
            $multiPageUrls = [$effectiveUrl];
            $multiPageContent = [];

            while ($nextPageUrl = $this->extractor->getNextPageUrl()) {
                $this->logger->info('Processing next page: {url}', ['url' => $nextPageUrl]);
                // If we've got URL, resolve against $url
                $nextPageUrl = $this->makeAbsoluteStr($effectiveUrl, $nextPageUrl);
                if (!$nextPageUrl) {
                    $this->logger->info('Failed to resolve against: {url}', ['url' => $effectiveUrl]);
                    $multiPageContent = [];
                    break;
                }

                // check it's not what we have already!
                if (\in_array($nextPageUrl, $multiPageUrls, true)) {
                    $this->logger->info('URL already processed');
                    $multiPageContent = [];
                    break;
                }

                // it's not, store it for later check & so let's attempt to fetch it
                $multiPageUrls[] = $nextPageUrl;

                $response = $this->httpClient->fetch($nextPageUrl, false, $siteConfig->http_header);

                // make sure mime type is not something with a different action associated
                $mimeInfo = $this->getMimeActionInfo($response['all_headers']);

                if (isset($mimeInfo['action'])) {
                    $this->logger->info('MIME type requires different action');
                    $multiPageContent = [];
                    break;
                }

                $extracSuccess = $this->extractor->process(
                    $this->convert2Utf8($response['body'], $response['all_headers']),
                    $nextPageUrl
                );

                if (!$extracSuccess) {
                    $this->logger->info('Failed to extract content');
                    $multiPageContent = [];
                    break;
                }

                $multiPageContent[] = clone $this->extractor->getContent();
            }

            // did we successfully deal with this multi-page article?
            if (empty($multiPageContent)) {
                $this->logger->info('Failed to extract all parts of multi-page article, so not going to include them');
                $page = $readability->dom->createElement('p');
                $page->innerHTML = '<em>This article appears to continue on subsequent pages which we could not extract</em>';
                $multiPageContent[] = $page;
            }

            foreach ($multiPageContent as $page) {
                $page = $contentBlock->ownerDocument->importNode($page, true);
                $contentBlock->appendChild($page);
            }

            unset($multiPageUrls, $multiPageContent, $nextPageUrl, $page);
        }

        $res = [
            'status' => $response['status'],
            'html' => $this->config['error_message'],
            'title' => $extractedTitle ?: $this->config['error_message_title'],
            'language' => $extractedLanguage,
            'date' => $extractedDate,
            'authors' => $extractedAuthors,
            'url' => $effectiveUrl,
            'content_type' => isset($mimeInfo['mime']) ? $mimeInfo['mime'] : '',
            'open_graph' => $ogData,
            'native_ad' => $this->extractor->isNativeAd(),
            'all_headers' => $response['all_headers'],
        ];

        // if we failed to extract content...
        if (!$extractResult || null === $contentBlock) {
            $this->logger->info('Extract failed');

            return $res;
        }

        $res['html'] = $this->cleanupHtml($contentBlock, $effectiveUrl);

        $this->logger->info('Returning data (most interesting ones): {data}', ['data' => ['html' => '(only length for debug): ' . \strlen($res['html'])] + $res]);

        return $res;
    }
1324455
public function createArticleAPI($url)
    {
        $api = new Article($url);
        if (!$this->getHttpClient()) {
            $this->setHttpClient();
        }
        if (!$this->getEntityFactory()) {
            $this->setEntityFactory();
        }
        return $api->registerDiffbot($this);
    }
782448
public function saveThumbnail(MediaInterface $media, $url)
    {
        $thumb = $this->mediaManager->createMedia();

        $thumb
            ->setStatus(Media::STATUS_HASPARENT)
            ->setName($media->getName().'_thumb')
            ->setProvider('image')
        ;

        $filename = '/tmp/'.basename($url);
        $filesystem = new Filesystem();
        $filesystem->dumpFile($filename, file_get_contents($url));
        $thumb->temp = $filename;
        $thumb->setFile(new UploadedFile($filename, basename($url)));

        $this->mediaManager->save($thumb);

        return $thumb;
    }
1014334
protected function getFormatFromUrl($url)
    {
        $path = dirname($url);

        $formatParts = array_reverse(explode('/', $path));

        if (count($formatParts) < 2) {
            throw new ImageProxyInvalidUrl('No `format` was found in the url');
        }

        $format = $formatParts[1];

        return $format;
    }
740050
public function resolve($url)
    {
        $urlParts = parse_url($url);
        if (isset($urlParts['scheme']) && $urlParts['scheme'] === MediaService::SCHEME_NAME && isset($urlParts['host'])) {
            $mediaService = new MediaService();
            $mediaSource = $mediaService->getMediaSource($urlParts['host']);
            $mediaId = (isset($urlParts['path'])) ? trim($urlParts['path'], '/') : '';
            return new MediaAsset($mediaSource, $mediaId);
        } elseif (isset($urlParts['scheme']) && in_array($urlParts['scheme'], array('http','https'))) {
            return new MediaAsset(new HttpSource(), $url);
        } else {
            throw new TaoMediaException('Cannot resolve '.$url);
        }
    }
1044122
protected function _getVideo($url) {
        return $this->_useVimeoPro ? $this->_getProVideo($url) : $this->_getRegularVideo($url);
    }
991621
public static function processMediaActions($medium, $url)
    {
        if (!is_array($url)) {
            $url_parts = parse_url($url);
        } else {
            $url_parts = $url;
        }

        $actions = [];

        // if there is a query, then parse it and build action calls
        if (isset($url_parts['query'])) {
            $actions = array_reduce(explode('&', $url_parts['query']), function ($carry, $item) {
                $parts = explode('=', $item, 2);
                $value = $parts[1] ?? null;
                $carry[] = ['method' => $parts[0], 'params' => $value];

                return $carry;
            }, []);
        }

        if (Grav::instance()['config']->get('system.images.auto_fix_orientation')) {
            $actions[] = ['method' => 'fixOrientation', 'params' => ''];
        }
        $defaults = Grav::instance()['config']->get('system.images.defaults');
        if (is_array($defaults) && count($defaults)) {
            foreach ($defaults as $method => $params) {
                $actions[] = [
                    'method' => $method,
                    'params' => $params,
                ];
            }
        }

        // loop through actions for the image and call them
        foreach ($actions as $action) {
            $matches = [];

            if (preg_match('/\[(.*)\]/', $action['params'], $matches)) {
                $args = [explode(',', $matches[1])];
            } else {
                $args = explode(',', $action['params']);
            }

            $medium = call_user_func_array([$medium, $action['method']], $args);
        }

        if (isset($url_parts['fragment'])) {
            $medium->urlHash($url_parts['fragment']);
        }

        return $medium;
    }
1075596
public function createImageAPI($url)
    {
        $api = new Image($url);
        if (!$this->getHttpClient()) {
            $this->setHttpClient();
        }
        if (!$this->getEntityFactory()) {
            $this->setEntityFactory();
        }
        return $api->registerDiffbot($this);
    }
1311095
public function registerCssFile($url, $media = '')
    {
        if (($cs = $this->getClientScript()) === false) {
            return null;
        }
        if (isset($this->_assetsUrl)) {
            $url = $this->_assetsUrl . '/' . ltrim($url, '/');
        }
        return $cs->registerCssFile($url, $media);
    }
737806
protected function getDetailByUrl(string $url)
    {
        try {
            $gc         =   new GC();
            $crawler    =   $gc->request('GET', $url)->filter('table')->eq(1);
            $url        =   $url;
            $id         =   $crawler->filter('td')->eq(1)->filter('span')->eq(0)->text();
            $kana       =   $crawler->filter('td')->eq(9)->filter('span')->eq(0)->text();
            $title      =   $crawler->filter('td')->eq(9)->filter('span')->eq(1)->text();
            $author     =   $crawler->filter('td')->eq(13)->filter('span')->eq(0)->text();
            $author     =   mb_strlen($author) > 0 ? $author : null;
            $cover      =   $this->getCover($id);
            $category   =   $crawler->filter('td')->eq(15)->filter('span')->eq(0)->text();
            $category   =   mb_strlen($category) > 0 ? $category : null;

            $asset      =   new Book($id, $url, $title, $cover, $author, $kana, $category);
        } catch (\GuzzleHttp\Exception\ConnectException $e) {
            $asset = null;
        } catch (\Exceptio $e) {
            $asset = null;
        }
        return $asset;
    }
1038554
public static function getImageFromUrl($url = '')
    {
        try {
            $curl = new Curl();
            $curl->setOpt(CURLOPT_RETURNTRANSFER, TRUE);
            $curl->setOpt(CURLOPT_ENCODING, "");
            $curl->setOpt(CURLOPT_MAXREDIRS, 10);
            $curl->setOpt(CURLOPT_TIMEOUT, 30);
            $curl->setOpt(CURLOPT_CONNECTTIMEOUT, 30);
            $curl->setOpt(CURLOPT_FOLLOWLOCATION, TRUE);
            $curl->get($url);
            if ($curl->error === TRUE) {
                self::debug('Error Exception: ' . $curl->httpErrorMessage);

                return array(
                    'status'          => 'error',
                    'code'            => $curl->httpStatusCode,
                    'error'           => $curl->errorMessage,
                    'response_header' => $curl->responseHeaders,
                    'content'         => NULL
                );
            } else {
                return array(
                    'status'          => 'success',
                    'code'            => $curl->httpStatusCode,
                    'error'           => $curl->errorMessage,
                    'response_header' => $curl->responseHeaders,
                    'content'         => $curl->response
                );
            }
        }
        catch (\Exception $e) {
            if (function_exists('log_message')) {
                $message = 'Error Code: ' . $e->getCode() . ' - File: ' . $e->getFile() . ' - Line: ' . $e->getLine() . ' - Message: ' . $e->getMessage();
                log_message('error', $message);
            }

            return file_get_contents($url);
        }
    }
853724
private function fetchImageContentFromURL($url)
    {
        $data = null;

        if ($stream = fopen($url, 'r')) {
            $data = stream_get_contents($stream);
            fclose($stream);
        }

        return $data;
    }