Index: branches/5.2.x/core/kernel/db/db_event_handler.php =================================================================== diff -u -N -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); }