Index: branches/5.2.x/core/kernel/utility/formatters/upload_formatter.php
===================================================================
diff -u -r15729 -r15733
--- branches/5.2.x/core/kernel/utility/formatters/upload_formatter.php (.../upload_formatter.php) (revision 15729)
+++ branches/5.2.x/core/kernel/utility/formatters/upload_formatter.php (.../upload_formatter.php) (revision 15733)
@@ -1,6 +1,6 @@
_getMaxFiles($options);
+ $pending_actions = $object->getPendingActions();
+ $files_to_delete = $this->_getFilesToDelete($object);
- // don't delete uploaded file, when it's name matches delete file name
- $files_to_delete = Array ();
- $var_name = $object->getPendingActionVariableName();
- $schedule = $this->Application->RecallVar($var_name);
- $schedule = $schedule ? unserialize($schedule) : Array ();
-
- foreach ($schedule as $data) {
- if ( $data['action'] == 'delete' ) {
- $files_to_delete[] = $data['file'];
- }
- }
-
for ($i = 0; $i < min($max_files, count($swf_uploaded_ids)); $i++) {
+ // don't delete uploaded file, when it's name matches delete file name
$real_name = $this->_getRealFilename($swf_uploaded_names[$i], $options, $object, $files_to_delete);
$file_name = $this->FullPath . $real_name;
@@ -146,13 +137,39 @@
@chmod($file_name, 0666);
$fret[] = getArrayValue($options, 'upload_dir') ? $real_name : $this->DestinationPath . $real_name;
+ $pending_actions[] = Array (
+ 'action' => 'make_live', 'id' => $object->GetID(), 'field' => $field_name, 'file' => $file_name
+ );
+
$this->_renameFileInSorting($swf_uploaded_names[$i], $real_name);
}
+ $object->setPendingActions($pending_actions);
+
return $this->_sortFiles(array_merge($existing, $fret));
}
/**
+ * Returns files, scheduled for deleting
+ *
+ * @param kDBItem $object
+ * @return Array
+ * @access protected
+ */
+ protected function _getFilesToDelete($object)
+ {
+ $ret = Array ();
+
+ foreach ($object->getPendingActions() as $data) {
+ if ( $data['action'] == 'delete' ) {
+ $ret[] = $data['file'];
+ }
+ }
+
+ return $ret;
+ }
+
+ /**
* Handles regular file upload
*
* @param string|Array $value
@@ -354,6 +371,8 @@
function getSingleFormat($format)
{
$single_mapping = Array (
+ 'file_raw_urls' => 'raw_url',
+ 'file_display_names' => 'display_name',
'file_urls' => 'full_url',
'file_paths' => 'full_path',
'file_sizes' => 'file_size',
@@ -386,7 +405,7 @@
$format = isset($options['format']) ? $options['format'] : false;
}
- if ( $format && preg_match('/(file_urls|file_paths|file_names|file_sizes|img_sizes|files_resized|wms)(.*)/', $format, $regs) ) {
+ if ( $format && preg_match('/(file_raw_urls|file_display_names|file_urls|file_paths|file_names|file_sizes|img_sizes|files_resized|wms)(.*)/', $format, $regs) ) {
if ( !$value || $format == 'file_names' ) {
// storage format matches display format OR no value
return $value;
@@ -410,8 +429,7 @@
return $value;
}
- // force direct links for case, when non-swf uploader is used
- return $this->GetFormatted($tc_value, $field_name, $object, $format, true);
+ return $this->GetFormatted($tc_value, $field_name, $object, $format);
}
/**
@@ -421,10 +439,9 @@
* @param string $field_name
* @param kDBItem $object
* @param string $format
- * @param bool $force_direct_links
* @return string
*/
- function GetFormatted($value, $field_name, &$object, $format = NULL, $force_direct_links = NULL)
+ function GetFormatted($value, $field_name, &$object, $format = NULL)
{
if ( !$format || !$value ) {
return $value;
@@ -441,13 +458,16 @@
}
switch ($format) {
+ case 'display_name':
+ return kUtil::removeTempExtension($value);
+ break;
+
+ case 'raw_url':
+ return $this->fileHelper->pathToUrl(FULL_PATH . $upload_dir . $value);
+ break;
+
case 'full_url':
- if ( isset($force_direct_links) ) {
- $direct_links = $force_direct_links;
- }
- else {
- $direct_links = isset($options['direct_links']) ? $options['direct_links'] : false;
- }
+ $direct_links = isset($options['direct_links']) ? $options['direct_links'] : true;
if ( $direct_links ) {
return $this->fileHelper->pathToUrl(FULL_PATH . $upload_dir . $value);
@@ -583,10 +603,9 @@
* @param string $field_name
* @param kDBItem $object
* @param string $format
- * @param bool $force_direct_links
* @return string
*/
- function GetFormatted($value, $field_name, &$object, $format = NULL, $force_direct_links = NULL)
+ function GetFormatted($value, $field_name, &$object, $format = NULL)
{
if ( $format == 'img_size' ) {
$options = $object->GetFieldOptions($field_name);
@@ -596,6 +615,6 @@
return ' ' . $image_info[3];
}
- return parent::GetFormatted($value, $field_name, $object, $format, $force_direct_links);
+ return parent::GetFormatted($value, $field_name, $object, $format);
}
}
\ No newline at end of file
Index: branches/5.2.x/core/kernel/globals.php
===================================================================
diff -u -r15725 -r15733
--- branches/5.2.x/core/kernel/globals.php (.../globals.php) (revision 15725)
+++ branches/5.2.x/core/kernel/globals.php (.../globals.php) (revision 15733)
@@ -1,6 +1,6 @@
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
@@ -636,7 +636,7 @@
*/
public static function mimeContentTypeByExtension($file)
{
- $file_extension = mb_strtolower( pathinfo($file, PATHINFO_EXTENSION) );
+ $file_extension = mb_strtolower(pathinfo(self::removeTempExtension($file), PATHINFO_EXTENSION));
$mapping = '(xls:application/excel)(hqx:application/macbinhex40)(doc,dot,wrd:application/msword)(pdf:application/pdf)
(pgp:application/pgp)(ps,eps,ai:application/postscript)(ppt:application/powerpoint)(rtf:application/rtf)
@@ -662,6 +662,19 @@
}
/**
+ * Strips ".tmp" suffix (added by flash uploader) from a filename
+ *
+ * @param string $file
+ * @return string
+ * @access public
+ * @static
+ */
+ public static function removeTempExtension($file)
+ {
+ return preg_replace('/(_[\d]+)?\.tmp$/', '', $file);
+ }
+
+ /**
* Return param value and removes it from params array
*
* @param string $name
Index: branches/5.2.x/core/admin_templates/js/uploader/upload_manager.js
===================================================================
diff -u -r15729 -r15733
--- branches/5.2.x/core/admin_templates/js/uploader/upload_manager.js (.../upload_manager.js) (revision 15729)
+++ branches/5.2.x/core/admin_templates/js/uploader/upload_manager.js (.../upload_manager.js) (revision 15733)
@@ -119,7 +119,7 @@
var $uploader = this._Uploaders[uploader_id];
$.get(
- $uploader.deleteURL.replace('#FILE#', encodeURIComponent(fname)).replace('#FIELD#', $uploader.params.field),
+ $uploader.deleteURL.replace('#FILE#', encodeURIComponent(fname)).replace('#FIELD_ID#', $uploader.id),
function ($data) {
$uploader.removeFile({id:fname});
$uploader.deleted.push(fname);
Index: branches/5.2.x/core/kernel/db/dbitem.php
===================================================================
diff -u -r15729 -r15733
--- branches/5.2.x/core/kernel/db/dbitem.php (.../dbitem.php) (revision 15729)
+++ branches/5.2.x/core/kernel/db/dbitem.php (.../dbitem.php) (revision 15733)
@@ -1,6 +1,6 @@
Application->GetTopmostWid($this->Prefix);
return $this->Prefix . '_file_pending_actions' . $window_id;
}
/**
+ * Returns pending actions
+ *
+ * @param mixed $id
+ * @return Array
+ * @access public
+ */
+ public function getPendingActions($id = null)
+ {
+ if ( !isset($id) ) {
+ $id = $this->GetID();
+ }
+
+ $pending_actions = $this->Application->RecallVar($this->_getPendingActionVariableName());
+ $pending_actions = $pending_actions ? unserialize($pending_actions) : Array ();
+
+ if ( is_numeric($id) ) {
+ // filter by given/current id
+ $ret = Array ();
+
+ foreach ($pending_actions as $pending_action) {
+ if ( $pending_action['id'] == $id ) {
+ $ret[] = $pending_action;
+ }
+ }
+
+ return $ret;
+ }
+
+ return $pending_actions;
+ }
+
+ /**
+ * Sets new pending actions
+ *
+ * @param Array|null $new_pending_actions
+ * @param mixed $id
+ * @return void
+ * @access public
+ */
+ public function setPendingActions($new_pending_actions = null, $id = null)
+ {
+ if ( !isset($new_pending_actions) ) {
+ $new_pending_actions = Array ();
+ }
+
+ if ( !isset($id) ) {
+ $id = $this->GetID();
+ }
+
+ $pending_actions = Array ();
+ $old_pending_actions = $this->getPendingActions(true);
+
+ if ( is_numeric($id) ) {
+ // remove old actions for this id
+ foreach ($old_pending_actions as $pending_action) {
+ if ( $pending_action['id'] != $id ) {
+ $pending_actions[] = $pending_action;
+ }
+ }
+
+ // add new actions for this id
+ $pending_actions = array_merge($pending_actions, $new_pending_actions);
+ }
+ else {
+ $pending_actions = $new_pending_actions;
+ }
+
+ // save changes
+ $var_name = $this->_getPendingActionVariableName();
+
+ if ( !$pending_actions ) {
+ $this->Application->RemoveVar($var_name);
+ }
+ else {
+ $this->Application->StoreVar($var_name, serialize($pending_actions));
+ }
+ }
+
+ /**
* Allows to skip certain fields from getting into sql queries
*
* @param string $field_name
Index: branches/5.2.x/core/admin_templates/js/uploader/uploader.js
===================================================================
diff -u -r15729 -r15733
--- branches/5.2.x/core/admin_templates/js/uploader/uploader.js (.../uploader.js) (revision 15729)
+++ branches/5.2.x/core/admin_templates/js/uploader/uploader.js (.../uploader.js) (revision 15733)
@@ -265,14 +265,16 @@
}
Uploader.prototype.isImage = function($filename) {
- $filename.match(/\.([^.]*)$/);
+ this.removeTempExtension($filename).match(/\.([^.]*)$/);
+
var $ext = RegExp.$1.toLowerCase();
return $ext.match(/^(bmp|gif|jpg|jpeg|png)$/);
}
Uploader.prototype.getFileIcon = function($filename) {
- $filename.match(/\.([^.]*)$/);
+ this.removeTempExtension($filename).match(/\.([^.]*)$/);
+
var $ext = RegExp.$1.toLowerCase(),
$ext_overrides = {
'doc': '^(docx|dotx|docm|dotm)$',
@@ -297,10 +299,14 @@
return this.IconPath + '/' + $icon + '.gif';
}
+Uploader.prototype.removeTempExtension = function ($file) {
+ return $file.replace(/(_[\d]+)?\.tmp$/, '');
+}
+
Uploader.prototype.getQueueElement = function($file) {
var $ret = '';
var $icon_image = this.getFileIcon($file.name);
- var $file_label = $file.name + ' (' + this._formatSize($file.size) + ')';
+ var $file_label = this.removeTempExtension($file.name) + ' (' + this._formatSize($file.size) + ')';
var $need_preview = false;
if (isset($file.uploaded)) {
@@ -533,7 +539,7 @@
this.files[$file_index].uploaded = 1;
this.files[$file_index].progress = 100;
this.files[$file_index].temp = 1;
- this.files[$file_index].url = this.params.tmp_url.replace('#ID#', file.id).replace('#FILE#', encodeURIComponent(file.name)).replace('#FIELD#', this.params.field);
+ this.files[$file_index].url = this.params.tmp_url.replace('#ID#', file.id).replace('#FILE#', encodeURIComponent(this.files[$file_index].name)).replace('#FIELD#', this.params.field);
this.updateInfo($file_index);
}
Index: branches/5.2.x/core/kernel/db/db_event_handler.php
===================================================================
diff -u -r15729 -r15733
--- branches/5.2.x/core/kernel/db/db_event_handler.php (.../db_event_handler.php) (revision 15729)
+++ branches/5.2.x/core/kernel/db/db_event_handler.php (.../db_event_handler.php) (revision 15733)
@@ -1,6 +1,6 @@
getEventParam('parent_event');
+ /* @var $parent_event kEvent */
if ( is_object($parent_event) ) {
$object->setParentEvent($parent_event);
@@ -1818,7 +1819,7 @@
$object = $event->getObject(Array('skip_autoload' => true));
/* @var $object kDBItem */
- $this->Application->RemoveVar($object->getPendingActionVariableName());
+ $object->setPendingActions(null, true);
$changes_var_name = $this->Prefix . '_changes_' . $this->Application->GetTopmostWid($this->Prefix);
$this->Application->RemoveVar($changes_var_name);
@@ -2402,7 +2403,7 @@
/* @var $object kDBItem */
if ( !$object->IsTempTable() ) {
- $this->_proccessPendingActions($event);
+ $this->_processPendingActions($event);
}
}
@@ -2431,7 +2432,7 @@
/* @var $object kDBItem */
if ( !$object->IsTempTable() ) {
- $this->_proccessPendingActions($event);
+ $this->_processPendingActions($event);
}
}
@@ -2585,7 +2586,13 @@
*/
protected function OnAfterCopyToLive(kEvent $event)
{
- $this->_proccessPendingActions($event);
+ $object = $event->getObject();
+ /* @var $object kDBItem */
+
+ $object->SwitchToLive();
+ $object->Load($event->getEventParam('id'));
+
+ $this->_processPendingActions($event);
}
/**
@@ -2595,24 +2602,45 @@
* @return void
* @access protected
*/
- protected function _proccessPendingActions(kEvent $event)
+ protected function _processPendingActions(kEvent $event)
{
$object = $event->getObject();
/* @var $object kDBItem */
- $var_name = $object->getPendingActionVariableName();
- $schedule = $this->Application->RecallVar($var_name);
+ $update_required = false;
+ $temp_id = $event->getEventParam('temp_id');
+ $id = $temp_id !== false ? $temp_id : $object->GetID();
- if ( $schedule ) {
- $schedule = unserialize($schedule);
-
- foreach ($schedule as $data) {
- if ( $data['action'] == 'delete' ) {
+ foreach ($object->getPendingActions($id) as $data) {
+ switch ( $data['action'] ) {
+ case 'delete':
unlink($data['file']);
- }
+ break;
+
+ case 'make_live':
+ $file_helper = $this->Application->recallObject('FileHelper');
+ /* @var $file_helper FileHelper */
+
+ $old_name = basename($data['file']);
+ $new_name = $file_helper->ensureUniqueFilename(dirname($data['file']), kUtil::removeTempExtension($old_name));
+ rename($data['file'], dirname($data['file']) . '/' . $new_name);
+
+ $db_value = $object->GetDBField($data['field']);
+ $object->SetDBField($data['field'], str_replace($old_name, $new_name, $db_value));
+ $update_required = true;
+ break;
+
+ default:
+ trigger_error('Unsupported pending action "' . $data['action'] . '" for "' . $event->getPrefixSpecial() . '" unit', E_USER_WARNING);
+ break;
}
+ }
- $this->Application->RemoveVar($var_name);
+ // remove pending actions before updating to prevent recursion
+ $object->setPendingActions();
+
+ if ( $update_required ) {
+ $object->Update();
}
}
@@ -2970,7 +2998,7 @@
*/
public function getCustomExportColumns(kEvent $event)
{
- return Array();
+ return Array ();
}
/**
@@ -3123,21 +3151,13 @@
}
$tmp_path = WRITEABLE . '/tmp/';
- $fname = $value['name'];
+ $filename = $value['name'] . '.tmp';
$id = $this->Application->GetVar('id');
if ( $id ) {
- $fname = $id . '_' . $fname;
+ $filename = $id . '_' . $filename;
}
- $field_name = $this->Application->GetVar('field');
- $fields = $this->Application->getUnitOption($event->Prefix, 'Fields');
- $virtual_fields = $this->Application->getUnitOption($event->Prefix, 'VirtualFields');
- $field_options = array_key_exists($field_name, $fields) ? $fields[$field_name] : $virtual_fields[$field_name];
-
- $upload_dir = $field_options['upload_dir'];
- $storage_format = array_key_exists('storage_format', $field_options) ? $field_options['storage_format'] : false;
-
if ( !is_writable($tmp_path) ) {
// 500 Internal Server Error
// check both temp and live upload directory
@@ -3149,7 +3169,8 @@
$file_helper = $this->Application->recallObject('FileHelper');
/* @var $file_helper FileHelper */
- $fname = $file_helper->ensureUniqueFilename($tmp_path, $fname);
+ $filename = $file_helper->ensureUniqueFilename($tmp_path, $filename);
+ $storage_format = $this->_getStorageFormat($this->Application->GetVar('field'), $event);
if ( $storage_format ) {
$image_helper = $this->Application->recallObject('ImageHelper');
@@ -3158,13 +3179,13 @@
move_uploaded_file($value['tmp_name'], $value['tmp_name'] . '.jpg'); // add extension, so ResizeImage can work
$url = $image_helper->ResizeImage($value['tmp_name'] . '.jpg', $storage_format);
$tmp_name = preg_replace('/^' . preg_quote($this->Application->BaseURL(), '/') . '/', '/', $url);
- rename($tmp_name, $tmp_path . $fname);
+ rename($tmp_name, $tmp_path . $filename);
}
else {
- move_uploaded_file($value['tmp_name'], $tmp_path . $fname);
+ move_uploaded_file($value['tmp_name'], $tmp_path . $filename);
}
- echo preg_replace('/^' . preg_quote($id, '/') . '_/', '', $fname);
+ echo preg_replace('/^' . preg_quote($id, '/') . '_/', '', $filename);
$this->deleteTempFiles($tmp_path);
@@ -3174,6 +3195,23 @@
}
/**
+ * Gets storage format for a given field
+ *
+ * @param string $field_name
+ * @param kEvent $event
+ * @return bool
+ * @access protected
+ */
+ protected function _getStorageFormat($field_name, kEvent $event)
+ {
+ $fields = $this->Application->getUnitOption($event->Prefix, 'Fields');
+ $virtual_fields = $this->Application->getUnitOption($event->Prefix, 'VirtualFields');
+ $field_options = array_key_exists($field_name, $fields) ? $fields[$field_name] : $virtual_fields[$field_name];
+
+ return isset($field_options['storage_format']) ? $field_options['storage_format'] : false;
+ }
+
+ /**
* Delete temporary files, that won't be used for sure
*
* @param string $path
@@ -3253,13 +3291,22 @@
$object = $event->getObject(Array ('skip_autoload' => true));
/* @var $object kDBItem */
- $upload_dir = $object->GetFieldOption($this->Application->GetVar('field'), 'upload_dir');
+ $field_id = $this->Application->GetVar('field_id');
- $var_name = $object->getPendingActionVariableName();
- $schedule = $this->Application->RecallVar($var_name);
- $schedule = $schedule ? unserialize($schedule) : Array ();
- $schedule[] = Array ('action' => 'delete', 'file' => FULL_PATH . $upload_dir . $filename);
- $this->Application->StoreVar($var_name, serialize($schedule));
+ if ( !preg_match_all('/\[([^\[\]]*)\]/', $field_id, $regs) ) {
+ return;
+ }
+
+ $field = $regs[1][1];
+ $record_id = $regs[1][0];
+ $pending_actions = $object->getPendingActions($record_id);
+ $upload_dir = $object->GetFieldOption($field, 'upload_dir');
+
+ $pending_actions[] = Array (
+ 'action' => 'delete', 'id' => $record_id, 'field' => $field, 'file' => FULL_PATH . $upload_dir . $filename
+ );
+
+ $object->setPendingActions($pending_actions, $record_id);
}
/**
@@ -3301,7 +3348,7 @@
$url = $object->GetField($field, $options['thumb_format']);
}
else {
- $url = $object->GetField($field, 'full_url'); // don't use "file_urls" format to prevent recursion
+ $url = $object->GetField($field, 'raw_url');
}
$file_helper = $this->Application->recallObject('FileHelper');
@@ -3315,7 +3362,7 @@
header('Content-Length: ' . filesize($path));
$this->Application->setContentType(kUtil::mimeContentType($path), false);
- header('Content-Disposition: inline; filename="' . $filename . '"');
+ header('Content-Disposition: inline; filename="' . kUtil::removeTempExtension($filename) . '"');
readfile($path);
}
Index: branches/5.2.x/core/admin_templates/incs/form_blocks.tpl
===================================================================
diff -u -r15729 -r15733
--- branches/5.2.x/core/admin_templates/incs/form_blocks.tpl (.../form_blocks.tpl) (revision 15729)
+++ branches/5.2.x/core/admin_templates/incs/form_blocks.tpl (.../form_blocks.tpl) (revision 15733)
@@ -371,7 +371,7 @@
sizes : '',
flashsid : '',
uploadURL : '',
- deleteURL : '',
+ deleteURL : '',
tmp_url : '',
// Button settings