Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.0.x will end 8 May 2023 (12 months).
  • Bug fixes for security issues in 4.0.x will end 13 November 2023 (18 months).
  • PHP version: minimum PHP 7.3.0 Note: the minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is also supported.

Differences Between: [Versions 310 and 400] [Versions 311 and 400] [Versions 39 and 400] [Versions 400 and 401] [Versions 400 and 402] [Versions 400 and 403]

   1  <?php
   2  
   3  namespace PhpOffice\PhpSpreadsheet\Worksheet;
   4  
   5  use GdImage;
   6  use PhpOffice\PhpSpreadsheet\Exception;
   7  
   8  class MemoryDrawing extends BaseDrawing
   9  {
  10      // Rendering functions
  11      const RENDERING_DEFAULT = 'imagepng';
  12      const RENDERING_PNG = 'imagepng';
  13      const RENDERING_GIF = 'imagegif';
  14      const RENDERING_JPEG = 'imagejpeg';
  15  
  16      // MIME types
  17      const MIMETYPE_DEFAULT = 'image/png';
  18      const MIMETYPE_PNG = 'image/png';
  19      const MIMETYPE_GIF = 'image/gif';
  20      const MIMETYPE_JPEG = 'image/jpeg';
  21  
  22      /**
  23       * Image resource.
  24       *
  25       * @var null|GdImage|resource
  26       */
  27      private $imageResource;
  28  
  29      /**
  30       * Rendering function.
  31       *
  32       * @var string
  33       */
  34      private $renderingFunction;
  35  
  36      /**
  37       * Mime type.
  38       *
  39       * @var string
  40       */
  41      private $mimeType;
  42  
  43      /**
  44       * Unique name.
  45       *
  46       * @var string
  47       */
  48      private $uniqueName;
  49  
  50      /**
  51       * Create a new MemoryDrawing.
  52       */
  53      public function __construct()
  54      {
  55          // Initialise values
  56          $this->renderingFunction = self::RENDERING_DEFAULT;
  57          $this->mimeType = self::MIMETYPE_DEFAULT;
  58          $this->uniqueName = md5(mt_rand(0, 9999) . time() . mt_rand(0, 9999));
  59  
  60          // Initialize parent
  61          parent::__construct();
  62      }
  63  
  64      public function __destruct()
  65      {
  66          if ($this->imageResource) {
  67              imagedestroy($this->imageResource);
  68              $this->imageResource = null;
  69          }
  70      }
  71  
  72      public function __clone()
  73      {
  74          parent::__clone();
  75          $this->cloneResource();
  76      }
  77  
  78      private function cloneResource(): void
  79      {
  80          if (!$this->imageResource) {
  81              return;
  82          }
  83  
  84          $width = imagesx($this->imageResource);
  85          $height = imagesy($this->imageResource);
  86  
  87          if (imageistruecolor($this->imageResource)) {
  88              $clone = imagecreatetruecolor($width, $height);
  89              if (!$clone) {
  90                  throw new Exception('Could not clone image resource');
  91              }
  92  
  93              imagealphablending($clone, false);
  94              imagesavealpha($clone, true);
  95          } else {
  96              $clone = imagecreate($width, $height);
  97              if (!$clone) {
  98                  throw new Exception('Could not clone image resource');
  99              }
 100  
 101              // If the image has transparency...
 102              $transparent = imagecolortransparent($this->imageResource);
 103              if ($transparent >= 0) {
 104                  $rgb = imagecolorsforindex($this->imageResource, $transparent);
 105                  if (empty($rgb)) {
 106                      throw new Exception('Could not get image colors');
 107                  }
 108  
 109                  imagesavealpha($clone, true);
 110                  $color = imagecolorallocatealpha($clone, $rgb['red'], $rgb['green'], $rgb['blue'], $rgb['alpha']);
 111                  if ($color === false) {
 112                      throw new Exception('Could not get image alpha color');
 113                  }
 114  
 115                  imagefill($clone, 0, 0, $color);
 116              }
 117          }
 118  
 119          //Create the Clone!!
 120          imagecopy($clone, $this->imageResource, 0, 0, 0, 0, $width, $height);
 121  
 122          $this->imageResource = $clone;
 123      }
 124  
 125      /**
 126       * Get image resource.
 127       *
 128       * @return null|GdImage|resource
 129       */
 130      public function getImageResource()
 131      {
 132          return $this->imageResource;
 133      }
 134  
 135      /**
 136       * Set image resource.
 137       *
 138       * @param GdImage|resource $value
 139       *
 140       * @return $this
 141       */
 142      public function setImageResource($value)
 143      {
 144          $this->imageResource = $value;
 145  
 146          if ($this->imageResource !== null) {
 147              // Get width/height
 148              $this->width = imagesx($this->imageResource);
 149              $this->height = imagesy($this->imageResource);
 150          }
 151  
 152          return $this;
 153      }
 154  
 155      /**
 156       * Get rendering function.
 157       *
 158       * @return string
 159       */
 160      public function getRenderingFunction()
 161      {
 162          return $this->renderingFunction;
 163      }
 164  
 165      /**
 166       * Set rendering function.
 167       *
 168       * @param string $value see self::RENDERING_*
 169       *
 170       * @return $this
 171       */
 172      public function setRenderingFunction($value)
 173      {
 174          $this->renderingFunction = $value;
 175  
 176          return $this;
 177      }
 178  
 179      /**
 180       * Get mime type.
 181       *
 182       * @return string
 183       */
 184      public function getMimeType()
 185      {
 186          return $this->mimeType;
 187      }
 188  
 189      /**
 190       * Set mime type.
 191       *
 192       * @param string $value see self::MIMETYPE_*
 193       *
 194       * @return $this
 195       */
 196      public function setMimeType($value)
 197      {
 198          $this->mimeType = $value;
 199  
 200          return $this;
 201      }
 202  
 203      /**
 204       * Get indexed filename (using image index).
 205       */
 206      public function getIndexedFilename(): string
 207      {
 208          $extension = strtolower($this->getMimeType());
 209          $extension = explode('/', $extension);
 210          $extension = $extension[1];
 211  
 212          return $this->uniqueName . $this->getImageIndex() . '.' . $extension;
 213      }
 214  
 215      /**
 216       * Get hash code.
 217       *
 218       * @return string Hash code
 219       */
 220      public function getHashCode()
 221      {
 222          return md5(
 223              $this->renderingFunction .
 224              $this->mimeType .
 225              $this->uniqueName .
 226              parent::getHashCode() .
 227              __CLASS__
 228          );
 229      }
 230  }