Clean up and documentation in photo_drive.
This commit is contained in:
parent
3217452b02
commit
d70bba2806
@ -1,18 +1,30 @@
|
|||||||
<?php /** @file */
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return a photo_driver object.
|
||||||
|
*
|
||||||
|
* Use this factory when manipulating images.
|
||||||
|
*
|
||||||
|
* Return a photo driver object implementing ImageMagick or GD.
|
||||||
|
*
|
||||||
|
* @param string $data Image data
|
||||||
|
* @param string $type
|
||||||
|
* @return null|photo_driver
|
||||||
|
* NULL if unsupported image type or failure, otherwise photo driver object
|
||||||
|
*/
|
||||||
function photo_factory($data, $type = null) {
|
function photo_factory($data, $type = null) {
|
||||||
$ph = null;
|
$ph = null;
|
||||||
|
$m = null;
|
||||||
|
|
||||||
|
$unsupported_types = [
|
||||||
$unsupported_types = array(
|
|
||||||
'image/bmp',
|
'image/bmp',
|
||||||
'image/vnd.microsoft.icon',
|
'image/vnd.microsoft.icon',
|
||||||
'image/tiff',
|
'image/tiff',
|
||||||
'image/svg+xml'
|
'image/svg+xml',
|
||||||
);
|
];
|
||||||
|
|
||||||
if($type && in_array(strtolower($type),$unsupported_types)) {
|
if($type && in_array(strtolower($type), $unsupported_types)) {
|
||||||
logger('photo_factory: unsupported image type');
|
logger('Unsupported image type ' . $type);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,29 +33,30 @@ function photo_factory($data, $type = null) {
|
|||||||
if(class_exists('Imagick') && !$ignore_imagick) {
|
if(class_exists('Imagick') && !$ignore_imagick) {
|
||||||
$v = Imagick::getVersion();
|
$v = Imagick::getVersion();
|
||||||
preg_match('/ImageMagick ([0-9]+\.[0-9]+\.[0-9]+)/', $v['versionString'], $m);
|
preg_match('/ImageMagick ([0-9]+\.[0-9]+\.[0-9]+)/', $v['versionString'], $m);
|
||||||
if(version_compare($m[1],'6.6.7') >= 0) {
|
if(version_compare($m[1], '6.6.7') >= 0) {
|
||||||
require_once('include/photo/photo_imagick.php');
|
require_once('include/photo/photo_imagick.php');
|
||||||
$ph = new photo_imagick($data,$type);
|
$ph = new photo_imagick($data, $type);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// earlier imagick versions have issues with scaling png's
|
// earlier imagick versions have issues with scaling png's
|
||||||
// don't log this because it will just fill the logfile.
|
// don't log this because it will just fill the logfile.
|
||||||
// leave this note here so those who are looking for why
|
// leave this note here so those who are looking for why
|
||||||
// we aren't using imagick can find it
|
// we aren't using imagick can find it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(! $ph) {
|
if(! $ph) {
|
||||||
require_once('include/photo/photo_gd.php');
|
require_once('include/photo/photo_gd.php');
|
||||||
$ph = new photo_gd($data,$type);
|
$ph = new photo_gd($data, $type);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $ph;
|
return $ph;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Abstract photo driver class.
|
||||||
|
*
|
||||||
|
*/
|
||||||
abstract class photo_driver {
|
abstract class photo_driver {
|
||||||
|
|
||||||
protected $image;
|
protected $image;
|
||||||
@ -79,12 +92,12 @@ abstract class photo_driver {
|
|||||||
|
|
||||||
public function __construct($data, $type='') {
|
public function __construct($data, $type='') {
|
||||||
$this->types = $this->supportedTypes();
|
$this->types = $this->supportedTypes();
|
||||||
if (! array_key_exists($type,$this->types)){
|
if (! array_key_exists($type, $this->types)){
|
||||||
$type='image/jpeg';
|
$type = 'image/jpeg';
|
||||||
}
|
}
|
||||||
$this->type = $type;
|
$this->type = $type;
|
||||||
$this->valid = false;
|
$this->valid = false;
|
||||||
$this->load($data,$type);
|
$this->load($data, $type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __destruct() {
|
public function __destruct() {
|
||||||
@ -99,12 +112,14 @@ abstract class photo_driver {
|
|||||||
public function getWidth() {
|
public function getWidth() {
|
||||||
if(!$this->is_valid())
|
if(!$this->is_valid())
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return $this->width;
|
return $this->width;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getHeight() {
|
public function getHeight() {
|
||||||
if(!$this->is_valid())
|
if(!$this->is_valid())
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return $this->height;
|
return $this->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,6 +127,7 @@ abstract class photo_driver {
|
|||||||
public function saveImage($path) {
|
public function saveImage($path) {
|
||||||
if(!$this->is_valid())
|
if(!$this->is_valid())
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return (file_put_contents($path, $this->imageString()) ? true : false);
|
return (file_put_contents($path, $this->imageString()) ? true : false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,12 +147,14 @@ abstract class photo_driver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief scale image
|
* @brief Scale image to max pixel size in either dimension.
|
||||||
* int $max maximum pixel size in either dimension
|
*
|
||||||
* boolean $float_height - if true allow height to float to any length on tall images,
|
* @param int $max maximum pixel size in either dimension
|
||||||
* constraining only the width
|
* @param boolean $float_height (optional)
|
||||||
|
* if true allow height to float to any length on tall images, constraining
|
||||||
|
* only the width
|
||||||
|
* @return boolean|void false on failure, otherwise void
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public function scaleImage($max, $float_height = true) {
|
public function scaleImage($max, $float_height = true) {
|
||||||
if(!$this->is_valid())
|
if(!$this->is_valid())
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -203,7 +221,6 @@ abstract class photo_driver {
|
|||||||
if(!$this->is_valid())
|
if(!$this->is_valid())
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
|
||||||
$width = $this->width;
|
$width = $this->width;
|
||||||
$height = $this->height;
|
$height = $this->height;
|
||||||
|
|
||||||
@ -241,33 +258,39 @@ abstract class photo_driver {
|
|||||||
$this->doScaleImage($dest_width,$dest_height);
|
$this->doScaleImage($dest_width,$dest_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Scales image to a square.
|
||||||
|
*
|
||||||
|
* @param int $dim Pixel of squre image
|
||||||
|
* @return boolean|void false on failure, otherwise void
|
||||||
|
*/
|
||||||
public function scaleImageSquare($dim) {
|
public function scaleImageSquare($dim) {
|
||||||
if(!$this->is_valid())
|
if(!$this->is_valid())
|
||||||
return FALSE;
|
return FALSE;
|
||||||
$this->doScaleImage($dim,$dim);
|
|
||||||
|
$this->doScaleImage($dim, $dim);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief reads exif data from filename
|
* @brief reads exif data from filename.
|
||||||
|
*
|
||||||
|
* @param string $filename
|
||||||
|
* @return boolean|array
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public function exif($filename) {
|
public function exif($filename) {
|
||||||
|
|
||||||
|
if((! function_exists('exif_read_data'))
|
||||||
if((! function_exists('exif_read_data'))
|
|
||||||
|| (! in_array($this->getType(), [ 'image/jpeg' , 'image/tiff'] ))) {
|
|| (! in_array($this->getType(), [ 'image/jpeg' , 'image/tiff'] ))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PHP 7.2 allows you to use a stream resource, which should reduce/avoid
|
* PHP 7.2 allows you to use a stream resource, which should reduce/avoid
|
||||||
* memory exhaustion on large images.
|
* memory exhaustion on large images.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if(version_compare(PHP_VERSION,'7.2.0') >= 0) {
|
if(version_compare(PHP_VERSION, '7.2.0') >= 0) {
|
||||||
$f = @fopen($filename,'rb');
|
$f = @fopen($filename, 'rb');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$f = $filename;
|
$f = $filename;
|
||||||
@ -281,21 +304,23 @@ abstract class photo_driver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief orients current image based on exif orientation information
|
* @brief Orients current image based on exif orientation information.
|
||||||
|
*
|
||||||
|
* @param array $exif
|
||||||
|
* @return boolean true if oriented, otherwise false
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public function orient($exif) {
|
public function orient($exif) {
|
||||||
|
|
||||||
if(! ($this->is_valid() && $exif)) {
|
if(! ($this->is_valid() && $exif)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$ort = ((array_key_exists('IFD0',$exif)) ? $exif['IFD0']['Orientation'] : $exif['Orientation']);
|
$ort = ((array_key_exists('IFD0', $exif)) ? $exif['IFD0']['Orientation'] : $exif['Orientation']);
|
||||||
|
|
||||||
if(! $ort) {
|
if(! $ort) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch($ort) {
|
switch($ort) {
|
||||||
case 1: // nothing
|
case 1: // nothing
|
||||||
break;
|
break;
|
||||||
@ -319,7 +344,7 @@ abstract class photo_driver {
|
|||||||
$this->flip();
|
$this->flip();
|
||||||
$this->rotate(-90);
|
$this->rotate(-90);
|
||||||
break;
|
break;
|
||||||
case 8: // 90 rotate left
|
case 8: // 90 rotate left
|
||||||
$this->rotate(90);
|
$this->rotate(90);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -329,15 +354,21 @@ abstract class photo_driver {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Save photo to database.
|
||||||
|
*
|
||||||
|
* @param array $arr
|
||||||
|
* @param boolean $skipcheck (optional) default false
|
||||||
|
* @return boolean|array
|
||||||
|
*/
|
||||||
public function save($arr, $skipcheck = false) {
|
public function save($arr, $skipcheck = false) {
|
||||||
|
|
||||||
if(! ($skipcheck || $this->is_valid())) {
|
if(! ($skipcheck || $this->is_valid())) {
|
||||||
logger('attempt to store invalid photo.');
|
logger('Attempt to store invalid photo.');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$p = array();
|
$p = [];
|
||||||
|
|
||||||
$p['aid'] = ((intval($arr['aid'])) ? intval($arr['aid']) : 0);
|
$p['aid'] = ((intval($arr['aid'])) ? intval($arr['aid']) : 0);
|
||||||
$p['uid'] = ((intval($arr['uid'])) ? intval($arr['uid']) : 0);
|
$p['uid'] = ((intval($arr['uid'])) ? intval($arr['uid']) : 0);
|
||||||
@ -351,11 +382,11 @@ abstract class photo_driver {
|
|||||||
$p['allow_gid'] = (($arr['allow_gid']) ? $arr['allow_gid'] : '');
|
$p['allow_gid'] = (($arr['allow_gid']) ? $arr['allow_gid'] : '');
|
||||||
$p['deny_cid'] = (($arr['deny_cid']) ? $arr['deny_cid'] : '');
|
$p['deny_cid'] = (($arr['deny_cid']) ? $arr['deny_cid'] : '');
|
||||||
$p['deny_gid'] = (($arr['deny_gid']) ? $arr['deny_gid'] : '');
|
$p['deny_gid'] = (($arr['deny_gid']) ? $arr['deny_gid'] : '');
|
||||||
$p['edited'] = (($arr['edited']) ? $arr['edited'] : datetime_convert());
|
$p['edited'] = (($arr['edited']) ? $arr['edited'] : datetime_convert());
|
||||||
$p['title'] = (($arr['title']) ? $arr['title'] : '');
|
$p['title'] = (($arr['title']) ? $arr['title'] : '');
|
||||||
$p['description'] = (($arr['description']) ? $arr['description'] : '');
|
$p['description'] = (($arr['description']) ? $arr['description'] : '');
|
||||||
$p['photo_usage'] = intval($arr['photo_usage']);
|
$p['photo_usage'] = intval($arr['photo_usage']);
|
||||||
$p['os_storage'] = intval($arr['os_storage']);
|
$p['os_storage'] = intval($arr['os_storage']);
|
||||||
$p['os_path'] = $arr['os_path'];
|
$p['os_path'] = $arr['os_path'];
|
||||||
$p['os_syspath'] = ((array_key_exists('os_syspath',$arr)) ? $arr['os_syspath'] : '');
|
$p['os_syspath'] = ((array_key_exists('os_syspath',$arr)) ? $arr['os_syspath'] : '');
|
||||||
$p['display_path'] = (($arr['display_path']) ? $arr['display_path'] : '');
|
$p['display_path'] = (($arr['display_path']) ? $arr['display_path'] : '');
|
||||||
@ -364,7 +395,7 @@ abstract class photo_driver {
|
|||||||
$p['expires'] = (($arr['expires']) ? $arr['expires'] : gmdate('Y-m-d H:i:s', time() + get_config('system','photo_cache_time', 86400)));
|
$p['expires'] = (($arr['expires']) ? $arr['expires'] : gmdate('Y-m-d H:i:s', time() + get_config('system','photo_cache_time', 86400)));
|
||||||
|
|
||||||
if(! intval($p['imgscale']))
|
if(! intval($p['imgscale']))
|
||||||
logger('save: ' . print_r($arr,true), LOGGER_DATA);
|
logger('save: ' . print_r($arr, true), LOGGER_DATA);
|
||||||
|
|
||||||
$x = q("select id, created from photo where resource_id = '%s' and uid = %d and xchan = '%s' and imgscale = %d limit 1",
|
$x = q("select id, created from photo where resource_id = '%s' and uid = %d and xchan = '%s' and imgscale = %d limit 1",
|
||||||
dbesc($p['resource_id']),
|
dbesc($p['resource_id']),
|
||||||
@ -372,7 +403,7 @@ abstract class photo_driver {
|
|||||||
dbesc($p['xchan']),
|
dbesc($p['xchan']),
|
||||||
intval($p['imgscale'])
|
intval($p['imgscale'])
|
||||||
);
|
);
|
||||||
|
|
||||||
if($x) {
|
if($x) {
|
||||||
$p['created'] = (($x['created']) ? $x['created'] : $p['edited']);
|
$p['created'] = (($x['created']) ? $x['created'] : $p['edited']);
|
||||||
$r = q("UPDATE photo set
|
$r = q("UPDATE photo set
|
||||||
@ -388,7 +419,7 @@ abstract class photo_driver {
|
|||||||
height = %d,
|
height = %d,
|
||||||
width = %d,
|
width = %d,
|
||||||
content = '%s',
|
content = '%s',
|
||||||
os_storage = %d,
|
os_storage = %d,
|
||||||
filesize = %d,
|
filesize = %d,
|
||||||
imgscale = %d,
|
imgscale = %d,
|
||||||
photo_usage = %d,
|
photo_usage = %d,
|
||||||
@ -463,33 +494,36 @@ abstract class photo_driver {
|
|||||||
dbescdate($p['expires'])
|
dbescdate($p['expires'])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
logger('photo save ' . $p['imgscale'] . ' returned ' . intval($r));
|
logger('Photo save ' . $p['imgscale'] . ' returned ' . intval($r));
|
||||||
|
|
||||||
return $r;
|
return $r;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Guess image mimetype from filename or from Content-Type header
|
* @brief Guess image mimetype from filename or from Content-Type header.
|
||||||
*
|
*
|
||||||
* @arg $filename string Image filename
|
* @param string $filename
|
||||||
* @arg $headers string Headers to check for Content-Type (from curl request)
|
* Image filename
|
||||||
|
* @param string $headers (optional)
|
||||||
|
* Headers to check for Content-Type (from curl request)
|
||||||
|
* @return null|string Guessed mimetype
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function guess_image_type($filename, $headers = '') {
|
function guess_image_type($filename, $headers = '') {
|
||||||
// logger('Photo: guess_image_type: '.$filename . ($headers?' from curl headers':''), LOGGER_DEBUG);
|
// logger('Photo: guess_image_type: '.$filename . ($headers?' from curl headers':''), LOGGER_DEBUG);
|
||||||
$type = null;
|
$type = null;
|
||||||
if ($headers) {
|
$m = null;
|
||||||
$hdrs=array();
|
|
||||||
$h = explode("\n",$headers);
|
if($headers) {
|
||||||
|
$hdrs = [];
|
||||||
|
$h = explode("\n", $headers);
|
||||||
foreach ($h as $l) {
|
foreach ($h as $l) {
|
||||||
list($k,$v) = array_map("trim", explode(":", trim($l), 2));
|
list($k,$v) = array_map('trim', explode(':', trim($l), 2));
|
||||||
$hdrs[strtolower($k)] = $v;
|
$hdrs[strtolower($k)] = $v;
|
||||||
}
|
}
|
||||||
logger('Curl headers: '.var_export($hdrs, true), LOGGER_DEBUG);
|
logger('Curl headers: ' .var_export($hdrs, true), LOGGER_DEBUG);
|
||||||
if (array_key_exists('content-type', $hdrs)) {
|
if(array_key_exists('content-type', $hdrs)) {
|
||||||
$ph = photo_factory('');
|
$ph = photo_factory('');
|
||||||
$types = $ph->supportedTypes();
|
$types = $ph->supportedTypes();
|
||||||
|
|
||||||
@ -498,13 +532,13 @@ function guess_image_type($filename, $headers = '') {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_null($type)){
|
if(is_null($type)){
|
||||||
$ignore_imagick = get_config('system', 'ignore_imagick');
|
$ignore_imagick = get_config('system', 'ignore_imagick');
|
||||||
// Guessing from extension? Isn't that... dangerous?
|
// Guessing from extension? Isn't that... dangerous?
|
||||||
if(class_exists('Imagick') && file_exists($filename) && is_readable($filename) && !$ignore_imagick) {
|
if(class_exists('Imagick') && file_exists($filename) && is_readable($filename) && !$ignore_imagick) {
|
||||||
$v = Imagick::getVersion();
|
$v = Imagick::getVersion();
|
||||||
preg_match('/ImageMagick ([0-9]+\.[0-9]+\.[0-9]+)/', $v['versionString'], $m);
|
preg_match('/ImageMagick ([0-9]+\.[0-9]+\.[0-9]+)/', $v['versionString'], $m);
|
||||||
if(version_compare($m[1],'6.6.7') >= 0) {
|
if(version_compare($m[1], '6.6.7') >= 0) {
|
||||||
/**
|
/**
|
||||||
* Well, this not much better,
|
* Well, this not much better,
|
||||||
* but at least it comes from the data inside the image,
|
* but at least it comes from the data inside the image,
|
||||||
@ -516,7 +550,7 @@ function guess_image_type($filename, $headers = '') {
|
|||||||
else {
|
else {
|
||||||
// earlier imagick versions have issues with scaling png's
|
// earlier imagick versions have issues with scaling png's
|
||||||
// don't log this because it will just fill the logfile.
|
// don't log this because it will just fill the logfile.
|
||||||
// leave this note here so those who are looking for why
|
// leave this note here so those who are looking for why
|
||||||
// we aren't using imagick can find it
|
// we aren't using imagick can find it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -551,33 +585,36 @@ function guess_image_type($filename, $headers = '') {
|
|||||||
|
|
||||||
}
|
}
|
||||||
logger('Photo: guess_image_type: filename = ' . $filename . ' type = ' . $type, LOGGER_DEBUG);
|
logger('Photo: guess_image_type: filename = ' . $filename . ' type = ' . $type, LOGGER_DEBUG);
|
||||||
return $type;
|
|
||||||
|
|
||||||
|
return $type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
function delete_thing_photo($url,$ob_hash) {
|
* @brief Delete thing photo from database.
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
* @param string $ob_hash
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function delete_thing_photo($url, $ob_hash) {
|
||||||
|
|
||||||
$hash = basename($url);
|
$hash = basename($url);
|
||||||
$hash = substr($hash,0,strpos($hash,'-'));
|
$hash = substr($hash, 0, strpos($hash, '-'));
|
||||||
|
|
||||||
// hashes should be 32 bytes.
|
// hashes should be 32 bytes.
|
||||||
|
|
||||||
if((! $ob_hash) || (strlen($hash) < 16))
|
if((! $ob_hash) || (strlen($hash) < 16))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
$r = q("delete from photo where xchan = '%s' and photo_usage = %d and resource_id = '%s'",
|
q("delete from photo where xchan = '%s' and photo_usage = %d and resource_id = '%s'",
|
||||||
dbesc($ob_hash),
|
dbesc($ob_hash),
|
||||||
intval(PHOTO_THING),
|
intval(PHOTO_THING),
|
||||||
dbesc($hash)
|
dbesc($hash)
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief fetches an photo from external site and prepares its miniatures.
|
* @brief Fetches a photo from external site and prepares its miniatures.
|
||||||
*
|
*
|
||||||
* @param string $photo
|
* @param string $photo
|
||||||
* external URL to fetch base image
|
* external URL to fetch base image
|
||||||
@ -596,223 +633,215 @@ function delete_thing_photo($url,$ob_hash) {
|
|||||||
* * \e boolean \b 4 => TRUE if fetch failure
|
* * \e boolean \b 4 => TRUE if fetch failure
|
||||||
* * \e string \b 5 => modification date
|
* * \e string \b 5 => modification date
|
||||||
*/
|
*/
|
||||||
|
function import_xchan_photo($photo, $xchan, $thing = false, $force = false) {
|
||||||
|
$modified = '';
|
||||||
|
$o = null;
|
||||||
|
|
||||||
function import_xchan_photo($photo,$xchan,$thing = false,$force = false) {
|
$flags = (($thing) ? PHOTO_THING : PHOTO_XCHAN);
|
||||||
|
$album = (($thing) ? 'Things' : 'Contact Photos');
|
||||||
|
|
||||||
$modified = '';
|
logger('Updating channel photo from ' . $photo . ' for ' . $xchan, LOGGER_DEBUG);
|
||||||
|
|
||||||
$flags = (($thing) ? PHOTO_THING : PHOTO_XCHAN);
|
if($thing) {
|
||||||
$album = (($thing) ? 'Things' : 'Contact Photos');
|
$hash = photo_new_resource();
|
||||||
|
} else {
|
||||||
|
$r = q("select resource_id, edited, mimetype from photo where xchan = '%s' and photo_usage = %d and imgscale = 4 limit 1", dbesc($xchan), intval(PHOTO_XCHAN));
|
||||||
|
if($r) {
|
||||||
|
$hash = $r[0]['resource_id'];
|
||||||
|
$modified = $r[0]['edited'];
|
||||||
|
$type = $r[0]['mimetype'];
|
||||||
|
} else {
|
||||||
|
$hash = photo_new_resource();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
logger('import_xchan_photo: updating channel photo from ' . $photo . ' for ' . $xchan, LOGGER_DEBUG);
|
$photo_failure = false;
|
||||||
|
$img_str = '';
|
||||||
if($thing) {
|
|
||||||
$hash = photo_new_resource();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$r = q("select resource_id, edited, mimetype from photo where xchan = '%s' and photo_usage = %d and imgscale = 4 limit 1",
|
|
||||||
dbesc($xchan),
|
|
||||||
intval(PHOTO_XCHAN)
|
|
||||||
);
|
|
||||||
if($r) {
|
|
||||||
$hash = $r[0]['resource_id'];
|
|
||||||
$modified = $r[0]['edited'];
|
|
||||||
$type = $r[0]['mimetype'];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$hash = photo_new_resource();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$photo_failure = false;
|
|
||||||
$img_str = '';
|
|
||||||
|
|
||||||
if($photo) {
|
|
||||||
$filename = basename($photo);
|
|
||||||
|
|
||||||
if($force || $modified == '') {
|
|
||||||
$result = z_fetch_url($photo,true);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$h = array('headers' => array("If-Modified-Since: " . gmdate("D, d M Y H:i:s", strtotime($modified . "Z")) . " GMT"));
|
|
||||||
$result = z_fetch_url($photo,true,0,$h);
|
|
||||||
}
|
|
||||||
|
|
||||||
if($result['success']) {
|
|
||||||
$img_str = $result['body'];
|
|
||||||
$type = guess_image_type($photo, $result['header']);
|
|
||||||
$modified = gmdate('Y-m-d H:i:s', (preg_match('/last-modified: (.+) \S+/i', $result['header'], $o) ? strtotime($o[1] . 'Z') : time()));
|
|
||||||
if(is_null($type))
|
|
||||||
$photo_failure = true;
|
|
||||||
}
|
|
||||||
elseif($result['return_code'] == 304) {
|
|
||||||
$photo = z_root() . '/photo/' . $hash . '-4';
|
|
||||||
$thumb = z_root() . '/photo/' . $hash . '-5';
|
|
||||||
$micro = z_root() . '/photo/' . $hash . '-6';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$photo_failure = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
$photo_failure = true;
|
|
||||||
|
|
||||||
if(! $photo_failure && $result['return_code'] != 304) {
|
|
||||||
$img = photo_factory($img_str, $type);
|
|
||||||
if($img->is_valid()) {
|
|
||||||
$width = $img->getWidth();
|
|
||||||
$height = $img->getHeight();
|
|
||||||
|
|
||||||
if($width && $height) {
|
|
||||||
if(($width / $height) > 1.2) {
|
|
||||||
// crop out the sides
|
|
||||||
$margin = $width - $height;
|
|
||||||
$img->cropImage(300,($margin / 2),0,$height,$height);
|
|
||||||
}
|
|
||||||
elseif(($height / $width) > 1.2) {
|
|
||||||
// crop out the bottom
|
|
||||||
$margin = $height - $width;
|
|
||||||
$img->cropImage(300,0,0,$width,$width);
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$img->scaleImageSquare(300);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
$photo_failure = true;
|
|
||||||
|
|
||||||
$p = array(
|
|
||||||
'xchan' => $xchan,
|
|
||||||
'resource_id' => $hash,
|
|
||||||
'filename' => basename($photo),
|
|
||||||
'album' => $album,
|
|
||||||
'photo_usage' => $flags,
|
|
||||||
'imgscale' => 4,
|
|
||||||
'edited' => $modified
|
|
||||||
);
|
|
||||||
|
|
||||||
$r = $img->save($p);
|
|
||||||
|
|
||||||
if($r === false)
|
|
||||||
$photo_failure = true;
|
|
||||||
|
|
||||||
$img->scaleImage(80);
|
|
||||||
$p['imgscale'] = 5;
|
|
||||||
|
|
||||||
$r = $img->save($p);
|
|
||||||
|
|
||||||
if($r === false)
|
|
||||||
$photo_failure = true;
|
|
||||||
|
|
||||||
$img->scaleImage(48);
|
|
||||||
$p['imgscale'] = 6;
|
|
||||||
|
|
||||||
$r = $img->save($p);
|
|
||||||
|
|
||||||
if($r === false)
|
|
||||||
$photo_failure = true;
|
|
||||||
|
|
||||||
$photo = z_root() . '/photo/' . $hash . '-4';
|
|
||||||
$thumb = z_root() . '/photo/' . $hash . '-5';
|
|
||||||
$micro = z_root() . '/photo/' . $hash . '-6';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
logger('import_xchan_photo: invalid image from ' . $photo);
|
|
||||||
$photo_failure = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if($photo_failure) {
|
|
||||||
$default = get_default_profile_photo();
|
|
||||||
$photo = z_root() . '/' . $default;
|
|
||||||
$thumb = z_root() . '/' . get_default_profile_photo(80);
|
|
||||||
$micro = z_root() . '/' . get_default_profile_photo(48);
|
|
||||||
$type = 'image/png';
|
|
||||||
$modified = gmdate('Y-m-d H:i:s', filemtime($default));
|
|
||||||
}
|
|
||||||
|
|
||||||
logger('HTTP code: ' . $result['return_code'] . '; modified: ' . $modified . '; failure: ' . ($photo_failure ? 'yes' : 'no') . '; URL: ' . $photo, LOGGER_DEBUG);
|
|
||||||
return(array($photo,$thumb,$micro,$type,$photo_failure,$modified));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function import_channel_photo_from_url($photo,$aid,$uid) {
|
|
||||||
|
|
||||||
if($photo) {
|
if($photo) {
|
||||||
$filename = basename($photo);
|
|
||||||
|
|
||||||
$result = z_fetch_url($photo,true);
|
if($force || $modified == '') {
|
||||||
|
$result = z_fetch_url($photo, true);
|
||||||
|
} else {
|
||||||
|
$h = [
|
||||||
|
'headers' => [
|
||||||
|
'If-Modified-Since: ' . gmdate('D, d M Y H:i:s', strtotime($modified . 'Z')) . ' GMT'
|
||||||
|
]
|
||||||
|
];
|
||||||
|
$result = z_fetch_url($photo, true, 0, $h);
|
||||||
|
}
|
||||||
|
|
||||||
|
if($result['success']) {
|
||||||
|
$img_str = $result['body'];
|
||||||
|
$type = guess_image_type($photo, $result['header']);
|
||||||
|
$modified = gmdate('Y-m-d H:i:s', (preg_match('/last-modified: (.+) \S+/i', $result['header'], $o) ? strtotime($o[1] . 'Z') : time()));
|
||||||
|
if(is_null($type))
|
||||||
|
$photo_failure = true;
|
||||||
|
} elseif($result['return_code'] == 304) {
|
||||||
|
$photo = z_root() . '/photo/' . $hash . '-4';
|
||||||
|
$thumb = z_root() . '/photo/' . $hash . '-5';
|
||||||
|
$micro = z_root() . '/photo/' . $hash . '-6';
|
||||||
|
} else {
|
||||||
|
$photo_failure = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$photo_failure = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$photo_failure && $result['return_code'] != 304) {
|
||||||
|
$img = photo_factory($img_str, $type);
|
||||||
|
if($img->is_valid()) {
|
||||||
|
$width = $img->getWidth();
|
||||||
|
$height = $img->getHeight();
|
||||||
|
|
||||||
|
if($width && $height) {
|
||||||
|
if(($width / $height) > 1.2) {
|
||||||
|
// crop out the sides
|
||||||
|
$margin = $width - $height;
|
||||||
|
$img->cropImage(300, ($margin / 2), 0, $height, $height);
|
||||||
|
} elseif(($height / $width) > 1.2) {
|
||||||
|
// crop out the bottom
|
||||||
|
$margin = $height - $width;
|
||||||
|
$img->cropImage(300, 0, 0, $width, $width);
|
||||||
|
} else {
|
||||||
|
$img->scaleImageSquare(300);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$photo_failure = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$p = [
|
||||||
|
'xchan' => $xchan,
|
||||||
|
'resource_id' => $hash,
|
||||||
|
'filename' => basename($photo),
|
||||||
|
'album' => $album,
|
||||||
|
'photo_usage' => $flags,
|
||||||
|
'imgscale' => 4,
|
||||||
|
'edited' => $modified,
|
||||||
|
];
|
||||||
|
|
||||||
|
$r = $img->save($p);
|
||||||
|
if($r === false)
|
||||||
|
$photo_failure = true;
|
||||||
|
|
||||||
|
$img->scaleImage(80);
|
||||||
|
$p['imgscale'] = 5;
|
||||||
|
$r = $img->save($p);
|
||||||
|
if($r === false)
|
||||||
|
$photo_failure = true;
|
||||||
|
|
||||||
|
$img->scaleImage(48);
|
||||||
|
$p['imgscale'] = 6;
|
||||||
|
$r = $img->save($p);
|
||||||
|
if($r === false)
|
||||||
|
$photo_failure = true;
|
||||||
|
|
||||||
|
$photo = z_root() . '/photo/' . $hash . '-4';
|
||||||
|
$thumb = z_root() . '/photo/' . $hash . '-5';
|
||||||
|
$micro = z_root() . '/photo/' . $hash . '-6';
|
||||||
|
} else {
|
||||||
|
logger('Invalid image from ' . $photo);
|
||||||
|
$photo_failure = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if($photo_failure) {
|
||||||
|
$default = get_default_profile_photo();
|
||||||
|
$photo = z_root() . '/' . $default;
|
||||||
|
$thumb = z_root() . '/' . get_default_profile_photo(80);
|
||||||
|
$micro = z_root() . '/' . get_default_profile_photo(48);
|
||||||
|
$type = 'image/png';
|
||||||
|
$modified = gmdate('Y-m-d H:i:s', filemtime($default));
|
||||||
|
}
|
||||||
|
|
||||||
|
logger('HTTP code: ' . $result['return_code'] . '; modified: ' . $modified
|
||||||
|
. '; failure: ' . ($photo_failure ? 'yes' : 'no') . '; URL: ' . $photo, LOGGER_DEBUG);
|
||||||
|
|
||||||
|
return(array($photo,$thumb,$micro,$type,$photo_failure,$modified));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Import channel photo from a URL.
|
||||||
|
*
|
||||||
|
* @param string $photo URL to a photo
|
||||||
|
* @param int $aid
|
||||||
|
* @param int $uid channel_id
|
||||||
|
* @return null|string Guessed image mimetype or null.
|
||||||
|
*/
|
||||||
|
function import_channel_photo_from_url($photo, $aid, $uid) {
|
||||||
|
$type = null;
|
||||||
|
|
||||||
|
if($photo) {
|
||||||
|
$result = z_fetch_url($photo, true);
|
||||||
|
|
||||||
if($result['success']) {
|
if($result['success']) {
|
||||||
$img_str = $result['body'];
|
$img_str = $result['body'];
|
||||||
$type = guess_image_type($photo, $result['header']);
|
$type = guess_image_type($photo, $result['header']);
|
||||||
|
|
||||||
if(is_null($type))
|
import_channel_photo($img_str, $type, $aid, $uid);
|
||||||
$photo_failure = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
$photo_failure = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
import_channel_photo($img_str,$type,$aid,$uid);
|
|
||||||
|
|
||||||
return $type;
|
return $type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Import a channel photo and prepare its miniatures.
|
||||||
|
*
|
||||||
|
* @param string $photo Image data
|
||||||
|
* @param string $type
|
||||||
|
* @param int $aid
|
||||||
|
* @param int $uid channel_id
|
||||||
|
* @return boolean|string false on failure, otherwise resource_id of photo
|
||||||
|
*/
|
||||||
|
function import_channel_photo($photo, $type, $aid, $uid) {
|
||||||
|
|
||||||
function import_channel_photo($photo,$type,$aid,$uid) {
|
logger('Importing channel photo for ' . $uid, LOGGER_DEBUG);
|
||||||
|
|
||||||
logger('import_channel_photo: importing channel photo for ' . $uid, LOGGER_DEBUG);
|
|
||||||
|
|
||||||
$hash = photo_new_resource();
|
|
||||||
|
|
||||||
$photo_failure = false;
|
$photo_failure = false;
|
||||||
|
$hash = photo_new_resource();
|
||||||
|
|
||||||
$filename = $hash;
|
$filename = $hash;
|
||||||
|
|
||||||
$img = photo_factory($photo, $type);
|
$img = photo_factory($photo, $type);
|
||||||
if($img->is_valid()) {
|
if($img->is_valid()) {
|
||||||
|
|
||||||
|
// config array for image save method
|
||||||
|
$p = [
|
||||||
|
'aid' => $aid,
|
||||||
|
'uid' => $uid,
|
||||||
|
'resource_id' => $hash,
|
||||||
|
'filename' => $filename,
|
||||||
|
'album' => t('Profile Photos'),
|
||||||
|
'photo_usage' => PHOTO_PROFILE,
|
||||||
|
'imgscale' => 4,
|
||||||
|
];
|
||||||
|
|
||||||
|
// photo size
|
||||||
$img->scaleImageSquare(300);
|
$img->scaleImageSquare(300);
|
||||||
|
|
||||||
$p = array('aid' => $aid, 'uid' => $uid, 'resource_id' => $hash, 'filename' => $filename, 'album' => t('Profile Photos'), 'photo_usage' => PHOTO_PROFILE, 'imgscale' => 4);
|
|
||||||
|
|
||||||
$r = $img->save($p);
|
$r = $img->save($p);
|
||||||
|
|
||||||
if($r === false)
|
if($r === false)
|
||||||
$photo_failure = true;
|
$photo_failure = true;
|
||||||
|
|
||||||
|
// thumb size
|
||||||
$img->scaleImage(80);
|
$img->scaleImage(80);
|
||||||
$p['imgscale'] = 5;
|
$p['imgscale'] = 5;
|
||||||
|
|
||||||
$r = $img->save($p);
|
$r = $img->save($p);
|
||||||
|
|
||||||
if($r === false)
|
if($r === false)
|
||||||
$photo_failure = true;
|
$photo_failure = true;
|
||||||
|
|
||||||
|
// micro size
|
||||||
$img->scaleImage(48);
|
$img->scaleImage(48);
|
||||||
$p['imgscale'] = 6;
|
$p['imgscale'] = 6;
|
||||||
|
|
||||||
$r = $img->save($p);
|
$r = $img->save($p);
|
||||||
|
|
||||||
if($r === false)
|
if($r === false)
|
||||||
$photo_failure = true;
|
$photo_failure = true;
|
||||||
|
|
||||||
}
|
} else {
|
||||||
else {
|
logger('Invalid image.');
|
||||||
logger('import_channel_photo: invalid image.');
|
|
||||||
$photo_failure = true;
|
$photo_failure = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//return(($photo_failure)? false : true);
|
|
||||||
|
|
||||||
if($photo_failure)
|
if($photo_failure)
|
||||||
return false;
|
return false;
|
||||||
else
|
else
|
||||||
return $hash;
|
return $hash;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user