Your IP : 216.73.216.95


Current Path : /var/www/ooareogundevinitiative/wp-content/plugins/brizy/editor/asset/crop/
Upload File :
Current File : /var/www/ooareogundevinitiative/wp-content/plugins/brizy/editor/asset/crop/cropper.php

<?php

class Brizy_Editor_Asset_Crop_Cropper {

	const BASIC_CROP_TYPE = 1;
	const ADVANCED_CROP_TYPE = 2;

	/**
	 * @var string[]
	 */
	private $services;

	/**
	 * Brizy_Editor_Asset_Crop_Cropper constructor.
	 */
	public function __construct() {

		$this->services = array(
			//'Brizy_Editor_Asset_Crop_ExternalService',
			'Brizy_Editor_Asset_Crop_WordpressService'
		);
	}

	/**
	 * @param $source
	 * @param $target
	 * @param $callback
	 *
	 * @return bool
	 */
	private function serviceLoop( $source, $target, $callback ) {
		foreach ( $this->services as $serviceClass ) {
			try {
				/**
				 * @var Brizy_Editor_Asset_Crop_ServiceInterface $service ;
				 */
				$service = new $serviceClass( $source, $target );

				if ( $callback( $service ) ) {
					return true;
				}
			} catch ( Exception $e ) {
				continue;
			}
		}

		return false;
	}

	/**
	 * @param $source
	 * @param $target
	 * @param $offsetX
	 * @param $offsetY
	 * @param $width
	 * @param $height
	 *
	 * @return bool
	 */
	private function serviceCrop( $source, $target, $offsetX, $offsetY, $width, $height ) {

		return $this->serviceLoop( $source, $target, function ( Brizy_Editor_Asset_Crop_ServiceInterface $service ) use ( $offsetX, $offsetY, $width, $height ) {
			$result = $service->crop( $offsetX, $offsetY, $width, $height );

			if ( $result ) {
				$result = $service->saveTargetImage();
			}

			return $result;
		} );
	}

	/**
	 * @param $source
	 * @param $target
	 * @param $width
	 * @param $height
	 *
	 * @return bool
	 */
	private function serviceResize( $source, $target, $width, $height ) {
		return $this->serviceLoop( $source, $target, function ( Brizy_Editor_Asset_Crop_ServiceInterface $service ) use ( $width, $height ) {
			$result = $service->resize( $width, $height );

			if ( $result ) {
				$result = $service->saveTargetImage();
			}

			return $result;
		} );
	}

	/**
	 * @param $source
	 * @param $target
	 * @param $filterOptions
	 *
	 * @return bool
	 */
	private function internalCrop( $source, $target, $filterOptions ) {
		if ( $filterOptions['format'] == "gif" ) {
			// do not resize
			return $this->copyFile( $source, $target );
		} else {
			list( $imgWidth, $imgHeight ) = $filterOptions['originalSize'];
			if ( $filterOptions['is_advanced'] === false ) {
				list( $requestedImgWidth, $requestedImgHeight ) = array_values( $filterOptions['requestedData'] );
				if ( $requestedImgWidth > $imgWidth && ( $requestedImgHeight == "any" || $requestedImgHeight == "*" ) ) {
					return $this->copyFile( $source, $target );
				}

				return $this->serviceResize( $source, $target, $requestedImgWidth, $requestedImgHeight );
			}

			list( $requestedImgWidth, $requestedImgHeight, $requestedOffsetX, $requestedOffsetY, $containerWidth, $containerHeight ) = array_values( $filterOptions['requestedData'] );

			if ( ( $containerWidth > $imgWidth || $containerHeight > $imgHeight ) || $requestedImgWidth > $imgWidth && $requestedImgHeight > $imgHeight ) {

				$newOffsetX = $imgWidth * $requestedOffsetX / $requestedImgWidth;
				$newOffsetY = $imgHeight * $requestedOffsetY / $requestedImgHeight;

				$newImgWidth  = $imgWidth * $containerWidth / $requestedImgWidth;
				$newImgHeight = $imgHeight * $containerHeight / $requestedImgHeight;

				return $this->serviceCrop( $source, $target, $newOffsetX, $newOffsetY, $newImgWidth, $newImgHeight );

			} else {

				return $this->serviceLoop( $source, $target, function ( Brizy_Editor_Asset_Crop_ServiceInterface $service ) use ( $source, $target, $requestedImgWidth, $requestedImgHeight, $requestedOffsetX, $requestedOffsetY, $containerWidth, $containerHeight ) {
					$result = $service->resize( $requestedImgWidth, $requestedImgHeight );
					if ( $result && $service->crop( $requestedOffsetX, $requestedOffsetY, $containerWidth, $containerHeight ) ) {
						$result = $service->saveTargetImage();

						if ( ! $result ) {
							@unlink( $target );
						}

						return $result;
					}

					return false;
				} );
			}
		}
	}

