From 2571e2875ebec54d42514c1945d8d23e11dfefb6 Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Fri, 1 Mar 2013 00:46:31 -0300 Subject: [PATCH 01/42] Fixed a bug where a SfilStoredFile could be erased mistakenly. --- .../plugins/jj_media/models/behaviors/stored_file_holder.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cake/app/plugins/jj_media/models/behaviors/stored_file_holder.php b/src/cake/app/plugins/jj_media/models/behaviors/stored_file_holder.php index 73514e09..e0b6cf90 100644 --- a/src/cake/app/plugins/jj_media/models/behaviors/stored_file_holder.php +++ b/src/cake/app/plugins/jj_media/models/behaviors/stored_file_holder.php @@ -106,8 +106,12 @@ function afterSave(&$Model, $created) $SfilStoredFile =& $this->getFileModel($Model); foreach ($this->settings[$Model->alias]['keys'] as $key) + { + if (empty($this->runtime[$Model->alias]['ids_bkp'][$key])) + continue; if (isset($Model->data[$Model->alias][$key]) && $Model->data[$Model->alias][$key] != $this->runtime[$Model->alias]['ids_bkp'][$key]) $SfilStoredFile->delete($this->runtime[$Model->alias]['ids_bkp'][$key]); + } } } From a49b67070d7bf11cda91039fd4325a4e55d1fbd0 Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Sat, 2 Mar 2013 20:03:10 -0300 Subject: [PATCH 02/42] Original schema --- .../app/plugins/jj_media/config/schema/empty | 0 .../plugins/jj_media/config/schema/schema.php | 34 +++++++++++++++++++ 2 files changed, 34 insertions(+) delete mode 100644 src/cake/app/plugins/jj_media/config/schema/empty create mode 100644 src/cake/app/plugins/jj_media/config/schema/schema.php diff --git a/src/cake/app/plugins/jj_media/config/schema/empty b/src/cake/app/plugins/jj_media/config/schema/empty deleted file mode 100644 index e69de29b..00000000 diff --git a/src/cake/app/plugins/jj_media/config/schema/schema.php b/src/cake/app/plugins/jj_media/config/schema/schema.php new file mode 100644 index 00000000..86d278cf --- /dev/null +++ b/src/cake/app/plugins/jj_media/config/schema/schema.php @@ -0,0 +1,34 @@ + array('type' => 'integer', 'null' => false, 'default' => NULL, 'key' => 'primary'), + 'checksum' => array('type' => 'string', 'null' => false, 'default' => NULL, 'collate' => 'latin1_swedish_ci', 'charset' => 'latin1'), + 'dirname' => array('type' => 'string', 'null' => false, 'default' => NULL, 'collate' => 'latin1_swedish_ci', 'charset' => 'latin1'), + 'basename' => array('type' => 'string', 'null' => false, 'default' => NULL, 'collate' => 'latin1_swedish_ci', 'charset' => 'latin1'), + 'original_filename' => array('type' => 'string', 'null' => false, 'default' => NULL, 'collate' => 'latin1_swedish_ci', 'charset' => 'latin1'), + 'mime_type' => array('type' => 'string', 'null' => false, 'default' => NULL, 'collate' => 'latin1_swedish_ci', 'charset' => 'latin1'), + 'size' => array('type' => 'integer', 'null' => false, 'default' => NULL), + 'width' => array('type' => 'integer', 'null' => true, 'default' => NULL), + 'height' => array('type' => 'integer', 'null' => true, 'default' => NULL), + 'original_id' => array('type' => 'integer', 'null' => true, 'default' => NULL), + 'transformation_version' => array('type' => 'integer', 'null' => true, 'default' => NULL), + 'transformation' => array('type' => 'string', 'null' => true, 'default' => NULL, 'collate' => 'latin1_swedish_ci', 'charset' => 'latin1'), + 'data' => array('type' => 'text', 'null' => true, 'default' => NULL, 'collate' => 'latin1_swedish_ci', 'charset' => 'latin1'), + 'created' => array('type' => 'datetime', 'null' => true, 'default' => NULL), + 'modified' => array('type' => 'datetime', 'null' => true, 'default' => NULL), + 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)), + 'tableParameters' => array('charset' => 'latin1', 'collate' => 'latin1_swedish_ci', 'engine' => 'InnoDB') + ); +} +?> \ No newline at end of file From 1f02a1755ec970df67355b9c8592523effd452f3 Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Sun, 3 Mar 2013 17:11:04 -0300 Subject: [PATCH 03/42] Starting the AjaxUpload component for burocrata --- .../plugins/burocrata/webroot/js/burocrata.js | 158 +++++++++++++++++- .../views/elements/backstage_css.ctp | 29 ++++ 2 files changed, 185 insertions(+), 2 deletions(-) diff --git a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js index 0698d87a..e0442f22 100644 --- a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js +++ b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js @@ -1792,7 +1792,11 @@ var BuroEditableList = Class.create(BuroCallbackable, { } }); - +var CAPTIONS = { + upload: { + sending: 'Enviando o arquivo #{fileName}. Aguarde...' + } +}; /** * @@ -1823,9 +1827,22 @@ var BuroUpload = Class.create(BuroCallbackable, { this.url = url; this.errors = errors; this.parameters = $H(parameters); + + this.ajax_upload = ( + 'multiple' in new Element('input', {type: 'file'}) && + !Object.isUndefined(File) && + !Object.isUndefined((new XMLHttpRequest()).upload) + ); + + if (this.ajax_upload) + { + new BuroAjaxUpload(id_base, url, errors, parameters); + return; + } + BuroCR.set(this.id_base, this); - + this.iframe = new Element('iframe', { name: 'if'+this.id_base, id: 'if'+this.id_base, @@ -1972,6 +1989,143 @@ var BuroUpload = Class.create(BuroCallbackable, { }); +var BuroAjaxUpload = Class.create(BuroCallbackable,{ + chunkSize: 1024*1024, // 1M + initialize: function(id_base, url, errors, parameters) + { + this.id_base = id_base; + this.url = url; + + BuroCR.set(this.id_base, this); + + if (document.loaded) this.loaded(); + else document.observe('dom:loaded', this.loaded.bind(this)) + }, + loaded: function() + { + this.hidden_input = $('hi'+this.id_base); + this.div_hidden = $('div'+this.id_base); + this.progress_bar = new Element('div', {className: 'progress_bar'}); + this.progress_bar.insert(new Element('div', {className: 'filling'})); + this.progress_bar.insert(new Element('span', {className: 'label'})); + this.upload_input = $('mi'+this.id_base); + this.upload_input.insert({ after: this.progress_bar }); + this.upload_input.on('change', this.inputChange.bind(this)); + }, + reset: function() + { + this.currentByte = + this.hash = + this.file = null; + }, + inputChange: function(ev) + { + if (!this.upload_input.files.length) + { + this.clearAll(); + } + else if (this.upload_input.files.length == 1) + { + var file = this.upload_input.files[0], + caption = CAPTIONS.upload.sending.interpolate({fileName: file.name || file.fileName}); + this.upload_input.insert({ after: (new Element('span')).insert(caption) }) + .hide(); + + this.reset(); + this.file = file; + this.uploadOnePiece(); + } + }, + getFileSize: function() + { + if (this.file) + return this.file.size || this.file.fileSize; + return null; + }, + uploadOnePiece: function() + { + var startByte = this.currentByte || 0, + endByte = Math.min(startByte + this.chunkSize, this.getFileSize()), + isLast = endByte == this.getFileSize(), + chunk, form; + + if (this.file.mozSlice) + chunk = this.file.mozSlice(startByte, endByte); + else if (this.file.webkitSlice) + chunk = this.file.webkitSlice(startByte, endByte); + else if (this.file.slice) + chunk = this.file.slice(startByte, chunkSize); + + if (!chunk) + throw "Chunk is empty"; + + this.xhr = new XMLHttpRequest(); + this.xhr.upload.addEventListener('error', this.handleError.bind(this)); + this.xhr.upload.addEventListener('progress', this.handleProgress.bind(this)); + this.xhr.upload.addEventListener('abort', this.handleAbort.bind(this)); + this.xhr.onreadystatechange = this.uploadStatusChange.bind(this, startByte, endByte, isLast); + + this.xhr.open('POST', this.url, true); + this.xhr.setRequestHeader('Cache-Control', 'no-cache'); + this.xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); + this.xhr.setRequestHeader('X-Uploader-Start-Byte', startByte); + this.xhr.setRequestHeader('X-Uploader-Is-Last', isLast ? 'yes' : 'no'); + + form = new FormData(); + form.append(this.upload_input.name, chunk); + if (this.hash) + form.append('data[hash]', this.hash); + + this.xhr.send(form); + }, + uploadStatusChange: function(startByte, endByte, isLast) + { + if (this.xhr.readyState != 4 || this.xhr.status != 200) + return; + + var jsone = false; + if (this.xhr.response.isJSON()) + { + json = this.xhr.response.evalJSON(); + if (json && json.hash) + { + this.hash = json.hash; + } + } + + this.currentByte = endByte; + if (!isLast) + this.uploadOnePiece(); + else + this.finish(); + }, + handleError: function(ev) + { + console.log('Erro no ajax!') + console.log(ev); + }, + handleProgress: function(ev) + { + if (ev.type == 'progress') + this.renderProgress((this.currentByte + ev.loaded)/this.getFileSize()*99); + }, + handleAbort: function(ev) + { + console.log('Abortado!') + console.log(ev); + }, + finish: function() + { + this.renderProgress(100); + }, + renderProgress: function(progress) + { + var percent = Math.round(progress) + '%'; + this.progress_bar.down('.filling').setStyle({width: percent}) + this.progress_bar.down('.label').update(percent); + } +}); + /** * diff --git a/src/cake/app/plugins/typographer/views/elements/backstage_css.ctp b/src/cake/app/plugins/typographer/views/elements/backstage_css.ctp index 33edc48e..fd33e819 100644 --- a/src/cake/app/plugins/typographer/views/elements/backstage_css.ctp +++ b/src/cake/app/plugins/typographer/views/elements/backstage_css.ctp @@ -996,6 +996,7 @@ 'font-style' => 'italic', 'display' => 'block' )); + @@ -1270,6 +1271,34 @@ '#login_box input[type=text], #login_box input[type=password]', array( 'width' => $u->t($hg->size(array('M' => 4, 'g' => -1),false) - 2*($border_size + $padding_size)) )); + + $this->Decorator->rule( + '.input.buro .progress_bar', array( + 'border' => '1px solid ' . $palette['input_borders'], + 'height' => $u->t($vg->size(array('g' => 1.5),false) - 2*$border_size - $padding_top), + 'padding' => $u->t($padding_top) . ' ' . $u->t($padding_size), + 'width' => $u->t($hg->size(array('M' => 5, 'g' => -1),false) - 2*($border_size + $padding_size)), + 'position' => 'relative' + ) + ); + + $this->Decorator->rule( + '.input.buro .progress_bar .filling', array( + 'background' => $palette['menu_bg'], + 'float' => 'left', + 'height' => $u->t($vg->size(array('g' => 1.5),false) - 2*$border_size - $padding_top), + 'width' => 0 + ) + ); + + $this->Decorator->rule( + '.input.buro .progress_bar .label', array( + 'position' => 'absolute', + 'left' => 0, + 'text-align' => 'center', + 'width' => '100%' + ) + ); $this->Decorator->rule( 'select.buro', array( From a3d30b2d8a9f01e34297126f81a13a3907d83952 Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Sun, 3 Mar 2013 17:11:52 -0300 Subject: [PATCH 04/42] Receiving the pieces on JjMedia plugin --- .../controllers/jj_media_controller.php | 70 ++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php b/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php index 62264e44..4d624d09 100644 --- a/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php +++ b/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php @@ -170,10 +170,16 @@ function index($download = null, $data = null, $name = null) */ function upload() { + if ($this->RequestHandler->isAjax()) + { + $this->performAjaxUpload(); + return; + } + $saved = $error = false; $filename = ''; $validationErrors = array(); - + $version = $fieldName = $model_name = null; if (!empty($this->buroData['data'])) list($version, $fieldName, $model_name) = SecureParams::unpack($this->buroData['data']); @@ -215,4 +221,66 @@ function upload() $this->view = 'Typographer.Type'; $this->set(compact('error', 'validationErrors', 'saved', 'version', 'filename')); } + +/** + * Method to receive and glue pieces togheter on a ajax upload + * + * This method is NOT a action. It is called at JjMediaController::upload() + * when is detected that the upload is performed by a ajax request. + * + * @access protected + * @return void + */ + protected function performAjaxUpload() + { + $error = false; + $version = ''; + + $startByte = env('HTTP_X_UPLOADER_START_BYTE'); + $isLast = env('HTTP_X_UPLOADER_IS_LAST'); + + if (empty($this->data['SfilStoredFile']['file']['tmp_name'])) + { + $error = 'upload-failed'; + if (!empty($this->data['hash']) && file_exists(TMP . $hash)) + unlink(TMP . $hash); + + goto renderAjaxUpload; + } + + if (empty($this->data['hash'])) + { + $n = 0; + do { + $hash = uniqid('', true); + } while (file_exists(TMP . $hash)); + } + else + { + $hash = $this->data['hash']; + } + + $chunkFileName = $this->data['SfilStoredFile']['file']['tmp_name']; + $chunkFile = fopen($chunkFileName, 'rb'); + $gluedFile = fopen(TMP . $hash, 'ab'); + + if (!$chunkFile || !$gluedFile) + { + $error = 'reading-file-error'; + goto renderAjaxUpload; + } + + fwrite($gluedFile, fread($chunkFile, filesize($chunkFileName))); + fclose($chunkFile); + fclose($gluedFile); + + if ($isLast) + { + //$this->saveUpload(); + } + + renderAjaxUpload: + $this->view = 'JjUtils.Json'; + $this->set('jsonVars', compact('error', 'validationErrors', 'saved', 'version', 'filename', 'hash')); + } } From eadc161c92eca501d023bfaf359f837a46c7149e Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Sun, 3 Mar 2013 22:38:03 -0300 Subject: [PATCH 05/42] AjaxUpload progress: a lot of error checking and fail-proof code. --- .../plugins/burocrata/webroot/js/burocrata.js | 166 ++++++++++++++---- .../controllers/jj_media_controller.php | 34 +++- .../views/elements/backstage_css.ctp | 3 +- 3 files changed, 162 insertions(+), 41 deletions(-) diff --git a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js index e0442f22..bee34dbf 100644 --- a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js +++ b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js @@ -1794,7 +1794,12 @@ var BuroEditableList = Class.create(BuroCallbackable, { var CAPTIONS = { upload: { - sending: 'Enviando o arquivo #{fileName}. Aguarde...' + sending: 'Enviando o arquivo #{fileName}. Aguarde...', + hours_left: 'Faltando #{hours} horas', + minutes_left: 'Faltando #{minutes} minutos', + seconds_left: 'Faltando #{seconds} segundos', + cancel: 'Cancelar', + try_again: 'Tentar de novo' } }; @@ -2005,35 +2010,68 @@ var BuroAjaxUpload = Class.create(BuroCallbackable,{ { this.hidden_input = $('hi'+this.id_base); this.div_hidden = $('div'+this.id_base); + + this.controls = new Element('div'); + this.controls.insert(this.cancelLink = new Element('a', {href: '#'}).update(CAPTIONS.upload.cancel)); + this.cancelLink.on('click', function(ev){ ev.stop(); this.abort(); }.bind(this)); + this.controls.insert(this.tryAgainLink = new Element('a', {href: '#'}).update(CAPTIONS.upload.try_again)); + this.progress_bar = new Element('div', {className: 'progress_bar'}); this.progress_bar.insert(new Element('div', {className: 'filling'})); this.progress_bar.insert(new Element('span', {className: 'label'})); + this.upload_input = $('mi'+this.id_base); + this.upload_input.insert({ after: this.controls }); this.upload_input.insert({ after: this.progress_bar }); this.upload_input.on('change', this.inputChange.bind(this)); + + this.handleAbortBinded = this.handleAbort.bind(this); + this.handleErrorBinded = this.handleError.bind(this); + this.handleProgressBinded = this.handleProgress.bind(this); + this.uploadStatusChangeBinded = this.uploadStatusChange.bind(this); + + this.reset(); }, reset: function() { - this.currentByte = - this.hash = - this.file = null; + this.hash = this.startTime = this.file = null; + this.currentByte = this.errorCount = 0; + this.aborted = false; + + this.upload_input.value = ''; + this.progress_bar.setStyle({visibility: 'hidden'}); + this.controls.setStyle({visibility: 'hidden'}); + }, + abort: function() + { + this.aborted = true; + this.xhr && this.xhr.abort(); + this.reset(); + }, + again: function() + { + this.reset(); + this.upload_input.show(); + this.caption.remove(); }, inputChange: function(ev) { if (!this.upload_input.files.length) { - this.clearAll(); + this.reset(); } else if (this.upload_input.files.length == 1) { var file = this.upload_input.files[0], caption = CAPTIONS.upload.sending.interpolate({fileName: file.name || file.fileName}); - this.upload_input.insert({ after: (new Element('span')).insert(caption) }) + this.upload_input.insert({ after: this.caption = (new Element('span')).insert(caption) }) .hide(); this.reset(); this.file = file; this.uploadOnePiece(); + this.startTime = new Date().getTime(); + this.controls.setStyle({visibility: 'visible'}); } }, getFileSize: function() @@ -2044,32 +2082,41 @@ var BuroAjaxUpload = Class.create(BuroCallbackable,{ }, uploadOnePiece: function() { - var startByte = this.currentByte || 0, - endByte = Math.min(startByte + this.chunkSize, this.getFileSize()), - isLast = endByte == this.getFileSize(), - chunk, form; + if (this.xhr) + { + console.log('tentando enviar mais um sem terminar o anterior'); + return; + } + + var chunk, form; + + this.endByte = Math.min(this.currentByte + this.chunkSize, this.getFileSize()); + this.isLast = this.endByte == this.getFileSize(); if (this.file.mozSlice) - chunk = this.file.mozSlice(startByte, endByte); + chunk = this.file.mozSlice(this.currentByte, this.endByte); else if (this.file.webkitSlice) - chunk = this.file.webkitSlice(startByte, endByte); + chunk = this.file.webkitSlice(this.currentByte, this.endByte); else if (this.file.slice) - chunk = this.file.slice(startByte, chunkSize); + chunk = this.file.slice(this.currentByte, this.endByte - this.currentByte); if (!chunk) throw "Chunk is empty"; + console.log(this.currentByte); + this.xhr = new XMLHttpRequest(); - this.xhr.upload.addEventListener('error', this.handleError.bind(this)); - this.xhr.upload.addEventListener('progress', this.handleProgress.bind(this)); - this.xhr.upload.addEventListener('abort', this.handleAbort.bind(this)); - this.xhr.onreadystatechange = this.uploadStatusChange.bind(this, startByte, endByte, isLast); + this.xhr.upload.addEventListener('error', this.handleErrorBinded); + this.xhr.upload.addEventListener('progress', this.handleProgressBinded); + this.xhr.upload.addEventListener('abort', this.handleAbortBinded); + this.xhr.onreadystatechange = this.uploadStatusChangeBinded; this.xhr.open('POST', this.url, true); this.xhr.setRequestHeader('Cache-Control', 'no-cache'); this.xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); - this.xhr.setRequestHeader('X-Uploader-Start-Byte', startByte); - this.xhr.setRequestHeader('X-Uploader-Is-Last', isLast ? 'yes' : 'no'); + this.xhr.setRequestHeader('X-Uploader-Start-Byte', this.currentByte); + this.xhr.setRequestHeader('X-Uploader-Is-Last', this.isLast ? 'yes' : 'no'); + this.xhr.setRequestHeader('X-Uploader-Chunk-Size', this.endByte-this.currentByte); form = new FormData(); form.append(this.upload_input.name, chunk); @@ -2078,12 +2125,16 @@ var BuroAjaxUpload = Class.create(BuroCallbackable,{ this.xhr.send(form); }, - uploadStatusChange: function(startByte, endByte, isLast) + uploadStatusChange: function() { if (this.xhr.readyState != 4 || this.xhr.status != 200) return; - var jsone = false; + this.requestEnded(); + }, + requestEnded: function() + { + var json = false; if (this.xhr.response.isJSON()) { json = this.xhr.response.evalJSON(); @@ -2093,36 +2144,87 @@ var BuroAjaxUpload = Class.create(BuroCallbackable,{ } } - this.currentByte = endByte; - if (!isLast) - this.uploadOnePiece(); - else - this.finish(); + if (json.error) + { + if (json.error == 'chunk-doesnt-fit' && json.nextByte) + { + this.currentByte = json.nextByte; + } + this.handleError(); + return; + } + + this.currentByte = this.endByte; + this.clearXHR(); + this.errorCount = 0; + + if (!this.aborted) + { + if (!this.isLast) + this.uploadOnePiece(); + else + this.finish(json); + } + }, + clearXHR: function() + { + this.xhr.upload.removeEventListener('error', this.handleErrorBinded); + this.xhr.upload.removeEventListener('progress', this.handleProgressBinded); + this.xhr.upload.removeEventListener('abort', this.handleAbortBinded); + this.xhr.onreadystatechange = null; + this.xhr = null; }, handleError: function(ev) { - console.log('Erro no ajax!') - console.log(ev); + this.errorCount++; + if (this.errorCount < 5) + { + this.clearXHR(); + this.uploadOnePiece(); + } }, handleProgress: function(ev) { - if (ev.type == 'progress') - this.renderProgress((this.currentByte + ev.loaded)/this.getFileSize()*99); + this.renderProgress((this.currentByte + ev.loaded)/this.getFileSize()*99); }, handleAbort: function(ev) { console.log('Abortado!') console.log(ev); }, - finish: function() + finish: function(json) { this.renderProgress(100); + this.reset(); + }, renderProgress: function(progress) { - var percent = Math.round(progress) + '%'; + var percent = Math.round(progress) + '%', + timeTaken = new Date().getTime() - this.startTime, + timeLeft = (timeTaken / (progress/100)) - timeTaken, + formatedTime = new Date(); + + if (false) + { + formatedTime.setHours(0,0,0,timeLeft); + if (formatedTime.getHours()) + formatedTime = CAPTIONS.upload.hours_left.interpolate({hours: formatedTime.getHours() + ':' + formatedTime.getMinutes()}); + else if (formatedTime.getMinutes()) + formatedTime = CAPTIONS.upload.minutes_left.interpolate({minutes: formatedTime.getMinutes() + ':' + formatedTime.getSeconds()}); + else if (formatedTime.getSeconds()) + formatedTime = CAPTIONS.upload.seconds_left.interpolate({seconds: formatedTime.getSeconds()}); + else + formatedTime = false; + + console.log(formatedTime); + } + this.progress_bar.down('.filling').setStyle({width: percent}) this.progress_bar.down('.label').update(percent); + + if (timeLeft > 2000) + this.progress_bar.setStyle({visibility: 'visible'}); } }); diff --git a/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php b/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php index 4d624d09..bca5e755 100644 --- a/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php +++ b/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php @@ -158,7 +158,6 @@ function index($download = null, $data = null, $name = null) } } - /** * upload action * @@ -238,12 +237,17 @@ protected function performAjaxUpload() $startByte = env('HTTP_X_UPLOADER_START_BYTE'); $isLast = env('HTTP_X_UPLOADER_IS_LAST'); + $chunkSize = env('HTTP_X_UPLOADER_CHUNK_SIZE'); + + $uploadError = empty($this->data['SfilStoredFile']['file']['tmp_name']) + || !file_exists($chunkFileName = $this->data['SfilStoredFile']['file']['tmp_name']) + || filesize($chunkFileName) != $chunkSize; - if (empty($this->data['SfilStoredFile']['file']['tmp_name'])) + if ($uploadError) { $error = 'upload-failed'; - if (!empty($this->data['hash']) && file_exists(TMP . $hash)) - unlink(TMP . $hash); + //if (!empty($this->data['hash']) && file_exists(TMP . $hash)) + //unlink(TMP . $hash); goto renderAjaxUpload; } @@ -260,10 +264,17 @@ protected function performAjaxUpload() $hash = $this->data['hash']; } - $chunkFileName = $this->data['SfilStoredFile']['file']['tmp_name']; + $chunkFile = fopen($chunkFileName, 'rb'); $gluedFile = fopen(TMP . $hash, 'ab'); + if (filesize(TMP . $hash) != $startByte) + { + $error = 'chunk-doesnt-fit'; + $nextByte = filesize(TMP . $hash); + goto renderAjaxUpload; + } + if (!$chunkFile || !$gluedFile) { $error = 'reading-file-error'; @@ -274,13 +285,20 @@ protected function performAjaxUpload() fclose($chunkFile); fclose($gluedFile); - if ($isLast) + if ($isLast == 'yes') + { + $data = array( + 'SfilStoredFile' => array('file' => TMP . $hash) + ); + $this->saveUpload($data); + } + else { - //$this->saveUpload(); + $nextByte = filesize(TMP . $hash); } renderAjaxUpload: $this->view = 'JjUtils.Json'; - $this->set('jsonVars', compact('error', 'validationErrors', 'saved', 'version', 'filename', 'hash')); + $this->set('jsonVars', compact('error', 'validationErrors', 'saved', 'version', 'filename', 'hash', 'nextByte')); } } diff --git a/src/cake/app/plugins/typographer/views/elements/backstage_css.ctp b/src/cake/app/plugins/typographer/views/elements/backstage_css.ctp index fd33e819..a8af4b92 100644 --- a/src/cake/app/plugins/typographer/views/elements/backstage_css.ctp +++ b/src/cake/app/plugins/typographer/views/elements/backstage_css.ctp @@ -1278,7 +1278,8 @@ 'height' => $u->t($vg->size(array('g' => 1.5),false) - 2*$border_size - $padding_top), 'padding' => $u->t($padding_top) . ' ' . $u->t($padding_size), 'width' => $u->t($hg->size(array('M' => 5, 'g' => -1),false) - 2*($border_size + $padding_size)), - 'position' => 'relative' + 'position' => 'relative', + 'margin-top' => $vg->size('m') ) ); From 44699c3599ad9dbf4135f69ae68e1d3238d6ad72 Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Mon, 4 Mar 2013 09:04:17 -0300 Subject: [PATCH 06/42] Some steps forwarding to the AjaxUpload completion Passing the 'buroData' data via POST New Model SfilBigFile with a different set of validation Renaming the file after upload complete so the stored file keeps the original name --- .../plugins/burocrata/webroot/js/burocrata.js | 27 +++- .../controllers/jj_media_controller.php | 137 ++++++++++-------- .../plugins/jj_media/models/sfil_big_file.php | 62 ++++++++ 3 files changed, 161 insertions(+), 65 deletions(-) create mode 100644 src/cake/app/plugins/jj_media/models/sfil_big_file.php diff --git a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js index bee34dbf..43ec52e9 100644 --- a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js +++ b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js @@ -2000,6 +2000,9 @@ var BuroAjaxUpload = Class.create(BuroCallbackable,{ { this.id_base = id_base; this.url = url; + this.parameters = null; + if (typeof parameters == 'object') + this.parameters = parameters; BuroCR.set(this.id_base, this); @@ -2062,13 +2065,15 @@ var BuroAjaxUpload = Class.create(BuroCallbackable,{ } else if (this.upload_input.files.length == 1) { - var file = this.upload_input.files[0], - caption = CAPTIONS.upload.sending.interpolate({fileName: file.name || file.fileName}); - this.upload_input.insert({ after: this.caption = (new Element('span')).insert(caption) }) - .hide(); + var caption, file = this.upload_input.files[0]; this.reset(); this.file = file; + + caption = CAPTIONS.upload.sending.interpolate({fileName: this.getFileName()}); + this.upload_input + .insert({ after: this.caption = (new Element('span')).insert(caption) }) + .hide(); this.uploadOnePiece(); this.startTime = new Date().getTime(); this.controls.setStyle({visibility: 'visible'}); @@ -2080,6 +2085,12 @@ var BuroAjaxUpload = Class.create(BuroCallbackable,{ return this.file.size || this.file.fileSize; return null; }, + getFileName: function() + { + if (this.file) + return this.file.name || this.file.fileName; + return null; + }, uploadOnePiece: function() { if (this.xhr) @@ -2103,8 +2114,6 @@ var BuroAjaxUpload = Class.create(BuroCallbackable,{ if (!chunk) throw "Chunk is empty"; - console.log(this.currentByte); - this.xhr = new XMLHttpRequest(); this.xhr.upload.addEventListener('error', this.handleErrorBinded); this.xhr.upload.addEventListener('progress', this.handleProgressBinded); @@ -2120,9 +2129,15 @@ var BuroAjaxUpload = Class.create(BuroCallbackable,{ form = new FormData(); form.append(this.upload_input.name, chunk); + for (fieldName in this.parameters) + form.append(fieldName, this.parameters[fieldName]); + if (this.hash) form.append('data[hash]', this.hash); + if (this.isLast) + form.append('data[original_name]', this.getFileName()); + this.xhr.send(form); }, uploadStatusChange: function() diff --git a/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php b/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php index bca5e755..e77682f3 100644 --- a/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php +++ b/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php @@ -97,24 +97,24 @@ function index($download = null, $data = null, $name = null) if (count($unpacked) != 2) $this->cakeError('error404'); - $model_name = 'JjMedia.SfilStoredFile'; - if (!$this->loadModel($model_name)) + $modelName = 'JjMedia.SfilStoredFile'; + if (!$this->loadModel($modelName)) return; list($sfil_stored_files_id, $version) = $unpacked; - list($plugin, $model_name) = pluginSplit($model_name); - $model_alias = $this->{$model_name}->alias; + list($plugin, $modelName) = pluginSplit($modelName); + $model_alias = $this->{$modelName}->alias; if(!empty($sfil_stored_files_id)) { - $this->{$model_name}->contain(); - $file_data = $this->{$model_name}->findById($sfil_stored_files_id); + $this->{$modelName}->contain(); + $file_data = $this->{$modelName}->findById($sfil_stored_files_id); if (empty($file_data)) $this->cakeError('error404'); if (empty($name) && !$download) - $this->redirect(array($download, $data, $file_data[$this->{$model_name}->alias]['original_filename'])); + $this->redirect(array($download, $data, $file_data[$this->{$modelName}->alias]['original_filename'])); if(!empty($file_data)) { @@ -175,50 +175,10 @@ function upload() return; } - $saved = $error = false; - $filename = ''; - $validationErrors = array(); - - $version = $fieldName = $model_name = null; - if (!empty($this->buroData['data'])) - list($version, $fieldName, $model_name) = SecureParams::unpack($this->buroData['data']); - - if (is_null($version) || is_null($fieldName) || is_null($model_name)) - { - $validationErrors['file'] = 'post_max_size'; - } - elseif (!$this->loadModel($model_name)) - { - $error = Configure::read()>0?'JjMediaController::upload - Model '.$model_name.' not found.':true; - } - else - { - list($plugin, $model_name) = pluginSplit($model_name); - $Model =& $this->{$model_name}; - $model_alias = $Model->alias; - - if (!empty($this->data)) - { - $scope = $Model->findTheScope($fieldName); - if ($scope) - $Model->setScope($scope); - - $Model->set($this->data); - $validationErrors = $this->validateErrors($Model); + $this->saveUpload($this->data); - if (empty($validationErrors) && $Model->save(null, false)) - { - $saved = $Model->id; - $filename = $this->data[$model_alias]['file']['name']; - list($fieldModelName, $fieldName) = pluginSplit($fieldName); - if (!empty($this->data[$fieldModelName][$fieldName])) - $Model->delete($this->data[$fieldModelName][$fieldName]); - } - } - } $this->layout = 'ajax'; $this->view = 'Typographer.Type'; - $this->set(compact('error', 'validationErrors', 'saved', 'version', 'filename')); } /** @@ -229,6 +189,7 @@ function upload() * * @access protected * @return void + * @todo A garbage collector avoiding all the data that is left behind due errors */ protected function performAjaxUpload() { @@ -246,9 +207,6 @@ protected function performAjaxUpload() if ($uploadError) { $error = 'upload-failed'; - //if (!empty($this->data['hash']) && file_exists(TMP . $hash)) - //unlink(TMP . $hash); - goto renderAjaxUpload; } @@ -258,20 +216,21 @@ protected function performAjaxUpload() do { $hash = uniqid('', true); } while (file_exists(TMP . $hash)); + mkdir(TMP . $hash); } else { $hash = $this->data['hash']; } - $chunkFile = fopen($chunkFileName, 'rb'); - $gluedFile = fopen(TMP . $hash, 'ab'); + $gluedFileName = TMP . $hash . DS . 'file'; + $gluedFile = fopen($gluedFileName, 'ab'); - if (filesize(TMP . $hash) != $startByte) + if (filesize($gluedFileName) != $startByte) { $error = 'chunk-doesnt-fit'; - $nextByte = filesize(TMP . $hash); + $nextByte = filesize($gluedFileName); goto renderAjaxUpload; } @@ -287,10 +246,16 @@ protected function performAjaxUpload() if ($isLast == 'yes') { - $data = array( - 'SfilStoredFile' => array('file' => TMP . $hash) - ); - $this->saveUpload($data); + $originalName = TMP . $hash . DS . $this->data['original_name']; + rename($gluedFileName, $originalName); + + $data = array('SfilBigFile' => array('file' => $originalName)); + if (!$this->saveUpload($data, 'JjMedia.SfilBigFile')) + { + $validationErrors = $this->SfilBigFile->validationErrors; + } + unlink($originalName); + rmdir(TMP . $hash); } else { @@ -301,4 +266,58 @@ protected function performAjaxUpload() $this->view = 'JjUtils.Json'; $this->set('jsonVars', compact('error', 'validationErrors', 'saved', 'version', 'filename', 'hash', 'nextByte')); } + +/** + * + * + * @access + */ + protected function saveUpload($data, $forceModel = null) + { + $saved = $error = false; + $filename = ''; + $validationErrors = array(); + + $version = $fieldName = $modelName = null; + if (!empty($this->buroData['data'])) + list($version, $fieldName, $modelName) = SecureParams::unpack($this->buroData['data']); + + if ($forceModel) + $modelName = $forceModel; + + if (is_null($version) || is_null($fieldName) || is_null($modelName)) + { + $validationErrors['file'] = 'post_max_size'; + } + elseif (!$this->loadModel($modelName)) + { + $error = Configure::read()>0?'JjMediaController::upload - Model '.$modelName.' not found.':true; + } + else + { + list($plugin, $modelName) = pluginSplit($modelName); + $Model =& $this->{$modelName}; + $model_alias = $Model->alias; + + if (!empty($data)) + { + $scope = $Model->findTheScope($fieldName); + if ($scope) + $Model->setScope($scope); + + $Model->set($data); + $validationErrors = $this->validateErrors($Model); + + if (empty($validationErrors) && $Model->save(null, false)) + { + $saved = $Model->id; + $filename = $this->data[$model_alias]['file']['name']; + list($fieldModelName, $fieldName) = pluginSplit($fieldName); + if (!empty($this->data[$fieldModelName][$fieldName])) + $Model->delete($this->data[$fieldModelName][$fieldName]); + } + } + } + $this->set(compact('error', 'validationErrors', 'saved', 'version', 'filename')); + } } diff --git a/src/cake/app/plugins/jj_media/models/sfil_big_file.php b/src/cake/app/plugins/jj_media/models/sfil_big_file.php new file mode 100644 index 00000000..e02766ad --- /dev/null +++ b/src/cake/app/plugins/jj_media/models/sfil_big_file.php @@ -0,0 +1,62 @@ + array( + 'notempty' => array( + 'rule' => array('notempty'), + ), + ), + 'dirname' => array( + 'notempty' => array( + 'rule' => array('notempty'), + ), + ), + 'basename' => array( + 'notempty' => array( + 'rule' => array('notempty'), + ), + ), + 'original_filename' => array( + 'notempty' => array( + 'rule' => array('notempty'), + ), + ), + 'mime_type' => array( + 'notempty' => array( + 'rule' => array('notempty'), + ), + ), + 'size' => array( + 'numeric' => array( + 'rule' => array('numeric'), + ), + ), + 'file' => array( + 'resource' => array('rule' => 'checkResource'), + 'access' => array('rule' => 'checkAccess'), + 'location' => array('rule' => array('checkLocation', array(TMP))), + 'permission' => array('rule' => array('checkPermission', '*')), + 'size' => array('rule' => array('checkSize', '500M')) + ), + ); +} From 65a0fbd0b6385e8bbcf4358a0f346567721961c8 Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Mon, 4 Mar 2013 13:17:47 -0300 Subject: [PATCH 07/42] Deletion of UserProfile is disabled when the profile has users Disabling the button on backstage area Blocking the model when trying to delete a non empty profile --- .../plugins/backstage/config/backstage.php | 4 +- .../plugins/jj_users/models/user_profile.php | 40 +++++++++++-------- .../jj_users/views/elements/user_profile.ctp | 24 +++++++---- .../views/elements/backstage_css.ctp | 17 ++++---- 4 files changed, 50 insertions(+), 35 deletions(-) diff --git a/src/cake/app/plugins/backstage/config/backstage.php b/src/cake/app/plugins/backstage/config/backstage.php index 6ca95726..c9973dbe 100644 --- a/src/cake/app/plugins/backstage/config/backstage.php +++ b/src/cake/app/plugins/backstage/config/backstage.php @@ -55,7 +55,7 @@ ), 'customRow' => true, 'customSearch' => true, - 'contain' => array('UserPermission'), + 'contain' => array('UserPermission', 'UserUser'), ), 'user_permissions' => array( 'actions' => array('delete','edit', 'create'), @@ -70,4 +70,4 @@ 'customSearch' => true, ), ) -); \ No newline at end of file +); diff --git a/src/cake/app/plugins/jj_users/models/user_profile.php b/src/cake/app/plugins/jj_users/models/user_profile.php index 13460d19..17723358 100644 --- a/src/cake/app/plugins/jj_users/models/user_profile.php +++ b/src/cake/app/plugins/jj_users/models/user_profile.php @@ -32,32 +32,31 @@ class UserProfile extends JjUsersAppModel 'notempty' => array('rule' => array('notempty')), ) ); - + var $hasAndBelongsToMany = array( 'UserPermission' => array( 'className' => 'JjUsers.UserPermission', 'joinTable' => 'user_profiles_user_permissions', + ), + 'UserUser' => array( + 'className' => 'JjUsers.UserUser', + 'joinTable' => 'user_users_user_profiles', + 'unique' => false ) ); - - + function backDelete($id) { - $this->bindModel(array( - 'hasMany' => array( - 'UserUsersUserProfile' => array( - 'className' => 'jjUsers.UserUsersUserProfile', - ) - ) - )); - - $this->UserUsersUserProfile->deleteAll(array('user_profile_id' => $id), false); + $this->contain('UserUser'); + $data = $this->findById($id); + if (!empty($data['UserUser'])) + return false; return $this->delete($id); } - /* Creates a blank row in the table. It is part of the backstage contract. - * - */ +/** + * Creates a blank row in the table. It is part of the backstage contract. + */ function createEmpty() { @@ -66,5 +65,14 @@ function createEmpty() return $data; } - + +/** + * + * + * @access + */ + function afterSave() + { + + } } diff --git a/src/cake/app/plugins/jj_users/views/elements/user_profile.ctp b/src/cake/app/plugins/jj_users/views/elements/user_profile.ctp index 59939461..be3d9909 100644 --- a/src/cake/app/plugins/jj_users/views/elements/user_profile.ctp +++ b/src/cake/app/plugins/jj_users/views/elements/user_profile.ctp @@ -131,6 +131,13 @@ switch ($type[0]) break; case 'table': + echo $this->Bl->br(); + echo $this->Bl->sboxContainer(array(), array('size' => array('M' => 4))); + echo $this->Bl->pDry(__d('jj_users', 'Cada perfil engloba uma ou mais permissões do sistema administrativo. Atenção para a exclusão de perfis: não é possível excluir um perfil se o mesmo ainda está em uso por algum usuário.', true)); + echo $this->Bl->eboxContainer(); + echo $this->Bl->floatBreak(); + echo $this->Bl->br(); + $classSize = array('M' => 9, 'g' => -1); $this->Bl->TypeStyleFactory->widthGenerateClasses(array(0 => $classSize)); $className = $this->Bl->TypeStyleFactory->widthClassNames($classSize); @@ -166,7 +173,7 @@ switch ($type[0]) $smartTableRow[] = ' '; - $links = $this->Bl->sdiv(array('class' => 'actions', array())); + $links = $this->Bl->sdiv(array('class' => 'actions')); $links .= $this->Bl->anchor( array('class' => 'link_button'), @@ -178,14 +185,17 @@ switch ($type[0]) ); $delete_url = $this->Html->url(array('action' => 'delete_item','user_profiles', $data['UserProfile']['id'])); - $links .= $this->Bl->anchor( - array( + $htmlAttr = array( 'class' => 'link_button', 'onclick' => "deleteID = '". $delete_url . "'; showPopup('delete_alert_confirmation'); event.returnValue = false; return false;", - ), - array('url' => ''), - __d('backstage','Delete', true) - ); + ); + if (!empty($data['UserUser'])) + { + $htmlAttr['class'] .= ' disabled'; + $htmlAttr['onclick'] = "alert('Existem usuários com o perfil \'{$data['UserProfile']['name']}\'. Por isso não é possível apagá-lo.'); return false;"; + } + + $links .= $this->Bl->anchor($htmlAttr, array('url' => ''), __d('backstage','Delete', true)); $links .= $this->Bl->ediv(); diff --git a/src/cake/app/plugins/typographer/views/elements/backstage_css.ctp b/src/cake/app/plugins/typographer/views/elements/backstage_css.ctp index 33edc48e..8aa5be1f 100644 --- a/src/cake/app/plugins/typographer/views/elements/backstage_css.ctp +++ b/src/cake/app/plugins/typographer/views/elements/backstage_css.ctp @@ -478,16 +478,6 @@ 'margin-right' => $hg->size(array('m' => 2)), )); - $this->Decorator->rule( - 'a.link_button.disabled', array( - 'color' => $palette['button_fg_disabled']->write(), - 'background-color' => $palette['button_bg_disabled']->write(), - )); - - $this->Decorator->rule( - 'a.link_button:visited', array( - 'color' => $palette['text']->write(), - )); $this->Decorator->rule( 'a.link_button:hover', array( @@ -500,6 +490,13 @@ 'color' => $palette['bg']->write(), 'background-color' => $palette['button_bg_hover']->write(), )); + + $this->Decorator->rule( + 'a.link_button.disabled, a.link_button.disabled:active, a.link_button.disabled:hover', array( + 'color' => $palette['button_fg_disabled'], + 'border-color' => $palette['button_fg_disabled'] . '!important', + 'background-color' => $palette['button_bg_disabled'] + )); // Textile input From 68d7e4222a22169a3337a2d2345b1c76b5a36ea7 Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Mon, 4 Mar 2013 13:27:34 -0300 Subject: [PATCH 08/42] Reloading cache of compiled permission if needed Propagating changes of profiles to users Fixes #12 --- .../controllers/components/jj_auth.php | 29 +++++++++++++------ .../plugins/jj_users/models/user_profile.php | 25 +++++++++++----- 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/src/cake/app/plugins/jj_users/controllers/components/jj_auth.php b/src/cake/app/plugins/jj_users/controllers/components/jj_auth.php index b71a2193..07be8acf 100644 --- a/src/cake/app/plugins/jj_users/controllers/components/jj_auth.php +++ b/src/cake/app/plugins/jj_users/controllers/components/jj_auth.php @@ -56,26 +56,38 @@ function initialize(&$Controller, $settings = array()) /** * Compile the array of permissions suming all UserPermission.slug from database. * - * For performance pouposes, this array is cached on a session var. + * For performance pouposes, this array is cached on a session var. But it checks + * for the `modified` field on users table to decide when is necessary to update + * the cache. * * @access protected + * @param boolean $force When true, the cache will be updated + * @return void */ protected function compilePermissions($force = false) { - $permissions = $this->user('permissions'); - if (!empty($permissions) && !$force) - { - return; - } - $id = $this->user('id'); if (empty($id)) { $this->Session->delete($this->sessionKey); return; } - + $userModel =& $this->getModel(); + $permissions = $this->user('permissions'); + + if (!empty($permissions)) + { + $userModel->id = $id; + $last_modified_at = $userModel->field('modified'); + $force = $force || $last_modified_at != $this->user('modified'); + + if (!$force) + { + return; + } + } + $userData = $userModel->find('first', array( 'conditions' => array('UserUser.id' => $this->user('id')), 'contain' => array('UserProfile' => array('UserPermission')) @@ -88,7 +100,6 @@ protected function compilePermissions($force = false) $this->Session->write($this->sessionKey, $userData['UserUser']); } - /** * Verify the permissions * diff --git a/src/cake/app/plugins/jj_users/models/user_profile.php b/src/cake/app/plugins/jj_users/models/user_profile.php index 17723358..7cfaa3aa 100644 --- a/src/cake/app/plugins/jj_users/models/user_profile.php +++ b/src/cake/app/plugins/jj_users/models/user_profile.php @@ -59,20 +59,29 @@ function backDelete($id) */ function createEmpty() { - - $data = $this->saveAll(array($this->alias => array()), array('validate' => false)); - $data = $this->find('first', array('conditions' => array($this->alias.'.id' => $this->id))); - - return $data; + $saved = $this->saveAll(array($this->alias => array()), array('validate' => false)); + if ($saved) + return $this->id; + return false; } /** + * Ensures that all related users be updated forcing permission reload of logged users. * - * - * @access + * @access public */ function afterSave() { - + $this->contain('UserUser'); + $data = $this->read(); + + $usersId = Set::extract('/UserUser/id', $data); + if (!empty($usersId)) + { + $this->UserUser->updateAll( + array('UserUser.modified' => '"' . date('Y-m-d H:i:s') . '"'), + array('UserUser.id' => $usersId) + ); + } } } From 4ebfacb41c223b4d3d0b01250e6f5d7ff0568cea Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Mon, 4 Mar 2013 13:39:32 -0300 Subject: [PATCH 09/42] UserUser list changes Full name instead of first name on users list When the name is empty, displaying some demoted text --- .../plugins/jj_users/views/elements/user_user.ctp | 13 ++++++++++++- .../typographer/views/elements/backstage_css.ctp | 6 ++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/cake/app/plugins/jj_users/views/elements/user_user.ctp b/src/cake/app/plugins/jj_users/views/elements/user_user.ctp index f5b6e1ac..a537fa80 100644 --- a/src/cake/app/plugins/jj_users/views/elements/user_user.ctp +++ b/src/cake/app/plugins/jj_users/views/elements/user_user.ctp @@ -246,7 +246,18 @@ switch ($type[0]) case 'row': $smartTableRow = array(); - $smartTableRow[] = $data['UserUser']['name']; + $data['UserUser']['full_name'] = trim($data['UserUser']['full_name']); + if (empty($data['UserUser']['full_name'])) + { + $smartTableRow[] .= $this->Bl->span( + array('class' => 'demoted'), array(), + __d('jj_users', 'Sem nome, ainda', true) + ); + } + else + { + $smartTableRow[] = $data['UserUser']['full_name']; + } if (!empty($data['UserProfile'])) { diff --git a/src/cake/app/plugins/typographer/views/elements/backstage_css.ctp b/src/cake/app/plugins/typographer/views/elements/backstage_css.ctp index 8aa5be1f..f1c4ebcc 100644 --- a/src/cake/app/plugins/typographer/views/elements/backstage_css.ctp +++ b/src/cake/app/plugins/typographer/views/elements/backstage_css.ctp @@ -885,6 +885,12 @@ '.small_text', array( 'font-size' => $u->t($line_height * 11/18) )); + + $this->Decorator->rule( + '.demoted', array( + 'color' => $palette['button_fg_disabled'] + ) + ); // Control Box From 2ea4862c92f17e899f8e7f435c145f798ddbdeb0 Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Mon, 4 Mar 2013 15:51:13 -0300 Subject: [PATCH 10/42] Changed the password field of user form to a password input Fixes #2 Also, changing the label of the password input accordingly the content of database row. --- .../jj_users/views/elements/user_user.ctp | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/cake/app/plugins/jj_users/views/elements/user_user.ctp b/src/cake/app/plugins/jj_users/views/elements/user_user.ctp index a537fa80..e3afcf5d 100644 --- a/src/cake/app/plugins/jj_users/views/elements/user_user.ctp +++ b/src/cake/app/plugins/jj_users/views/elements/user_user.ctp @@ -111,22 +111,32 @@ switch ($type[0]) 'instructions' => __d('jj_users', 'username instructions', true) ) ); - + + if (empty($this->data['UserUser']['password'])) + { + $label = __d('jj_users', 'create password label', true); + $instructions = __d('jj_users', 'create password instructions', true); + } + else + { + $label = __d('jj_users', 'password_change label', true); + $instructions = __d('jj_users', 'password_change instructions', true); + } echo $this->Buro->input( array(), array( 'fieldName' => 'password_change', - 'type' => 'text', - 'label' => __d('jj_users', 'password_change label', true), - 'instructions' => __d('jj_users', 'password_change instructions', true) + 'type' => 'password', + 'label' => $label, + 'instructions' => $instructions ) ); - + echo $this->Buro->input( array(), array( 'fieldName' => 'password_retype', - 'type' => 'text', + 'type' => 'password', 'label' => __d('jj_users', 'password_retype label', true), 'instructions' => __d('jj_users', 'password_retype instructions', true) ) From 34bd8c6fa942b69fcc59c2eb15e8f10abdf91f35 Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Mon, 4 Mar 2013 15:52:51 -0300 Subject: [PATCH 11/42] Better validation and flux control for user form Some validation (still needing to use the get-text schema) Form updating the validation errors, always --- .../locale/por/LC_MESSAGES/jj_users.mo | Bin 2316 -> 2383 bytes .../locale/por/LC_MESSAGES/jj_users.po | 108 ++++++++++------- .../app/plugins/jj_users/models/user_user.php | 110 ++++++++++++------ .../jj_users/views/elements/user_user.ctp | 14 ++- 4 files changed, 149 insertions(+), 83 deletions(-) diff --git a/src/cake/app/plugins/jj_users/locale/por/LC_MESSAGES/jj_users.mo b/src/cake/app/plugins/jj_users/locale/por/LC_MESSAGES/jj_users.mo index 88f83bd4bbe332b3bbfe123a0c99b065a00f4805..5fd15bd86afc7f451dcc6ed32e9b9b205477185d 100644 GIT binary patch delta 948 zcmY+COK4L;6o#j1^RV`1;CL>ob>2%#=Svn=R#dNWNfBzNM>y(%bP+zBdF zu8JGM`r1{biZ1E{i6A1P2wkWfK{q0Z;8GXP z7eGw02UahFE1;iP{Sq96er5FskS_Ac>Te+Kz`iF##!h1J69L*#PjwQU0;!PGASJqB zbsWrKuWM+`3Q_bKL%<2GmtLwx?mT)u?yZ?y#zW~@DUsW_aQ57 zNJXVsrk_gK2uC9si$p9FQhzgWDwcjZU51Q`SPRd=x4_eIDuCVx8C{aY>FoIpP$mgGj-uBJ;C=2&y{svn%1J$x~cfy zN;?q!NaRvw;Z*}sl~G^v;lQMJh2}v+a3j51^fZ|bj|Q%hnv1$GHRd`qf>)$L{ecNu zbJ|tgc~eX2IW@thF_Jr?(NtV=g>$Nb>-lnwPYR>BqdZ^REi>Yn(m2RHLFYE6mEp3% VQKRRmG0sZuj8Qz5jSi)r{{`jlq2d4l delta 897 zcmXxi&ubGw6bJBe(u1$ z!GlV{>LQ+sP>)hPRP-ta!IO#}{2v58=+T3IUv@I^`0UHR-FdSwpL46ZwT7K#jIAXY z8-p8g8g9Zv@Ebe;f5Sa6^Z0JQSHQ*95yqzAZMYLYg%fZC?t*XO4EzA8{+DrlG|o$q zo^QZ?P{V2X0Mf>ZQ>$=^Y0{JqJ)K=jPM!sGBe%)o!CUi`vLI^H-7kKhJ}w81&!1xOoTfwa+_ z$>$+8wqWulqX%h2Z49A>{1&A8JCNRY-!TObO~E6RKY>jYJcHx#FQf-pbk@q#(b#?j z2FbFKu<||JW_biPO`m*F0;!2fL;-Oakwee{X#TWl+#Eqo(W3DT7yXB5ob*8sB4{!+ z=Ha5g=qqAHf2{SWpZJ(w_H|piGKj7vrY43754y|JUuY}owzlq#B&_+8?abQ6Szatw z%FYP~YpizJuFIP$P`YEE7on{1l2aVkIj1Y9%C=KR-9-_EcEcB)z!jnPE4;2-zPheC zuln&-^dnh_CR1D0ny);me9b%BlQ`xjVovf-|Apo)8OR%g3pbR$@J}LFE0Rl(FXG)z m9WAAg&PZ1_(U0U^kLxb?gbFxL(gtEts1?m>gDhH2_x}T)l!avg diff --git a/src/cake/app/plugins/jj_users/locale/por/LC_MESSAGES/jj_users.po b/src/cake/app/plugins/jj_users/locale/por/LC_MESSAGES/jj_users.po index 2bf93229..f5b2486c 100644 --- a/src/cake/app/plugins/jj_users/locale/por/LC_MESSAGES/jj_users.po +++ b/src/cake/app/plugins/jj_users/locale/por/LC_MESSAGES/jj_users.po @@ -4,146 +4,164 @@ msgid "" msgstr "" "Project-Id-Version: Jodel\n" -"POT-Creation-Date: 2012-05-15 11:30+0000\n" -"PO-Revision-Date: 2012-05-15 08:43-0300\n" -"Last-Translator: Rodrigo \n" +"POT-Creation-Date: 2013-03-04 15:38-0300\n" +"PO-Revision-Date: 2013-03-04 15:44-0300\n" +"Last-Translator: Daniel Abrahão \n" "Language-Team: \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" -#: \plugins\jj_users\views\elements\user_permission.ctp:47 +#: /plugins/jj_users/models/user_user.php:115 +msgid "Por favor, selecione ao menos um perfil" +msgstr "" + +#: /plugins/jj_users/views/elements/user_permission.ctp:60 msgid "user_permisson name label" msgstr "Nome" -#: \plugins\jj_users\views\elements\user_permission.ctp:48 +#: /plugins/jj_users/views/elements/user_permission.ctp:61 msgid "user_permission name instructions" msgstr " " -#: \plugins\jj_users\views\elements\user_permission.ctp:57 +#: /plugins/jj_users/views/elements/user_permission.ctp:70 msgid "user_permission slug label" msgstr "Slug" -#: \plugins\jj_users\views\elements\user_permission.ctp:58 +#: /plugins/jj_users/views/elements/user_permission.ctp:71 msgid "user_permission slug instructions" msgstr " " -#: \plugins\jj_users\views\elements\user_permission.ctp:67 +#: /plugins/jj_users/views/elements/user_permission.ctp:80 msgid "user_permission description label" msgstr "Descrição" -#: \plugins\jj_users\views\elements\user_permission.ctp:68 +#: /plugins/jj_users/views/elements/user_permission.ctp:81 msgid "user_permission description instructions" msgstr " " -#: \plugins\jj_users\views\elements\user_permission.ctp:77 -#: \plugins\jj_users\views\elements\user_profile.ctp:94 -#: \plugins\jj_users\views\elements\user_user.ctp:175;185 +#: /plugins/jj_users/views/elements/user_permission.ctp:90 +#: /plugins/jj_users/views/elements/user_profile.ctp:107 +#: /plugins/jj_users/views/elements/user_user.ctp:186;196 msgid "submit label" msgstr "Salvar" -#: \plugins\jj_users\views\elements\user_profile.ctp:48 +#: /plugins/jj_users/views/elements/user_profile.ctp:61 msgid "user_profile name label" msgstr "Nome" -#: \plugins\jj_users\views\elements\user_profile.ctp:49 +#: /plugins/jj_users/views/elements/user_profile.ctp:62 msgid "user_profile name instructions" msgstr " " -#: \plugins\jj_users\views\elements\user_profile.ctp:58 +#: /plugins/jj_users/views/elements/user_profile.ctp:71 msgid "user_profile slug label" msgstr "Slug" -#: \plugins\jj_users\views\elements\user_profile.ctp:59 +#: /plugins/jj_users/views/elements/user_profile.ctp:72 msgid "user_profile slug instructions" msgstr " " -#: \plugins\jj_users\views\elements\user_profile.ctp:68 +#: /plugins/jj_users/views/elements/user_profile.ctp:81 msgid "user_profile description label" msgstr "Descrição" -#: \plugins\jj_users\views\elements\user_profile.ctp:69 +#: /plugins/jj_users/views/elements/user_profile.ctp:82 msgid "user_profile description instructions" msgstr " " -#: \plugins\jj_users\views\elements\user_profile.ctp:78 +#: /plugins/jj_users/views/elements/user_profile.ctp:91 msgid "UserPermission label" msgstr "Permissões" -#: \plugins\jj_users\views\elements\user_profile.ctp:79 +#: /plugins/jj_users/views/elements/user_profile.ctp:92 msgid "UserPermission instructions" msgstr " " -#: \plugins\jj_users\views\elements\user_user.ctp:55 +#: /plugins/jj_users/views/elements/user_profile.ctp:136 +msgid "Cada perfil engloba uma ou mais permissões do sistema administrativo. Atenção para a exclusão de perfis: não é possível excluir um perfil se o mesmo ainda está em uso por algum usuário." +msgstr "" + +#: /plugins/jj_users/views/elements/user_user.ctp:68 msgid "name_surname super_field label" msgstr "Nome" -#: \plugins\jj_users\views\elements\user_user.ctp:56 +#: /plugins/jj_users/views/elements/user_user.ctp:69 msgid "name_surname super_field instructions" msgstr " " -#: \plugins\jj_users\views\elements\user_user.ctp:65 +#: /plugins/jj_users/views/elements/user_user.ctp:78 msgid "name label" msgstr "Primeiro nome" -#: \plugins\jj_users\views\elements\user_user.ctp:66 +#: /plugins/jj_users/views/elements/user_user.ctp:79 msgid "name instructions" msgstr " " -#: \plugins\jj_users\views\elements\user_user.ctp:75 +#: /plugins/jj_users/views/elements/user_user.ctp:88 msgid "surname label" msgstr "Sobrenome" -#: \plugins\jj_users\views\elements\user_user.ctp:76 +#: /plugins/jj_users/views/elements/user_user.ctp:89 msgid "surname instructions" msgstr " " -#: \plugins\jj_users\views\elements\user_user.ctp:87 +#: /plugins/jj_users/views/elements/user_user.ctp:100 msgid "account super_field label" msgstr "Sua conta" -#: \plugins\jj_users\views\elements\user_user.ctp:88 +#: /plugins/jj_users/views/elements/user_user.ctp:101 msgid "account super_field instructions" msgstr " " -#: \plugins\jj_users\views\elements\user_user.ctp:97 +#: /plugins/jj_users/views/elements/user_user.ctp:110 msgid "username label" msgstr "Nome de usuário" -#: \plugins\jj_users\views\elements\user_user.ctp:98 +#: /plugins/jj_users/views/elements/user_user.ctp:111 msgid "username instructions" msgstr "Da próxima vez que for acessar a página administrativa, você deverá usar esse nome de usuário." -#: \plugins\jj_users\views\elements\user_user.ctp:107 +#: /plugins/jj_users/views/elements/user_user.ctp:117 +msgid "create password label" +msgstr "Criar uma senha" + +#: /plugins/jj_users/views/elements/user_user.ctp:118 +msgid "create password instructions" +msgstr " " + +#: /plugins/jj_users/views/elements/user_user.ctp:122 msgid "password_change label" msgstr "Alterar a senha" -#: \plugins\jj_users\views\elements\user_user.ctp:108 +#: /plugins/jj_users/views/elements/user_user.ctp:123 msgid "password_change instructions" -msgstr "Se não deseja alterar, deixe em branco" +msgstr "Se quiser alterar a senha deste usuário, preencha esse campo e o seguinte. Caso contrário, favor deixar ambos em branco. " -#: \plugins\jj_users\views\elements\user_user.ctp:117 +#: /plugins/jj_users/views/elements/user_user.ctp:140 msgid "password_retype label" msgstr "Repita a senha" -#: \plugins\jj_users\views\elements\user_user.ctp:118 +#: /plugins/jj_users/views/elements/user_user.ctp:141 msgid "password_retype instructions" msgstr " " -#: \plugins\jj_users\views\elements\user_user.ctp:129 -msgid "profiles super_field label" -msgstr "Perfis" - -#: \plugins\jj_users\views\elements\user_user.ctp:130 -msgid "profiles super_field instructions" -msgstr "Selecione um ou mais perfis abaixo" - -#: \plugins\jj_users\views\elements\user_user.ctp:155 +#: /plugins/jj_users/views/elements/user_user.ctp:169 msgid "UserProfile label" msgstr "Perfis" -#: \plugins\jj_users\views\elements\user_user.ctp:156 +#: /plugins/jj_users/views/elements/user_user.ctp:170 msgid "UserProfile instructions" msgstr " " +#: /plugins/jj_users/views/elements/user_user.ctp:264 +msgid "Sem nome, ainda" +msgstr "" + +#~ msgid "profiles super_field label" +#~ msgstr "Perfis" + +#~ msgid "profiles super_field instructions" +#~ msgstr "Selecione um ou mais perfis abaixo" diff --git a/src/cake/app/plugins/jj_users/models/user_user.php b/src/cake/app/plugins/jj_users/models/user_user.php index c744d71e..e101ed63 100644 --- a/src/cake/app/plugins/jj_users/models/user_user.php +++ b/src/cake/app/plugins/jj_users/models/user_user.php @@ -26,68 +26,106 @@ class UserUser extends JjUsersAppModel var $validate = array( 'name' => array( - 'notempty' => array('rule' => array('notempty')) + 'rule' => 'notEmpty', + 'message' => 'Não deixe em branco' ), 'email' => array( - 'notempty' => array('rule' => array('notempty')), - 'email' => array('rule' => array('email')) + 'notempty' => array( + 'rule' => 'notEmpty', + 'message' => 'Não deixe em branco' + ), + 'email' => array( + 'rule' => 'email' + ) ), 'username' => array( - 'notempty' => array('rule' => array('notempty')), + 'rule' => 'notEmpty', + 'message' => 'Não deixe em branco' ), 'password_change' => array( - 'notempty' => array('rule' => array('notempty')), - 'minLength' => array('rule' => array('minLength', 6), 'message' => 'A senha deve conter no mínimo 6 caracteres.') + 'minLength' => array( + 'rule' => array('minLength', 6), + 'message' => 'A senha deve conter no mínimo 6 caracteres.' + ) ), 'password_retype' => array( - 'same' => array('rule' => array('identicalFieldValues', 'password_change')) - ), + 'rule' => array('identicalFieldValues', 'password_change'), + 'message' => 'Deve ser igual ao campo anterior' + ) ); - - var $hasAndBelongsToMany = array('UserProfile' => array('className' => 'JjUsers.UserProfile', 'joinTable' => 'user_users_user_profiles')); - - - /* Creates a blank row in the table. It is part of the backstage contract. - * - */ +/** + * Many to many relationship + * + * @access + */ + var $hasAndBelongsToMany = array( + 'UserProfile' => array( + 'className' => 'JjUsers.UserProfile', + 'joinTable' => 'user_users_user_profiles' + ) + ); + +/** + * Creates a blank row in the table. It is part of the backstage contract. + */ function createEmpty() { - - $data = $this->saveAll(array(), array('validate' => false)); - $data = $this->find('first', array('conditions' => array($this->alias.'.id' => $this->id))); - - return $data; + if ($this->saveAll(array(), array('validate' => false))) + return $this->id; + return false; } - + +/** + * Saves data from burocrata form + * + * This method does some data validation and manipulation mainly + * with the password sent + * + * @access public + * @param array $data Data to save + */ function saveBurocrata($data) - { - App::import('Component','JjUsers.JjAuth'); - + { + unset($data[$this->alias]['password']); + $this->set($data); - - if ($this->validates()) { - if (!empty($data[$this->alias]['password_change'])) { - $data[$this->alias]['password'] = JjAuthComponent::password($data[$this->alias]['password_change']); - } + + if ($this->validates()) + { + if (!empty($data[$this->alias]['password_change'])) + $data[$this->alias]['password'] = Security::hash($data[$this->alias]['password_change'], null, true); - return $this->saveAll($data); - } - else { - return false; + return $this->save($data); } + return false; } - + +/** + * Some hard-coded validations + * + * @access public + */ function beforeValidate($options) { if (empty($this->data[$this->alias]['password_change']) && empty($this->data[$this->alias]['password_retype'])) unset($this->data[$this->alias]['password_change'], $this->data[$this->alias]['password_retype']); + + $currentPassword = $this->field('password'); + if (empty($currentPassword) && empty($this->data[$this->alias]['password_change'])) + $this->invalidate('password_change', __d('jj_user', 'Favor criar uma senha para o usuário.', true)); - if ((!isset($this->data['UserProfile']['UserProfile']) || empty($this->data['UserProfile']['UserProfile'])) && isset($this->data[$this->alias]['validate_profiles'])) + if (empty($this->data['UserProfile']['UserProfile']) && isset($this->data[$this->alias]['validate_profiles'])) { $this->invalidate('non_existent_field'); // fake validation error on Profile - $this->UserProfile->invalidate('UserProfile', 'Por favor, selecione ao menos um perfil'); + $this->UserProfile->invalidate('UserProfile', __d('jj_users', 'Por favor, selecione ao menos um perfil', true)); } return true; } + + function findBurocrata($user_user_id) + { + $this->contain('UserProfile'); + return $this->findById($user_user_id); + } } diff --git a/src/cake/app/plugins/jj_users/views/elements/user_user.ctp b/src/cake/app/plugins/jj_users/views/elements/user_user.ctp index e3afcf5d..7f7e19b3 100644 --- a/src/cake/app/plugins/jj_users/views/elements/user_user.ctp +++ b/src/cake/app/plugins/jj_users/views/elements/user_user.ctp @@ -55,8 +55,8 @@ switch ($type[0]) 'callbacks' => array( 'onStart' => array('lockForm', 'js' => 'form.setLoading()'), 'onComplete' => array('unlockForm', 'js' => 'form.unsetLoading()'), - 'onReject' => array('js' => '$("content").scrollTo(); showPopup("error");', 'contentUpdate' => 'replace'), - 'onSave' => array('js' => '$("content").scrollTo(); showPopup("custom_notice");'), + 'onReject' => array('contentUpdate' => 'replace', 'js' => 'showPopup("error");'), + 'onSave' => array('contentUpdate' => 'replace', 'js' => 'showPopup("custom_notice");'), ) )); } @@ -121,6 +121,16 @@ switch ($type[0]) { $label = __d('jj_users', 'password_change label', true); $instructions = __d('jj_users', 'password_change instructions', true); + echo $this->Buro->input( + array(), + array( + 'type' => 'hidden', + 'fieldName' => 'password', + 'options' => array( + 'value' => 'nothing_here' + ) + ) + ); } echo $this->Buro->input( array(), From 225872c8fec6189bd5155dfdbf214973ded22429 Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Wed, 6 Mar 2013 15:50:04 -0300 Subject: [PATCH 12/42] Creating a caption manager for Javascript Using the manager at Upload validation for testing. --- .../views/helpers/buro_burocrata.php | 9 ++- .../views/helpers/buro_office_boy.php | 49 ++++++++++++--- .../plugins/burocrata/webroot/js/burocrata.js | 60 ++++++++++++++++--- 3 files changed, 98 insertions(+), 20 deletions(-) diff --git a/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php b/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php index 82ede28b..6f27930e 100644 --- a/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php +++ b/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php @@ -2363,9 +2363,12 @@ protected function _uploadParams($options) $gen_options['error'] = $file_input_options['error']; unset($file_input_options['error']); } - - $gen_options['error']['size'] = __d('burocrata', 'The uploaded file is too large. (filesize > upload_max_filesize or filesize > Model::$validate definitions)', true); - $gen_options['error']['post_max_size'] = __d('burocrata', 'The uploaded file is too large. (filesize > post_max_size)', true); + + $this->BuroOfficeBoy->addCaption('upload', 'error_size', __d('burocrata', 'The uploaded file is too large. (filesize > upload_max_filesize or filesize > Model::$validate definitions)', true)); + $this->BuroOfficeBoy->addCaption('upload', 'error_post_max_size', __d('burocrata', 'The uploaded file is too large. (filesize > post_max_size)', true)); + $this->BuroOfficeBoy->addCaption('upload', 'error_location', __d('burocrata', 'The upload process could not be completed because the file was placed on a non-allowed directory.', true)); + $this->BuroOfficeBoy->addCaption('upload', 'error_access', __d('burocrata', 'The resource is blocked and the webserver can not work properly with it.', true)); + $this->BuroOfficeBoy->addCaption('upload', 'error_resource', __d('burocrata', 'The upload data does not define any type of resource', true)); return compact('gen_options', 'file_input_options'); } diff --git a/src/cake/app/plugins/burocrata/views/helpers/buro_office_boy.php b/src/cake/app/plugins/burocrata/views/helpers/buro_office_boy.php index 711f85eb..5e92026a 100644 --- a/src/cake/app/plugins/burocrata/views/helpers/buro_office_boy.php +++ b/src/cake/app/plugins/burocrata/views/helpers/buro_office_boy.php @@ -40,6 +40,17 @@ class BuroOfficeBoyHelper extends AppHelper */ public $helpers = array('Html', 'Ajax', 'Js' => 'prototype'); +/** + * List of captions for JS + * + * This variable holds a list of captions that will or may be used by the Javascript + * for construct some interface items. + * + * @access protected + * @var array + */ + protected $captions = array(); + /** * Callbacks template * @@ -141,14 +152,37 @@ public function afterRender() $View = ClassRegistry::getObject('view'); if ($View && !$this->Ajax->isAjax()) { - $this->Html->scriptBlock('var debug = ' . Configure::read() . ';', array('inline' => false)); + $preScript = array(); + $preScript[] = 'var debug = ' . Configure::read() . ';'; + if (empty($this->captions)) + $preScript[] = 'var buroCaptions = {};'; + else + $preScript[] = 'var buroCaptions = '.$this->Js->object($this->captions).';'; $script = implode("\n", $this->scripts); if (Configure::read('debug')) - $script = sprintf('try{ %s }catch(e){ console.log(e); }', $script); - - $View->addScript($this->Html->scriptBlock($this->Js->domReady($script))); + $script = sprintf('try{ %s }catch(e){ console.error(e); }', $script); + + $script = implode("\n", $preScript) . "\n" . $this->Js->domReady($script); + + $View->addScript($this->Html->scriptBlock($script)); } + elseif (!empty($this->captions)) + { + $captions = $this->Js->object($this->captions); + echo $this->addHtmlEmbScript("BuroCaption.merge($captions)"); + } + } + +/** + * Add caption for JS interface + * + * Those captions will be available using the buroCaption method + * @access public + */ + public function addCaption($space, $key, $caption = '') + { + $this->captions[$space][$key] = $caption; } /** @@ -300,17 +334,14 @@ public function listOfItems($options) */ public function upload($options) { - $defaults = array('callbacks' => array(), 'baseID' => uniqid(), 'url' => '', 'error' => array()); + $defaults = array('callbacks' => array(), 'baseID' => uniqid(), 'url' => ''); extract(am($defaults, $options)); unset($defaults); - if (!empty($error)) $error = $this->Js->object($error); - else $error = '{}'; - if (!empty($parameters)) $parameters = $this->Js->object($parameters); else $parameters = '{}'; - $script = sprintf("new BuroUpload('%s', '%s', %s, %s)", $baseID, $url, $error, $parameters); + $script = sprintf("new BuroUpload('%s', '%s', %s)", $baseID, $url, $parameters); if(!empty($callbacks) && is_array($callbacks)) $script .= sprintf('.addCallbacks(%s)', $this->formatCallbacks('upload', $callbacks)); diff --git a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js index 0698d87a..1bc8d665 100644 --- a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js +++ b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js @@ -49,6 +49,46 @@ var BuroCR = new (Class.create(Hash, { }))(); +/** + * Caption manager + * + * BuroCaption is an instace at window scope that is used to retrieve + * a caption given a namespace and a key. + * + * If either do not exists at the calling time, than it issues an error + * + * @access public + */ +var BuroCaption = new (Class.create({ + initialize: function() + {}, + get: function(space, key) + { + if (!this.isSet(space, key)) + throw "BuroCaption::get() - Pair space/key given ("+space+"/"+key+") is not set."; + + return buroCaptions[space][key]; + }, + isSet: function(space, key) + { + if (Object.isUndefined(buroCaptions[space])) + return false; + if (Object.isUndefined(buroCaptions[space][key])) + return false; + return true; + }, + merge: function(data) + { + if (typeof data != 'object') + throw "BuroCaption::merge() - Data must be an object"; + + for (space in data) + for (key in data[space]) + buroCaptions[space][key] = data[space][key]; + } +}))(); + + /** * Abstract class that implements the behaviour of callbacks * with the methods `addCallbacks` and `trigger` @@ -1807,7 +1847,7 @@ var BuroEditableList = Class.create(BuroCallbackable, { * @access public */ var BuroUpload = Class.create(BuroCallbackable, { - initialize: function(id_base, url, errors, parameters) + initialize: function(id_base, url, parameters) { if (Prototype.Browser.IE) { @@ -1821,7 +1861,6 @@ var BuroUpload = Class.create(BuroCallbackable, { this.uploading = false; this.id_base = id_base; this.url = url; - this.errors = errors; this.parameters = $H(parameters); BuroCR.set(this.id_base, this); @@ -1953,17 +1992,22 @@ var BuroUpload = Class.create(BuroCallbackable, { }, rejected: function() { + var errorName, errorMsg = []; this.hidden_input.value = ''; - if (this.responseJSON.validationErrors && this.errors) + if (typeof this.responseJSON.validationErrors == 'object') { - if (this.errors[$H(this.responseJSON.validationErrors).values()[0]]) - this.responseJSON.error = this.errors[$H(this.responseJSON.validationErrors).values()[0]]; - else - this.responseJSON.error = $H(this.responseJSON.validationErrors).values()[0]; + for (errorName in this.responseJSON.validationErrors) + { + errorName = this.responseJSON.validationErrors[errorName]; + if (BuroCaption.isSet('upload', 'error_'+errorName)) + errorMsg.push(BuroCaption.get('upload', 'error_'+errorName)) + else + errorMsg.push(errorName); + } } this.div_hidden.up().addClassName('error'); - this.div_hidden.up().insert(new Element('div', {className:'error-message'}).update(this.responseJSON.error)); + this.div_hidden.up().insert(new Element('div', {className:'error-message'}).update(errorMsg.join('
'))); this.trigger('onReject', this.tmp_input, this.responseJSON, this.responseJSON.saved); From 7a8920c7eb4d1c25749f12d3aad5b70a8bfdc334 Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Thu, 7 Mar 2013 11:12:10 -0300 Subject: [PATCH 13/42] Caption system ready Created getter for captions on BuroOfficeBoyHelper Handling ajax calls with JsonView (injecting the captions into the Json object) Merging captions when the Json comes with extra captions --- .../views/helpers/buro_office_boy.php | 34 ++++++++++++++---- .../plugins/burocrata/webroot/js/burocrata.js | 22 ++++++++++-- .../jj_media/views/jj_media/upload.ctp | 4 ++- src/cake/app/plugins/jj_utils/views/json.php | 35 +++++++++++++------ 4 files changed, 74 insertions(+), 21 deletions(-) diff --git a/src/cake/app/plugins/burocrata/views/helpers/buro_office_boy.php b/src/cake/app/plugins/burocrata/views/helpers/buro_office_boy.php index 5e92026a..40964028 100644 --- a/src/cake/app/plugins/burocrata/views/helpers/buro_office_boy.php +++ b/src/cake/app/plugins/burocrata/views/helpers/buro_office_boy.php @@ -154,6 +154,8 @@ public function afterRender() { $preScript = array(); $preScript[] = 'var debug = ' . Configure::read() . ';'; + + // Ajax calls will handle captions on JsonView or directly on View if (empty($this->captions)) $preScript[] = 'var buroCaptions = {};'; else @@ -167,17 +169,13 @@ public function afterRender() $View->addScript($this->Html->scriptBlock($script)); } - elseif (!empty($this->captions)) - { - $captions = $this->Js->object($this->captions); - echo $this->addHtmlEmbScript("BuroCaption.merge($captions)"); - } } /** * Add caption for JS interface * - * Those captions will be available using the buroCaption method + * Those captions will be available using the BuroCaption instance on JS + * * @access public */ public function addCaption($space, $key, $caption = '') @@ -185,6 +183,30 @@ public function addCaption($space, $key, $caption = '') $this->captions[$space][$key] = $caption; } +/** + * Returns all caption structure + * + * @access public + */ + public function getAllCaptions($flush = true) + { + $captions = $this->captions; + if ($flush) + $this->flushCaptions(); + + return $captions; + } + +/** + * Empties all registered captions + * + * @access public + */ + public function flushCaptions() + { + $this->captions = array(); + } + /** * Creates the javascript counter-part of one autocomplete input. * diff --git a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js index 1bc8d665..e873f4b7 100644 --- a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js +++ b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js @@ -83,8 +83,17 @@ var BuroCaption = new (Class.create({ throw "BuroCaption::merge() - Data must be an object"; for (space in data) + { + if (typeof data[space] != 'object') + throw "BuroCaption::merge() - Data inside each space must be object"; + for (key in data[space]) + { + if (!buroCaptions[space]) + buroCaptions[space] = {}; buroCaptions[space][key] = data[space][key]; + } + } } }))(); @@ -629,10 +638,17 @@ var BuroAjax = Class.create(BuroCallbackable, { this.trigger('onError', E_NOT_JSON); if (debug != 0 && !this.fulldebug) this.dumpResquest(re); - } else if (json.error != false) { - this.trigger('onError', E_JSON, json.error, json); } else { - this.trigger('onSuccess', re, json); + if (json.extraCaptions) { + BuroCaption.merge(json.extraCaptions); + delete json.extraCaptions; + } + + if (json.error != false) { + this.trigger('onError', E_JSON, json.error, json); + } else { + this.trigger('onSuccess', re, json); + } } }, requestOnFailure: function(re) diff --git a/src/cake/app/plugins/jj_media/views/jj_media/upload.ctp b/src/cake/app/plugins/jj_media/views/jj_media/upload.ctp index 97754d2f..447b382b 100644 --- a/src/cake/app/plugins/jj_media/views/jj_media/upload.ctp +++ b/src/cake/app/plugins/jj_media/views/jj_media/upload.ctp @@ -19,5 +19,7 @@ $url = $this->Bl->fileURL($saved, $version); $dlurl = $this->Bl->fileURL($saved, $version, true); } + + $extraCaptions = $this->BuroOfficeBoy->getAllCaptions(); - echo json_encode(compact('error', 'validationErrors', 'saved', 'url', 'dlurl', 'filename')); \ No newline at end of file + echo json_encode(compact('error', 'validationErrors', 'saved', 'url', 'dlurl', 'filename', 'extraCaptions')); diff --git a/src/cake/app/plugins/jj_utils/views/json.php b/src/cake/app/plugins/jj_utils/views/json.php index 2147bb70..3ea78090 100644 --- a/src/cake/app/plugins/jj_utils/views/json.php +++ b/src/cake/app/plugins/jj_utils/views/json.php @@ -36,18 +36,31 @@ function render($action = null, $layout = null, $file = null) if(Configure::read() > 1) Configure::write('debug', 1); header('Content-Type: application/json; charset=UTF-8'); - - $loaded; - if(!isset($this->Js)) - $this->_loadHelpers($loaded, array('Js')); - $this->Js = $loaded['Js']; - - if(isset($this->viewVars['jsonVars'])) { - return $this->Js->object($this->viewVars['jsonVars']); - } else { - if(empty($layout)) + + if (isset($this->viewVars['jsonVars'])) + { + return json_encode($this->viewVars['jsonVars']); + } + else + { + if (empty($layout)) $layout = 'ajax'; - return parent::render($action, $layout, $file); + + $out = parent::render($action, $layout, $file); + + if (isset($this->BuroOfficeBoy)) + { + $extraCaptions = $this->BuroOfficeBoy->getAllCaptions(); + if (!empty($extraCaptions)) + { + $json = json_decode($out, true); + if (is_array($json)) + $json['extraCaptions'] = $extraCaptions; + $out = json_encode($json); + } + } + + return $out; } } } From 74a3618156be2343ed43aa751de0ad0c2098d7ac Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Fri, 8 Mar 2013 16:29:49 -0300 Subject: [PATCH 14/42] Some fixes making the AjaxUpload funcional Location validation fixed JjMediaController::saveUpload() method fixed --- src/cake/app/plugins/burocrata/webroot/js/burocrata.js | 4 ++-- .../plugins/jj_media/controllers/jj_media_controller.php | 8 +++++--- src/cake/app/plugins/jj_media/models/sfil_big_file.php | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js index aa5ade71..28668640 100644 --- a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js +++ b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js @@ -1897,7 +1897,7 @@ var BuroUpload = Class.create(BuroCallbackable, { if (this.ajax_upload) { - new BuroAjaxUpload(id_base, url, errors, parameters); + new BuroAjaxUpload(id_base, url, parameters); return; } @@ -2056,7 +2056,7 @@ var BuroUpload = Class.create(BuroCallbackable, { var BuroAjaxUpload = Class.create(BuroCallbackable,{ chunkSize: 1024*1024, // 1M - initialize: function(id_base, url, errors, parameters) + initialize: function(id_base, url, parameters) { this.id_base = id_base; this.url = url; diff --git a/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php b/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php index e77682f3..5f089392 100644 --- a/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php +++ b/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php @@ -311,10 +311,12 @@ protected function saveUpload($data, $forceModel = null) if (empty($validationErrors) && $Model->save(null, false)) { $saved = $Model->id; - $filename = $this->data[$model_alias]['file']['name']; + if (isset($data[$model_alias]['file']['name'])) + $filename = $data[$model_alias]['file']['name']; + list($fieldModelName, $fieldName) = pluginSplit($fieldName); - if (!empty($this->data[$fieldModelName][$fieldName])) - $Model->delete($this->data[$fieldModelName][$fieldName]); + if (!empty($data[$fieldModelName][$fieldName])) + $Model->delete($data[$fieldModelName][$fieldName]); } } } diff --git a/src/cake/app/plugins/jj_media/models/sfil_big_file.php b/src/cake/app/plugins/jj_media/models/sfil_big_file.php index e02766ad..409ec629 100644 --- a/src/cake/app/plugins/jj_media/models/sfil_big_file.php +++ b/src/cake/app/plugins/jj_media/models/sfil_big_file.php @@ -54,7 +54,7 @@ class SfilBigFile extends SfilStoredFile 'file' => array( 'resource' => array('rule' => 'checkResource'), 'access' => array('rule' => 'checkAccess'), - 'location' => array('rule' => array('checkLocation', array(TMP))), + 'location' => array('rule' => array('checkLocation', array(MEDIA_TRANSFER, TMP))), 'permission' => array('rule' => array('checkPermission', '*')), 'size' => array('rule' => array('checkSize', '500M')) ), From 2801a835210ee7b9eed3bbfb723e659146348261 Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Fri, 8 Mar 2013 16:30:37 -0300 Subject: [PATCH 15/42] New helper class: BuroCaptionerHelper --- .../views/helpers/buro_burocrata.php | 25 ++----- .../views/helpers/buro_captioner.php | 66 +++++++++++++++++++ .../views/helpers/buro_office_boy.php | 9 --- 3 files changed, 73 insertions(+), 27 deletions(-) create mode 100644 src/cake/app/plugins/burocrata/views/helpers/buro_captioner.php diff --git a/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php b/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php index 6f27930e..8dbf4ba8 100644 --- a/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php +++ b/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php @@ -12,29 +12,22 @@ * @link https://github.com/prefacedesign/jodeljodel Jodel Jodel public repository */ -/** - * Main Helper for burocrata plugin - * - * PHP versions 5 - * - * @package jodel - * @subpackage jodel.burocrata.views.helpers - */ App::import('Helper', 'Burocrata.XmlTag'); App::import('Lib', 'JjUtils.SecureParams'); - /** - * BuroOfficeBoy helper. + * Main Helper for burocrata plugin * - * Creates all javascript necessary for BuroBurocrataHelper work. + * PHP versions 5 * * @package jodel * @subpackage jodel.burocrata.views.helpers */ class BuroBurocrataHelper extends XmlTagHelper { - public $helpers = array('Html', 'Form', 'Ajax', 'Js' => 'prototype', 'Burocrata.BuroOfficeBoy', + public $helpers = array('Html', 'Form', 'Ajax', 'Js' => 'prototype', + 'Burocrata.BuroOfficeBoy', + 'Burocrata.BuroCaptioner', 'JjUtils.Jodel', 'Typographer.*TypeBricklayer' => array( 'name' => 'Bl', @@ -2364,12 +2357,8 @@ protected function _uploadParams($options) unset($file_input_options['error']); } - $this->BuroOfficeBoy->addCaption('upload', 'error_size', __d('burocrata', 'The uploaded file is too large. (filesize > upload_max_filesize or filesize > Model::$validate definitions)', true)); - $this->BuroOfficeBoy->addCaption('upload', 'error_post_max_size', __d('burocrata', 'The uploaded file is too large. (filesize > post_max_size)', true)); - $this->BuroOfficeBoy->addCaption('upload', 'error_location', __d('burocrata', 'The upload process could not be completed because the file was placed on a non-allowed directory.', true)); - $this->BuroOfficeBoy->addCaption('upload', 'error_access', __d('burocrata', 'The resource is blocked and the webserver can not work properly with it.', true)); - $this->BuroOfficeBoy->addCaption('upload', 'error_resource', __d('burocrata', 'The upload data does not define any type of resource', true)); - + $this->BuroCaptioner->addCaptions('upload'); + return compact('gen_options', 'file_input_options'); } diff --git a/src/cake/app/plugins/burocrata/views/helpers/buro_captioner.php b/src/cake/app/plugins/burocrata/views/helpers/buro_captioner.php new file mode 100644 index 00000000..829f8a0b --- /dev/null +++ b/src/cake/app/plugins/burocrata/views/helpers/buro_captioner.php @@ -0,0 +1,66 @@ +{"_$type"}(); + } + } + +/** + * Adds all captions for upload input + * + * @access protected + */ + protected function _upload() + { + $this->BuroOfficeBoy->addCaption('upload', 'error_size', __d('burocrata', 'The uploaded file is too large. (filesize > upload_max_filesize or filesize > Model::$validate definitions)', true)); + $this->BuroOfficeBoy->addCaption('upload', 'error_post_max_size', __d('burocrata', 'The uploaded file is too large. (filesize > post_max_size)', true)); + $this->BuroOfficeBoy->addCaption('upload', 'error_location', __d('burocrata', 'The upload process could not be completed because the file was placed on a non-allowed directory.', true)); + $this->BuroOfficeBoy->addCaption('upload', 'error_access', __d('burocrata', 'The resource is blocked and the webserver can not work properly with it.', true)); + $this->BuroOfficeBoy->addCaption('upload', 'error_resource', __d('burocrata', 'The upload data does not define any type of resource', true)); + $this->BuroOfficeBoy->addCaption('upload', 'sending', __d('burocrata', 'Enviando o arquivo #{fileName}. Aguarde...', true)); + $this->BuroOfficeBoy->addCaption('upload', 'hours_left', __d('burocrata', 'Faltando #{hours} horas', true)); + $this->BuroOfficeBoy->addCaption('upload', 'minutes_left', __d('burocrata', 'Faltando #{minutes} minutos', true)); + $this->BuroOfficeBoy->addCaption('upload', 'seconds_left', __d('burocrata', 'Faltando #{seconds} segundos', true)); + $this->BuroOfficeBoy->addCaption('upload', 'cancel', __d('burocrata', 'Cancelar', true)); + $this->BuroOfficeBoy->addCaption('upload', 'try_again', __d('burocrata', 'Tentar de novo', true)); + } +} diff --git a/src/cake/app/plugins/burocrata/views/helpers/buro_office_boy.php b/src/cake/app/plugins/burocrata/views/helpers/buro_office_boy.php index 40964028..6b71a089 100644 --- a/src/cake/app/plugins/burocrata/views/helpers/buro_office_boy.php +++ b/src/cake/app/plugins/burocrata/views/helpers/buro_office_boy.php @@ -12,15 +12,6 @@ * @link https://github.com/prefacedesign/jodeljodel Jodel Jodel public repository */ -/** - * Office boy Helper for burocrata. - * - * PHP versions 5 - * - * @package jodel - * @subpackage jodel.burocrata.views.helpers - */ - /** * BuroOfficeBoy helper. * From e19c6937f9389c9f7ebf6dac71bcf523e00bfa7a Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Fri, 8 Mar 2013 16:31:22 -0300 Subject: [PATCH 16/42] Added interpolate functionality to the BuroCaption.get() --- .../plugins/burocrata/webroot/js/burocrata.js | 66 +++++++++---------- 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js index 28668640..bdc39d45 100644 --- a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js +++ b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js @@ -61,13 +61,18 @@ var BuroCR = new (Class.create(Hash, { */ var BuroCaption = new (Class.create({ initialize: function() - {}, - get: function(space, key) + { + }, + get: function(space, key, interpolateData) { if (!this.isSet(space, key)) throw "BuroCaption::get() - Pair space/key given ("+space+"/"+key+") is not set."; - return buroCaptions[space][key]; + var caption = buroCaptions[space][key]; + if (typeof interpolateData == 'object') + caption.interpolate(interpolateData); + + return caption; }, isSet: function(space, key) { @@ -1848,16 +1853,6 @@ var BuroEditableList = Class.create(BuroCallbackable, { } }); -var CAPTIONS = { - upload: { - sending: 'Enviando o arquivo #{fileName}. Aguarde...', - hours_left: 'Faltando #{hours} horas', - minutes_left: 'Faltando #{minutes} minutos', - seconds_left: 'Faltando #{seconds} segundos', - cancel: 'Cancelar', - try_again: 'Tentar de novo' - } -}; /** * @@ -1874,6 +1869,18 @@ var CAPTIONS = { var BuroUpload = Class.create(BuroCallbackable, { initialize: function(id_base, url, parameters) { + this.ajax_upload = ( + 'multiple' in new Element('input', {type: 'file'}) && + !Object.isUndefined(File) && + !Object.isUndefined((new XMLHttpRequest()).upload) + ); + + if (this.ajax_upload) + { + new BuroAjaxUpload(this, id_base, url, parameters); + return; + } + if (Prototype.Browser.IE) { var ua = navigator.userAgent; @@ -1888,19 +1895,6 @@ var BuroUpload = Class.create(BuroCallbackable, { this.url = url; this.parameters = $H(parameters); - this.ajax_upload = ( - 'multiple' in new Element('input', {type: 'file'}) && - !Object.isUndefined(File) && - !Object.isUndefined((new XMLHttpRequest()).upload) - ); - - - if (this.ajax_upload) - { - new BuroAjaxUpload(id_base, url, parameters); - return; - } - BuroCR.set(this.id_base, this); this.iframe = new Element('iframe', { @@ -2054,10 +2048,11 @@ var BuroUpload = Class.create(BuroCallbackable, { }); -var BuroAjaxUpload = Class.create(BuroCallbackable,{ +var BuroAjaxUpload = Class.create({ chunkSize: 1024*1024, // 1M - initialize: function(id_base, url, parameters) + initialize: function(parent, id_base, url, parameters) { + this.parent = parent; this.id_base = id_base; this.url = url; this.parameters = null; @@ -2074,10 +2069,13 @@ var BuroAjaxUpload = Class.create(BuroCallbackable,{ this.hidden_input = $('hi'+this.id_base); this.div_hidden = $('div'+this.id_base); + this.cancelLink = new Element('a', {href: '#'}).update(BuroCaption.get('upload', 'cancel')); + this.tryAgainLink = new Element('a', {href: '#'}).update(BuroCaption.get('upload', 'try_again')); + this.controls = new Element('div'); - this.controls.insert(this.cancelLink = new Element('a', {href: '#'}).update(CAPTIONS.upload.cancel)); + this.controls.insert(this.cancelLink); this.cancelLink.on('click', function(ev){ ev.stop(); this.abort(); }.bind(this)); - this.controls.insert(this.tryAgainLink = new Element('a', {href: '#'}).update(CAPTIONS.upload.try_again)); + this.controls.insert(); this.progress_bar = new Element('div', {className: 'progress_bar'}); this.progress_bar.insert(new Element('div', {className: 'filling'})); @@ -2130,7 +2128,7 @@ var BuroAjaxUpload = Class.create(BuroCallbackable,{ this.reset(); this.file = file; - caption = CAPTIONS.upload.sending.interpolate({fileName: this.getFileName()}); + caption = BuroCaption.get('upload', 'sending', {fileName: this.getFileName()}); this.upload_input .insert({ after: this.caption = (new Element('span')).insert(caption) }) .hide(); @@ -2284,11 +2282,11 @@ var BuroAjaxUpload = Class.create(BuroCallbackable,{ { formatedTime.setHours(0,0,0,timeLeft); if (formatedTime.getHours()) - formatedTime = CAPTIONS.upload.hours_left.interpolate({hours: formatedTime.getHours() + ':' + formatedTime.getMinutes()}); + formatedTime = BuroCaption.get('upload', 'hours_left', {hours: formatedTime.getHours() + ':' + formatedTime.getMinutes()}); else if (formatedTime.getMinutes()) - formatedTime = CAPTIONS.upload.minutes_left.interpolate({minutes: formatedTime.getMinutes() + ':' + formatedTime.getSeconds()}); + formatedTime = BuroCaption.get('upload', 'minutes_left', {minutes: formatedTime.getMinutes() + ':' + formatedTime.getSeconds()}); else if (formatedTime.getSeconds()) - formatedTime = CAPTIONS.upload.seconds_left.interpolate({seconds: formatedTime.getSeconds()}); + formatedTime = BuroCaption.get('upload', 'seconds_left', {seconds: formatedTime.getSeconds()}); else formatedTime = false; From 5b176e7dc6fae15aa4fb004c30b0b2b0a901d336 Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Thu, 14 Mar 2013 12:01:31 -0300 Subject: [PATCH 17/42] Better and more solid separation of the classic upload and the new HTML5 upload --- .../views/helpers/buro_burocrata.php | 3 +- .../views/helpers/buro_office_boy.php | 35 +++- .../plugins/burocrata/webroot/js/burocrata.js | 152 +++++++++++++----- 3 files changed, 142 insertions(+), 48 deletions(-) diff --git a/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php b/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php index 8dbf4ba8..86da5648 100644 --- a/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php +++ b/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php @@ -2440,9 +2440,8 @@ public function inputUpload($options) $gen_options['callbacks']['onRestart']['js'] = ''; $gen_options['callbacks']['onRestart']['js'] .= "$('{$act_id}').hide(); $('{$prv_id}').hide();"; - $value = $this->Form->value($file_input_options['fieldName']); - $script = ''; + $value = $this->Form->value($file_input_options['fieldName']); if (empty($value)) $script .= "$('{$act_id}').hide(); $('{$prv_id}').hide();"; $script .= "$('{$chg_id}').observe('click', function(ev){ev.stop(); BuroCR.get('{$gen_options['baseID']}').again();});"; diff --git a/src/cake/app/plugins/burocrata/views/helpers/buro_office_boy.php b/src/cake/app/plugins/burocrata/views/helpers/buro_office_boy.php index 6b71a089..8ce4f826 100644 --- a/src/cake/app/plugins/burocrata/views/helpers/buro_office_boy.php +++ b/src/cake/app/plugins/burocrata/views/helpers/buro_office_boy.php @@ -97,6 +97,14 @@ class BuroOfficeBoyHelper extends AppHelper 'onRestart' => 'function(){%s}', 'onError' => 'function(code, error, json){%s}' ), + 'upload_ajax' => array( + 'onStart' => 'function(upload){%s}', + 'onComplete' => 'function(upload, json){%s}', + 'onPieceSent' => 'function(upload, json){%s}', + 'onReject' => 'function(upload, json, saved){%s}', + 'onRestart' => 'function(upload){%s}', + 'onError' => 'function(upload, json){%s}' + ), 'listOfItems' => array( 'onShowForm' => 'function(form){%s}', 'onAction' => 'function(action, id, content_type){%s}', @@ -347,17 +355,34 @@ public function listOfItems($options) */ public function upload($options) { - $defaults = array('callbacks' => array(), 'baseID' => uniqid(), 'url' => ''); + $defaults = array('baseID' => uniqid(), 'url' => ''); extract(am($defaults, $options)); unset($defaults); if (!empty($parameters)) $parameters = $this->Js->object($parameters); else $parameters = '{}'; - $script = sprintf("new BuroUpload('%s', '%s', %s)", $baseID, $url, $parameters); - if(!empty($callbacks) && is_array($callbacks)) - $script .= sprintf('.addCallbacks(%s)', $this->formatCallbacks('upload', $callbacks)); - + $script = sprintf("new BuroUploadGeneric('%s', '%s', %s)", $baseID, $url, $parameters); + if(!empty($callbacks)) + { + if (isset($callbacks['ajax'])) + { + $script .= sprintf(".addCallbacks('ajax', %s)", $this->formatCallbacks('upload_ajax', $callbacks['ajax'])); + unset($callbacks['ajax']); + } + + $classic = array(); + if (isset($callbacks['classic'])) + { + $classic = $callbacks['classic']; + unset($callbacks['classic']); + } + + $classic += $callbacks; + if (!empty($callbacks)) + $script .= sprintf(".addCallbacks('classic', %s)", $this->formatCallbacks('upload', $classic)); + } + return $this->addHtmlEmbScript($script); } diff --git a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js index bdc39d45..e556b1a5 100644 --- a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js +++ b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js @@ -70,7 +70,7 @@ var BuroCaption = new (Class.create({ var caption = buroCaptions[space][key]; if (typeof interpolateData == 'object') - caption.interpolate(interpolateData); + caption = caption.interpolate(interpolateData); return caption; }, @@ -1854,6 +1854,34 @@ var BuroEditableList = Class.create(BuroCallbackable, { }); +var BuroUploadGeneric = Class.create({ + initialize: function(id_base, url, parameters) + { + this.ajax_upload = ( + 'multiple' in new Element('input', {type: 'file'}) && + !Object.isUndefined(File) && + !Object.isUndefined((new XMLHttpRequest()).upload) + ); + + if (this.ajax_upload) + { + this.object = new BuroAjaxUpload(this, id_base, url, parameters); + return; + } + + this.object = new BuroUpload(id_base, url, parameters); + }, + addCallbacks: function($super, type, callback) + { + if (type == 'ajax' && this.ajax_upload) + this.object.addCallbacks(callbacks); + else if (type == 'classic') + this.object.addCallbacks(callbacks); + + return this; + } +}); + /** * * @@ -1869,18 +1897,6 @@ var BuroEditableList = Class.create(BuroCallbackable, { var BuroUpload = Class.create(BuroCallbackable, { initialize: function(id_base, url, parameters) { - this.ajax_upload = ( - 'multiple' in new Element('input', {type: 'file'}) && - !Object.isUndefined(File) && - !Object.isUndefined((new XMLHttpRequest()).upload) - ); - - if (this.ajax_upload) - { - new BuroAjaxUpload(this, id_base, url, parameters); - return; - } - if (Prototype.Browser.IE) { var ua = navigator.userAgent; @@ -2048,8 +2064,10 @@ var BuroUpload = Class.create(BuroCallbackable, { }); -var BuroAjaxUpload = Class.create({ +var BuroAjaxUpload = Class.create(BuroCallbackable, { chunkSize: 1024*1024, // 1M + MAX_TRIES: 5, + ST_READY: 1 , ST_UPLOADING: 2, ST_DONE: 3, ST_ERROR: 4, initialize: function(parent, id_base, url, parameters) { this.parent = parent; @@ -2070,12 +2088,16 @@ var BuroAjaxUpload = Class.create({ this.div_hidden = $('div'+this.id_base); this.cancelLink = new Element('a', {href: '#'}).update(BuroCaption.get('upload', 'cancel')); + this.cancelLink.on('click', function(ev){ ev.stop(); this.abort(); }.bind(this)); this.tryAgainLink = new Element('a', {href: '#'}).update(BuroCaption.get('upload', 'try_again')); + this.tryAgainLink.on('click', this.again.bind(this)); + this.removeFileLink = new Element('a', {href: '#'}).update(BuroCaption.get('upload', 'remove')); + this.removeFileLink.on('click', this.reset.bind(this)); this.controls = new Element('div'); - this.controls.insert(this.cancelLink); - this.cancelLink.on('click', function(ev){ ev.stop(); this.abort(); }.bind(this)); - this.controls.insert(); + this.controls.insert(this.cancelLink).insert(' ') + .insert(this.tryAgainLink).insert(' ') + .insert(this.removeFile) this.progress_bar = new Element('div', {className: 'progress_bar'}); this.progress_bar.insert(new Element('div', {className: 'filling'})); @@ -2095,25 +2117,54 @@ var BuroAjaxUpload = Class.create({ }, reset: function() { - this.hash = this.startTime = this.file = null; + this.json = this.hash = this.startTime = this.file = null; this.currentByte = this.errorCount = 0; this.aborted = false; - - this.upload_input.value = ''; + this.state = BuroAjaxUpload.ST_READY; + if (this.caption) + { + this.caption.remove(); + this.caption = null; + } + this.upload_input.show().value = ''; this.progress_bar.setStyle({visibility: 'hidden'}); - this.controls.setStyle({visibility: 'hidden'}); + this.controlControls(); + }, + controlControls: function() + { + this.tryAgainLink.hide(); + this.removeFileLink.hide(); + this.cancelLink.hide(); + switch (this.state) + { + case BuroAjaxUpload.ST_READY: + break; + + case BuroAjaxUpload.ST_UPLOADING: + this.cancelLink.show(); + break; + + case BuroAjaxUpload.ST_DONE: + this.removeFileLink.show(); + break; + + case BuroAjaxUpload.ST_ERROR: + this.tryAgainLink.show(); + break; + } }, abort: function() { this.aborted = true; this.xhr && this.xhr.abort(); - this.reset(); + // the xhr will trigger the handleAbort method. }, again: function() { this.reset(); this.upload_input.show(); - this.caption.remove(); + + this.trigger('onRestart', this); }, inputChange: function(ev) { @@ -2135,6 +2186,8 @@ var BuroAjaxUpload = Class.create({ this.uploadOnePiece(); this.startTime = new Date().getTime(); this.controls.setStyle({visibility: 'visible'}); + + this.trigger('onStart', this); } }, getFileSize: function() @@ -2152,10 +2205,7 @@ var BuroAjaxUpload = Class.create({ uploadOnePiece: function() { if (this.xhr) - { - console.log('tentando enviar mais um sem terminar o anterior'); return; - } var chunk, form; @@ -2197,31 +2247,38 @@ var BuroAjaxUpload = Class.create({ form.append('data[original_name]', this.getFileName()); this.xhr.send(form); + this.state = BuroAjaxUpload.ST_UPLOADING; }, uploadStatusChange: function() { - if (this.xhr.readyState != 4 || this.xhr.status != 200) + if (this.xhr.readyState != 4) return; + this.state = BuroAjaxUpload.ST_DONE; + + if (this.xhr.status != 200) + this.handleError(); + this.requestEnded(); }, requestEnded: function() { - var json = false; + this.json = false; if (this.xhr.response.isJSON()) { - json = this.xhr.response.evalJSON(); - if (json && json.hash) + this.json = this.xhr.response.evalJSON(); + if (this.json && this.json.hash) { - this.hash = json.hash; + this.hash = this.json.hash; } } - if (json.error) + if (this.json.error) { - if (json.error == 'chunk-doesnt-fit' && json.nextByte) + if (this.json.error == 'chunk-doesnt-fit' && this.json.nextByte) { - this.currentByte = json.nextByte; + this.currentByte = this.json.nextByte; + // Trying to sync the JS with the server (tries 5 times, and then, aborts it) } this.handleError(); return; @@ -2234,9 +2291,14 @@ var BuroAjaxUpload = Class.create({ if (!this.aborted) { if (!this.isLast) + { + this.trigger('onPieceSent', this); this.uploadOnePiece(); + } else - this.finish(json); + { + this.finish(); + } } }, clearXHR: function() @@ -2246,15 +2308,23 @@ var BuroAjaxUpload = Class.create({ this.xhr.upload.removeEventListener('abort', this.handleAbortBinded); this.xhr.onreadystatechange = null; this.xhr = null; + this.json = false; }, handleError: function(ev) { - this.errorCount++; - if (this.errorCount < 5) + if (this.state == BuroAjaxUpload.ST_UPLOADING) { - this.clearXHR(); - this.uploadOnePiece(); + this.errorCount++; + if (this.errorCount < BuroAjaxUpload.MAX_TRIES) + { + this.clearXHR(); + this.uploadOnePiece(); + return; + } } + this.state = BuroAjaxUpload.ST_ERROR; + this.controlControls(); + this.trigger('onError', this, this.json); }, handleProgress: function(ev) { @@ -2265,11 +2335,11 @@ var BuroAjaxUpload = Class.create({ console.log('Abortado!') console.log(ev); }, - finish: function(json) + finish: function() { this.renderProgress(100); this.reset(); - + this.trigger('onComplete', this, this.json); }, renderProgress: function(progress) { From 30f2822422c0d670f3ffe5289e10f785b8be028e Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Thu, 14 Mar 2013 12:02:02 -0300 Subject: [PATCH 18/42] Indentation changes and new captions --- .../views/helpers/buro_captioner.php | 35 +++++++++++++------ 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/cake/app/plugins/burocrata/views/helpers/buro_captioner.php b/src/cake/app/plugins/burocrata/views/helpers/buro_captioner.php index 829f8a0b..cbb1a9b9 100644 --- a/src/cake/app/plugins/burocrata/views/helpers/buro_captioner.php +++ b/src/cake/app/plugins/burocrata/views/helpers/buro_captioner.php @@ -51,16 +51,29 @@ public function addCaptions($type) */ protected function _upload() { - $this->BuroOfficeBoy->addCaption('upload', 'error_size', __d('burocrata', 'The uploaded file is too large. (filesize > upload_max_filesize or filesize > Model::$validate definitions)', true)); - $this->BuroOfficeBoy->addCaption('upload', 'error_post_max_size', __d('burocrata', 'The uploaded file is too large. (filesize > post_max_size)', true)); - $this->BuroOfficeBoy->addCaption('upload', 'error_location', __d('burocrata', 'The upload process could not be completed because the file was placed on a non-allowed directory.', true)); - $this->BuroOfficeBoy->addCaption('upload', 'error_access', __d('burocrata', 'The resource is blocked and the webserver can not work properly with it.', true)); - $this->BuroOfficeBoy->addCaption('upload', 'error_resource', __d('burocrata', 'The upload data does not define any type of resource', true)); - $this->BuroOfficeBoy->addCaption('upload', 'sending', __d('burocrata', 'Enviando o arquivo #{fileName}. Aguarde...', true)); - $this->BuroOfficeBoy->addCaption('upload', 'hours_left', __d('burocrata', 'Faltando #{hours} horas', true)); - $this->BuroOfficeBoy->addCaption('upload', 'minutes_left', __d('burocrata', 'Faltando #{minutes} minutos', true)); - $this->BuroOfficeBoy->addCaption('upload', 'seconds_left', __d('burocrata', 'Faltando #{seconds} segundos', true)); - $this->BuroOfficeBoy->addCaption('upload', 'cancel', __d('burocrata', 'Cancelar', true)); - $this->BuroOfficeBoy->addCaption('upload', 'try_again', __d('burocrata', 'Tentar de novo', true)); + $this->BuroOfficeBoy->addCaption('upload', 'error_size', + __d('burocrata', 'The uploaded file is too large. (filesize > upload_max_filesize or filesize > Model::$validate definitions)', true)); + $this->BuroOfficeBoy->addCaption('upload', 'error_post_max_size', + __d('burocrata', 'The uploaded file is too large. (filesize > post_max_size)', true)); + $this->BuroOfficeBoy->addCaption('upload', 'error_location', + __d('burocrata', 'The upload process could not be completed because the file was placed on a non-allowed directory.', true)); + $this->BuroOfficeBoy->addCaption('upload', 'error_access', + __d('burocrata', 'The resource is blocked and the webserver can not work properly with it.', true)); + $this->BuroOfficeBoy->addCaption('upload', 'error_resource', + __d('burocrata', 'The upload data does not define any type of resource', true)); + $this->BuroOfficeBoy->addCaption('upload', 'sending', + __d('burocrata', 'Enviando o arquivo #{fileName}. Aguarde...', true)); + $this->BuroOfficeBoy->addCaption('upload', 'hours_left', + __d('burocrata', 'Faltando #{hours} horas', true)); + $this->BuroOfficeBoy->addCaption('upload', 'minutes_left', + __d('burocrata', 'Faltando #{minutes} minutos', true)); + $this->BuroOfficeBoy->addCaption('upload', 'seconds_left', + __d('burocrata', 'Faltando #{seconds} segundos', true)); + $this->BuroOfficeBoy->addCaption('upload', 'cancel', + __d('burocrata', 'Cancelar', true)); + $this->BuroOfficeBoy->addCaption('upload', 'try_again', + __d('burocrata', 'Tentar de novo', true)); + $this->BuroOfficeBoy->addCaption('upload', 'remove', + __d('burocrata', 'Remover arquivo', true)); } } From a842f0d1f5f2bde3344c025c1f7a8defb9b14688 Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Thu, 14 Mar 2013 12:03:20 -0300 Subject: [PATCH 19/42] Creating a garbage collector for abandoned uploads --- .../controllers/jj_media_controller.php | 7 ++++ .../jj_media/vendors/shells/tasks/empty | 0 .../jj_media/vendors/shells/upload_gc.php | 42 +++++++++++++++++++ 3 files changed, 49 insertions(+) delete mode 100644 src/cake/app/plugins/jj_media/vendors/shells/tasks/empty create mode 100644 src/cake/app/plugins/jj_media/vendors/shells/upload_gc.php diff --git a/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php b/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php index 5f089392..b349e1a2 100644 --- a/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php +++ b/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php @@ -217,6 +217,7 @@ protected function performAjaxUpload() $hash = uniqid('', true); } while (file_exists(TMP . $hash)); mkdir(TMP . $hash); + chmod(TMP . $hash, 0777); } else { @@ -226,6 +227,7 @@ protected function performAjaxUpload() $chunkFile = fopen($chunkFileName, 'rb'); $gluedFileName = TMP . $hash . DS . 'file'; $gluedFile = fopen($gluedFileName, 'ab'); + chmod($chunkFileName, 0666); if (filesize($gluedFileName) != $startByte) { @@ -244,6 +246,11 @@ protected function performAjaxUpload() fclose($chunkFile); fclose($gluedFile); + // This file will tell the GC cron job to clean files when "abandoned" + $lastInteractionFile = TMP . $hash . DS . 'last_interaction'; + file_put_contents($lastInteractionFile, time()); + chmod($lastInteractionFile, 0666); + if ($isLast == 'yes') { $originalName = TMP . $hash . DS . $this->data['original_name']; diff --git a/src/cake/app/plugins/jj_media/vendors/shells/tasks/empty b/src/cake/app/plugins/jj_media/vendors/shells/tasks/empty deleted file mode 100644 index e69de29b..00000000 diff --git a/src/cake/app/plugins/jj_media/vendors/shells/upload_gc.php b/src/cake/app/plugins/jj_media/vendors/shells/upload_gc.php new file mode 100644 index 00000000..7ad521a8 --- /dev/null +++ b/src/cake/app/plugins/jj_media/vendors/shells/upload_gc.php @@ -0,0 +1,42 @@ +read()); // read only directories (array[0]) + + foreach ($folders as $folder) + { + $tmp->cd(TMP); + $tmp->cd($folder); + $files = end($tmp->read()); // read only files (array[1]) + if (in_array('last_interaction', $files)) + { + $file_interaction = (int) file_get_contents($tmp->pwd() . DS . 'last_interaction'); + + // as each piece is 1Mb, this will give the user the chance of uploading at 2,3 kbps (0,28 kb/s) + if (time() - $file_interaction > HOUR) + { + $this->out("Removing $folder"); + foreach ($files as $file) + unlink($tmp->pwd() . DS . $file); + $tmp->delete(); + } + } + } + } +} From 4e1208f39464038757fe964326baadddc2135e8b Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Thu, 14 Mar 2013 14:45:58 -0300 Subject: [PATCH 20/42] Documenting and introduced a new parameter: -quiet --- .../jj_media/vendors/shells/upload_gc.php | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/cake/app/plugins/jj_media/vendors/shells/upload_gc.php b/src/cake/app/plugins/jj_media/vendors/shells/upload_gc.php index 7ad521a8..d0830e32 100644 --- a/src/cake/app/plugins/jj_media/vendors/shells/upload_gc.php +++ b/src/cake/app/plugins/jj_media/vendors/shells/upload_gc.php @@ -12,10 +12,44 @@ * @link https://github.com/prefacedesign/jodeljodel Jodel Jodel public repository */ +/** + * Shell script for cleaning uploads that did not finish properly. + * + * @package jodel.jj_media + * @subpackage .vendors.shell + */ class UploadGcShell extends Shell { + +/** + * If verbose actions or not. + * + * @access protected + */ + protected $quiet = false; + +/** + * Overwriting parent method avoiding the default header + * + * @access public + */ + public function startup() + { + // intentionally left blank + } + +/** + * The main method: where things happen + * + * @access public + */ function main() { + if (isset($this->params['quiet'])) + { + $this->quiet = true; + } + $tmp = new Folder(TMP); $folders = reset($tmp->read()); // read only directories (array[0]) @@ -39,4 +73,15 @@ function main() } } } + +/** + * Overwrites parent method to introduce the "quiet" variant + * + * @access public + */ + function out($msg = '') + { + if (!$this->quiet) + parent::out($msg); + } } From df7da349837b9c63e994ba259f4fdc4aa963b211 Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Thu, 14 Mar 2013 17:02:49 -0300 Subject: [PATCH 21/42] Aborting ajax upload already working --- .../views/helpers/buro_captioner.php | 2 + .../plugins/burocrata/webroot/js/burocrata.js | 90 ++++++++++++------- 2 files changed, 58 insertions(+), 34 deletions(-) diff --git a/src/cake/app/plugins/burocrata/views/helpers/buro_captioner.php b/src/cake/app/plugins/burocrata/views/helpers/buro_captioner.php index cbb1a9b9..f73ba461 100644 --- a/src/cake/app/plugins/burocrata/views/helpers/buro_captioner.php +++ b/src/cake/app/plugins/burocrata/views/helpers/buro_captioner.php @@ -75,5 +75,7 @@ protected function _upload() __d('burocrata', 'Tentar de novo', true)); $this->BuroOfficeBoy->addCaption('upload', 'remove', __d('burocrata', 'Remover arquivo', true)); + $this->BuroOfficeBoy->addCaption('upload', 'really_abort', + __d('burocrata', 'Really abort?', true)); } } diff --git a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js index e556b1a5..45c2c0b1 100644 --- a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js +++ b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js @@ -2120,7 +2120,7 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { this.json = this.hash = this.startTime = this.file = null; this.currentByte = this.errorCount = 0; this.aborted = false; - this.state = BuroAjaxUpload.ST_READY; + this.state = this.ST_READY; if (this.caption) { this.caption.remove(); @@ -2137,27 +2137,39 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { this.cancelLink.hide(); switch (this.state) { - case BuroAjaxUpload.ST_READY: + case this.ST_READY: break; - case BuroAjaxUpload.ST_UPLOADING: + case this.ST_UPLOADING: this.cancelLink.show(); break; - case BuroAjaxUpload.ST_DONE: + case this.ST_DONE: this.removeFileLink.show(); break; - case BuroAjaxUpload.ST_ERROR: + case this.ST_ERROR: this.tryAgainLink.show(); break; } }, abort: function() { + if (this.xhr && this.xhr.readyState != 4) + { + this.xhr.onreadystatechange = function() {}; + this.xhr.abort(); + this.clearXHR(); + } + + if (!confirm(BuroCaption.get('upload', 'really_abort'))) + { + this.uploadOnePiece(); + return; + } + this.aborted = true; - this.xhr && this.xhr.abort(); - // the xhr will trigger the handleAbort method. + this.handleAbort(); }, again: function() { @@ -2205,7 +2217,9 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { uploadOnePiece: function() { if (this.xhr) - return; + return console.log('Opa! Tem alguém trabalhando, já.'); + + console.log('Empurrando mais um bloquinho.'); var chunk, form; @@ -2225,7 +2239,6 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { this.xhr = new XMLHttpRequest(); this.xhr.upload.addEventListener('error', this.handleErrorBinded); this.xhr.upload.addEventListener('progress', this.handleProgressBinded); - this.xhr.upload.addEventListener('abort', this.handleAbortBinded); this.xhr.onreadystatechange = this.uploadStatusChangeBinded; this.xhr.open('POST', this.url, true); @@ -2247,15 +2260,14 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { form.append('data[original_name]', this.getFileName()); this.xhr.send(form); - this.state = BuroAjaxUpload.ST_UPLOADING; + this.state = this.ST_UPLOADING; + this.controlControls(); }, uploadStatusChange: function() { if (this.xhr.readyState != 4) return; - - this.state = BuroAjaxUpload.ST_DONE; - + if (this.xhr.status != 200) this.handleError(); @@ -2265,12 +2277,17 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { { this.json = false; if (this.xhr.response.isJSON()) - { this.json = this.xhr.response.evalJSON(); - if (this.json && this.json.hash) - { - this.hash = this.json.hash; - } + + if (this.aborted) + return this.handleAbort(); + + if (!this.json) + return this.handleError(); + + if (this.json.hash) + { + this.hash = this.json.hash; } if (this.json.error) @@ -2280,25 +2297,21 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { this.currentByte = this.json.nextByte; // Trying to sync the JS with the server (tries 5 times, and then, aborts it) } - this.handleError(); - return; + return this.handleError(); } this.currentByte = this.endByte; this.clearXHR(); this.errorCount = 0; - if (!this.aborted) + if (!this.isLast) { - if (!this.isLast) - { - this.trigger('onPieceSent', this); - this.uploadOnePiece(); - } - else - { - this.finish(); - } + this.trigger('onPieceSent', this); + this.uploadOnePiece(); + } + else + { + this.finish(); } }, clearXHR: function() @@ -2312,19 +2325,24 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { }, handleError: function(ev) { - if (this.state == BuroAjaxUpload.ST_UPLOADING) + if (this.state == this.ST_UPLOADING) { this.errorCount++; - if (this.errorCount < BuroAjaxUpload.MAX_TRIES) + if (this.errorCount < this.MAX_TRIES) { this.clearXHR(); this.uploadOnePiece(); return; } } - this.state = BuroAjaxUpload.ST_ERROR; + + if (this.aborted) + return this.handleAbort(); + + this.state = this.ST_ERROR; this.controlControls(); this.trigger('onError', this, this.json); + console.log('erro definitivo!'); }, handleProgress: function(ev) { @@ -2333,12 +2351,16 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { handleAbort: function(ev) { console.log('Abortado!') - console.log(ev); + this.reset(); + this.controlControls(); }, finish: function() { this.renderProgress(100); this.reset(); + this.state = this.ST_DONE; + console.log('acabou!'); + // todo handle finish this.trigger('onComplete', this, this.json); }, renderProgress: function(progress) From 57bd292beadb25f1761042f9cce5882b403aa511 Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Thu, 14 Mar 2013 17:42:44 -0300 Subject: [PATCH 22/42] Some fixes: smaller timeout for upload and clearing correctly the folder when finish --- .../app/plugins/jj_media/controllers/jj_media_controller.php | 1 + src/cake/app/plugins/jj_media/vendors/empty | 0 src/cake/app/plugins/jj_media/vendors/shells/upload_gc.php | 4 ++-- 3 files changed, 3 insertions(+), 2 deletions(-) delete mode 100644 src/cake/app/plugins/jj_media/vendors/empty diff --git a/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php b/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php index b349e1a2..ad544ac8 100644 --- a/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php +++ b/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php @@ -262,6 +262,7 @@ protected function performAjaxUpload() $validationErrors = $this->SfilBigFile->validationErrors; } unlink($originalName); + unlink($lastInteractionFile); rmdir(TMP . $hash); } else diff --git a/src/cake/app/plugins/jj_media/vendors/empty b/src/cake/app/plugins/jj_media/vendors/empty deleted file mode 100644 index e69de29b..00000000 diff --git a/src/cake/app/plugins/jj_media/vendors/shells/upload_gc.php b/src/cake/app/plugins/jj_media/vendors/shells/upload_gc.php index d0830e32..3ebddd4a 100644 --- a/src/cake/app/plugins/jj_media/vendors/shells/upload_gc.php +++ b/src/cake/app/plugins/jj_media/vendors/shells/upload_gc.php @@ -62,8 +62,8 @@ function main() { $file_interaction = (int) file_get_contents($tmp->pwd() . DS . 'last_interaction'); - // as each piece is 1Mb, this will give the user the chance of uploading at 2,3 kbps (0,28 kb/s) - if (time() - $file_interaction > HOUR) + // as each piece is 1Mb, this will give the user the chance of uploading at 13,7 kbps (1,7 kb/s) + if (time() - $file_interaction > 600) { $this->out("Removing $folder"); foreach ($files as $file) From ab6ca26161e596fba6977601cad7816a1c64579a Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Fri, 15 Mar 2013 08:27:28 -0300 Subject: [PATCH 23/42] More changes to the ajax upload input Handling error better Making the image upload to work Added more messages (captions) Fixed the forced model at ajax upload --- .../views/helpers/buro_burocrata.php | 4 +- .../views/helpers/buro_captioner.php | 15 ++++ .../plugins/burocrata/webroot/js/burocrata.js | 88 ++++++++++++++++--- .../controllers/jj_media_controller.php | 48 +++++++--- 4 files changed, 126 insertions(+), 29 deletions(-) diff --git a/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php b/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php index 86da5648..011b18ce 100644 --- a/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php +++ b/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php @@ -2488,8 +2488,8 @@ public function inputImage($options) $gen_options['change_file_text'] = __d('burocrata','Burocrata::inputImage - Change image', true); if (empty($gen_options['remove_file_text'])) $gen_options['remove_file_text'] = __d('burocrata','Burocrata::inputImage - Remove image', true); - - $gen_options['error'] += array('validImage' => __d('burocrata','The uploaded file is not a valid image file.',true)); + + $this->BuroCaptioner->addCaptions('imageUpload'); $value = $this->Form->value($file_input_options['fieldName']); diff --git a/src/cake/app/plugins/burocrata/views/helpers/buro_captioner.php b/src/cake/app/plugins/burocrata/views/helpers/buro_captioner.php index f73ba461..a310d459 100644 --- a/src/cake/app/plugins/burocrata/views/helpers/buro_captioner.php +++ b/src/cake/app/plugins/burocrata/views/helpers/buro_captioner.php @@ -77,5 +77,20 @@ protected function _upload() __d('burocrata', 'Remover arquivo', true)); $this->BuroOfficeBoy->addCaption('upload', 'really_abort', __d('burocrata', 'Really abort?', true)); + $this->BuroOfficeBoy->addCaption('upload', 'generic_error', + __d('burocrata', 'Something went wrong and the file was not sent.', true)); + $this->BuroOfficeBoy->addCaption('upload', 'error_with_server_resp', + __d('burocrata', 'Something went wrong and the file was not sent. The server returned #{error}', true)); + } + +/** + * Complement for image upload field + * + * @access + */ + protected function _imageUpload() + { + $this->BuroOfficeBoy->addCaption('upload', 'error_validImage', + __d('burocrata','The uploaded file is not a valid image file.',true)); } } diff --git a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js index 45c2c0b1..8f394ccc 100644 --- a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js +++ b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js @@ -1883,7 +1883,7 @@ var BuroUploadGeneric = Class.create({ }); /** - * + * Classic "Ajax" upload using the iframe method * * Callbacks: * - `onStart` function (input){} @@ -2064,10 +2064,23 @@ var BuroUpload = Class.create(BuroCallbackable, { }); +/** + * HTML 5 upload, using XMLHttpRequest + * + * Callbacks: + * - `onStart` function(upload){%s} + * - `onComplete` function(upload, json){%s} + * - `onPieceSent` function(upload, json){%s} + * - `onReject` function(upload, json, saved){%s} + * - `onRestart` function(upload){%s} + * - `onError` function(upload, json){%s} + * + * @access public + */ var BuroAjaxUpload = Class.create(BuroCallbackable, { chunkSize: 1024*1024, // 1M MAX_TRIES: 5, - ST_READY: 1 , ST_UPLOADING: 2, ST_DONE: 3, ST_ERROR: 4, + ST_READY: 1 , ST_UPLOADING: 2, ST_DONE: 3, ST_ERROR: 4, ST_INVALIDATED: 5, initialize: function(parent, id_base, url, parameters) { this.parent = parent; @@ -2084,9 +2097,6 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { }, loaded: function() { - this.hidden_input = $('hi'+this.id_base); - this.div_hidden = $('div'+this.id_base); - this.cancelLink = new Element('a', {href: '#'}).update(BuroCaption.get('upload', 'cancel')); this.cancelLink.on('click', function(ev){ ev.stop(); this.abort(); }.bind(this)); this.tryAgainLink = new Element('a', {href: '#'}).update(BuroCaption.get('upload', 'try_again')); @@ -2127,6 +2137,7 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { this.caption = null; } this.upload_input.show().value = ''; + this.upload_input.up('.input').removeClassName('error').select('.error-message').invoke('remove'); this.progress_bar.setStyle({visibility: 'hidden'}); this.controlControls(); }, @@ -2171,8 +2182,10 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { this.aborted = true; this.handleAbort(); }, - again: function() + again: function(ev) { + if (ev) ev.stop(); + this.reset(); this.upload_input.show(); @@ -2180,6 +2193,9 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { }, inputChange: function(ev) { + if (this.state != this.ST_READY) + return; + if (!this.upload_input.files.length) { this.reset(); @@ -2286,9 +2302,7 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { return this.handleError(); if (this.json.hash) - { this.hash = this.json.hash; - } if (this.json.error) { @@ -2300,6 +2314,17 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { return this.handleError(); } + if (this.isLast) + this.renderProgress(100); + + if (this.json.validationErrors) + { + this.state = this.ST_INVALIDATED; + this.handleError() + this.clearXHR(); + return; + } + this.currentByte = this.endByte; this.clearXHR(); this.errorCount = 0; @@ -2316,6 +2341,8 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { }, clearXHR: function() { + if (!this.xhr) + return; this.xhr.upload.removeEventListener('error', this.handleErrorBinded); this.xhr.upload.removeEventListener('progress', this.handleProgressBinded); this.xhr.upload.removeEventListener('abort', this.handleAbortBinded); @@ -2325,9 +2352,13 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { }, handleError: function(ev) { + if (this.aborted) + return this.handleAbort(); + if (this.state == this.ST_UPLOADING) { this.errorCount++; + console.log('eita, deixe-me tentar novamente.'); if (this.errorCount < this.MAX_TRIES) { this.clearXHR(); @@ -2336,12 +2367,14 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { } } - if (this.aborted) - return this.handleAbort(); + this.renderError(); this.state = this.ST_ERROR; this.controlControls(); - this.trigger('onError', this, this.json); + if (this.json && this.json.validationErrors) + this.trigger('onReject', this, this.json, false); + else + this.trigger('onError', this, this.json); console.log('erro definitivo!'); }, handleProgress: function(ev) @@ -2350,13 +2383,11 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { }, handleAbort: function(ev) { - console.log('Abortado!') this.reset(); this.controlControls(); }, finish: function() { - this.renderProgress(100); this.reset(); this.state = this.ST_DONE; console.log('acabou!'); @@ -2390,6 +2421,37 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { if (timeLeft > 2000) this.progress_bar.setStyle({visibility: 'visible'}); + }, + renderError: function() + { + var errorName, errorMsg = []; + if (typeof this.json.validationErrors == 'object') + { + for (errorName in this.json.validationErrors) + { + errorName = this.json.validationErrors[errorName]; + if (BuroCaption.isSet('upload', 'error_'+errorName)) + errorMsg.push(BuroCaption.get('upload', 'error_'+errorName)) + else + errorMsg.push(errorName); + } + } + + if (this.json.error) + { + if (BuroCaption.isSet('upload', 'error_'+errorName)) + errorMsg.push(BuroCaption.get('upload', 'error_'+errorName)) + else if (BuroCaption.isSet('upload', 'error_with_server_resp')) + errorMsg.push(BuroCaption.get('upload', 'error_with_server_resp', this.json)); + } + + if (!errorMsg.length) + errorMsg.push(BuroCaption.get('upload', 'generic_error')); + + this.upload_input.up().up().addClassName('error'); + this.controls.insert({ + before: new Element('div', {className:'error-message'}).update(errorMsg.join('
')) + }); } }); diff --git a/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php b/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php index ad544ac8..7802e0aa 100644 --- a/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php +++ b/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php @@ -175,7 +175,7 @@ function upload() return; } - $this->saveUpload($this->data); + $this->set($this->saveUpload($this->data)); $this->layout = 'ajax'; $this->view = 'Typographer.Type'; @@ -199,16 +199,24 @@ protected function performAjaxUpload() $startByte = env('HTTP_X_UPLOADER_START_BYTE'); $isLast = env('HTTP_X_UPLOADER_IS_LAST'); $chunkSize = env('HTTP_X_UPLOADER_CHUNK_SIZE'); - - $uploadError = empty($this->data['SfilStoredFile']['file']['tmp_name']) - || !file_exists($chunkFileName = $this->data['SfilStoredFile']['file']['tmp_name']) - || filesize($chunkFileName) != $chunkSize; - if ($uploadError) + $version = $fieldName = $modelName = null; + if (!empty($this->buroData['data'])) { + list($version, $fieldName, $modelName) = SecureParams::unpack($this->buroData['data']); + list($plugin, $modelName) = pluginSplit($modelName); + } + + if (empty($this->data[$modelName]['file']['tmp_name'])) $error = 'upload-failed'; + elseif (!file_exists($chunkFileName = $this->data[$modelName]['file']['tmp_name'])) + $error = 'upload-failed-no-tempfile'; + elseif (filesize($chunkFileName) != $chunkSize) + $error = 'upload-failed-chunksize-wrong'; + + if ($error) goto renderAjaxUpload; - } + if (empty($this->data['hash'])) { @@ -256,14 +264,26 @@ protected function performAjaxUpload() $originalName = TMP . $hash . DS . $this->data['original_name']; rename($gluedFileName, $originalName); - $data = array('SfilBigFile' => array('file' => $originalName)); - if (!$this->saveUpload($data, 'JjMedia.SfilBigFile')) - { - $validationErrors = $this->SfilBigFile->validationErrors; - } + $data = array($modelName => array('file' => $originalName)); + $savedData = $this->saveUpload($data); + + // remove temporary dir unlink($originalName); unlink($lastInteractionFile); rmdir(TMP . $hash); + + if (!$savedData['saved']) + { + $validationErrors = $savedData['validationErrors']; + } + else + { + App::import('Lib', array('JjUtils.SecureParams')); + $packed_params = SecureParams::pack(array($savedData['saved'], $savedData['version']), true); + $baseUrl = array('plugin' => 'jj_media', 'controller' => 'jj_media', 'action' => 'index'); + $dlurl = Router::url($baseUrl + array('1', $packed_params)); + $url = Router::url($baseUrl + array($packed_params)); + } } else { @@ -272,7 +292,7 @@ protected function performAjaxUpload() renderAjaxUpload: $this->view = 'JjUtils.Json'; - $this->set('jsonVars', compact('error', 'validationErrors', 'saved', 'version', 'filename', 'hash', 'nextByte')); + $this->set('jsonVars', compact('error', 'validationErrors', 'saved', 'version', 'url', 'dlurl', 'hash', 'nextByte')); } /** @@ -328,6 +348,6 @@ protected function saveUpload($data, $forceModel = null) } } } - $this->set(compact('error', 'validationErrors', 'saved', 'version', 'filename')); + return compact('error', 'validationErrors', 'saved', 'version', 'filename'); } } From 784d8d923305f94fbd24efbcc38b9cf4710d6b88 Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Tue, 19 Mar 2013 10:53:57 -0300 Subject: [PATCH 24/42] BuroOfficeBoy enhancement Now is possible to use the BuroOfficeBoy::addHtmlEmbScript() method inside the layout file, also. --- .../views/helpers/buro_office_boy.php | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/cake/app/plugins/burocrata/views/helpers/buro_office_boy.php b/src/cake/app/plugins/burocrata/views/helpers/buro_office_boy.php index 711f85eb..7a0b484f 100644 --- a/src/cake/app/plugins/burocrata/views/helpers/buro_office_boy.php +++ b/src/cake/app/plugins/burocrata/views/helpers/buro_office_boy.php @@ -115,6 +115,21 @@ class BuroOfficeBoyHelper extends AppHelper */ protected $scripts = array(); +/** + * Boolean variable used to tracking if the layout was rendered + * + * @access protected + * @var boolean + */ + protected $rendered = false; + +/** + * Before render logic + * + * This method links some script files to the HTML + * + * @access public + */ public function beforeRender() { if (!$this->Ajax->isAjax() && ClassRegistry::getObject('view')) @@ -131,7 +146,9 @@ public function beforeRender() } /** - * afterRender callback used for print automagically all created scripts on HTML + * After render logic + * + * This callback is used for automagically print all created scripts on HTML * when it is not a Ajax request * * @access public @@ -149,6 +166,8 @@ public function afterRender() $View->addScript($this->Html->scriptBlock($this->Js->domReady($script))); } + + $this->rendered = true; } /** @@ -368,8 +387,10 @@ public function color($options) */ public function addHtmlEmbScript($script) { - if($this->Ajax->isAjax()) + if ($this->Ajax->isAjax()) return $this->Html->scriptBlock($script); + elseif ($this->rendered) + return $this->Html->scriptBlock($this->Js->domReady($script)); else $this->scripts[] = $script; } From 5a59cb407d409782fc5f551f00dac6748770be29 Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Wed, 20 Mar 2013 23:33:58 -0300 Subject: [PATCH 25/42] Some fixes to the HTML5 upload input "Try again" link working! Error is rendering properly. The end of the upload is detected correctly. --- .../plugins/burocrata/webroot/js/burocrata.js | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js index 8f394ccc..3da39b6c 100644 --- a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js +++ b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js @@ -2131,6 +2131,7 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { this.currentByte = this.errorCount = 0; this.aborted = false; this.state = this.ST_READY; + this.clearXHR(); if (this.caption) { this.caption.remove(); @@ -2211,11 +2212,11 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { this.upload_input .insert({ after: this.caption = (new Element('span')).insert(caption) }) .hide(); - this.uploadOnePiece(); this.startTime = new Date().getTime(); this.controls.setStyle({visibility: 'visible'}); this.trigger('onStart', this); + this.uploadOnePiece(); } }, getFileSize: function() @@ -2275,9 +2276,10 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { if (this.isLast) form.append('data[original_name]', this.getFileName()); - this.xhr.send(form); this.state = this.ST_UPLOADING; this.controlControls(); + + this.xhr.send(form); }, uploadStatusChange: function() { @@ -2292,6 +2294,9 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { requestEnded: function() { this.json = false; + if (!this.xhr) + return; + if (this.xhr.response.isJSON()) this.json = this.xhr.response.evalJSON(); @@ -2352,15 +2357,18 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { }, handleError: function(ev) { + if (this.state == this.ST_ERROR) + return; + if (this.aborted) return this.handleAbort(); if (this.state == this.ST_UPLOADING) { this.errorCount++; - console.log('eita, deixe-me tentar novamente.'); if (this.errorCount < this.MAX_TRIES) { + console.log('eita, deixe-me tentar novamente.'); this.clearXHR(); this.uploadOnePiece(); return; @@ -2388,10 +2396,8 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { }, finish: function() { - this.reset(); this.state = this.ST_DONE; - console.log('acabou!'); - // todo handle finish + this.controlControls(); this.trigger('onComplete', this, this.json); }, renderProgress: function(progress) From 72f928ae28c1a72dcace82e342249fac8ab0107a Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Wed, 20 Mar 2013 23:42:56 -0300 Subject: [PATCH 26/42] Some translations strings --- .../locale/por/LC_MESSAGES/burocrata.mo | Bin 4578 -> 5553 bytes .../locale/por/LC_MESSAGES/burocrata.po | 180 +++++++++++------- 2 files changed, 116 insertions(+), 64 deletions(-) diff --git a/src/cake/app/plugins/burocrata/locale/por/LC_MESSAGES/burocrata.mo b/src/cake/app/plugins/burocrata/locale/por/LC_MESSAGES/burocrata.mo index 182d57fffdc9f62331f13c04196383264916b6f2..acf21e0a154ec7ce6ac026301341684ea381c2d3 100644 GIT binary patch delta 2252 zcmb7^Ux-yj9LHyK%{1Lw%d{*TcgywPUhnR8GtJzDjS{5Y)E){G=H4@R_qgYtxt>4w zvh?TnQeY8e5)~971tOtf8~M^hve1JBK@e0_4?;zSP(2k`^!c50HjJJcnDd!GznR~6 ze!rP>vH$F*&bQ0EUs05u)LW^SyOi1wzh1zHvVNgbx5Eu^9oz%Ot_kmeFBbjx;ClL> z!VU0uxCZuJo!jq*!}JfqyWufdQL3XZ(AdGiUvMkjz9=^g;XU+EzK3m{sxECIT55iMWBJdkDaG(bpcoa&6KY-KlSBQyv{5qoYeiwr@ zdKu7sgu{GRz%eL>k3q7drr`C^6?_Jg6?F{W0AGg$Q=Nu4!gG*ps85Rd&mr#AkFXp5 z+)Mm5jb9j$ko7Ll4TcI&md`5UlslDAkkBoploot;6l7#MZX7%gI*}>RzcaPABxaT zP}c2)Vt0Rs2GLi0i-ChsE?o`Q;d4-)<|Q};Hxk!};X(KkJOkImQSv40rV73QMbH^2 zAs44oc^zA+ za_Q#F_M#z&SVtYC@_*>4QZXSv6?vahLzB|2ul^ndO30k(;4)UuI|Y?4M{ z$9lT|2^&Q&dP>P`WMh{`HLLwtR|8j@#$aAR+g6LkH4|nk+Af;b&B!%v#39;#GNpZF z$wp~2aK_V~NsRWK%~gB0?uV8QXLK^twAxMA|M7U`Dz>cIIMy|n243c=YUwnZflUxp zwKbE*_TN!y2ByZG3$bWztxWw2Zs94_nO%8tr5 z+U4?+iSfaGw&lk@E5}S?cj)2r&=q!Dhh~3Rc632!%*OVxL9_`PqySYWtl7Xs+G!iM zd^f6g2a`^FHr0gHcut#qMoePj;kme^=Z;F)T5~5_Hqb{>vXUA(U>f>0Gk0?CZ6`hU zjD39AI1#6ebYxjIunklCkDq)&CZeRrvpoBr%QEev(51R>KGS_A^^mxzJ6|_l9M7E= z840(75XNyPnV_W+P1z64B{eSMJE)%@BBi;`uh5Yi%*S`-u%SXfX}X)T1I7D7ZT zDX4`NNVKShjEi2I$VGvz0-+WOE~-t7B6@+*_jl(M9sJMdoO91P_ul_K$Eo;2edb+7 z;WeYQ6E(zao>>o$7Vty4U1+u*?_dm{p~ij0jaXEaYqww%?cLanLs*M9-StP9q&ZtUko(y;EW{re z#YI#GYFSj*JDodG^ShmU!sK5a`&`E%36V$jF z)Pui7l4-9|^X8GSVjo=lOPKtZ(eaB8El^C}WCiA9HR=YnsEG}zg?wa+b)d%gpvLth zFK-82dk~vw4`ChNa6Uz?KcAtZ6s;qw2yG-4P0}v)2#$%ZAv8fZixE1mK9L~YNe#X& z&0urM)r4M7nNX=9v~g9mAGDV;dfHWl%H|xwF>=-5sHv{c@we!Bt|fT(py*p~A(R1S zN&g?Tk#*ekKcJalj~YimI57}p4`RW_YNV#L{$G@?D539Jnr$fh85;jw7RgSOh4R{x zo}cg%sc0gZPNqCR>H8(Ud%gaFk-@Wrr%!pij+`4vN0WZy-?**m*7oe%^2-I|U6C_? E00ek#UH||9 diff --git a/src/cake/app/plugins/burocrata/locale/por/LC_MESSAGES/burocrata.po b/src/cake/app/plugins/burocrata/locale/por/LC_MESSAGES/burocrata.po index 13cfd4af..10b12a1e 100644 --- a/src/cake/app/plugins/burocrata/locale/por/LC_MESSAGES/burocrata.po +++ b/src/cake/app/plugins/burocrata/locale/por/LC_MESSAGES/burocrata.po @@ -4,8 +4,8 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" -"POT-Creation-Date: 2012-01-13 12:23-0200\n" -"PO-Revision-Date: 2012-01-13 17:46-0300\n" +"POT-Creation-Date: 2013-03-20 23:37-0300\n" +"PO-Revision-Date: 2013-03-20 23:41-0300\n" "Last-Translator: Daniel Abrahão \n" "Language-Team: Preface Design \n" "Language: \n" @@ -16,218 +16,270 @@ msgstr "" "X-Poedit-Language: Portuguese\n" "X-Poedit-Country: BRAZIL\n" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:561 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:574 msgid "Burocrata::submit - Submit label" msgstr "Enviar" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:575;652 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:588;665 msgid "Burocrata::okOrCancel - Cancel label" msgstr "Cancelar" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:634 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:647 msgid "Burocrata::okOrCancel - OK label" msgstr "Ok" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:662 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:675 msgid "anchorList or" msgstr "ou" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:917 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:972 msgid "Burocrata: nothing found on autocomplete." msgstr "Nada encontrado." -#: /plugins/burocrata/views/helpers/buro_burocrata.php:1020;1833 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:1081;1971 msgid "Burocrata: create a new related item" msgstr "Criar um novo" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:1021;1834 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:1082;1972 msgid "Burocrata: edit related data" msgstr "Editar" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:1022 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:1083 msgid "Burocrata: nothing found on autocomplete" msgstr "Nada encontrado." -#: /plugins/burocrata/views/helpers/buro_burocrata.php:1023 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:1084 msgid "Burocrata: choose another related item" msgstr "Escolher um outro" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:1024 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:1085 msgid "Burocrata: Bring last item back" msgstr "Usar último item" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:1561 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:1644 msgid "Burocrata::orderdItensMenu - list caption:" msgstr "Adicionar:" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:1567 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:1650 msgid "Burocrata::orderdItensMenu - close list" msgstr "Fechar" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:1669 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:1752 msgid "Burocrata::orderedItensControls - up" msgstr "Mover para cima" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:1675 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:1758 msgid "Burocrata::orderedItensControls - down" msgstr "Mover para baixo" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:1681 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:1764 msgid "Burocrata::orderedItensControls - delete" msgstr "Excluir" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:1687 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:1772 msgid "Burocrata::orderedItensControls - duplicate" msgstr "Duplicar" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:1693 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:1779 msgid "Burocrata::orderedItensControls - edit" msgstr "Editar" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:1835 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:1973 msgid "Burocrata: view related data" msgstr "Ver dados completos" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:1836 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:1974 msgid "Burocrata: unlink related data" msgstr "Remover" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:1837 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:1975 msgid "Burocrata: confirm unlinking" msgstr "Deseja remover mesmo?" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2217 -msgid "The uploaded file is too large. (filesize > upload_max_filesize or filesize > Model::$validate definitions)" -msgstr "O arquivo enviado é muito grande." - -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2218 -msgid "The uploaded file is too large. (filesize > post_max_size)" -msgstr "O arquivo enviado é muito grande." - -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2285 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2420 msgid "Burocrata::inputUpload - Change file" msgstr "Alterar" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2313 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2447 msgid "Burocrata::inputUpload - Download file" msgstr "Baixar arquivo" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2317 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2451 msgid "Burocrata::inputUpload - File: " msgstr "Arquivo:" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2347 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2481 msgid "Burocrata::inputImage - Change image" msgstr "Alterar essa imagem" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2349 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2483 msgid "Burocrata::inputImage - Remove image" msgstr "Remover essa imagem" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2351 -msgid "The uploaded file is not a valid image file." -msgstr "O arquivo enviado deveria ser de imagem." - -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2390 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2528 msgid "Burocrata::inputImage - or " msgstr " ou " -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2469 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2609 msgid "Burocrata::inputTextile - Preview" msgstr "Visualizar" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2498 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2644 msgid "Burocrata::inputTextile - Add bold" msgstr "Negrito" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2499 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2645 msgid "Burocrata::inputTextile - Add italic" msgstr "Itálico" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2500 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2646 msgid "Burocrata::inputTextile - Add link" msgstr "Link" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2501 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2647 msgid "Burocrata::inputTextile - Add title" msgstr "Título" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2502 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2648 msgid "Burocrata::inputTextile - Add image" msgstr "Imagem" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2503 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2649 msgid "Burocrata::inputTextile - Add file" msgstr "Arquivo" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2504 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2650 msgid "Burocrata::inputTextile - Add superscript" msgstr "Sobrescrito" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2505 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2651 msgid "Burocrata::inputTextile - Add subscript" msgstr "Subscrito" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2520 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2666 msgid "Burocrata::_popupTextileLink - Instructions for link" msgstr " " -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2521 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2667 msgid "Burocrata::_popupTextileLink - What is the text for this link" msgstr "Qual é o texto para este link?" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2522 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2668 msgid "Burocrata::_popupTextileLink - What is the URL of this link" msgstr "Qual é o endereço para o link?" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2523 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2669 msgid "Burocrata::_popupTextileLink - Title of link popup" msgstr "Link" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2555 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2701 msgid "Burocrata::_popupTextileTitle - Instructions for link" msgstr " " -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2556 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2702 msgid "Burocrata::_popupTextileTitle - What is the type of this title" msgstr " Tipo do título" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2557 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2703 msgid "Burocrata::_popupTextileTitle - Title" msgstr " Título" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2558 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2704 msgid "Burocrata::_popupTextileTitle - Subtitle" msgstr " Título" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2559 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2705 msgid "Burocrata::_popupTextileTitle - What is the title" msgstr " Título" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2560 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2706 msgid "Burocrata::_popupTextileTitle - Title of title popup" msgstr " Título" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2605 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2751 msgid "Burocrata::_popupTextilePreview - Title of preview popup" msgstr " " -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2630 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2776 msgid "Burocrata::_popupTextileFile - Title of `add file` popup" msgstr " Adição de arquivo" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2631 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2777 msgid "Burocrata::_popupTextileFile - Label of file input" msgstr " Arquivo:" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2669 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2815 msgid "Burocrata::_popupTextileImage - Title of `add image` popup" msgstr " Adição de imagem" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2670 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2816 msgid "Burocrata::_popupTextileImage - Label of file input" msgstr " Imagem:" +#: /plugins/burocrata/views/helpers/buro_captioner.php:55 +msgid "The uploaded file is too large. (filesize > upload_max_filesize or filesize > Model::$validate definitions)" +msgstr "O arquivo enviado é muito grande." + +#: /plugins/burocrata/views/helpers/buro_captioner.php:57 +msgid "The uploaded file is too large. (filesize > post_max_size)" +msgstr "O arquivo enviado é muito grande." + +#: /plugins/burocrata/views/helpers/buro_captioner.php:59 +msgid "The upload process could not be completed because the file was placed on a non-allowed directory." +msgstr "O local que o arquivo foi colocado não é permitido. Isso pode significar tentativa de burlar o sistema ou falha na configuração do servidor." + +#: /plugins/burocrata/views/helpers/buro_captioner.php:61 +msgid "The resource is blocked and the webserver can not work properly with it." +msgstr "Não foi possível ter acesso ao recurso enviado." + +#: /plugins/burocrata/views/helpers/buro_captioner.php:63 +msgid "The upload data does not define any type of resource" +msgstr "Os dados enviados não configuram um recurso que possa ser convertido em arquivo." + +#: /plugins/burocrata/views/helpers/buro_captioner.php:65 +msgid "Enviando o arquivo #{fileName}. Aguarde..." +msgstr "" + +#: /plugins/burocrata/views/helpers/buro_captioner.php:67 +msgid "Faltando #{hours} horas" +msgstr "" + +#: /plugins/burocrata/views/helpers/buro_captioner.php:69 +msgid "Faltando #{minutes} minutos" +msgstr "" + +#: /plugins/burocrata/views/helpers/buro_captioner.php:71 +msgid "Faltando #{seconds} segundos" +msgstr "" + +#: /plugins/burocrata/views/helpers/buro_captioner.php:73 +msgid "Cancelar" +msgstr "" + +#: /plugins/burocrata/views/helpers/buro_captioner.php:75 +msgid "Tentar de novo" +msgstr "" + +#: /plugins/burocrata/views/helpers/buro_captioner.php:77 +msgid "Remover arquivo" +msgstr "" + +#: /plugins/burocrata/views/helpers/buro_captioner.php:79 +msgid "Really abort?" +msgstr "Deseja realmente cancelar o envio?" + +#: /plugins/burocrata/views/helpers/buro_captioner.php:81 +msgid "Something went wrong and the file was not sent." +msgstr "Algo deu errado ao enviar os dados. É provável que sua comunicação com o site esteja com problema." + +#: /plugins/burocrata/views/helpers/buro_captioner.php:83 +msgid "Something went wrong and the file was not sent. The server returned #{error}" +msgstr "Algo deu errado com o envio. O servidor retornou \"#{error}\"." + +#: /plugins/burocrata/views/helpers/buro_captioner.php:94 +msgid "The uploaded file is not a valid image file." +msgstr "O arquivo enviado deveria ser de imagem." + #~ msgid "Burocrata: default save button" #~ msgstr "Salvar" From cc09924e875fedc678c49db600da7975b83b9c91 Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Wed, 20 Mar 2013 23:44:04 -0300 Subject: [PATCH 27/42] Fixing the addCallbacks of BuroUploadGeneric --- src/cake/app/plugins/burocrata/webroot/js/burocrata.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js index 3da39b6c..4a78e3ff 100644 --- a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js +++ b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js @@ -1871,11 +1871,11 @@ var BuroUploadGeneric = Class.create({ this.object = new BuroUpload(id_base, url, parameters); }, - addCallbacks: function($super, type, callback) + addCallbacks: function(type, callbacks) { if (type == 'ajax' && this.ajax_upload) this.object.addCallbacks(callbacks); - else if (type == 'classic') + else if (type == 'classic' && !this.ajax_upload) this.object.addCallbacks(callbacks); return this; From e520f5c340555154a55947ae9f5c04b3bea9982e Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Wed, 20 Mar 2013 23:44:46 -0300 Subject: [PATCH 28/42] Created the new BuroAjaxUpload callback: onSave --- .../app/plugins/burocrata/views/helpers/buro_office_boy.php | 1 + src/cake/app/plugins/burocrata/webroot/js/burocrata.js | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cake/app/plugins/burocrata/views/helpers/buro_office_boy.php b/src/cake/app/plugins/burocrata/views/helpers/buro_office_boy.php index 8ce4f826..85e6c70e 100644 --- a/src/cake/app/plugins/burocrata/views/helpers/buro_office_boy.php +++ b/src/cake/app/plugins/burocrata/views/helpers/buro_office_boy.php @@ -102,6 +102,7 @@ class BuroOfficeBoyHelper extends AppHelper 'onComplete' => 'function(upload, json){%s}', 'onPieceSent' => 'function(upload, json){%s}', 'onReject' => 'function(upload, json, saved){%s}', + 'onSave' => 'function(upload, json, saved){%s}', 'onRestart' => 'function(upload){%s}', 'onError' => 'function(upload, json){%s}' ), diff --git a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js index 4a78e3ff..8643e095 100644 --- a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js +++ b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js @@ -2339,8 +2339,9 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { this.trigger('onPieceSent', this); this.uploadOnePiece(); } - else + else if (this.state == this.ST_UPLOADING) { + this.trigger('onSave', this, this.json); this.finish(); } }, From 6d6c87acb4bd8bd81e285784a848edf7e0022f45 Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Wed, 20 Mar 2013 23:45:54 -0300 Subject: [PATCH 29/42] Allowing to specify the saving model of Upload inputs --- .../plugins/backstage/views/back_contents/layout_test.ctp | 3 ++- .../app/plugins/burocrata/views/helpers/buro_burocrata.php | 7 ------- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/cake/app/plugins/backstage/views/back_contents/layout_test.ctp b/src/cake/app/plugins/backstage/views/back_contents/layout_test.ctp index b233a44f..841bf276 100644 --- a/src/cake/app/plugins/backstage/views/back_contents/layout_test.ctp +++ b/src/cake/app/plugins/backstage/views/back_contents/layout_test.ctp @@ -289,7 +289,8 @@ echo $this->Bl->sbox(null, array('size' => array('M' => 7, 'g' => -1))); 'type' => 'upload', 'fieldName' => 'upload', 'label' => 'Label for a upload input', - 'instructions' => 'Instructions for a upload input' + 'instructions' => 'Instructions for a upload input', + 'options' => array('model' => 'JjMedia.SfilBigFile') ) ); diff --git a/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php b/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php index 011b18ce..b3dd6980 100644 --- a/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php +++ b/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php @@ -2344,13 +2344,6 @@ protected function _uploadParams($options) $gen_options = $options['options'] + $defaults; - // Temporary warning - if ($gen_options['model'] != 'JjMedia.SfilStoredFile') - { - trigger_error('BuroBurocrataHelper::_uploadParams() - Changing the upload model is not supported yet! Using the default.'); - $gen_options['model'] = 'JjMedia.SfilStoredFile'; - } - if (isset($file_input_options['error'])) { $gen_options['error'] = $file_input_options['error']; From 286e40017503d9c887b2f5e6a50cb169e6f8f31c Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Wed, 20 Mar 2013 23:55:53 -0300 Subject: [PATCH 30/42] Some re-factor on BuroAjaxUpload code Also, making the "Remove file" link work --- .../plugins/burocrata/webroot/js/burocrata.js | 45 ++++++++++--------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js index 8643e095..312096b2 100644 --- a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js +++ b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js @@ -2102,12 +2102,12 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { this.tryAgainLink = new Element('a', {href: '#'}).update(BuroCaption.get('upload', 'try_again')); this.tryAgainLink.on('click', this.again.bind(this)); this.removeFileLink = new Element('a', {href: '#'}).update(BuroCaption.get('upload', 'remove')); - this.removeFileLink.on('click', this.reset.bind(this)); + this.removeFileLink.on('click', this.again.bind(this)); this.controls = new Element('div'); this.controls.insert(this.cancelLink).insert(' ') .insert(this.tryAgainLink).insert(' ') - .insert(this.removeFile) + .insert(this.removeFileLink) this.progress_bar = new Element('div', {className: 'progress_bar'}); this.progress_bar.insert(new Element('div', {className: 'filling'})); @@ -2131,16 +2131,34 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { this.currentByte = this.errorCount = 0; this.aborted = false; this.state = this.ST_READY; - this.clearXHR(); + + this.upload_input.show().value = ''; + this.upload_input.up('.input').removeClassName('error').select('.error-message').invoke('remove'); + this.progress_bar.setStyle({visibility: 'hidden'}); + + this.clearCaption().clearXHR().controlControls(); + }, + clearCaption: function() + { if (this.caption) { this.caption.remove(); this.caption = null; } - this.upload_input.show().value = ''; - this.upload_input.up('.input').removeClassName('error').select('.error-message').invoke('remove'); - this.progress_bar.setStyle({visibility: 'hidden'}); - this.controlControls(); + return this; + }, + clearXHR: function() + { + if (this.xhr) + { + this.xhr.upload.removeEventListener('error', this.handleErrorBinded); + this.xhr.upload.removeEventListener('progress', this.handleProgressBinded); + this.xhr.upload.removeEventListener('abort', this.handleAbortBinded); + this.xhr.onreadystatechange = null; + this.xhr = null; + this.json = false; + } + return this; }, controlControls: function() { @@ -2188,8 +2206,6 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { if (ev) ev.stop(); this.reset(); - this.upload_input.show(); - this.trigger('onRestart', this); }, inputChange: function(ev) @@ -2345,17 +2361,6 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { this.finish(); } }, - clearXHR: function() - { - if (!this.xhr) - return; - this.xhr.upload.removeEventListener('error', this.handleErrorBinded); - this.xhr.upload.removeEventListener('progress', this.handleProgressBinded); - this.xhr.upload.removeEventListener('abort', this.handleAbortBinded); - this.xhr.onreadystatechange = null; - this.xhr = null; - this.json = false; - }, handleError: function(ev) { if (this.state == this.ST_ERROR) From 1219e99271fdd749e0059efd450b74650c7d5a4c Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Thu, 21 Mar 2013 00:36:42 -0300 Subject: [PATCH 31/42] Moving forward to the great finish! The BuroAjaxUpload already displays message when everything goes ok. Link for downloading data after complete working. Minor re-factoring that removes the need of upload view. --- .../views/helpers/buro_burocrata.php | 4 +++ .../views/helpers/buro_captioner.php | 6 ++++ .../plugins/burocrata/webroot/js/burocrata.js | 36 +++++++++++++------ .../controllers/jj_media_controller.php | 32 +++++++++++------ .../app/plugins/jj_media/views/helpers/empty | 0 .../jj_media/views/jj_media/upload.ctp | 25 ------------- 6 files changed, 57 insertions(+), 46 deletions(-) delete mode 100644 src/cake/app/plugins/jj_media/views/helpers/empty delete mode 100644 src/cake/app/plugins/jj_media/views/jj_media/upload.ctp diff --git a/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php b/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php index b3dd6980..0ba70cc5 100644 --- a/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php +++ b/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php @@ -2439,6 +2439,10 @@ public function inputUpload($options) $script .= "$('{$act_id}').hide(); $('{$prv_id}').hide();"; $script .= "$('{$chg_id}').observe('click', function(ev){ev.stop(); BuroCR.get('{$gen_options['baseID']}').again();});"; $out .= $this->BuroOfficeBoy->addHtmlEmbScript($script); + + if (!isset($gen_options['callbacks']['ajax']['onSave']['js'])) + $gen_options['callbacks']['ajax']['onSave']['js'] = ''; + $gen_options['callbacks']['ajax']['onSave']['js'] = "BuroCR.get('{$gen_options['baseID']}').addCaption(BuroCaption.get('upload', 'transfer_ok', json));"; $out .= $this->_upload($gen_options, $file_input_options); diff --git a/src/cake/app/plugins/burocrata/views/helpers/buro_captioner.php b/src/cake/app/plugins/burocrata/views/helpers/buro_captioner.php index a310d459..9a29afa7 100644 --- a/src/cake/app/plugins/burocrata/views/helpers/buro_captioner.php +++ b/src/cake/app/plugins/burocrata/views/helpers/buro_captioner.php @@ -77,10 +77,16 @@ protected function _upload() __d('burocrata', 'Remover arquivo', true)); $this->BuroOfficeBoy->addCaption('upload', 'really_abort', __d('burocrata', 'Really abort?', true)); + $this->BuroOfficeBoy->addCaption('upload', 'really_remove', + __d('burocrata', 'Really remove?', true)); $this->BuroOfficeBoy->addCaption('upload', 'generic_error', __d('burocrata', 'Something went wrong and the file was not sent.', true)); $this->BuroOfficeBoy->addCaption('upload', 'error_with_server_resp', __d('burocrata', 'Something went wrong and the file was not sent. The server returned #{error}', true)); + $this->BuroOfficeBoy->addCaption('upload', 'transfer_ok', + __d('burocrata', 'The file was successfully recevied.', true)); + $this->BuroOfficeBoy->addCaption('upload', 'get_file', + __d('burocrata', 'Download the file', true)); } /** diff --git a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js index 312096b2..7345fd94 100644 --- a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js +++ b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js @@ -2102,12 +2102,14 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { this.tryAgainLink = new Element('a', {href: '#'}).update(BuroCaption.get('upload', 'try_again')); this.tryAgainLink.on('click', this.again.bind(this)); this.removeFileLink = new Element('a', {href: '#'}).update(BuroCaption.get('upload', 'remove')); - this.removeFileLink.on('click', this.again.bind(this)); + this.removeFileLink.on('click', this.removeFile.bind(this)); + this.getFileLink = new Element('a', {href: ''}).update(BuroCaption.get('upload', 'get_file')); this.controls = new Element('div'); this.controls.insert(this.cancelLink).insert(' ') .insert(this.tryAgainLink).insert(' ') - .insert(this.removeFileLink) + .insert(this.removeFileLink).insert(' ') + .insert(this.getFileLink); this.progress_bar = new Element('div', {className: 'progress_bar'}); this.progress_bar.insert(new Element('div', {className: 'filling'})); @@ -2134,10 +2136,17 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { this.upload_input.show().value = ''; this.upload_input.up('.input').removeClassName('error').select('.error-message').invoke('remove'); - this.progress_bar.setStyle({visibility: 'hidden'}); + this.progress_bar.hide(); this.clearCaption().clearXHR().controlControls(); }, + addCaption: function(caption) + { + this.clearCaption(); + this.upload_input.insert({ + after: this.caption = (new Element('span')).insert(caption) + }); + }, clearCaption: function() { if (this.caption) @@ -2156,7 +2165,6 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { this.xhr.upload.removeEventListener('abort', this.handleAbortBinded); this.xhr.onreadystatechange = null; this.xhr = null; - this.json = false; } return this; }, @@ -2165,6 +2173,7 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { this.tryAgainLink.hide(); this.removeFileLink.hide(); this.cancelLink.hide(); + this.getFileLink.hide(); switch (this.state) { case this.ST_READY: @@ -2176,6 +2185,7 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { case this.ST_DONE: this.removeFileLink.show(); + this.getFileLink.show(); break; case this.ST_ERROR: @@ -2208,6 +2218,12 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { this.reset(); this.trigger('onRestart', this); }, + removeFile: function(ev) + { + ev.stop(); + if (confirm(BuroCaption.get('upload', 'really_remove'))) + this.reset(); + }, inputChange: function(ev) { if (this.state != this.ST_READY) @@ -2219,15 +2235,14 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { } else if (this.upload_input.files.length == 1) { - var caption, file = this.upload_input.files[0]; + var file = this.upload_input.files[0]; this.reset(); this.file = file; - caption = BuroCaption.get('upload', 'sending', {fileName: this.getFileName()}); - this.upload_input - .insert({ after: this.caption = (new Element('span')).insert(caption) }) - .hide(); + this.upload_input.hide(); + this.addCaption(BuroCaption.get('upload', 'sending', {fileName: this.getFileName()})); + this.startTime = new Date().getTime(); this.controls.setStyle({visibility: 'visible'}); @@ -2402,6 +2417,7 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { }, finish: function() { + this.getFileLink.href = this.json.dlurl; this.state = this.ST_DONE; this.controlControls(); this.trigger('onComplete', this, this.json); @@ -2432,7 +2448,7 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { this.progress_bar.down('.label').update(percent); if (timeLeft > 2000) - this.progress_bar.setStyle({visibility: 'visible'}); + this.progress_bar.show(); }, renderError: function() { diff --git a/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php b/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php index 7802e0aa..ce72ea95 100644 --- a/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php +++ b/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php @@ -175,10 +175,9 @@ function upload() return; } - $this->set($this->saveUpload($this->data)); - $this->layout = 'ajax'; $this->view = 'Typographer.Type'; + $this->set('jsonVars', $this->saveUpload($this->data)); } /** @@ -278,11 +277,7 @@ protected function performAjaxUpload() } else { - App::import('Lib', array('JjUtils.SecureParams')); - $packed_params = SecureParams::pack(array($savedData['saved'], $savedData['version']), true); - $baseUrl = array('plugin' => 'jj_media', 'controller' => 'jj_media', 'action' => 'index'); - $dlurl = Router::url($baseUrl + array('1', $packed_params)); - $url = Router::url($baseUrl + array($packed_params)); + extract($savedData); } } else @@ -296,9 +291,17 @@ protected function performAjaxUpload() } /** - * - * - * @access + * Performs the logic of saving the upload data + * + * This method receive the POSTed data from each action (classic or ajax upload) + * validates the upload and saves it. + * The returned data is a array of the generated data (that will generally be + * sent back to the view, through JSON object) + * + * @access protected + * @param array $data The POSTed data to be analised and saved + * @param string $forceModel When not null, will force a Model to be used, instead of the specified on POSTed data + * @return array The array of data of generated data */ protected function saveUpload($data, $forceModel = null) { @@ -345,9 +348,16 @@ protected function saveUpload($data, $forceModel = null) list($fieldModelName, $fieldName) = pluginSplit($fieldName); if (!empty($data[$fieldModelName][$fieldName])) $Model->delete($data[$fieldModelName][$fieldName]); + + App::import('Lib', array('JjUtils.SecureParams')); + $packed_params = SecureParams::pack(array($saved, $version), true); + $baseUrl = array('plugin' => 'jj_media', 'controller' => 'jj_media', 'action' => 'index'); + $dlurl = Router::url($baseUrl + array('1', $packed_params)); + $url = Router::url($baseUrl + array($packed_params)); } } } - return compact('error', 'validationErrors', 'saved', 'version', 'filename'); + + return compact('error', 'validationErrors', 'saved', 'version', 'filename', 'url', 'dlurl'); } } diff --git a/src/cake/app/plugins/jj_media/views/helpers/empty b/src/cake/app/plugins/jj_media/views/helpers/empty deleted file mode 100644 index e69de29b..00000000 diff --git a/src/cake/app/plugins/jj_media/views/jj_media/upload.ctp b/src/cake/app/plugins/jj_media/views/jj_media/upload.ctp deleted file mode 100644 index 447b382b..00000000 --- a/src/cake/app/plugins/jj_media/views/jj_media/upload.ctp +++ /dev/null @@ -1,25 +0,0 @@ -Bl->fileURL($saved, $version); - $dlurl = $this->Bl->fileURL($saved, $version, true); - } - - $extraCaptions = $this->BuroOfficeBoy->getAllCaptions(); - - echo json_encode(compact('error', 'validationErrors', 'saved', 'url', 'dlurl', 'filename', 'extraCaptions')); From 8a7c7ef01ec87466268e29abf67fab5a904fd69f Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Thu, 21 Mar 2013 00:37:35 -0300 Subject: [PATCH 32/42] Removing a bunch of "empty" files from jj_media plugin --- src/cake/app/plugins/jj_media/controllers/components/empty | 0 src/cake/app/plugins/jj_media/libs/empty | 0 src/cake/app/plugins/jj_media/models/datasources/empty | 0 src/cake/app/plugins/jj_media/tests/cases/behaviors/empty | 0 src/cake/app/plugins/jj_media/tests/cases/components/empty | 0 src/cake/app/plugins/jj_media/tests/cases/helpers/empty | 0 src/cake/app/plugins/jj_media/tests/fixtures/empty | 0 src/cake/app/plugins/jj_media/tests/groups/empty | 0 src/cake/app/plugins/jj_media/webroot/empty | 0 9 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/cake/app/plugins/jj_media/controllers/components/empty delete mode 100644 src/cake/app/plugins/jj_media/libs/empty delete mode 100644 src/cake/app/plugins/jj_media/models/datasources/empty delete mode 100644 src/cake/app/plugins/jj_media/tests/cases/behaviors/empty delete mode 100644 src/cake/app/plugins/jj_media/tests/cases/components/empty delete mode 100644 src/cake/app/plugins/jj_media/tests/cases/helpers/empty delete mode 100644 src/cake/app/plugins/jj_media/tests/fixtures/empty delete mode 100644 src/cake/app/plugins/jj_media/tests/groups/empty delete mode 100644 src/cake/app/plugins/jj_media/webroot/empty diff --git a/src/cake/app/plugins/jj_media/controllers/components/empty b/src/cake/app/plugins/jj_media/controllers/components/empty deleted file mode 100644 index e69de29b..00000000 diff --git a/src/cake/app/plugins/jj_media/libs/empty b/src/cake/app/plugins/jj_media/libs/empty deleted file mode 100644 index e69de29b..00000000 diff --git a/src/cake/app/plugins/jj_media/models/datasources/empty b/src/cake/app/plugins/jj_media/models/datasources/empty deleted file mode 100644 index e69de29b..00000000 diff --git a/src/cake/app/plugins/jj_media/tests/cases/behaviors/empty b/src/cake/app/plugins/jj_media/tests/cases/behaviors/empty deleted file mode 100644 index e69de29b..00000000 diff --git a/src/cake/app/plugins/jj_media/tests/cases/components/empty b/src/cake/app/plugins/jj_media/tests/cases/components/empty deleted file mode 100644 index e69de29b..00000000 diff --git a/src/cake/app/plugins/jj_media/tests/cases/helpers/empty b/src/cake/app/plugins/jj_media/tests/cases/helpers/empty deleted file mode 100644 index e69de29b..00000000 diff --git a/src/cake/app/plugins/jj_media/tests/fixtures/empty b/src/cake/app/plugins/jj_media/tests/fixtures/empty deleted file mode 100644 index e69de29b..00000000 diff --git a/src/cake/app/plugins/jj_media/tests/groups/empty b/src/cake/app/plugins/jj_media/tests/groups/empty deleted file mode 100644 index e69de29b..00000000 diff --git a/src/cake/app/plugins/jj_media/webroot/empty b/src/cake/app/plugins/jj_media/webroot/empty deleted file mode 100644 index e69de29b..00000000 From 2233b139492ba1f23f3462ce2800ce7d327cc6de Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Thu, 21 Mar 2013 00:40:48 -0300 Subject: [PATCH 33/42] Removing console.log() calls from code. --- src/cake/app/plugins/burocrata/webroot/js/burocrata.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js index 7345fd94..e870590e 100644 --- a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js +++ b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js @@ -2265,9 +2265,7 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { uploadOnePiece: function() { if (this.xhr) - return console.log('Opa! Tem alguém trabalhando, já.'); - - console.log('Empurrando mais um bloquinho.'); + return ; var chunk, form; @@ -2389,7 +2387,6 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { this.errorCount++; if (this.errorCount < this.MAX_TRIES) { - console.log('eita, deixe-me tentar novamente.'); this.clearXHR(); this.uploadOnePiece(); return; @@ -2404,7 +2401,6 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { this.trigger('onReject', this, this.json, false); else this.trigger('onError', this, this.json); - console.log('erro definitivo!'); }, handleProgress: function(ev) { From cb5dfdf94907f13e06e235f3f0530599fe6df731 Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Thu, 21 Mar 2013 00:52:45 -0300 Subject: [PATCH 34/42] Translation of some portuguese code --- .../locale/por/LC_MESSAGES/burocrata.mo | Bin 5553 -> 6024 bytes .../locale/por/LC_MESSAGES/burocrata.po | 170 +++++++++--------- .../views/helpers/buro_captioner.php | 20 +-- 3 files changed, 95 insertions(+), 95 deletions(-) diff --git a/src/cake/app/plugins/burocrata/locale/por/LC_MESSAGES/burocrata.mo b/src/cake/app/plugins/burocrata/locale/por/LC_MESSAGES/burocrata.mo index acf21e0a154ec7ce6ac026301341684ea381c2d3..d026db19a945e98b434b1f163818f8f50e67a757 100644 GIT binary patch delta 1900 zcmYk+O>7ip9LMpeQYZqo+JY4od0a}}+IG8rQ)m@zLBOQa+Mq~cBGc{DI%PW}v%4*7 zv_?}j9EjT3#BlInG=@kbwkB#~jB(cx{aALqg?cH<2d%r+qLn`_Myr} zcrPxZ%71~)_%mw7s@KK$o6wSf4AssQ-jDBKn*Pn#T&UtzY{lBzIKLg$@L{w#kF1{g z2yeqP$j^Mk-!1q(-ilYS1Fzu_ZsMT^Jcax4Bxk@&xe{u?uOmgxiNsUL?wU{PS^owumbsyh&f|K# zh-|O<4fXsFq(4(lrW#kF#kHuVZbLmEO5BgCKazMTaV+r&YCy#X)}L!L&!2pcKXq^h zHNwvlze3IAJ5<9LP~|S727U?IcJnK$-ZkXdnCnSivtqT)YE=EkL_5a?Z=7jCbY z*o|sv2Wq5yP!$iN${j{_$4n;q+2r{vsE*#i6fR;1eu>(u-*E!}!G~~ej1AM_cpvrJ zoWm#ZI=+Q_Z;xNI%cusc8e^MK1KW!_J5Qq~GLPB{J<~wRmJhLBQJO5jF?>4A9Rx|| zKTbMeN)Hf^5Sr~KqKD`rl=K~_r1s=O`>&KH^uf`rbojJ7mBfoxe)Tj!B~5gI=&tn7 z`6}-xt5RMjiz^5vy%AYL%h*Ebqogk&TU-8W4x&;ov60aBRZ=Rs&>2x`CiL#Jm}Wb% zO<%MOp~ItPtR#K8w2%5yX?yM@bRLv;5)UqIUHNy-o?Tv$b9u8noDK4!H*Sm1IXmI! zof&mrKL3LC#=@w$vyzM4bU5Rbl@#_1<x zqN62$CR`Y6Xc~Ab%$+-Ji*DNHTvT)~diH3^*>P8JQy!z%1S1<(s#NBD!>xt+h7VK2 zl>&Am^vjbS^T$J*3#YXVtU|byUVpr5;D8H?3?K++m|;+K=Fwor_X3Lk--S)xum-7& Q9hfY6(YRy&CM=o%0N?rpJ^%m! delta 1405 zcmYk+eQ3>59LMqRwI>_9?wyS>4|f}TW)FAQY-XbfwKPwE(5yzZSSDFfawWv1Y&TD( zq*n6BmbtQj{6WeeijaHsR|een=%LX7jNWi*OyP-F{qv=Un|ZmQa6+rT7!)VL@u5{YtE%-i}ML z55s0r8>P^|gTGjd^=XNQ`*0cc>$n`>pgQJFHjCh9)PTLX5aX!+FR>c^>1Iv10yWVn zs@(wQ;V2d`zJ2ftX6YGbh5S*0>d=Y>*n`D*8B6g#s@*5dNB@*W`zkD=z6BMrBkuWC z3{ii8de1v7!;GmcfblItK^@z%98bFXFlr(%Fob_F6X)?$i51v_ZMYV1q9X7eJFwVK z8$5%G@Lk-C-;gG@eHu}@as&0=p)BIBh9f-C%es15!G&WlmgMW7WbeHb?A2DZajs$nqydvWyEy@w&8gk!V+v|ztpeO zc@{OHAymjUsFD_`NG~DRk)xW0R>XDnPB#nk4h4M-W9ZnBJv_K--oCzc7N!jqWh_&LpPJmqP>rXwnT|zVl&7JZ82FZjF6Rd zr9vvWq^Rn9p){9VNuEW{Cr_jtJ=V`<*=yf0%Q^ Jm(<;3{{ZKCd@uk2 diff --git a/src/cake/app/plugins/burocrata/locale/por/LC_MESSAGES/burocrata.po b/src/cake/app/plugins/burocrata/locale/por/LC_MESSAGES/burocrata.po index 10b12a1e..5e5d532b 100644 --- a/src/cake/app/plugins/burocrata/locale/por/LC_MESSAGES/burocrata.po +++ b/src/cake/app/plugins/burocrata/locale/por/LC_MESSAGES/burocrata.po @@ -4,8 +4,8 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" -"POT-Creation-Date: 2013-03-20 23:37-0300\n" -"PO-Revision-Date: 2013-03-20 23:41-0300\n" +"POT-Creation-Date: 2013-03-21 00:50-0300\n" +"PO-Revision-Date: 2013-03-21 00:51-0300\n" "Last-Translator: Daniel Abrahão \n" "Language-Team: Preface Design \n" "Language: \n" @@ -16,267 +16,267 @@ msgstr "" "X-Poedit-Language: Portuguese\n" "X-Poedit-Country: BRAZIL\n" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:574 +#: /views/helpers/buro_burocrata.php:574 msgid "Burocrata::submit - Submit label" msgstr "Enviar" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:588;665 +#: /views/helpers/buro_burocrata.php:588;665 msgid "Burocrata::okOrCancel - Cancel label" msgstr "Cancelar" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:647 +#: /views/helpers/buro_burocrata.php:647 msgid "Burocrata::okOrCancel - OK label" msgstr "Ok" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:675 +#: /views/helpers/buro_burocrata.php:675 msgid "anchorList or" msgstr "ou" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:972 +#: /views/helpers/buro_burocrata.php:972 msgid "Burocrata: nothing found on autocomplete." msgstr "Nada encontrado." -#: /plugins/burocrata/views/helpers/buro_burocrata.php:1081;1971 +#: /views/helpers/buro_burocrata.php:1081;1971 msgid "Burocrata: create a new related item" msgstr "Criar um novo" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:1082;1972 +#: /views/helpers/buro_burocrata.php:1082;1972 msgid "Burocrata: edit related data" msgstr "Editar" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:1083 +#: /views/helpers/buro_burocrata.php:1083 msgid "Burocrata: nothing found on autocomplete" msgstr "Nada encontrado." -#: /plugins/burocrata/views/helpers/buro_burocrata.php:1084 +#: /views/helpers/buro_burocrata.php:1084 msgid "Burocrata: choose another related item" msgstr "Escolher um outro" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:1085 +#: /views/helpers/buro_burocrata.php:1085 msgid "Burocrata: Bring last item back" msgstr "Usar último item" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:1644 +#: /views/helpers/buro_burocrata.php:1644 msgid "Burocrata::orderdItensMenu - list caption:" msgstr "Adicionar:" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:1650 +#: /views/helpers/buro_burocrata.php:1650 msgid "Burocrata::orderdItensMenu - close list" msgstr "Fechar" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:1752 +#: /views/helpers/buro_burocrata.php:1752 msgid "Burocrata::orderedItensControls - up" msgstr "Mover para cima" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:1758 +#: /views/helpers/buro_burocrata.php:1758 msgid "Burocrata::orderedItensControls - down" msgstr "Mover para baixo" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:1764 +#: /views/helpers/buro_burocrata.php:1764 msgid "Burocrata::orderedItensControls - delete" msgstr "Excluir" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:1772 +#: /views/helpers/buro_burocrata.php:1772 msgid "Burocrata::orderedItensControls - duplicate" msgstr "Duplicar" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:1779 +#: /views/helpers/buro_burocrata.php:1779 msgid "Burocrata::orderedItensControls - edit" msgstr "Editar" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:1973 +#: /views/helpers/buro_burocrata.php:1973 msgid "Burocrata: view related data" msgstr "Ver dados completos" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:1974 +#: /views/helpers/buro_burocrata.php:1974 msgid "Burocrata: unlink related data" msgstr "Remover" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:1975 +#: /views/helpers/buro_burocrata.php:1975 msgid "Burocrata: confirm unlinking" msgstr "Deseja remover mesmo?" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2420 +#: /views/helpers/buro_burocrata.php:2420 msgid "Burocrata::inputUpload - Change file" msgstr "Alterar" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2447 +#: /views/helpers/buro_burocrata.php:2451 msgid "Burocrata::inputUpload - Download file" msgstr "Baixar arquivo" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2451 +#: /views/helpers/buro_burocrata.php:2455 msgid "Burocrata::inputUpload - File: " msgstr "Arquivo:" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2481 +#: /views/helpers/buro_burocrata.php:2485 msgid "Burocrata::inputImage - Change image" msgstr "Alterar essa imagem" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2483 +#: /views/helpers/buro_burocrata.php:2487 msgid "Burocrata::inputImage - Remove image" msgstr "Remover essa imagem" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2528 +#: /views/helpers/buro_burocrata.php:2532 msgid "Burocrata::inputImage - or " msgstr " ou " -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2609 +#: /views/helpers/buro_burocrata.php:2613 msgid "Burocrata::inputTextile - Preview" msgstr "Visualizar" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2644 +#: /views/helpers/buro_burocrata.php:2648 msgid "Burocrata::inputTextile - Add bold" msgstr "Negrito" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2645 +#: /views/helpers/buro_burocrata.php:2649 msgid "Burocrata::inputTextile - Add italic" msgstr "Itálico" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2646 +#: /views/helpers/buro_burocrata.php:2650 msgid "Burocrata::inputTextile - Add link" msgstr "Link" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2647 +#: /views/helpers/buro_burocrata.php:2651 msgid "Burocrata::inputTextile - Add title" msgstr "Título" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2648 +#: /views/helpers/buro_burocrata.php:2652 msgid "Burocrata::inputTextile - Add image" msgstr "Imagem" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2649 +#: /views/helpers/buro_burocrata.php:2653 msgid "Burocrata::inputTextile - Add file" msgstr "Arquivo" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2650 +#: /views/helpers/buro_burocrata.php:2654 msgid "Burocrata::inputTextile - Add superscript" msgstr "Sobrescrito" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2651 +#: /views/helpers/buro_burocrata.php:2655 msgid "Burocrata::inputTextile - Add subscript" msgstr "Subscrito" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2666 +#: /views/helpers/buro_burocrata.php:2670 msgid "Burocrata::_popupTextileLink - Instructions for link" msgstr " " -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2667 +#: /views/helpers/buro_burocrata.php:2671 msgid "Burocrata::_popupTextileLink - What is the text for this link" msgstr "Qual é o texto para este link?" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2668 +#: /views/helpers/buro_burocrata.php:2672 msgid "Burocrata::_popupTextileLink - What is the URL of this link" msgstr "Qual é o endereço para o link?" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2669 +#: /views/helpers/buro_burocrata.php:2673 msgid "Burocrata::_popupTextileLink - Title of link popup" msgstr "Link" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2701 +#: /views/helpers/buro_burocrata.php:2705 msgid "Burocrata::_popupTextileTitle - Instructions for link" msgstr " " -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2702 +#: /views/helpers/buro_burocrata.php:2706 msgid "Burocrata::_popupTextileTitle - What is the type of this title" msgstr " Tipo do título" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2703 +#: /views/helpers/buro_burocrata.php:2707 msgid "Burocrata::_popupTextileTitle - Title" msgstr " Título" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2704 +#: /views/helpers/buro_burocrata.php:2708 msgid "Burocrata::_popupTextileTitle - Subtitle" msgstr " Título" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2705 +#: /views/helpers/buro_burocrata.php:2709 msgid "Burocrata::_popupTextileTitle - What is the title" msgstr " Título" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2706 +#: /views/helpers/buro_burocrata.php:2710 msgid "Burocrata::_popupTextileTitle - Title of title popup" msgstr " Título" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2751 +#: /views/helpers/buro_burocrata.php:2755 msgid "Burocrata::_popupTextilePreview - Title of preview popup" msgstr " " -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2776 +#: /views/helpers/buro_burocrata.php:2780 msgid "Burocrata::_popupTextileFile - Title of `add file` popup" msgstr " Adição de arquivo" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2777 +#: /views/helpers/buro_burocrata.php:2781 msgid "Burocrata::_popupTextileFile - Label of file input" msgstr " Arquivo:" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2815 +#: /views/helpers/buro_burocrata.php:2819 msgid "Burocrata::_popupTextileImage - Title of `add image` popup" msgstr " Adição de imagem" -#: /plugins/burocrata/views/helpers/buro_burocrata.php:2816 +#: /views/helpers/buro_burocrata.php:2820 msgid "Burocrata::_popupTextileImage - Label of file input" msgstr " Imagem:" -#: /plugins/burocrata/views/helpers/buro_captioner.php:55 +#: /views/helpers/buro_captioner.php:55 msgid "The uploaded file is too large. (filesize > upload_max_filesize or filesize > Model::$validate definitions)" msgstr "O arquivo enviado é muito grande." -#: /plugins/burocrata/views/helpers/buro_captioner.php:57 +#: /views/helpers/buro_captioner.php:57 msgid "The uploaded file is too large. (filesize > post_max_size)" msgstr "O arquivo enviado é muito grande." -#: /plugins/burocrata/views/helpers/buro_captioner.php:59 +#: /views/helpers/buro_captioner.php:59 msgid "The upload process could not be completed because the file was placed on a non-allowed directory." msgstr "O local que o arquivo foi colocado não é permitido. Isso pode significar tentativa de burlar o sistema ou falha na configuração do servidor." -#: /plugins/burocrata/views/helpers/buro_captioner.php:61 +#: /views/helpers/buro_captioner.php:61 msgid "The resource is blocked and the webserver can not work properly with it." msgstr "Não foi possível ter acesso ao recurso enviado." -#: /plugins/burocrata/views/helpers/buro_captioner.php:63 +#: /views/helpers/buro_captioner.php:63 msgid "The upload data does not define any type of resource" msgstr "Os dados enviados não configuram um recurso que possa ser convertido em arquivo." -#: /plugins/burocrata/views/helpers/buro_captioner.php:65 -msgid "Enviando o arquivo #{fileName}. Aguarde..." -msgstr "" - -#: /plugins/burocrata/views/helpers/buro_captioner.php:67 -msgid "Faltando #{hours} horas" -msgstr "" - -#: /plugins/burocrata/views/helpers/buro_captioner.php:69 -msgid "Faltando #{minutes} minutos" -msgstr "" - -#: /plugins/burocrata/views/helpers/buro_captioner.php:71 -msgid "Faltando #{seconds} segundos" -msgstr "" +#: /views/helpers/buro_captioner.php:65 +msgid "Uploading file #{fileName}. Please, wait..." +msgstr "Enviando o arquivo \"#{fileName}\". Aguarde..." -#: /plugins/burocrata/views/helpers/buro_captioner.php:73 -msgid "Cancelar" -msgstr "" +#: /views/helpers/buro_captioner.php:73 +msgid "Cancel" +msgstr "Cancelar" -#: /plugins/burocrata/views/helpers/buro_captioner.php:75 -msgid "Tentar de novo" -msgstr "" +#: /views/helpers/buro_captioner.php:75 +msgid "Try again" +msgstr "Tentar novamente" -#: /plugins/burocrata/views/helpers/buro_captioner.php:77 -msgid "Remover arquivo" -msgstr "" +#: /views/helpers/buro_captioner.php:77 +msgid "Remove this file" +msgstr "Remover o arquivo" -#: /plugins/burocrata/views/helpers/buro_captioner.php:79 +#: /views/helpers/buro_captioner.php:79 msgid "Really abort?" msgstr "Deseja realmente cancelar o envio?" -#: /plugins/burocrata/views/helpers/buro_captioner.php:81 +#: /views/helpers/buro_captioner.php:81 +msgid "Really remove?" +msgstr "Você tem certeza que deseja remover o arquivo?" + +#: /views/helpers/buro_captioner.php:83 msgid "Something went wrong and the file was not sent." msgstr "Algo deu errado ao enviar os dados. É provável que sua comunicação com o site esteja com problema." -#: /plugins/burocrata/views/helpers/buro_captioner.php:83 +#: /views/helpers/buro_captioner.php:85 msgid "Something went wrong and the file was not sent. The server returned #{error}" msgstr "Algo deu errado com o envio. O servidor retornou \"#{error}\"." -#: /plugins/burocrata/views/helpers/buro_captioner.php:94 +#: /views/helpers/buro_captioner.php:87 +msgid "The file was successfully recevied." +msgstr "O arquivo foi recebido com sucesso." + +#: /views/helpers/buro_captioner.php:89 +msgid "Download the file" +msgstr "Baixar arquivo" + +#: /views/helpers/buro_captioner.php:100 msgid "The uploaded file is not a valid image file." msgstr "O arquivo enviado deveria ser de imagem." diff --git a/src/cake/app/plugins/burocrata/views/helpers/buro_captioner.php b/src/cake/app/plugins/burocrata/views/helpers/buro_captioner.php index 9a29afa7..810ffa22 100644 --- a/src/cake/app/plugins/burocrata/views/helpers/buro_captioner.php +++ b/src/cake/app/plugins/burocrata/views/helpers/buro_captioner.php @@ -62,19 +62,19 @@ protected function _upload() $this->BuroOfficeBoy->addCaption('upload', 'error_resource', __d('burocrata', 'The upload data does not define any type of resource', true)); $this->BuroOfficeBoy->addCaption('upload', 'sending', - __d('burocrata', 'Enviando o arquivo #{fileName}. Aguarde...', true)); - $this->BuroOfficeBoy->addCaption('upload', 'hours_left', - __d('burocrata', 'Faltando #{hours} horas', true)); - $this->BuroOfficeBoy->addCaption('upload', 'minutes_left', - __d('burocrata', 'Faltando #{minutes} minutos', true)); - $this->BuroOfficeBoy->addCaption('upload', 'seconds_left', - __d('burocrata', 'Faltando #{seconds} segundos', true)); + __d('burocrata', 'Uploading file #{fileName}. Please, wait...', true)); + //$this->BuroOfficeBoy->addCaption('upload', 'hours_left', + // __d('burocrata', 'Faltando #{hours} horas', true)); + //$this->BuroOfficeBoy->addCaption('upload', 'minutes_left', + // __d('burocrata', 'Faltando #{minutes} minutos', true)); + //$this->BuroOfficeBoy->addCaption('upload', 'seconds_left', + // __d('burocrata', 'Faltando #{seconds} segundos', true)); $this->BuroOfficeBoy->addCaption('upload', 'cancel', - __d('burocrata', 'Cancelar', true)); + __d('burocrata', 'Cancel', true)); $this->BuroOfficeBoy->addCaption('upload', 'try_again', - __d('burocrata', 'Tentar de novo', true)); + __d('burocrata', 'Try again', true)); $this->BuroOfficeBoy->addCaption('upload', 'remove', - __d('burocrata', 'Remover arquivo', true)); + __d('burocrata', 'Remove this file', true)); $this->BuroOfficeBoy->addCaption('upload', 'really_abort', __d('burocrata', 'Really abort?', true)); $this->BuroOfficeBoy->addCaption('upload', 'really_remove', From 40cafc3fe98f553913b15d1c18eee597261df349 Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Thu, 21 Mar 2013 10:47:05 -0300 Subject: [PATCH 35/42] Showing image preview: need test, though. --- .../plugins/burocrata/views/helpers/buro_burocrata.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php b/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php index 0ba70cc5..fd6fa170 100644 --- a/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php +++ b/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php @@ -2442,7 +2442,7 @@ public function inputUpload($options) if (!isset($gen_options['callbacks']['ajax']['onSave']['js'])) $gen_options['callbacks']['ajax']['onSave']['js'] = ''; - $gen_options['callbacks']['ajax']['onSave']['js'] = "BuroCR.get('{$gen_options['baseID']}').addCaption(BuroCaption.get('upload', 'transfer_ok', json));"; + $gen_options['callbacks']['ajax']['onSave']['js'] = "BuroCR.get('{$gen_options['baseID']}').addCaption(BuroCaption.get('upload', 'transfer_ok'));"; $out .= $this->_upload($gen_options, $file_input_options); @@ -2503,7 +2503,11 @@ public function inputImage($options) if (empty($gen_options['callbacks']['onRestart']['js'])) $gen_options['callbacks']['onRestart']['js'] = ''; $gen_options['callbacks']['onRestart']['js'] .= "$('{$act_id}').hide(); $('{$prv_id}').hide();"; - + + if (empty($gen_options['callbacks']['ajax']['onSave']['js'])) + $gen_options['callbacks']['ajax']['onSave']['js'] = ''; + $gen_options['callbacks']['ajax']['onSave']['js'] .= "$('{$img_id}').src = json.dlurl; $('{$prv_id}').show();"; + $script = ''; $script .= "$('{$chg_id}').observe('click', function(ev){ev.stop(); BuroCR.get('{$gen_options['baseID']}').again();});"; $script .= "$('{$rmv_id}').observe('click', function(ev){ev.stop(); BuroCR.get('{$gen_options['baseID']}').again(true);});"; From 68eae1cb6535cc5b06d97562778f373ea11c0fbf Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Thu, 21 Mar 2013 23:02:38 -0300 Subject: [PATCH 36/42] More changes to the BuroAjaxUpload Fixing translations. Filling the hidden input with the uploaded file ID. Triggering the onComplete callback in the right moment. --- .../locale/por/LC_MESSAGES/burocrata.mo | Bin 6024 -> 6050 bytes .../locale/por/LC_MESSAGES/burocrata.po | 140 +++++++++--------- .../views/helpers/buro_captioner.php | 2 +- .../plugins/burocrata/webroot/js/burocrata.js | 5 +- 4 files changed, 75 insertions(+), 72 deletions(-) diff --git a/src/cake/app/plugins/burocrata/locale/por/LC_MESSAGES/burocrata.mo b/src/cake/app/plugins/burocrata/locale/por/LC_MESSAGES/burocrata.mo index d026db19a945e98b434b1f163818f8f50e67a757..c6988b71d3eb287aea19b09d04fd88085d02f5da 100644 GIT binary patch delta 745 zcmYk)KS&!<9KiA4g;Q(&m&T-4IvA1;fD=26#Yjq|Aa3r4Ru zY)(|nL>0A>m&i}v8@Eskd_!&UyKx`&CcjY+K0w`fgxdHicHkLm-X-2di`!`288YB& zOA_^ftZ^7)#AB!h@~DXqQ4=4bHadfv=c4ZOk=K#H#IMbI4Yf`kGq{O441Y4vw`yP! z+jyu4Siuq8H6G#<;-1?g@6f?PJV!n7ZeP<0)W#gt|IQNXMLy%zQ!&;?3FRLBJhdmS zLVd%oS`ziQ%(rK=tHqMuBfh_#H47RE;E Yzv9`e(RkE|@7Z0MYw4M2Cv|N72S{UDtN;K2 delta 702 zcmXZaJuE{}6u|NGnpaAxR#jsn7>FjVU@2+Bpaz7=$KqokG%=wjZxA0bh@?pq=^)G` zqFoqSSUV__NF-vASWFiGqc?fU@11+kz31F_-+A;Pdi8EOZ6dPj6B)rH?8Oo;U`?G! z1lKT*IZWXbR^gCeqzgx}7PqiqiR@v3xWB&a7>0=FQ1dph0(a`g5pv~_0X2t}c!5DI zpcZ<-1}vfnKg|3$QcrA>ZLGi+^kOqcQ0GUD7KdZ;wZ((FLD<-WF5*tq0uj`OJ*XQc zP#YaaT{nfAH;>$oESorO=C@Jn>|-ltF^bL&FM3y>xP-qrfQww1{u`&*jrTZ-KX{DE zMv)GDM%~Z~mu*LFEQ$K>OrsuT7xgN1P8%hZc9G1SJ!nbh%uZYJe3N^&D&zP diff --git a/src/cake/app/plugins/burocrata/locale/por/LC_MESSAGES/burocrata.po b/src/cake/app/plugins/burocrata/locale/por/LC_MESSAGES/burocrata.po index 5e5d532b..0927fa12 100644 --- a/src/cake/app/plugins/burocrata/locale/por/LC_MESSAGES/burocrata.po +++ b/src/cake/app/plugins/burocrata/locale/por/LC_MESSAGES/burocrata.po @@ -4,8 +4,8 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" -"POT-Creation-Date: 2013-03-21 00:50-0300\n" -"PO-Revision-Date: 2013-03-21 00:51-0300\n" +"POT-Creation-Date: 2013-03-21 22:51-0300\n" +"PO-Revision-Date: 2013-03-21 22:59-0300\n" "Last-Translator: Daniel Abrahão \n" "Language-Team: Preface Design \n" "Language: \n" @@ -16,267 +16,267 @@ msgstr "" "X-Poedit-Language: Portuguese\n" "X-Poedit-Country: BRAZIL\n" -#: /views/helpers/buro_burocrata.php:574 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:574 msgid "Burocrata::submit - Submit label" msgstr "Enviar" -#: /views/helpers/buro_burocrata.php:588;665 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:588;665 msgid "Burocrata::okOrCancel - Cancel label" msgstr "Cancelar" -#: /views/helpers/buro_burocrata.php:647 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:647 msgid "Burocrata::okOrCancel - OK label" msgstr "Ok" -#: /views/helpers/buro_burocrata.php:675 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:675 msgid "anchorList or" msgstr "ou" -#: /views/helpers/buro_burocrata.php:972 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:972 msgid "Burocrata: nothing found on autocomplete." msgstr "Nada encontrado." -#: /views/helpers/buro_burocrata.php:1081;1971 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:1081;1971 msgid "Burocrata: create a new related item" msgstr "Criar um novo" -#: /views/helpers/buro_burocrata.php:1082;1972 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:1082;1972 msgid "Burocrata: edit related data" msgstr "Editar" -#: /views/helpers/buro_burocrata.php:1083 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:1083 msgid "Burocrata: nothing found on autocomplete" msgstr "Nada encontrado." -#: /views/helpers/buro_burocrata.php:1084 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:1084 msgid "Burocrata: choose another related item" msgstr "Escolher um outro" -#: /views/helpers/buro_burocrata.php:1085 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:1085 msgid "Burocrata: Bring last item back" msgstr "Usar último item" -#: /views/helpers/buro_burocrata.php:1644 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:1644 msgid "Burocrata::orderdItensMenu - list caption:" msgstr "Adicionar:" -#: /views/helpers/buro_burocrata.php:1650 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:1650 msgid "Burocrata::orderdItensMenu - close list" msgstr "Fechar" -#: /views/helpers/buro_burocrata.php:1752 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:1752 msgid "Burocrata::orderedItensControls - up" msgstr "Mover para cima" -#: /views/helpers/buro_burocrata.php:1758 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:1758 msgid "Burocrata::orderedItensControls - down" msgstr "Mover para baixo" -#: /views/helpers/buro_burocrata.php:1764 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:1764 msgid "Burocrata::orderedItensControls - delete" msgstr "Excluir" -#: /views/helpers/buro_burocrata.php:1772 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:1772 msgid "Burocrata::orderedItensControls - duplicate" msgstr "Duplicar" -#: /views/helpers/buro_burocrata.php:1779 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:1779 msgid "Burocrata::orderedItensControls - edit" msgstr "Editar" -#: /views/helpers/buro_burocrata.php:1973 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:1973 msgid "Burocrata: view related data" msgstr "Ver dados completos" -#: /views/helpers/buro_burocrata.php:1974 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:1974 msgid "Burocrata: unlink related data" msgstr "Remover" -#: /views/helpers/buro_burocrata.php:1975 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:1975 msgid "Burocrata: confirm unlinking" msgstr "Deseja remover mesmo?" -#: /views/helpers/buro_burocrata.php:2420 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2420 msgid "Burocrata::inputUpload - Change file" msgstr "Alterar" -#: /views/helpers/buro_burocrata.php:2451 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2453 msgid "Burocrata::inputUpload - Download file" msgstr "Baixar arquivo" -#: /views/helpers/buro_burocrata.php:2455 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2455 msgid "Burocrata::inputUpload - File: " msgstr "Arquivo:" -#: /views/helpers/buro_burocrata.php:2485 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2487 msgid "Burocrata::inputImage - Change image" msgstr "Alterar essa imagem" -#: /views/helpers/buro_burocrata.php:2487 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2489 msgid "Burocrata::inputImage - Remove image" msgstr "Remover essa imagem" -#: /views/helpers/buro_burocrata.php:2532 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2536 msgid "Burocrata::inputImage - or " msgstr " ou " -#: /views/helpers/buro_burocrata.php:2613 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2617 msgid "Burocrata::inputTextile - Preview" msgstr "Visualizar" -#: /views/helpers/buro_burocrata.php:2648 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2652 msgid "Burocrata::inputTextile - Add bold" msgstr "Negrito" -#: /views/helpers/buro_burocrata.php:2649 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2653 msgid "Burocrata::inputTextile - Add italic" msgstr "Itálico" -#: /views/helpers/buro_burocrata.php:2650 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2654 msgid "Burocrata::inputTextile - Add link" msgstr "Link" -#: /views/helpers/buro_burocrata.php:2651 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2655 msgid "Burocrata::inputTextile - Add title" msgstr "Título" -#: /views/helpers/buro_burocrata.php:2652 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2656 msgid "Burocrata::inputTextile - Add image" msgstr "Imagem" -#: /views/helpers/buro_burocrata.php:2653 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2657 msgid "Burocrata::inputTextile - Add file" msgstr "Arquivo" -#: /views/helpers/buro_burocrata.php:2654 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2658 msgid "Burocrata::inputTextile - Add superscript" msgstr "Sobrescrito" -#: /views/helpers/buro_burocrata.php:2655 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2659 msgid "Burocrata::inputTextile - Add subscript" msgstr "Subscrito" -#: /views/helpers/buro_burocrata.php:2670 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2674 msgid "Burocrata::_popupTextileLink - Instructions for link" msgstr " " -#: /views/helpers/buro_burocrata.php:2671 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2675 msgid "Burocrata::_popupTextileLink - What is the text for this link" msgstr "Qual é o texto para este link?" -#: /views/helpers/buro_burocrata.php:2672 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2676 msgid "Burocrata::_popupTextileLink - What is the URL of this link" msgstr "Qual é o endereço para o link?" -#: /views/helpers/buro_burocrata.php:2673 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2677 msgid "Burocrata::_popupTextileLink - Title of link popup" msgstr "Link" -#: /views/helpers/buro_burocrata.php:2705 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2709 msgid "Burocrata::_popupTextileTitle - Instructions for link" msgstr " " -#: /views/helpers/buro_burocrata.php:2706 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2710 msgid "Burocrata::_popupTextileTitle - What is the type of this title" msgstr " Tipo do título" -#: /views/helpers/buro_burocrata.php:2707 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2711 msgid "Burocrata::_popupTextileTitle - Title" msgstr " Título" -#: /views/helpers/buro_burocrata.php:2708 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2712 msgid "Burocrata::_popupTextileTitle - Subtitle" msgstr " Título" -#: /views/helpers/buro_burocrata.php:2709 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2713 msgid "Burocrata::_popupTextileTitle - What is the title" msgstr " Título" -#: /views/helpers/buro_burocrata.php:2710 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2714 msgid "Burocrata::_popupTextileTitle - Title of title popup" msgstr " Título" -#: /views/helpers/buro_burocrata.php:2755 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2759 msgid "Burocrata::_popupTextilePreview - Title of preview popup" msgstr " " -#: /views/helpers/buro_burocrata.php:2780 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2784 msgid "Burocrata::_popupTextileFile - Title of `add file` popup" msgstr " Adição de arquivo" -#: /views/helpers/buro_burocrata.php:2781 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2785 msgid "Burocrata::_popupTextileFile - Label of file input" msgstr " Arquivo:" -#: /views/helpers/buro_burocrata.php:2819 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2823 msgid "Burocrata::_popupTextileImage - Title of `add image` popup" msgstr " Adição de imagem" -#: /views/helpers/buro_burocrata.php:2820 +#: /plugins/burocrata/views/helpers/buro_burocrata.php:2824 msgid "Burocrata::_popupTextileImage - Label of file input" msgstr " Imagem:" -#: /views/helpers/buro_captioner.php:55 +#: /plugins/burocrata/views/helpers/buro_captioner.php:55 msgid "The uploaded file is too large. (filesize > upload_max_filesize or filesize > Model::$validate definitions)" msgstr "O arquivo enviado é muito grande." -#: /views/helpers/buro_captioner.php:57 +#: /plugins/burocrata/views/helpers/buro_captioner.php:57 msgid "The uploaded file is too large. (filesize > post_max_size)" msgstr "O arquivo enviado é muito grande." -#: /views/helpers/buro_captioner.php:59 +#: /plugins/burocrata/views/helpers/buro_captioner.php:59 msgid "The upload process could not be completed because the file was placed on a non-allowed directory." msgstr "O local que o arquivo foi colocado não é permitido. Isso pode significar tentativa de burlar o sistema ou falha na configuração do servidor." -#: /views/helpers/buro_captioner.php:61 +#: /plugins/burocrata/views/helpers/buro_captioner.php:61 msgid "The resource is blocked and the webserver can not work properly with it." msgstr "Não foi possível ter acesso ao recurso enviado." -#: /views/helpers/buro_captioner.php:63 +#: /plugins/burocrata/views/helpers/buro_captioner.php:63 msgid "The upload data does not define any type of resource" msgstr "Os dados enviados não configuram um recurso que possa ser convertido em arquivo." -#: /views/helpers/buro_captioner.php:65 +#: /plugins/burocrata/views/helpers/buro_captioner.php:65 msgid "Uploading file #{fileName}. Please, wait..." msgstr "Enviando o arquivo \"#{fileName}\". Aguarde..." -#: /views/helpers/buro_captioner.php:73 +#: /plugins/burocrata/views/helpers/buro_captioner.php:73 msgid "Cancel" msgstr "Cancelar" -#: /views/helpers/buro_captioner.php:75 +#: /plugins/burocrata/views/helpers/buro_captioner.php:75 msgid "Try again" msgstr "Tentar novamente" -#: /views/helpers/buro_captioner.php:77 +#: /plugins/burocrata/views/helpers/buro_captioner.php:77 msgid "Remove this file" msgstr "Remover o arquivo" -#: /views/helpers/buro_captioner.php:79 +#: /plugins/burocrata/views/helpers/buro_captioner.php:79 msgid "Really abort?" msgstr "Deseja realmente cancelar o envio?" -#: /views/helpers/buro_captioner.php:81 +#: /plugins/burocrata/views/helpers/buro_captioner.php:81 msgid "Really remove?" msgstr "Você tem certeza que deseja remover o arquivo?" -#: /views/helpers/buro_captioner.php:83 +#: /plugins/burocrata/views/helpers/buro_captioner.php:83 msgid "Something went wrong and the file was not sent." msgstr "Algo deu errado ao enviar os dados. É provável que sua comunicação com o site esteja com problema." -#: /views/helpers/buro_captioner.php:85 +#: /plugins/burocrata/views/helpers/buro_captioner.php:85 msgid "Something went wrong and the file was not sent. The server returned #{error}" msgstr "Algo deu errado com o envio. O servidor retornou \"#{error}\"." -#: /views/helpers/buro_captioner.php:87 -msgid "The file was successfully recevied." -msgstr "O arquivo foi recebido com sucesso." +#: /plugins/burocrata/views/helpers/buro_captioner.php:87 +msgid "The file #{filename} was successfully received." +msgstr "O arquivo \"#{filename}\" foi recebido com sucesso." -#: /views/helpers/buro_captioner.php:89 +#: /plugins/burocrata/views/helpers/buro_captioner.php:89 msgid "Download the file" msgstr "Baixar arquivo" -#: /views/helpers/buro_captioner.php:100 +#: /plugins/burocrata/views/helpers/buro_captioner.php:100 msgid "The uploaded file is not a valid image file." msgstr "O arquivo enviado deveria ser de imagem." diff --git a/src/cake/app/plugins/burocrata/views/helpers/buro_captioner.php b/src/cake/app/plugins/burocrata/views/helpers/buro_captioner.php index 810ffa22..ab054bab 100644 --- a/src/cake/app/plugins/burocrata/views/helpers/buro_captioner.php +++ b/src/cake/app/plugins/burocrata/views/helpers/buro_captioner.php @@ -84,7 +84,7 @@ protected function _upload() $this->BuroOfficeBoy->addCaption('upload', 'error_with_server_resp', __d('burocrata', 'Something went wrong and the file was not sent. The server returned #{error}', true)); $this->BuroOfficeBoy->addCaption('upload', 'transfer_ok', - __d('burocrata', 'The file was successfully recevied.', true)); + __d('burocrata', 'The file #{filename} was successfully received.', true)); $this->BuroOfficeBoy->addCaption('upload', 'get_file', __d('burocrata', 'Download the file', true)); } diff --git a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js index e870590e..1949a858 100644 --- a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js +++ b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js @@ -2319,6 +2319,9 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { this.handleError(); this.requestEnded(); + + if (this.isLast) + this.trigger('onComplete', this, this.json); }, requestEnded: function() { @@ -2370,6 +2373,7 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { } else if (this.state == this.ST_UPLOADING) { + this.hidden_input.value = this.json.saved; this.trigger('onSave', this, this.json); this.finish(); } @@ -2416,7 +2420,6 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { this.getFileLink.href = this.json.dlurl; this.state = this.ST_DONE; this.controlControls(); - this.trigger('onComplete', this, this.json); }, renderProgress: function(progress) { From 80d196c72fba0263c04802dc861648186b4cf67d Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Thu, 21 Mar 2013 23:33:02 -0300 Subject: [PATCH 37/42] Upload input fully functional, finally! Showing the filename and proper actions when the form comes already filled. Created a new callback: onLoad The BuroAjaxUpload may receive some extra data on a extra parameter. --- .../views/helpers/buro_burocrata.php | 45 +++++++++++++------ .../views/helpers/buro_office_boy.php | 10 +++-- .../plugins/burocrata/webroot/js/burocrata.js | 37 ++++++++++++--- 3 files changed, 69 insertions(+), 23 deletions(-) diff --git a/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php b/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php index fd6fa170..7760c10e 100644 --- a/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php +++ b/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php @@ -2423,6 +2423,15 @@ public function inputUpload($options) foreach ($ids as $id) ${$id.'_id'} = $id . $gen_options['baseID']; + $value = $this->Form->value($file_input_options['fieldName']); + if (!empty($value)) + { + $SfilStoredFile = ClassRegistry::init('JjMedia.SfilStoredFile'); + $SfilStoredFile->id = $value; + $gen_options['aditionalData']['dlurl'] = $dlurl = $this->Bl->fileURL($value, '', true); + $gen_options['aditionalData']['filename'] = $SfilStoredFile->field('original_filename'); + } + $out = ''; if (empty($gen_options['callbacks']['onSave']['js'])) @@ -2433,26 +2442,32 @@ public function inputUpload($options) $gen_options['callbacks']['onRestart']['js'] = ''; $gen_options['callbacks']['onRestart']['js'] .= "$('{$act_id}').hide(); $('{$prv_id}').hide();"; - $script = ''; - $value = $this->Form->value($file_input_options['fieldName']); - if (empty($value)) - $script .= "$('{$act_id}').hide(); $('{$prv_id}').hide();"; - $script .= "$('{$chg_id}').observe('click', function(ev){ev.stop(); BuroCR.get('{$gen_options['baseID']}').again();});"; - $out .= $this->BuroOfficeBoy->addHtmlEmbScript($script); + $out .= $this->BuroOfficeBoy->addHtmlEmbScript( + "$('{$chg_id}').observe('click', function(ev){ev.stop(); BuroCR.get('{$gen_options['baseID']}').again();});" + . "$('{$act_id}').hide(); $('{$prv_id}').hide();" + ); if (!isset($gen_options['callbacks']['ajax']['onSave']['js'])) $gen_options['callbacks']['ajax']['onSave']['js'] = ''; - $gen_options['callbacks']['ajax']['onSave']['js'] = "BuroCR.get('{$gen_options['baseID']}').addCaption(BuroCaption.get('upload', 'transfer_ok'));"; + $gen_options['callbacks']['ajax']['onSave']['js'] .= "upload.addCaption(BuroCaption.get('upload', 'transfer_ok', {filename: upload.getFileName()}));"; + + $fileCaption = __d('burocrata','Burocrata::inputUpload - File: ', true); + + if (!empty($value)) + { + if (!isset($gen_options['callbacks']['ajax']['onLoad']['js'])) + $gen_options['callbacks']['ajax']['onLoad']['js'] = ''; + $gen_options['callbacks']['ajax']['onLoad']['js'] .= "upload.addCaption('$fileCaption ' + upload.getFileName());"; + } $out .= $this->_upload($gen_options, $file_input_options); // Div for previews $out .= $this->Bl->sdiv(array('id' => $prv_id)); $filename = __d('burocrata','Burocrata::inputUpload - Download file', true); - $htmlAttributes = array('id' => $lnk_id); - if (!empty($value)) - $htmlAttributes['href'] = $this->Bl->fileURL($value, '', true); - $out .= $this->Bl->pDry(__d('burocrata','Burocrata::inputUpload - File: ', true) . $this->Bl->a($htmlAttributes, array(), $filename)); + $out .= $this->Bl->pDry( + "$fileCaption " . $this->Bl->a(array('id' => $lnk_id, 'href' => $dlurl), array(), $filename) + ); $out .= $this->Bl->ediv(); // Div for actions ID must be `'act' . $gen_options['baseID']` @@ -2499,7 +2514,6 @@ public function inputImage($options) if (empty($gen_options['callbacks']['onSave']['js'])) $gen_options['callbacks']['onSave']['js'] = ''; $gen_options['callbacks']['onSave']['js'] .= "$('{$img_id}').src = ''; $('{$img_id}').writeAttribute({src: json.url, alt: json.filename}); $('{$act_id}').show(); $('{$prv_id}').show();"; - if (empty($gen_options['callbacks']['onRestart']['js'])) $gen_options['callbacks']['onRestart']['js'] = ''; $gen_options['callbacks']['onRestart']['js'] .= "$('{$act_id}').hide(); $('{$prv_id}').hide();"; @@ -2507,14 +2521,17 @@ public function inputImage($options) if (empty($gen_options['callbacks']['ajax']['onSave']['js'])) $gen_options['callbacks']['ajax']['onSave']['js'] = ''; $gen_options['callbacks']['ajax']['onSave']['js'] .= "$('{$img_id}').src = json.dlurl; $('{$prv_id}').show();"; + if (empty($gen_options['callbacks']['ajax']['onRestart']['js'])) + $gen_options['callbacks']['ajax']['onRestart']['js'] = ''; + $gen_options['callbacks']['ajax']['onRestart']['js'] .= "$('{$img_id}').hide();"; + $script = ''; $script .= "$('{$chg_id}').observe('click', function(ev){ev.stop(); BuroCR.get('{$gen_options['baseID']}').again();});"; $script .= "$('{$rmv_id}').observe('click', function(ev){ev.stop(); BuroCR.get('{$gen_options['baseID']}').again(true);});"; + $out .= $this->BuroOfficeBoy->addHtmlEmbScript($script); $gen_options['model'] = 'JjMedia.SfilImageFile'; - - $out .= $this->BuroOfficeBoy->addHtmlEmbScript($script); $out .= $this->_upload($gen_options, $file_input_options); // Div for previews diff --git a/src/cake/app/plugins/burocrata/views/helpers/buro_office_boy.php b/src/cake/app/plugins/burocrata/views/helpers/buro_office_boy.php index 85e6c70e..b8335db1 100644 --- a/src/cake/app/plugins/burocrata/views/helpers/buro_office_boy.php +++ b/src/cake/app/plugins/burocrata/views/helpers/buro_office_boy.php @@ -98,6 +98,7 @@ class BuroOfficeBoyHelper extends AppHelper 'onError' => 'function(code, error, json){%s}' ), 'upload_ajax' => array( + 'onLoad' => 'function(upload){%s}', 'onStart' => 'function(upload){%s}', 'onComplete' => 'function(upload, json){%s}', 'onPieceSent' => 'function(upload, json){%s}', @@ -360,10 +361,13 @@ public function upload($options) extract(am($defaults, $options)); unset($defaults); - if (!empty($parameters)) $parameters = $this->Js->object($parameters); - else $parameters = '{}'; + if (empty($parameters)) $parameters = '{}'; + else $parameters = $this->Js->object($parameters); + + if (empty($aditionalData)) $aditionalData = '{}'; + else $aditionalData = $this->Js->object($aditionalData); - $script = sprintf("new BuroUploadGeneric('%s', '%s', %s)", $baseID, $url, $parameters); + $script = sprintf("new BuroUploadGeneric('%s', '%s', %s, %s)", $baseID, $url, $parameters, $aditionalData); if(!empty($callbacks)) { if (isset($callbacks['ajax'])) diff --git a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js index 1949a858..208c90a7 100644 --- a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js +++ b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js @@ -1855,7 +1855,7 @@ var BuroEditableList = Class.create(BuroCallbackable, { var BuroUploadGeneric = Class.create({ - initialize: function(id_base, url, parameters) + initialize: function(id_base, url, parameters, aditionalData) { this.ajax_upload = ( 'multiple' in new Element('input', {type: 'file'}) && @@ -1865,7 +1865,7 @@ var BuroUploadGeneric = Class.create({ if (this.ajax_upload) { - this.object = new BuroAjaxUpload(this, id_base, url, parameters); + this.object = new BuroAjaxUpload(this, id_base, url, parameters, aditionalData); return; } @@ -1959,6 +1959,11 @@ var BuroUpload = Class.create(BuroCallbackable, { this.tmp_input.observe('change', this.submit.bind(this)); this.master_input.insert({after: this.tmp_input}); } + + if (this.hidden_input.value.blank()) + { + ['act' + this.id_base, 'prv' + this.id_base].each(Element.hide); + } }, submit: function() { @@ -2081,18 +2086,20 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { chunkSize: 1024*1024, // 1M MAX_TRIES: 5, ST_READY: 1 , ST_UPLOADING: 2, ST_DONE: 3, ST_ERROR: 4, ST_INVALIDATED: 5, - initialize: function(parent, id_base, url, parameters) + initialize: function(parent, id_base, url, parameters, additionalData) { this.parent = parent; this.id_base = id_base; this.url = url; this.parameters = null; + this.additionalData = additionalData; + if (typeof parameters == 'object') this.parameters = parameters; BuroCR.set(this.id_base, this); - if (document.loaded) this.loaded(); + if (document.loaded) this.loaded.bind(this).defer(); else document.observe('dom:loaded', this.loaded.bind(this)) }, loaded: function() @@ -2125,7 +2132,16 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { this.handleProgressBinded = this.handleProgress.bind(this); this.uploadStatusChangeBinded = this.uploadStatusChange.bind(this); + this.hidden_input = $('hi' + this.id_base); + this.reset(); + + if (!this.hidden_input.value.blank()) + { + this.upload_input.hide(); + this.finish(); + } + this.trigger('onLoad', this); }, reset: function() { @@ -2135,7 +2151,8 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { this.state = this.ST_READY; this.upload_input.show().value = ''; - this.upload_input.up('.input').removeClassName('error').select('.error-message').invoke('remove'); + if (this.upload_input.up('.input')) + this.upload_input.up('.input').removeClassName('error').select('.error-message').invoke('remove'); this.progress_bar.hide(); this.clearCaption().clearXHR().controlControls(); @@ -2260,6 +2277,8 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { { if (this.file) return this.file.name || this.file.fileName; + else if (this.additionalData.filename) + return this.additionalData.filename; return null; }, uploadOnePiece: function() @@ -2417,7 +2436,13 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { }, finish: function() { - this.getFileLink.href = this.json.dlurl; + if (this.json && this.json.dlurl) + this.getFileLink.href = this.json.dlurl; + else if (this.additionalData.dlurl) + this.getFileLink.href = this.additionalData.dlurl; + else + throw "BuroAjaxUpload.finish() called, but not seems to be finished."; + this.state = this.ST_DONE; this.controlControls(); }, From fec41cb1db4ca6b3efdcb05c98f165b110a0f91e Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Thu, 21 Mar 2013 23:59:24 -0300 Subject: [PATCH 38/42] Making the old version to work --- .../views/helpers/buro_burocrata.php | 6 ++--- .../plugins/burocrata/webroot/js/burocrata.js | 4 +-- .../controllers/jj_media_controller.php | 3 +-- .../plugins/jj_media/models/sfil_big_file.php | 2 +- .../jj_media/views/jj_media/upload.ctp | 25 +++++++++++++++++++ 5 files changed, 31 insertions(+), 9 deletions(-) create mode 100644 src/cake/app/plugins/jj_media/views/jj_media/upload.ctp diff --git a/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php b/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php index 7760c10e..7e8c3519 100644 --- a/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php +++ b/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php @@ -2422,7 +2422,8 @@ public function inputUpload($options) $ids = array('act', 'prv', 'lnk', 'chg'); foreach ($ids as $id) ${$id.'_id'} = $id . $gen_options['baseID']; - + + $fileCaption = __d('burocrata','Burocrata::inputUpload - File: ', true); $value = $this->Form->value($file_input_options['fieldName']); if (!empty($value)) { @@ -2450,9 +2451,6 @@ public function inputUpload($options) if (!isset($gen_options['callbacks']['ajax']['onSave']['js'])) $gen_options['callbacks']['ajax']['onSave']['js'] = ''; $gen_options['callbacks']['ajax']['onSave']['js'] .= "upload.addCaption(BuroCaption.get('upload', 'transfer_ok', {filename: upload.getFileName()}));"; - - $fileCaption = __d('burocrata','Burocrata::inputUpload - File: ', true); - if (!empty($value)) { if (!isset($gen_options['callbacks']['ajax']['onLoad']['js'])) diff --git a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js index 208c90a7..ba54af62 100644 --- a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js +++ b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js @@ -1960,9 +1960,9 @@ var BuroUpload = Class.create(BuroCallbackable, { this.master_input.insert({after: this.tmp_input}); } - if (this.hidden_input.value.blank()) + if (!this.hidden_input.value.blank()) { - ['act' + this.id_base, 'prv' + this.id_base].each(Element.hide); + ['act' + this.id_base, 'prv' + this.id_base].each(Element.show); } }, submit: function() diff --git a/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php b/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php index ce72ea95..2d4554fa 100644 --- a/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php +++ b/src/cake/app/plugins/jj_media/controllers/jj_media_controller.php @@ -165,7 +165,6 @@ function index($download = null, $data = null, $name = null) * It already saves the file, generating the filtered copies, and renders a JSON, directly on view. * * @access public - * @todo Receive, through posted data, the model that will handle the save */ function upload() { @@ -177,7 +176,7 @@ function upload() $this->layout = 'ajax'; $this->view = 'Typographer.Type'; - $this->set('jsonVars', $this->saveUpload($this->data)); + $this->set($this->saveUpload($this->data)); } /** diff --git a/src/cake/app/plugins/jj_media/models/sfil_big_file.php b/src/cake/app/plugins/jj_media/models/sfil_big_file.php index 409ec629..d74b7b53 100644 --- a/src/cake/app/plugins/jj_media/models/sfil_big_file.php +++ b/src/cake/app/plugins/jj_media/models/sfil_big_file.php @@ -54,7 +54,7 @@ class SfilBigFile extends SfilStoredFile 'file' => array( 'resource' => array('rule' => 'checkResource'), 'access' => array('rule' => 'checkAccess'), - 'location' => array('rule' => array('checkLocation', array(MEDIA_TRANSFER, TMP))), + 'location' => array('rule' => array('checkLocation', array(MEDIA_TRANSFER, TMP, '/tmp/', 'D:\wamp\tmp'))), 'permission' => array('rule' => array('checkPermission', '*')), 'size' => array('rule' => array('checkSize', '500M')) ), diff --git a/src/cake/app/plugins/jj_media/views/jj_media/upload.ctp b/src/cake/app/plugins/jj_media/views/jj_media/upload.ctp new file mode 100644 index 00000000..447b382b --- /dev/null +++ b/src/cake/app/plugins/jj_media/views/jj_media/upload.ctp @@ -0,0 +1,25 @@ +Bl->fileURL($saved, $version); + $dlurl = $this->Bl->fileURL($saved, $version, true); + } + + $extraCaptions = $this->BuroOfficeBoy->getAllCaptions(); + + echo json_encode(compact('error', 'validationErrors', 'saved', 'url', 'dlurl', 'filename', 'extraCaptions')); From 3a4377f2823bde46dd93f91ebc56890611e2962c Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Fri, 22 Mar 2013 00:28:15 -0300 Subject: [PATCH 39/42] Last fixes Hiding image after reseting the input Adding some space between the image and the control links --- .../views/helpers/buro_burocrata.php | 53 +++++++++---------- .../plugins/burocrata/webroot/js/burocrata.js | 4 +- .../views/elements/backstage_css.ctp | 9 ++++ 3 files changed, 37 insertions(+), 29 deletions(-) diff --git a/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php b/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php index 7e8c3519..52f78110 100644 --- a/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php +++ b/src/cake/app/plugins/burocrata/views/helpers/buro_burocrata.php @@ -2350,6 +2350,15 @@ protected function _uploadParams($options) unset($file_input_options['error']); } + $value = $this->Form->value($file_input_options['fieldName']); + if (!empty($value)) + { + $SfilStoredFile = ClassRegistry::init('JjMedia.SfilStoredFile'); + $SfilStoredFile->id = $value; + $gen_options['aditionalData']['dlurl'] = $this->Bl->fileURL($value, '', true); + $gen_options['aditionalData']['filename'] = $SfilStoredFile->field('original_filename'); + } + $this->BuroCaptioner->addCaptions('upload'); return compact('gen_options', 'file_input_options'); @@ -2424,15 +2433,6 @@ public function inputUpload($options) ${$id.'_id'} = $id . $gen_options['baseID']; $fileCaption = __d('burocrata','Burocrata::inputUpload - File: ', true); - $value = $this->Form->value($file_input_options['fieldName']); - if (!empty($value)) - { - $SfilStoredFile = ClassRegistry::init('JjMedia.SfilStoredFile'); - $SfilStoredFile->id = $value; - $gen_options['aditionalData']['dlurl'] = $dlurl = $this->Bl->fileURL($value, '', true); - $gen_options['aditionalData']['filename'] = $SfilStoredFile->field('original_filename'); - } - $out = ''; if (empty($gen_options['callbacks']['onSave']['js'])) @@ -2451,7 +2451,8 @@ public function inputUpload($options) if (!isset($gen_options['callbacks']['ajax']['onSave']['js'])) $gen_options['callbacks']['ajax']['onSave']['js'] = ''; $gen_options['callbacks']['ajax']['onSave']['js'] .= "upload.addCaption(BuroCaption.get('upload', 'transfer_ok', {filename: upload.getFileName()}));"; - if (!empty($value)) + + if (!empty($gen_options['aditionalData']['dlurl'])) { if (!isset($gen_options['callbacks']['ajax']['onLoad']['js'])) $gen_options['callbacks']['ajax']['onLoad']['js'] = ''; @@ -2459,12 +2460,14 @@ public function inputUpload($options) } $out .= $this->_upload($gen_options, $file_input_options); - + + $exists = !empty($gen_options['aditionalData']['dlurl']); // Div for previews $out .= $this->Bl->sdiv(array('id' => $prv_id)); $filename = __d('burocrata','Burocrata::inputUpload - Download file', true); $out .= $this->Bl->pDry( - "$fileCaption " . $this->Bl->a(array('id' => $lnk_id, 'href' => $dlurl), array(), $filename) + "$fileCaption " . + $this->Bl->a(array('id' => $lnk_id, 'href' => $exists ? $gen_options['aditionalData']['dlurl'] : ''), array(), $filename) ); $out .= $this->Bl->ediv(); @@ -2501,8 +2504,6 @@ public function inputImage($options) $this->BuroCaptioner->addCaptions('imageUpload'); - $value = $this->Form->value($file_input_options['fieldName']); - $ids = array('act', 'prv', 'img', 'chg', 'rmv'); foreach ($ids as $id) ${$id.'_id'} = $id . $gen_options['baseID']; @@ -2521,27 +2522,25 @@ public function inputImage($options) $gen_options['callbacks']['ajax']['onSave']['js'] .= "$('{$img_id}').src = json.dlurl; $('{$prv_id}').show();"; if (empty($gen_options['callbacks']['ajax']['onRestart']['js'])) $gen_options['callbacks']['ajax']['onRestart']['js'] = ''; - $gen_options['callbacks']['ajax']['onRestart']['js'] .= "$('{$img_id}').hide();"; + $gen_options['callbacks']['ajax']['onRestart']['js'] .= "$('{$prv_id}').hide();"; - - $script = ''; - $script .= "$('{$chg_id}').observe('click', function(ev){ev.stop(); BuroCR.get('{$gen_options['baseID']}').again();});"; - $script .= "$('{$rmv_id}').observe('click', function(ev){ev.stop(); BuroCR.get('{$gen_options['baseID']}').again(true);});"; - $out .= $this->BuroOfficeBoy->addHtmlEmbScript($script); + $out .= $this->BuroOfficeBoy->addHtmlEmbScript( + "$('{$chg_id}').observe('click', function(ev){ev.stop(); BuroCR.get('{$gen_options['baseID']}').again();});" + . "$('{$rmv_id}').observe('click', function(ev){ev.stop(); BuroCR.get('{$gen_options['baseID']}').again(true);});" + . "$('{$act_id}').hide();" + ); $gen_options['model'] = 'JjMedia.SfilImageFile'; $out .= $this->_upload($gen_options, $file_input_options); // Div for previews - $out .= $this->Bl->sdiv(array('id' => $prv_id, 'style' => empty($value) ? 'display:none;' : '')); - $url = ''; - if (!empty($value)) - $url = $this->Bl->imageURL($value, $gen_options['version']); - $out .= $this->Bl->img(array('id' => $img_id, 'alt' => '', 'src' => $url)); + $exists = !empty($gen_options['aditionalData']['dlurl']); + $out .= $this->Bl->sdiv(array('id' => $prv_id, 'style' => $exists ? '' : 'display:none;')); + $out .= $this->Bl->img(array('id' => $img_id, 'alt' => '', 'src' => $exists ? $gen_options['aditionalData']['dlurl'] : '')); $out .= $this->Bl->ediv(); - + // Div for actions ID must be `'act' . $gen_options['baseID']` - $out .= $this->Bl->sdiv(array('id' => $act_id, 'style' => empty($value) ? 'display:none;' : '')); + $out .= $this->Bl->sdiv(array('id' => $act_id, 'style' => $exists ? '' : 'display:none;')); $change_link = $this->Bl->a(array('href' => '#', 'id' => $chg_id), array(), $gen_options['change_file_text']); $remove_link = $this->Bl->a(array('href' => '#', 'id' => $rmv_id), array(), $gen_options['remove_file_text']); $out .= $this->Bl->pDry($change_link . __d('burocrata','Burocrata::inputImage - or ', true) . $remove_link); diff --git a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js index ba54af62..05caf707 100644 --- a/src/cake/app/plugins/burocrata/webroot/js/burocrata.js +++ b/src/cake/app/plugins/burocrata/webroot/js/burocrata.js @@ -2112,7 +2112,7 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { this.removeFileLink.on('click', this.removeFile.bind(this)); this.getFileLink = new Element('a', {href: ''}).update(BuroCaption.get('upload', 'get_file')); - this.controls = new Element('div'); + this.controls = new Element('div', {className: 'upload_control'}); this.controls.insert(this.cancelLink).insert(' ') .insert(this.tryAgainLink).insert(' ') .insert(this.removeFileLink).insert(' ') @@ -2239,7 +2239,7 @@ var BuroAjaxUpload = Class.create(BuroCallbackable, { { ev.stop(); if (confirm(BuroCaption.get('upload', 'really_remove'))) - this.reset(); + this.again(); }, inputChange: function(ev) { diff --git a/src/cake/app/plugins/typographer/views/elements/backstage_css.ctp b/src/cake/app/plugins/typographer/views/elements/backstage_css.ctp index 056d8421..3e411d21 100644 --- a/src/cake/app/plugins/typographer/views/elements/backstage_css.ctp +++ b/src/cake/app/plugins/typographer/views/elements/backstage_css.ctp @@ -318,6 +318,15 @@ 'border' => '0', //'position' => 'absolute', )); + + + // Input upload + + $this->Decorator->rule( + '.upload_control', array( + 'margin' => $vg->size('m') . ' 0' + ) + ); From 17ab9e35695e59a9681c96f9a477aecbc7682969 Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Fri, 22 Mar 2013 00:40:15 -0300 Subject: [PATCH 40/42] CSS fix for progress bar inside forms inside forms. --- .../views/elements/backstage_css.ctp | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/cake/app/plugins/typographer/views/elements/backstage_css.ctp b/src/cake/app/plugins/typographer/views/elements/backstage_css.ctp index 3e411d21..f2a3fb38 100644 --- a/src/cake/app/plugins/typographer/views/elements/backstage_css.ctp +++ b/src/cake/app/plugins/typographer/views/elements/backstage_css.ctp @@ -318,15 +318,6 @@ 'border' => '0', //'position' => 'absolute', )); - - - // Input upload - - $this->Decorator->rule( - '.upload_control', array( - 'margin' => $vg->size('m') . ' 0' - ) - ); @@ -1304,6 +1295,12 @@ ) ); + $this->Decorator->rule( + '.buro_form .buro_form .input.buro .progress_bar .filling', array( + 'background' => $palette['bg'] + ) + ); + $this->Decorator->rule( '.input.buro .progress_bar .label', array( 'position' => 'absolute', @@ -1312,6 +1309,14 @@ 'width' => '100%' ) ); + + // Input upload + + $this->Decorator->rule( + '.upload_control', array( + 'margin' => $vg->size('m') . ' 0' + ) + ); $this->Decorator->rule( 'select.buro', array( From cc949aaa9ee3f9c3910a4b5d47dfc0a1932149e8 Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Fri, 22 Mar 2013 00:41:31 -0300 Subject: [PATCH 41/42] A example of use of content_stream input on layout_test. --- src/cake/app/models/cs_test.php | 13 +++++++++++ .../controllers/back_contents_controller.php | 8 ++++++- .../views/back_contents/layout_test.ctp | 22 +++++++++++++++++-- 3 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 src/cake/app/models/cs_test.php diff --git a/src/cake/app/models/cs_test.php b/src/cake/app/models/cs_test.php new file mode 100644 index 00000000..4b44c07f --- /dev/null +++ b/src/cake/app/models/cs_test.php @@ -0,0 +1,13 @@ + array( + 'streams' => array( + 'cs_content_stream_id' => 'document' + ) + ) + ); +} diff --git a/src/cake/app/plugins/backstage/controllers/back_contents_controller.php b/src/cake/app/plugins/backstage/controllers/back_contents_controller.php index 9e5534d7..243072d4 100644 --- a/src/cake/app/plugins/backstage/controllers/back_contents_controller.php +++ b/src/cake/app/plugins/backstage/controllers/back_contents_controller.php @@ -464,6 +464,12 @@ function create_empty_translation($moduleName, $id = null) function layout_test() { - + $this->loadModel('CsTest'); + $data = $this->CsTest->findById(1); + if (empty($data)) + { + $data = $this->CsTest->save(array('id' => 1)); + } + $this->data = $data; } } diff --git a/src/cake/app/plugins/backstage/views/back_contents/layout_test.ctp b/src/cake/app/plugins/backstage/views/back_contents/layout_test.ctp index 841bf276..606a4230 100644 --- a/src/cake/app/plugins/backstage/views/back_contents/layout_test.ctp +++ b/src/cake/app/plugins/backstage/views/back_contents/layout_test.ctp @@ -58,7 +58,7 @@ echo $this->Bl->sbox(null, array('size' => array('M' => 7, 'g' => -1))); 'default' => 'Suspendisse dignissim ante sit amet leo bibendum rhoncus? Integer at enim eget tortor cursus tristique. Cras vel vehicula nisi? Phasellus nisl massa, commodo sed porttitor quis, imperdiet quis lacus. Aliquam erat volutpat. Sed dictum, dui blandit sodales dapibus, sapien massa mollis augue, in porta ligula odio vel sapien. Donec interdum metus eu nunc tristique mattis. Donec luctus aliquam lectus, quis fermentum arcu dignissim at.' ) ) - ); + ); // Textarea with textile controll echo $this->Buro->input( @@ -224,7 +224,25 @@ echo $this->Bl->sbox(null, array('size' => array('M' => 7, 'g' => -1))); ) ) ); - + + echo $this->Buro->sform(null, array('model' => 'CsTest')); + + echo $this->Buro->input( + array(), + array( + 'type' => 'content_stream', + 'label' => 'Label for a content_stream input', + 'instructions' => 'Instructions for a content_stream input', + 'options' => array( + 'foreignKey' => 'cs_content_stream_id' + ) + ) + ); + echo $this->Bl->floatBreak(); + + echo $this->Buro->eform(); + echo $this->Bl->floatBreak(); + // Datetime without time echo $this->Buro->input( null, From 4c0089c6caff31542bbbc34d9e55283905ba00aa Mon Sep 17 00:00:00 2001 From: Daniel Abrahao Date: Fri, 22 Mar 2013 00:43:36 -0300 Subject: [PATCH 42/42] Some improvements on CsContentStreamHolder behavior Checking if cs parent exists calling Model::exists() instead of testing for Model::$data Simpler way of starting transactions. --- .../behaviors/cs_content_stream_holder.php | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/cake/app/plugins/content_stream/models/behaviors/cs_content_stream_holder.php b/src/cake/app/plugins/content_stream/models/behaviors/cs_content_stream_holder.php index dcd8cfe6..b4dca697 100644 --- a/src/cake/app/plugins/content_stream/models/behaviors/cs_content_stream_holder.php +++ b/src/cake/app/plugins/content_stream/models/behaviors/cs_content_stream_holder.php @@ -153,16 +153,9 @@ function setup(&$Model, $options) */ function beforeSave(&$Model) { - if (empty($Model->data[$Model->alias][$Model->primaryKey])) + if (!$Model->exists()) { - $dbo = $Model->getDataSource(); - - if (!$dbo->_transactionStarted) - { - $this->transactionContentStream = true; - $dbo->begin($Model); - } - + $this->transactionContentStream = $Model->getDataSource()->begin($Model); foreach ($this->settings[$Model->alias]['streams'] as $fk => $stream) if (empty($Model->data[$Model->alias][$fk]) && $Model->{$stream['assocName']}->createEmpty($stream['type'])) $Model->data[$Model->alias][$fk] = $Model->{$stream['assocName']}->id; @@ -184,9 +177,8 @@ function afterSave(&$Model, $created) { if ($this->transactionContentStream) { - $dbo = $Model->getDataSource(); - if ($created) $dbo->commit($Model); - else $dbo->rollback($Model); + if ($created) $Model->getDataSource()->commit($Model); + else $Model->getDataSource()->rollback($Model); $this->transactionContentStream = false; } }