~xibo-maintainers/xibo/tempel

« back to all changes in this revision

Viewing changes to lib/Entity/Media.php

  • Committer: Dan Garner
  • Date: 2016-06-28 15:02:11 UTC
  • mto: This revision was merged to the branch mainline in revision 528.
  • Revision ID: git-v1:51031805c36c1d366fa330b2c2320d1927c57003
Fixes for upgrade steps

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
namespace Xibo\Entity;
24
24
 
25
25
 
 
26
use GuzzleHttp\Client;
 
27
use GuzzleHttp\Exception\RequestException;
26
28
use Respect\Validation\Validator as v;
27
29
use Xibo\Exception\ConfigurationException;
28
 
use Xibo\Exception\DuplicateEntityException;
29
 
use Xibo\Exception\InvalidArgumentException;
30
30
use Xibo\Exception\NotFoundException;
31
 
use Xibo\Exception\XiboException;
32
 
use Xibo\Factory\DisplayFactory;
33
31
use Xibo\Factory\DisplayGroupFactory;
34
32
use Xibo\Factory\LayoutFactory;
35
33
use Xibo\Factory\MediaFactory;
36
34
use Xibo\Factory\PermissionFactory;
37
35
use Xibo\Factory\PlaylistFactory;
38
 
use Xibo\Factory\ScheduleFactory;
39
36
use Xibo\Factory\TagFactory;
40
37
use Xibo\Factory\WidgetFactory;
41
38
use Xibo\Service\ConfigServiceInterface;
177
174
    private $unassignTags = [];
178
175
 
179
176
    // New file revision
180
 
    public $isSaveRequired;
 
177
    public $force;
181
178
    public $isRemote;
182
 
 
183
179
    public $cloned = false;
184
180
    public $newExpiry;
185
181
    public $alwaysCopy = false;
229
225
     */
230
226
    private $playlistFactory;
231
227
 
232
 
    /** @var  DisplayFactory */
233
 
    private $displayFactory;
234
 
 
235
 
    /** @var  ScheduleFactory */
236
 
    private $scheduleFactory;
237
 
 
238
228
    /**
239
229
     * Entity constructor.
240
230
     * @param StorageServiceInterface $store
261
251
     * @param LayoutFactory $layoutFactory
262
252
     * @param WidgetFactory $widgetFactory
263
253
     * @param DisplayGroupFactory $displayGroupFactory
264
 
     * @param DisplayFactory $displayFactory
265
 
     * @param ScheduleFactory $scheduleFactory
266
254
     * @return $this
267
255
     */
268
 
    public function setChildObjectDependencies($layoutFactory, $widgetFactory, $displayGroupFactory, $displayFactory, $scheduleFactory)
 
256
    public function setChildObjectDependencies($layoutFactory, $widgetFactory, $displayGroupFactory)
269
257
    {
270
258
        $this->layoutFactory = $layoutFactory;
271
259
        $this->widgetFactory = $widgetFactory;
272
260
        $this->displayGroupFactory  = $displayGroupFactory;
273
 
        $this->displayFactory = $displayFactory;
274
 
        $this->scheduleFactory = $scheduleFactory;
275
261
        return $this;
276
262
    }
277
263
 
349
335
    {
350
336
        $this->load();
351
337
 
352
 
        $found = false;
353
 
        foreach ($this->tags as $existingTag) {
354
 
            if ($existingTag->tag === $tag->tag) {
355
 
                $found = true;
356
 
                break;
357
 
            }
358
 
        }
359
 
 
360
 
        if (!$found) {
361
 
            $this->getLog()->debug('Tag ' . $tag->tag . ' not found - assigning');
 
338
        if (!in_array($tag, $this->tags))
362
339
            $this->tags[] = $tag;
363
 
        }
364
340
 
365
341
        return $this;
366
342
    }
372
348
     */
373
349
    public function unassignTag($tag)