	/**
	 * @param $source
	 * @param $target
	 * @param $filter
	 *
	 * @return bool
	 * @throws Exception
	 */
	public function crop( $source, $target, $filter ) {

		if ( ! file_exists( $source ) ) {
			throw new Exception( 'Unable to crop media. Source file not found.' );
		}

		if ( ! is_writable( dirname( $target ) ) ) {
			throw new Exception( 'Unable to crop media. Target directory is not writable.' );
		}

		try {
			wp_raise_memory_limit( 'image' );
			$filterOptions = $this->getFilterOptions( $source, $filter );
			$result        = $this->internalCrop( $source, $target, $filterOptions );

			return $result;
		} catch ( Exception $e ) {
			Brizy_Logger::instance()->error( $e->getMessage(), [ $e ] );

			return false;
		}
	}

	/**
	 * @param $source
	 * @param $filter
	 *
	 * @return array
	 * @throws Exception
	 */
	private function getFilterOptions( $source, $filter ) {

		$imageEditor = wp_get_image_editor( $source );

		if($imageEditor instanceof WP_Error) {
			throw new Exception('No image editor returned');
		}

		parse_str( strtolower( $filter ), $output );
		$configuration                 = array();
		$configuration['format']       = pathinfo( basename( $source ), PATHINFO_EXTENSION );
		$configuration['originalSize'] = array_values( $imageEditor->get_size() );

		$cropType = $this->getCropType( $filter );

		switch ( $cropType ) {
			case self::BASIC_CROP_TYPE:
				$configuration['requestedData']['imageWidth']  = (int) $output['iw'];
				$configuration['requestedData']['imageHeight'] = (int) $output['ih'];
				$configuration['is_advanced']                  = false;
				break;
			case self::ADVANCED_CROP_TYPE:
				$configuration['requestedData']['imageWidth']  = (int) $output['iw'];
				$configuration['requestedData']['imageHeight'] = (int) $output['ih'];
				$configuration['requestedData']['offsetX']     = (int) $output['ox'];
				$configuration['requestedData']['offsetY']     = (int) $output['oy'];
				$configuration['requestedData']['cropWidth']   = (int) $output['cw'];
				$configuration['requestedData']['cropHeight']  = (int) $output['ch'];
				$configuration['is_advanced']                  = true;
				break;
		}

		return $configuration;
	}

	/**
	 * @param $filter
	 *
	 * @return int|null
	 * @throws Exception
	 */
	private function getCropType( $filter ) {
		$regExAdvanced = "/^iW=[0-9]{1,4}&iH=[0-9]{1,4}&oX=[0-9]{1,4}&oY=[0-9]{1,4}&cW=[0-9]{1,4}&cH=[0-9]{1,4}$/is";
		$regExBasic    = "/^iW=[0-9]{1,4}&iH=([0-9]{1,4}|any|\*{1})$/is";
		$cropType      = null;

		if ( preg_match( $regExBasic, $filter ) ) {
			$cropType = self::BASIC_CROP_TYPE;
		} elseif ( preg_match( $regExAdvanced, $filter ) ) {
			$cropType = self::ADVANCED_CROP_TYPE;
		} else {
			throw new Exception( "Invalid size format." );
		}

		return $cropType;
	}

	/**
	 * @param $source
	 * @param $target
	 *
	 * @return bool
	 */
	private function copyFile( $source, $target ) {
		return (bool) copy( $source, $target );
	}
}