spotweb/spotweb

View on GitHub
lib/services/Providers/Services_Providers_SpotImage.php

Summary

Maintainability
C
7 hrs
Test Coverage
<?php

class Services_Providers_SpotImage
{
    private $_cacheDao;
    private $_serviceHttp;
    private $_nntpSpotReading;

    /*
     * constructor
     */
    public function __construct(
        Services_Providers_Http $serviceHttp,
        Services_Nntp_SpotReading $nntpSpotReading,
        Dao_Cache $cacheDao
    ) {
        $this->_serviceHttp = $serviceHttp;
        $this->_cacheDao = $cacheDao;
        $this->_nntpSpotReading = $nntpSpotReading;
    }

    // ctor

    /*
     * Checks if we have the specified image in the cache,
     * this prevents us from reading the image from disk
     * when this is not necessary
     */
    public function hasCachedSpotImage($messageId)
    {
        return $this->_cacheDao->hasCachedSpotImage($messageId);
    }

    // hasCachedSpotImage

    /*
     * Fetches an image either from the cache, the web or a
     * newsgroup depending on where the image is available
     */
    public function fetchSpotImage($fullSpot)
    {
        SpotTiming::start(__CLASS__.'::'.__FUNCTION__);
        $return_code = 0;
        $validImage = false;
        $imageString = '';

        $data = $this->_cacheDao->getCachedSpotImage($fullSpot['messageid']);
        if ($data !== false) {
            $this->_cacheDao->updateSpotImageCacheStamp($fullSpot['messageid'], $data);

            SpotTiming::stop(__CLASS__.'::'.__FUNCTION__);

            return $data;
        } // if

        /*
         * Determine whether the spot is stored on an NNTP server or a web resource,
         * older spots are stored on an HTTP server
         */
        if (is_array($fullSpot['image'])) {
            try {
                /*
                 * Convert the list of segments to a format
                 * usable for readBinary()
                 */
                $segmentList = [];
                foreach ($fullSpot['image']['segment'] as $seg) {
                    $segmentList[] = $seg;
                } // foreach

                SpotTiming::start('fetchSpotImage::readBinary()');
                $imageString = $this->_nntpSpotReading->readBinary($segmentList, false);
                SpotTiming::stop('fetchSpotImage::readBinary()');
                $validImage = true;
            } catch (Exception $x) {
                $validImage = false;
                $return_code = $x->getCode();
            } // catch
        } elseif (empty($fullSpot['image'])) {
            /*
             * Spot did not contain an image (this is illegal?),
             * create a dummy error message
             */
            $validImage = false;
            $return_code = 901;
        } elseif (!empty($fullSpot['image'])) {
            /*
             * We don't want the HTTP layer of this code to cache the image, because
             * we want to cache / store additional information in the cache for images
             */
            $tmpPerform = $this->_serviceHttp->perform($fullSpot['image'], null, 0);
            $return_code = $tmpPerform['http_code'];
            $imageString = $tmpPerform['data'];

            if (($return_code == 200) || ($return_code == 304)) {
                $validImage = true;
            } // else
        } // elseif

        /*
         * Now validate the resource we have retrieved from the server
         */
        if ($validImage) {
            SpotTiming::start('fetchSpotImage::getImageDimensions()');
            $svc_ImageUtil = new Services_Image_Util();
            $dimensions = $svc_ImageUtil->getImageDimensions($imageString);
            SpotTiming::stop('fetchSpotImage::getImageDimensions()', []);

            /*
             * If this is not a valid image, create a dummy error code,
             * else we save it in the cache
             */
            if ($dimensions !== false) {
                /*
                 * If the current image is an BMP file, convert it to
                 * JPEG
                 */
                if ($dimensions['isbmp']) {
                    SpotTiming::start('fetchSpotImage::convertToBmp()');
                    $svc_ImageBmpConverter = new Services_Image_BmpConverter();
                    $imageString = $svc_ImageBmpConverter->convertBmpImageStringToJpeg($imageString, $dimensions);

                    $dimensions = $svc_ImageUtil->getImageDimensions($imageString);
                    $validImage = ($dimensions !== false);
                    SpotTiming::stop('fetchSpotImage::convertToBmp()', serialize($validImage));
                } // if

                /*
                 * and store the file in the cache
                 */
                if ($validImage) {
                    /*
                     * This is an actual SpotImage
                     */
                    $dimensions['is_tempimage'] = false;

                    SpotTiming::start('fetchSpotImage::savingToCache()');
                    if (!$this->_cacheDao->saveSpotImageCache(
                        $fullSpot['messageid'],
                        $dimensions,
                        $imageString,
                        false
                    )) {
                        $validImage = false;
                        $return_code = 997;
                    } // if
                    SpotTiming::stop('fetchSpotImage::savingToCache()', serialize($validImage));
                } // if
            } else {
                $validImage = false;
                $return_code = 998;
            } // if
        } // if

        /*
         * Did we get a return code other than 200 OK and
         * other than 304 (Resource Not modified), create
         * an error code image
         */
        if (!$validImage) {
            SpotTiming::start('fetchSpotImage::createErrorImage()');
            $svc_ImageError = new Services_Image_Error();
            $errorImage = $svc_ImageError->createErrorImage($return_code);
            SpotTiming::stop('fetchSpotImage::createErrorImage()');

            $imageString = $errorImage['content'];
            $dimensions = $errorImage['metadata'];

            /*
             * Store a copy of the error image so we don't request
             * the same image over and over.
             */
            $this->_cacheDao->saveSpotImageCache(
                $fullSpot['messageid'],
                $dimensions,
                $imageString,
                true
            );
        } // if

        SpotTiming::stop(__CLASS__.'::'.__FUNCTION__, [$fullSpot]);

        return ['content' => $imageString,
            'metadata'    => $dimensions, ];
    }

    // fetchSpotImage
} // Services_Providers_SpotImage