Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Sun, Nov 9, 1:13 AM

in-portal

Index: branches/RC/core/kernel/utility/formatters/upload_formatter.php
===================================================================
--- branches/RC/core/kernel/utility/formatters/upload_formatter.php (revision 10578)
+++ branches/RC/core/kernel/utility/formatters/upload_formatter.php (revision 10579)
@@ -1,313 +1,317 @@
<?php
class kUploadFormatter extends kFormatter
{
var $DestinationPath;
var $FullPath;
function kUploadFormatter()
{
parent::kBase();
if ($this->DestinationPath) {
$this->FullPath = FULL_PATH.$this->DestinationPath;
}
}
/**
* Processes file uploads from form
*
* @param mixed $value
* @param string $field_name
* @param kDBItem $object
* @return string
*/
function Parse($value, $field_name, &$object)
{
$ret = '';
$options = $object->GetFieldOptions($field_name);
if(getArrayValue($options, 'upload_dir'))
{
$this->DestinationPath = $options['upload_dir'];
$this->FullPath = FULL_PATH.$this->DestinationPath;
}
// SWF Uploader
if (is_array($value) && isset($value['tmp_ids'])) {
if ($value['tmp_deleted']) {
$deleted = explode('|', $value['tmp_deleted']);
$upload = explode('|', $value['upload']);
$n_upload = array();
// $n_ids = array();
foreach ($upload as $name) {
if (in_array($name, $deleted)) continue;
$n_upload[] = $name;
// $n_ids[] = $name;
}
$value['upload'] = implode('|', $n_upload);
// $value['tmp_ids'] = implode('|', $n_ids);
}
if (!$value['tmp_ids']) {
- return getArrayValue($value, 'upload');
+ $uploaded_files = getArrayValue($value, 'upload');
+ if (!$uploaded_files && getArrayValue($options, 'required')) {
+ $object->SetError($field_name, 'required');
+ }
+ return $uploaded_files;
}
$swf_uploaded_ids = explode('|', $value['tmp_ids']);
$swf_uploaded_names = explode('|', $value['tmp_names']);
$existing = $value['upload'] ? explode('|', $value['upload']) : array();
if (isset($options['multiple'])) {
$max_files = $options['multiple'] == false ? 1 : $options['multiple'];
}
else {
$max_files = 1;
}
$fret = array();
// don't delete uploaded file, when it's name matches delete file name
$var_name = $object->getPrefixSpecial().'_file_pending_actions'.$this->Application->GetVar('m_wid');
$schedule = $this->Application->RecallVar($var_name);
$schedule = $schedule ? unserialize($schedule) : Array();
$files2delete = Array();
foreach ($schedule as $data) {
if ($data['action'] == 'delete') {
$files2delete[] = $data['file'];
}
}
for ($i=0; $i<min($max_files, count($swf_uploaded_ids)); $i++) {
$real_name = $swf_uploaded_names[$i];
$real_name = $this->ValidateFileName($this->FullPath, $real_name, $files2delete);
$file_name = $this->FullPath.$real_name;
$tmp_file = (defined('WRITEABLE') ? WRITEABLE.'/tmp/' : FULL_PATH.'/kernel/cache/').$swf_uploaded_ids[$i].'_'.$swf_uploaded_names[$i];
rename($tmp_file, $file_name);
@chmod($file_name, 0666);
$fret[] = getArrayValue($options, 'upload_dir') ? $real_name : $this->DestinationPath.$real_name;
}
$fret = array_merge($existing, $fret);
return implode('|', $fret);
}
// SWF Uploader END
if (getArrayValue($value, 'upload') && getArrayValue($value, 'error') == UPLOAD_ERR_NO_FILE) {
// file was not uploaded this time, but was uploaded before, then use previously uploaded file (from db)
return getArrayValue($value, 'upload');
}
if (is_array($value) && count($value) > 1 && $value['size']) {
if (is_array($value) && $value['error'] === UPLOAD_ERR_OK) {
$max_filesize = isset($options['max_size']) ? $options['max_size'] : MAX_UPLOAD_SIZE;
if (getArrayValue($options, 'allowed_types') && !in_array($value['type'], $options['allowed_types'])) {
$error_params = Array (
'file_type' => $value['type'],
'allowed_types' => $options['allowed_types'],
);
$object->SetError($field_name, 'bad_file_format', 'la_error_InvalidFileFormat', $error_params);
}
elseif ($value['size'] > $max_filesize) {
$object->SetError($field_name, 'bad_file_size', 'la_error_FileTooLarge');
}
elseif (!is_writable($this->FullPath)) {
$object->SetError($field_name, 'cant_save_file', 'la_error_cant_save_file');
}
else {
$real_name = $this->ValidateFileName($this->FullPath, $value['name']);
$file_name = $this->FullPath.$real_name;
if (!move_uploaded_file($value['tmp_name'], $file_name)) {
$object->SetError($field_name, 'cant_save_file', 'la_error_cant_save_file');
}
else {
@chmod($file_name, 0666);
if (getArrayValue($options, 'size_field')) {
$object->SetDBField($options['size_field'], $value['size']);
}
if (getArrayValue($options, 'orig_name_field')) {
$object->SetDBField($options['orig_name_field'], $value['name']);
}
if (getArrayValue($options, 'content_type_field')) {
$object->SetDBField($options['content_type_field'], $value['type']);
}
$ret = getArrayValue($options, 'upload_dir') ? $real_name : $this->DestinationPath.$real_name;
// delete previous file, when new file is uploaded under same field
/*$previous_file = isset($value['upload']) ? $value['upload'] : false;
if ($previous_file && file_exists($this->FullPath.$previous_file)) {
unlink($this->FullPath.$previous_file);
}*/
}
}
}
else {
$object->SetError($field_name, 'cant_save_file', 'la_error_cant_save_file');
}
}
else {
if (getArrayValue($options, 'required')) {
$object->SetError($field_name, 'required');
}
}
// && !$object->FieldErrors[$field_name]['pseudo'] - already implemented in kDBItem::SetError method
if ((count($value) > 1) && $value['error'] && ($value['error'] != UPLOAD_ERR_NO_FILE)) {
$object->SetError($field_name, 'cant_save_file', 'la_error_cant_save_file');
}
return $ret;
}
function getSingleFormat($format)
{
$single_mapping = Array (
'file_urls' => 'full_url',
'file_sizes' => 'file_size',
'files_resized' => 'resize',
'wms' => 'wm',
);
return $single_mapping[$format];
}
/**
* Return formatted file url,path or size (or same for multiple files)
*
* @param string $value
* @param string $field_name
* @param kDBItem $object
* @param string $format
* @return string
*/
function Format($value, $field_name, &$object, $format = null)
{
if (is_null($value)) {
return '';
}
$options = $object->GetFieldOptions($field_name);
if (!isset($format)) {
$format = isset($options['format']) ? $options['format'] : false;
}
if ($format && preg_match('/(file_urls|file_names|file_sizes|files_resized|wms)(.*)/', $format, $regs)) {
if (!$value || $format == 'file_names') {
// storage format matches display format OR no value
return $value;
}
$ret = Array ();
$files = explode('|', $value);
$format = $this->getSingleFormat($regs[1]).$regs[2];
foreach ($files as $a_file) {
$ret[] = $this->GetFormatted($a_file, $field_name, $object, $format);
}
return implode('|', $ret);
}
$tc_value = $this->TypeCast($value, $options);
if( ($tc_value === false) || ($tc_value != $value) ) return $value; // for leaving badly formatted date on the form
$object->Fields[$field_name]['direct_links'] = true; // for case, when non-swf uploader is used
return $this->GetFormatted($tc_value, $field_name, $object, $format);
}
/**
* Return formatted file url,path or size
*
* @param string $value
* @param string $field_name
* @param kDBItem $object
* @param string $format
* @return string
*/
function GetFormatted($value, $field_name, &$object, $format = null)
{
if (!$format) {
return $value;
}
$options = $object->GetFieldOptions($field_name);
$upload_dir = isset($options['upload_dir']) ? $options['upload_dir'] : $this->DestinationPath;
if (preg_match('/resize:([\d]*)x([\d]*)/', $format, $regs)) {
$image_helper =& $this->Application->recallObject('ImageHelper');
/* @var $image_helper ImageHelper */
return $image_helper->ResizeImage(FULL_PATH.$upload_dir.$value, $format);
}
switch ($format) {
case 'full_url':
if (isset($options['direct_links']) && $options['direct_links']) {
return rtrim($this->Application->BaseURL(), '/').$upload_dir.$value;
}
else {
$url_params = Array (
'no_amp' => 1, 'pass' => 'm,'.$object->Prefix,
$object->Prefix.'_event' => 'OnViewFile',
'file' => $value, 'field' => $field_name
);
return $this->Application->HREF('', '', $url_params);
}
break;
case 'full_path':
return FULL_PATH.$upload_dir.$value;
break;
case 'file_size':
return filesize(FULL_PATH.$upload_dir.$value);
break;
}
return sprintf($format, $value);
}
function ValidateFileName($path, $name, $forbidden_names = Array())
{
$parts = pathinfo($name);
$ext = '.'.$parts['extension'];
$filename = mb_substr($parts['basename'], 0, -mb_strlen($ext));
$new_name = $filename.$ext;
while ( file_exists($path.'/'.$new_name) || in_array(rtrim($path, '/').'/'.$new_name, $forbidden_names) )
{
if ( preg_match('/('.preg_quote($filename, '/').'_)([0-9]*)('.preg_quote($ext, '/').')/', $new_name, $regs) ) {
$new_name = $regs[1].($regs[2]+1).$regs[3];
}
else {
$new_name = $filename.'_1'.$ext;
}
}
return $new_name;
}
}
class kPictureFormatter extends kUploadFormatter
{
function kPictureFormatter()
{
$this->NakeLookupPath = IMAGES_PATH; // used ?
$this->DestinationPath = constOn('ADMIN') ? IMAGES_PENDING_PATH : IMAGES_PATH;
parent::kUploadFormatter();
}
function GetFormatted($value, $field_name, &$object, $format = null)
{
if ($format == 'img_size') {
$upload_dir = isset($options['upload_dir']) ? $options['upload_dir'] : $this->DestinationPath;
$img_path = FULL_PATH.'/'.$upload_dir.$value;
$image_info = @getimagesize($img_path);
return ' width="'.$image_info[0].'" height="'.$image_info[1].'"';
}
return parent::GetFormatted($value, $field_name, $object, $format);
}
}
\ No newline at end of file
Property changes on: branches/RC/core/kernel/utility/formatters/upload_formatter.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.10.2.12
\ No newline at end of property
+1.10.2.13
\ No newline at end of property
Index: branches/RC/core/admin_templates/js/forms.js
===================================================================
--- branches/RC/core/admin_templates/js/forms.js (revision 10578)
+++ branches/RC/core/admin_templates/js/forms.js (revision 10579)
@@ -1,297 +1,315 @@
var last_shown_error = false;
var errors = new Object();
var first_error = new Object();
var fields = new Object();
function show_form_error(prefix, field, sticky)
{
if (isset(errors[prefix]) && isset(errors[prefix][field])) {
span = document.getElementById('error_msg_'+prefix);
span.innerHTML = fields[prefix][field] + ' - ' + errors[prefix][field];
if (sticky) last_shown_error = field;
}
}
function hide_form_error(prefix)
{
span = document.getElementById('error_msg_'+prefix);
if (!span) return;
span.innerHTML = '<br/>';
if (typeof(last_shown_error) != 'undefined' && last_shown_error) {
show_form_error(prefix, last_shown_error);
}
}
function add_form_error(prefix, field, element, error_msg) {
if (error_msg != '') {
if (typeof(errors[prefix]) == 'undefined') {
errors[prefix] = new Object();
}
errors[prefix][field] = error_msg;
- addEvent(document.getElementById(element), 'focus', function() {
- show_form_error(prefix, field, true)
- } );
- addEvent(document.getElementById(element), 'blur', function() {last_shown_error = false} )
+
+ if (document.getElementById(element)) {
+ // some controls don't have element to focus on (e.g. swf uploader)
+ addEvent(
+ document.getElementById(element),
+ 'focus',
+ function() {
+ show_form_error(prefix, field, true)
+ }
+ );
+ addEvent(
+ document.getElementById(element),
+ 'blur',
+ function() {
+ last_shown_error = false
+ }
+ );
+ }
+
if (typeof(first_error[prefix]) == 'undefined' || first_error[prefix] == false) {
first_error[prefix] = [field, element];
}
}
}
function Form() {}
Form = new Form();
Form.Controls = new Array();
Form.Div = false;
Form.MinControlsHeight = 0;
Form.Options = new Object();
Form.FlexibleCount = 0;
Form.ScrollerW = 17;
Form.ScrollerH = 17;
Form.Wrap = true;
Form.HasChanged = false;
Form.Init = function(id)
{
this.Div = document.getElementById(id);
for (var i in this.Controls) {
dim = getDimensions(document.getElementById(this.Controls[i]));
options = this.Options[this.Controls[i]];
if (options.height) { // fixed height
options.min_height = options.height;
options.max_height = options.height;
}
if (!options.min_height) options.min_height = dim.innerHeight;
this.MinControlsHeight += options.min_height;
if (dim.innerHeight < options.min_height) {
document.getElementById(this.Controls[i]).style.height = options.min_height+'px';
}
// alert('adding element '+this.Controls[i]+' height: '+options.min_height+' total: '+this.MinControlsHeight)
}
/*alert('one more time');
document.body.style.height = '100%';
document.body.style.overflow = 'hidden';
document.body.scroll = 'no'
alert('done');*/
var a_div = document.createElement('DIV');
a_div.style.position = 'relative';
a_div.style.overflow = 'auto';
a_div.style.width = '100%';
// a_div.style.height = '100%';
// a_div.style.backgroundColor = 'yellow';
a_div.appendChild(this.Div.parentNode.replaceChild(a_div, this.Div));
this.Table = this.Div.getElementsByTagName('table')[0];
this.Table.style.height = 'auto';
// this.Table.style.width = 'auto';
this.MinHeight = this.Table.offsetHeight;
this.MinWidth = this.Table.offsetWidth;
// alert('Measuring min width now')
addEvent(window, 'resize', function() {Form.Resize()})
this.Resize()
if (isset(first_error)) {
- for (var i in first_error) {
- if (first_error[i] != false) {
+ for (var i in first_error) {
+ if (first_error[i] != false) {
+ if (document.getElementById(first_error[i][1])) {
+ // some controls don't have element to focus on (e.g. swf uploader)
document.getElementById(first_error[i][1]).focus();
- show_form_error(i, first_error[i][0], true);
-// alert('focused on '+first_error[i][1])
}
+ show_form_error(i, first_error[i][0], true);
+// alert('focused on '+first_error[i][1])
}
}
+ }
addEvent(window, 'unload', function() {
if (!unload_legal) { // it's set in submit_kernel_form - if we are submitting form, the unload is already handled
// if we got here, it means that we are closing window ilegally (through OS interace X button)
// alert('closing window');
// we need to clear temp tables then
window.opener.WatchClosing(window, _DropTempUrl);
}
});
// we need to set unload_legal to true if we are refreshing current window, because onunload will still fire
addEvent(document, 'keydown', function(e) {
var code;
if (!e) var e = window.event;
if (e.keyCode) code = e.keyCode;
else if (e.which) code = e.which;
if (code == 116 || (e.ctrlKey && code == 82)) unload_legal = true; //F5 or Ctrl+R
});
if (_Simultanious_Edit_Message != '') {
alert(_Simultanious_Edit_Message);
}
-
+
this.InitOnChange();
}
Form.InitOnChange = function()
{
var inputs = window.document.getElementsByTagName('INPUT');
var selects = window.document.getElementsByTagName('SELECT');
var textareas = window.document.getElementsByTagName('TEXTAREA');
-
+
var groups = [inputs, selects, textareas];
-
+
for (var g=0; g<groups.length; g++) {
for (var i=0; i<groups[g].length; i++) {
var elem = groups[g][i];
if (elem.tagName == 'INPUT' && elem.type == 'hidden') continue;
addEvent(elem, elem.type=='button' ? 'click' : 'change', function() {Form.Changed()});
}
}
}
Form.Changed = function()
{
this.HasChanged = true;
}
Form.addControl = function(id, options) {
this.Controls.push(id);
if (!options) {
options = {coeff: 1, max_height: 0, min_height: 0};
}
else {
if (typeof(options['coeff']) == 'undefined') options['coeff'] = 1;
if (typeof(options['max_height']) == 'undefined') options['max_height'] = 0;
if (typeof(options['min_height']) == 'undefined') options['min_height'] = 0;
}
options['real_height'] = 0;
this.Options[id] = options; // for future use
// print_pre(this.Options[id]);
}
Form.Resize = function()
{
var h = (document.all ? window.document.body.offsetHeight : window.innerHeight);
var pos = findPos(this.Div);
var dim = getDimensions(this.Div);
h -= pos[1] + dim.padding[0] + dim.padding[2] + dim.borders[0] + dim.borders[2];
// alert('h after correction is '+h);
window.document.body.style.width = '100%';
var w = (document.all ? window.document.body.offsetWidth : window.innerWidth);
w -= pos[0] + dim.padding[1] + dim.padding[3] + dim.borders[1] + dim.borders[3];
scroller_height = this.MinWidth > w ? this.ScrollerH : 0;
scroller_width = this.MinHeight > h - scroller_height ? this.ScrollerW : 0;
scroller_height = this.MinWidth > w - scroller_width ? this.ScrollerH : 0;
var st = document.getElementById('width_status');
if (st) st.innerHTML = 'minWdith: '+this.MinWidth+' minHeight: '+this.MinHeight+' w: '+w+' h: '+h+' scroll_w: '+scroller_width+' scroll_h: '+scroller_height;
// alert('scroller W x H = '+scroller_width+' x '+scroller_height);
// alert('resize: '+w+'x'+h)
// h -= 100;
this.Table.style.width = (w-scroller_width) + 'px';
this.Div.parentNode.style.width = (w)+'px';
this.Div.style.width = (w-scroller_width)+'px';
this.Div.parentNode.style.height = (h)+'px';
var count = this.Controls.length;
// -count here is adjustment - 1px for each control
var split = h - count*2 - this.MinHeight + this.MinControlsHeight;
if (split < this.MinControlsHeight) split = this.MinControlsHeight;
this.ResetHeights();
var used = this.SetMinHeights();
split -= used;
var cur_diff = 0;
var iterations = 0;
do {
var prev_diff = cur_diff;
var cur_diff = this.SplitExtra(split);
split = cur_diff;
iterations++;
} while (cur_diff != 0 && cur_diff != prev_diff && iterations < 10);
for (var i in this.Controls) {
document.getElementById(this.Controls[i]).style.height = this.Options[this.Controls[i]]['real_height'] + 'px';
// document.getElementById(this.Controls[i]).value = this.Options[this.Controls[i]]['real_height'];
}
// alert('h is: '+h+' min height is '+this.MinHeight+' MinControlsHeight is '+this.MinControlsHeight+' -> '+split+' to split between '+count+' new height is '+new_height);
// print_pre(this.Controls)
}
Form.ResetHeights = function()
{
for (var i in this.Controls) {
var options = this.Options[this.Controls[i]]
options['real_height'] = 0;
options.fixed = false;
}
this.FlexibleCount = this.Controls.length;
}
// Enlarge heights when possible
// Return any not split pixels number
Form.SplitExtra = function(split)
{
var number = 0;
for (var i in this.Controls) {
var options = this.Options[this.Controls[i]]
if (options['max_height'] ==0 || options['real_height'] < options.max_height) {
number++;
}
}
if (number == 0) return 0;
var delta = Math.floor(split / number);
// alert('splitting '+split+' between '+number+' delta is '+delta)
var added = 0;
for (var i in this.Controls) {
var options = this.Options[this.Controls[i]];
var to_add;
if (options['max_height'] != 0 && options['real_height']+delta > options['max_height']) {
to_add = options['max_height']-options['real_height'];
}
else {
to_add = delta;
}
// alert('delta: '+delta+' current real: '+options['real_height']+' min: '+options['min_height']+' max:'+options['max_height']+' to_add: '+to_add)
options['real_height'] = options['real_height']+to_add;
added += to_add;
}
// alert('added total '+added)
// removing extra added from the last (any) control
if (added > split) {
extra = added-split;
options['real_height'] -= extra;
added -= extra;
}
return split - added;
}
Form.SetMinHeights = function()
{
var used = 0;
for (var i in this.Controls) {
var options = this.Options[this.Controls[i]]
if (options['real_height'] < options['min_height']) {
options['real_height'] = options.min_height;
used += options.min_height;
}
}
return used;
}
\ No newline at end of file
Property changes on: branches/RC/core/admin_templates/js/forms.js
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.4.2.5
\ No newline at end of property
+1.4.2.6
\ No newline at end of property

Event Timeline