Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Fri, Feb 7, 9:13 AM

in-portal

Index: branches/RC/core/units/general/helpers/image_helper.php
===================================================================
--- branches/RC/core/units/general/helpers/image_helper.php (revision 9650)
+++ branches/RC/core/units/general/helpers/image_helper.php (revision 9651)
@@ -1,415 +1,366 @@
<?php
class ImageHelper extends kHelper {
+ /**
+ * Parses format string into array
+ *
+ * @param string $format sample format: "resize:300x500;wm:inc/wm.png|c|-20"
+ * @return Array sample result: Array('max_width' => 300, 'max_height' => 500, 'wm_filename' => 'inc/wm.png', 'h_margin' => 'c', 'v_margin' => -20)
+ */
function parseFormat($format)
{
- // resize:300x500;wm:inc/wm.png|c|-20
- // Array('max_width' => 300, 'max_height' => 500, 'wm_filename' => 'inc/wm.png', 'h_margin' => 'c', 'v_margin' => -20)
$format_parts = explode(';', $format);
foreach ($format_parts as $format_part) {
if (preg_match('/resize:(\d*)x(\d*)/', $format_part, $regs)) {
$res['max_width'] = $regs[1];
$res['max_height'] = $regs[2];
}
elseif (preg_match('/wm:([^\|]*)\|([^\|]*)\|([^\|]*)/', $format_part, $regs)) {
$res['wm_filename'] = FULL_PATH.THEMES_PATH.'/'.$regs[1];
$res['h_margin'] = $regs[2];
$res['v_margin'] = $regs[3];
}
}
+
+ return $res;
}
+
/**
* Resized given image to required dimensions & saves resized image to "resized" subfolder in source image folder
*
* @param string $src_image full path to image (on server)
* @param mixed $max_width maximal allowed resized image width or false if no limit
* @param mixed $max_height maximal allowed resized image height or false if no limit
* @return string direct url to resized image
*/
function ResizeImage($src_image, $max_width, $max_height = null)
{
if(isset($max_height)) {
$params['max_height'] = $max_height;
$params['max_width'] = $max_width;
}
else {
$params = $this->parseFormat($max_width);
}
+
if ($params['max_width'] > 0 || $params['max_height'] > 0) {
list ($params['max_width'], $params['max_height'], $needs_resize) = $this->GetImageDimensions($src_image, $params['max_width'], $params['max_height']);
- $src_path = dirname($src_image);
+
+ $src_path = dirname($src_image);
$dst_image = preg_replace('/^'.preg_quote($src_path, '/').'(.*)\.(.*)$/', $src_path.'/resized\\1_'.crc32(serialize($params)).'.\\2', $src_image);
+
if ($needs_resize || array_key_exists('wm_filename', $params) && $params['wm_filename']) {
+
if (!file_exists($dst_image) || filemtime($src_image) > filemtime($dst_image)) {
// resized image not available OR should be recreated due source image change
$params['dst_image'] = $dst_image;
$image_resized = $this->ScaleImage($src_image, $params);
if (!$image_resized) {
// resize failed, because of server error
$dst_image = $src_image;
}
- // resize ok
+ // resize ok
+
}
}
- $src_image = $dst_image;
- }
+ $src_image = $dst_image;
+ }
$base_url = rtrim($this->Application->BaseURL(), '/');
return preg_replace('/^'.preg_quote(FULL_PATH, '/').'(.*)/', $base_url.'\\1', $src_image);
}
/**
* Proportionally resizes given image to destination dimensions
*
* @param string $src_image full path to source image (already existing)
* @param string $dst_image full path to destination image (will be created)
* @param int $dst_width destination image width (in pixels)
* @param int $dst_height destination image height (in pixels)
*/
function ScaleImage($src_image, $params)
{
$image_info = $this->getImageInfo($src_image);
if (!$image_info) {
return false;
}
/* list ($params['max_width'], $params['max_height'], $resized) = $this->GetImageDimensions($src_image, $params['max_width'], $params['max_height']);
if (!$resized) {
// image dimensions are smaller or equals to required dimensions
return false;
}*/
if (function_exists('imagecreatefromjpeg')) {
// try to resize using GD
$resize_map = Array (
'image/jpeg' => 'imagecreatefromjpeg:imagejpeg:jpg',
'image/gif' => 'imagecreatefromgif:imagegif:gif',
'image/png' => 'imagecreatefrompng:imagepng:png',
);
$mime_type = $image_info['mime'];
if (!isset($resize_map[$mime_type])) {
return false;
}
list ($read_function, $write_function, $file_extension) = explode(':', $resize_map[$mime_type]);
$src_image_rs = @$read_function($src_image);
if ($src_image_rs) {
$dst_image_rs = imagecreatetruecolor($params['max_width'], $params['max_height']);
if ($file_extension == 'png') {
// preserve transparency of PNG images
$transparent_color = imagecolorallocate($dst_image_rs, 0, 0, 0);
imagecolortransparent($dst_image_rs, $transparent_color);
}
imagecopyresampled($dst_image_rs, $src_image_rs, 0, 0, 0, 0, $params['max_width'], $params['max_height'], $image_info[0], $image_info[1]);
if(array_key_exists('wm_filename', $params) && $params['wm_filename'] && file_exists($params['wm_filename']))
{
$logo_img = imagecreatefrompng($params['wm_filename']);
list($logo_width, $logo_height) = getimagesize($params['wm_filename']);
+
//if(($params['max_width'] > $logo_width * 2) && ($params['max_height'] > $logo_height * 2))
//{
imagealphablending($dst_image_rs, true);
//imagecopy($dst_image_rs, $logo_img, $params['max_width'] - $logo_width - $right_margin, $params['max_height'] - $logo_height - $bottom_margin, 0, 0, $logo_width, $logo_height);
+
if ($params['h_margin'] == 'c') {
$x_position = round($params['max_width']/2 - $logo_width/2);
}
elseif ($params['h_margin'] >= 0) {
$x_position = $params['h_margin'];
}
else {
$x_position = $params['max_width'] - (-$params['h_margin'] + $logo_width);
}
+
if ($params['v_margin'] == 'c') {
$y_position = round($params['max_height']/2 - $logo_height/2);
}
elseif ($params['v_margin'] >= 0) {
$y_position = $params['v_margin'];
}
else {
$y_position = $params['max_height'] - (-$params['v_margin'] + $logo_height);
}
+
imagecopy($dst_image_rs, $logo_img, $x_position, $y_position, 0, 0, $logo_width, $logo_height);
//}
}
+
return @$write_function($dst_image_rs, $params['dst_image'], 100);
}
}
else {
// try to resize using ImageMagick
exec('/usr/bin/convert '.$src_image.' -resize '.$params['max_width'].'x'.$params['max_height'].' '.$params['dst_image'], $shell_output, $exec_status);
return $exec_status == 0;
}
return false;
}
/**
* Returns destination image size without actual resizing (useful for <img .../> HTML tag)
*
* @param string $src_image full path to source image (already existing)
* @param int $dst_width destination image width (in pixels)
* @param int $dst_height destination image height (in pixels)
* @return Array resized image dimensions (0 - width, 1 - height)
*/
function GetImageDimensions($src_image, $dst_width, $dst_height)
{
$image_info = $this->getImageInfo($src_image);
if (!$image_info) {
return false;
}
$orig_width = $image_info[0];
$orig_height = $image_info[1];
$too_large = is_numeric($dst_width) ? ($orig_width > $dst_width) : false;
$too_large = $too_large || (is_numeric($dst_height) ? ($orig_height > $dst_height) : false);
if ($too_large) {
$width_ratio = $dst_width ? $dst_width / $orig_width : 1;
$height_ratio = $dst_height ? $dst_height / $orig_height : 1;
$ratio = min($width_ratio, $height_ratio);
$width = ceil($orig_width * $ratio);
$height = ceil($orig_height * $ratio);
}
else {
$width = $orig_width;
$height = $orig_height;
}
return Array ($width, $height, $too_large);
}
/**
* Returns image dimensions + checks if given file is existing image
*
* @param string $src_image full path to source image (already existing)
* @return mixed
*/
function getImageInfo($src_image)
{
if (!file_exists($src_image)) {
return false;
}
$image_info = @getimagesize($src_image);
if (!$image_info) {
trigger_error('Image <b>'.$src_image.'</b> <span class="debug_error">missing or invalid</span>', E_USER_WARNING);
return false;
}
return $image_info;
}
/**
* Returns maximal image size (width & height) among fields specified
*
* @param kDBItem $object
* @param string $fields
* @param string $format any format, that returns full url (e.g. files_resized:WxH, resize:WxH, full_url, full_urls)
* @return string
*/
function MaxImageSize(&$object, $fields, $format = null)
{
static $cached_sizes = Array ();
$cache_key = $object->getPrefixSpecial().'_'.$object->GetID();
if (!isset($cached_sizes[$cache_key])) {
$images = Array ();
$fields = explode(',', $fields);
foreach ($fields as $field) {
$image_data = $object->GetField($field, $format);
if (!$image_data) {
continue;
}
$images = array_merge($images, explode('|', $image_data));
}
$max_width = 0;
$max_height = 0;
$base_url = rtrim($this->Application->BaseURL(), '/');
foreach ($images as $image_url) {
$image_path = preg_replace('/^'.preg_quote($base_url, '/').'(.*)/', FULL_PATH.'\\1', $image_url);
$image_info = $this->getImageInfo($image_path);
$max_width = max($max_width, $image_info[0]);
$max_height = max($max_height, $image_info[1]);
}
$cached_sizes[$cache_key] = Array ($max_width, $max_height);
}
return $cached_sizes[$cache_key];
}
/**
- * Determines what image fields should be created (from post or just dummy fields for 1st upload)
- *
- * @param string $prefix
- */
- function createItemImages($prefix)
- {
- $items_info = $this->Application->GetVar($prefix);
- if ($items_info) {
- list ($id, $fields_values) = each($items_info);
- $this->createImageFields($prefix, $fields_values);
- }
- else {
- $this->createImageFields($prefix, Array());
- }
- }
- /**
- * Dynamically creates virtual fields for item for each image field in submit
- *
- * @param string $prefix
- * @param Array $fields_values
- */
- function createImageFields($prefix, $fields_values)
- {
- $field_options = Array (
- 'type' => 'string',
- 'formatter' => 'kPictureFormatter',
-// 'skip_empty' => 1,
- 'max_len' => 240,
- 'default' => '',
- 'not_null' => 1,
- 'include_path' => 1,
- 'allowed_types' => Array ('image/jpeg', 'image/pjpeg', 'image/png', 'image/gif', 'image/bmp'),
- 'error_msgs' => Array (
- 'bad_file_format' => '!la_error_InvalidFileFormat!',
- 'bad_file_size' => '!la_error_FileTooLarge!',
- 'cant_save_file' => '!la_error_cant_save_file!'
- ),
- );
- $fields = $this->Application->getUnitOption($prefix, 'Fields');
- $virtual_fields = $this->Application->getUnitOption($prefix, 'VirtualFields');
- $image_count = 0;
- foreach ($fields_values as $field_name => $field_value) {
- if (preg_match('/^(Image[\d]+|PrimaryImage)$/', $field_name)) {
- $fields[$field_name] = $field_options;
- $virtual_fields[$field_name] = $field_options;
- $virtual_fields['Delete'.$field_name] = Array ('type' => 'int', 'not_null' => 1, 'default' => 0);
- $image_count++;
- }
- }
- if (!$image_count) {
- // no images found in POST -> create default image fields
- $image_names = Array ('PrimaryImage' => '');
- $image_count = $this->Application->ConfigValue($prefix.'_MaxImageCount');
- $created_count = 1;
- while ($created_count < $image_count) {
- $image_names['Image'.$created_count] = '';
- $created_count++;
- }
- $this->createImageFields($prefix, $image_names);
- return ;
- }
- $this->Application->setUnitOption($prefix, 'ImageCount', $image_count);
- $this->Application->setUnitOption($prefix, 'Fields', $fields);
- $this->Application->setUnitOption($prefix, 'VirtualFields', $virtual_fields);
- }
- /**
* Puts existing item images (from subitem) to virtual fields (in main item)
*
* @param kCatDBItem $object
*/
function LoadItemImages(&$object)
{
$max_image_count = $this->Application->ConfigValue($object->Prefix.'_MaxImageCount');
$sql = 'SELECT *
FROM '.TABLE_PREFIX.'Images
WHERE ResourceId = '.$object->GetDBField('ResourceId').'
ORDER BY ImageId ASC
LIMIT 0, '.(int)$max_image_count;
$item_images = $this->Conn->Query($sql);
$image_counter = 1;
foreach ($item_images as $item_image) {
$image_path = $item_image['ThumbPath'];
if ($item_image['DefaultImg'] == 1 || $item_image['Name'] == 'main') {
// process primary image separately
$object->SetDBField('PrimaryImage', $image_path);
$object->SetOriginalField('PrimaryImage', $image_path);
$object->Fields['PrimaryImage']['original_field'] = $item_image['Name'];
continue;
}
$object->SetDBField('Image'.$image_counter, $image_path);
$object->SetOriginalField('Image'.$image_counter, $image_path);
$object->Fields['Image'.$image_counter]['original_field'] = $item_image['Name'];
$image_counter++;
}
}
/**
* Saves newly uploaded images to external image table
*
* @param kCatDBItem $object
*/
function SaveItemImages(&$object)
{
$table_name = $this->Application->getUnitOption('img', 'TableName');
$max_image_count = $this->Application->getUnitOption($object->Prefix, 'ImageCount'); // $this->Application->ConfigValue($object->Prefix.'_MaxImageCount');
$i = 0;
while ($i < $max_image_count) {
$field = $i ? 'Image'.$i : 'PrimaryImage';
$field_options = $object->GetFieldOptions($field);
$image_src = $object->GetDBField($field);
if ($image_src) {
if (isset($field_options['original_field'])) {
$key_clause = 'Name = '.$this->Conn->qstr($field_options['original_field']).' AND ResourceId = '.$object->GetDBField('ResourceId');
if ($object->GetDBField('Delete'.$field)) {
// if item was cloned, then new filename is in db (not in $image_src)
$sql = 'SELECT ThumbPath
FROM '.$table_name.'
WHERE '.$key_clause;
$image_src = $this->Conn->GetOne($sql);
if (@unlink(FULL_PATH.$image_src)) {
$sql = 'DELETE FROM '.$table_name.'
WHERE '.$key_clause;
$this->Conn->Query($sql);
}
}
else {
// image record found -> update
$fields_hash = Array (
'ThumbPath' => $image_src,
);
$this->Conn->doUpdate($fields_hash, $table_name, $key_clause);
}
}
else {
// image record not found -> create
$fields_hash = Array (
'ResourceId' => $object->GetDBField('ResourceId'),
'Name' => $field,
'AltName' => $field,
'Enabled' => STATUS_ACTIVE,
'DefaultImg' => $i ? 0 : 1, // first image is primary, others not primary
'ThumbPath' => $image_src,
);
$this->Conn->doInsert($fields_hash, $table_name);
$field_options['original_field'] = $field;
$object->SetFieldOptions($field, $field_options);
}
}
$i++;
}
}
}
?>
\ No newline at end of file
Property changes on: branches/RC/core/units/general/helpers/image_helper.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.6.2.7
\ No newline at end of property
+1.6.2.8
\ No newline at end of property

Event Timeline