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 PhpOffice\PhpSpreadsheet\Cell\Hyperlink;
   6  use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
   7  use PhpOffice\PhpSpreadsheet\IComparable;
   8  
   9  class BaseDrawing implements IComparable
  10  {
  11      /**
  12       * Image counter.
  13       *
  14       * @var int
  15       */
  16      private static $imageCounter = 0;
  17  
  18      /**
  19       * Image index.
  20       *
  21       * @var int
  22       */
  23      private $imageIndex = 0;
  24  
  25      /**
  26       * Name.
  27       *
  28       * @var string
  29       */
  30      protected $name;
  31  
  32      /**
  33       * Description.
  34       *
  35       * @var string
  36       */
  37      protected $description;
  38  
  39      /**
  40       * Worksheet.
  41       *
  42       * @var null|Worksheet
  43       */
  44      protected $worksheet;
  45  
  46      /**
  47       * Coordinates.
  48       *
  49       * @var string
  50       */
  51      protected $coordinates;
  52  
  53      /**
  54       * Offset X.
  55       *
  56       * @var int
  57       */
  58      protected $offsetX;
  59  
  60      /**
  61       * Offset Y.
  62       *
  63       * @var int
  64       */
  65      protected $offsetY;
  66  
  67      /**
  68       * Width.
  69       *
  70       * @var int
  71       */
  72      protected $width;
  73  
  74      /**
  75       * Height.
  76       *
  77       * @var int
  78       */
  79      protected $height;
  80  
  81      /**
  82       * Proportional resize.
  83       *
  84       * @var bool
  85       */
  86      protected $resizeProportional;
  87  
  88      /**
  89       * Rotation.
  90       *
  91       * @var int
  92       */
  93      protected $rotation;
  94  
  95      /**
  96       * Shadow.
  97       *
  98       * @var Drawing\Shadow
  99       */
 100      protected $shadow;
 101  
 102      /**
 103       * Image hyperlink.
 104       *
 105       * @var null|Hyperlink
 106       */
 107      private $hyperlink;
 108  
 109      /**
 110       * Image type.
 111       *
 112       * @var int
 113       */
 114      protected $type;
 115  
 116      /**
 117       * Create a new BaseDrawing.
 118       */
 119      public function __construct()
 120      {
 121          // Initialise values
 122          $this->name = '';
 123          $this->description = '';
 124          $this->worksheet = null;
 125          $this->coordinates = 'A1';
 126          $this->offsetX = 0;
 127          $this->offsetY = 0;
 128          $this->width = 0;
 129          $this->height = 0;
 130          $this->resizeProportional = true;
 131          $this->rotation = 0;
 132          $this->shadow = new Drawing\Shadow();
 133          $this->type = IMAGETYPE_UNKNOWN;
 134  
 135          // Set image index
 136          ++self::$imageCounter;
 137          $this->imageIndex = self::$imageCounter;
 138      }
 139  
 140      /**
 141       * Get image index.
 142       *
 143       * @return int
 144       */
 145      public function getImageIndex()
 146      {
 147          return $this->imageIndex;
 148      }
 149  
 150      /**
 151       * Get Name.
 152       *
 153       * @return string
 154       */
 155      public function getName()
 156      {
 157          return $this->name;
 158      }
 159  
 160      /**
 161       * Set Name.
 162       *
 163       * @param string $name
 164       *
 165       * @return $this
 166       */
 167      public function setName($name)
 168      {
 169          $this->name = $name;
 170  
 171          return $this;
 172      }
 173  
 174      /**
 175       * Get Description.
 176       *
 177       * @return string
 178       */
 179      public function getDescription()
 180      {
 181          return $this->description;
 182      }
 183  
 184      /**
 185       * Set Description.
 186       *
 187       * @param string $description
 188       *
 189       * @return $this
 190       */
 191      public function setDescription($description)
 192      {
 193          $this->description = $description;
 194  
 195          return $this;
 196      }
 197  
 198      /**
 199       * Get Worksheet.
 200       *
 201       * @return null|Worksheet
 202       */
 203      public function getWorksheet()
 204      {
 205          return $this->worksheet;
 206      }
 207  
 208      /**
 209       * Set Worksheet.
 210       *
 211       * @param bool $overrideOld If a Worksheet has already been assigned, overwrite it and remove image from old Worksheet?
 212       *
 213       * @return $this
 214       */
 215      public function setWorksheet(?Worksheet $worksheet = null, $overrideOld = false)
 216      {
 217          if ($this->worksheet === null) {
 218              // Add drawing to \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet
 219              $this->worksheet = $worksheet;
 220              $this->worksheet->getCell($this->coordinates);
 221              $this->worksheet->getDrawingCollection()->append($this);
 222          } else {
 223              if ($overrideOld) {
 224                  // Remove drawing from old \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet
 225                  $iterator = $this->worksheet->getDrawingCollection()->getIterator();
 226  
 227                  while ($iterator->valid()) {
 228                      if ($iterator->current()->getHashCode() === $this->getHashCode()) {
 229                          $this->worksheet->getDrawingCollection()->offsetUnset($iterator->key());
 230                          $this->worksheet = null;
 231  
 232                          break;
 233                      }
 234                  }
 235  
 236                  // Set new \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet
 237                  $this->setWorksheet($worksheet);
 238              } else {
 239                  throw new PhpSpreadsheetException('A Worksheet has already been assigned. Drawings can only exist on one \\PhpOffice\\PhpSpreadsheet\\Worksheet.');
 240              }
 241          }
 242  
 243          return $this;
 244      }
 245  
 246      /**
 247       * Get Coordinates.
 248       *
 249       * @return string
 250       */
 251      public function getCoordinates()
 252      {
 253          return $this->coordinates;
 254      }
 255  
 256      /**
 257       * Set Coordinates.
 258       *
 259       * @param string $coordinates eg: 'A1'
 260       *
 261       * @return $this
 262       */
 263      public function setCoordinates($coordinates)
 264      {
 265          $this->coordinates = $coordinates;
 266  
 267          return $this;
 268      }
 269  
 270      /**
 271       * Get OffsetX.
 272       *
 273       * @return int
 274       */
 275      public function getOffsetX()
 276      {
 277          return $this->offsetX;
 278      }
 279  
 280      /**
 281       * Set OffsetX.
 282       *
 283       * @param int $offsetX
 284       *
 285       * @return $this
 286       */
 287      public function setOffsetX($offsetX)
 288      {
 289          $this->offsetX = $offsetX;
 290  
 291          return $this;
 292      }
 293  
 294      /**
 295       * Get OffsetY.
 296       *
 297       * @return int
 298       */
 299      public function getOffsetY()
 300      {
 301          return $this->offsetY;
 302      }
 303  
 304      /**
 305       * Set OffsetY.
 306       *
 307       * @param int $offsetY
 308       *
 309       * @return $this
 310       */
 311      public function setOffsetY($offsetY)
 312      {
 313          $this->offsetY = $offsetY;
 314  
 315          return $this;
 316      }
 317  
 318      /**
 319       * Get Width.
 320       *
 321       * @return int
 322       */
 323      public function getWidth()
 324      {
 325          return $this->width;
 326      }
 327  
 328      /**
 329       * Set Width.
 330       *
 331       * @param int $width
 332       *
 333       * @return $this
 334       */
 335      public function setWidth($width)
 336      {
 337          // Resize proportional?
 338          if ($this->resizeProportional && $width != 0) {
 339              $ratio = $this->height / ($this->width != 0 ? $this->width : 1);
 340              $this->height = (int) round($ratio * $width);
 341          }
 342  
 343          // Set width
 344          $this->width = $width;
 345  
 346          return $this;
 347      }
 348  
 349      /**
 350       * Get Height.
 351       *
 352       * @return int
 353       */
 354      public function getHeight()
 355      {
 356          return $this->height;
 357      }
 358  
 359      /**
 360       * Set Height.
 361       *
 362       * @param int $height
 363       *
 364       * @return $this
 365       */
 366      public function setHeight($height)
 367      {
 368          // Resize proportional?
 369          if ($this->resizeProportional && $height != 0) {
 370              $ratio = $this->width / ($this->height != 0 ? $this->height : 1);
 371              $this->width = (int) round($ratio * $height);
 372          }
 373  
 374          // Set height
 375          $this->height = $height;
 376  
 377          return $this;
 378      }
 379  
 380      /**
 381       * Set width and height with proportional resize.
 382       *
 383       * Example:
 384       * <code>
 385       * $objDrawing->setResizeProportional(true);
 386       * $objDrawing->setWidthAndHeight(160,120);
 387       * </code>
 388       *
 389       * @param int $width
 390       * @param int $height
 391       *
 392       * @return $this
 393       *
 394       * @author Vincent@luo MSN:kele_100@hotmail.com
 395       */
 396      public function setWidthAndHeight($width, $height)
 397      {
 398          $xratio = $width / ($this->width != 0 ? $this->width : 1);
 399          $yratio = $height / ($this->height != 0 ? $this->height : 1);
 400          if ($this->resizeProportional && !($width == 0 || $height == 0)) {
 401              if (($xratio * $this->height) < $height) {
 402                  $this->height = (int) ceil($xratio * $this->height);
 403                  $this->width = $width;
 404              } else {
 405                  $this->width = (int) ceil($yratio * $this->width);
 406                  $this->height = $height;
 407              }
 408          } else {
 409              $this->width = $width;
 410              $this->height = $height;
 411          }
 412  
 413          return $this;
 414      }
 415  
 416      /**
 417       * Get ResizeProportional.
 418       *
 419       * @return bool
 420       */
 421      public function getResizeProportional()
 422      {
 423          return $this->resizeProportional;
 424      }
 425  
 426      /**
 427       * Set ResizeProportional.
 428       *
 429       * @param bool $resizeProportional
 430       *
 431       * @return $this
 432       */
 433      public function setResizeProportional($resizeProportional)
 434      {
 435          $this->resizeProportional = $resizeProportional;
 436  
 437          return $this;
 438      }
 439  
 440      /**
 441       * Get Rotation.
 442       *
 443       * @return int
 444       */
 445      public function getRotation()
 446      {
 447          return $this->rotation;
 448      }
 449  
 450      /**
 451       * Set Rotation.
 452       *
 453       * @param int $rotation
 454       *
 455       * @return $this
 456       */
 457      public function setRotation($rotation)
 458      {
 459          $this->rotation = $rotation;
 460  
 461          return $this;
 462      }
 463  
 464      /**
 465       * Get Shadow.
 466       *
 467       * @return Drawing\Shadow
 468       */
 469      public function getShadow()
 470      {
 471          return $this->shadow;
 472      }
 473  
 474      /**
 475       * Set Shadow.
 476       *
 477       * @return $this
 478       */
 479      public function setShadow(?Drawing\Shadow $shadow = null)
 480      {
 481          $this->shadow = $shadow;
 482  
 483          return $this;
 484      }
 485  
 486      /**
 487       * Get hash code.
 488       *
 489       * @return string Hash code
 490       */
 491      public function getHashCode()
 492      {
 493          return md5(
 494              $this->name .
 495              $this->description .
 496              $this->worksheet->getHashCode() .
 497              $this->coordinates .
 498              $this->offsetX .
 499              $this->offsetY .
 500              $this->width .
 501              $this->height .
 502              $this->rotation .
 503              $this->shadow->getHashCode() .
 504              __CLASS__
 505          );
 506      }
 507  
 508      /**
 509       * Implement PHP __clone to create a deep clone, not just a shallow copy.
 510       */
 511      public function __clone()
 512      {
 513          $vars = get_object_vars($this);
 514          foreach ($vars as $key => $value) {
 515              if ($key == 'worksheet') {
 516                  $this->worksheet = null;
 517              } elseif (is_object($value)) {
 518                  $this->$key = clone $value;
 519              } else {
 520                  $this->$key = $value;
 521              }
 522          }
 523      }
 524  
 525      public function setHyperlink(?Hyperlink $hyperlink = null): void
 526      {
 527          $this->hyperlink = $hyperlink;
 528      }
 529  
 530      /**
 531       * @return null|Hyperlink
 532       */
 533      public function getHyperlink()
 534      {
 535          return $this->hyperlink;
 536      }
 537  
 538      /**
 539       * Set Fact Sizes and Type of Image.
 540       */
 541      protected function setSizesAndType(string $path): void
 542      {
 543          if ($this->width == 0 && $this->height == 0 && $this->type == IMAGETYPE_UNKNOWN) {
 544              $imageData = getimagesize($path);
 545  
 546              if (is_array($imageData)) {
 547                  $this->width = $imageData[0];
 548                  $this->height = $imageData[1];
 549                  $this->type = $imageData[2];
 550              }
 551          }
 552      }
 553  
 554      /**
 555       * Get Image Type.
 556       */
 557      public function getType(): int
 558      {
 559          return $this->type;
 560      }
 561  }