mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-08 18:44:30 +00:00

* add verify ssl * add info in webhook payload on subdef create * reset cache of list of subdef for a record when create new subdef
885 lines
25 KiB
PHP
885 lines
25 KiB
PHP
<?php
|
|
|
|
/*
|
|
* This file is part of Phraseanet
|
|
*
|
|
* (c) 2005-2016 Alchemy
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
use Alchemy\Phrasea\Application;
|
|
use Alchemy\Phrasea\Databox\Subdef\MediaSubdefRepository;
|
|
use Alchemy\Phrasea\Filesystem\PhraseanetFilesystem as Filesystem;
|
|
use Alchemy\Phrasea\Http\StaticFile\Symlink\SymLinker;
|
|
use Alchemy\Phrasea\Model\RecordReferenceInterface;
|
|
use Alchemy\Phrasea\Utilities\NullableDateTime;
|
|
use Assert\Assertion;
|
|
use Guzzle\Http\Url;
|
|
use MediaAlchemyst\Alchemyst;
|
|
use MediaVorus\Media\MediaInterface;
|
|
use MediaVorus\MediaVorus;
|
|
|
|
|
|
class media_subdef extends media_abstract implements cache_cacheableInterface
|
|
{
|
|
/**
|
|
* @param Application $app
|
|
* @param int $databoxId
|
|
* @return MediaSubdefRepository
|
|
*/
|
|
private static function getMediaSubdefRepository(Application $app, $databoxId)
|
|
{
|
|
return $app['provider.repo.media_subdef']->getRepositoryForDatabox($databoxId);
|
|
}
|
|
|
|
/**
|
|
* @return Filesystem
|
|
*/
|
|
private function getFilesystem()
|
|
{
|
|
return $this->app['filesystem'];
|
|
}
|
|
|
|
/** @var Application */
|
|
protected $app;
|
|
|
|
/** @var string */
|
|
protected $mime;
|
|
|
|
/** @var string */
|
|
protected $file;
|
|
|
|
/** @var string */
|
|
protected $path;
|
|
|
|
/** @var record_adapter */
|
|
protected $record;
|
|
|
|
/** @var media_Permalink_Adapter */
|
|
protected $permalink;
|
|
|
|
/** @var boolean */
|
|
protected $is_substituted = false;
|
|
|
|
/** @var string */
|
|
protected $pathfile;
|
|
|
|
/** @var int */
|
|
protected $subdef_id;
|
|
|
|
/** @var string */
|
|
protected $name;
|
|
|
|
/** @var string */
|
|
protected $etag;
|
|
|
|
/** @var DateTime */
|
|
protected $creation_date;
|
|
|
|
/** @var DateTime */
|
|
protected $modification_date;
|
|
|
|
/** @var bool */
|
|
protected $is_physically_present = false;
|
|
|
|
/** @var integer */
|
|
private $size = 0;
|
|
|
|
/** @var array */
|
|
private static $technicalFieldsList = [];
|
|
|
|
/*
|
|
* Players types constants
|
|
*/
|
|
const TYPE_VIDEO_MP4 = 'VIDEO_MP4';
|
|
const TYPE_VIDEO_FLV = 'VIDEO_FLV';
|
|
const TYPE_FLEXPAPER = 'FLEXPAPER';
|
|
const TYPE_AUDIO_MP3 = 'AUDIO_MP3';
|
|
const TYPE_IMAGE = 'IMAGE';
|
|
const TYPE_NO_PLAYER = 'UNKNOWN';
|
|
const TYPE_PDF = 'PDF';
|
|
|
|
/*
|
|
* Technical datas types constants
|
|
*/
|
|
const TC_DATA_WIDTH = 'Width';
|
|
const TC_DATA_HEIGHT = 'Height';
|
|
const TC_DATA_COLORSPACE = 'ColorSpace';
|
|
const TC_DATA_CHANNELS = 'Channels';
|
|
const TC_DATA_ORIENTATION = 'Orientation';
|
|
const TC_DATA_THUMBNAILORIENTATION = 'ThumbnailOrientation';
|
|
const TC_DATA_COLORDEPTH = 'ColorDepth';
|
|
const TC_DATA_DURATION = 'Duration';
|
|
const TC_DATA_AUDIOCODEC = 'AudioCodec';
|
|
const TC_DATA_AUDIOSAMPLERATE = 'AudioSamplerate';
|
|
const TC_DATA_VIDEOCODEC = 'VideoCodec';
|
|
const TC_DATA_FRAMERATE = 'FrameRate';
|
|
const TC_DATA_MIMETYPE = 'MimeType';
|
|
const TC_DATA_FILESIZE = 'FileSize';
|
|
const TC_DATA_LONGITUDE = 'Longitude';
|
|
const TC_DATA_LONGITUDE_REF = 'LongitudeRef';
|
|
const TC_DATA_LATITUDE = 'Latitude';
|
|
const TC_DATA_LATITUDE_REF = 'LatitudeRef';
|
|
const TC_DATA_FOCALLENGTH = 'FocalLength';
|
|
const TC_DATA_CAMERAMODEL = 'CameraModel';
|
|
const TC_DATA_FLASHFIRED = 'FlashFired';
|
|
const TC_DATA_APERTURE = 'Aperture';
|
|
const TC_DATA_SHUTTERSPEED = 'ShutterSpeed';
|
|
const TC_DATA_HYPERFOCALDISTANCE = 'HyperfocalDistance';
|
|
const TC_DATA_ISO = 'ISO';
|
|
const TC_DATA_LIGHTVALUE = 'LightValue';
|
|
|
|
/**
|
|
* @param Application $app
|
|
* @param RecordReferenceInterface $record
|
|
* @param string $name
|
|
* @param bool $substitute
|
|
* @param array|null $data
|
|
*/
|
|
public function __construct(Application $app, RecordReferenceInterface $record, $name, $substitute = false, array $data = null)
|
|
{
|
|
$this->app = $app;
|
|
$this->name = $name;
|
|
$this->record = $record instanceof record_adapter
|
|
? $record
|
|
: $app->findDataboxById($record->getDataboxId())->get_record($record->getRecordId());
|
|
|
|
if (null !== $data) {
|
|
$this->loadFromArray($data);
|
|
} else {
|
|
$this->load($substitute);
|
|
}
|
|
|
|
parent::__construct($this->width, $this->height, $this->generateUrl());
|
|
}
|
|
|
|
/**
|
|
* @param bool $substitute
|
|
* @return void
|
|
*/
|
|
protected function load($substitute)
|
|
{
|
|
try {
|
|
$data = $this->get_data_from_cache();
|
|
} catch (Exception $e) {
|
|
$data = false;
|
|
}
|
|
|
|
if (is_array($data)) {
|
|
$this->loadFromArray($data);
|
|
|
|
return;
|
|
}
|
|
|
|
$data = self::getMediaSubdefRepository($this->app, $this->record->getDataboxId())
|
|
->findOneByRecordIdAndName($this->record->getRecordId(), $this->name);
|
|
|
|
if ($data) {
|
|
$this->loadFromArray($data->toArray());
|
|
} elseif ($substitute === false) {
|
|
throw new Exception_Media_SubdefNotFound($this->name . ' not found');
|
|
}
|
|
|
|
$this->loadFromArray([]);
|
|
|
|
$this->set_data_to_cache($this->toArray());
|
|
}
|
|
|
|
private function loadFromArray(array $data)
|
|
{
|
|
if (!$data) {
|
|
$data = [
|
|
'mime' => 'unknown',
|
|
'width' => 0,
|
|
'height' => 0,
|
|
'size' => 0,
|
|
'path' => '',
|
|
'file' => '',
|
|
'physically_present' => false,
|
|
'is_substituted' => false,
|
|
'subdef_id' => null,
|
|
'updated_on' => null,
|
|
'created_on' => null,
|
|
'url' => null,
|
|
];
|
|
}
|
|
|
|
$normalizer = function ($field, callable $then, callable $else = null) use ($data) {
|
|
if (isset($data[$field]) || array_key_exists($field, $data)) {
|
|
return $then($data[$field]);
|
|
}
|
|
|
|
return $else ? $else() : null;
|
|
};
|
|
|
|
$this->mime = $data['mime'];
|
|
$this->width = (int)$data['width'];
|
|
$this->height = (int)$data['height'];
|
|
$this->size = (int)$data['size'];
|
|
$this->etag = $normalizer('etag', 'strval');
|
|
$this->path = p4string::addEndSlash($data['path']);
|
|
$this->file = $data['file'];
|
|
$this->is_physically_present = (bool)$data['physically_present'];
|
|
$this->is_substituted = (bool)$data['is_substituted'];
|
|
$this->subdef_id = $normalizer('subdef_id', 'intval');
|
|
$this->modification_date = $normalizer('updated_on', 'date_create');
|
|
$this->creation_date = $normalizer('created_on', 'date_create');
|
|
$this->url = $normalizer('url', [Url::class, 'factory'], [$this, 'generateUrl']);
|
|
|
|
if (!$this->isStillAccessible()) {
|
|
$this->markPhysicallyUnavailable();
|
|
}
|
|
}
|
|
|
|
private function toArray()
|
|
{
|
|
return [
|
|
'record_id' => $this->get_record_id(),
|
|
'name' => $this->get_name(),
|
|
'width' => $this->width,
|
|
'size' => $this->size,
|
|
'height' => $this->height,
|
|
'mime' => $this->mime,
|
|
'file' => $this->file,
|
|
'path' => $this->path,
|
|
'physically_present' => $this->is_physically_present,
|
|
'is_substituted' => $this->is_substituted,
|
|
'subdef_id' => $this->subdef_id,
|
|
'updated_on' => NullableDateTime::format($this->modification_date),
|
|
'created_on' => NullableDateTime::format($this->creation_date),
|
|
'etag' => $this->etag,
|
|
'url' => (string)$this->url,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Removes the file associated to a subdef
|
|
*
|
|
* @return \media_subdef
|
|
*/
|
|
public function remove_file()
|
|
{
|
|
if ($this->is_physically_present() && is_writable($this->getRealPath())) {
|
|
// @unlink($this->getWatermarkRealPath());
|
|
@unlink($this->getStampRealPath());
|
|
unlink($this->getRealPath());
|
|
|
|
$this->delete_data_from_cache();
|
|
|
|
$permalink = $this->get_permalink();
|
|
|
|
if ($permalink instanceof media_Permalink_Adapter) {
|
|
$permalink->delete_data_from_cache();
|
|
}
|
|
|
|
$this->markPhysicallyUnavailable();
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* delete this subdef
|
|
*
|
|
* @throws \Doctrine\DBAL\DBALException
|
|
*/
|
|
public function delete()
|
|
{
|
|
$this->remove_file();
|
|
|
|
$connection = $this->getDataboxConnection();
|
|
|
|
$connection->executeUpdate(
|
|
'DELETE FROM permalinks WHERE subdef_id = :subdef_id',
|
|
['subdef_id' => $this->subdef_id]
|
|
);
|
|
|
|
self::getMediaSubdefRepository($this->app, $this->record->getDataboxId())->delete($this);
|
|
$this->delete_data_from_cache();
|
|
$this->record->delete_data_from_cache(record_adapter::CACHE_SUBDEFS);
|
|
}
|
|
|
|
private function getSubstituteFilename()
|
|
{
|
|
if ($this->record->isStory()) {
|
|
return 'regroup_thumb.png';
|
|
}
|
|
|
|
$mime = $this->record->getMimeType();
|
|
$mime = trim($mime) != '' ? str_replace('/', '_', $mime) : 'application_octet-stream';
|
|
|
|
return str_replace('+', '%20', $mime) . '.png';
|
|
}
|
|
|
|
/**
|
|
* Find a substitution file for a subdef
|
|
* @return void
|
|
*/
|
|
protected function markPhysicallyUnavailable()
|
|
{
|
|
$this->is_physically_present = false;
|
|
|
|
$this->mime = 'image/png';
|
|
$this->width = 256;
|
|
$this->height = 256;
|
|
$this->file = $this->getSubstituteFilename();
|
|
$this->etag = null;
|
|
|
|
$this->path = $this->app['root.path'] . '/www/assets/common/images/icons/substitution/';
|
|
$this->url = Url::factory('/assets/common/images/icons/substitution/' . $this->file);
|
|
|
|
if (!file_exists($this->getRealPath())) {
|
|
$this->path = $this->app['root.path'] . '/www/assets/common/images/icons/';
|
|
$this->file = 'substitution.png';
|
|
$this->url = Url::factory('/assets/common/images/icons/' . $this->file);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return bool
|
|
*/
|
|
public function is_physically_present()
|
|
{
|
|
return $this->is_physically_present;
|
|
}
|
|
|
|
/**
|
|
* @return record_adapter
|
|
*/
|
|
public function get_record()
|
|
{
|
|
return $this->record;
|
|
}
|
|
|
|
/**
|
|
* @return media_Permalink_Adapter
|
|
*/
|
|
public function get_permalink()
|
|
{
|
|
if (null === $this->permalink && $this->is_physically_present()) {
|
|
$this->permalink = media_Permalink_Adapter::getPermalink($this->app, $this->record->getDatabox(), $this);
|
|
}
|
|
|
|
return $this->permalink;
|
|
}
|
|
|
|
/**
|
|
* @return int
|
|
*/
|
|
public function get_record_id()
|
|
{
|
|
return $this->record->getRecordId();
|
|
}
|
|
|
|
public function getEtag()
|
|
{
|
|
if ((!$this->etag && $this->is_physically_present())) {
|
|
$file = new SplFileInfo($this->getRealPath());
|
|
if ($file->isFile()) {
|
|
$this->generateEtag($file);
|
|
}
|
|
}
|
|
|
|
return $this->etag;
|
|
}
|
|
|
|
/**
|
|
* @param string|null $etag
|
|
*/
|
|
public function setEtag($etag)
|
|
{
|
|
$this->etag = $etag;
|
|
|
|
return $this->save();
|
|
}
|
|
|
|
/**
|
|
* @param boolean $substit
|
|
*/
|
|
public function set_substituted($substit)
|
|
{
|
|
$this->is_substituted = !!$substit;
|
|
|
|
return $this->save();
|
|
}
|
|
|
|
/**
|
|
* @return int
|
|
*/
|
|
public function get_sbas_id()
|
|
{
|
|
return $this->record->getDataboxId();
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function get_type()
|
|
{
|
|
static $types = [
|
|
'application/x-shockwave-flash' => self::TYPE_FLEXPAPER,
|
|
'application/pdf' => self::TYPE_PDF,
|
|
'audio/mp3' => self::TYPE_AUDIO_MP3,
|
|
'audio/mpeg' => self::TYPE_AUDIO_MP3,
|
|
'image/gif' => self::TYPE_IMAGE,
|
|
'image/jpeg' => self::TYPE_IMAGE,
|
|
'image/png' => self::TYPE_IMAGE,
|
|
'video/mp4' => self::TYPE_VIDEO_MP4,
|
|
'video/x-flv' => self::TYPE_VIDEO_FLV,
|
|
];
|
|
|
|
if (isset($types[$this->mime])) {
|
|
return $types[$this->mime];
|
|
}
|
|
|
|
return self::TYPE_NO_PLAYER;
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function get_mime()
|
|
{
|
|
return $this->mime;
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function get_path()
|
|
{
|
|
return $this->path;
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function get_file()
|
|
{
|
|
return $this->file;
|
|
}
|
|
|
|
/**
|
|
* @return int
|
|
*/
|
|
public function get_size()
|
|
{
|
|
return $this->size;
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function get_name()
|
|
{
|
|
return $this->name;
|
|
}
|
|
|
|
/**
|
|
* @return int
|
|
*/
|
|
public function get_subdef_id()
|
|
{
|
|
return $this->subdef_id;
|
|
}
|
|
|
|
/**
|
|
* @return bool
|
|
*/
|
|
public function is_substituted()
|
|
{
|
|
return $this->is_substituted;
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
* @deprecated use {@link self::getRealPath} instead
|
|
*/
|
|
public function get_pathfile()
|
|
{
|
|
return $this->getRealPath();
|
|
}
|
|
|
|
/**
|
|
* @return DateTime
|
|
*/
|
|
public function get_modification_date()
|
|
{
|
|
return $this->modification_date;
|
|
}
|
|
|
|
/**
|
|
* @return DateTime
|
|
*/
|
|
public function get_creation_date()
|
|
{
|
|
return $this->creation_date;
|
|
}
|
|
|
|
/**
|
|
* @return Url
|
|
*/
|
|
public function renew_url()
|
|
{
|
|
$this->url = $this->generateUrl();
|
|
|
|
return $this->get_url();
|
|
}
|
|
|
|
/**
|
|
* Return the databox subdef corresponding to the subdef
|
|
*
|
|
* @return \databox_subdef
|
|
*/
|
|
public function getDataboxSubdef()
|
|
{
|
|
return $this->record
|
|
->getDatabox()
|
|
->get_subdef_structure()
|
|
->get_subdef($this->record->getType(), $this->get_name());
|
|
}
|
|
|
|
public function getDevices()
|
|
{
|
|
if ($this->get_name() === 'document') {
|
|
return [\databox_subdef::DEVICE_ALL];
|
|
}
|
|
|
|
try {
|
|
return $this->record
|
|
->getDatabox()
|
|
->get_subdef_structure()
|
|
->get_subdef($this->record->getType(), $this->get_name())
|
|
->getDevices();
|
|
} catch (\Exception_Databox_SubdefNotFound $e) {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param int $angle
|
|
* @param Alchemyst $alchemyst
|
|
* @param MediaVorus $mediavorus
|
|
*
|
|
* @return media_subdef
|
|
*/
|
|
public function rotate($angle, Alchemyst $alchemyst, MediaVorus $mediavorus)
|
|
{
|
|
// @unlink($this->getWatermarkRealPath());
|
|
@unlink($this->getStampRealPath());
|
|
|
|
if (!$this->is_physically_present()) {
|
|
throw new \Alchemy\Phrasea\Exception\RuntimeException('You can not rotate a substitution');
|
|
}
|
|
|
|
$specs = new \MediaAlchemyst\Specification\Image();
|
|
$specs->setRotationAngle($angle);
|
|
|
|
try {
|
|
$alchemyst->turnInto($this->getRealPath(), $this->getRealPath(), $specs);
|
|
} catch (\MediaAlchemyst\Exception\ExceptionInterface $e) {
|
|
return $this;
|
|
}
|
|
|
|
$media = $mediavorus->guess($this->getRealPath());
|
|
|
|
$this->width = $media->getWidth();
|
|
$this->height = $media->getHeight();
|
|
|
|
// generate a new etag after rotation
|
|
$file = new SplFileInfo($this->getRealPath());
|
|
$this->generateEtag($file); // with repository save
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Read the technical datas of the file.
|
|
* Returns an empty array for non physical present files
|
|
*
|
|
* @return array An array of technical datas Key/values
|
|
*/
|
|
public function readTechnicalDatas(MediaVorus $mediavorus)
|
|
{
|
|
if (!$this->is_physically_present()) {
|
|
return [];
|
|
}
|
|
|
|
$media = $mediavorus->guess($this->getRealPath());
|
|
|
|
$datas = [];
|
|
|
|
$techDatas = self::getTechnicalFieldsList();
|
|
|
|
foreach ($techDatas as $tc_name => $techData) {
|
|
if (array_key_exists('method', $techData)) {
|
|
if (method_exists($media, $techData['method'])) {
|
|
$result = call_user_func([$media, $techData['method']]);
|
|
|
|
if (null !== $result) {
|
|
$datas[$tc_name] = $result;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
$datas[self::TC_DATA_MIMETYPE] = $media->getFile()->getMimeType();
|
|
$datas[self::TC_DATA_FILESIZE] = $media->getFile()->getSize();
|
|
|
|
unset($media);
|
|
|
|
return $datas;
|
|
}
|
|
|
|
public static function create(Application $app, RecordReferenceInterface $record, $name, MediaInterface $media)
|
|
{
|
|
$path = $media->getFile()->getPath();
|
|
$newname = $media->getFile()->getFilename();
|
|
|
|
$params = [
|
|
'record_id' => $record->getRecordId(),
|
|
'name' => $name,
|
|
'path' => $path,
|
|
'file' => $newname,
|
|
'width' => 0,
|
|
'height' => 0,
|
|
'mime' => $media->getFile()->getMimeType(),
|
|
'size' => $media->getFile()->getSize(),
|
|
'physically_present' => true,
|
|
'is_substituted' => false,
|
|
];
|
|
|
|
if (method_exists($media, 'getWidth') && null !== $media->getWidth()) {
|
|
$params['width'] = $media->getWidth();
|
|
}
|
|
if (method_exists($media, 'getHeight') && null !== $media->getHeight()) {
|
|
$params['height'] = $media->getHeight();
|
|
}
|
|
|
|
/** @var callable $factoryProvider */
|
|
$factoryProvider = $app['provider.factory.media_subdef'];
|
|
$factory = $factoryProvider($record->getDataboxId());
|
|
|
|
$subdef = $factory($params);
|
|
|
|
Assertion::isInstanceOf($subdef, \media_subdef::class);
|
|
|
|
$repository = self::getMediaSubdefRepository($app, $record->getDataboxId());
|
|
$repository->save($subdef);
|
|
|
|
// Refresh from Database.
|
|
$subdef = $repository->findOneByRecordIdAndName($record->getRecordId(), $name);
|
|
|
|
$permalink = $subdef->get_permalink();
|
|
|
|
if ($permalink instanceof media_Permalink_Adapter) {
|
|
$permalink->delete_data_from_cache();
|
|
}
|
|
|
|
if ($name === 'thumbnail') {
|
|
/** @var SymLinker $symlinker */
|
|
$symlinker = $app['phraseanet.thumb-symlinker'];
|
|
$symlinker->symlink($subdef->getRealPath());
|
|
}
|
|
|
|
// delete from cache the list of available subdef for the record to taken account the new subdef
|
|
$subdef->get_record()->delete_data_from_cache(record_adapter::CACHE_SUBDEFS);
|
|
|
|
return $subdef;
|
|
}
|
|
|
|
/**
|
|
* @return Url
|
|
*/
|
|
protected function generateUrl()
|
|
{
|
|
if (!$this->is_physically_present()) {
|
|
$this->markPhysicallyUnavailable();
|
|
|
|
return $this->url;
|
|
}
|
|
|
|
$generators = [
|
|
[$this, 'tryGetThumbnailUrl'],
|
|
[$this, 'tryGetVideoUrl'],
|
|
];
|
|
|
|
foreach ($generators as $generator) {
|
|
$url = $generator();
|
|
|
|
if ($url instanceof Url) {
|
|
return $url;
|
|
}
|
|
}
|
|
|
|
return Url::factory($this->app->path('datafile', [
|
|
'sbas_id' => $this->record->getDataboxId(),
|
|
'record_id' => $this->record->getRecordId(),
|
|
'subdef' => $this->get_name(),
|
|
'etag' => $this->getEtag(),
|
|
]));
|
|
}
|
|
|
|
public function get_cache_key($option = null)
|
|
{
|
|
return 'subdef_' . $this->get_record()->getId()
|
|
. '_' . $this->name . ($option ? '_' . $option : '');
|
|
}
|
|
|
|
public function get_data_from_cache($option = null)
|
|
{
|
|
$databox = $this->get_record()->getDatabox();
|
|
|
|
return $databox->get_data_from_cache($this->get_cache_key($option));
|
|
}
|
|
|
|
public function set_data_to_cache($value, $option = null, $duration = 0)
|
|
{
|
|
$databox = $this->get_record()->getDatabox();
|
|
|
|
return $databox->set_data_to_cache($value, $this->get_cache_key($option), $duration);
|
|
}
|
|
|
|
public function delete_data_from_cache($option = null)
|
|
{
|
|
$databox = $this->get_record()->getDatabox();
|
|
|
|
$databox->delete_data_from_cache($this->get_cache_key($option));
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function getRealPath()
|
|
{
|
|
return $this->path . $this->file;
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function getWatermarkRealPath()
|
|
{
|
|
return $this->path . 'watermark_' . $this->file;
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function getStampRealPath()
|
|
{
|
|
return $this->path . 'stamp_' . $this->file;
|
|
}
|
|
|
|
/**
|
|
* @return \Doctrine\DBAL\Connection
|
|
*/
|
|
private function getDataboxConnection()
|
|
{
|
|
return $this->record->getDatabox()->get_connection();
|
|
}
|
|
|
|
/**
|
|
* @return bool
|
|
*/
|
|
private function isStillAccessible()
|
|
{
|
|
// return $this->is_physically_present && $this->getFilesystem()->exists($this->getRealPath(), 10); // allow 10 secs for the file to be visible on shared fs
|
|
return $this->is_physically_present && $this->getFilesystem()->exists($this->getRealPath()); // NO delay allowed, this slows down phr if any subdef is missing
|
|
}
|
|
|
|
/**
|
|
* @return Url|null
|
|
*/
|
|
protected function tryGetThumbnailUrl()
|
|
{
|
|
if ('thumbnail' !== $this->get_name()) {
|
|
return null;
|
|
}
|
|
|
|
$url = $this->app['phraseanet.static-file']->getUrl($this->getRealPath());
|
|
|
|
if (null === $url) {
|
|
return null;
|
|
}
|
|
|
|
$url->getQuery()->offsetSet('etag', $this->getEtag());
|
|
|
|
return $url;
|
|
}
|
|
|
|
/**
|
|
* @return Url|null
|
|
*/
|
|
protected function tryGetVideoUrl()
|
|
{
|
|
if ($this->mime !== 'video/mp4' || !$this->app['phraseanet.h264-factory']->isH264Enabled()) {
|
|
return null;
|
|
}
|
|
|
|
return $this->app['phraseanet.h264']->getUrl($this->getRealPath());
|
|
}
|
|
|
|
/**
|
|
* @param SplFileInfo $file
|
|
*/
|
|
private function generateEtag(SplFileInfo $file)
|
|
{
|
|
$this->setEtag(md5($file->getRealPath() . $file->getMTime()));
|
|
}
|
|
|
|
/**
|
|
* @return $this
|
|
*/
|
|
private function save()
|
|
{
|
|
self::getMediaSubdefRepository($this->app, $this->record->getDataboxId())->save($this);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Return list of technical data and their attributes
|
|
*
|
|
* @return array
|
|
*/
|
|
public static function getTechnicalFieldsList()
|
|
{
|
|
if (empty(self::$technicalFieldsList)) {
|
|
self::$technicalFieldsList = [
|
|
self::TC_DATA_WIDTH => ['method' => 'getWidth', 'type' => 'integer', 'analyzable' => false],
|
|
self::TC_DATA_HEIGHT => ['method' => 'getHeight', 'type' => 'integer', 'analyzable' => false],
|
|
self::TC_DATA_FOCALLENGTH => ['method' => 'getFocalLength', 'type' => 'float', 'analyzable' => false],
|
|
self::TC_DATA_CHANNELS => ['method' => 'getChannels', 'type' => 'integer', 'analyzable' => false],
|
|
self::TC_DATA_COLORDEPTH => ['method' => 'getColorDepth', 'type' => 'integer', 'analyzable' => false],
|
|
self::TC_DATA_CAMERAMODEL => ['method' => 'getCameraModel', 'type' => 'string', 'analyzable' => false],
|
|
self::TC_DATA_FLASHFIRED => ['method' => 'getFlashFired', 'type' => 'boolean', 'analyzable' => false],
|
|
self::TC_DATA_APERTURE => ['method' => 'getAperture', 'type' => 'float', 'analyzable' => false],
|
|
self::TC_DATA_SHUTTERSPEED => ['method' => 'getShutterSpeed', 'type' => 'float', 'analyzable' => false],
|
|
self::TC_DATA_HYPERFOCALDISTANCE => ['method' => 'getHyperfocalDistance', 'type' => 'float', 'analyzable' => false],
|
|
self::TC_DATA_ISO => ['method' => 'getISO', 'type' => 'integer', 'analyzable' => false],
|
|
self::TC_DATA_LIGHTVALUE => ['method' => 'getLightValue', 'type' => 'float', 'analyzable' => false],
|
|
self::TC_DATA_COLORSPACE => ['method' => 'getColorSpace', 'type' => 'integer', 'analyzable' => false],
|
|
self::TC_DATA_DURATION => ['method' => 'getDuration', 'type' => 'float', 'analyzable' => false],
|
|
self::TC_DATA_FRAMERATE => ['method' => 'getFrameRate', 'type' => 'float', 'analyzable' => false],
|
|
self::TC_DATA_AUDIOSAMPLERATE => ['method' => 'getAudioSampleRate', 'type' => 'float', 'analyzable' => false],
|
|
self::TC_DATA_VIDEOCODEC => ['method' => 'getVideoCodec', 'type' => 'string', 'analyzable' => false],
|
|
self::TC_DATA_AUDIOCODEC => ['method' => 'getAudioCodec', 'type' => 'string', 'analyzable' => false],
|
|
self::TC_DATA_ORIENTATION => ['method' => 'getOrientation', 'type' => 'integer', 'analyzable' => false],
|
|
self::TC_DATA_THUMBNAILORIENTATION => ['type' => 'string', 'analyzable' => false],
|
|
self::TC_DATA_LONGITUDE => ['method' => 'getLongitude', 'type' => 'float', 'analyzable' => false],
|
|
self::TC_DATA_LONGITUDE_REF => ['method' => 'getLongitudeRef'],
|
|
self::TC_DATA_LATITUDE => ['method' => 'getLatitude', 'type' => 'float', 'analyzable' => false],
|
|
self::TC_DATA_LATITUDE_REF => ['method' => 'getLatitudeRef'],
|
|
self::TC_DATA_MIMETYPE => ['type' => 'string', 'analyzable' => false],
|
|
self::TC_DATA_FILESIZE => ['type' => 'long', 'analyzable' => false],
|
|
];
|
|
}
|
|
|
|
|
|
return self::$technicalFieldsList;
|
|
}
|
|
}
|