Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

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