Invision Power Services, Inc. * @copyright (c) Invision Power Services, Inc. * @package Invision Community * @subpackage convert * @since 09 Jul 2019 */ namespace IPS\convert\Tools; /* To prevent PHP errors (extending class does not exist) revealing path */ use InvalidArgumentException; use IPS\Image; use IPS\Image\Gd; use OutOfRangeException; use UnderflowException; use function defined; use function file_exists; use function file_get_contents; use function is_null; use function unserialize; if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) ) { header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' ); exit; } /** * Converter software exception */ trait Xenforo { /** * Helper to unpack an either serialized or json encoded value * * XenForo < 2.1 used serialize to store information, XenForo 2.1 moved to json encoded data */ public static function unpack( string $value ) { if ( static::$useJson ) { return json_decode( $value, TRUE ); } else { return unserialize( $value ); } } /** * Helper to fetch a xenforo phrase * * @param string $xfOneTitle XF1 Phrase title * @param string $xfTwoTitle XF2 Phrase Title * @return string|null */ protected function getPhrase( string $xfOneTitle, string $xfTwoTitle ) : ?string { try { $title = ( static::$isLegacy === FALSE OR is_null( static::$isLegacy ) ) ? $xfTwoTitle : $xfOneTitle; return $this->db->select( 'phrase_text', 'xf_phrase', array( "title=?", $title ) )->first(); } catch( UnderflowException $e ) { return NULL; } } /** * @brief Cache sprite image objects */ protected array $_spriteImages = array(); /** * Return image from sprite - We must use GD for this, it's generally available on most servers * And we don't have any relevant methods in either image handler for doing this completly within * the image class * * @param string $sprite Sprite path * @param array $spriteParams Sprite parameters * @return array * * @throws OutOfRangeException * @throws InvalidArgumentException */ protected function _imageFromSprite( string $sprite, array $spriteParams ) : array { $key = md5( $sprite ); /* Set up image canvas */ if( !isset( $this->_spriteImages[ $key ] ) ) { if( !file_exists( $sprite ) ) { throw new OutOfRangeException; } // Check valid image $image = file_get_contents( $sprite ); Image::create( $image ); $this->_spriteImages[ $key ] = new Gd( $image ); } /* x2 image? */ $multiplier = 1; if( $this->_spriteImages[ $key ]->width > $spriteParams['w'] ) { $multiplier = 2; } $image = Gd::newImageCanvas( $spriteParams['w'] * $multiplier, $spriteParams['h'] * $multiplier, array( 0, 0, 0 ) ); /* Set the background to transparent */ imagefill( $image->image, 0, 0, imagecolorallocatealpha( $image->image, 0, 0, 0, 127 ) ); /* Extract sprite */ imagecopy( $image->image, $this->_spriteImages[ $key ]->image, 0, 0, abs( (int) $spriteParams['x'] ) * $multiplier, abs( (int) $spriteParams['y'] ) * $multiplier, $spriteParams['w'] * $multiplier, $spriteParams['h'] * $multiplier ); /* x2 image? */ $return = array(); if( $multiplier == 2 ) { $return['image_x2'] = (string) $image; /* Resize */ $image->resize( $spriteParams['w'], $spriteParams['h'] ); } $return['image'] = (string) $image; unset( $image ); return $return; } }