belongsToMany(Person::class); } public function Tags() { return $this->belongsToMany(Tag::class); } /** * Multimedia NOT duplicate. * * @return \Illuminate\Database\Eloquent\Builder */ public function scopeNotDuplicate($query) { return $query->where(function($query) { $query->where('duplicate','!=',TRUE) ->orWhere('duplicate','=',NULL); }); } /** * Multimedia NOT pending removal. * * @return \Illuminate\Database\Eloquent\Builder */ public function scopeNotRemove($query) { return $query->where(function($query) { $query->where('remove','!=',TRUE) ->orWhere('remove','=',NULL); }); } /** * Multimedia NOT scanned. * * @return \Illuminate\Database\Eloquent\Builder */ public function scopeNotScanned($query) { return $query->where(function($query) { $query->where('scanned','!=',TRUE) ->orWhere('scanned','=',NULL); }); } abstract public function setDateCreated(); abstract public function setLocation(); abstract public function setMakeModel(); abstract public function setSignature(); abstract public function setSubSecTime(); abstract public function setThumbnail(); abstract public function view(); /** * Date the multimedia was created */ public function date_taken() { return $this->date_created ? date('Y-m-d H:i:s',$this->date_created) : 'UNKNOWN'; } /** * Return the date of the file */ public function file_date($type,$format=FALSE) { if (! is_readable($this->file_path())) return NULL; switch ($type) { case 'a': $t = fileatime($this->file_path()); break; case 'c': $t = filectime($this->file_path()); break; case 'm': $t = filemtime($this->file_path()); break; } return $format ? date('d-m-Y H:i:s',$t) : $t; } /** * Determine the new name for the image */ public function file_path($short=FALSE,$new=FALSE) { $file = $this->filename; if ($new) $file = sprintf('%s.%s',((is_null($this->date_created) OR ! $this->date_created) ? sprintf('UNKNOWN/%07s',$this->file_path_id()) : date('Y/m/d-His',$this->date_created)),$this->type()); return (($short OR preg_match('/^\//',$file)) ? '' : config('video.dir').DIRECTORY_SEPARATOR).$file; } /** * Calculate a file path ID based on the id of the file */ public function file_path_id($sep=3,$depth=9) { return trim(chunk_split(sprintf("%0{$depth}s",$this->id),$sep,'/'),'/'); } /** * Display the file signature */ public function file_signature($short=FALSE) { return $short ? static::signaturetrim($this->file_signature) : $this->file_signature; } /** * Return the photo size */ public function file_size() { return (! is_readable($this->file_path())) ? NULL : filesize($this->file_path()); } public function getFileSizeAttribute() { return (! is_readable($this->file_path())) ? NULL : filesize($this->file_path()); } public function getDateCreatedTextAttribute() { if ($this->date_created) return date('d-m-Y H:i:s',$this->date_created); } public function getDuplicateTextAttribute() { return $this->TextTrueFalse($this->duplicate); } public function getFlagTextAttribute() { return $this->TextTrueFalse($this->flag); } /** * Return item dimensions */ public function getDimensionsAttribute() { return $this->width.'x'.$this->height; } /** * Return HTML Checkbox for duplicate */ public function getDuplicateCheckboxAttribute() { return $this->HTMLCheckbox('duplicate',$this->id,$this->duplicate); } /** * Return HTML Checkbox for flagged */ public function getFlagCheckboxAttribute() { return $this->HTMLCheckbox('flag',$this->id,$this->flag); } /** * Return HTML Checkbox for remove */ public function getRemoveCheckboxAttribute() { return $this->HTMLCheckbox('remove',$this->id,$this->remove); } /** * Display the GPS coordinates */ public function gps() { return ($this->gps_lat AND $this->gps_lon) ? sprintf('%s/%s',$this->gps_lat,$this->gps_lon) : 'UNKNOWN'; } /** * Get ID Info link */ protected function HTMLLinkAttribute($id,$url) { return sprintf('%s',url($url.$id),$id,$id); } /** * Return an HTML checkbox */ protected function HTMLCheckbox($name,$id,$value) { return sprintf('',$name,$id,$value ? ' checked="checked"' : ''); } public function isParentWritable($dir) { if (file_exists($dir) AND is_writable($dir) AND is_dir($dir)) return TRUE; elseif ($dir == dirname($dir) OR file_exists($dir)) return FALSE; else return ($this->isParentWritable(dirname($dir))); } /** * Determine if a file is moveable * * useID boolean Determine if the path is based on the the ID or date */ public function moveable() { // If the source and target are the same, we dont need to move it if ($this->file_path() == $this->file_path(FALSE,TRUE)) return FALSE; // If there is already a file in the target. // @todo If the target file is to be deleted, we could move this file if (file_exists($this->file_path(FALSE,TRUE))) return 1; // Test if the source is readable if (! is_readable($this->file_path())) return 2; // Test if the dir is writable (so we can remove the file) if (! $this->isParentWritable(dirname($this->file_path()))) return 3; // Test if the target dir is writable // @todo The target dir may not exist yet, so we should check that a parent exists and is writable. if (! $this->isParentWritable($this->file_path(FALSE,TRUE))) return 4; return TRUE; } /** * Get the id of the previous record */ public function next() { return DB::table($this->getTable()) ->where('id','>',$this->id) ->orderby('id','ASC') ->first(); } /** * Return my class shortname */ public function objectType() { return (new \ReflectionClass($this))->getShortName(); } /** * Get the id of the previous record */ public function previous() { return DB::table($this->getTable()) ->where('id','<',$this->id) ->orderby('id','DEC') ->first(); } public function setHeightWidth() { $this->height = $this->property('height'); $this->width = $this->property('width'); $this->orientation = $this->property('orientation'); } /** * Display the media signature */ public function signature($short=FALSE) { return $short ? static::signaturetrim($this->signature) : $this->signature; } public static function signaturetrim($signature,$chars=6) { return sprintf('%s...%s',substr($signature,0,$chars),substr($signature,-1*$chars)); } /** * Determine if the image should be moved */ public function shouldMove() { return ($this->filename != $this->file_path(TRUE,TRUE)); } protected function TextTrueFalse($value) { return $value ? 'TRUE' : 'FALSE'; } public function list_duplicate($includeme=FALSE) { return $this->list_duplicates($includeme)->pluck('id'); } /** * Find duplicate images based on some attributes of the current image */ public function list_duplicates($includeme=FALSE) { $o = static::select(); if ($this->id AND ! $includeme) $o->where('id','!=',$this->id); // Ignore photo's pending removal. if (! $includeme) $o->where(function($query) { $query->where('remove','!=',TRUE) ->orWhere('remove','=',NULL); }); // Where the signature is the same $o->where(function($query) { $query->where('signature','=',$this->signature); // Or they have the same time taken with the same camera if ($this->date_created AND ($this->model OR $this->make)) { $query->orWhere(function($query) { $query->where('date_created','=',$this->date_created ? $this->date_created : NULL); if (Schema::hasColumn($this->getTable(),'subsectime')) $query->where('subsectime','=',$this->subsectime ? $this->subsectime : NULL); if (! is_null($this->model)) $query->where('model','=',$this->model); if (! is_null($this->make)) $query->where('make','=',$this->make); }); } }); return $o->get(); } }