374
350
    {
375
 
        $this->load();
376
 
 
377
351
        $this->tags = array_udiff($this->tags, [$tag], function($a, $b) {
378
352
            /* @var Tag $a */
379
353
            /* @var Tag $b */
408
382
    /**
409
383
     * Validate
410
384
     * @param array $options
411
 
     * @throws XiboException
412
385
     */
413
386
    public function validate($options)
414
387
    {
415
388
        if (!v::string()->notEmpty()->validate($this->mediaType))
416
 
            throw new InvalidArgumentException(__('Unknown Module Type'), 'type');
 
389
            throw new \InvalidArgumentException(__('Unknown Module Type'));
417
390
 
418
391
        if (!v::string()->notEmpty()->length(1, 100)->validate($this->name))
419
 
            throw new InvalidArgumentException(__('The name must be between 1 and 100 characters'), 'name');
 
392
            throw new \InvalidArgumentException(__('The name must be between 1 and 100 characters'));
420
393
 
421
394
        // Check the naming of this item to ensure it doesn't conflict
422
395
        $params = array();
436
409
        $result = $this->getStore()->select($checkSQL, $params);
437
410
 
438
411
        if (count($result) > 0)
439
 
            throw new DuplicateEntityException(__('Media you own already has this name. Please choose another.'));
 
412
            throw new \InvalidArgumentException(__('Media you own already has this name. Please choose another.'));
440
413
    }
441
414
 
442
415
    /**
443
416
     * Load
444
417
     * @param array $options
445
 
     * @throws XiboException
446
418
     */
447
419
    public function load($options = [])
448
420
    {
449
 
        if ($this->loaded || $this->mediaId == null)
450
 
            return;
451
 
 
452
421
        $options = array_merge([
453
422
            'deleting' => false,
454
423
            'fullInfo' => false
487
456
     */
488
457
    public function save($options = [])
489
458
    {
490
 
        $this->getLog()->debug('Save for mediaId: ' . $this->mediaId);
491
 
 
492
459
        $options = array_merge([
493
460
            'validate' => true,
494
 
            'oldMedia' => null,
495
 
            'deferred' => false
 
461
            'oldMedia' => null
496
462
        ], $options);
497
463
 
498
464
        if ($options['validate'] && $this->mediaType != 'module')
501
467
        // Add or edit
502
468
        if ($this->mediaId == null || $this->mediaId == 0) {
503
469
            $this->add();
504
 
 
505
 
            // Always set force to true as we always want to save new files
506
 
            $this->isSaveRequired = true;
507
470
        }
508
471
        else {
 
472
            // If the media file is invalid, then force an update (only applies to module files)
 
473
            if ($this->valid == 0)
 
474
                $this->force = true;
 
475
 
509
476
            $this->edit();
510
 
 
511
 
            // If the media file is invalid, then force an update (only applies to module files)
512
 
            $expires = $this->getOriginalValue('expires');
513
 
            $this->isSaveRequired = ($this->isSaveRequired || $this->valid == 0 || ($expires > 0 && $expires < time()));
514
 
        }
515
 
 
516
 
        if ($options['deferred']) {
517
 
            $this->getLog()->debug('Media Update deferred until later');
518
 
        } else {
519
 
            $this->getLog()->debug('Media Update happening now');
520
 
 
521
 
            // Call save file
522
 
            if ($this->isSaveRequired)
523
 
                $this->saveFile();
524
477
        }
525
478
 
526
479
        // Save the tags
536
489
        if (is_array($this->unassignTags)) {
537
490
            foreach ($this->unassignTags as $tag) {
538
491
                /* @var Tag $tag */
 
492
                $this->getLog()->debug('Unassigning tag: %s', $tag->tag);
 
493
 
539
494
                $tag->unassignMedia($this->mediaId);
540
495
                $tag->save();
541
496
            }
543
498
    }
544
499
 
545
500
    /**
546
 
     * Save Async
547
 
     * @param array $options
548
 
     * @return $this
549
 
     */
550
 
    public function saveAsync($options = [])
551
 
    {
552
 
        $options = array_merge([
553
 
            'deferred' => true
554
 
        ], $options);
555
 
 
556
 
        $this->save($options);
557
 
 
558
 
        return $this;
559
 
    }
560
 
 
561
 
    /**
562
501
     * Delete
563
502
     * @throws \Xibo\Exception\NotFoundException
564
503
     */
599
538
 
600
539
                // Swap any audio nodes over to this new widget media assignment.
601
540
                $this->getStore()->update('
602
 
                  UPDATE `lkwidgetaudio` SET mediaId = :mediaId WHERE widgetId = :widgetId AND mediaId = :oldMediaId
 
541
                  UPDATE `lkwidgetaudio` SET mediaId = :mediaId WHERE widgetId = :widgetId AND oldMediaId = :oldMediaId
603
542
                ' , [
604
543
                    'mediaId' => $parentMedia->mediaId,
605
544
                    'widgetId' => $widget->widgetId,
621
560
 
622
561
        foreach ($this->displayGroups as $displayGroup) {
623
562
            /* @var \Xibo\Entity\DisplayGroup $displayGroup */
624
 
            $displayGroup->setChildObjectDependencies($this->displayFactory, $this->layoutFactory, $this->mediaFactory, $this->scheduleFactory);
625
563
            $displayGroup->unassignMedia($this);
626
564
 
627
565
            if ($parentMedia != null)
660
598
    private function add()
661
599
    {
662
600
        $this->mediaId = $this->getStore()->insert('
663
 
            INSERT INTO `media` (`name`, `type`, duration, originalFilename, userID, retired, moduleSystemFile, released, apiRef, valid)
664
 
              VALUES (:name, :type, :duration, :originalFileName, :userId, :retired, :moduleSystemFile, :released, :apiRef, :valid)
 
601
            INSERT INTO media (name, type, duration, originalFilename, userID, retired, moduleSystemFile, expires, released, apiRef)
 
602
              VALUES (:name, :type, :duration, :originalFileName, :userId, :retired, :moduleSystemFile, :expires, :released, :apiRef)
665
603
        ', [
666
604
            'name' => $this->name,
667
605
            'type' => $this->mediaType,
670
608
            'userId' => $this->ownerId,
671
609
            'retired' => $this->retired,
672
610
            'moduleSystemFile' => (($this->moduleSystemFile) ? 1 : 0),
 
611
            'expires' => $this->expires,
673
612
            'released' => $this->released,
674
 
            'apiRef' => $this->apiRef,
675
 
            'valid' => 0
 
613
            'apiRef' => $this->apiRef
 
614
        ]);
 
615
 
 
616
        $this->saveFile();
 
617
 
 
618
        // Update the MD5 and storedAs to suit
 
619
        $this->getStore()->update('UPDATE `media` SET md5 = :md5, fileSize = :fileSize, storedAs = :storedAs, duration = :duration WHERE mediaId = :mediaId', [
 
620
            'fileSize' => $this->fileSize,
 
621
            'md5' => $this->md5,
 
622
            'storedAs' => $this->storedAs,
 
623
            'duration' => $this->duration,
 
624
            'mediaId' => $this->mediaId
676
625
        ]);
677
626
    }
678
627
 
682
631
     */
683
632
    private function edit()
684
633
    {
 
634
        // Do we need to pull a new update?
 
635
        // Is the file either expired or is force set
 
636
        if ($this->force || ($this->expires > 0 && $this->expires < time())) {
 
637
            $this->getLog()->debug('Media %s has expired: %s. Force = %d', $this->name, date('Y-m-d H:i', $this->expires), $this->force);
 
638
            $this->saveFile();
 
639
        }
 
640
 
685
641
        $this->getStore()->update('
686
642
          UPDATE `media`
687
 
            SET `name` = :name,
 
643
              SET `name` = :name,
688
644
                duration = :duration,
689
645
                retired = :retired,
 
646
                md5 = :md5,
 
647
                filesize = :fileSize,
 
648
                expires = :expires,
690
649
                moduleSystemFile = :moduleSystemFile,
691
650
                editedMediaId = :editedMediaId,
692
651
                isEdited = :isEdited,
698
657
            'name' => $this->name,
699
658
            'duration' => $this->duration,
700
659
            'retired' => $this->retired,
 
660
            'fileSize' => $this->fileSize,
 
661
            'md5' => $this->md5,
 
662
            'expires' => $this->expires,
701
663
            'moduleSystemFile' => $this->moduleSystemFile,
702
664
            'editedMediaId' => $this->parentId,
703
665
            'isEdited' => $this->isEdited,
710
672
 
711
673
    /**
712
674
     * Save File to Library
713
 
     *  works on files that are already in the File system
 
675
     *  this should download remote files, handle clones, handle local module files and also handle files uploaded
 
676
     *  over the web ui
714
677
     * @throws ConfigurationException
715
678
     */
716
 
    public function saveFile()
 
679
    private function saveFile()
717
680
    {
 
681
        // If we are a remote media item, we want to download the newFile and save it to a temporary location
 
682
        if ($this->isRemote) {
 
683
            $this->download();
 
684
        }
 
685
 
718
686
        $libraryFolder = $this->config->GetSetting('LIBRARY_LOCATION');
719
687
 
720
688
        // Work out the extension
721
 
        $lastPeriod = strrchr($this->fileName, '.');
722
 
 
723
 
        // Determine the save name
724
 
        if ($lastPeriod === false) {
725
 
            $saveName = $this->mediaId;
726
 
        } else {
727
 
            $saveName = $this->mediaId . '.' . strtolower(substr($lastPeriod, 1));
728
 
        }
729
 
 
730
 
        $this->getLog()->debug('saveFile for "%s" with storedAs = "%s", fileName = "%s" to "%s". Always Copy = "%s", Cloned = "%s"',
 
689
        $extension = strtolower(substr(strrchr($this->fileName, '.'), 1));
 
690
 
 
691
        $this->getLog()->debug('saveFile for "%s" with storedAs = "%s" (empty = %s), fileName = "%s" to "%s". Always Copy = "%s", Cloned = "%s"',
731
692
            $this->name,
732
693
            $this->storedAs,
 
694
            empty($this->storedAs),
733
695
            $this->fileName,
734
 
            $saveName,
 
696
            $this->mediaId . '.' . $extension,
735
697
            $this->alwaysCopy,
736
698
            $this->cloned
737
699
        );
743
705
            if ($this->cloned) {
744
706
                $this->getLog()->debug('Copying cloned file');
745
707
                // Copy the file into the library
746
 
                if (!@copy($libraryFolder . $this->fileName, $libraryFolder . $saveName))
 
708
                if (!@copy($libraryFolder . $this->fileName, $libraryFolder . $this->mediaId . '.' . $extension))
747
709
                    throw new ConfigurationException(__('Problem copying file in the Library Folder'));
748
710
 
749
711
            } else {
750
712
                $this->getLog()->debug('Moving temporary file');
751
713
                // Move the file into the library
752
 
                if (!@rename($libraryFolder . 'temp/' . $this->fileName, $libraryFolder . $saveName))
 
714
                if (!@rename($libraryFolder . 'temp/' . $this->fileName, $libraryFolder . $this->mediaId . '.' . $extension))
753
715
                    throw new ConfigurationException(__('Problem moving uploaded file into the Library Folder'));
754
716
            }
755
717
 
756
718
            // Set the storedAs
757
 
            $this->storedAs = $saveName;
 
719
            $this->storedAs = $this->mediaId . '.' . $extension;
758
720
        }
759
721
        else {
 
722
            $this->getLog()->debug('Copying specified file');
760
723
            // We have pre-defined where we want this to be stored
761
724
            if (empty($this->storedAs)) {
762
725
                // Assume we want to set this automatically (i.e. we are set to always copy)
763
 
                $this->storedAs = $saveName;
 
726
                $this->storedAs = $this->mediaId . '.' . $extension;
764
727
            }
765
728
 
766
 
            if ($this->isRemote) {
767
 
                $this->getLog()->debug('Moving temporary file');
768
 
 
769
 
                // Move the file into the library
770
 
                if (!@rename($libraryFolder . 'temp/' . $this->fileName, $libraryFolder . $this->storedAs))
771
 
                    throw new ConfigurationException(__('Problem moving downloaded file into the Library Folder'));
772
 
            } else {
773
 
                $this->getLog()->debug('Copying specified file');
774
 
 
775
 
                if (!@copy($this->fileName, $libraryFolder . $this->storedAs)) {
776
 
                    $this->getLog()->error('Cannot copy %s to %s', $this->fileName, $libraryFolder . $this->storedAs);
777
 
                    throw new ConfigurationException(__('Problem copying provided file into the Library Folder'));
778
 
                }
 
729
            if (!@copy($this->fileName, $libraryFolder . $this->storedAs)) {
 
730
                $this->getLog()->error('Cannot copy %s to %s', $this->fileName, $libraryFolder . $this->storedAs);
 
731
                throw new ConfigurationException(__('Problem moving provided file into the Library Folder'));
779
732
            }
780
733
        }
781
734
 
782
735
        // Work out the MD5
783
736
        $this->md5 = md5_file($libraryFolder . $this->storedAs);
784
737
        $this->fileSize = filesize($libraryFolder . $this->storedAs);
785
 
 
786
 
        // Update the MD5 and storedAs to suit
787
 
        $this->getStore()->update('UPDATE `media` SET md5 = :md5, fileSize = :fileSize, storedAs = :storedAs, expires = :expires, valid = 1 WHERE mediaId = :mediaId', [
788
 
            'fileSize' => $this->fileSize,
789
 
            'md5' => $this->md5,
790
 
            'storedAs' => $this->storedAs,
791
 
            'expires' => $this->expires,
792
 
            'mediaId' => $this->mediaId
793
 
        ]);
794
738
    }
795
739
 
796
740
    /**
829
773
    }
830
774
 
831
775
    /**
832
 
     * Download URL
833
 
     * @return string
834
 
     */
835
 
    public function downloadUrl()
836
 
    {
837
 
        return $this->fileName;
838
 
    }
839
 
 
840
 
    /**
841
 
     * Download Sink
842
 
     * @return string
843
 
     */
844
 
    public function downloadSink()
845
 
    {
846
 
        return $this->config->GetSetting('LIBRARY_LOCATION') . 'temp' . DIRECTORY_SEPARATOR . $this->name;
 
776
     * Download remote file
 
777
     */
 
778
    private function download()
 
779
    {
 
780
        if (!$this->isRemote || $this->fileName == '')
 
781
            throw new \InvalidArgumentException(__('Not in a suitable state to download'));
 
782
 
 
783
        // Open the temporary file
 
784
        $storedAs = $this->config->GetSetting('LIBRARY_LOCATION') . 'temp' . DIRECTORY_SEPARATOR . $this->name;
 
785
 
 
786
        $this->getLog()->debug('Downloading %s to %s', $this->fileName, $storedAs);
 
787
 
 
788
        if (!$fileHandle = fopen($storedAs, 'w'))
 
789
            throw new ConfigurationException(__('Temporary location not writable'));
 
790
 
 
791
        try {
 
792
            $client = new Client();
 
793
            $client->get($this->fileName, $this->config->getGuzzleProxy(['save_to' => $fileHandle]));
 
794
        }
 
795
        catch (RequestException $e) {
 
796
            $this->getLog()->error('Unable to get %s, %s', $this->fileName, $e->getMessage());
 
797
        }
 
798
 
 
799
        // Change the filename to our temporary file
 
800
        $this->fileName = $storedAs;
847
801
    }
848
802
}
 
 
b'\\ No newline at end of file'